Skip to content

Commit fb27c4c

Browse files
authored
Rollup merge of #87557 - rylev:fix-invalid-prelude-collision-error, r=nikomatsakis
Fix issue with autofix for ambiguous associated function from Rust 2021 prelude when struct is generic Fixes #86940 The test cases and associated issue should make it clear what specifically this is meant to fix. The fix is slightly hacky in that we check against the literal source code of the call site for the presence of `<` in order to determine if the user has included the generics for the struct (meaning we don't need to include them for them). r? ``@nikomatsakis``
2 parents f7a2a22 + 578fcbd commit fb27c4c

File tree

5 files changed

+126
-3
lines changed

5 files changed

+126
-3
lines changed

compiler/rustc_typeck/src/check/method/prelude2021.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_ast::Mutability;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_middle::ty::subst::InternalSubsts;
8-
use rustc_middle::ty::{Ref, Ty};
8+
use rustc_middle::ty::{Adt, Ref, Ty};
99
use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
1010
use rustc_span::symbol::kw::Underscore;
1111
use rustc_span::symbol::{sym, Ident};
@@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
255255
method_name.name
256256
));
257257

258-
let self_ty = self
258+
let self_ty_name = self
259259
.sess()
260260
.source_map()
261261
.span_to_snippet(self_ty_span)
262262
.unwrap_or_else(|_| self_ty.to_string());
263263

264+
let self_ty_generics_count = match self_ty.kind() {
265+
// Get the number of generics the self type has (if an Adt) unless we can determine that
266+
// the user has written the self type with generics already which we (naively) do by looking
267+
// for a "<" in `self_ty_name`.
268+
Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
269+
_ => 0,
270+
};
271+
let self_ty_generics = if self_ty_generics_count > 0 {
272+
format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
273+
} else {
274+
String::new()
275+
};
264276
lint.span_suggestion(
265277
span,
266278
"disambiguate the associated function",
267-
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
279+
format!(
280+
"<{}{} as {}>::{}",
281+
self_ty_name, self_ty_generics, trait_name, method_name.name,
282+
),
268283
Applicability::MachineApplicable,
269284
);
270285

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// test for https://github.com/rust-lang/rust/issues/86940
2+
// run-rustfix
3+
// edition:2018
4+
// check-pass
5+
#![warn(rust_2021_prelude_collisions)]
6+
#![allow(dead_code)]
7+
#![allow(unused_imports)]
8+
9+
struct Generic<T, U>(T, U);
10+
11+
trait MyFromIter {
12+
fn from_iter(_: i32) -> Self;
13+
}
14+
15+
impl MyFromIter for Generic<i32, i32> {
16+
fn from_iter(x: i32) -> Self {
17+
Self(x, x)
18+
}
19+
}
20+
21+
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
22+
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
23+
todo!()
24+
}
25+
}
26+
27+
fn main() {
28+
<Generic<_, _> as MyFromIter>::from_iter(1);
29+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
30+
//~| this is accepted in the current edition (Rust 2018)
31+
<Generic::<i32, i32> as MyFromIter>::from_iter(1);
32+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
33+
//~| this is accepted in the current edition (Rust 2018)
34+
<Generic::<_, _> as MyFromIter>::from_iter(1);
35+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
36+
//~| this is accepted in the current edition (Rust 2018)
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// test for https://github.com/rust-lang/rust/issues/86940
2+
// run-rustfix
3+
// edition:2018
4+
// check-pass
5+
#![warn(rust_2021_prelude_collisions)]
6+
#![allow(dead_code)]
7+
#![allow(unused_imports)]
8+
9+
struct Generic<T, U>(T, U);
10+
11+
trait MyFromIter {
12+
fn from_iter(_: i32) -> Self;
13+
}
14+
15+
impl MyFromIter for Generic<i32, i32> {
16+
fn from_iter(x: i32) -> Self {
17+
Self(x, x)
18+
}
19+
}
20+
21+
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
22+
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
23+
todo!()
24+
}
25+
}
26+
27+
fn main() {
28+
Generic::from_iter(1);
29+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
30+
//~| this is accepted in the current edition (Rust 2018)
31+
Generic::<i32, i32>::from_iter(1);
32+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
33+
//~| this is accepted in the current edition (Rust 2018)
34+
Generic::<_, _>::from_iter(1);
35+
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
36+
//~| this is accepted in the current edition (Rust 2018)
37+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
2+
--> $DIR/future-prelude-collision-generic.rs:28:5
3+
|
4+
LL | Generic::from_iter(1);
5+
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/future-prelude-collision-generic.rs:5:9
9+
|
10+
LL | #![warn(rust_2021_prelude_collisions)]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
13+
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
14+
15+
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
16+
--> $DIR/future-prelude-collision-generic.rs:31:5
17+
|
18+
LL | Generic::<i32, i32>::from_iter(1);
19+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
20+
|
21+
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
22+
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
23+
24+
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
25+
--> $DIR/future-prelude-collision-generic.rs:34:5
26+
|
27+
LL | Generic::<_, _>::from_iter(1);
28+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
29+
|
30+
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
31+
= note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
32+
33+
warning: 3 warnings emitted
34+
File renamed without changes.

0 commit comments

Comments
 (0)