about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-08-06 10:00:08 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-09-08 16:39:12 +0200
commitc81935e6dfd3877db266f0a01d9323f203f92eda (patch)
treede33a2c05acad8b98b4318a8f29e3c42de870c02 /compiler
parent7bc0bf72545f5d6ac6d9639391da875d5e147d9a (diff)
downloadrust-c81935e6dfd3877db266f0a01d9323f203f92eda.tar.gz
rust-c81935e6dfd3877db266f0a01d9323f203f92eda.zip
make `ConstEvaluatable` more strict
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs27
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs20
4 files changed, 45 insertions, 21 deletions
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 96e2a0ba618..197e8dd5341 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -186,6 +186,19 @@ pub struct Body<'tcx> {
     /// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components.
     pub ignore_interior_mut_in_const_validation: bool,
 
+    /// Does this body use generic parameters. This is used for the `ConstEvaluatable` check.
+    ///
+    /// Note that this does not actually mean that this body is not computable right now.
+    /// The repeat count in the following example is polymorphic, but can still be evaluated
+    /// without knowing anything about the type parameter `T`.
+    ///
+    /// ```rust
+    /// fn test<T>() {
+    ///     let _ = [0; std::mem::size_of::<*mut T>()];
+    /// }
+    /// ```
+    pub is_polymorphic: bool,
+
     predecessor_cache: PredecessorCache,
 }
 
@@ -208,7 +221,7 @@ impl<'tcx> Body<'tcx> {
             local_decls.len()
         );
 
-        Body {
+        let mut body = Body {
             phase: MirPhase::Build,
             basic_blocks,
             source_scopes,
@@ -224,8 +237,11 @@ impl<'tcx> Body<'tcx> {
             span,
             required_consts: Vec::new(),
             ignore_interior_mut_in_const_validation: false,
+            is_polymorphic: false,
             predecessor_cache: PredecessorCache::new(),
-        }
+        };
+        body.is_polymorphic = body.has_param_types_or_consts();
+        body
     }
 
     /// Returns a partially initialized MIR body containing only a list of basic blocks.
@@ -234,7 +250,7 @@ impl<'tcx> Body<'tcx> {
     /// is only useful for testing but cannot be `#[cfg(test)]` because it is used in a different
     /// crate.
     pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
-        Body {
+        let mut body = Body {
             phase: MirPhase::Build,
             basic_blocks,
             source_scopes: IndexVec::new(),
@@ -250,8 +266,11 @@ impl<'tcx> Body<'tcx> {
             generator_kind: None,
             var_debug_info: Vec::new(),
             ignore_interior_mut_in_const_validation: false,
+            is_polymorphic: false,
             predecessor_cache: PredecessorCache::new(),
-        }
+        };
+        body.is_polymorphic = body.has_param_types_or_consts();
+        body
     }
 
     #[inline]
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index a5c6dc042ab..989c6e6dbc2 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -10,6 +10,7 @@ use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
 use std::marker::PhantomData;
 
+use super::const_evaluatable;
 use super::project;
 use super::select::SelectionContext;
 use super::wf;
@@ -458,16 +459,17 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
                 }
 
                 ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
-                    match self.selcx.infcx().const_eval_resolve(
-                        obligation.param_env,
+                    const_evaluatable::is_const_evaluatable(
+                        self.selcx.infcx(),
                         def_id,
                         substs,
-                        None,
-                        Some(obligation.cause.span),
-                    ) {
-                        Ok(_) => ProcessResult::Changed(vec![]),
-                        Err(err) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(err))),
-                    }
+                        obligation.param_env,
+                        obligation.cause.span,
+                    )
+                    .map_or_else(
+                        |e| ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))),
+                        |()| ProcessResult::Changed(vec![]),
+                    )
                 }
 
                 ty::PredicateAtom::ConstEquate(c1, c2) => {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index fe406e88c52..49dac873cde 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -7,6 +7,7 @@ pub mod auto_trait;
 mod chalk_fulfill;
 pub mod codegen;
 mod coherence;
+mod const_evaluatable;
 mod engine;
 pub mod error_reporting;
 mod fulfill;
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 4258d8e3010..5a1e1eb89a6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -6,6 +6,7 @@ use self::EvaluationResult::*;
 use self::SelectionCandidate::*;
 
 use super::coherence::{self, Conflict};
+use super::const_evaluatable;
 use super::project;
 use super::project::normalize_with_depth_to;
 use super::util;
@@ -542,17 +543,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
 
             ty::PredicateAtom::ConstEvaluatable(def_id, substs) => {
-                match self.tcx().const_eval_resolve(
-                    obligation.param_env,
+                const_evaluatable::is_const_evaluatable(
+                    self.infcx,
                     def_id,
                     substs,
-                    None,
-                    None,
-                ) {
-                    Ok(_) => Ok(EvaluatedToOk),
-                    Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig),
-                    Err(_) => Ok(EvaluatedToErr),
-                }
+                    obligation.param_env,
+                    obligation.cause.span,
+                )
+                .map(|()| EvaluatedToOk)
+                .or_else(|e| match e {
+                    ErrorHandled::TooGeneric => Ok(EvaluatedToAmbig),
+                    _ => Ok(EvaluatedToErr),
+                })
             }
 
             ty::PredicateAtom::ConstEquate(c1, c2) => {