Skip to content

Commit b0ed5ac

Browse files
Rollup merge of #133394 - compiler-errors:dyn-more-errors, r=lcnr
Bail on more errors in dyn ty lowering If we have more than one principal trait, or if we have a principal trait with errors in it, then bail with `TyKind::Error` rather than attempting lowering. Lowering a dyn trait with more than one principal just arbitrarily chooses the first one and drops the subsequent ones, and lowering a dyn trait path with errors in it is just kinda useless. This suppresses unnecessary errors which I think is net-good, but also is important to make sure that we don't end up leaking `{type error}` in #133388 error messaging :) r? types
2 parents cf09718 + cfa8fcb commit b0ed5ac

22 files changed

+61
-455
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
88
use rustc_middle::span_bug;
99
use rustc_middle::ty::fold::BottomUpFolder;
1010
use rustc_middle::ty::{
11-
self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, Upcast,
11+
self, DynKind, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable,
12+
TypeVisitableExt, Upcast,
1213
};
1314
use rustc_span::{ErrorGuaranteed, Span};
1415
use rustc_trait_selection::error_reporting::traits::report_dyn_incompatibility;
@@ -92,11 +93,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
9293

9394
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) =
9495
expanded_traits.partition(|i| tcx.trait_is_auto(i.trait_ref().def_id()));
96+
97+
// We don't support >1 principal
9598
if regular_traits.len() > 1 {
96-
let _ = self.report_trait_object_addition_traits_error(&regular_traits);
97-
} else if regular_traits.is_empty() && auto_traits.is_empty() {
98-
let reported = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
99-
return Ty::new_error(tcx, reported);
99+
let guar = self.report_trait_object_addition_traits_error(&regular_traits);
100+
return Ty::new_error(tcx, guar);
101+
}
102+
// We don't support empty trait objects.
103+
if regular_traits.is_empty() && auto_traits.is_empty() {
104+
let guar = self.report_trait_object_with_no_traits_error(span, &trait_bounds);
105+
return Ty::new_error(tcx, guar);
106+
}
107+
// Don't create a dyn trait if we have errors in the principal.
108+
if let Err(guar) = trait_bounds.error_reported() {
109+
return Ty::new_error(tcx, guar);
100110
}
101111

102112
// Check that there are no gross dyn-compatibility violations;

tests/crashes/130521.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//@ known-bug: #130521
22

33
#![feature(dyn_compatible_for_dispatch)]
4-
struct Vtable(dyn Cap);
4+
struct Vtable(dyn Cap<'static>);
55

66
trait Cap<'a> {}
77

tests/rustdoc-ui/unable-fulfill-trait.rs

-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
pub struct Foo<'a, 'b, T> {
44
field1: dyn Bar<'a, 'b>,
55
//~^ ERROR
6-
//~| ERROR
76
}
87

98
pub trait Bar<'x, 's, U>

tests/rustdoc-ui/unable-fulfill-trait.stderr

+3-10
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | field1: dyn Bar<'a, 'b>,
55
| ^^^ expected 1 generic argument
66
|
77
note: trait defined here, with 1 generic parameter: `U`
8-
--> $DIR/unable-fulfill-trait.rs:9:11
8+
--> $DIR/unable-fulfill-trait.rs:8:11
99
|
1010
LL | pub trait Bar<'x, 's, U>
1111
| ^^^ -
@@ -14,13 +14,6 @@ help: add missing generic argument
1414
LL | field1: dyn Bar<'a, 'b, U>,
1515
| +++
1616

17-
error[E0227]: ambiguous lifetime bound, explicit lifetime bound required
18-
--> $DIR/unable-fulfill-trait.rs:4:13
19-
|
20-
LL | field1: dyn Bar<'a, 'b>,
21-
| ^^^^^^^^^^^^^^^
22-
23-
error: aborting due to 2 previous errors
17+
error: aborting due to 1 previous error
2418

25-
Some errors have detailed explanations: E0107, E0227.
26-
For more information about an error, try `rustc --explain E0107`.
19+
For more information about this error, try `rustc --explain E0107`.

tests/ui/associated-types/issue-22560.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ trait Sub<Rhs=Self> {
77
}
88

99
type Test = dyn Add + Sub;
10-
//~^ ERROR E0393
11-
//~| ERROR E0191
12-
//~| ERROR E0393
13-
//~| ERROR E0225
10+
//~^ ERROR E0225
1411

1512
fn main() { }

tests/ui/associated-types/issue-22560.stderr

+2-52
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,6 @@ LL | type Test = dyn Add + Sub;
99
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add + Sub {}`
1010
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

12-
error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified
13-
--> $DIR/issue-22560.rs:9:17
14-
|
15-
LL | type Output;
16-
| ----------- `Output` defined here
17-
...
18-
LL | type Output;
19-
| ----------- `Output` defined here
20-
...
21-
LL | type Test = dyn Add + Sub;
22-
| ^^^ ^^^ associated type `Output` must be specified
23-
| |
24-
| associated type `Output` must be specified
25-
|
26-
help: specify the associated types
27-
|
28-
LL | type Test = dyn Add<Output = Type> + Sub<Output = Type>;
29-
| ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
30-
31-
error[E0393]: the type parameter `Rhs` must be explicitly specified
32-
--> $DIR/issue-22560.rs:9:17
33-
|
34-
LL | trait Add<Rhs=Self> {
35-
| ------------------- type parameter `Rhs` must be specified for this
36-
...
37-
LL | type Test = dyn Add + Sub;
38-
| ^^^
39-
|
40-
= note: because of the default `Self` reference, type parameters must be specified on object types
41-
help: set the type parameter to the desired type
42-
|
43-
LL | type Test = dyn Add<Rhs> + Sub;
44-
| +++++
45-
46-
error[E0393]: the type parameter `Rhs` must be explicitly specified
47-
--> $DIR/issue-22560.rs:9:23
48-
|
49-
LL | trait Sub<Rhs=Self> {
50-
| ------------------- type parameter `Rhs` must be specified for this
51-
...
52-
LL | type Test = dyn Add + Sub;
53-
| ^^^
54-
|
55-
= note: because of the default `Self` reference, type parameters must be specified on object types
56-
help: set the type parameter to the desired type
57-
|
58-
LL | type Test = dyn Add + Sub<Rhs>;
59-
| +++++
60-
61-
error: aborting due to 4 previous errors
12+
error: aborting due to 1 previous error
6213

63-
Some errors have detailed explanations: E0191, E0225, E0393.
64-
For more information about an error, try `rustc --explain E0191`.
14+
For more information about this error, try `rustc --explain E0225`.

tests/ui/associated-types/missing-associated-types.rs

-4
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@ trait Fine<Rhs>: Div<Rhs, Output = Rhs> {}
1111

1212
type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
1313
//~^ ERROR only auto traits can be used as additional traits in a trait object
14-
//~| ERROR the value of the associated types
1514
type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
1615
//~^ ERROR only auto traits can be used as additional traits in a trait object
17-
//~| ERROR the value of the associated types
1816
type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
1917
//~^ ERROR only auto traits can be used as additional traits in a trait object
20-
//~| ERROR the value of the associated types
2118
type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
2219
//~^ ERROR only auto traits can be used as additional traits in a trait object
23-
//~| ERROR the value of the associated types
2420
type Bal<Rhs> = dyn X<Rhs>;
2521
//~^ ERROR the value of the associated types
2622

tests/ui/associated-types/missing-associated-types.stderr

+5-78
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,8 @@ LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
99
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs> {}`
1010
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
1111

12-
error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified
13-
--> $DIR/missing-associated-types.rs:12:21
14-
|
15-
LL | type A;
16-
| ------ `A` defined here
17-
...
18-
LL | type Foo<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Y<Rhs>;
19-
| ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated type `A` must be specified
20-
| | | |
21-
| | | associated type `Output` must be specified
22-
| | associated type `Output` must be specified
23-
| associated type `Output` must be specified
24-
|
25-
help: specify the associated types
26-
|
27-
LL | type Foo<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs, Output = Type> + Y<Rhs, A = Type>;
28-
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
29-
3012
error[E0225]: only auto traits can be used as additional traits in a trait object
31-
--> $DIR/missing-associated-types.rs:15:32
13+
--> $DIR/missing-associated-types.rs:14:32
3214
|
3315
LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
3416
| -------- ^^^^^^^^ additional non-auto trait
@@ -38,33 +20,8 @@ LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
3820
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs> {}`
3921
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
4022

41-
error[E0191]: the value of the associated types `A` and `B` in `Z`, `Output` and `Output` in `Div`, `Output` in `Add`, `Output` in `Mul`, `Output` in `Sub` must be specified
42-
--> $DIR/missing-associated-types.rs:15:21
43-
|
44-
LL | type A;
45-
| ------ `A` defined here
46-
LL | type B;
47-
| ------ `B` defined here
48-
...
49-
LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
50-
| ^^^^^^^^ ^^^^^^^^ ^^^^^^ ^^^^^^ associated types `A`, `B`, `Output` must be specified
51-
| | | |
52-
| | | associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
53-
| | associated type `Output` must be specified
54-
| associated type `Output` must be specified
55-
|
56-
help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
57-
--> $DIR/missing-associated-types.rs:15:43
58-
|
59-
LL | type Bar<Rhs> = dyn Add<Rhs> + Sub<Rhs> + X<Rhs> + Z<Rhs>;
60-
| ^^^^^^
61-
help: specify the associated types
62-
|
63-
LL | type Bar<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + X<Rhs> + Z<Rhs, A = Type, B = Type, Output = Type>;
64-
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
65-
6623
error[E0225]: only auto traits can be used as additional traits in a trait object
67-
--> $DIR/missing-associated-types.rs:18:32
24+
--> $DIR/missing-associated-types.rs:16:32
6825
|
6926
LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
7027
| -------- ^^^^^^^^ additional non-auto trait
@@ -74,25 +31,8 @@ LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
7431
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Y<Rhs> {}`
7532
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
7633

77-
error[E0191]: the value of the associated types `A` in `Y`, `Output` in `Add`, `Output` in `Sub` must be specified
78-
--> $DIR/missing-associated-types.rs:18:21
79-
|
80-
LL | type A;
81-
| ------ `A` defined here
82-
...
83-
LL | type Baz<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Y<Rhs>;
84-
| ^^^^^^^^ ^^^^^^^^ ^^^^^^ associated type `A` must be specified
85-
| | |
86-
| | associated type `Output` must be specified
87-
| associated type `Output` must be specified
88-
|
89-
help: specify the associated types
90-
|
91-
LL | type Baz<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Y<Rhs, A = Type>;
92-
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
93-
9434
error[E0225]: only auto traits can be used as additional traits in a trait object
95-
--> $DIR/missing-associated-types.rs:21:32
35+
--> $DIR/missing-associated-types.rs:18:32
9636
|
9737
LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
9838
| -------- ^^^^^^^^ additional non-auto trait
@@ -102,28 +42,15 @@ LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
10242
= help: consider creating a new trait with all of these as supertraits and using that trait here instead: `trait NewTrait: Add<Rhs> + Sub<Rhs> + Fine<Rhs> {}`
10343
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
10444

105-
error[E0191]: the value of the associated types `Output` in `Add`, `Output` in `Sub` must be specified
106-
--> $DIR/missing-associated-types.rs:21:21
107-
|
108-
LL | type Bat<Rhs> = dyn Add<Rhs> + Sub<Rhs> + Fine<Rhs>;
109-
| ^^^^^^^^ ^^^^^^^^ associated type `Output` must be specified
110-
| |
111-
| associated type `Output` must be specified
112-
|
113-
help: specify the associated types
114-
|
115-
LL | type Bat<Rhs> = dyn Add<Rhs, Output = Type> + Sub<Rhs, Output = Type> + Fine<Rhs>;
116-
| ~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~
117-
11845
error[E0191]: the value of the associated types `Output` in `Div`, `Output` in `Mul` must be specified
119-
--> $DIR/missing-associated-types.rs:24:21
46+
--> $DIR/missing-associated-types.rs:20:21
12047
|
12148
LL | type Bal<Rhs> = dyn X<Rhs>;
12249
| ^^^^^^ associated types `Output` (from trait `Div`), `Output` (from trait `Mul`) must be specified
12350
|
12451
= help: consider introducing a new type parameter, adding `where` constraints using the fully-qualified path to the associated types
12552

126-
error: aborting due to 9 previous errors
53+
error: aborting due to 5 previous errors
12754

12855
Some errors have detailed explanations: E0191, E0225.
12956
For more information about an error, try `rustc --explain E0191`.

tests/ui/const-generics/not_wf_param_in_rpitit.rs

-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
trait Trait<const N: dyn Trait = bar> {
44
//~^ ERROR: cannot find value `bar` in this scope
55
//~| ERROR: cycle detected when computing type of `Trait::N`
6-
//~| ERROR: the trait `Trait` cannot be made into an object
7-
//~| ERROR: the trait `Trait` cannot be made into an object
8-
//~| ERROR: the trait `Trait` cannot be made into an object
96
async fn a() {}
107
}
118

tests/ui/const-generics/not_wf_param_in_rpitit.stderr

+3-73
Original file line numberDiff line numberDiff line change
@@ -18,77 +18,7 @@ LL | trait Trait<const N: dyn Trait = bar> {
1818
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1919
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
2020

21-
error[E0038]: the trait `Trait` cannot be made into an object
22-
--> $DIR/not_wf_param_in_rpitit.rs:3:22
23-
|
24-
LL | trait Trait<const N: dyn Trait = bar> {
25-
| ^^^^^^^^^ `Trait` cannot be made into an object
26-
|
27-
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
28-
--> $DIR/not_wf_param_in_rpitit.rs:9:14
29-
|
30-
LL | trait Trait<const N: dyn Trait = bar> {
31-
| ----- this trait cannot be made into an object...
32-
...
33-
LL | async fn a() {}
34-
| ^ ...because associated function `a` has no `self` parameter
35-
help: consider turning `a` into a method by giving it a `&self` argument
36-
|
37-
LL | async fn a(&self) {}
38-
| +++++
39-
help: alternatively, consider constraining `a` so it does not apply to trait objects
40-
|
41-
LL | async fn a() where Self: Sized {}
42-
| +++++++++++++++++
43-
44-
error[E0038]: the trait `Trait` cannot be made into an object
45-
--> $DIR/not_wf_param_in_rpitit.rs:3:13
46-
|
47-
LL | trait Trait<const N: dyn Trait = bar> {
48-
| ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
49-
|
50-
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
51-
--> $DIR/not_wf_param_in_rpitit.rs:9:14
52-
|
53-
LL | trait Trait<const N: dyn Trait = bar> {
54-
| ----- this trait cannot be made into an object...
55-
...
56-
LL | async fn a() {}
57-
| ^ ...because associated function `a` has no `self` parameter
58-
help: consider turning `a` into a method by giving it a `&self` argument
59-
|
60-
LL | async fn a(&self) {}
61-
| +++++
62-
help: alternatively, consider constraining `a` so it does not apply to trait objects
63-
|
64-
LL | async fn a() where Self: Sized {}
65-
| +++++++++++++++++
66-
67-
error[E0038]: the trait `Trait` cannot be made into an object
68-
--> $DIR/not_wf_param_in_rpitit.rs:3:13
69-
|
70-
LL | trait Trait<const N: dyn Trait = bar> {
71-
| ^^^^^^^^^^^^^^^^^^^^^^^^ `Trait` cannot be made into an object
72-
|
73-
note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
74-
--> $DIR/not_wf_param_in_rpitit.rs:9:14
75-
|
76-
LL | trait Trait<const N: dyn Trait = bar> {
77-
| ----- this trait cannot be made into an object...
78-
...
79-
LL | async fn a() {}
80-
| ^ ...because associated function `a` has no `self` parameter
81-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
82-
help: consider turning `a` into a method by giving it a `&self` argument
83-
|
84-
LL | async fn a(&self) {}
85-
| +++++
86-
help: alternatively, consider constraining `a` so it does not apply to trait objects
87-
|
88-
LL | async fn a() where Self: Sized {}
89-
| +++++++++++++++++
90-
91-
error: aborting due to 5 previous errors
21+
error: aborting due to 2 previous errors
9222

93-
Some errors have detailed explanations: E0038, E0391, E0425.
94-
For more information about an error, try `rustc --explain E0038`.
23+
Some errors have detailed explanations: E0391, E0425.
24+
For more information about an error, try `rustc --explain E0391`.

tests/ui/issues/issue-23024.rs

-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,4 @@ fn main()
88
println!("{:?}",(vfnfer[0] as dyn Fn)(3));
99
//~^ ERROR the precise format of `Fn`-family traits'
1010
//~| ERROR missing generics for trait `Fn`
11-
//~| ERROR the value of the associated type `Output` in `FnOnce`
1211
}

tests/ui/issues/issue-23024.stderr

+2-8
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,7 @@ help: add missing generic argument
1919
LL | println!("{:?}",(vfnfer[0] as dyn Fn<Args>)(3));
2020
| ++++++
2121

22-
error[E0191]: the value of the associated type `Output` in `FnOnce` must be specified
23-
--> $DIR/issue-23024.rs:8:39
24-
|
25-
LL | println!("{:?}",(vfnfer[0] as dyn Fn)(3));
26-
| ^^ help: specify the associated type: `Fn::<Output = Type>`
27-
28-
error: aborting due to 3 previous errors
22+
error: aborting due to 2 previous errors
2923

30-
Some errors have detailed explanations: E0107, E0191, E0658.
24+
Some errors have detailed explanations: E0107, E0658.
3125
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)