Skip to content

Commit 22d25f2

Browse files
committed
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`
2 parents 41419e7 + a0ebb2e commit 22d25f2

File tree

6 files changed

+46
-67
lines changed

6 files changed

+46
-67
lines changed

compiler/rustc_middle/src/ty/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,19 @@ impl<'tcx> Predicate<'tcx> {
575575

576576
Some(tcx.mk_predicate(kind))
577577
}
578+
579+
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self {
580+
if let PredicateKind::Trait(TraitPredicate { trait_ref, constness, polarity }) = self.kind().skip_binder()
581+
&& constness != BoundConstness::NotConst
582+
{
583+
self = tcx.mk_predicate(self.kind().rebind(PredicateKind::Trait(TraitPredicate {
584+
trait_ref,
585+
constness: BoundConstness::NotConst,
586+
polarity,
587+
})));
588+
}
589+
self
590+
}
578591
}
579592

580593
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {

compiler/rustc_trait_selection/src/traits/relationships.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ pub(crate) fn update<'tcx, T>(
3131
obligation
3232
.predicate
3333
.kind()
34-
.map_bound(|_| {
34+
.rebind(
3535
// (*) binder moved here
3636
ty::PredicateKind::Trait(ty::TraitPredicate {
3737
trait_ref,
3838
constness: tpred.constness,
3939
polarity: tpred.polarity,
4040
})
41-
})
41+
)
4242
.to_predicate(infcx.tcx),
4343
);
4444
// Don't report overflow errors. Otherwise equivalent to may_hold.

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+27-46
Original file line numberDiff line numberDiff line change
@@ -42,115 +42,96 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4242
obligation: &TraitObligation<'tcx>,
4343
candidate: SelectionCandidate<'tcx>,
4444
) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
45-
let mut obligation = obligation;
46-
let new_obligation;
47-
48-
// HACK(const_trait_impl): the surrounding environment is remapped to a non-const context
49-
// because nested obligations might be actually `~const` then (incorrectly) requiring
50-
// const impls. for example:
51-
// ```
52-
// pub trait Super {}
53-
// pub trait Sub: Super {}
54-
//
55-
// impl<A> const Super for &A where A: ~const Super {}
56-
// impl<A> const Sub for &A where A: ~const Sub {}
57-
// ```
58-
//
59-
// The procedure to check the code above without the remapping code is as follows:
60-
// ```
61-
// CheckWf(impl const Sub for &A where A: ~const Sub) // <- const env
62-
// CheckPredicate(&A: Super)
63-
// CheckPredicate(A: ~const Super) // <- still const env, failure
64-
// ```
65-
if obligation.param_env.is_const() && !obligation.predicate.is_const_if_const() {
66-
new_obligation = TraitObligation {
67-
cause: obligation.cause.clone(),
68-
param_env: obligation.param_env.without_const(),
69-
..*obligation
70-
};
71-
obligation = &new_obligation;
72-
}
73-
74-
match candidate {
45+
let mut impl_src = match candidate {
7546
BuiltinCandidate { has_nested } => {
7647
let data = self.confirm_builtin_candidate(obligation, has_nested);
77-
Ok(ImplSource::Builtin(data))
48+
ImplSource::Builtin(data)
7849
}
7950

8051
ParamCandidate(param) => {
8152
let obligations =
8253
self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
83-
Ok(ImplSource::Param(obligations, param.skip_binder().constness))
54+
ImplSource::Param(obligations, param.skip_binder().constness)
8455
}
8556

8657
ImplCandidate(impl_def_id) => {
87-
Ok(ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id)))
58+
ImplSource::UserDefined(self.confirm_impl_candidate(obligation, impl_def_id))
8859
}
8960

9061
AutoImplCandidate(trait_def_id) => {
9162
let data = self.confirm_auto_impl_candidate(obligation, trait_def_id);
92-
Ok(ImplSource::AutoImpl(data))
63+
ImplSource::AutoImpl(data)
9364
}
9465

9566
ProjectionCandidate(idx) => {
9667
let obligations = self.confirm_projection_candidate(obligation, idx)?;
9768
// FIXME(jschievink): constness
98-
Ok(ImplSource::Param(obligations, ty::BoundConstness::NotConst))
69+
ImplSource::Param(obligations, ty::BoundConstness::NotConst)
9970
}
10071

10172
ObjectCandidate(idx) => {
10273
let data = self.confirm_object_candidate(obligation, idx)?;
103-
Ok(ImplSource::Object(data))
74+
ImplSource::Object(data)
10475
}
10576

10677
ClosureCandidate => {
10778
let vtable_closure = self.confirm_closure_candidate(obligation)?;
108-
Ok(ImplSource::Closure(vtable_closure))
79+
ImplSource::Closure(vtable_closure)
10980
}
11081

11182
GeneratorCandidate => {
11283
let vtable_generator = self.confirm_generator_candidate(obligation)?;
113-
Ok(ImplSource::Generator(vtable_generator))
84+
ImplSource::Generator(vtable_generator)
11485
}
11586

11687
FnPointerCandidate { .. } => {
11788
let data = self.confirm_fn_pointer_candidate(obligation)?;
118-
Ok(ImplSource::FnPointer(data))
89+
ImplSource::FnPointer(data)
11990
}
12091

12192
DiscriminantKindCandidate => {
122-
Ok(ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData))
93+
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
12394
}
12495

125-
PointeeCandidate => Ok(ImplSource::Pointee(ImplSourcePointeeData)),
96+
PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData),
12697

12798
TraitAliasCandidate(alias_def_id) => {
12899
let data = self.confirm_trait_alias_candidate(obligation, alias_def_id);
129-
Ok(ImplSource::TraitAlias(data))
100+
ImplSource::TraitAlias(data)
130101
}
131102

132103
BuiltinObjectCandidate => {
133104
// This indicates something like `Trait + Send: Send`. In this case, we know that
134105
// this holds because that's what the object type is telling us, and there's really
135106
// no additional obligations to prove and no types in particular to unify, etc.
136-
Ok(ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst))
107+
ImplSource::Param(Vec::new(), ty::BoundConstness::NotConst)
137108
}
138109

139110
BuiltinUnsizeCandidate => {
140111
let data = self.confirm_builtin_unsize_candidate(obligation)?;
141-
Ok(ImplSource::Builtin(data))
112+
ImplSource::Builtin(data)
142113
}
143114

144115
TraitUpcastingUnsizeCandidate(idx) => {
145116
let data = self.confirm_trait_upcasting_unsize_candidate(obligation, idx)?;
146-
Ok(ImplSource::TraitUpcasting(data))
117+
ImplSource::TraitUpcasting(data)
147118
}
148119

149120
ConstDestructCandidate(def_id) => {
150121
let data = self.confirm_const_destruct_candidate(obligation, def_id)?;
151-
Ok(ImplSource::ConstDestruct(data))
122+
ImplSource::ConstDestruct(data)
152123
}
124+
};
125+
126+
if !obligation.predicate.is_const_if_const() {
127+
// normalize nested predicates according to parent predicate's constness.
128+
impl_src = impl_src.map(|mut o| {
129+
o.predicate = o.predicate.without_const(self.tcx());
130+
o
131+
});
153132
}
133+
134+
Ok(impl_src)
154135
}
155136

156137
fn confirm_projection_candidate(

compiler/rustc_typeck/src/check/closure.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
182182
ty::PredicateKind::Projection(proj_predicate) => self
183183
.deduce_sig_from_projection(
184184
Some(span.0),
185-
pred.0.kind().rebind(
186-
pred.map_bound(|_| proj_predicate).subst(self.tcx, substs),
187-
),
185+
pred.0
186+
.kind()
187+
.rebind(pred.rebind(proj_predicate).subst(self.tcx, substs)),
188188
),
189189
_ => None,
190190
});

src/test/ui/unsized/issue-30355.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pub static Y: &'static X = {
44
const Y: &'static [u8] = b"";
55
&X(*Y)
66
//~^ ERROR E0277
7-
//~| ERROR E0277
87
};
98

109
fn main() {}

src/test/ui/unsized/issue-30355.stderr

+1-15
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,6 @@ LL | &X(*Y)
88
= note: all function arguments must have a statically known size
99
= help: unsized fn params are gated as an unstable feature
1010

11-
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
12-
--> $DIR/issue-30355.rs:5:6
13-
|
14-
LL | &X(*Y)
15-
| ^ doesn't have a size known at compile-time
16-
|
17-
= help: within `X`, the trait `Sized` is not implemented for `[u8]`
18-
note: required because it appears within the type `X`
19-
--> $DIR/issue-30355.rs:1:12
20-
|
21-
LL | pub struct X([u8]);
22-
| ^
23-
= note: the return type of a function must have a statically known size
24-
25-
error: aborting due to 2 previous errors
11+
error: aborting due to previous error
2612

2713
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)