From 83084a04a290aef6559efa95c067d9f03bbccff5 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Wed, 2 Dec 2020 13:22:09 +0100 Subject: [PATCH 1/2] change_lazy_normalization --- compiler/rustc_middle/src/ty/context.rs | 4 +-- .../rustc_trait_selection/src/traits/misc.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 5 ++-- .../src/traits/project.rs | 2 +- .../src/traits/select/confirmation.rs | 10 ++++++- .../src/traits/select/mod.rs | 28 +++++++++++++++++++ .../src/traits/specialize/mod.rs | 1 + compiler/rustc_typeck/src/collect.rs | 18 +----------- 8 files changed, 45 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index f078bbacfe96c..f5561bb48fea4 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1371,9 +1371,7 @@ impl<'tcx> TyCtxt<'tcx> { /// we still evaluate them eagerly. #[inline] pub fn lazy_normalization(self) -> bool { - let features = self.features(); - // Note: We do not enable lazy normalization for `features.min_const_generics`. - features.const_generics || features.lazy_normalization_consts + false } #[inline] diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index cedd1aa54b876..d2fde17e8e8f2 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -50,7 +50,7 @@ pub fn can_type_implement_copy( let span = tcx.def_span(field.did); let cause = ObligationCause::dummy_with_span(span); let ctx = traits::FulfillmentContext::new(); - match traits::fully_normalize(&infcx, ctx, cause, param_env, ty) { + match traits::fully_normalize(&infcx, ctx, false, cause, param_env, ty) { Ok(ty) => { if !infcx.type_is_copy_modulo_regions(param_env, ty, span) { infringing.push(field); diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index d6048d092b116..cfed68f64c4a4 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -224,7 +224,7 @@ fn do_normalize_predicates<'tcx>( // we move over to lazy normalization *anyway*. let fulfill_cx = FulfillmentContext::new_ignoring_regions(); let predicates = - match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) { + match fully_normalize(&infcx, fulfill_cx, true, cause, elaborated_env, predicates) { Ok(predicates) => predicates, Err(errors) => { infcx.report_fulfillment_errors(&errors, None, false); @@ -383,6 +383,7 @@ pub fn normalize_param_env_or_error<'tcx>( pub fn fully_normalize<'a, 'tcx, T>( infcx: &InferCtxt<'a, 'tcx>, mut fulfill_cx: FulfillmentContext<'tcx>, + lazy_normalization_consts: bool, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, value: T, @@ -391,7 +392,7 @@ where T: TypeFoldable<'tcx>, { debug!("fully_normalize_with_fulfillcx(value={:?})", value); - let selcx = &mut SelectionContext::new(infcx); + let selcx = &mut SelectionContext::with_lazy_normalization_consts(infcx, lazy_normalization_consts); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, param_env, cause, value); debug!( diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index df472e6ed7e9d..906654d579446 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -401,7 +401,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { } fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - if self.selcx.tcx().lazy_normalization() { + if self.selcx.lazy_normalization_consts() { constant } else { let constant = constant.super_fold_with(self); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index a42c802134649..e737acf85753d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -843,7 +843,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // by putting it in a query; it would only need the `DefId` as it // looks at declared field types, not anything substituted. for field in prefix_fields { - for arg in tcx.type_of(field.did).walk() { + let ty = normalize_with_depth_to( + self, + obligation.param_env, + obligation.cause.clone(), + obligation.recursion_depth + 1, + tcx.type_of(field.did), + &mut nested, + ); + for arg in ty.walk() { if let Some(i) = maybe_unsizing_param_idx(arg) { if unsizing_params.contains(i) { return Err(Unimplemented); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 74b6652981a8b..b9f93b123f334 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -120,6 +120,11 @@ pub struct SelectionContext<'cx, 'tcx> { /// would satisfy it. This avoids crippling inference, basically. intercrate: bool, + /// Whether we should lazily normalize constants, this is only true + /// while normalizing the predicates as evaluating constants would + /// cause a cycle error there. + lazy_normalization_consts: bool, + intercrate_ambiguity_causes: Option>, /// Controls whether or not to filter out negative impls when selecting. @@ -216,6 +221,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: false, + lazy_normalization_consts: false, intercrate_ambiguity_causes: None, allow_negative_impls: false, query_mode: TraitQueryMode::Standard, @@ -227,6 +233,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: true, + lazy_normalization_consts: false, intercrate_ambiguity_causes: None, allow_negative_impls: false, query_mode: TraitQueryMode::Standard, @@ -242,6 +249,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: false, + lazy_normalization_consts: false, intercrate_ambiguity_causes: None, allow_negative_impls, query_mode: TraitQueryMode::Standard, @@ -257,12 +265,32 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { infcx, freshener: infcx.freshener(), intercrate: false, + lazy_normalization_consts: false, intercrate_ambiguity_causes: None, allow_negative_impls: false, query_mode, } } + pub fn with_lazy_normalization_consts( + infcx: &'cx InferCtxt<'cx, 'tcx>, + lazy_normalization_consts: bool, + ) -> SelectionContext<'cx, 'tcx> { + SelectionContext { + infcx, + freshener: infcx.freshener(), + intercrate: false, + lazy_normalization_consts, + intercrate_ambiguity_causes: None, + allow_negative_impls: false, + query_mode: TraitQueryMode::Standard, + } + } + + pub fn lazy_normalization_consts(&self) -> bool { + self.lazy_normalization_consts + } + /// Enables tracking of intercrate ambiguity causes. These are /// used in coherence to give improved diagnostics. We don't do /// this until we detect a coherence error because it can lead to diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 0133a961c11a7..7b0847e98bbd7 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -156,6 +156,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId, let impl1_trait_ref = match traits::fully_normalize( &infcx, FulfillmentContext::new(), + false, ObligationCause::dummy(), penv, impl1_trait_ref, diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f8b7ccb2cd618..1f2d7bdf2564d 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1334,7 +1334,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // This affects both default type bindings, e.g. `struct()]>(T, U)`, // and the types of const parameters, e.g. `struct V();`. None - } else if tcx.lazy_normalization() { + } else { // HACK(eddyb) this provides the correct generics when // `feature(const_generics)` is enabled, so that const expressions // used with const generics, e.g. `Foo<{N+1}>`, can work at all. @@ -1342,22 +1342,6 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { // Note that we do not supply the parent generics when using // `feature(min_const_generics)`. Some(parent_def_id.to_def_id()) - } else { - let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id)); - match parent_node { - // HACK(eddyb) this provides the correct generics for repeat - // expressions' count (i.e. `N` in `[x; N]`), and explicit - // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), - // as they shouldn't be able to cause query cycle errors. - Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. }) - | Node::Variant(Variant { disr_expr: Some(ref constant), .. }) - if constant.hir_id == hir_id => - { - Some(parent_def_id.to_def_id()) - } - - _ => None, - } } } Node::Expr(&hir::Expr { kind: hir::ExprKind::Closure(..), .. }) => { From 653a713eb6eaece7abe4be09a725fe36d7b491ad Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 6 Dec 2020 17:44:28 +0100 Subject: [PATCH 2/2] tmp --- .../rustc_codegen_cranelift/src/constant.rs | 6 +- compiler/rustc_infer/src/infer/freshen.rs | 4 +- compiler/rustc_middle/src/ty/consts.rs | 63 ++++++++++++++++++- compiler/rustc_middle/src/ty/consts/kind.rs | 6 ++ compiler/rustc_middle/src/ty/flags.rs | 4 ++ compiler/rustc_middle/src/ty/mod.rs | 15 +++-- compiler/rustc_middle/src/ty/print/pretty.rs | 13 ++++ .../rustc_middle/src/ty/structural_impls.rs | 8 ++- compiler/rustc_middle/src/ty/walk.rs | 3 +- compiler/rustc_mir/src/interpret/operand.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 3 +- .../src/traits/select/mod.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 3 + 13 files changed, 116 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 544b020b71190..56e66d2bafdb8 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -66,7 +66,8 @@ pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, impl Module>) { | ConstKind::Infer(_) | ConstKind::Bound(_, _) | ConstKind::Placeholder(_) - | ConstKind::Error(_) => unreachable!("{:?}", const_), + | ConstKind::Error(_) + | ConstKind::Unnormalized(_, _) => unreachable!("{:?}", const_), } } } @@ -148,7 +149,8 @@ pub(crate) fn codegen_constant<'tcx>( | ConstKind::Infer(_) | ConstKind::Bound(_, _) | ConstKind::Placeholder(_) - | ConstKind::Error(_) => unreachable!("{:?}", const_), + | ConstKind::Error(_) + | ConstKind::Unnormalized(_, _) => unreachable!("{:?}", const_), }; codegen_const_value(fx, const_val, const_.ty) diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index b3d7876c6e819..3263ee716d0fc 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -243,7 +243,9 @@ impl<'a, 'tcx> TypeFolder<'tcx> for TypeFreshener<'a, 'tcx> { return ct; } - ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + ty::ConstKind::Bound(..) + | ty::ConstKind::Placeholder(_) + | ty::ConstKind::Unnormalized(_, _) => { bug!("unexpected const {:?}", ct) } diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 0af884a286d6e..775bdd1277c53 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,7 +1,7 @@ use crate::mir::interpret::ConstValue; use crate::mir::interpret::{LitToConstInput, Scalar}; use crate::ty::subst::InternalSubsts; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, TypeFolder, TypeFoldable}; use crate::ty::{ParamEnv, ParamEnvAnd}; use rustc_errors::ErrorReported; use rustc_hir as hir; @@ -97,10 +97,9 @@ impl<'tcx> Const<'tcx> { let name = tcx.hir().name(hir_id); ty::ConstKind::Param(ty::ParamConst::new(index, name)) } - _ => ty::ConstKind::Unevaluated( + _ => ty::ConstKind::Unnormalized( def.to_global(), InternalSubsts::identity_for_item(tcx, def.did.to_def_id()), - None, ), }; @@ -201,3 +200,61 @@ impl<'tcx> Const<'tcx> { .unwrap_or_else(|| bug!("expected usize, got {:#?}", self)) } } + +impl<'tcx> TyCtxt<'tcx> { + pub fn normalize_consts>(self, value: T) -> T { + value.fold_with(&mut ConstNormalizer::new(self)) + } +} + +pub struct ConstNormalizer<'tcx> { + tcx: TyCtxt<'tcx> +} + +impl ConstNormalizer<'_> { + pub fn new(tcx: TyCtxt<'_>) -> ConstNormalizer<'_> { + ConstNormalizer { tcx } + } +} + +impl<'tcx> TypeFolder<'tcx> for ConstNormalizer<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if t.flags().intersects(ty::TypeFlags::HAS_CT_UNNORMALIZED) { + t.super_fold_with(self) + } else { + t + } + } + + fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> { + match ct.val { + ConstKind::Unnormalized(def, substs) => { + match self.tcx.mir_abstract_const_opt_const_arg(def) { + // FIXME(const_evaluatable_checked): Replace the arguments not used + // in the abstract const with dummy ones while keeping everything that is + // used. + Ok(Some(_abstr_ct)) => self.tcx.mk_const(Const { + ty: ct.ty, + val: ConstKind::Unevaluated(def, substs, None) + }), + Ok(None) => { + let dummy_substs = InternalSubsts::for_item(self.tcx, def.did, |param, _| { + match param.kind { + ty::GenericParamDefKind::Lifetime => self.tcx.lifetimes.re_static.into(), + ty::GenericParamDefKind::Type { .. } => self.tcx.types.unit.into(), + ty::GenericParamDefKind::Const => self.tcx.consts.unit.into(), // TODO + } + }); + self.tcx.mk_const(Const { ty: ct.ty, val: ConstKind::Unevaluated(def, dummy_substs, None) }) + } + Err(_) => self.tcx.const_error(ct.ty), + } + } + _ => ct.super_fold_with(self), + } + } +} \ No newline at end of file diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ecf2837b3e423..d78f7ba22c956 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -25,6 +25,12 @@ pub enum ConstKind<'tcx> { /// A placeholder const - universally quantified higher-ranked const. Placeholder(ty::PlaceholderConst<'tcx>), + /// An unnormalized unevaluated constant. + /// + /// Converted into an unevaluated one as eagerly as possible. + /// The big exception being `type_of` and `predicates_of` where + /// typechecking a constant would cause a cycle error. + Unnormalized(ty::WithOptConstParam, SubstsRef<'tcx>), /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. Unevaluated(ty::WithOptConstParam, SubstsRef<'tcx>, Option), diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 8b97a87f214b8..f6a0524b549e7 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -281,6 +281,10 @@ impl FlagComputation { fn add_const(&mut self, c: &ty::Const<'_>) { self.add_ty(c.ty); match c.val { + ty::ConstKind::Unnormalized(_, substs) => { + self.add_substs(substs); + self.add_flags(TypeFlags::HAS_CT_PROJECTION | TypeFlags::HAS_CT_UNNORMALIZED); + } ty::ConstKind::Unevaluated(_, substs, _) => { self.add_substs(substs); self.add_flags(TypeFlags::HAS_CT_PROJECTION); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 5d8edcf70bfd3..9cab893456845 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -554,7 +554,7 @@ bitflags! { const HAS_TY_PROJECTION = 1 << 10; /// Does this have [Opaque]? const HAS_TY_OPAQUE = 1 << 11; - /// Does this have [ConstKind::Unevaluated]? + /// Does this have [ConstKind::Unevaluated] or [ConstKind::Unnormalized]? const HAS_CT_PROJECTION = 1 << 12; /// Could this type be normalized further? @@ -562,23 +562,26 @@ bitflags! { | TypeFlags::HAS_TY_OPAQUE.bits | TypeFlags::HAS_CT_PROJECTION.bits; + // Does this have [ConstKind::Unnormalized]? + const HAS_CT_UNNORMALIZED = 1 << 13; + /// Is an error type/const reachable? - const HAS_ERROR = 1 << 13; + const HAS_ERROR = 1 << 14; /// Does this have any region that "appears free" in the type? /// Basically anything but [ReLateBound] and [ReErased]. - const HAS_FREE_REGIONS = 1 << 14; + const HAS_FREE_REGIONS = 1 << 15; /// Does this have any [ReLateBound] regions? Used to check /// if a global bound is safe to evaluate. - const HAS_RE_LATE_BOUND = 1 << 15; + const HAS_RE_LATE_BOUND = 1 << 16; /// Does this have any [ReErased] regions? - const HAS_RE_ERASED = 1 << 16; + const HAS_RE_ERASED = 1 << 17; /// Does this value have parameters/placeholders/inference variables which could be /// replaced later, in a way that would change the results of `impl` specialization? - const STILL_FURTHER_SPECIALIZABLE = 1 << 17; + const STILL_FURTHER_SPECIALIZABLE = 1 << 18; } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 38f8e779f6a92..f0186cc6b74b5 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -899,6 +899,19 @@ pub trait PrettyPrinter<'tcx>: } match ct.val { + ty::ConstKind::Unnormalized(def, _) => { + assert_eq!(self.tcx().def_kind(def.did), DefKind::AnonConst); + if def.is_local() { + let span = self.tcx().def_span(def.did); + if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span) { + p!(write("{}", snip)) + } else { + print_underscore!() + } + } else { + print_underscore!() + } + } ty::ConstKind::Unevaluated(def, substs, promoted) => { if let Some(promoted) = promoted { p!(print_value_path(def.did, substs)); diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 94e69a93a6b18..57f73e3e0c730 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -1107,8 +1107,11 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { match self { ty::ConstKind::Infer(ic) => ty::ConstKind::Infer(ic.fold_with(folder)), ty::ConstKind::Param(p) => ty::ConstKind::Param(p.fold_with(folder)), - ty::ConstKind::Unevaluated(did, substs, promoted) => { - ty::ConstKind::Unevaluated(did, substs.fold_with(folder), promoted) + ty::ConstKind::Unevaluated(def, substs, promoted) => { + ty::ConstKind::Unevaluated(def, substs.fold_with(folder), promoted) + } + ty::ConstKind::Unnormalized(def, substs) => { + ty::ConstKind::Unnormalized(def, substs.fold_with(folder)) } ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) @@ -1122,6 +1125,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ConstKind<'tcx> { ty::ConstKind::Infer(ic) => ic.visit_with(visitor), ty::ConstKind::Param(p) => p.visit_with(visitor), ty::ConstKind::Unevaluated(_, substs, _) => substs.visit_with(visitor), + ty::ConstKind::Unnormalized(_, substs) => substs.visit_with(visitor), ty::ConstKind::Value(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 357a0dd65c414..8a4b7fc4841dd 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -195,7 +195,8 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {} - ty::ConstKind::Unevaluated(_, substs, _) => { + ty::ConstKind::Unevaluated(_, substs, _) + | ty::ConstKind::Unnormalized(_, substs) => { stack.extend(substs.iter().rev()); } } diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index d9437a312aec0..365b919ec28e4 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -549,7 +549,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let instance = self.resolve(def, substs)?; return Ok(self.eval_to_allocation(GlobalId { instance, promoted })?.into()); } - ty::ConstKind::Infer(..) | ty::ConstKind::Placeholder(..) => { + ty::ConstKind::Infer(..) + | ty::ConstKind::Placeholder(..) + | ty::ConstKind::Unnormalized(..) => { span_bug!(self.cur_span(), "const_to_op: Unexpected ConstKind {:?}", val) } ty::ConstKind::Value(val_val) => val_val, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index cfed68f64c4a4..04e366bafadc0 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -392,7 +392,8 @@ where T: TypeFoldable<'tcx>, { debug!("fully_normalize_with_fulfillcx(value={:?})", value); - let selcx = &mut SelectionContext::with_lazy_normalization_consts(infcx, lazy_normalization_consts); + let selcx = + &mut SelectionContext::with_lazy_normalization_consts(infcx, lazy_normalization_consts); let Normalized { value: normalized_value, obligations } = project::normalize(selcx, param_env, cause, value); debug!( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b9f93b123f334..3e9daab427512 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -289,7 +289,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn lazy_normalization_consts(&self) -> bool { self.lazy_normalization_consts - } + } /// Enables tracking of intercrate ambiguity causes. These are /// used in coherence to give improved diagnostics. We don't do diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 5bcb16d21e09c..d524b12aec461 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -428,6 +428,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { GenericArgKind::Const(constant) => { match constant.val { + ty::ConstKind::Unnormalized(_, _) => { + bug!("unexpected const in wf: {:?}", arg) + } ty::ConstKind::Unevaluated(def, substs, promoted) => { assert!(promoted.is_none());