-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Add a diagnostic for similarly named traits #144674
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
base: master
Are you sure you want to change the base?
Add a diagnostic for similarly named traits #144674
Conversation
This comment has been minimized.
This comment has been minimized.
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
Outdated
Show resolved
Hide resolved
ff869dc
to
abdb087
Compare
This PR modifies cc @jieyouxu |
Fixed by using predicate_must_hold_modulo_regions |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
Outdated
Show resolved
Hide resolved
The current version is the following. I no longer browse the impls, so it is no longer per impl. It's mostly working (other::Trait or other::Trait<T> are working), however I still get weird behaviours with super traits and the GenericArgs . That's why I did not push the commit yet, some tests are broken, I am investigating. UPDATE: switch to the last commit directly and see update below regarding generics and ICE pub(crate) fn suggest_impl_similarly_named_trait(
&self,
err: &mut Diag<'_>,
obligation: &PredicateObligation<'tcx>,
trait_predicate: ty::PolyTraitPredicate<'tcx>,
) {
let trait_def_id = trait_predicate.def_id();
let trait_name = self.tcx.item_name(trait_def_id);
if let Some(other_trait_def_id) = self.tcx.all_traits_including_private().find(|def_id| {
if trait_def_id != *def_id && trait_name == self.tcx.item_name(def_id) {
if let Some(pred) = self.tcx.predicates_of(*def_id).instantiate(self.tcx, trait_predicate.skip_binder().trait_ref.args).predicates.iter().find(|clause| {
clause.as_trait_clause().map_or(false, |trait_clause| trait_clause.def_id() == *def_id)
})
{
let pred = pred.as_trait_clause().unwrap();
self.predicate_must_hold_modulo_regions(&Obligation::new(
self.tcx,
obligation.cause.clone(),
obligation.param_env,
pred,
))
} else {
false
}
} else {
false
}
}) {
err.note(format!(
"`{}` implements similarly named `{}`, but not `{}`",
trait_predicate.self_ty(),
self.tcx.def_path_str(other_trait_def_id),
trait_predicate.print_modifiers_and_trait_path()
));
}
()
} |
abdb087
to
532c561
Compare
This is another proposal, feedbacks are welcomed. I am not convinced about the part regarding the generic args. The idea being that you cannot select a similarly named trait with different generics (or different constraints), it does not makes sense and might cause ICE. |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
Outdated
Show resolved
Hide resolved
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
Outdated
Show resolved
Hide resolved
532c561
to
3fcbf63
Compare
This is another proposal, I have simplified the code. This is to show you the code before I merge it with the other suggestion. I have to analyze the other suggestion you were talking about and try to merge my code with it now. |
compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the impl lgtm now, I don't think we should have these two similar suggestions however (similarly named trait vs similarly named trait from different crate version), and believe they should be merged into 1
OK, thanks for your feedbacks. I will merge with the other suggestion and fix param.kind during the weekend |
3fcbf63
to
a6853be
Compare
Merged into the suggestion we have discussed above. I have kept each note/notice independent, because I have the feeling that the three notes/notices might still be emitted independently when you think about it. You might have similarly named traits within the same crate but also in different crates. You might have cases when similarly named traits are found but not traits with the same path (this is typically the case in some ui tests) |
@rustbot author |
Reminder, once the PR becomes ready for a review, use |
@lcnr I am a bit confused because we have:
and
which one are we talking about ? both ? Because currently my suggestion in the note_version_mismatch() function (into rustc_trait_selection). I can easily be exclusive with the second one (as I am in the same function), the first suggestion being inside another compiler crate. There is way to know that a suggestion was already emitted from another compiler crate ? (rustc_hir_typeck in our case) |
compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
Outdated
Show resolved
Hide resolved
66cc4f4
to
35d44c6
Compare
Renaming the fonction to note_impl_ambiguous_trait() . What about the rest ? Do you want that I investigate something ? |
/// a probable version mismatch is added to `err`. Otherwise if it implements | ||
/// another trait with the same name, a note message about a similarly named | ||
/// trait is added to `err`. | ||
fn note_impl_ambiguous_trait( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn note_impl_ambiguous_trait( | |
fn note_different_trait_with_same_name( |
// If there are multiple different versions of a crate in the dependency graph, there is already | ||
// a suggestion designed for this purpose in the rustc_hir_typeck compiler crate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to a FIXME and explicitly mention FnCtxt::detect_and_explain_multiple_crate_versions_of_trait_item
🤔
I don't really understand when this doesn't trigger but the method one does 🤔 I feel like the method one is just a subset of the above note and should be removed 🤔
moving this to zulip https://rust-lang.zulipchat.com/#narrow/channel/182449-t-compiler.2Fhelp/topic/.28PR.20.23144674.29.20Merge.20multiple.20suggestions.20into.20a.20single/with/536652274
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So to continue the discussion, as dicussed on zulip , by disabling detect_and_explain_multiple_crate_versions_of_trait_item
(it returns false) and updating note_different_trait_with_same_name
(the new note_version_mismatch
) my suggestion is emitted in tests/run-make. But only for E0599 , not for E0277. for E0277 the old disabled suggestion "note: there are multiple different versions of crate dependency
in the dependency graph" is still shown... Suppose that depending on the constrainst on the instanciated DiagCtxt (when instanciating the err
) the span_note might be attached or ignored for a given error... let's admit that... but how is it technically possible to still see the message ? It is disabled in the code... I think I need help to understand this
35d44c6
to
db2569b
Compare
The other CCed PR, is quit similar no ? ^^ |
@rustbot ready |
So I have basically no ideas why the output of the compiler is not completly updated when I disable the suggestion in EDIT: see #t-compiler/help > (PR #144674) Merge multiple suggestions into a single @ 💬 I am gonna to test by removing the 3nd diagnostic @rustbot author |
db2569b
to
de2b67f
Compare
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
@rustbot ready This is a proposal of a first refactoring. I have voluntarily kept things simple, so it is maintainable. The idea being to not report exactly the same messages as before, but to report a single diagnostic about possible different crate versions instead, and this in all cases. Otherwises, in the other case, if we find another trait with the same name and the same "interface", which is implemented by the Ty, we report a similarly named trait. I am opened to suggestions. |
This comment has been minimized.
This comment has been minimized.
de2b67f
to
4ceac06
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
maybe even split the function into two sub-functions here
- check_same_trait_different_version
- check_same_name_different_path
and only call teh second one if the first one didn't say anything
} | ||
err.span_note(multi_span, msg); | ||
true | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you've always returning false
if the argument is None
, i generally prefer doing this in the caller. Is this method call code even reachable? I remember you saying that even replacing it with a panic never triggers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is reachable by the error E0599 "no method named foo
found for struct dep_2_reexport::Type
in the current scope" from the test tests/run-make/crate-loading/multiple-dep-versions
&& (self.tcx.def_path_str(trait_def_id) == required_trait_path | ||
|| self.tcx.crate_name(trait_def_id.krate) == krate | ||
&& self.tcx.item_name(trait_def_id) == name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when is self.tcx.crate_name(trait_def_id.krate) == krate && self.tcx.item_name(trait_def_id) == name
false but self.tcx.def_path_str(trait_def_id) == required_trait_path
holds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It used by tests/ui/traits/bound/same-crate-name.rs
, disabling this case makes the test fail.
4ceac06
to
2f81c6e
Compare
Fixed, see the replies to your questions above |
This comment has been minimized.
This comment has been minimized.
…equired one This is useful when you have two dependencies that use different trait for the same thing and with the same name. The user can accidentally implement the bad one which might be confusing. This commits refactorizes existing diagnostics about multiple different crates with the same version and adds a note when similarly named traits are found. Both diagnostics are merged into a single function.
2f81c6e
to
1181c3f
Compare
☔ The latest upstream changes (presumably #147397) made this pull request unmergeable. Please resolve the merge conflicts. |
cc #133123
This is a first proposal, suggestions are welcome