Skip to content

Commit 8140dcd

Browse files
committed
Emit method not found error for object safe traits without dyn
Given `Trait::foo()` in edition 2021 where `Trait` is object safe and `foo` isn't resolved, emit E0782 instead of marking the expression as `{type error}`, as `foo` not being part of `Trait` is more useful information. If `Trait` *isn't* object safe, then the resolve error isn't as useful because E0782 will have more actionable feedback.
1 parent 8ee6812 commit 8140dcd

File tree

5 files changed

+49
-10
lines changed

5 files changed

+49
-10
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
8181
}
8282

8383
if !object_safe && self_ty.span.can_be_used_for_suggestions() {
84-
// suggest_impl_trait_on_bare_trait(tcx, &mut diag, self_ty);
8584
let parent = tcx.parent_hir_node(self_ty.hir_id);
8685
suggest_path_on_bare_trait(tcx, &mut diag, parent);
8786
}
8887

8988
// Check if the impl trait that we are considering is an impl of a local trait.
9089
self.maybe_suggest_blanket_trait_impl(self_ty, &mut diag);
9190
self.maybe_suggest_assoc_ty_bound(self_ty, &mut diag);
91+
92+
if object_safe {
93+
let parents = self.tcx().hir().parent_iter(self_ty.hir_id);
94+
for (_, parent) in parents {
95+
let hir::Node::Expr(expr) = parent else {
96+
break;
97+
};
98+
if let hir::ExprKind::Path(hir::QPath::TypeRelative(_, segment)) = expr.kind
99+
&& let Res::Err = segment.res
100+
{
101+
// If the trait is object safe *and* there's a path segment that couldn't be
102+
// resolved, we know that we will have a resolve error later. If there's an
103+
// unresolved segment *and* the trait is not object safe, then no other
104+
// error would have been emitted, so we always emit an error in that case.
105+
diag.emit();
106+
return None;
107+
}
108+
}
109+
}
92110
diag.stash(self_ty.span, StashKey::TraitMissingMethod)
93111
} else {
94112
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, |lint| {

tests/ui/resolve/issue-111312.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ trait Has {
77
trait HasNot {}
88

99
fn main() {
10-
<dyn HasNot>::has();
10+
HasNot::has();
1111
//~^ ERROR no function or associated item named `has` found for trait `HasNot`
12+
//~| ERROR trait objects must include the `dyn` keyword
1213
}

tests/ui/resolve/issue-111312.stderr

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,27 @@
1-
error[E0599]: no function or associated item named `has` found for trait `HasNot`
2-
--> $DIR/issue-111312.rs:10:19
1+
error[E0782]: trait objects must include the `dyn` keyword
2+
--> $DIR/issue-111312.rs:10:5
3+
|
4+
LL | HasNot::has();
5+
| ^^^^^^
6+
|
7+
help: add `dyn` keyword before this trait
38
|
49
LL | <dyn HasNot>::has();
5-
| ^^^ function or associated item not found in `HasNot`
10+
| ++++ +
11+
12+
error[E0599]: no function or associated item named `has` found for trait `HasNot`
13+
--> $DIR/issue-111312.rs:10:13
14+
|
15+
LL | HasNot::has();
16+
| ^^^ function or associated item not found in `HasNot`
617
|
718
note: `Has` defines an item `has`
819
--> $DIR/issue-111312.rs:3:1
920
|
1021
LL | trait Has {
1122
| ^^^^^^^^^
1223

13-
error: aborting due to 1 previous error
24+
error: aborting due to 2 previous errors
1425

15-
For more information about this error, try `rustc --explain E0599`.
26+
Some errors have detailed explanations: E0599, E0782.
27+
For more information about an error, try `rustc --explain E0599`.

tests/ui/resolve/issue-111727.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22

33
fn main() {
44
std::any::Any::create();
5-
//~^ ERROR trait objects must include the `dyn` keyword
5+
//~^ ERROR no function or associated item named `create` found for trait `Any`
6+
//~| ERROR trait objects must include the `dyn` keyword
67
}

tests/ui/resolve/issue-111727.stderr

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ help: add `dyn` keyword before this trait
99
LL | <dyn std::any::Any>::create();
1010
| ++++ +
1111

12-
error: aborting due to 1 previous error
12+
error[E0599]: no function or associated item named `create` found for trait `Any`
13+
--> $DIR/issue-111727.rs:4:20
14+
|
15+
LL | std::any::Any::create();
16+
| ^^^^^^ function or associated item not found in `Any`
17+
18+
error: aborting due to 2 previous errors
1319

14-
For more information about this error, try `rustc --explain E0782`.
20+
Some errors have detailed explanations: E0599, E0782.
21+
For more information about an error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)