diff options
| author | bors <bors@rust-lang.org> | 2022-07-22 12:48:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-22 12:48:29 +0000 |
| commit | 22d25f21dc008785f52e7c2833de4f4236b1066b (patch) | |
| tree | a0889b431c8ff50d97957efce13bde8f21d91649 /compiler | |
| parent | 41419e70366962c9a878bfe673ef4df38db6f7f1 (diff) | |
| parent | a0ebb2ed8b59e8eec9add6acda0673dcf468596f (diff) | |
| download | rust-22d25f21dc008785f52e7c2833de4f4236b1066b.tar.gz rust-22d25f21dc008785f52e7c2833de4f4236b1066b.zip | |
Auto merge of #99521 - fee1-dead-contrib:const_fix_hax, r=oli-obk
Fix hack that remaps env constness. WARNING: might have perf implications. Are there any more problems with having a constness in the `ParamEnv` now? :) r? `@oli-obk`
Diffstat (limited to 'compiler')
4 files changed, 45 insertions, 51 deletions
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4346dbdb16b..281a1265546 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -575,6 +575,19 @@ impl<'tcx> Predicate<'tcx> { Some(tcx.mk_predicate(kind)) } + + pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self { + if let PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) = self.kind().skip_binder() + && constness != BoundConstness::NotConst + { + self = tcx.mk_predicate(self.kind().rebind(PredicateKind::Trait(TraitPredicate { + trait_ref, + constness: BoundConstness::NotConst, + polarity, + }))); + } + self + } } impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index 56bdeafeeca..8148e2b7871 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -31,14 +31,14 @@ pub(crate) fn update<'tcx, T>( obligation .predicate .kind() - .map_bound(|_| { + .rebind( // (*) binder moved here ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: tpred.constness, polarity: tpred.polarity, }) - }) + ) .to_predicate(infcx.tcx), ); // Don't report overflow errors. Otherwise equivalent to may_hold. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index da8ca6e5749..d4c9fd1c5f9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -42,115 +42,96 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation: &TraitObligation<'tcx>, candidate: SelectionCandidate<'tcx>, ) -> Result<Selection<'tcx>, SelectionError<'tcx>> { - let mut obligation = obligation; - let new_obligation; - - // HACK(const_trait_impl): the surrounding environment is remapped to a non-const context - // because nested obligations might be actually `~const` then (incorrectly) requiring - // const impls. for example: - // ``` - // pub trait Super {} - // pub trait Sub: Super {} - // - // impl<A> const Super for &A where A: ~const Super {} - // impl<A> const Sub for &A where A: ~const Sub {} - // ``` - // - // The procedure to check the code above without the remapping code is as follows: - // ``` - // CheckWf(impl const Sub for &A where A: ~const Sub) // <- const env - // CheckPredicate(&A: Super) - // CheckPredicate(A: ~const Super) // <- still const env, failure - // ``` - if obligation.param_env.is_const() && !obligation.predicate.is_const_if_const() { - new_obligation = TraitObligation { - cause: obligation.cause.clone(), - param_env: obligation.param_env.without_const(), - ..*obligation - }; - obligation = &new_obligation; - } - - match candidate { + let mut impl_src = match candidate { BuiltinCandidate { has_nested } => { let data = self.confirm_builtin_candidate(obligation, has_nested); - Ok(ImplSource::Builtin(data)) + ImplSource::Builtin(data) } ParamCandidate(param) => { let obligations = self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref)); - Ok(ImplSource::Param(obligations, param.skip_binder().constness)) + ImplSource::Param(obligations, param.skip_binder().constness) } ImplCandidate(impl_def_id) => { - Ok(ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))) + ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id)) } AutoImplCandidate(trait_def_id) => { let data = self.confirm_auto_impl_candidate(obligation, trait_def_id); - Ok(ImplSource::AutoImpl(data)) + ImplSource::AutoImpl(data) } ProjectionCandidate(idx) => { let obligations = self.confirm_projection_candidate(obligation, idx)?; // FIXME(jschievink): constness - Ok(ImplSource::Param(obligations, ty::BoundConstness::NotConst)) + ImplSource::Param(obligations, ty::BoundConstness::NotConst) } ObjectCandidate(idx) => { let data = self.confirm_object_candidate(obligation, idx)?; - Ok(ImplSource::Object(data)) + ImplSource::Object(data) } ClosureCandidate => { let vtable_closure = self.confirm_closure_candidate(obligation)?; - Ok(ImplSource::Closure(vtable_closure)) + ImplSource::Closure(vtable_closure) } GeneratorCandidate => { let vtable_generator = self.confirm_generator_candidate(obligation)?; - Ok(ImplSource::Generator(vtable_generator)) + ImplSource::Generator(vtable_generator) } FnPointerCandidate { .. } => { let data = self.confirm_fn_pointer_candidate(obligation)?; - Ok(ImplSource::FnPointer(data)) + ImplSource::FnPointer(data) } DiscriminantKindCandidate => { - Ok(ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)) + ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) } - PointeeCandidate => Ok(ImplSource::Pointee(ImplSourcePointeeData)), + PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData), TraitAliasCandidate(alias_def_id) => { let data = self.confirm_trait_alias_candidate(obligation, alias_def_id); - Ok(ImplSource::TraitAlias(data)) + ImplSource::TraitAlias(data) } BuiltinObjectCandidate => { // This indicates something like `Trait + Send: Send`. In this case, we know that // this holds because that's what the object type is telling us, and there's really // no additional obligations to prove and no types in particular to unify, etc. - Ok(ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst)) + ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst) } BuiltinUnsizeCandidate => { let data = self.confirm_builtin_unsize_candidate(obligation)?; - Ok(ImplSource::Builtin(data)) + ImplSource::Builtin(data) } TraitUpcastingUnsizeCandidate(idx) => { let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?; - Ok(ImplSource::TraitUpcasting(data)) + ImplSource::TraitUpcasting(data) } ConstDestructCandidate(def_id) => { let data = self.confirm_const_destruct_candidate(obligation, def_id)?; - Ok(ImplSource::ConstDestruct(data)) + ImplSource::ConstDestruct(data) } + }; + + if !obligation.predicate.is_const_if_const() { + // normalize nested predicates according to parent predicate's constness. + impl_src = impl_src.map(|mut o| { + o.predicate = o.predicate.without_const(self.tcx()); + o + }); } + + Ok(impl_src) } fn confirm_projection_candidate( diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs index 1681e6af812..2005fc24ed0 100644 --- a/compiler/rustc_typeck/src/check/closure.rs +++ b/compiler/rustc_typeck/src/check/closure.rs @@ -182,9 +182,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::PredicateKind::Projection(proj_predicate) => self .deduce_sig_from_projection( Some(span.0), - pred.0.kind().rebind( - pred.map_bound(|_| proj_predicate).subst(self.tcx, substs), - ), + pred.0 + .kind() + .rebind(pred.rebind(proj_predicate).subst(self.tcx, substs)), ), _ => None, }); |
