Skip to content

Note if the user wants to use associated items of a trait directly #111324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3635,7 +3635,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {

fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
let tcx = self.tcx();
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
if let hir::TyKind::TraitObject([poly_trait_ref, res @ ..], _, TraitObjectSyntax::None) =
self_ty.kind
{
let needs_bracket = in_path
Expand Down Expand Up @@ -3680,6 +3680,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
Applicability::MachineApplicable,
);
}
// note if the user wants to use associated items of a trait directly
if in_path && res.len() == 0 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we checking res here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because I think there is no need to make this note for trait objects with multi traits such as <TraitA + TraitB>::foo()

diag.span_label(
self_ty.span,
"no desired associated item found in this trait, if you do not want to use a bare trait object here",
);
}
// check if the impl trait that we are considering is a impl of a local trait
self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
diag.emit();
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/associated-item/issue-111312.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// edition:2021

trait Has {
fn has() {}
}

trait HasNot {}

fn main() {
HasNot::has(); //~ ERROR E0782
//~^ ERROR E0599
}
28 changes: 28 additions & 0 deletions tests/ui/associated-item/issue-111312.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/issue-111312.rs:10:5
|
LL | HasNot::has();
| ^^^^^^ no desired associated item found in this trait, if you do not want to use a bare trait object here
|
help: add `dyn` keyword before this trait
|
LL | <dyn HasNot>::has();
| ++++ +

error[E0599]: no function or associated item named `has` found for trait object `dyn HasNot` in the current scope
--> $DIR/issue-111312.rs:10:13
|
LL | HasNot::has();
| ^^^ function or associated item not found in `dyn HasNot`
|
= help: items from traits can only be used if the trait is implemented and in scope
note: `Has` defines an item `has`, perhaps you need to implement it
--> $DIR/issue-111312.rs:3:1
|
LL | trait Has {
| ^^^^^^^^^

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0599, E0782.
For more information about an error, try `rustc --explain E0599`.
2 changes: 1 addition & 1 deletion tests/ui/editions/dyn-trait-sugg-2021.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ error[E0782]: trait objects must include the `dyn` keyword
--> $DIR/dyn-trait-sugg-2021.rs:10:5
|
LL | Foo::hi(123);
| ^^^
| ^^^ no desired associated item found in this trait, if you do not want to use a bare trait object here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is the only suggestion I don't think it helps much. It's probably better to first do something different for when <dyn A as B>::something and dyn A: B does not hold. Because in that case we are certain that the user didn't want A::something to mean <dyn A as B>::something.

|
help: add `dyn` keyword before this trait
|
Expand Down