Skip to content

Commit 46216f9

Browse files
Do not create trait object type if missing associated types
1 parent 871926d commit 46216f9

File tree

15 files changed

+27
-206
lines changed

15 files changed

+27
-206
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
222222
}
223223
}
224224

225-
self.complain_about_missing_assoc_tys(
225+
if let Err(guar) = self.complain_about_missing_assoc_tys(
226226
principal_span,
227227
needed_associated_types,
228228
potential_assoc_types,
229229
hir_trait_bounds,
230-
);
230+
) {
231+
return Ty::new_error(tcx, guar);
232+
}
231233

232234
// De-duplicate auto traits so that, e.g., `dyn Trait + Send + Send` is the same as
233235
// `dyn Trait + Send`.

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
720720
missing_assoc_types: FxIndexSet<(DefId, ty::PolyTraitRef<'tcx>)>,
721721
potential_assoc_types: Vec<usize>,
722722
trait_bounds: &[hir::PolyTraitRef<'_>],
723-
) {
723+
) -> Result<(), ErrorGuaranteed> {
724724
if missing_assoc_types.is_empty() {
725-
return;
725+
return Ok(());
726726
}
727727

728728
let tcx = self.tcx();
@@ -736,28 +736,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
736736

737737
// Account for things like `dyn Foo + 'a`, like in tests `issue-22434.rs` and
738738
// `issue-22560.rs`.
739-
let mut dyn_compatibility_violations = false;
739+
let mut dyn_compatibility_violations = Ok(());
740740
for (assoc_item, trait_ref) in &missing_assoc_types {
741741
names.entry(trait_ref).or_default().push(assoc_item.name);
742742
names_len += 1;
743743

744744
let violations =
745745
dyn_compatibility_violations_for_assoc_item(tcx, trait_ref.def_id(), *assoc_item);
746746
if !violations.is_empty() {
747-
report_dyn_incompatibility(
747+
dyn_compatibility_violations = Err(report_dyn_incompatibility(
748748
tcx,
749749
principal_span,
750750
None,
751751
trait_ref.def_id(),
752752
&violations,
753753
)
754-
.emit();
755-
dyn_compatibility_violations = true;
754+
.emit());
756755
}
757756
}
758-
if dyn_compatibility_violations {
759-
return;
760-
}
757+
758+
dyn_compatibility_violations?;
761759

762760
// related to issue #91997, turbofishes added only when in an expr or pat
763761
let mut in_expr_or_pat = false;
@@ -962,7 +960,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
962960
}
963961
}
964962

965-
err.emit();
963+
Err(err.emit())
966964
}
967965

968966
/// On ambiguous associated type, look for an associated function whose name matches the

tests/crashes/131668.rs

Lines changed: 0 additions & 12 deletions
This file was deleted.

tests/ui/associated-type-bounds/overlaping-bound-suggestion.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ trait Item {
55
pub struct Flatten<I> {
66
inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
77
//~^ ERROR E0191
8-
//~| ERROR E0223
98
}
109

1110
fn main() {}

tests/ui/associated-type-bounds/overlaping-bound-suggestion.stderr

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,6 @@ error[E0191]: the value of the associated types `Item` and `IntoIter` in `IntoIt
44
LL | inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: specify the associated types: `IntoIterator<Item: IntoIterator<Item: >, Item = Type, IntoIter = Type>`
66

7-
error[E0223]: ambiguous associated type
8-
--> $DIR/overlaping-bound-suggestion.rs:6:13
9-
|
10-
LL | inner: <IntoIterator<Item: IntoIterator<Item: >>::IntoIterator as Item>::Core,
11-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12-
|
13-
help: if there were a trait named `Example` with associated type `IntoIterator` implemented for `(dyn IntoIterator + 'static)`, you could use the fully-qualified path
14-
|
15-
LL | inner: <<(dyn IntoIterator + 'static) as Example>::IntoIterator as Item>::Core,
16-
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17-
18-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
198

20-
Some errors have detailed explanations: E0191, E0223.
21-
For more information about an error, try `rustc --explain E0191`.
9+
For more information about this error, try `rustc --explain E0191`.

tests/ui/async-await/async-fn/dyn-pos.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
#![feature(async_closure)]
44

55
fn foo(x: &dyn async Fn()) {}
6-
//~^ ERROR the trait `AsyncFn` cannot be made into an object
7-
//~| ERROR the trait `AsyncFnMut` cannot be made into an object
8-
//~| ERROR the trait `AsyncFnMut` cannot be made into an object
9-
//~| ERROR the trait `AsyncFnMut` cannot be made into an object
6+
//~^ ERROR the trait `AsyncFnMut` cannot be made into an object
107

118
fn main() {}

tests/ui/async-await/async-fn/dyn-pos.stderr

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,52 +13,6 @@ note: for a trait to be "dyn-compatible" it needs to allow building a vtable to
1313
&mut F
1414
std::boxed::Box<F, A>
1515

16-
error[E0038]: the trait `AsyncFnMut` cannot be made into an object
17-
--> $DIR/dyn-pos.rs:5:16
18-
|
19-
LL | fn foo(x: &dyn async Fn()) {}
20-
| ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object
21-
|
22-
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>
23-
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
24-
|
25-
= note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
26-
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
27-
&F
28-
&mut F
29-
std::boxed::Box<F, A>
30-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
31-
32-
error[E0038]: the trait `AsyncFnMut` cannot be made into an object
33-
--> $DIR/dyn-pos.rs:5:16
34-
|
35-
LL | fn foo(x: &dyn async Fn()) {}
36-
| ^^^^^^^^^^ `AsyncFnMut` cannot be made into an object
37-
|
38-
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>
39-
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
40-
|
41-
= note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
42-
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFnMut` for this new enum and using it instead:
43-
&F
44-
&mut F
45-
std::boxed::Box<F, A>
46-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
47-
48-
error[E0038]: the trait `AsyncFn` cannot be made into an object
49-
--> $DIR/dyn-pos.rs:5:12
50-
|
51-
LL | fn foo(x: &dyn async Fn()) {}
52-
| ^^^^^^^^^^^^^^ `AsyncFn` cannot be made into an object
53-
|
54-
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>
55-
--> $SRC_DIR/core/src/ops/async_function.rs:LL:COL
56-
|
57-
= note: the trait cannot be made into an object because it contains the generic associated type `CallRefFuture`
58-
= help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `AsyncFn` for this new enum and using it instead:
59-
&F
60-
std::boxed::Box<F, A>
61-
62-
error: aborting due to 4 previous errors
16+
error: aborting due to 1 previous error
6317

6418
For more information about this error, try `rustc --explain E0038`.

tests/ui/dyn-compatibility/missing-assoc-type.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,5 @@ trait Foo {
33
}
44

55
fn bar(x: &dyn Foo) {} //~ ERROR the trait `Foo` cannot be made into an object
6-
//~^ ERROR the trait `Foo` cannot be made into an object
7-
//~| ERROR the trait `Foo` cannot be made into an object
8-
//~| ERROR the trait `Foo` cannot be made into an object
96

107
fn main() {}

tests/ui/dyn-compatibility/missing-assoc-type.stderr

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,53 +13,6 @@ LL | type Bar<T>;
1313
| ^^^ ...because it contains the generic associated type `Bar`
1414
= help: consider moving `Bar` to another trait
1515

16-
error[E0038]: the trait `Foo` cannot be made into an object
17-
--> $DIR/missing-assoc-type.rs:5:16
18-
|
19-
LL | fn bar(x: &dyn Foo) {}
20-
| ^^^ `Foo` cannot be made into an object
21-
|
22-
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>
23-
--> $DIR/missing-assoc-type.rs:2:10
24-
|
25-
LL | trait Foo {
26-
| --- this trait cannot be made into an object...
27-
LL | type Bar<T>;
28-
| ^^^ ...because it contains the generic associated type `Bar`
29-
= help: consider moving `Bar` to another trait
30-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
31-
32-
error[E0038]: the trait `Foo` cannot be made into an object
33-
--> $DIR/missing-assoc-type.rs:5:16
34-
|
35-
LL | fn bar(x: &dyn Foo) {}
36-
| ^^^ `Foo` cannot be made into an object
37-
|
38-
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>
39-
--> $DIR/missing-assoc-type.rs:2:10
40-
|
41-
LL | trait Foo {
42-
| --- this trait cannot be made into an object...
43-
LL | type Bar<T>;
44-
| ^^^ ...because it contains the generic associated type `Bar`
45-
= help: consider moving `Bar` to another trait
46-
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
47-
48-
error[E0038]: the trait `Foo` cannot be made into an object
49-
--> $DIR/missing-assoc-type.rs:5:12
50-
|
51-
LL | fn bar(x: &dyn Foo) {}
52-
| ^^^^^^^ `Foo` cannot be made into an object
53-
|
54-
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>
55-
--> $DIR/missing-assoc-type.rs:2:10
56-
|
57-
LL | trait Foo {
58-
| --- this trait cannot be made into an object...
59-
LL | type Bar<T>;
60-
| ^^^ ...because it contains the generic associated type `Bar`
61-
= help: consider moving `Bar` to another trait
62-
63-
error: aborting due to 4 previous errors
16+
error: aborting due to 1 previous error
6417

6518
For more information about this error, try `rustc --explain E0038`.

tests/ui/issues/issue-21950.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,5 @@ impl Add for i32 {
88

99
fn main() {
1010
let x = &10 as &dyn Add;
11-
//~^ ERROR E0393
12-
//~| ERROR E0191
11+
//~^ ERROR E0191
1312
}

0 commit comments

Comments
 (0)