Change:
For generic types, the prelude collision lint can produce suggestions that do not compile: Code: Suggestion from the prelude collision lint: Error after applying the suggestion: <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
cc
My guess is this should be a simple fix, just copying the code the lint already uses for adding unspecified generics (). Will try implementing a fix soon.
assign
release-assignment
The code related to this lint lives in the . The relevant suggestion is generated here: The "self type" string comes from here: The code for traits is here: This is actually just a touch tricky, because currently we are getting the "self type" just by copying the text the user wrote. Probably the most correct thing for us to do would be to examine the 'self expression' HIR and, if it is a plain path, then to append the and otherwise skip it. Specifically, the other case that I am thinking about is code like this: Currently , meaning that it offers the suggestion "disambiguate the associated function: ".
claim
great! Let us know if you need anything or make progress. This issue is fairly time sensitive.
release-assignment
claim

Discussion:
use rustc_errors::Applicability; use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; <del> use rustc_middle::ty::{Ref, Ty}; </del> <ins> use rustc_middle::ty::{Adt, Ref, Ty}; </ins> use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::Underscore; use rustc_span::symbol::{sym, Ident};

method_name.name )); <del> let self_ty = self </del> <ins> let self_ty_name = self </ins> .sess() .source_map() .span_to_snippet(self_ty_span) .unwrap_or_else(|_| self_ty.to_string()); <ins> let self_ty_generics_count = match self_ty.kind() { // Get the number of generics the self type has (if an Adt) unless we can determine that // the user has written the self type with generics already which we (naively) do by looking // for a "<" in `self_ty_name`. Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(), _ => 0, }; let self_ty_generics = if self_ty_generics_count > 0 { format!("<{}>", vec!["_"; self_ty_generics_count].join(", ")) } else { String::new() }; </ins> lint.span_suggestion( span, "disambiguate the associated function", <del> format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,), </del> <ins> format!( "<{}{} as {}>::{}", self_ty_name, self_ty_generics, trait_name, method_name.name, ), </ins> Applicability::MachineApplicable, );

<del> // check-pass // edition:2021 // compile-flags: -Zunstable-options fn main() { let _: u16 = 123i32.try_into().unwrap(); } </del>

<ins> // test for https://github.com/rust-lang/rust/issues/86940 // run-rustfix // edition:2018 // check-pass #![warn(rust_2021_prelude_collisions)] #![allow(dead_code)] #![allow(unused_imports)] struct Generic<T, U>(T, U); trait MyFromIter { fn from_iter(_: i32) -> Self; } impl MyFromIter for Generic<i32, i32> { fn from_iter(x: i32) -> Self { Self(x, x) } } impl std::iter::FromIterator<i32> for Generic<i32, i32> { fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self { todo!() } } fn main() { <Generic<_, _> as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) <Generic::<i32, i32> as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) <Generic::<_, _> as MyFromIter>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) } </ins>

<ins> // test for https://github.com/rust-lang/rust/issues/86940 // run-rustfix // edition:2018 // check-pass #![warn(rust_2021_prelude_collisions)] #![allow(dead_code)] #![allow(unused_imports)] struct Generic<T, U>(T, U); trait MyFromIter { fn from_iter(_: i32) -> Self; } impl MyFromIter for Generic<i32, i32> { fn from_iter(x: i32) -> Self { Self(x, x) } } impl std::iter::FromIterator<i32> for Generic<i32, i32> { fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self { todo!() } } fn main() { Generic::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) Generic::<i32, i32>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) Generic::<_, _>::from_iter(1); //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021 //~| this is accepted in the current edition (Rust 2018) } </ins>

<ins> warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:28:5 | LL |     Generic::from_iter(1); |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter` | note: the lint level is defined here --> $DIR/future-prelude-collision-generic.rs:5:9 | LL | #![warn(rust_2021_prelude_collisions)] |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:31:5 | LL |     Generic::<i32, i32>::from_iter(1); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter` | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> warning: trait-associated function `from_iter` will become ambiguous in Rust 2021 --> $DIR/future-prelude-collision-generic.rs:34:5 | LL |     Generic::<_, _>::from_iter(1); |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter` | = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684> warning: 3 warnings emitted </ins>

<ins> // check-pass // edition:2021 // compile-flags: -Zunstable-options fn main() { let _: u16 = 123i32.try_into().unwrap(); } </ins>