about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir/src/transform/mod.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/mod.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/qualify_min_const_fn.rs (renamed from compiler/rustc_mir/src/transform/qualify_min_const_fn.rs)130
5 files changed, 32 insertions, 103 deletions
diff --git a/compiler/rustc_mir/src/transform/mod.rs b/compiler/rustc_mir/src/transform/mod.rs
index a622de9a8af..850cafcf898 100644
--- a/compiler/rustc_mir/src/transform/mod.rs
+++ b/compiler/rustc_mir/src/transform/mod.rs
@@ -36,7 +36,6 @@ pub mod match_branches;
 pub mod no_landing_pads;
 pub mod nrvo;
 pub mod promote_consts;
-pub mod qualify_min_const_fn;
 pub mod remove_noop_landing_pads;
 pub mod remove_unneeded_drops;
 pub mod required_consts;
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 58112ac8da5..c3ff34e6e1e 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -6,6 +6,7 @@
 #![feature(concat_idents)]
 #![feature(crate_visibility_modifier)]
 #![feature(drain_filter)]
+#![feature(in_band_lifetimes)]
 #![feature(or_patterns)]
 #![feature(rustc_private)]
 #![feature(stmt_expr_attributes)]
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 1ad184dfc46..e5f7cc51111 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -4,7 +4,7 @@ use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Constness, FnDecl, GenericParamKind, HirId};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
-use rustc_mir::transform::qualify_min_const_fn::is_min_const_fn;
+use crate::utils::qualify_min_const_fn::is_min_const_fn;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::Span;
 use rustc_typeck::hir_ty_to_ty;
diff --git a/src/tools/clippy/clippy_lints/src/utils/mod.rs b/src/tools/clippy/clippy_lints/src/utils/mod.rs
index ea52741b7cc..96d9905027b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/mod.rs
@@ -20,6 +20,7 @@ pub mod paths;
 pub mod ptr;
 pub mod sugg;
 pub mod usage;
+pub mod qualify_min_const_fn;
 
 pub use self::attrs::*;
 pub use self::diagnostics::*;
diff --git a/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs b/src/tools/clippy/clippy_lints/src/utils/qualify_min_const_fn.rs
index f15a7f7c2c8..6809b1fa88d 100644
--- a/compiler/rustc_mir/src/transform/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/qualify_min_const_fn.rs
@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::mir::*;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::{sym};
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi::RustIntrinsic;
 use std::borrow::Cow;
@@ -11,14 +11,6 @@ use std::borrow::Cow;
 type McfResult = Result<(), (Span, Cow<'static, str>)>;
 
 pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -> McfResult {
-    // Prevent const trait methods from being annotated as `stable`.
-    if tcx.features().staged_api {
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
-        if crate::const_eval::is_parent_const_impl_raw(tcx, hir_id) {
-            return Err((body.span, "trait methods cannot be stable const fn".into()));
-        }
-    }
-
     let mut current = def_id;
     loop {
         let predicates = tcx.predicates_of(current);
@@ -32,27 +24,20 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
                 | ty::PredicateAtom::ConstEquate(..)
                 | ty::PredicateAtom::TypeWellFormedFromEnv(..) => continue,
                 ty::PredicateAtom::ObjectSafe(_) => {
-                    bug!("object safe predicate on function: {:#?}", predicate)
+                    panic!("object safe predicate on function: {:#?}", predicate)
                 }
                 ty::PredicateAtom::ClosureKind(..) => {
-                    bug!("closure kind predicate on function: {:#?}", predicate)
+                    panic!("closure kind predicate on function: {:#?}", predicate)
                 }
                 ty::PredicateAtom::Subtype(_) => {
-                    bug!("subtype predicate on function: {:#?}", predicate)
+                    panic!("subtype predicate on function: {:#?}", predicate)
                 }
-                ty::PredicateAtom::Trait(pred, constness) => {
+                ty::PredicateAtom::Trait(pred, _) => {
                     if Some(pred.def_id()) == tcx.lang_items().sized_trait() {
                         continue;
                     }
                     match pred.self_ty().kind() {
                         ty::Param(ref p) => {
-                            // Allow `T: ?const Trait`
-                            if constness == hir::Constness::NotConst
-                                && feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out)
-                            {
-                                continue;
-                            }
-
                             let generics = tcx.generics_of(current);
                             let def = generics.type_param(p, tcx);
                             let span = tcx.def_span(def.def_id);
@@ -77,18 +62,17 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
     }
 
     for local in &body.local_decls {
-        check_ty(tcx, local.ty, local.source_info.span, def_id)?;
+        check_ty(tcx, local.ty, local.source_info.span)?;
     }
     // impl trait is gone in MIR, so check the return type manually
     check_ty(
         tcx,
         tcx.fn_sig(def_id).output().skip_binder(),
         body.local_decls.iter().next().unwrap().source_info.span,
-        def_id,
     )?;
 
     for bb in body.basic_blocks() {
-        check_terminator(tcx, body, def_id, bb.terminator())?;
+        check_terminator(tcx, body, bb.terminator())?;
         for stmt in &bb.statements {
             check_statement(tcx, body, def_id, stmt)?;
         }
@@ -96,7 +80,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
     Ok(())
 }
 
-fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> McfResult {
+fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span) -> McfResult {
     for arg in ty.walk() {
         let ty = match arg.unpack() {
             GenericArgKind::Type(ty) => ty,
@@ -108,15 +92,11 @@ fn check_ty(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, span: Span, fn_def_id: DefId) -> Mc
 
         match ty.kind() {
             ty::Ref(_, _, hir::Mutability::Mut) => {
-                if !feature_allowed(tcx, fn_def_id, sym::const_mut_refs) {
                     return Err((span, "mutable references in const fn are unstable".into()));
-                }
             }
             ty::Opaque(..) => return Err((span, "`impl Trait` in const fn is unstable".into())),
             ty::FnPtr(..) => {
-                if !tcx.const_fn_is_allowed_fn_ptr(fn_def_id) {
                     return Err((span, "function pointers in const fn are unstable".into()));
-                }
             }
             ty::Dynamic(preds, _) => {
                 for pred in preds.iter() {
@@ -161,12 +141,12 @@ fn check_rvalue(
             Err((span, "cannot access thread local storage in const fn".into()))
         }
         Rvalue::Repeat(operand, _) | Rvalue::Use(operand) => {
-            check_operand(tcx, operand, span, def_id, body)
+            check_operand(tcx, operand, span, body)
         }
         Rvalue::Len(place)
         | Rvalue::Discriminant(place)
         | Rvalue::Ref(_, _, place)
-        | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span, def_id, body),
+        | Rvalue::AddressOf(_, place) => check_place(tcx, *place, span,  body),
         Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
             use rustc_middle::ty::cast::CastTy;
             let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
@@ -175,14 +155,14 @@ fn check_rvalue(
                 (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
                     Err((span, "casting pointers to ints is unstable in const fn".into()))
                 }
-                _ => check_operand(tcx, operand, span, def_id, body),
+                _ => check_operand(tcx, operand, span, body),
             }
         }
         Rvalue::Cast(
             CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer),
             operand,
             _,
-        ) => check_operand(tcx, operand, span, def_id, body),
+        ) => check_operand(tcx, operand, span, body),
         Rvalue::Cast(
             CastKind::Pointer(
                 PointerCast::UnsafeFnPointer
@@ -204,7 +184,7 @@ fn check_rvalue(
             };
             let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id));
             if let ty::Slice(_) | ty::Str = unsized_ty.kind() {
-                check_operand(tcx, op, span, def_id, body)?;
+                check_operand(tcx, op, span, body)?;
                 // Casting/coercing things to slices is fine.
                 Ok(())
             } else {
@@ -214,8 +194,8 @@ fn check_rvalue(
         }
         // binops are fine on integers
         Rvalue::BinaryOp(_, lhs, rhs) | Rvalue::CheckedBinaryOp(_, lhs, rhs) => {
-            check_operand(tcx, lhs, span, def_id, body)?;
-            check_operand(tcx, rhs, span, def_id, body)?;
+            check_operand(tcx, lhs, span, body)?;
+            check_operand(tcx, rhs, span, body)?;
             let ty = lhs.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() || ty.is_char() {
                 Ok(())
@@ -230,14 +210,14 @@ fn check_rvalue(
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
             if ty.is_integral() || ty.is_bool() {
-                check_operand(tcx, operand, span, def_id, body)
+                check_operand(tcx, operand, span, body)
             } else {
                 Err((span, "only int and `bool` operations are stable in const fn".into()))
             }
         }
         Rvalue::Aggregate(_, operands) => {
             for operand in operands {
-                check_operand(tcx, operand, span, def_id, body)?;
+                check_operand(tcx, operand, span, body)?;
             }
             Ok(())
         }
@@ -253,15 +233,15 @@ fn check_statement(
     let span = statement.source_info.span;
     match &statement.kind {
         StatementKind::Assign(box (place, rval)) => {
-            check_place(tcx, *place, span, def_id, body)?;
+            check_place(tcx, *place, span,  body)?;
             check_rvalue(tcx, body, def_id, rval, span)
         }
 
-        StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, def_id, body),
+        StatementKind::FakeRead(_, place) => check_place(tcx, **place, span, body),
 
         // just an assignment
         StatementKind::SetDiscriminant { place, .. } => {
-            check_place(tcx, **place, span, def_id, body)
+            check_place(tcx, **place, span,  body)
         }
 
         StatementKind::LlvmInlineAsm { .. } => {
@@ -282,11 +262,10 @@ fn check_operand(
     tcx: TyCtxt<'tcx>,
     operand: &Operand<'tcx>,
     span: Span,
-    def_id: DefId,
     body: &Body<'tcx>,
 ) -> McfResult {
     match operand {
-        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, def_id, body),
+        Operand::Move(place) | Operand::Copy(place) => check_place(tcx, *place, span, body),
         Operand::Constant(c) => match c.check_static_ptr(tcx) {
             Some(_) => Err((span, "cannot access `static` items in const fn".into())),
             None => Ok(()),
@@ -298,7 +277,6 @@ fn check_place(
     tcx: TyCtxt<'tcx>,
     place: Place<'tcx>,
     span: Span,
-    def_id: DefId,
     body: &Body<'tcx>,
 ) -> McfResult {
     let mut cursor = place.projection.as_ref();
@@ -310,9 +288,7 @@ fn check_place(
                 if let Some(def) = base_ty.ty_adt_def() {
                     // No union field accesses in `const fn`
                     if def.is_union() {
-                        if !feature_allowed(tcx, def_id, sym::const_fn_union) {
                             return Err((span, "accessing union fields is unstable".into()));
-                        }
                     }
                 }
             }
@@ -327,48 +303,9 @@ fn check_place(
     Ok(())
 }
 
-/// 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 {
-    // 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) {
-        return false;
-    }
-
-    // If this crate is not using stability attributes, or this function is not claiming to be a
-    // stable `const fn`, that is all that is required.
-    if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
-        return true;
-    }
-
-    // However, we cannot allow stable `const fn`s to use unstable features without an explicit
-    // opt-in via `allow_internal_unstable`.
-    super::check_consts::allow_internal_unstable(tcx, def_id, feature_gate)
-}
-
-/// Returns `true` if the given library feature gate is allowed within the function with the given `DefId`.
-pub fn lib_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().declared_lib_features.iter().any(|&(sym, _)| sym == feature_gate) {
-        return false;
-    }
-
-    // If this crate is not using stability attributes, or this function is not claiming to be a
-    // stable `const fn`, that is all that is required.
-    if !tcx.features().staged_api || tcx.has_attr(def_id, sym::rustc_const_unstable) {
-        return true;
-    }
-
-    // However, we cannot allow stable `const fn`s to use unstable features without an explicit
-    // opt-in via `allow_internal_unstable`.
-    super::check_consts::allow_internal_unstable(tcx, def_id, feature_gate)
-}
-
 fn check_terminator(
     tcx: TyCtxt<'tcx>,
     body: &'a Body<'tcx>,
-    def_id: DefId,
     terminator: &Terminator<'tcx>,
 ) -> McfResult {
     let span = terminator.source_info.span;
@@ -380,14 +317,14 @@ fn check_terminator(
         | TerminatorKind::Resume
         | TerminatorKind::Unreachable => Ok(()),
 
-        TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span, def_id, body),
+        TerminatorKind::Drop { place, .. } => check_place(tcx, *place, span,  body),
         TerminatorKind::DropAndReplace { place, value, .. } => {
-            check_place(tcx, *place, span, def_id, body)?;
-            check_operand(tcx, value, span, def_id, body)
+            check_place(tcx, *place, span,  body)?;
+            check_operand(tcx, value, span, body)
         }
 
         TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => {
-            check_operand(tcx, discr, span, def_id, body)
+            check_operand(tcx, discr, span, body)
         }
 
         TerminatorKind::Abort => Err((span, "abort is not stable in const fn".into())),
@@ -405,15 +342,7 @@ fn check_terminator(
         } => {
             let fn_ty = func.ty(body, tcx);
             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)
-                                || lib_feature_allowed(tcx, def_id, feature)
-                        })
-                        .unwrap_or(false)
+                if !rustc_mir::const_eval::is_min_const_fn(tcx, fn_def_id)
                 {
                     return Err((
                         span,
@@ -432,7 +361,6 @@ fn check_terminator(
                 // transmutes in const fn before we add more hacks to this.
                 if tcx.fn_sig(fn_def_id).abi() == RustIntrinsic
                     && tcx.item_name(fn_def_id) == sym::transmute
-                    && !feature_allowed(tcx, def_id, sym::const_fn_transmute)
                 {
                     return Err((
                         span,
@@ -440,10 +368,10 @@ fn check_terminator(
                     ));
                 }
 
-                check_operand(tcx, func, span, fn_def_id, body)?;
+                check_operand(tcx, func, span, body)?;
 
                 for arg in args {
-                    check_operand(tcx, arg, span, fn_def_id, body)?;
+                    check_operand(tcx, arg, span, body)?;
                 }
                 Ok(())
             } else {
@@ -452,7 +380,7 @@ fn check_terminator(
         }
 
         TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => {
-            check_operand(tcx, cond, span, def_id, body)
+            check_operand(tcx, cond, span, body)
         }
 
         TerminatorKind::InlineAsm { .. } => {