Skip to content

Commit 418bbb2

Browse files
authored
Rollup merge of #145765 - lqd:revert-142034, r=fmease
Revert suggestions for missing methods in tuples As requested by `@estebank` and as discussed with `@jackh726,` this reverts #142034 because of diagnostics ICEs like #142488 and its duplicates that have reached stable by now. We will work on a proper fix to reland this cool work in the near future, but in the meantime, a revert is safer to validate and backport to beta and stable, so here it is.
2 parents 676d383 + 5a2b70b commit 418bbb2

File tree

5 files changed

+111
-218
lines changed

5 files changed

+111
-218
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 2 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
1313
use rustc_data_structures::sorted_map::SortedMap;
1414
use rustc_data_structures::unord::UnordSet;
1515
use rustc_errors::codes::*;
16-
use rustc_errors::{
17-
Applicability, Diag, DiagStyledString, MultiSpan, StashKey, pluralize, struct_span_code_err,
18-
};
16+
use rustc_errors::{Applicability, Diag, MultiSpan, StashKey, pluralize, struct_span_code_err};
1917
use rustc_hir::attrs::AttributeKind;
2018
use rustc_hir::def::{CtorKind, DefKind, Res};
2119
use rustc_hir::def_id::DefId;
@@ -1560,11 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15601558
);
15611559
}
15621560

1563-
if rcvr_ty.is_numeric() && rcvr_ty.is_fresh()
1564-
|| restrict_type_params
1565-
|| suggested_derive
1566-
|| self.lookup_alternative_tuple_impls(&mut err, &unsatisfied_predicates)
1567-
{
1561+
if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params || suggested_derive {
15681562
} else {
15691563
self.suggest_traits_to_import(
15701564
&mut err,
@@ -1741,119 +1735,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
17411735
err.emit()
17421736
}
17431737

1744-
/// If the predicate failure is caused by an unmet bound on a tuple, recheck if the bound would
1745-
/// succeed if all the types on the tuple had no borrows. This is a common problem for libraries
1746-
/// like Bevy and ORMs, which rely heavily on traits being implemented on tuples.
1747-
fn lookup_alternative_tuple_impls(
1748-
&self,
1749-
err: &mut Diag<'_>,
1750-
unsatisfied_predicates: &[(
1751-
ty::Predicate<'tcx>,
1752-
Option<ty::Predicate<'tcx>>,
1753-
Option<ObligationCause<'tcx>>,
1754-
)],
1755-
) -> bool {
1756-
let mut found_tuple = false;
1757-
for (pred, root, _ob) in unsatisfied_predicates {
1758-
let mut preds = vec![pred];
1759-
if let Some(root) = root {
1760-
// We will look at both the current predicate and the root predicate that caused it
1761-
// to be needed. If calling something like `<(A, &B)>::default()`, then `pred` is
1762-
// `&B: Default` and `root` is `(A, &B): Default`, which is the one we are checking
1763-
// for further down, so we check both.
1764-
preds.push(root);
1765-
}
1766-
for pred in preds {
1767-
if let Some(clause) = pred.as_clause()
1768-
&& let Some(clause) = clause.as_trait_clause()
1769-
&& let ty = clause.self_ty().skip_binder()
1770-
&& let ty::Tuple(types) = ty.kind()
1771-
{
1772-
let path = clause.skip_binder().trait_ref.print_only_trait_path();
1773-
let def_id = clause.def_id();
1774-
let ty = Ty::new_tup(
1775-
self.tcx,
1776-
self.tcx.mk_type_list_from_iter(types.iter().map(|ty| ty.peel_refs())),
1777-
);
1778-
let args = ty::GenericArgs::for_item(self.tcx, def_id, |param, _| {
1779-
if param.index == 0 {
1780-
ty.into()
1781-
} else {
1782-
self.infcx.var_for_def(DUMMY_SP, param)
1783-
}
1784-
});
1785-
if self
1786-
.infcx
1787-
.type_implements_trait(def_id, args, self.param_env)
1788-
.must_apply_modulo_regions()
1789-
{
1790-
// "`Trait` is implemented for `(A, B)` but not for `(A, &B)`"
1791-
let mut msg = DiagStyledString::normal(format!("`{path}` "));
1792-
msg.push_highlighted("is");
1793-
msg.push_normal(" implemented for `(");
1794-
let len = types.len();
1795-
for (i, t) in types.iter().enumerate() {
1796-
msg.push(
1797-
format!("{}", with_forced_trimmed_paths!(t.peel_refs())),
1798-
t.peel_refs() != t,
1799-
);
1800-
if i < len - 1 {
1801-
msg.push_normal(", ");
1802-
}
1803-
}
1804-
msg.push_normal(")` but ");
1805-
msg.push_highlighted("not");
1806-
msg.push_normal(" for `(");
1807-
for (i, t) in types.iter().enumerate() {
1808-
msg.push(
1809-
format!("{}", with_forced_trimmed_paths!(t)),
1810-
t.peel_refs() != t,
1811-
);
1812-
if i < len - 1 {
1813-
msg.push_normal(", ");
1814-
}
1815-
}
1816-
msg.push_normal(")`");
1817-
1818-
// Find the span corresponding to the impl that was found to point at it.
1819-
if let Some(impl_span) = self
1820-
.tcx
1821-
.all_impls(def_id)
1822-
.filter(|&impl_def_id| {
1823-
let header = self.tcx.impl_trait_header(impl_def_id).unwrap();
1824-
let trait_ref = header.trait_ref.instantiate(
1825-
self.tcx,
1826-
self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id),
1827-
);
1828-
1829-
let value = ty::fold_regions(self.tcx, ty, |_, _| {
1830-
self.tcx.lifetimes.re_erased
1831-
});
1832-
// FIXME: Don't bother dealing with non-lifetime binders here...
1833-
if value.has_escaping_bound_vars() {
1834-
return false;
1835-
}
1836-
self.infcx.can_eq(ty::ParamEnv::empty(), trait_ref.self_ty(), value)
1837-
&& header.polarity == ty::ImplPolarity::Positive
1838-
})
1839-
.map(|impl_def_id| self.tcx.def_span(impl_def_id))
1840-
.next()
1841-
{
1842-
err.highlighted_span_note(impl_span, msg.0);
1843-
} else {
1844-
err.highlighted_note(msg.0);
1845-
}
1846-
found_tuple = true;
1847-
}
1848-
// If `pred` was already on the tuple, we don't need to look at the root
1849-
// obligation too.
1850-
break;
1851-
}
1852-
}
1853-
}
1854-
found_tuple
1855-
}
1856-
18571738
/// If an appropriate error source is not found, check method chain for possible candidates
18581739
fn lookup_segments_chain_for_no_match_method(
18591740
&self,

tests/ui/methods/missing-bound-on-tuple.rs

Lines changed: 0 additions & 39 deletions
This file was deleted.

tests/ui/methods/missing-bound-on-tuple.stderr

Lines changed: 0 additions & 58 deletions
This file was deleted.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Regression test for issue #142488, a diagnostics ICE when trying to suggest missing methods
2+
// present in similar tuple types.
3+
// This is a few of the MCVEs from the issues and its many duplicates.
4+
5+
// 1
6+
fn main() {
7+
for a in x {
8+
//~^ ERROR: cannot find value `x` in this scope
9+
(a,).to_string()
10+
//~^ ERROR: the method `to_string` exists for tuple
11+
}
12+
}
13+
14+
// 2
15+
trait Trait {
16+
fn meth(self);
17+
}
18+
19+
impl<T, U: Trait> Trait for (T, U) {
20+
fn meth(self) {}
21+
}
22+
23+
fn mcve2() {
24+
((), std::collections::HashMap::new()).meth()
25+
//~^ ERROR: the method `meth` exists for tuple
26+
}
27+
28+
// 3
29+
trait I {}
30+
31+
struct Struct;
32+
impl I for Struct {}
33+
34+
trait Tr {
35+
fn f<A>(self) -> (A,)
36+
where
37+
Self: Sized,
38+
{
39+
loop {}
40+
}
41+
}
42+
43+
impl<T> Tr for T where T: I {}
44+
45+
fn mcve3() {
46+
Struct.f().f();
47+
//~^ ERROR: the method `f` exists for tuple
48+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
error[E0425]: cannot find value `x` in this scope
2+
--> $DIR/tuple-suggestions-issue-142488.rs:7:14
3+
|
4+
LL | for a in x {
5+
| ^ not found in this scope
6+
7+
error[E0599]: the method `to_string` exists for tuple `(_,)`, but its trait bounds were not satisfied
8+
--> $DIR/tuple-suggestions-issue-142488.rs:9:14
9+
|
10+
LL | (a,).to_string()
11+
| ^^^^^^^^^ method cannot be called on `(_,)` due to unsatisfied trait bounds
12+
|
13+
= note: the following trait bounds were not satisfied:
14+
`(_,): std::fmt::Display`
15+
which is required by `(_,): ToString`
16+
17+
error[E0599]: the method `meth` exists for tuple `((), HashMap<_, _>)`, but its trait bounds were not satisfied
18+
--> $DIR/tuple-suggestions-issue-142488.rs:24:44
19+
|
20+
LL | ((), std::collections::HashMap::new()).meth()
21+
| ^^^^ method cannot be called on `((), HashMap<_, _>)` due to unsatisfied trait bounds
22+
|
23+
note: trait bound `HashMap<_, _>: Trait` was not satisfied
24+
--> $DIR/tuple-suggestions-issue-142488.rs:19:12
25+
|
26+
LL | impl<T, U: Trait> Trait for (T, U) {
27+
| ^^^^^ ----- ------
28+
| |
29+
| unsatisfied trait bound introduced here
30+
= help: items from traits can only be used if the trait is implemented and in scope
31+
note: `Trait` defines an item `meth`, perhaps you need to implement it
32+
--> $DIR/tuple-suggestions-issue-142488.rs:15:1
33+
|
34+
LL | trait Trait {
35+
| ^^^^^^^^^^^
36+
37+
error[E0599]: the method `f` exists for tuple `(_,)`, but its trait bounds were not satisfied
38+
--> $DIR/tuple-suggestions-issue-142488.rs:46:16
39+
|
40+
LL | Struct.f().f();
41+
| ^ method cannot be called on `(_,)` due to unsatisfied trait bounds
42+
|
43+
note: the following trait bounds were not satisfied:
44+
`&(_,): I`
45+
`&mut (_,): I`
46+
`(_,): I`
47+
--> $DIR/tuple-suggestions-issue-142488.rs:43:27
48+
|
49+
LL | impl<T> Tr for T where T: I {}
50+
| -- - ^ unsatisfied trait bound introduced here
51+
= help: items from traits can only be used if the trait is implemented and in scope
52+
note: `Tr` defines an item `f`, perhaps you need to implement it
53+
--> $DIR/tuple-suggestions-issue-142488.rs:34:1
54+
|
55+
LL | trait Tr {
56+
| ^^^^^^^^
57+
58+
error: aborting due to 4 previous errors
59+
60+
Some errors have detailed explanations: E0425, E0599.
61+
For more information about an error, try `rustc --explain E0425`.

0 commit comments

Comments
 (0)