about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_middle/ty/mod.rs26
-rw-r--r--src/librustc_middle/ty/sty.rs19
-rw-r--r--src/librustc_typeck/astconv.rs10
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs20
5 files changed, 67 insertions, 10 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index bec1200d7aa..f8a205084de 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1571,6 +1571,32 @@ pub type PlaceholderType = Placeholder<BoundVar>;
 
 pub type PlaceholderConst = Placeholder<BoundVar>;
 
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Hash, HashStable)]
+pub struct WithOptParam<T> {
+    pub did: T,
+    pub param_did: Option<DefId>,
+}
+
+impl<T> WithOptParam<T> {
+    pub fn dummy(did: T) -> WithOptParam<T> {
+        WithOptParam { did, param_did: None }
+    }
+}
+
+impl WithOptParam<LocalDefId> {
+    pub fn ty_def_id(self) -> DefId {
+        if let Some(did) = self.param_did { did } else { self.did.to_def_id() }
+    }
+}
+
+impl WithOptParam<DefId> {
+    pub fn ty_def_id(self) -> DefId {
+        self.param_did.unwrap_or(self.did)
+    }
+}
+
 /// When type checking, we use the `ParamEnv` to track
 /// details about the set of where-clauses that are in scope at this
 /// particular point.
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index c7683cefd82..6326068905d 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -2210,21 +2210,28 @@ impl<'tcx> Const<'tcx> {
     /// Literals and const generic parameters are eagerly converted to a constant, everything else
     /// becomes `Unevaluated`.
     pub fn from_anon_const(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx Self {
-        debug!("Const::from_anon_const(id={:?})", def_id);
+        Self::const_arg_from_anon_const(tcx, ty::WithOptParam::dummy(def_id))
+    }
+
+    pub fn const_arg_from_anon_const(
+        tcx: TyCtxt<'tcx>,
+        def: ty::WithOptParam<LocalDefId>,
+    ) -> &'tcx Self {
+        debug!("Const::from_anon_const(def={:?})", def);
 
-        let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
+        let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
 
         let body_id = match tcx.hir().get(hir_id) {
             hir::Node::AnonConst(ac) => ac.body,
             _ => span_bug!(
-                tcx.def_span(def_id.to_def_id()),
+                tcx.def_span(def.did.to_def_id()),
                 "from_anon_const can only process anonymous constants"
             ),
         };
 
         let expr = &tcx.hir().body(body_id).value;
 
-        let ty = tcx.type_of(def_id.to_def_id());
+        let ty = tcx.type_of(def.ty_def_id());
 
         let lit_input = match expr.kind {
             hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
@@ -2271,8 +2278,8 @@ impl<'tcx> Const<'tcx> {
                 ty::ConstKind::Param(ty::ParamConst::new(index, name))
             }
             _ => ty::ConstKind::Unevaluated(
-                def_id.to_def_id(),
-                InternalSubsts::identity_for_item(tcx, def_id.to_def_id()),
+                def.did.to_def_id(),
+                InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
                 None,
             ),
         };
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 616f5d90395..eeb14352ca0 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -886,8 +886,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     }
                 }
                 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
-                    let ct_def_id = tcx.hir().local_def_id(ct.value.hir_id);
-                    ty::Const::from_anon_const(tcx, ct_def_id).into()
+                    ty::Const::const_arg_from_anon_const(
+                        tcx,
+                        ty::WithOptParam {
+                            did: tcx.hir().local_def_id(ct.value.hir_id),
+                            param_did: Some(param.def_id),
+                        },
+                    )
+                    .into()
                 }
                 _ => unreachable!(),
             },
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 1c3d23a3a24..0ca85b5165e 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -325,7 +325,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 }
                 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => self.to_ty(ty).into(),
                 (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
-                    self.to_const(&ct.value).into()
+                    self.const_arg_to_const(&ct.value, param.def_id).into()
                 }
                 _ => unreachable!(),
             },
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index bc01da324b6..56f751e000b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3542,6 +3542,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         c
     }
 
+    pub fn const_arg_to_const(
+        &self,
+        ast_c: &hir::AnonConst,
+        param_def_id: DefId,
+    ) -> &'tcx ty::Const<'tcx> {
+        let const_def = ty::WithOptParam {
+            did: self.tcx.hir().local_def_id(ast_c.hir_id),
+            param_did: Some(param_def_id),
+        };
+        let c = ty::Const::const_arg_from_anon_const(self.tcx, const_def);
+        self.register_wf_obligation(
+            c.into(),
+            self.tcx.hir().span(ast_c.hir_id),
+            ObligationCauseCode::MiscObligation,
+        );
+        c
+    }
+
     // If the type given by the user has free regions, save it for later, since
     // NLL would like to enforce those. Also pass in types that involve
     // projections, since those can resolve to `'static` bounds (modulo #54940,
@@ -5655,7 +5673,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         self.to_ty(ty).into()
                     }
                     (GenericParamDefKind::Const, GenericArg::Const(ct)) => {
-                        self.to_const(&ct.value).into()
+                        self.const_arg_to_const(&ct.value, param.def_id).into()
                     }
                     _ => unreachable!(),
                 },