Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 576655a

Browse files
committedMar 24, 2025
wip: trait_sel: skip elaboration of sizedness supertrait
As a performance optimization, skip elaborating the supertraits of `Sized`, and if a `MetaSized` obligation is being checked, then look for a `Sized` predicate in the parameter environment. This makes the `ParamEnv` smaller which should improve compiler performance as it avoids all the iteration over the larger `ParamEnv`.
1 parent 86f4f6c commit 576655a

19 files changed

+310
-85
lines changed
 

‎compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

+22-7
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ where
4545
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
4646
) -> Result<Candidate<I>, NoSolution> {
4747
if let Some(host_clause) = assumption.as_host_effect_clause() {
48-
if host_clause.def_id() == goal.predicate.def_id()
48+
let goal_did = goal.predicate.def_id();
49+
let host_clause_did = host_clause.def_id();
50+
if host_clause_did == goal_did
4951
&& host_clause.constness().satisfies(goal.predicate.constness)
5052
{
5153
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
@@ -55,21 +57,34 @@ where
5557
return Err(NoSolution);
5658
}
5759

58-
ecx.probe_trait_candidate(source).enter(|ecx| {
60+
return ecx.probe_trait_candidate(source).enter(|ecx| {
5961
let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
6062
ecx.eq(
6163
goal.param_env,
6264
goal.predicate.trait_ref,
6365
assumption_trait_pred.trait_ref,
6466
)?;
6567
then(ecx)
66-
})
67-
} else {
68-
Err(NoSolution)
68+
});
69+
}
70+
71+
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
72+
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
73+
// are syntactic sugar for a lack of bounds so don't need this.
74+
if ecx.cx().is_lang_item(goal_did, TraitSolverLangItem::MetaSized)
75+
&& ecx.cx().is_lang_item(host_clause_did, TraitSolverLangItem::Sized)
76+
&& {
77+
let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty());
78+
let found_self_ty =
79+
ecx.resolve_vars_if_possible(host_clause.self_ty().skip_binder());
80+
expected_self_ty == found_self_ty
81+
}
82+
{
83+
return ecx.probe_trait_candidate(source).enter(then);
6984
}
70-
} else {
71-
Err(NoSolution)
7285
}
86+
87+
Err(NoSolution)
7388
}
7489

7590
/// Register additional assumptions for aliases corresponding to `~const` item bounds.

‎compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -132,31 +132,44 @@ where
132132
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
133133
) -> Result<Candidate<I>, NoSolution> {
134134
if let Some(trait_clause) = assumption.as_trait_clause() {
135-
if trait_clause.def_id() == goal.predicate.def_id()
136-
&& trait_clause.polarity() == goal.predicate.polarity
137-
{
135+
let goal_did = goal.predicate.def_id();
136+
let trait_clause_did = trait_clause.def_id();
137+
if trait_clause_did == goal_did && trait_clause.polarity() == goal.predicate.polarity {
138138
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
139139
goal.predicate.trait_ref.args,
140140
trait_clause.skip_binder().trait_ref.args,
141141
) {
142142
return Err(NoSolution);
143143
}
144144

145-
ecx.probe_trait_candidate(source).enter(|ecx| {
145+
return ecx.probe_trait_candidate(source).enter(|ecx| {
146146
let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
147147
ecx.eq(
148148
goal.param_env,
149149
goal.predicate.trait_ref,
150150
assumption_trait_pred.trait_ref,
151151
)?;
152152
then(ecx)
153-
})
154-
} else {
155-
Err(NoSolution)
153+
});
154+
}
155+
156+
// PERF(sized-hierarchy): Sizedness supertraits aren't elaborated to improve perf, so
157+
// check for a `Sized` subtrait when looking for `MetaSized`. `PointeeSized` bounds
158+
// are syntactic sugar for a lack of bounds so don't need this.
159+
if ecx.cx().is_lang_item(goal_did, TraitSolverLangItem::MetaSized)
160+
&& ecx.cx().is_lang_item(trait_clause_did, TraitSolverLangItem::Sized)
161+
&& {
162+
let expected_self_ty = ecx.resolve_vars_if_possible(goal.predicate.self_ty());
163+
let found_self_ty =
164+
ecx.resolve_vars_if_possible(trait_clause.self_ty().skip_binder());
165+
expected_self_ty == found_self_ty
166+
}
167+
{
168+
return ecx.probe_trait_candidate(source).enter(then);
156169
}
157-
} else {
158-
Err(NoSolution)
159170
}
171+
172+
Err(NoSolution)
160173
}
161174

162175
fn consider_auto_trait_candidate(

‎compiler/rustc_trait_selection/src/traits/coherence.rs

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::fmt::Debug;
88

99
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
1010
use rustc_errors::{Diag, EmissionGuarantee};
11+
use rustc_hir::LangItem;
1112
use rustc_hir::def::DefKind;
1213
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
1314
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
@@ -582,6 +583,21 @@ fn try_prove_negated_where_clause<'tcx>(
582583
return false;
583584
};
584585

586+
let maybe_meta_sized_self_ty = clause
587+
.as_trait_clause()
588+
.filter(|c| root_infcx.tcx.is_lang_item(c.def_id(), LangItem::MetaSized))
589+
.map(|c| c.self_ty());
590+
if let Some(meta_sized_self_ty) = maybe_meta_sized_self_ty
591+
&& util::sizedness_elab_opt_fast_path_from_paramenv(
592+
root_infcx,
593+
meta_sized_self_ty,
594+
param_env,
595+
)
596+
.is_some()
597+
{
598+
return false;
599+
}
600+
585601
// N.B. We don't need to use intercrate mode here because we're trying to prove
586602
// the *existence* of a negative goal, not the non-existence of a positive goal.
587603
// Without this, we over-eagerly register coherence ambiguity candidates when

‎compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
1616
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
1717
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode};
1818
use rustc_middle::{bug, span_bug};
19-
use rustc_type_ir::{Interner, elaborate};
19+
use rustc_type_ir::{Binder, Interner, elaborate};
2020
use tracing::{debug, instrument, trace};
2121

2222
use super::SelectionCandidate::*;
@@ -188,15 +188,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
188188
let mut distinct_normalized_bounds = FxHashSet::default();
189189
let _ = self.for_each_item_bound::<!>(
190190
placeholder_trait_predicate.self_ty(),
191-
|selcx, bound, idx| {
192-
let Some(bound) = bound.as_trait_clause() else {
191+
|selcx, clause, idx| {
192+
let Some(bound) = clause.as_trait_clause() else {
193193
return ControlFlow::Continue(());
194194
};
195195
if bound.polarity() != placeholder_trait_predicate.polarity {
196196
return ControlFlow::Continue(());
197197
}
198198

199199
selcx.infcx.probe(|_| {
200+
if selcx
201+
.tcx()
202+
.is_lang_item(placeholder_trait_predicate.def_id(), LangItem::MetaSized)
203+
&& util::sizedness_elab_opt_fast_path_from_clauses(
204+
selcx.infcx,
205+
Binder::dummy(placeholder_trait_predicate.self_ty()),
206+
[clause],
207+
)
208+
.is_some()
209+
{
210+
candidates.vec.push(ProjectionCandidate(idx));
211+
return;
212+
}
213+
200214
// We checked the polarity already
201215
match selcx.match_normalize_trait_ref(
202216
obligation,
@@ -235,6 +249,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
235249
) -> Result<(), SelectionError<'tcx>> {
236250
debug!(?stack.obligation);
237251

252+
if self.tcx().is_lang_item(stack.obligation.predicate.def_id(), LangItem::MetaSized)
253+
&& let Some(bound) = util::sizedness_elab_opt_fast_path_from_paramenv(
254+
self.infcx,
255+
stack.obligation.self_ty(),
256+
stack.obligation.param_env,
257+
)
258+
{
259+
candidates.vec.push(ParamCandidate(bound));
260+
return Ok(());
261+
}
262+
238263
let bounds = stack
239264
.obligation
240265
.param_env

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

+12-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
1818
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, Upcast};
1919
use rustc_middle::{bug, span_bug};
2020
use rustc_span::def_id::DefId;
21-
use rustc_type_ir::elaborate;
21+
use rustc_type_ir::{Binder, elaborate};
2222
use thin_vec::thin_vec;
2323
use tracing::{debug, instrument};
2424

@@ -189,6 +189,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
189189
&mut obligations,
190190
);
191191

192+
if tcx.is_lang_item(obligation.predicate.def_id(), LangItem::MetaSized)
193+
&& util::sizedness_elab_opt_fast_path_from_traitrefs(
194+
self.infcx,
195+
obligation.predicate.self_ty(),
196+
[Binder::dummy(candidate)],
197+
)
198+
.is_some()
199+
{
200+
return Ok(obligations);
201+
}
202+
192203
obligations.extend(
193204
self.infcx
194205
.at(&obligation.cause, obligation.param_env)

‎compiler/rustc_trait_selection/src/traits/select/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ use rustc_middle::ty::{
3131
TypingMode, Upcast,
3232
};
3333
use rustc_span::{Symbol, sym};
34-
use rustc_type_ir::elaborate;
3534
use rustc_type_ir::solve::SizedTraitKind;
35+
use rustc_type_ir::{Binder, elaborate};
36+
use thin_vec::thin_vec;
3637
use tracing::{debug, instrument, trace};
3738

3839
use self::EvaluationResult::*;
@@ -2641,6 +2642,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
26412642
HigherRankedType,
26422643
poly_trait_ref,
26432644
);
2645+
2646+
if self.tcx().is_lang_item(predicate.def_id(), LangItem::MetaSized)
2647+
&& util::sizedness_elab_opt_fast_path_from_traitrefs(
2648+
self.infcx,
2649+
Binder::dummy(predicate.self_ty()),
2650+
[Binder::dummy(trait_ref)],
2651+
)
2652+
.is_some()
2653+
{
2654+
return Ok(thin_vec![]);
2655+
}
2656+
26442657
self.infcx
26452658
.at(&obligation.cause, obligation.param_env)
26462659
.eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref)

‎compiler/rustc_trait_selection/src/traits/util.rs

+67
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use rustc_middle::ty::{
99
self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
1010
};
1111
use rustc_span::Span;
12+
use rustc_type_ir::lang_items::TraitSolverLangItem;
13+
use rustc_type_ir::{InferCtxtLike, Interner, Upcast};
1214
use smallvec::{SmallVec, smallvec};
1315
use tracing::debug;
1416

@@ -504,3 +506,68 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
504506
}
505507
}
506508
}
509+
510+
/// To improve performance, Sizedness traits are not elaborated and so special-casing is required
511+
/// in the trait solver to find a `Sized` candidate for a `MetaSized` predicate. This is a helper
512+
/// function for that special-casing, intended to be used when the obligation to be proven has been
513+
/// confirmed to be `MetaSized`, and checking whether the `param_env` contains `Sized` for the same
514+
/// `self_ty` is all that remains to be done.
515+
// Ideally this would be re-used by the next solver, but there is no `InferCtxtLike` implementor.
516+
pub(crate) fn sizedness_elab_opt_fast_path_from_paramenv<Infcx, I>(
517+
infcx: &Infcx,
518+
self_ty: rustc_type_ir::Binder<I, I::Ty>,
519+
param_env: I::ParamEnv,
520+
) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitPredicate<I>>>
521+
where
522+
I: Interner,
523+
Infcx: InferCtxtLike<Interner = I>,
524+
{
525+
#[allow(rustc::usage_of_type_ir_inherent)]
526+
use rustc_type_ir::inherent::*;
527+
sizedness_elab_opt_fast_path_from_clauses(infcx, self_ty, param_env.caller_bounds().iter())
528+
}
529+
530+
/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of clauses instead
531+
/// of a parameter environment.
532+
pub(crate) fn sizedness_elab_opt_fast_path_from_clauses<Infcx, I, Trs>(
533+
infcx: &Infcx,
534+
self_ty: rustc_type_ir::Binder<I, I::Ty>,
535+
clauses: Trs,
536+
) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitPredicate<I>>>
537+
where
538+
I: Interner,
539+
Infcx: InferCtxtLike<Interner = I>,
540+
Trs: IntoIterator<Item = I::Clause>,
541+
{
542+
#[allow(rustc::usage_of_type_ir_inherent)]
543+
use rustc_type_ir::inherent::*;
544+
sizedness_elab_opt_fast_path_from_traitrefs(
545+
infcx,
546+
self_ty,
547+
clauses
548+
.into_iter()
549+
.filter_map(|p| p.as_trait_clause())
550+
.map(|c| c.map_bound(|c| c.trait_ref)),
551+
)
552+
.map(|f| f.map_bound(|f| f.upcast(infcx.cx())))
553+
}
554+
555+
/// Same as `sizedness_elab_opt_fast_path_from_paramenv` but takes an iterator of trait refs instead
556+
/// of a parameter environment.
557+
pub(crate) fn sizedness_elab_opt_fast_path_from_traitrefs<Infcx, I, TraitRefs>(
558+
infcx: &Infcx,
559+
self_ty: rustc_type_ir::Binder<I, I::Ty>,
560+
trait_refs: TraitRefs,
561+
) -> Option<rustc_type_ir::Binder<I, rustc_type_ir::TraitRef<I>>>
562+
where
563+
I: Interner,
564+
Infcx: InferCtxtLike<Interner = I>,
565+
TraitRefs: IntoIterator<Item = rustc_type_ir::Binder<I, rustc_type_ir::TraitRef<I>>>,
566+
{
567+
trait_refs.into_iter().find(|c| {
568+
let expected_self_ty = infcx.resolve_vars_if_possible(self_ty);
569+
let found_self_ty = infcx.resolve_vars_if_possible(c.self_ty());
570+
expected_self_ty == found_self_ty
571+
&& infcx.cx().is_lang_item(c.def_id(), TraitSolverLangItem::Sized)
572+
})
573+
}

‎compiler/rustc_type_ir/src/elaborate.rs

+47-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use smallvec::smallvec;
44

55
use crate::data_structures::HashSet;
66
use crate::inherent::*;
7+
use crate::lang_items::TraitSolverLangItem;
78
use crate::outlives::{Component, push_outlives_components};
89
use crate::{self as ty, Interner, Upcast as _};
910

@@ -79,20 +80,57 @@ pub fn elaborate<I: Interner, O: Elaboratable<I>>(
7980
) -> Elaborator<I, O> {
8081
let mut elaborator =
8182
Elaborator { cx, stack: Vec::new(), visited: HashSet::default(), mode: Filter::All };
82-
elaborator.extend_deduped(obligations);
83+
elaborator.extend_deduped(None, obligations);
8384
elaborator
8485
}
8586

8687
impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
87-
fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = O>) {
88+
/// Adds `obligations` to the stack. `current_clause` is the clause which was elaborated to
89+
/// produce these obligations.
90+
fn extend_deduped(
91+
&mut self,
92+
current_clause: Option<I::Clause>,
93+
obligations: impl IntoIterator<Item = O>,
94+
) {
8895
// Only keep those bounds that we haven't already seen.
8996
// This is necessary to prevent infinite recursion in some
9097
// cases. One common case is when people define
9198
// `trait Sized: Sized { }` rather than `trait Sized { }`.
9299
self.stack.extend(
93-
obligations.into_iter().filter(|o| {
94-
self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind()))
95-
}),
100+
obligations
101+
.into_iter()
102+
.filter(|o| self.visited.insert(self.cx.anonymize_bound_vars(o.predicate().kind())))
103+
.filter(|o| {
104+
let Some(current_clause) = current_clause else {
105+
return true;
106+
};
107+
let Some(next_clause) = o.predicate().as_clause() else {
108+
return true;
109+
};
110+
111+
let current_did = match current_clause.kind().skip_binder() {
112+
ty::ClauseKind::Trait(data) => data.def_id(),
113+
ty::ClauseKind::HostEffect(data) => data.def_id(),
114+
_ => return true,
115+
};
116+
let next_did = match next_clause.kind().skip_binder() {
117+
ty::ClauseKind::Trait(data) => data.def_id(),
118+
ty::ClauseKind::HostEffect(data) => data.def_id(),
119+
_ => return true,
120+
};
121+
122+
// PERF(sized-hierarchy): To avoid iterating over sizedness supertraits in
123+
// parameter environments, as an optimisation, sizedness supertraits aren't
124+
// elaborated, so check if a `Sized` obligation is being elaborated to a
125+
// `MetaSized` obligation and emit it. Candidate assembly and confirmation
126+
// are modified to check for the `Sized` subtrait when a `MetaSized` obligation
127+
// is present.
128+
if self.cx.is_lang_item(current_did, TraitSolverLangItem::Sized) {
129+
!self.cx.is_lang_item(next_did, TraitSolverLangItem::MetaSized)
130+
} else {
131+
true
132+
}
133+
}),
96134
);
97135
}
98136

@@ -132,12 +170,14 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
132170
// Get predicates implied by the trait, or only super predicates if we only care about self predicates.
133171
match self.mode {
134172
Filter::All => self.extend_deduped(
173+
Some(clause),
135174
cx.explicit_implied_predicates_of(data.def_id())
136175
.iter_identity()
137176
.enumerate()
138177
.map(map_to_child_clause),
139178
),
140179
Filter::OnlySelf => self.extend_deduped(
180+
Some(clause),
141181
cx.explicit_super_predicates_of(data.def_id())
142182
.iter_identity()
143183
.enumerate()
@@ -147,6 +187,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
147187
}
148188
// `T: ~const Trait` implies `T: ~const Supertrait`.
149189
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
190+
Some(clause),
150191
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
151192
elaboratable.child(
152193
trait_ref
@@ -177,6 +218,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
177218
let mut components = smallvec![];
178219
push_outlives_components(cx, ty_max, &mut components);
179220
self.extend_deduped(
221+
Some(clause),
180222
components
181223
.into_iter()
182224
.filter_map(|component| elaborate_component_to_clause(cx, component, r_min))

‎tests/ui/attributes/dump-preds.stderr

-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ LL | type Assoc<P: Eq>: std::ops::Deref<Target = ()>
4242
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::ops::Deref>, polarity:Positive), bound_vars: [] }
4343
= note: Binder { value: HostEffectPredicate { trait_ref: <<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, constness: Const }, bound_vars: [] }
4444
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::Sized>, polarity:Positive), bound_vars: [] }
45-
= note: Binder { value: TraitPredicate(<<Self as Trait<T>>::Assoc<P> as std::marker::MetaSized>, polarity:Positive), bound_vars: [] }
4645

4746
error: aborting due to 3 previous errors
4847

‎tests/ui/extern/extern-types-unsized.rs

+2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ fn main() {
2727

2828
assert_sized::<Bar<A>>();
2929
//~^ ERROR the size for values of type
30+
//~| ERROR the size for values of type
3031

3132
assert_sized::<Bar<Bar<A>>>();
3233
//~^ ERROR the size for values of type
34+
//~| ERROR the size for values of type
3335
}

‎tests/ui/extern/extern-types-unsized.stderr

+28-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,21 @@ help: consider relaxing the implicit `Sized` restriction
5959
LL | fn assert_sized<T: ?Sized>() {}
6060
| ++++++++
6161

62+
error[E0277]: the size for values of type `A` cannot be known
63+
--> $DIR/extern-types-unsized.rs:28:20
64+
|
65+
LL | assert_sized::<Bar<A>>();
66+
| ^^^^^^ doesn't have a known size
67+
|
68+
= help: the trait `MetaSized` is not implemented for `A`
69+
note: required by a bound in `Bar`
70+
--> $DIR/extern-types-unsized.rs:14:12
71+
|
72+
LL | struct Bar<T: ?Sized> {
73+
| ^ required by this bound in `Bar`
74+
6275
error[E0277]: the size for values of type `A` cannot be known at compilation time
63-
--> $DIR/extern-types-unsized.rs:31:20
76+
--> $DIR/extern-types-unsized.rs:32:20
6477
|
6578
LL | assert_sized::<Bar<Bar<A>>>();
6679
| ^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -81,6 +94,19 @@ help: consider relaxing the implicit `Sized` restriction
8194
LL | fn assert_sized<T: ?Sized>() {}
8295
| ++++++++
8396

84-
error: aborting due to 4 previous errors
97+
error[E0277]: the size for values of type `A` cannot be known
98+
--> $DIR/extern-types-unsized.rs:32:20
99+
|
100+
LL | assert_sized::<Bar<Bar<A>>>();
101+
| ^^^^^^^^^^^ doesn't have a known size
102+
|
103+
= help: the trait `MetaSized` is not implemented for `A`
104+
note: required by a bound in `Bar`
105+
--> $DIR/extern-types-unsized.rs:14:12
106+
|
107+
LL | struct Bar<T: ?Sized> {
108+
| ^ required by this bound in `Bar`
109+
110+
error: aborting due to 6 previous errors
85111

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

‎tests/ui/nll/issue-50716.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trait A {
55
type X: ?Sized;
66
}
77

8-
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>) //~ ERROR mismatched types
8+
fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
99
where
1010
for<'b> &'b T: A,
1111
<&'static T as A>::X: Sized

‎tests/ui/nll/issue-50716.stderr

+1-17
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,3 @@
1-
error[E0308]: mismatched types
2-
--> $DIR/issue-50716.rs:8:27
3-
|
4-
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
5-
| ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
6-
|
7-
= note: expected trait `<<&'a T as A>::X as MetaSized>`
8-
found trait `<<&'static T as A>::X as MetaSized>`
9-
note: the lifetime `'a` as defined here...
10-
--> $DIR/issue-50716.rs:8:8
11-
|
12-
LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
13-
| ^^
14-
= note: ...does not necessarily outlive the static lifetime
15-
161
error: lifetime may not live long enough
172
--> $DIR/issue-50716.rs:13:14
183
|
@@ -22,6 +7,5 @@ LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
227
LL | let _x = *s;
238
| ^^ proving this value is `Sized` requires that `'a` must outlive `'static`
249

25-
error: aborting due to 2 previous errors
10+
error: aborting due to 1 previous error
2611

27-
For more information about this error, try `rustc --explain E0308`.

‎tests/ui/sized-hierarchy/impls.rs

+1
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ fn main() {
209209
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
210210
needs_metasized::<(Foo, Foo)>();
211211
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
212+
//~| ERROR the size for values of type `main::Foo` cannot be known
212213
needs_pointeesized::<(Foo, Foo)>();
213214
//~^ ERROR the size for values of type `main::Foo` cannot be known at compilation time
214215

‎tests/ui/sized-hierarchy/impls.stderr

+37-23
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
2-
--> $DIR/impls.rs:241:42
2+
--> $DIR/impls.rs:242:42
33
|
44
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
55
| ^^^^ doesn't have a size known at compile-time
@@ -17,7 +17,7 @@ LL | struct StructAllFieldsMetaSized { x: Box<[u8]>, y: [u8] }
1717
| ++++ +
1818

1919
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
20-
--> $DIR/impls.rs:249:40
20+
--> $DIR/impls.rs:250:40
2121
|
2222
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
2323
| ^^^ doesn't have a size known at compile-time
@@ -35,7 +35,7 @@ LL | struct StructAllFieldsUnsized { x: Box<Foo>, y: Foo }
3535
| ++++ +
3636

3737
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
38-
--> $DIR/impls.rs:285:44
38+
--> $DIR/impls.rs:286:44
3939
|
4040
LL | enum EnumAllFieldsMetaSized { Qux { x: [u8], y: [u8] } }
4141
| ^^^^ doesn't have a size known at compile-time
@@ -53,7 +53,7 @@ LL | enum EnumAllFieldsMetaSized { Qux { x: Box<[u8]>, y: [u8] } }
5353
| ++++ +
5454

5555
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
56-
--> $DIR/impls.rs:292:42
56+
--> $DIR/impls.rs:293:42
5757
|
5858
LL | enum EnumAllFieldsUnsized { Qux { x: Foo, y: Foo } }
5959
| ^^^ doesn't have a size known at compile-time
@@ -71,7 +71,7 @@ LL | enum EnumAllFieldsUnsized { Qux { x: Box<Foo>, y: Foo } }
7171
| ++++ +
7272

7373
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
74-
--> $DIR/impls.rs:299:52
74+
--> $DIR/impls.rs:300:52
7575
|
7676
LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: [u8] } }
7777
| ^^^^ doesn't have a size known at compile-time
@@ -89,7 +89,7 @@ LL | enum EnumLastFieldMetaSized { Qux { x: u32, y: Box<[u8]> } }
8989
| ++++ +
9090

9191
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
92-
--> $DIR/impls.rs:306:50
92+
--> $DIR/impls.rs:307:50
9393
|
9494
LL | enum EnumLastFieldUnsized { Qux { x: u32, y: Foo } }
9595
| ^^^ doesn't have a size known at compile-time
@@ -216,8 +216,22 @@ LL | needs_metasized::<(Foo, Foo)>();
216216
= help: the trait `Sized` is not implemented for `main::Foo`
217217
= note: only the last element of a tuple may have a dynamically sized type
218218

219+
error[E0277]: the size for values of type `main::Foo` cannot be known
220+
--> $DIR/impls.rs:210:23
221+
|
222+
LL | needs_metasized::<(Foo, Foo)>();
223+
| ^^^^^^^^^^ doesn't have a known size
224+
|
225+
= help: within `(main::Foo, main::Foo)`, the trait `MetaSized` is not implemented for `main::Foo`
226+
= note: required because it appears within the type `(main::Foo, main::Foo)`
227+
note: required by a bound in `needs_metasized`
228+
--> $DIR/impls.rs:18:23
229+
|
230+
LL | fn needs_metasized<T: MetaSized>() { }
231+
| ^^^^^^^^^ required by this bound in `needs_metasized`
232+
219233
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
220-
--> $DIR/impls.rs:212:26
234+
--> $DIR/impls.rs:213:26
221235
|
222236
LL | needs_pointeesized::<(Foo, Foo)>();
223237
| ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -226,7 +240,7 @@ LL | needs_pointeesized::<(Foo, Foo)>();
226240
= note: only the last element of a tuple may have a dynamically sized type
227241

228242
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
229-
--> $DIR/impls.rs:216:19
243+
--> $DIR/impls.rs:217:19
230244
|
231245
LL | needs_sized::<(u32, [u8])>();
232246
| ^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -240,7 +254,7 @@ LL | fn needs_sized<T: Sized>() { }
240254
| ^^^^^ required by this bound in `needs_sized`
241255

242256
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
243-
--> $DIR/impls.rs:222:19
257+
--> $DIR/impls.rs:223:19
244258
|
245259
LL | needs_sized::<(u32, Foo)>();
246260
| ^^^^^^^^^^ doesn't have a size known at compile-time
@@ -254,7 +268,7 @@ LL | fn needs_sized<T: Sized>() { }
254268
| ^^^^^ required by this bound in `needs_sized`
255269

256270
error[E0277]: the size for values of type `main::Foo` cannot be known
257-
--> $DIR/impls.rs:224:23
271+
--> $DIR/impls.rs:225:23
258272
|
259273
LL | needs_metasized::<(u32, Foo)>();
260274
| ^^^^^^^^^^ doesn't have a known size
@@ -268,14 +282,14 @@ LL | fn needs_metasized<T: MetaSized>() { }
268282
| ^^^^^^^^^ required by this bound in `needs_metasized`
269283

270284
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
271-
--> $DIR/impls.rs:243:19
285+
--> $DIR/impls.rs:244:19
272286
|
273287
LL | needs_sized::<StructAllFieldsMetaSized>();
274288
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
275289
|
276290
= help: within `StructAllFieldsMetaSized`, the trait `Sized` is not implemented for `[u8]`
277291
note: required because it appears within the type `StructAllFieldsMetaSized`
278-
--> $DIR/impls.rs:241:12
292+
--> $DIR/impls.rs:242:12
279293
|
280294
LL | struct StructAllFieldsMetaSized { x: [u8], y: [u8] }
281295
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -286,14 +300,14 @@ LL | fn needs_sized<T: Sized>() { }
286300
| ^^^^^ required by this bound in `needs_sized`
287301

288302
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
289-
--> $DIR/impls.rs:251:19
303+
--> $DIR/impls.rs:252:19
290304
|
291305
LL | needs_sized::<StructAllFieldsUnsized>();
292306
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
293307
|
294308
= help: within `StructAllFieldsUnsized`, the trait `Sized` is not implemented for `main::Foo`
295309
note: required because it appears within the type `StructAllFieldsUnsized`
296-
--> $DIR/impls.rs:249:12
310+
--> $DIR/impls.rs:250:12
297311
|
298312
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
299313
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -304,14 +318,14 @@ LL | fn needs_sized<T: Sized>() { }
304318
| ^^^^^ required by this bound in `needs_sized`
305319

306320
error[E0277]: the size for values of type `main::Foo` cannot be known
307-
--> $DIR/impls.rs:253:23
321+
--> $DIR/impls.rs:254:23
308322
|
309323
LL | needs_metasized::<StructAllFieldsUnsized>();
310324
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
311325
|
312326
= help: within `StructAllFieldsUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
313327
note: required because it appears within the type `StructAllFieldsUnsized`
314-
--> $DIR/impls.rs:249:12
328+
--> $DIR/impls.rs:250:12
315329
|
316330
LL | struct StructAllFieldsUnsized { x: Foo, y: Foo }
317331
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -322,14 +336,14 @@ LL | fn needs_metasized<T: MetaSized>() { }
322336
| ^^^^^^^^^ required by this bound in `needs_metasized`
323337

324338
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
325-
--> $DIR/impls.rs:259:19
339+
--> $DIR/impls.rs:260:19
326340
|
327341
LL | needs_sized::<StructLastFieldMetaSized>();
328342
| ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
329343
|
330344
= help: within `StructLastFieldMetaSized`, the trait `Sized` is not implemented for `[u8]`
331345
note: required because it appears within the type `StructLastFieldMetaSized`
332-
--> $DIR/impls.rs:258:12
346+
--> $DIR/impls.rs:259:12
333347
|
334348
LL | struct StructLastFieldMetaSized { x: u32, y: [u8] }
335349
| ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -340,14 +354,14 @@ LL | fn needs_sized<T: Sized>() { }
340354
| ^^^^^ required by this bound in `needs_sized`
341355

342356
error[E0277]: the size for values of type `main::Foo` cannot be known at compilation time
343-
--> $DIR/impls.rs:266:19
357+
--> $DIR/impls.rs:267:19
344358
|
345359
LL | needs_sized::<StructLastFieldUnsized>();
346360
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
347361
|
348362
= help: within `StructLastFieldUnsized`, the trait `Sized` is not implemented for `main::Foo`
349363
note: required because it appears within the type `StructLastFieldUnsized`
350-
--> $DIR/impls.rs:265:12
364+
--> $DIR/impls.rs:266:12
351365
|
352366
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
353367
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -358,14 +372,14 @@ LL | fn needs_sized<T: Sized>() { }
358372
| ^^^^^ required by this bound in `needs_sized`
359373

360374
error[E0277]: the size for values of type `main::Foo` cannot be known
361-
--> $DIR/impls.rs:268:23
375+
--> $DIR/impls.rs:269:23
362376
|
363377
LL | needs_metasized::<StructLastFieldUnsized>();
364378
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a known size
365379
|
366380
= help: within `StructLastFieldUnsized`, the trait `MetaSized` is not implemented for `main::Foo`
367381
note: required because it appears within the type `StructLastFieldUnsized`
368-
--> $DIR/impls.rs:265:12
382+
--> $DIR/impls.rs:266:12
369383
|
370384
LL | struct StructLastFieldUnsized { x: u32, y: Foo }
371385
| ^^^^^^^^^^^^^^^^^^^^^^
@@ -375,6 +389,6 @@ note: required by a bound in `needs_metasized`
375389
LL | fn needs_metasized<T: MetaSized>() { }
376390
| ^^^^^^^^^ required by this bound in `needs_metasized`
377391

378-
error: aborting due to 26 previous errors
392+
error: aborting due to 27 previous errors
379393

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

‎tests/ui/sized-hierarchy/pretty-print-opaque.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub fn pointeesized() -> Box<impl Tr + PointeeSized> {
5757
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
5858
let y: Box<dyn Tr> = x;
5959
//~^ ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
60+
//~| ERROR: the size for values of type `impl Tr + PointeeSized` cannot be known
6061
}
6162
Box::new(1u32)
6263
}

‎tests/ui/sized-hierarchy/pretty-print-opaque.stderr

+10-1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ LL | let y: Box<dyn Tr> = x;
5454
= help: the trait `Sized` is not implemented for `impl Tr + PointeeSized`
5555
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
5656

57-
error: aborting due to 6 previous errors
57+
error[E0277]: the size for values of type `impl Tr + PointeeSized` cannot be known
58+
--> $DIR/pretty-print-opaque.rs:58:30
59+
|
60+
LL | let y: Box<dyn Tr> = x;
61+
| ^ doesn't have a known size
62+
|
63+
= help: the trait `MetaSized` is not implemented for `impl Tr + PointeeSized`
64+
= note: required for the cast from `Box<impl Tr + PointeeSized>` to `Box<dyn Tr>`
65+
66+
error: aborting due to 7 previous errors
5867

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

‎tests/ui/traits/next-solver/issue-118950-root-region.rs

-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@ impl<T> Overlap<T> for T {}
1919
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
2020
//~^ ERROR cannot find type `Missing` in this scope
2121
//~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
22-
//~| ERROR the trait bound `{type error}: const MetaSized` is not satisfied
2322

2423
fn main() {}

‎tests/ui/traits/next-solver/issue-118950-root-region.stderr

+1-13
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,7 @@ help: consider further restricting type parameter `T` with trait `Overlap`
3737
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
3838
| ++++++++++++++++++++++++++++++++++++++
3939

40-
error[E0277]: the trait bound `{type error}: const MetaSized` is not satisfied
41-
--> $DIR/issue-118950-root-region.rs:19:64
42-
|
43-
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
44-
| ^^^^^^^^^^
45-
|
46-
note: required by a bound in `Overlap`
47-
--> $DIR/issue-118950-root-region.rs:12:1
48-
|
49-
LL | trait Overlap<T> {}
50-
| ^^^^^^^^^^^^^^^^ required by this bound in `Overlap`
51-
52-
error: aborting due to 4 previous errors; 1 warning emitted
40+
error: aborting due to 3 previous errors; 1 warning emitted
5341

5442
Some errors have detailed explanations: E0277, E0412.
5543
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)
Please sign in to comment.