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

Commit 4a21a0b

Browse files
jam1garnernikomatsakis
authored andcommitted
Fix future_prelude_collision not maintaining type aliases
1 parent cb49992 commit 4a21a0b

File tree

7 files changed

+71
-32
lines changed

7 files changed

+71
-32
lines changed

compiler/rustc_typeck/src/check/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
466466
expr: &'tcx hir::Expr<'tcx>,
467467
) -> Ty<'tcx> {
468468
let tcx = self.tcx;
469-
let (res, opt_ty, segs) = self.resolve_ty_and_res_ufcs(qpath, expr.hir_id, expr.span);
469+
let (res, opt_ty, segs) =
470+
self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span);
470471
let ty = match res {
471472
Res::Err => {
472473
self.set_tainted_by_errors();

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -906,13 +906,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
906906

907907
/// Resolves an associated value path into a base type and associated constant, or method
908908
/// resolution. The newly resolved definition is written into `type_dependent_defs`.
909-
pub fn resolve_ty_and_res_ufcs(
909+
pub fn resolve_ty_and_res_fully_qualified_call(
910910
&self,
911911
qpath: &'tcx QPath<'tcx>,
912912
hir_id: hir::HirId,
913913
span: Span,
914914
) -> (Res, Option<Ty<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
915-
debug!("resolve_ty_and_res_ufcs: qpath={:?} hir_id={:?} span={:?}", qpath, hir_id, span);
915+
debug!(
916+
"resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
917+
qpath, hir_id, span
918+
);
916919
let (ty, qself, item_segment) = match *qpath {
917920
QPath::Resolved(ref opt_qself, ref path) => {
918921
return (
@@ -922,7 +925,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
922925
);
923926
}
924927
QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
925-
QPath::LangItem(..) => bug!("`resolve_ty_and_res_ufcs` called on `LangItem`"),
928+
QPath::LangItem(..) => {
929+
bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
930+
}
926931
};
927932
if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
928933
{
@@ -932,25 +937,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
932937
return (def, Some(ty), slice::from_ref(&**item_segment));
933938
}
934939
let item_name = item_segment.ident;
935-
let result = self.resolve_ufcs(span, item_name, ty, hir_id).or_else(|error| {
936-
let result = match error {
937-
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
938-
_ => Err(ErrorReported),
939-
};
940-
if item_name.name != kw::Empty {
941-
if let Some(mut e) = self.report_method_error(
942-
span,
943-
ty,
944-
item_name,
945-
SelfSource::QPath(qself),
946-
error,
947-
None,
948-
) {
949-
e.emit();
940+
let result = self
941+
.resolve_fully_qualified_call(span, item_name, ty, qself.span, hir_id)
942+
.or_else(|error| {
943+
let result = match error {
944+
method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
945+
_ => Err(ErrorReported),
946+
};
947+
if item_name.name != kw::Empty {
948+
if let Some(mut e) = self.report_method_error(
949+
span,
950+
ty,
951+
item_name,
952+
SelfSource::QPath(qself),
953+
error,
954+
None,
955+
) {
956+
e.emit();
957+
}
950958
}
951-
}
952-
result
953-
});
959+
result
960+
});
954961

955962
if result.is_ok() {
956963
self.maybe_lint_bare_trait(qpath, hir_id);

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
501501
Some(InferOk { obligations, value: callee })
502502
}
503503

504-
/// Performs "universal function call" lookup. If lookup is successful, it will return the type
505-
/// of definition and the [`DefId`] of the found function definition.
504+
/// Performs a [full-qualified function call] (formerly "universal function call") lookup. If
505+
/// lookup is successful, it will return the type of definition and the [`DefId`] of the found
506+
/// function definition.
507+
///
508+
/// [full-qualified function call]: https://doc.rust-lang.org/reference/expressions/call-expr.html#disambiguating-function-calls
506509
///
507510
/// # Arguments
508511
///
@@ -512,17 +515,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
512515
/// * `span`: the span of the call, excluding arguments (`Foo::bar::<T1, ...Tn>`)
513516
/// * `method_name`: the identifier of the function within the container type (`bar`)
514517
/// * `self_ty`: the type to search within (`Foo`)
518+
/// * `self_ty_span` the span for the type being searched within (span of `Foo`)
515519
/// * `expr_id`: the [`hir::HirId`] of the expression composing the entire call
516520
#[instrument(level = "debug", skip(self))]
517-
pub fn resolve_ufcs(
521+
pub fn resolve_fully_qualified_call(
518522
&self,
519523
span: Span,
520524
method_name: Ident,
521525
self_ty: Ty<'tcx>,
526+
self_ty_span: Span,
522527
expr_id: hir::HirId,
523528
) -> Result<(DefKind, DefId), MethodError<'tcx>> {
524529
debug!(
525-
"resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}",
530+
"resolve_fully_qualified_call: method_name={:?} self_ty={:?} expr_id={:?}",
526531
method_name, self_ty, expr_id,
527532
);
528533

@@ -589,6 +594,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
589594
method_name.name
590595
));
591596

597+
let self_ty = self
598+
.sess()
599+
.source_map()
600+
.span_to_snippet(self_ty_span)
601+
.unwrap_or_else(|_| self_ty.to_string());
602+
592603
lint.span_suggestion(
593604
span,
594605
"disambiguate the associated function",
@@ -602,18 +613,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
602613
}
603614
}
604615

605-
debug!("resolve_ufcs: pick={:?}", pick);
616+
debug!("resolve_fully_qualified_call: pick={:?}", pick);
606617
{
607618
let mut typeck_results = self.typeck_results.borrow_mut();
608619
let used_trait_imports = Lrc::get_mut(&mut typeck_results.used_trait_imports).unwrap();
609620
for import_id in pick.import_ids {
610-
debug!("resolve_ufcs: used_trait_import: {:?}", import_id);
621+
debug!("resolve_fully_qualified_call: used_trait_import: {:?}", import_id);
611622
used_trait_imports.insert(import_id);
612623
}
613624
}
614625

615626
let def_kind = pick.item.kind.as_def_kind();
616-
debug!("resolve_ufcs: def_kind={:?}, def_id={:?}", def_kind, pick.item.def_id);
627+
debug!(
628+
"resolve_fully_qualified_call: def_kind={:?}, def_id={:?}",
629+
def_kind, pick.item.def_id
630+
);
617631
tcx.check_stability(pick.item.def_id, Some(expr_id), span, Some(method_name.span));
618632
Ok((def_kind, pick.item.def_id))
619633
}

compiler/rustc_typeck/src/check/pat.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
160160
ti: TopInfo<'tcx>,
161161
) {
162162
let path_res = match &pat.kind {
163-
PatKind::Path(qpath) => Some(self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span)),
163+
PatKind::Path(qpath) => {
164+
Some(self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span))
165+
}
164166
_ => None,
165167
};
166168
let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
@@ -904,7 +906,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
904906
};
905907

906908
// Resolve the path and check the definition for errors.
907-
let (res, opt_ty, segments) = self.resolve_ty_and_res_ufcs(qpath, pat.hir_id, pat.span);
909+
let (res, opt_ty, segments) =
910+
self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span);
908911
if res == Res::Err {
909912
self.set_tainted_by_errors();
910913
on_error();

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,8 @@ fn main() {
8080
let mut_ptr = std::ptr::addr_of_mut!(data);
8181
let _: u32 = TryIntoU32::try_into(mut_ptr as *const _).unwrap();
8282
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
83+
84+
type U32Alias = u32;
85+
let _ = <U32Alias as TryFromU8>::try_from(3u8).unwrap();
86+
//~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
8387
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,8 @@ fn main() {
8080
let mut_ptr = std::ptr::addr_of_mut!(data);
8181
let _: u32 = mut_ptr.try_into().unwrap();
8282
//~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
83+
84+
type U32Alias = u32;
85+
let _ = U32Alias::try_from(3u8).unwrap();
86+
//~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
8387
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,11 @@ warning: trait method `try_into` will become ambiguous in Rust 2021
4242
LL | let _: u32 = mut_ptr.try_into().unwrap();
4343
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(mut_ptr as *const _)`
4444

45-
warning: 7 warnings emitted
45+
warning: trait-associated function `try_from` will become ambiguous in Rust 2021
46+
--> $DIR/future-prelude-collision.rs:85:13
47+
|
48+
LL | let _ = U32Alias::try_from(3u8).unwrap();
49+
| ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<U32Alias as TryFromU8>::try_from`
50+
51+
warning: 8 warnings emitted
4652

0 commit comments

Comments
 (0)