]> git.lizzy.rs Git - rust.git/commitdiff
Fix allow_internal_unstable with rustc_const_unstable
authorGary Guo <gary@garyguo.net>
Fri, 26 Jun 2020 20:05:39 +0000 (21:05 +0100)
committerGary Guo <gary@garyguo.net>
Fri, 26 Jun 2020 20:30:36 +0000 (21:30 +0100)
src/librustc_mir/transform/check_consts/validation.rs
src/librustc_mir/transform/qualify_min_const_fn.rs

index d263bf12e8868c20e8599614205d926dd00fe37b..80257260f01837cc002d77a3f121658fb589193f 100644 (file)
@@ -548,9 +548,12 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
                 if is_lang_panic_fn(self.tcx, def_id) {
                     self.check_op(ops::Panic);
                 } else if let Some(feature) = is_unstable_const_fn(self.tcx, def_id) {
-                    // Exempt unstable const fns inside of macros with
+                    // Exempt unstable const fns inside of macros or functions with
                     // `#[allow_internal_unstable]`.
-                    if !self.span.allows_unstable(feature) {
+                    use crate::transform::qualify_min_const_fn::feature_allowed;
+                    if !self.span.allows_unstable(feature)
+                        && !feature_allowed(self.tcx, self.def_id, feature)
+                    {
                         self.check_op(ops::FnCallUnstable(def_id, feature));
                     }
                 } else {
index caf6c7715a9e1caa3cc717c266e1a1a670cc5b87..6f252ad4ed535fdd9171ed50141d5b123fddebe0 100644 (file)
@@ -315,7 +315,7 @@ fn check_place(
 }
 
 /// Returns `true` if the given feature gate is allowed within the function with the given `DefId`.
-fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
+pub fn feature_allowed(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {
     // All features require that the corresponding gate be enabled,
     // even if the function has `#[allow_internal_unstable(the_gate)]`.
     if !tcx.features().enabled(feature_gate) {
@@ -377,8 +377,16 @@ fn check_terminator(
             fn_span: _,
         } => {
             let fn_ty = func.ty(body, tcx);
-            if let ty::FnDef(def_id, _) = fn_ty.kind {
-                if !crate::const_eval::is_min_const_fn(tcx, def_id) {
+            if let ty::FnDef(fn_def_id, _) = fn_ty.kind {
+                // Allow unstable const if we opt in by using #[allow_internal_unstable]
+                // on function or macro declaration.
+                if !crate::const_eval::is_min_const_fn(tcx, fn_def_id)
+                    && !crate::const_eval::is_unstable_const_fn(tcx, fn_def_id)
+                        .map(|feature| {
+                            span.allows_unstable(feature) || feature_allowed(tcx, def_id, feature)
+                        })
+                        .unwrap_or(false)
+                {
                     return Err((
                         span,
                         format!(
@@ -390,10 +398,10 @@ fn check_terminator(
                     ));
                 }
 
-                check_operand(tcx, func, span, def_id, body)?;
+                check_operand(tcx, func, span, fn_def_id, body)?;
 
                 for arg in args {
-                    check_operand(tcx, arg, span, def_id, body)?;
+                    check_operand(tcx, arg, span, fn_def_id, body)?;
                 }
                 Ok(())
             } else {