diff options
| -rw-r--r-- | src/librustc_middle/ty/mod.rs | 26 | ||||
| -rw-r--r-- | src/librustc_middle/ty/sty.rs | 19 | ||||
| -rw-r--r-- | src/librustc_typeck/astconv.rs | 10 | ||||
| -rw-r--r-- | src/librustc_typeck/check/method/confirm.rs | 2 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 20 |
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!(), }, |
