Fix future_prelude_collision
lint breaking for pointer mutabilty coercion
This commit is contained in:
parent
93c60f26bf
commit
cb4999242d
4 changed files with 138 additions and 85 deletions
|
@ -203,60 +203,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
if span.edition() < Edition::Edition2021 {
|
||||
if let sym::try_into = segment.ident.name {
|
||||
if let probe::PickKind::TraitPick = pick.kind {
|
||||
if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core)
|
||||
{
|
||||
self.tcx.struct_span_lint_hir(
|
||||
FUTURE_PRELUDE_COLLISION,
|
||||
call_expr.hir_id,
|
||||
call_expr.span,
|
||||
|lint| {
|
||||
let sp = call_expr.span;
|
||||
let trait_name =
|
||||
self.tcx.def_path_str(pick.item.container.assert_trait());
|
||||
if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
|
||||
self.tcx.struct_span_lint_hir(
|
||||
FUTURE_PRELUDE_COLLISION,
|
||||
call_expr.hir_id,
|
||||
call_expr.span,
|
||||
|lint| {
|
||||
let sp = call_expr.span;
|
||||
let type_name = self.tcx.def_path_str(pick.item.container.id());
|
||||
let type_generics = self.tcx.generics_of(pick.item.container.id());
|
||||
let parameter_count =
|
||||
type_generics.count() - (type_generics.has_self as usize);
|
||||
let trait_name = if parameter_count == 0 {
|
||||
type_name
|
||||
} else {
|
||||
format!(
|
||||
"{}<{}>",
|
||||
type_name,
|
||||
std::iter::repeat("_")
|
||||
.take(parameter_count)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
};
|
||||
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait method `{}` will become ambiguous in Rust 2021",
|
||||
segment.ident.name
|
||||
));
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait method `{}` will become ambiguous in Rust 2021",
|
||||
segment.ident.name
|
||||
));
|
||||
|
||||
if let Ok(self_expr) =
|
||||
self.sess().source_map().span_to_snippet(self_expr.span)
|
||||
{
|
||||
let derefs = "*".repeat(pick.autoderefs);
|
||||
let self_adjusted = match pick.autoref_or_ptr_adjustment {
|
||||
Some(probe::AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl: Mutability::Mut, ..
|
||||
}) => format!("&mut {}{}", derefs, self_expr),
|
||||
Some(probe::AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl: Mutability::Not, ..
|
||||
}) => format!("&{}{}", derefs, self_expr),
|
||||
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None
|
||||
=> format!("{}{}", derefs, self_expr),
|
||||
if let Ok(self_expr) =
|
||||
self.sess().source_map().span_to_snippet(self_expr.span)
|
||||
{
|
||||
let derefs = "*".repeat(pick.autoderefs);
|
||||
|
||||
let autoref = match pick.autoref_or_ptr_adjustment {
|
||||
Some(probe::AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl: Mutability::Mut,
|
||||
..
|
||||
}) => "&mut ",
|
||||
Some(probe::AutorefOrPtrAdjustment::Autoref {
|
||||
mutbl: Mutability::Not,
|
||||
..
|
||||
}) => "&",
|
||||
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
|
||||
};
|
||||
let self_adjusted =
|
||||
if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
|
||||
pick.autoref_or_ptr_adjustment
|
||||
{
|
||||
format!("{}{} as *const _", derefs, self_expr)
|
||||
} else {
|
||||
format!("{}{}{}", autoref, derefs, self_expr)
|
||||
};
|
||||
lint.span_suggestion(
|
||||
sp,
|
||||
"disambiguate the associated function",
|
||||
format!(
|
||||
"{}::{}({})",
|
||||
trait_name, segment.ident.name, self_adjusted,
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
lint.span_help(
|
||||
sp,
|
||||
&format!(
|
||||
"disambiguate the associated function with `{}::{}(...)`",
|
||||
trait_name, segment.ident,
|
||||
),
|
||||
);
|
||||
}
|
||||
lint.span_suggestion(
|
||||
sp,
|
||||
"disambiguate the associated function",
|
||||
format!(
|
||||
"{}::{}({})",
|
||||
trait_name, segment.ident.name, self_adjusted,
|
||||
),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else {
|
||||
lint.span_help(
|
||||
sp,
|
||||
&format!(
|
||||
"disambiguate the associated function with `{}::{}(...)`",
|
||||
trait_name, segment.ident,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
lint.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
lint.emit();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -541,38 +562,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
|
||||
if span.edition() < Edition::Edition2021 {
|
||||
if let sym::try_into | sym::try_from | sym::from_iter = method_name.name {
|
||||
if let probe::PickKind::TraitPick = pick.kind {
|
||||
if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
|
||||
tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
|
||||
let trait_def_id = pick.item.container.assert_trait();
|
||||
let trait_generics = tcx.generics_of(trait_def_id);
|
||||
let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
|
||||
if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
|
||||
tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
|
||||
// "type" refers to either a type or, more likely, a trait from which
|
||||
// the associated function or method is from.
|
||||
let type_name = tcx.def_path_str(pick.item.container.id());
|
||||
let type_generics = tcx.generics_of(pick.item.container.id());
|
||||
|
||||
let trait_name = if parameter_count == 0 {
|
||||
tcx.def_path_str(trait_def_id)
|
||||
} else {
|
||||
format!(
|
||||
"{}<{}>",
|
||||
tcx.def_path_str(trait_def_id),
|
||||
std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
|
||||
)
|
||||
};
|
||||
let parameter_count =
|
||||
type_generics.count() - (type_generics.has_self as usize);
|
||||
let trait_name = if parameter_count == 0 {
|
||||
type_name
|
||||
} else {
|
||||
format!(
|
||||
"{}<{}>",
|
||||
type_name,
|
||||
std::iter::repeat("_")
|
||||
.take(parameter_count)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
};
|
||||
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||
method_name.name
|
||||
));
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||
method_name.name
|
||||
));
|
||||
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
lint.emit();
|
||||
});
|
||||
}
|
||||
lint.emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ impl TryFromU8 for u32 {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryIntoU32 for *const u16 {
|
||||
fn try_into(self) -> Result<u32, ()> {
|
||||
Ok(unsafe { *self } as u32)
|
||||
}
|
||||
}
|
||||
|
||||
trait FromByteIterator {
|
||||
fn from_iter<T>(iter: T) -> Self
|
||||
where T: Iterator<Item = u8>;
|
||||
|
@ -69,4 +75,9 @@ fn main() {
|
|||
// test autoref
|
||||
let _: u32 = TryIntoU32::try_into(&3.0).unwrap();
|
||||
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
|
||||
|
||||
let mut data = 3u16;
|
||||
let mut_ptr = std::ptr::addr_of_mut!(data);
|
||||
let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap();
|
||||
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ impl TryFromU8 for u32 {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryIntoU32 for *const u16 {
|
||||
fn try_into(self) -> Result<u32, ()> {
|
||||
Ok(unsafe { *self } as u32)
|
||||
}
|
||||
}
|
||||
|
||||
trait FromByteIterator {
|
||||
fn from_iter<T>(iter: T) -> Self
|
||||
where T: Iterator<Item = u8>;
|
||||
|
@ -69,4 +75,9 @@ fn main() {
|
|||
// test autoref
|
||||
let _: u32 = 3.0.try_into().unwrap();
|
||||
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
|
||||
|
||||
let mut data = 3u16;
|
||||
let mut_ptr = std::ptr::addr_of_mut!(data);
|
||||
let _: u32 = mut_ptr.try_into().unwrap();
|
||||
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
warning: trait method `try_into` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:47:18
|
||||
--> $DIR/future-prelude-collision.rs:53:18
|
||||
|
|
||||
LL | let _: u32 = 3u8.try_into().unwrap();
|
||||
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
|
||||
|
@ -7,34 +7,40 @@ LL | let _: u32 = 3u8.try_into().unwrap();
|
|||
= note: `#[warn(future_prelude_collision)]` on by default
|
||||
|
||||
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:51:13
|
||||
--> $DIR/future-prelude-collision.rs:57:13
|
||||
|
|
||||
LL | let _ = u32::try_from(3u8).unwrap();
|
||||
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
|
||||
|
||||
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:55:13
|
||||
--> $DIR/future-prelude-collision.rs:61:13
|
||||
|
|
||||
LL | let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
|
||||
| ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<u8> as FromByteIterator>::from_iter`
|
||||
|
||||
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:62:18
|
||||
--> $DIR/future-prelude-collision.rs:68:18
|
||||
|
|
||||
LL | let _: u32 = <_>::try_from(3u8).unwrap();
|
||||
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
|
||||
|
||||
warning: trait method `try_into` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:66:18
|
||||
--> $DIR/future-prelude-collision.rs:72:18
|
||||
|
|
||||
LL | let _: u32 = (&3u8).try_into().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
|
||||
|
||||
warning: trait method `try_into` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:70:18
|
||||
--> $DIR/future-prelude-collision.rs:76:18
|
||||
|
|
||||
LL | let _: u32 = 3.0.try_into().unwrap();
|
||||
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
|
||||
|
||||
warning: 6 warnings emitted
|
||||
warning: trait method `try_into` will become ambiguous in Rust 2021
|
||||
--> $DIR/future-prelude-collision.rs:81:18
|
||||
|
|
||||
LL | let _: u32 = mut_ptr.try_into().unwrap();
|
||||
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
|
||||
|
||||
warning: 7 warnings emitted
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue