Skip to content

Commit 0add056

Browse files
Rework print_disambiguation_help
1 parent 88a37ac commit 0add056

8 files changed

+93
-113
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

+53-73
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeVisitableExt};
3434
use rustc_span::def_id::DefIdSet;
3535
use rustc_span::symbol::{kw, sym, Ident};
3636
use rustc_span::Symbol;
37-
use rustc_span::{edit_distance, source_map, ExpnKind, FileName, MacroKind, Span};
37+
use rustc_span::{edit_distance, ExpnKind, FileName, MacroKind, Span};
3838
use rustc_trait_selection::infer::InferCtxtExt;
3939
use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedNote;
4040
use rustc_trait_selection::traits::error_reporting::on_unimplemented::TypeErrCtxtExt as _;
@@ -1320,39 +1320,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13201320
}
13211321
if let Some(sugg_span) = sugg_span
13221322
&& let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did)
1323-
{
1324-
let path = self.tcx.def_path_str(trait_ref.skip_binder().def_id);
1325-
1326-
let ty = match item.kind {
1327-
ty::AssocKind::Const | ty::AssocKind::Type => impl_ty,
1328-
ty::AssocKind::Fn => self
1329-
.tcx
1330-
.fn_sig(item.def_id)
1331-
.instantiate_identity()
1332-
.inputs()
1333-
.skip_binder()
1334-
.get(0)
1335-
.filter(|ty| ty.is_ref() && !rcvr_ty.is_ref())
1336-
.copied()
1337-
.unwrap_or(rcvr_ty),
1338-
};
1339-
if let Some(sugg) = print_disambiguation_help(
1340-
item_name,
1341-
args,
1342-
self_source,
1323+
&& let Some(sugg) = print_disambiguation_help(
1324+
self.tcx,
13431325
err,
1344-
path,
1345-
ty,
1346-
Some(impl_ty),
1347-
item.kind,
1348-
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
1349-
sugg_span,
1326+
self_source,
1327+
args,
1328+
trait_ref.instantiate(
1329+
self.tcx,
1330+
self.fresh_args_for_item(sugg_span, impl_did)
1331+
).with_self_ty(self.tcx, rcvr_ty),
13501332
idx,
1351-
self.tcx.sess.source_map(),
1352-
item.fn_has_self_parameter,
1353-
) {
1354-
suggs.push(sugg);
1355-
}
1333+
sugg_span,
1334+
item,
1335+
)
1336+
{
1337+
suggs.push(sugg);
13561338
}
13571339
}
13581340
CandidateSource::Trait(trait_did) => {
@@ -1374,25 +1356,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13741356
err.span_note(item_span, msg);
13751357
None
13761358
};
1377-
if let Some(sugg_span) = sugg_span {
1378-
let path = self.tcx.def_path_str(trait_did);
1379-
if let Some(sugg) = print_disambiguation_help(
1380-
item_name,
1381-
args,
1382-
self_source,
1359+
if let Some(sugg_span) = sugg_span
1360+
&& let Some(sugg) = print_disambiguation_help(
1361+
self.tcx,
13831362
err,
1384-
path,
1385-
rcvr_ty,
1386-
None,
1387-
item.kind,
1388-
self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id),
1389-
sugg_span,
1363+
self_source,
1364+
args,
1365+
ty::TraitRef::new(
1366+
self.tcx,
1367+
trait_did,
1368+
self.fresh_args_for_item(sugg_span, trait_did)
1369+
).with_self_ty(self.tcx, rcvr_ty),
13901370
idx,
1391-
self.tcx.sess.source_map(),
1392-
item.fn_has_self_parameter,
1393-
) {
1394-
suggs.push(sugg);
1395-
}
1371+
sugg_span,
1372+
item,
1373+
)
1374+
{
1375+
suggs.push(sugg);
13961376
}
13971377
}
13981378
}
@@ -3263,59 +3243,59 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
32633243
}
32643244

32653245
fn print_disambiguation_help<'tcx>(
3266-
item_name: Ident,
3267-
args: Option<&'tcx [hir::Expr<'tcx>]>,
3268-
source: SelfSource<'tcx>,
3246+
tcx: TyCtxt<'tcx>,
32693247
err: &mut Diagnostic,
3270-
trait_name: String,
3271-
rcvr_ty: Ty<'_>,
3272-
impl_self_ty: Option<Ty<'_>>,
3273-
kind: ty::AssocKind,
3274-
def_kind_descr: &'static str,
3248+
source: SelfSource<'tcx>,
3249+
args: Option<&'tcx [hir::Expr<'tcx>]>,
3250+
trait_ref: ty::TraitRef<'tcx>,
3251+
candidate_idx: Option<usize>,
32753252
span: Span,
3276-
candidate: Option<usize>,
3277-
source_map: &source_map::SourceMap,
3278-
fn_has_self_parameter: bool,
3253+
item: ty::AssocItem,
32793254
) -> Option<String> {
3255+
let trait_ref = if item.fn_has_self_parameter {
3256+
trait_ref.print_only_trait_name().to_string()
3257+
} else {
3258+
format!("<{} as {}>", trait_ref.args[0], trait_ref.print_only_trait_name())
3259+
};
32803260
Some(
3281-
if matches!(kind, ty::AssocKind::Fn)
3261+
if matches!(item.kind, ty::AssocKind::Fn)
32823262
&& let SelfSource::MethodCall(receiver) = source
32833263
&& let Some(args) = args
32843264
{
3265+
let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id);
3266+
let item_name = item.ident(tcx);
3267+
let rcvr_ref = tcx.fn_sig(item.def_id).skip_binder().skip_binder().inputs()[0]
3268+
.ref_mutability()
3269+
.map_or("", |mutbl| mutbl.ref_prefix_str());
32853270
let args = format!(
32863271
"({}{})",
3287-
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
3272+
rcvr_ref,
32883273
std::iter::once(receiver)
32893274
.chain(args.iter())
3290-
.map(|arg| source_map
3275+
.map(|arg| tcx
3276+
.sess
3277+
.source_map()
32913278
.span_to_snippet(arg.span)
32923279
.unwrap_or_else(|_| { "_".to_owned() }))
32933280
.collect::<Vec<_>>()
32943281
.join(", "),
32953282
);
3296-
let trait_name = if !fn_has_self_parameter && let Some(impl_self_ty) = impl_self_ty {
3297-
format!("<{impl_self_ty} as {trait_name}>")
3298-
} else {
3299-
trait_name
3300-
};
33013283
err.span_suggestion_verbose(
33023284
span,
33033285
format!(
33043286
"disambiguate the {def_kind_descr} for {}",
3305-
if let Some(candidate) = candidate {
3287+
if let Some(candidate) = candidate_idx {
33063288
format!("candidate #{candidate}")
33073289
} else {
33083290
"the candidate".to_string()
33093291
},
33103292
),
3311-
format!("{trait_name}::{item_name}{args}"),
3293+
format!("{trait_ref}::{item_name}{args}"),
33123294
Applicability::HasPlaceholders,
33133295
);
33143296
return None;
3315-
} else if let Some(impl_self_ty) = impl_self_ty {
3316-
format!("<{impl_self_ty} as {trait_name}>::")
33173297
} else {
3318-
format!("{trait_name}::")
3298+
format!("{trait_ref}::")
33193299
},
33203300
)
33213301
}

tests/ui/methods/disambiguate-multiple-blanket-impl.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ LL | fn foo(&self) {}
2929
| ^^^^^^^^^^^^^
3030
help: use fully-qualified syntax to disambiguate
3131
|
32-
LL | <T as A>::foo(&s);
33-
| ~~~~~~~~~~
34-
LL | <T as B>::foo(&s);
35-
| ~~~~~~~~~~
32+
LL | A::foo(&s);
33+
| ~~~
34+
LL | B::foo(&s);
35+
| ~~~
3636

3737
error[E0034]: multiple applicable items in scope
3838
--> $DIR/disambiguate-multiple-blanket-impl.rs:33:8
@@ -52,9 +52,9 @@ LL | const CONST: usize = 2;
5252
| ^^^^^^^^^^^^^^^^^^
5353
help: use fully-qualified syntax to disambiguate
5454
|
55-
LL | <T as A>::CONST;
55+
LL | <S as A>::CONST;
5656
| ~~~~~~~~~~
57-
LL | <T as B>::CONST;
57+
LL | <S as B>::CONST;
5858
| ~~~~~~~~~~
5959

6060
error: aborting due to 3 previous errors

tests/ui/methods/disambiguate-multiple-impl.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ LL | fn foo(&self) {}
2929
| ^^^^^^^^^^^^^
3030
help: use fully-qualified syntax to disambiguate
3131
|
32-
LL | <S as A>::foo(&s);
33-
| ~~~~~~~~~~
34-
LL | <S as B>::foo(&s);
35-
| ~~~~~~~~~~
32+
LL | A::foo(&s);
33+
| ~~~
34+
LL | B::foo(&s);
35+
| ~~~
3636

3737
error[E0034]: multiple applicable items in scope
3838
--> $DIR/disambiguate-multiple-impl.rs:34:16

tests/ui/methods/disambiguate-multiple-trait-2.stderr

+14-14
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ LL | fn foo(&self);
3737
| ^^^^^^^^^^^^^^
3838
help: disambiguate the method for candidate #1
3939
|
40-
LL | A::foo(t);
41-
| ~~~~~~~~~
40+
LL | A::foo(&t);
41+
| ~~~~~~~~~~
4242
help: disambiguate the method for candidate #2
4343
|
44-
LL | B::foo(t);
45-
| ~~~~~~~~~
44+
LL | B::foo(&t);
45+
| ~~~~~~~~~~
4646

4747
error[E0034]: multiple applicable items in scope
4848
--> $DIR/disambiguate-multiple-trait-2.rs:20:16
@@ -62,10 +62,10 @@ LL | const CONST: usize;
6262
| ^^^^^^^^^^^^^^^^^^
6363
help: use fully-qualified syntax to disambiguate
6464
|
65-
LL | let _ = A::CONST;
66-
| ~~~
67-
LL | let _ = B::CONST;
68-
| ~~~
65+
LL | let _ = <T as A>::CONST;
66+
| ~~~~~~~~~~
67+
LL | let _ = <T as B>::CONST;
68+
| ~~~~~~~~~~
6969

7070
error[E0223]: ambiguous associated type
7171
--> $DIR/disambiguate-multiple-trait-2.rs:52:12
@@ -98,10 +98,10 @@ LL | fn foo(&self) {}
9898
| ^^^^^^^^^^^^^
9999
help: use fully-qualified syntax to disambiguate
100100
|
101-
LL | <T as A>::foo(&s);
102-
| ~~~~~~~~~~
103-
LL | <T as B>::foo(&s);
104-
| ~~~~~~~~~~
101+
LL | A::foo(&s);
102+
| ~~~
103+
LL | B::foo(&s);
104+
| ~~~
105105

106106
error[E0034]: multiple applicable items in scope
107107
--> $DIR/disambiguate-multiple-trait-2.rs:49:16
@@ -121,9 +121,9 @@ LL | const CONST: usize = 1;
121121
| ^^^^^^^^^^^^^^^^^^
122122
help: use fully-qualified syntax to disambiguate
123123
|
124-
LL | let _ = <T as A>::CONST;
124+
LL | let _ = <S as A>::CONST;
125125
| ~~~~~~~~~~
126-
LL | let _ = <T as B>::CONST;
126+
LL | let _ = <S as B>::CONST;
127127
| ~~~~~~~~~~
128128

129129
error: aborting due to 6 previous errors

tests/ui/methods/disambiguate-multiple-trait.stderr

+6-6
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ LL | fn foo(&self) {}
2929
| ^^^^^^^^^^^^^
3030
help: use fully-qualified syntax to disambiguate
3131
|
32-
LL | <T as A>::foo(&s);
33-
| ~~~~~~~~~~
34-
LL | <T as B>::foo(&s);
35-
| ~~~~~~~~~~
32+
LL | A::foo(&s);
33+
| ~~~
34+
LL | B::foo(&s);
35+
| ~~~
3636

3737
error[E0034]: multiple applicable items in scope
3838
--> $DIR/disambiguate-multiple-trait.rs:27:16
@@ -52,9 +52,9 @@ LL | const CONST: usize = 2;
5252
| ^^^^^^^^^^^^^^^^^^
5353
help: use fully-qualified syntax to disambiguate
5454
|
55-
LL | let _ = <T as A>::CONST;
55+
LL | let _ = <S as A>::CONST;
5656
| ~~~~~~~~~~
57-
LL | let _ = <T as B>::CONST;
57+
LL | let _ = <S as B>::CONST;
5858
| ~~~~~~~~~~
5959

6060
error: aborting due to 3 previous errors

tests/ui/methods/method-ambig-two-traits-from-bounds.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ LL | trait B { fn foo(&self); }
1616
| ^^^^^^^^^^^^^^
1717
help: disambiguate the method for candidate #1
1818
|
19-
LL | A::foo(t);
20-
| ~~~~~~~~~
19+
LL | A::foo(&t);
20+
| ~~~~~~~~~~
2121
help: disambiguate the method for candidate #2
2222
|
23-
LL | B::foo(t);
24-
| ~~~~~~~~~
23+
LL | B::foo(&t);
24+
| ~~~~~~~~~~
2525

2626
error: aborting due to previous error
2727

tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ LL | let z = NuisanceFoo::foo(x);
5454
| ~~~~~~~~~~~~~~~~~~~
5555
help: disambiguate the method for candidate #3
5656
|
57-
LL | let z = FinalFoo::foo(x);
58-
| ~~~~~~~~~~~~~~~~
57+
LL | let z = FinalFoo::foo(&x);
58+
| ~~~~~~~~~~~~~~~~~
5959

6060
error[E0308]: mismatched types
6161
--> $DIR/method-deref-to-same-trait-object-with-separate-params.rs:139:24

tests/ui/span/issue-37767.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ LL | fn foo(&mut self) {}
1616
| ^^^^^^^^^^^^^^^^^
1717
help: disambiguate the method for candidate #1
1818
|
19-
LL | A::foo(&a)
20-
| ~~~~~~~~~~
19+
LL | A::foo(&mut a)
20+
| ~~~~~~~~~~~~~~
2121
help: disambiguate the method for candidate #2
2222
|
23-
LL | B::foo(&a)
24-
| ~~~~~~~~~~
23+
LL | B::foo(&mut a)
24+
| ~~~~~~~~~~~~~~
2525

2626
error[E0034]: multiple applicable items in scope
2727
--> $DIR/issue-37767.rs:22:7

0 commit comments

Comments
 (0)