]> git.lizzy.rs Git - rust.git/commitdiff
`const_evaluatable_unchecked` to const eval
authorlcnr <rust@lcnr.de>
Tue, 18 Oct 2022 14:31:56 +0000 (16:31 +0200)
committerlcnr <rust@lcnr.de>
Tue, 18 Oct 2022 14:31:56 +0000 (16:31 +0200)
12 files changed:
compiler/rustc_middle/src/lib.rs
compiler/rustc_middle/src/mir/interpret/queries.rs
compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
src/test/ui/const-generics/generic_const_exprs/dependence_lint.full.stderr
src/test/ui/const-generics/generic_const_exprs/dependence_lint.gce.stderr
src/test/ui/const-generics/generic_const_exprs/dependence_lint.rs
src/test/ui/const-generics/generic_const_exprs/function-call.rs
src/test/ui/const-generics/generic_const_exprs/function-call.stderr
src/test/ui/const-generics/min_const_generics/complex-expression.rs
src/test/ui/const-generics/min_const_generics/complex-expression.stderr
src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.rs
src/test/ui/const-generics/min_const_generics/const-evaluatable-unchecked.stderr

index 45c84680ad298192c6b186d6473513a3e60eeba7..a58cbc3767ed658980878daebc399a2cb7a6d672 100644 (file)
@@ -55,6 +55,7 @@
 #![feature(drain_filter)]
 #![feature(intra_doc_pointers)]
 #![feature(yeet_expr)]
+#![feature(result_option_inspect)]
 #![feature(const_option)]
 #![recursion_limit = "512"]
 #![allow(rustc::potential_query_instability)]
index 8f67161420dad95ae4063eae999e81da397adf4c..1358425b259fa0ccde6d0555a7ccfe480cc59c43 100644 (file)
@@ -4,7 +4,9 @@
 use crate::ty::subst::InternalSubsts;
 use crate::ty::visit::TypeVisitable;
 use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt};
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
+use rustc_session::lint;
 use rustc_span::{Span, DUMMY_SP};
 
 impl<'tcx> TyCtxt<'tcx> {
@@ -83,7 +85,29 @@ pub fn const_eval_resolve_for_typeck(
         match ty::Instance::resolve_opt_const_arg(self, param_env, ct.def, ct.substs) {
             Ok(Some(instance)) => {
                 let cid = GlobalId { instance, promoted: None };
-                self.const_eval_global_id_for_typeck(param_env, cid, span)
+                self.const_eval_global_id_for_typeck(param_env, cid, span).inspect(|_| {
+                    // We are emitting the lint here instead of in `is_const_evaluatable`
+                    // as we normalize obligations before checking them, and normalization
+                    // uses this function to evaluate this constant.
+                    //
+                    // @lcnr believes that successfully evaluating even though there are
+                    // used generic parameters is a bug of evaluation, so checking for it
+                    // here does feel somewhat sensible.
+                    if !self.features().generic_const_exprs && ct.substs.has_non_region_param() {
+                        assert!(matches!(self.def_kind(ct.def.did), DefKind::AnonConst));
+                        let mir_body = self.mir_for_ctfe_opt_const_arg(ct.def);
+                        if mir_body.is_polymorphic {
+                            let Some(local_def_id) = ct.def.did.as_local() else { return };
+                            self.struct_span_lint_hir(
+                                lint::builtin::CONST_EVALUATABLE_UNCHECKED,
+                                self.hir().local_def_id_to_hir_id(local_def_id),
+                                self.def_span(ct.def.did),
+                                "cannot use constants which depend on generic parameters in types",
+                                |err| err,
+                            )
+                        }
+                    }
+                })
             }
             Ok(None) => Err(ErrorHandled::TooGeneric),
             Err(error_reported) => Err(ErrorHandled::Reported(error_reported)),
index 2e5a607a9808ac953a590c95e65c9e7e37278f6d..84038625fb2792038f5243d02584f737d34645b2 100644 (file)
@@ -9,14 +9,12 @@
 //! `thir_abstract_const` which can then be checked for structural equality with other
 //! generic constants mentioned in the `caller_bounds` of the current environment.
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir::def::DefKind;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::abstract_const::{
     walk_abstract_const, AbstractConst, FailureKind, Node, NotConstEvaluatable,
 };
 use rustc_middle::ty::{self, TyCtxt, TypeVisitable};
-use rustc_session::lint;
 use rustc_span::Span;
 
 use std::iter;
@@ -262,25 +260,7 @@ pub fn is_const_evaluatable<'tcx>(
                 Err(NotConstEvaluatable::Error(reported))
             }
             Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
-            Ok(_) => {
-                if uv.substs.has_non_region_param() {
-                    assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
-                    let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
-
-                    if mir_body.is_polymorphic {
-                        let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
-                        tcx.struct_span_lint_hir(
-                            lint::builtin::CONST_EVALUATABLE_UNCHECKED,
-                            tcx.hir().local_def_id_to_hir_id(local_def_id),
-                            span,
-                            "cannot use constants which depend on generic parameters in types",
-                            |err| err
-                        )
-                    }
-                }
-
-                Ok(())
-            },
+            Ok(_) => Ok(()),
         }
     }
 }
index 828f0988a039f7b4b045d71bcbe687b482db11a0..d674e3acdffde4bfd4a7463648e3f27908098ee3 100644 (file)
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/dependence_lint.rs:13:32
+  --> $DIR/dependence_lint.rs:14:32
    |
 LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |                                ^ cannot perform const operation using `T`
@@ -8,7 +8,7 @@ LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/dependence_lint.rs:20:37
+  --> $DIR/dependence_lint.rs:21:37
    |
 LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
    |                                     ^ cannot perform const operation using `T`
@@ -17,7 +17,7 @@ LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/dependence_lint.rs:9:9
+  --> $DIR/dependence_lint.rs:10:9
    |
 LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
    |         ^^^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_
    = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/dependence_lint.rs:16:9
+  --> $DIR/dependence_lint.rs:17:9
    |
 LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
index b13bcdb2c4786f392f2bc6004561ef02b2a5df0d..74111ef1d38cd28f321fc5211fd804be504bbdbf 100644 (file)
@@ -1,5 +1,5 @@
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:16:9
+  --> $DIR/dependence_lint.rs:17:9
    |
 LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error with gce
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
@@ -7,7 +7,7 @@ LL |     [0; if false { size_of::<T>() } else { 3 }]; // lint on stable, error w
    = help: consider moving this anonymous constant into a `const` function
 
 error: overly complex generic constant
-  --> $DIR/dependence_lint.rs:20:17
+  --> $DIR/dependence_lint.rs:21:17
    |
 LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable, error with gce
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ control flow is not supported in generic constants
@@ -15,7 +15,7 @@ LL |     let _: [u8; if true { size_of::<T>() } else { 3 }]; // error on stable,
    = help: consider moving this anonymous constant into a `const` function
 
 error: unconstrained generic constant
-  --> $DIR/dependence_lint.rs:13:12
+  --> $DIR/dependence_lint.rs:14:12
    |
 LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     let _: [u8; size_of::<*mut T>()]; // error on stable, error with gce
    = help: try adding a `where` bound using this expression: `where [(); size_of::<*mut T>()]:`
 
 error: unconstrained generic constant
-  --> $DIR/dependence_lint.rs:9:9
+  --> $DIR/dependence_lint.rs:10:9
    |
 LL |     [0; size_of::<*mut T>()]; // lint on stable, error with `generic_const_exprs`
    |         ^^^^^^^^^^^^^^^^^^^
index dcdfd75def9063c2b635867e9db06526e3331ea0..b715e07f8fa006158d572beef23ca776d66ced39 100644 (file)
@@ -1,4 +1,5 @@
 // revisions: full gce
+// compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![cfg_attr(gce, feature(generic_const_exprs))]
 #![allow(incomplete_features)]
index b5de66621c50ee950cd6b1640a5d877ddeb226ba..3c866333d60968ca84eea059b458447d9047c8e7 100644 (file)
@@ -1,4 +1,5 @@
 // check-pass
+// compile-flags: -Zdeduplicate-diagnostics=yes
 
 const fn foo<T>() -> usize {
     // We might instead branch on `std::mem::size_of::<*mut T>() < 8` here,
index 796dc01043cd89afddf339bf970600d09d185424..84abfe57876cd12b105eb93146e1ec8a4a0f8263 100644 (file)
@@ -1,5 +1,5 @@
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/function-call.rs:14:17
+  --> $DIR/function-call.rs:15:17
    |
 LL |     let _ = [0; foo::<T>()];
    |                 ^^^^^^^^^^
index 7840989cb0814c156799f76b4a1f7bc919ecc313..8e667aebaadc2bcdca048661bfda021fb9916a72 100644 (file)
@@ -1,3 +1,4 @@
+// compile-flags: -Zdeduplicate-diagnostics=yes
 use std::mem::size_of;
 
 fn test<const N: usize>() {}
index 0b051c6131b85bf2f75f0fb534706865c5b52654..deabd05a6d5b0807af86d048978dfdccdf37dbbc 100644 (file)
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:9:38
+  --> $DIR/complex-expression.rs:10:38
    |
 LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    |                                      ^ cannot perform const operation using `N`
@@ -8,7 +8,7 @@ LL | struct Break0<const N: usize>([u8; { N + 1 }]);
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:12:40
+  --> $DIR/complex-expression.rs:13:40
    |
 LL | struct Break1<const N: usize>([u8; { { N } }]);
    |                                        ^ cannot perform const operation using `N`
@@ -17,7 +17,7 @@ LL | struct Break1<const N: usize>([u8; { { N } }]);
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:16:17
+  --> $DIR/complex-expression.rs:17:17
    |
 LL |     let _: [u8; N + 1];
    |                 ^ cannot perform const operation using `N`
@@ -26,7 +26,7 @@ LL |     let _: [u8; N + 1];
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:21:17
+  --> $DIR/complex-expression.rs:22:17
    |
 LL |     let _ = [0; N + 1];
    |                 ^ cannot perform const operation using `N`
@@ -35,7 +35,7 @@ LL |     let _ = [0; N + 1];
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:25:45
+  --> $DIR/complex-expression.rs:26:45
    |
 LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
    |                                             ^ cannot perform const operation using `T`
@@ -44,7 +44,7 @@ LL | struct BreakTy0<T>(T, [u8; { size_of::<*mut T>() }]);
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:28:47
+  --> $DIR/complex-expression.rs:29:47
    |
 LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
    |                                               ^ cannot perform const operation using `T`
@@ -53,7 +53,7 @@ LL | struct BreakTy1<T>(T, [u8; { { size_of::<*mut T>() } }]);
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/complex-expression.rs:32:32
+  --> $DIR/complex-expression.rs:33:32
    |
 LL |     let _: [u8; size_of::<*mut T>() + 1];
    |                                ^ cannot perform const operation using `T`
@@ -62,7 +62,7 @@ LL |     let _: [u8; size_of::<*mut T>() + 1];
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/complex-expression.rs:37:17
+  --> $DIR/complex-expression.rs:38:17
    |
 LL |     let _ = [0; size_of::<*mut T>() + 1];
    |                 ^^^^^^^^^^^^^^^^^^^^^^^
index 71d13ca61c9b3bfc634166ee31a47c4088933eaf..e9d868093e7698b2b0e492eacd3c0147bb8cc33e 100644 (file)
@@ -1,4 +1,5 @@
 // check-pass
+// compile-flags: -Zdeduplicate-diagnostics=yes
 #![allow(dead_code)]
 
 fn foo<T>() {
index f0ba7a39d1eafc7555b3ce512cc651276b788870..8003dfa4071721eea15438a768b3385aa753e22f 100644 (file)
@@ -1,5 +1,5 @@
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:5:9
+  --> $DIR/const-evaluatable-unchecked.rs:6:9
    |
 LL |     [0; std::mem::size_of::<*mut T>()];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     [0; std::mem::size_of::<*mut T>()];
    = note: `#[warn(const_evaluatable_unchecked)]` on by default
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:16:21
+  --> $DIR/const-evaluatable-unchecked.rs:17:21
    |
 LL |         let _ = [0; Self::ASSOC];
    |                     ^^^^^^^^^^^
@@ -18,7 +18,7 @@ LL |         let _ = [0; Self::ASSOC];
    = note: for more information, see issue #76200 <https://github.com/rust-lang/rust/issues/76200>
 
 warning: cannot use constants which depend on generic parameters in types
-  --> $DIR/const-evaluatable-unchecked.rs:28:21
+  --> $DIR/const-evaluatable-unchecked.rs:29:21
    |
 LL |         let _ = [0; Self::ASSOC];
    |                     ^^^^^^^^^^^