Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit cb49992

Browse files
jam1garnernikomatsakis
authored andcommitted
Fix future_prelude_collision lint breaking for pointer mutabilty coercion
1 parent 93c60f2 commit cb49992

File tree

4 files changed

+144
-91
lines changed

4 files changed

+144
-91
lines changed

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

Lines changed: 109 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -203,60 +203,81 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
203203

204204
if span.edition() < Edition::Edition2021 {
205205
if let sym::try_into = segment.ident.name {
206-
if let probe::PickKind::TraitPick = pick.kind {
207-
if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core)
208-
{
209-
self.tcx.struct_span_lint_hir(
210-
FUTURE_PRELUDE_COLLISION,
211-
call_expr.hir_id,
212-
call_expr.span,
213-
|lint| {
214-
let sp = call_expr.span;
215-
let trait_name =
216-
self.tcx.def_path_str(pick.item.container.assert_trait());
217-
218-
let mut lint = lint.build(&format!(
219-
"trait method `{}` will become ambiguous in Rust 2021",
220-
segment.ident.name
221-
));
222-
223-
if let Ok(self_expr) =
224-
self.sess().source_map().span_to_snippet(self_expr.span)
225-
{
226-
let derefs = "*".repeat(pick.autoderefs);
227-
let self_adjusted = match pick.autoref_or_ptr_adjustment {
228-
Some(probe::AutorefOrPtrAdjustment::Autoref {
229-
mutbl: Mutability::Mut, ..
230-
}) => format!("&mut {}{}", derefs, self_expr),
231-
Some(probe::AutorefOrPtrAdjustment::Autoref {
232-
mutbl: Mutability::Not, ..
233-
}) => format!("&{}{}", derefs, self_expr),
234-
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None
235-
=> format!("{}{}", derefs, self_expr),
206+
if !matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
207+
self.tcx.struct_span_lint_hir(
208+
FUTURE_PRELUDE_COLLISION,
209+
call_expr.hir_id,
210+
call_expr.span,
211+
|lint| {
212+
let sp = call_expr.span;
213+
let type_name = self.tcx.def_path_str(pick.item.container.id());
214+
let type_generics = self.tcx.generics_of(pick.item.container.id());
215+
let parameter_count =
216+
type_generics.count() - (type_generics.has_self as usize);
217+
let trait_name = if parameter_count == 0 {
218+
type_name
219+
} else {
220+
format!(
221+
"{}<{}>",
222+
type_name,
223+
std::iter::repeat("_")
224+
.take(parameter_count)
225+
.collect::<Vec<_>>()
226+
.join(", ")
227+
)
228+
};
229+
230+
let mut lint = lint.build(&format!(
231+
"trait method `{}` will become ambiguous in Rust 2021",
232+
segment.ident.name
233+
));
234+
235+
if let Ok(self_expr) =
236+
self.sess().source_map().span_to_snippet(self_expr.span)
237+
{
238+
let derefs = "*".repeat(pick.autoderefs);
239+
240+
let autoref = match pick.autoref_or_ptr_adjustment {
241+
Some(probe::AutorefOrPtrAdjustment::Autoref {
242+
mutbl: Mutability::Mut,
243+
..
244+
}) => "&mut ",
245+
Some(probe::AutorefOrPtrAdjustment::Autoref {
246+
mutbl: Mutability::Not,
247+
..
248+
}) => "&",
249+
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
250+
};
251+
let self_adjusted =
252+
if let Some(probe::AutorefOrPtrAdjustment::ToConstPtr) =
253+
pick.autoref_or_ptr_adjustment
254+
{
255+
format!("{}{} as *const _", derefs, self_expr)
256+
} else {
257+
format!("{}{}{}", autoref, derefs, self_expr)
236258
};
237-
lint.span_suggestion(
238-
sp,
239-
"disambiguate the associated function",
240-
format!(
241-
"{}::{}({})",
242-
trait_name, segment.ident.name, self_adjusted,
243-
),
244-
Applicability::MachineApplicable,
245-
);
246-
} else {
247-
lint.span_help(
248-
sp,
249-
&format!(
250-
"disambiguate the associated function with `{}::{}(...)`",
251-
trait_name, segment.ident,
252-
),
253-
);
254-
}
255-
256-
lint.emit();
257-
},
258-
);
259-
}
259+
lint.span_suggestion(
260+
sp,
261+
"disambiguate the associated function",
262+
format!(
263+
"{}::{}({})",
264+
trait_name, segment.ident.name, self_adjusted,
265+
),
266+
Applicability::MachineApplicable,
267+
);
268+
} else {
269+
lint.span_help(
270+
sp,
271+
&format!(
272+
"disambiguate the associated function with `{}::{}(...)`",
273+
trait_name, segment.ident,
274+
),
275+
);
276+
}
277+
278+
lint.emit();
279+
},
280+
);
260281
}
261282
}
262283
}
@@ -541,38 +562,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
541562

542563
if span.edition() < Edition::Edition2021 {
543564
if let sym::try_into | sym::try_from | sym::from_iter = method_name.name {
544-
if let probe::PickKind::TraitPick = pick.kind {
545-
if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
546-
tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
547-
let trait_def_id = pick.item.container.assert_trait();
548-
let trait_generics = tcx.generics_of(trait_def_id);
549-
let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
550-
551-
let trait_name = if parameter_count == 0 {
552-
tcx.def_path_str(trait_def_id)
553-
} else {
554-
format!(
555-
"{}<{}>",
556-
tcx.def_path_str(trait_def_id),
557-
std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
558-
)
559-
};
560-
561-
let mut lint = lint.build(&format!(
562-
"trait-associated function `{}` will become ambiguous in Rust 2021",
563-
method_name.name
564-
));
565-
566-
lint.span_suggestion(
567-
span,
568-
"disambiguate the associated function",
569-
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
570-
Applicability::MachineApplicable,
571-
);
565+
if !matches!(tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
566+
tcx.struct_span_lint_hir(FUTURE_PRELUDE_COLLISION, expr_id, span, |lint| {
567+
// "type" refers to either a type or, more likely, a trait from which
568+
// the associated function or method is from.
569+
let type_name = tcx.def_path_str(pick.item.container.id());
570+
let type_generics = tcx.generics_of(pick.item.container.id());
571+
572+
let parameter_count =
573+
type_generics.count() - (type_generics.has_self as usize);
574+
let trait_name = if parameter_count == 0 {
575+
type_name
576+
} else {
577+
format!(
578+
"{}<{}>",
579+
type_name,
580+
std::iter::repeat("_")
581+
.take(parameter_count)
582+
.collect::<Vec<_>>()
583+
.join(", ")
584+
)
585+
};
586+
587+
let mut lint = lint.build(&format!(
588+
"trait-associated function `{}` will become ambiguous in Rust 2021",
589+
method_name.name
590+
));
591+
592+
lint.span_suggestion(
593+
span,
594+
"disambiguate the associated function",
595+
format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
596+
Applicability::MachineApplicable,
597+
);
572598

573-
lint.emit();
574-
});
575-
}
599+
lint.emit();
600+
});
576601
}
577602
}
578603
}

src/test/ui/lint/future-prelude-collision.fixed

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ impl TryFromU8 for u32 {
2929
}
3030
}
3131

32+
impl TryIntoU32 for *const u16 {
33+
fn try_into(self) -> Result<u32, ()> {
34+
Ok(unsafe { *self } as u32)
35+
}
36+
}
37+
3238
trait FromByteIterator {
3339
fn from_iter<T>(iter: T) -> Self
3440
where T: Iterator<Item = u8>;
@@ -69,4 +75,9 @@ fn main() {
6975
// test autoref
7076
let _: u32 = TryIntoU32::try_into(&3.0).unwrap();
7177
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
78+
79+
let mut data = 3u16;
80+
let mut_ptr = std::ptr::addr_of_mut!(data);
81+
let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap();
82+
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
7283
}

src/test/ui/lint/future-prelude-collision.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ impl TryFromU8 for u32 {
2929
}
3030
}
3131

32+
impl TryIntoU32 for *const u16 {
33+
fn try_into(self) -> Result<u32, ()> {
34+
Ok(unsafe { *self } as u32)
35+
}
36+
}
37+
3238
trait FromByteIterator {
3339
fn from_iter<T>(iter: T) -> Self
3440
where T: Iterator<Item = u8>;
@@ -69,4 +75,9 @@ fn main() {
6975
// test autoref
7076
let _: u32 = 3.0.try_into().unwrap();
7177
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
78+
79+
let mut data = 3u16;
80+
let mut_ptr = std::ptr::addr_of_mut!(data);
81+
let _: u32 = mut_ptr.try_into().unwrap();
82+
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
7283
}
Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,46 @@
11
warning: trait method `try_into` will become ambiguous in Rust 2021
2-
--> $DIR/future-prelude-collision.rs:47:18
2+
--> $DIR/future-prelude-collision.rs:53:18
33
|
44
LL | let _: u32 = 3u8.try_into().unwrap();
55
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
66
|
77
= note: `#[warn(future_prelude_collision)]` on by default
88

99
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
10-
--> $DIR/future-prelude-collision.rs:51:13
10+
--> $DIR/future-prelude-collision.rs:57:13
1111
|
1212
LL | let _ = u32::try_from(3u8).unwrap();
1313
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<u32 as TryFromU8>::try_from`
1414

1515
warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
16-
--> $DIR/future-prelude-collision.rs:55:13
16+
--> $DIR/future-prelude-collision.rs:61:13
1717
|
1818
LL | let _ = <Vec<u8>>::from_iter(vec![1u8, 2, 3, 4, 5, 6].into_iter());
1919
| ^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Vec<u8> as FromByteIterator>::from_iter`
2020

2121
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
22-
--> $DIR/future-prelude-collision.rs:62:18
22+
--> $DIR/future-prelude-collision.rs:68:18
2323
|
2424
LL | let _: u32 = <_>::try_from(3u8).unwrap();
2525
| ^^^^^^^^^^^^^ help: disambiguate the associated function: `<_ as TryFromU8>::try_from`
2626

2727
warning: trait method `try_into` will become ambiguous in Rust 2021
28-
--> $DIR/future-prelude-collision.rs:66:18
28+
--> $DIR/future-prelude-collision.rs:72:18
2929
|
3030
LL | let _: u32 = (&3u8).try_into().unwrap();
3131
| ^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(*(&3u8))`
3232

3333
warning: trait method `try_into` will become ambiguous in Rust 2021
34-
--> $DIR/future-prelude-collision.rs:70:18
34+
--> $DIR/future-prelude-collision.rs:76:18
3535
|
3636
LL | let _: u32 = 3.0.try_into().unwrap();
3737
| ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(&3.0)`
3838

39-
warning: 6 warnings emitted
39+
warning: trait method `try_into` will become ambiguous in Rust 2021
40+
--> $DIR/future-prelude-collision.rs:81:18
41+
|
42+
LL | let _: u32 = mut_ptr.try_into().unwrap();
43+
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
44+
45+
warning: 7 warnings emitted
4046

0 commit comments

Comments
 (0)