mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
Rollup merge of #88496 - m-ou-se:prelude-collision-lifetime-generics, r=petrochenkov
Fix prelude collision lint suggestion for generics with lifetimes Fixes https://github.com/rust-lang/rust/issues/88470 cc `@nikomatsakis`
This commit is contained in:
commit
fdf9c09c50
@ -239,47 +239,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
|
let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
|
||||||
let trait_generics = self.tcx.generics_of(pick.item.container.id());
|
let trait_generics = self.tcx.generics_of(pick.item.container.id());
|
||||||
|
|
||||||
let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
|
let trait_name =
|
||||||
let trait_name = if parameter_count == 0 {
|
if trait_generics.params.len() <= trait_generics.has_self as usize {
|
||||||
trait_path
|
trait_path
|
||||||
} else {
|
} else {
|
||||||
format!(
|
let counts = trait_generics.own_counts();
|
||||||
"{}<{}>",
|
format!(
|
||||||
trait_path,
|
"{}<{}>",
|
||||||
std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
|
trait_path,
|
||||||
)
|
std::iter::repeat("'_")
|
||||||
};
|
.take(counts.lifetimes)
|
||||||
|
.chain(std::iter::repeat("_").take(
|
||||||
|
counts.types + counts.consts - trait_generics.has_self as usize
|
||||||
|
))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
let mut lint = lint.build(&format!(
|
let mut lint = lint.build(&format!(
|
||||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||||
method_name.name
|
method_name.name
|
||||||
));
|
));
|
||||||
|
|
||||||
let self_ty_name = self
|
let mut self_ty_name = self
|
||||||
.sess()
|
.sess()
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_snippet(self_ty_span)
|
.span_to_snippet(self_ty_span)
|
||||||
.unwrap_or_else(|_| self_ty.to_string());
|
.unwrap_or_else(|_| self_ty.to_string());
|
||||||
|
|
||||||
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
|
||||||
// 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
|
||||||
// the user has written the self type with generics already which we (naively) do by looking
|
// for a "<" in `self_ty_name`.
|
||||||
// for a "<" in `self_ty_name`.
|
if !self_ty_name.contains('<') {
|
||||||
Adt(def, _) if !self_ty_name.contains('<') => self.tcx.generics_of(def.did).count(),
|
if let Adt(def, _) = self_ty.kind() {
|
||||||
_ => 0,
|
let generics = self.tcx.generics_of(def.did);
|
||||||
};
|
if !generics.params.is_empty() {
|
||||||
let self_ty_generics = if self_ty_generics_count > 0 {
|
let counts = generics.own_counts();
|
||||||
format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
|
self_ty_name += &format!(
|
||||||
} else {
|
"<{}>",
|
||||||
String::new()
|
std::iter::repeat("'_")
|
||||||
};
|
.take(counts.lifetimes)
|
||||||
|
.chain(std::iter::repeat("_").take(counts.types + counts.consts))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
lint.span_suggestion(
|
lint.span_suggestion(
|
||||||
span,
|
span,
|
||||||
"disambiguate the associated function",
|
"disambiguate the associated function",
|
||||||
format!(
|
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
|
||||||
"<{}{} as {}>::{}",
|
|
||||||
self_ty_name, self_ty_generics, trait_name, method_name.name,
|
|
||||||
),
|
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
// See https://github.com/rust-lang/rust/issues/88470
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2018
|
||||||
|
// check-pass
|
||||||
|
#![warn(rust_2021_prelude_collisions)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
pub trait PyTryFrom<'v, T>: Sized {
|
||||||
|
fn try_from<V>(value: V) -> Result<&'v Self, T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyTryInto<T>: Sized {
|
||||||
|
fn try_into(&self) -> Result<&T, i32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl<U> PyTryInto<U> for Foo
|
||||||
|
where
|
||||||
|
U: for<'v> PyTryFrom<'v, i32>,
|
||||||
|
{
|
||||||
|
fn try_into(&self) -> Result<&U, i32> {
|
||||||
|
<U as PyTryFrom<'_, _>>::try_from(self)
|
||||||
|
//~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
|
||||||
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,30 @@
|
|||||||
|
// See https://github.com/rust-lang/rust/issues/88470
|
||||||
|
// run-rustfix
|
||||||
|
// edition:2018
|
||||||
|
// check-pass
|
||||||
|
#![warn(rust_2021_prelude_collisions)]
|
||||||
|
#![allow(dead_code)]
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
|
pub trait PyTryFrom<'v, T>: Sized {
|
||||||
|
fn try_from<V>(value: V) -> Result<&'v Self, T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PyTryInto<T>: Sized {
|
||||||
|
fn try_into(&self) -> Result<&T, i32>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl<U> PyTryInto<U> for Foo
|
||||||
|
where
|
||||||
|
U: for<'v> PyTryFrom<'v, i32>,
|
||||||
|
{
|
||||||
|
fn try_into(&self) -> Result<&U, i32> {
|
||||||
|
U::try_from(self)
|
||||||
|
//~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
|
||||||
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,16 @@
|
|||||||
|
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
|
||||||
|
--> $DIR/future-prelude-collision-generic-trait.rs:24:9
|
||||||
|
|
|
||||||
|
LL | U::try_from(self)
|
||||||
|
| ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from`
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/future-prelude-collision-generic-trait.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 <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
|
||||||
|
|
||||||
|
warning: 1 warning emitted
|
||||||
|
|
@ -6,32 +6,32 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
struct Generic<T, U>(T, U);
|
struct Generic<'a, U>(&'a U);
|
||||||
|
|
||||||
trait MyFromIter {
|
trait MyFromIter {
|
||||||
fn from_iter(_: i32) -> Self;
|
fn from_iter(_: i32) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyFromIter for Generic<i32, i32> {
|
impl MyFromIter for Generic<'static, i32> {
|
||||||
fn from_iter(x: i32) -> Self {
|
fn from_iter(_: i32) -> Self {
|
||||||
Self(x, x)
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
|
impl std::iter::FromIterator<i32> for Generic<'static, i32> {
|
||||||
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
<Generic<_, _> as MyFromIter>::from_iter(1);
|
<Generic<'_, _> as MyFromIter>::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
<Generic::<i32, i32> as MyFromIter>::from_iter(1);
|
<Generic::<'static, i32> as MyFromIter>::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
<Generic::<_, _> as MyFromIter>::from_iter(1);
|
<Generic::<'_, _> as MyFromIter>::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,19 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
struct Generic<T, U>(T, U);
|
struct Generic<'a, U>(&'a U);
|
||||||
|
|
||||||
trait MyFromIter {
|
trait MyFromIter {
|
||||||
fn from_iter(_: i32) -> Self;
|
fn from_iter(_: i32) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MyFromIter for Generic<i32, i32> {
|
impl MyFromIter for Generic<'static, i32> {
|
||||||
fn from_iter(x: i32) -> Self {
|
fn from_iter(_: i32) -> Self {
|
||||||
Self(x, x)
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::iter::FromIterator<i32> for Generic<i32, i32> {
|
impl std::iter::FromIterator<i32> for Generic<'static, i32> {
|
||||||
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
@ -28,10 +28,10 @@ fn main() {
|
|||||||
Generic::from_iter(1);
|
Generic::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
Generic::<i32, i32>::from_iter(1);
|
Generic::<'static, i32>::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
Generic::<_, _>::from_iter(1);
|
Generic::<'_, _>::from_iter(1);
|
||||||
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
//~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
//~| this is accepted in the current edition (Rust 2018)
|
//~| this is accepted in the current edition (Rust 2018)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202
|
|||||||
--> $DIR/future-prelude-collision-generic.rs:28:5
|
--> $DIR/future-prelude-collision-generic.rs:28:5
|
||||||
|
|
|
|
||||||
LL | Generic::from_iter(1);
|
LL | Generic::from_iter(1);
|
||||||
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
|
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter`
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/future-prelude-collision-generic.rs:5:9
|
--> $DIR/future-prelude-collision-generic.rs:5:9
|
||||||
@ -15,8 +15,8 @@ LL | #![warn(rust_2021_prelude_collisions)]
|
|||||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
--> $DIR/future-prelude-collision-generic.rs:31:5
|
--> $DIR/future-prelude-collision-generic.rs:31:5
|
||||||
|
|
|
|
||||||
LL | Generic::<i32, i32>::from_iter(1);
|
LL | Generic::<'static, i32>::from_iter(1);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'static, i32> as MyFromIter>::from_iter`
|
||||||
|
|
|
|
||||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
|
||||||
@ -24,8 +24,8 @@ LL | Generic::<i32, i32>::from_iter(1);
|
|||||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||||
--> $DIR/future-prelude-collision-generic.rs:34:5
|
--> $DIR/future-prelude-collision-generic.rs:34:5
|
||||||
|
|
|
|
||||||
LL | Generic::<_, _>::from_iter(1);
|
LL | Generic::<'_, _>::from_iter(1);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 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!
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
|
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
|
||||||
|
Loading…
Reference in New Issue
Block a user