trait_sel: skip nominal_obligations for Sized

`nominal_obligations` calls `predicates_of` on a `Sized` obligation,
effectively elaborating the trait and making the well-formedness checking
machinery do a bunch of extra work checking a `MetaSized` obligation is
well-formed, but given that both `Sized` and `MetaSized` are built-ins,
if `Sized` is otherwise well-formed, so `MetaSized` will be.
This commit is contained in:
David Wood 2025-04-12 21:09:38 +00:00
parent 607eb322a8
commit d531a84e51
No known key found for this signature in database
4 changed files with 12 additions and 36 deletions

View file

@ -567,6 +567,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
def_id: DefId,
args: GenericArgsRef<'tcx>,
) -> PredicateObligations<'tcx> {
// PERF: `Sized`'s predicates include `MetaSized`, but both are compiler implemented marker
// traits, so `MetaSized` will always be WF if `Sized` is WF and vice-versa. Determining
// the nominal obligations of `Sized` would in-effect just elaborate `MetaSized` and make
// the compiler do a bunch of work needlessly.
if self.tcx().is_lang_item(def_id, LangItem::Sized) {
return Default::default();
}
let predicates = self.tcx().predicates_of(def_id);
let mut origins = vec![def_id; predicates.predicates.len()];
let mut head = predicates;

View file

@ -1,20 +1,5 @@
error[E0308]: mismatched types
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23
|
LL | (MyType<'a, T>,): Sized,
| ^^^^^ lifetime mismatch
|
= note: expected trait `<MyType<'a, T> as Sized>`
found trait `<MyType<'static, T> as Sized>`
note: the lifetime `'a` as defined here...
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8
|
LL | fn foo<'a, T: ?Sized>()
| ^^
= note: ...does not necessarily outlive the static lifetime
error: lifetime may not live long enough
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5
|
LL | fn foo<'a, T: ?Sized>()
| -- lifetime `'a` defined here
@ -22,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>()
LL | is_sized::<(MyType<'a, T>,)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,18 +1,5 @@
error[E0478]: lifetime bound not satisfied
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:13:23
|
LL | (MyType<'a, T>,): Sized,
| ^^^^^
|
note: lifetime parameter instantiated with the lifetime `'a` as defined here
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:11:8
|
LL | fn foo<'a, T: ?Sized>()
| ^^
= note: but lifetime parameter must outlive the static lifetime
error: lifetime may not live long enough
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:22:5
--> $DIR/lifetime-incomplete-prefer-sized-builtin-over-wc.rs:20:5
|
LL | fn foo<'a, T: ?Sized>()
| -- lifetime `'a` defined here
@ -20,6 +7,5 @@ LL | fn foo<'a, T: ?Sized>()
LL | is_sized::<(MyType<'a, T>,)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0478`.

View file

@ -11,8 +11,6 @@ fn is_sized<T>() {}
fn foo<'a, T: ?Sized>()
where
(MyType<'a, T>,): Sized,
//[current]~^ ERROR mismatched types
//[next]~^^ ERROR lifetime bound not satisfied
MyType<'static, T>: Sized,
{
// Preferring the builtin `Sized` impl of tuples