]> git.lizzy.rs Git - rust.git/commitdiff
convert to future compat lint
authorBastian Kauschke <bastian_kauschke@hotmail.de>
Thu, 6 Aug 2020 08:48:36 +0000 (10:48 +0200)
committerBastian Kauschke <bastian_kauschke@hotmail.de>
Tue, 8 Sep 2020 14:39:12 +0000 (16:39 +0200)
compiler/rustc_session/src/lint/builtin.rs
src/librustc_trait_selection/traits/const_evaluatable.rs
src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
src/test/ui/enum-discriminant/issue-70453-polymorphic-ctfe.stderr
src/test/ui/lazy_normalization_consts/issue-73980.rs
src/test/ui/lazy_normalization_consts/issue-73980.stderr

index 2db4d2a7f51d999268035ababcd3adee2161a9ee..66497df66cad50b205380aa1c09eb70e856720b6 100644 (file)
     };
 }
 
+declare_lint! {
+    pub CONST_EVALUATABLE_UNCHECKED,
+    Warn,
+    "detects a generic constant is used in a type without a emitting a warning",
+    @future_incompatible = FutureIncompatibleInfo {
+        reference: "TODO",
+        edition: None,
+    };
+}
+
 declare_lint_pass! {
     /// Does nothing as a lint pass, but registers some `Lint`s
     /// that are used by other parts of the compiler.
         UNSAFE_OP_IN_UNSAFE_FN,
         INCOMPLETE_INCLUDE,
         CENUM_IMPL_DROP_CAST,
+        CONST_EVALUATABLE_UNCHECKED,
     ]
 }
 
index eb0e7f16fa37a82c172ded1c6446bb565b4aa32b..87762cc43a199e76c5ad5ce20803262e25e90a26 100644 (file)
@@ -1,10 +1,11 @@
-use rustc_middle::ty::{self, TypeFoldable};
+use rustc_hir::def::DefKind;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::subst::SubstsRef;
-use rustc_span::Span;
+use rustc_middle::ty::{self, TypeFoldable};
+use rustc_session::lint;
 use rustc_span::def_id::DefId;
-use rustc_middle::mir::interpret::ErrorHandled;
-use rustc_hir::def::DefKind;
+use rustc_span::Span;
 
 pub fn is_const_evaluatable<'cx, 'tcx>(
     infcx: &InferCtxt<'cx, 'tcx>,
@@ -12,8 +13,31 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
     substs: SubstsRef<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
     span: Span,
-) -> Result<(), ErrorHandled>
-{
+) -> Result<(), ErrorHandled> {
+    let future_compat_lint = || {
+        if let Some(local_def_id) = def.did.as_local() {
+            infcx.tcx.struct_span_lint_hir(
+                lint::builtin::CONST_EVALUATABLE_UNCHECKED,
+                infcx.tcx.hir().as_local_hir_id(local_def_id),
+                span,
+                |err| {
+                    err.build("cannot use constants which depend on generic parameters in types")
+                        .emit();
+                },
+            );
+        }
+    };
+
+    // FIXME: We should only try to evaluate a given constant here if it is fully concrete
+    // as we don't want to allow things like `[u8; std::mem::size_of::<*mut T>()]`.
+    //
+    // We previously did not check this, so we only emit a future compat warning if
+    // const evaluation succeeds and the given constant is still polymorphic for now
+    // and hopefully soon change this to an error.
+    //
+    // See #74595 for more details about this.
+    let concrete = infcx.const_eval_resolve(param_env, def, substs, None, Some(span));
+
     let def_kind = infcx.tcx.def_kind(def.did);
     match def_kind {
         DefKind::AnonConst => {
@@ -22,33 +46,16 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
             } else {
                 infcx.tcx.optimized_mir(def.did)
             };
-            if mir_body.is_polymorphic {
-                return Err(ErrorHandled::TooGeneric);
+            if mir_body.is_polymorphic && concrete.is_ok() {
+                future_compat_lint();
             }
         }
         _ => {
-            if substs.has_param_types_or_consts() {
-                return Err(ErrorHandled::TooGeneric);
+            if substs.has_param_types_or_consts() && concrete.is_ok() {
+                future_compat_lint();
             }
         }
     }
 
-    match infcx.const_eval_resolve(
-        param_env,
-        def,
-        substs,
-        None,
-        Some(span),
-    ) {
-        Ok(_) => Ok(()),
-        Err(err) => {
-            if matches!(err, ErrorHandled::TooGeneric) {
-                infcx.tcx.sess.delay_span_bug(
-                    span,
-                    &format!("ConstEvaluatable too generic: {:?}, {:?}, {:?}", def, substs, param_env),
-                );
-            }
-            Err(err)
-        }
-    }
-}
\ No newline at end of file
+    concrete.map(drop)
+}
index 5fe526df5a7417b0f7cb1c8d83dd6688db32d69b..cdc1db4c0b48203e3adfad7d21c1b263147db072 100644 (file)
@@ -1,3 +1,4 @@
+// run-pass
 #![feature(arbitrary_enum_discriminant, core_intrinsics)]
 
 extern crate core;
@@ -7,7 +8,8 @@
 enum MyWeirdOption<T> {
     None = 0,
     Some(T) = core::mem::size_of::<*mut T>(),
-    //~^ ERROR constant expression depends on a generic parameter
+    //~^ WARN cannot use constants which depend on generic parameters in types
+    //~| WARN this was previously accepted by the compiler but is being phased out
 }
 
 fn main() {
index 9aba2ea543f4c17e8f24d944508c6bea828751da..2aeb1b32bcb0a7c41b47dbb1239181ac86bbafe2 100644 (file)
@@ -1,10 +1,12 @@
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-70453-polymorphic-ctfe.rs:9:15
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/issue-70453-polymorphic-ctfe.rs:10:15
    |
 LL |     Some(T) = core::mem::size_of::<*mut T>(),
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: this may fail depending on what value the parameter takes
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see TODO
 
-error: aborting due to previous error
+warning: 1 warning emitted
 
index 2e4cb9ff7a8253d1fc0595efe73b56cc3853ac32..e10040652c78d36dbce7febd3c60b08c3f11d699 100644 (file)
@@ -1,3 +1,4 @@
+// check-pass
 #![feature(lazy_normalization_consts)]
 #![allow(incomplete_features)]
 
@@ -9,6 +10,7 @@ impl<T: ?Sized> L<T> {
 }
 
 impl<T> X<T, [u8; L::<T>::S]> {}
-//~^ ERROR constant expression depends on a generic parameter
+//~^ WARN cannot use constants which depend on generic parameters
+//~| WARN this was previously accepted by the compiler but is being phased out
 
 fn main() {}
index 5ca11bf55fc583da1fe152d38c84816739d215a3..8636407a3a102dc9bdc4519c17886994c165dbe2 100644 (file)
@@ -1,10 +1,12 @@
-error: constant expression depends on a generic parameter
-  --> $DIR/issue-73980.rs:11:9
+warning: cannot use constants which depend on generic parameters in types
+  --> $DIR/issue-73980.rs:12:9
    |
 LL | impl<T> X<T, [u8; L::<T>::S]> {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: this may fail depending on what value the parameter takes
+   = note: `#[warn(const_evaluatable_unchecked)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see TODO
 
-error: aborting due to previous error
+warning: 1 warning emitted