Skip to content

Commit 09a8017

Browse files
committed
On E0599 show type identity to avoid expanding the receiver's generic parameters
1 parent 0786a11 commit 09a8017

24 files changed

+94
-71
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -379,16 +379,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
379379
&self,
380380
rcvr_ty: Ty<'tcx>,
381381
rcvr_expr: &hir::Expr<'tcx>,
382-
mut file: Option<PathBuf>,
382+
mut long_ty_path: Option<PathBuf>,
383383
) -> Diag<'_> {
384384
let mut err = struct_span_code_err!(
385385
self.dcx(),
386386
rcvr_expr.span,
387387
E0599,
388388
"cannot write into `{}`",
389-
self.tcx.short_string(rcvr_ty, &mut file),
389+
self.tcx.short_string(rcvr_ty, &mut long_ty_path),
390390
);
391-
*err.long_ty_path() = file;
391+
*err.long_ty_path() = long_ty_path;
392392
err.span_note(
393393
rcvr_expr.span,
394394
"must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method",
@@ -680,6 +680,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
680680
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
681681
self.suggest_missing_writer(rcvr_ty, rcvr_expr, ty_file)
682682
} else {
683+
// Don't show expanded generic arguments when the method can't be found in any
684+
// implementation (#81576).
685+
let mut ty = rcvr_ty;
686+
if let ty::Adt(def, generics) = rcvr_ty.kind() {
687+
if generics.len() > 0 {
688+
let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors();
689+
let candidate_found = autoderef.any(|(ty, _)| {
690+
if let ty::Adt(adt_def, _) = ty.kind() {
691+
self.tcx
692+
.inherent_impls(adt_def.did())
693+
.into_iter()
694+
.any(|def_id| self.associated_value(*def_id, item_ident).is_some())
695+
} else {
696+
false
697+
}
698+
});
699+
let has_deref = autoderef.step_count() > 0;
700+
if !candidate_found && !has_deref && unsatisfied_predicates.is_empty() {
701+
ty = self.tcx.at(span).type_of(def.did()).instantiate_identity();
702+
}
703+
}
704+
}
705+
683706
let mut err = self.dcx().create_err(NoAssociatedItem {
684707
span,
685708
item_kind,
@@ -690,7 +713,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
690713
} else {
691714
rcvr_ty.prefix_string(self.tcx)
692715
},
693-
ty: rcvr_ty,
716+
ty,
694717
trait_missing_method,
695718
});
696719

tests/ui/attributes/rustc_confusables_std_cases.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `push` found for struct `BTreeSet<_>` in the current scope
1+
error[E0599]: no method named `push` found for struct `BTreeSet<T, A>` in the current scope
22
--> $DIR/rustc_confusables_std_cases.rs:6:7
33
|
44
LL | x.push(1);
@@ -22,7 +22,7 @@ LL - x.push_back(1);
2222
LL + x.push(1);
2323
|
2424

25-
error[E0599]: no method named `push` found for struct `VecDeque<_>` in the current scope
25+
error[E0599]: no method named `push` found for struct `VecDeque<T, A>` in the current scope
2626
--> $DIR/rustc_confusables_std_cases.rs:12:7
2727
|
2828
LL | x.push(1);

tests/ui/confuse-field-and-method/issue-18343.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `closure` found for struct `Obj<{closure@$DIR/issue-18343.rs:6:28: 6:30}>` in the current scope
1+
error[E0599]: no method named `closure` found for struct `Obj<F>` in the current scope
22
--> $DIR/issue-18343.rs:7:7
33
|
44
LL | struct Obj<F> where F: FnMut() -> u32 {

tests/ui/confuse-field-and-method/issue-2392.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `closure` found for struct `Obj<{closure@$DIR/issue-2392.rs:35:36: 35:38}>` in the current scope
1+
error[E0599]: no method named `closure` found for struct `Obj<F>` in the current scope
22
--> $DIR/issue-2392.rs:36:15
33
|
44
LL | struct Obj<F> where F: FnOnce() -> u32 {
@@ -12,7 +12,7 @@ help: to call the closure stored in `closure`, surround the field access with pa
1212
LL | (o_closure.closure)();
1313
| + +
1414

15-
error[E0599]: no method named `not_closure` found for struct `Obj<{closure@$DIR/issue-2392.rs:35:36: 35:38}>` in the current scope
15+
error[E0599]: no method named `not_closure` found for struct `Obj<F>` in the current scope
1616
--> $DIR/issue-2392.rs:38:15
1717
|
1818
LL | struct Obj<F> where F: FnOnce() -> u32 {
@@ -23,7 +23,7 @@ LL | o_closure.not_closure();
2323
| |
2424
| field, not a method
2525

26-
error[E0599]: no method named `closure` found for struct `Obj<fn() -> u32 {func}>` in the current scope
26+
error[E0599]: no method named `closure` found for struct `Obj<F>` in the current scope
2727
--> $DIR/issue-2392.rs:42:12
2828
|
2929
LL | struct Obj<F> where F: FnOnce() -> u32 {
@@ -65,7 +65,7 @@ help: to call the trait object stored in `boxed_closure`, surround the field acc
6565
LL | (boxed_closure.boxed_closure)();
6666
| + +
6767

68-
error[E0599]: no method named `closure` found for struct `Obj<fn() -> u32 {func}>` in the current scope
68+
error[E0599]: no method named `closure` found for struct `Obj<F>` in the current scope
6969
--> $DIR/issue-2392.rs:53:12
7070
|
7171
LL | struct Obj<F> where F: FnOnce() -> u32 {
@@ -79,7 +79,7 @@ help: to call the function stored in `closure`, surround the field access with p
7979
LL | (w.wrap.closure)();
8080
| + +
8181

82-
error[E0599]: no method named `not_closure` found for struct `Obj<fn() -> u32 {func}>` in the current scope
82+
error[E0599]: no method named `not_closure` found for struct `Obj<F>` in the current scope
8383
--> $DIR/issue-2392.rs:55:12
8484
|
8585
LL | struct Obj<F> where F: FnOnce() -> u32 {
@@ -90,7 +90,7 @@ LL | w.wrap.not_closure();
9090
| |
9191
| field, not a method
9292

93-
error[E0599]: no method named `closure` found for struct `Obj<Box<(dyn FnOnce() -> u32 + 'static)>>` in the current scope
93+
error[E0599]: no method named `closure` found for struct `Obj<F>` in the current scope
9494
--> $DIR/issue-2392.rs:58:24
9595
|
9696
LL | struct Obj<F> where F: FnOnce() -> u32 {

tests/ui/delegation/correct_body_owner_parent_found_in_diagnostics.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ help: consider introducing lifetime `'a` here
4343
LL | impl<'a> Trait for Z {
4444
| ++++
4545

46-
error[E0599]: no function or associated item named `new` found for struct `InvariantRef<'_, _>` in the current scope
46+
error[E0599]: no function or associated item named `new` found for struct `InvariantRef<'a, T>` in the current scope
4747
--> $DIR/correct_body_owner_parent_found_in_diagnostics.rs:9:41
4848
|
4949
LL | pub struct InvariantRef<'a, T: ?Sized>(&'a T, PhantomData<&'a mut &'a T>);

tests/ui/issues/issue-41880.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `iter` found for struct `Iterate<{integer}, {closure@$DIR/issue-41880.rs:26:24: 26:27}>` in the current scope
1+
error[E0599]: no method named `iter` found for struct `Iterate<T, F>` in the current scope
22
--> $DIR/issue-41880.rs:27:24
33
|
44
LL | pub struct Iterate<T, F> {

tests/ui/methods/call_method_unknown_referent.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ error[E0282]: type annotations needed
1010
LL | let _b = (rc as std::rc::Rc<_>).read();
1111
| ^^^^ cannot infer type
1212

13-
error[E0599]: no method named `read` found for struct `SmartPtr<_>` in the current scope
13+
error[E0599]: no method named `read` found for struct `SmartPtr<T>` in the current scope
1414
--> $DIR/call_method_unknown_referent.rs:46:35
1515
|
1616
LL | struct SmartPtr<T>(T);

tests/ui/methods/method-not-found-generic-arg-elision.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ LL | let d = point_i32.distance();
1010
= note: the method was found for
1111
- `Point<f64>`
1212

13-
error[E0599]: no method named `other` found for struct `Point<i32>` in the current scope
13+
error[E0599]: no method named `other` found for struct `Point<T>` in the current scope
1414
--> $DIR/method-not-found-generic-arg-elision.rs:84:23
1515
|
1616
LL | struct Point<T> {
@@ -19,7 +19,7 @@ LL | struct Point<T> {
1919
LL | let d = point_i32.other();
2020
| ^^^^^ method not found in `Point<i32>`
2121

22-
error[E0599]: no method named `extend` found for struct `Map<std::slice::Iter<'_, i32>, Box<dyn for<'a> Fn(&'a i32) -> i32>>` in the current scope
22+
error[E0599]: no method named `extend` found for struct `Map<I, F>` in the current scope
2323
--> $DIR/method-not-found-generic-arg-elision.rs:87:67
2424
|
2525
LL | v.iter().map(Box::new(|x| x * x) as Box<dyn Fn(&i32) -> i32>).extend(std::iter::once(100));
@@ -41,7 +41,7 @@ LL | wrapper.method();
4141
- `Wrapper<i8>`
4242
and 2 more types
4343

44-
error[E0599]: no method named `other` found for struct `Wrapper<bool>` in the current scope
44+
error[E0599]: no method named `other` found for struct `Wrapper<T>` in the current scope
4545
--> $DIR/method-not-found-generic-arg-elision.rs:92:13
4646
|
4747
LL | struct Wrapper<T>(T);
@@ -64,7 +64,7 @@ LL | wrapper.method();
6464
- `Wrapper2<'a, i32, C>`
6565
- `Wrapper2<'a, i8, C>`
6666

67-
error[E0599]: no method named `other` found for struct `Wrapper2<'_, bool, 3>` in the current scope
67+
error[E0599]: no method named `other` found for struct `Wrapper2<'a, T, C>` in the current scope
6868
--> $DIR/method-not-found-generic-arg-elision.rs:98:13
6969
|
7070
LL | struct Wrapper2<'a, T, const C: usize> {

tests/ui/methods/untrimmed-path-type.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0599]: no method named `unknown` found for enum `Result<(), std::io::Error>` in the current scope
1+
error[E0599]: no method named `unknown` found for enum `Result<T, E>` in the current scope
22
--> $DIR/untrimmed-path-type.rs:5:11
33
|
44
LL | meow().unknown();

tests/ui/self/arbitrary_self_type_infinite_recursion.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ LL | p.method();
3232
|
3333
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`arbitrary_self_type_infinite_recursion`)
3434

35-
error[E0599]: no method named `method` found for struct `MySmartPtr<Content>` in the current scope
35+
error[E0599]: no method named `method` found for struct `MySmartPtr<T>` in the current scope
3636
--> $DIR/arbitrary_self_type_infinite_recursion.rs:21:5
3737
|
3838
LL | struct MySmartPtr<T>(T);

0 commit comments

Comments
 (0)