Skip to content

Commit 60d5044

Browse files
committed
hir_analysis: add missing sizedness bounds
Default sizedness bounds were not being added to `explicit_super_predicates_of` and `explicit_implied_predicates_of` which meant that a trait bound added to a associated type projection would be missing the implied predicate of the default sizedness supertrait of that trait. An unexpected consequence of this change was that the check for multiple principals was now finding an additional `MetaSized` principal when eagerly expanding trait aliases - this required modifying lowering to no longer add default bounds to trait aliases.
1 parent 27733d4 commit 60d5044

File tree

10 files changed

+62
-87
lines changed

10 files changed

+62
-87
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,14 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
658658
| PredicateFilter::SelfOnly
659659
| PredicateFilter::SelfTraitThatDefines(_)
660660
| PredicateFilter::SelfAndAssociatedTypeBounds => {
661+
icx.lowerer().add_sizedness_bounds(
662+
&mut bounds,
663+
self_param_ty,
664+
superbounds,
665+
None,
666+
Some(trait_def_id),
667+
item.span,
668+
);
661669
icx.lowerer().add_default_super_traits(
662670
trait_def_id,
663671
&mut bounds,

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -215,14 +215,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
215215
&& !collected.meta_sized.any()
216216
&& !collected.pointee_sized.any()
217217
{
218-
// `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any
219-
// other explicit ones) - this can happen for trait aliases as well as bounds.
220-
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
221-
} else if !collected.any() {
222-
if trait_did.is_some() {
223-
// If there are no explicit sizedness bounds on a trait then add a default
224-
// `MetaSized` supertrait.
218+
if trait_did.map(|did| !tcx.is_trait_alias(did.to_def_id())).unwrap_or(true) {
219+
// `?Sized` is equivalent to `MetaSized` (but only add the bound if there aren't any
220+
// other explicit ones and it isn't a trait alias).
225221
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
222+
}
223+
} else if !collected.any() {
224+
if let Some(trait_did) = trait_did {
225+
if !tcx.is_trait_alias(trait_did.to_def_id()) {
226+
// If there are no explicit sizedness bounds on a trait and it is not a trait
227+
// alias then add a default `MetaSized` supertrait.
228+
add_trait_bound(tcx, bounds, self_ty, meta_sized_did, span);
229+
}
226230
} else {
227231
// If there are no explicit sizedness bounds on a parameter then add a default
228232
// `Sized` bound.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ check-pass
2+
#![crate_type = "lib"]
3+
#![feature(sized_hierarchy)]
4+
5+
trait FalseDeref {
6+
type Target: std::marker::PointeeSized;
7+
}
8+
9+
trait Bar {}
10+
11+
fn foo<T: FalseDeref>()
12+
where
13+
T::Target: Bar,
14+
{
15+
}

tests/ui/sized-hierarchy/default-supertrait.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,11 @@ fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_>() {
4747
requires_pointeesized::<T>();
4848
}
4949

50-
// `T` won't inherit the `const MetaSized` implicit supertrait of `Bare`, so there is an error on
51-
// the bound, which is expected.
50+
// `T` inherits the `const MetaSized` implicit supertrait of `Bare`.
5251
fn with_bare_trait<T: PointeeSized + Bare>() {
53-
//~^ ERROR the size for values of type `T` cannot be known
5452
requires_sized::<T>();
5553
//~^ ERROR the size for values of type `T` cannot be known
5654
requires_metasized::<T>();
57-
//~^ ERROR the size for values of type `T` cannot be known
5855
requires_pointeesized::<T>();
5956
}
6057

tests/ui/sized-hierarchy/default-supertrait.stderr

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,6 @@ LL | trait NegPointeeSized: ?PointeeSized { }
2828
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
2929
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3030

31-
error[E0277]: the size for values of type `T` cannot be known
32-
--> $DIR/default-supertrait.rs:52:38
33-
|
34-
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
35-
| ^^^^ doesn't have a known size
36-
|
37-
note: required by a bound in `Bare`
38-
--> $DIR/default-supertrait.rs:22:1
39-
|
40-
LL | trait Bare {}
41-
| ^^^^^^^^^^^^^ required by this bound in `Bare`
42-
help: consider further restricting type parameter `T` with unstable trait `MetaSized`
43-
|
44-
LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
45-
| ++++++++++++++++++++++++
46-
4731
error[E0277]: the size for values of type `T` cannot be known at compilation time
4832
--> $DIR/default-supertrait.rs:35:22
4933
|
@@ -89,11 +73,10 @@ LL | fn with_pointeesized_supertrait<T: PointeeSized + PointeeSized_ + std::mark
8973
| ++++++++++++++++++++++++
9074

9175
error[E0277]: the size for values of type `T` cannot be known at compilation time
92-
--> $DIR/default-supertrait.rs:54:22
76+
--> $DIR/default-supertrait.rs:52:22
9377
|
9478
LL | fn with_bare_trait<T: PointeeSized + Bare>() {
9579
| - this type parameter needs to be `Sized`
96-
LL |
9780
LL | requires_sized::<T>();
9881
| ^ doesn't have a size known at compile-time
9982
|
@@ -103,23 +86,7 @@ note: required by a bound in `requires_sized`
10386
LL | fn requires_sized<T: Sized>() {}
10487
| ^^^^^ required by this bound in `requires_sized`
10588

106-
error[E0277]: the size for values of type `T` cannot be known
107-
--> $DIR/default-supertrait.rs:56:26
108-
|
109-
LL | requires_metasized::<T>();
110-
| ^ doesn't have a known size
111-
|
112-
note: required by a bound in `requires_metasized`
113-
--> $DIR/default-supertrait.rs:25:26
114-
|
115-
LL | fn requires_metasized<T: MetaSized>() {}
116-
| ^^^^^^^^^ required by this bound in `requires_metasized`
117-
help: consider further restricting type parameter `T` with unstable trait `MetaSized`
118-
|
119-
LL | fn with_bare_trait<T: PointeeSized + Bare + std::marker::MetaSized>() {
120-
| ++++++++++++++++++++++++
121-
122-
error: aborting due to 9 previous errors
89+
error: aborting due to 7 previous errors
12390

12491
Some errors have detailed explanations: E0277, E0658.
12592
For more information about an error, try `rustc --explain E0277`.

tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
1919
LL | Self::Assoc: A<T>,
2020
| ^^^^
2121

22-
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: MetaSized`
23-
--> $DIR/normalize-param-env-2.rs:24:22
24-
|
25-
LL | Self::Assoc: A<T>,
26-
| ^^^^
27-
|
28-
note: required by a bound in `A`
29-
--> $DIR/normalize-param-env-2.rs:9:1
30-
|
31-
LL | / trait A<T> {
32-
LL | | type Assoc;
33-
LL | |
34-
LL | | fn f()
35-
... |
36-
LL | | }
37-
| |_^ required by this bound in `A`
38-
3922
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
4023
--> $DIR/normalize-param-env-2.rs:24:22
4124
|
@@ -63,6 +46,6 @@ LL | where
6346
LL | Self::Assoc: A<T>,
6447
| ^^^^ required by this bound in `A::f`
6548

66-
error: aborting due to 6 previous errors
49+
error: aborting due to 5 previous errors
6750

6851
For more information about this error, try `rustc --explain E0275`.

tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,6 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
44
LL | <T as Trait>::Assoc: Trait,
55
| ^^^^^
66

7-
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: MetaSized`
8-
--> $DIR/normalize-param-env-4.rs:19:26
9-
|
10-
LL | <T as Trait>::Assoc: Trait,
11-
| ^^^^^
12-
|
13-
note: required by a bound in `Trait`
14-
--> $DIR/normalize-param-env-4.rs:7:1
15-
|
16-
LL | / trait Trait {
17-
LL | | type Assoc;
18-
LL | | }
19-
| |_^ required by this bound in `Trait`
20-
21-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
228

239
For more information about this error, try `rustc --explain E0275`.
Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/drop-impl-pred.rs:6:12
2+
--> $DIR/drop-impl-pred.rs:5:12
33
|
44
LL | #![feature(non_lifetime_binders)]
55
| ^^^^^^^^^^^^^^^^^^^^
@@ -8,17 +8,24 @@ LL | #![feature(non_lifetime_binders)]
88
= note: `#[warn(incomplete_features)]` on by default
99

1010
error[E0367]: `Drop` impl requires `H: Foo` but the struct it is implemented for does not
11-
--> $DIR/drop-impl-pred.rs:19:15
11+
--> $DIR/drop-impl-pred.rs:20:15
1212
|
1313
LL | for<H> H: Foo,
1414
| ^^^
1515
|
1616
note: the implementor must specify the same requirement
17-
--> $DIR/drop-impl-pred.rs:12:1
17+
--> $DIR/drop-impl-pred.rs:11:1
1818
|
1919
LL | struct Bar<T>(T) where T: Foo;
2020
| ^^^^^^^^^^^^^
2121

22-
error: aborting due to 1 previous error; 1 warning emitted
22+
error[E0282]: type annotations needed
23+
--> $DIR/drop-impl-pred.rs:16:18
24+
|
25+
LL | impl<T> Drop for Bar<T>
26+
| ^^^^^^ cannot infer type for struct `Bar<T>`
27+
28+
error: aborting due to 2 previous errors; 1 warning emitted
2329

24-
For more information about this error, try `rustc --explain E0367`.
30+
Some errors have detailed explanations: E0282, E0367.
31+
For more information about an error, try `rustc --explain E0282`.

tests/ui/traits/non_lifetime_binders/drop-impl-pred.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
//@ revisions: no yes
2-
//@[yes] check-pass
32

43
// Issue 110557
54

@@ -15,6 +14,8 @@ struct Bar<T>(T) where T: Foo;
1514
struct Bar<T>(T) where for<H> H: Foo;
1615

1716
impl<T> Drop for Bar<T>
17+
//[yes]~^ ERROR type annotations needed
18+
//[no]~^^ ERROR type annotations needed
1819
where
1920
for<H> H: Foo,
2021
//[no]~^ ERROR `Drop` impl requires `H: Foo` but the struct it is implemented for does not
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/drop-impl-pred.rs:6:12
2+
--> $DIR/drop-impl-pred.rs:5:12
33
|
44
LL | #![feature(non_lifetime_binders)]
55
| ^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
88
= note: `#[warn(incomplete_features)]` on by default
99

10-
warning: 1 warning emitted
10+
error[E0282]: type annotations needed
11+
--> $DIR/drop-impl-pred.rs:16:18
12+
|
13+
LL | impl<T> Drop for Bar<T>
14+
| ^^^^^^ cannot infer type for struct `Bar<T>`
15+
16+
error: aborting due to 1 previous error; 1 warning emitted
1117

18+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)