Skip to content

Commit 94c11df

Browse files
committed
Report "nice" placeholder errors more often
If we have a cause containing `ValuePairs::PolyTraitRefs` but neither TraitRef has any escaping bound regions then we report the same error as for `ValuePairs::TraitRefs`.
1 parent daab6db commit 94c11df

19 files changed

+181
-263
lines changed

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs

+69-73
Original file line numberDiff line numberDiff line change
@@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> {
3030
Some(RegionResolutionError::SubSupConflict(
3131
vid,
3232
_,
33-
SubregionOrigin::Subtype(box TypeTrace {
34-
cause,
35-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
36-
}),
33+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
3734
sub_placeholder @ ty::RePlaceholder(_),
3835
_,
3936
sup_placeholder @ ty::RePlaceholder(_),
40-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
37+
)) => self.try_report_trait_placeholder_mismatch(
4138
Some(self.tcx().mk_region(ty::ReVar(*vid))),
4239
cause,
4340
Some(sub_placeholder),
4441
Some(sup_placeholder),
45-
expected.def_id,
46-
expected.substs,
47-
found.substs,
48-
)),
42+
values,
43+
),
4944

5045
Some(RegionResolutionError::SubSupConflict(
5146
vid,
5247
_,
53-
SubregionOrigin::Subtype(box TypeTrace {
54-
cause,
55-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
56-
}),
48+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
5749
sub_placeholder @ ty::RePlaceholder(_),
5850
_,
5951
_,
60-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
52+
)) => self.try_report_trait_placeholder_mismatch(
6153
Some(self.tcx().mk_region(ty::ReVar(*vid))),
6254
cause,
6355
Some(sub_placeholder),
6456
None,
65-
expected.def_id,
66-
expected.substs,
67-
found.substs,
68-
)),
57+
values,
58+
),
6959

7060
Some(RegionResolutionError::SubSupConflict(
7161
vid,
7262
_,
73-
SubregionOrigin::Subtype(box TypeTrace {
74-
cause,
75-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
76-
}),
63+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
7764
_,
7865
_,
7966
sup_placeholder @ ty::RePlaceholder(_),
80-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
67+
)) => self.try_report_trait_placeholder_mismatch(
8168
Some(self.tcx().mk_region(ty::ReVar(*vid))),
8269
cause,
8370
None,
8471
Some(*sup_placeholder),
85-
expected.def_id,
86-
expected.substs,
87-
found.substs,
88-
)),
72+
values,
73+
),
8974

9075
Some(RegionResolutionError::SubSupConflict(
9176
vid,
9277
_,
9378
_,
9479
_,
95-
SubregionOrigin::Subtype(box TypeTrace {
96-
cause,
97-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
98-
}),
80+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
9981
sup_placeholder @ ty::RePlaceholder(_),
100-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
82+
)) => self.try_report_trait_placeholder_mismatch(
10183
Some(self.tcx().mk_region(ty::ReVar(*vid))),
10284
cause,
10385
None,
10486
Some(*sup_placeholder),
105-
expected.def_id,
106-
expected.substs,
107-
found.substs,
108-
)),
87+
values,
88+
),
10989

11090
Some(RegionResolutionError::UpperBoundUniverseConflict(
11191
vid,
11292
_,
11393
_,
114-
SubregionOrigin::Subtype(box TypeTrace {
115-
cause,
116-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
117-
}),
94+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
11895
sup_placeholder @ ty::RePlaceholder(_),
119-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
96+
)) => self.try_report_trait_placeholder_mismatch(
12097
Some(self.tcx().mk_region(ty::ReVar(*vid))),
12198
cause,
12299
None,
123100
Some(*sup_placeholder),
124-
expected.def_id,
125-
expected.substs,
126-
found.substs,
127-
)),
101+
values,
102+
),
128103

129104
Some(RegionResolutionError::ConcreteFailure(
130-
SubregionOrigin::Subtype(box TypeTrace {
131-
cause,
132-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
133-
}),
105+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
134106
sub_region @ ty::RePlaceholder(_),
135107
sup_region @ ty::RePlaceholder(_),
136-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
108+
)) => self.try_report_trait_placeholder_mismatch(
137109
None,
138110
cause,
139111
Some(*sub_region),
140112
Some(*sup_region),
141-
expected.def_id,
142-
expected.substs,
143-
found.substs,
144-
)),
113+
values,
114+
),
145115

146116
Some(RegionResolutionError::ConcreteFailure(
147-
SubregionOrigin::Subtype(box TypeTrace {
148-
cause,
149-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
150-
}),
117+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
151118
sub_region @ ty::RePlaceholder(_),
152119
sup_region,
153-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
120+
)) => self.try_report_trait_placeholder_mismatch(
154121
Some(sup_region),
155122
cause,
156123
Some(*sub_region),
157124
None,
158-
expected.def_id,
159-
expected.substs,
160-
found.substs,
161-
)),
125+
values,
126+
),
162127

163128
Some(RegionResolutionError::ConcreteFailure(
164-
SubregionOrigin::Subtype(box TypeTrace {
165-
cause,
166-
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
167-
}),
129+
SubregionOrigin::Subtype(box TypeTrace { cause, values }),
168130
sub_region,
169131
sup_region @ ty::RePlaceholder(_),
170-
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait(
132+
)) => self.try_report_trait_placeholder_mismatch(
171133
Some(sub_region),
172134
cause,
173135
None,
174136
Some(*sup_region),
175-
expected.def_id,
176-
expected.substs,
177-
found.substs,
178-
)),
137+
values,
138+
),
179139

180140
_ => None,
181141
}
182142
}
183143

144+
fn try_report_trait_placeholder_mismatch(
145+
&self,
146+
vid: Option<ty::Region<'tcx>>,
147+
cause: &ObligationCause<'tcx>,
148+
sub_placeholder: Option<ty::Region<'tcx>>,
149+
sup_placeholder: Option<ty::Region<'tcx>>,
150+
value_pairs: &ValuePairs<'tcx>,
151+
) -> Option<DiagnosticBuilder<'tcx>> {
152+
let (expected_substs, found_substs, trait_def_id) = match value_pairs {
153+
ValuePairs::TraitRefs(ExpectedFound { expected, found })
154+
if expected.def_id == found.def_id =>
155+
{
156+
(expected.substs, found.substs, expected.def_id)
157+
}
158+
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
159+
if expected.def_id() == found.def_id() =>
160+
{
161+
// It's possible that the placeholders come from a binder
162+
// outside of this value pair. Use `no_bound_vars` as a
163+
// simple heuristic for that.
164+
(expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id())
165+
}
166+
_ => return None,
167+
};
168+
169+
Some(self.report_trait_placeholder_mismatch(
170+
vid,
171+
cause,
172+
sub_placeholder,
173+
sup_placeholder,
174+
trait_def_id,
175+
expected_substs,
176+
found_substs,
177+
))
178+
}
179+
184180
// error[E0308]: implementation of `Foo` does not apply to enough lifetimes
185181
// --> /home/nmatsakis/tmp/foo.rs:12:5
186182
// |
@@ -191,7 +187,7 @@ impl NiceRegionError<'me, 'tcx> {
191187
// = note: `T` must implement `...` for any two lifetimes `'1` and `'2`.
192188
// = note: However, the type `T` only implements `...` for some specific lifetime `'2`.
193189
#[instrument(level = "debug", skip(self))]
194-
fn try_report_placeholders_trait(
190+
fn report_trait_placeholder_mismatch(
195191
&self,
196192
vid: Option<ty::Region<'tcx>>,
197193
cause: &ObligationCause<'tcx>,

src/test/ui/hrtb/hrtb-perfect-forwarding.nll.stderr

+20-18
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
warning: function cannot return without recursing
2-
--> $DIR/hrtb-perfect-forwarding.rs:22:1
2+
--> $DIR/hrtb-perfect-forwarding.rs:16:1
33
|
4-
LL | / fn no_hrtb<'b,T>(mut t: T)
5-
LL | | where T : Bar<&'b isize>
4+
LL | / fn no_hrtb<'b, T>(mut t: T)
5+
LL | | where
6+
LL | | T: Bar<&'b isize>,
67
LL | | {
7-
LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
8-
LL | | // `&mut T : Bar<&'b isize>`.
8+
... |
99
LL | | no_hrtb(&mut t);
1010
| | --------------- recursive call site
1111
LL | | }
@@ -15,12 +15,12 @@ LL | | }
1515
= help: a `loop` may express intention better if this is on purpose
1616

1717
warning: function cannot return without recursing
18-
--> $DIR/hrtb-perfect-forwarding.rs:30:1
18+
--> $DIR/hrtb-perfect-forwarding.rs:25:1
1919
|
2020
LL | / fn bar_hrtb<T>(mut t: T)
21-
LL | | where T : for<'b> Bar<&'b isize>
21+
LL | | where
22+
LL | | T: for<'b> Bar<&'b isize>,
2223
LL | | {
23-
LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
2424
... |
2525
LL | | bar_hrtb(&mut t);
2626
| | ---------------- recursive call site
@@ -30,25 +30,26 @@ LL | | }
3030
= help: a `loop` may express intention better if this is on purpose
3131

3232
warning: function cannot return without recursing
33-
--> $DIR/hrtb-perfect-forwarding.rs:39:1
33+
--> $DIR/hrtb-perfect-forwarding.rs:35:1
3434
|
35-
LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T)
36-
LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
35+
LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
36+
LL | | where
37+
LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
3738
LL | | {
38-
LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
3939
... |
4040
LL | | foo_hrtb_bar_not(&mut t);
4141
| | ------------------------ recursive call site
4242
LL | |
43+
LL | |
4344
LL | | }
4445
| |_^ cannot return without recursing
4546
|
4647
= help: a `loop` may express intention better if this is on purpose
4748

4849
error: lifetime may not live long enough
49-
--> $DIR/hrtb-perfect-forwarding.rs:46:5
50+
--> $DIR/hrtb-perfect-forwarding.rs:43:5
5051
|
51-
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
52+
LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
5253
| -- lifetime `'b` defined here
5354
...
5455
LL | foo_hrtb_bar_not(&mut t);
@@ -57,18 +58,19 @@ LL | foo_hrtb_bar_not(&mut t);
5758
= help: consider replacing `'b` with `'static`
5859

5960
error: higher-ranked subtype error
60-
--> $DIR/hrtb-perfect-forwarding.rs:46:5
61+
--> $DIR/hrtb-perfect-forwarding.rs:43:5
6162
|
6263
LL | foo_hrtb_bar_not(&mut t);
6364
| ^^^^^^^^^^^^^^^^^^^^^^^^
6465

6566
warning: function cannot return without recursing
66-
--> $DIR/hrtb-perfect-forwarding.rs:50:1
67+
--> $DIR/hrtb-perfect-forwarding.rs:48:1
6768
|
6869
LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
69-
LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>
70+
LL | | where
71+
LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
7072
LL | | {
71-
LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`.
73+
LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`.
7274
LL | | foo_hrtb_bar_hrtb(&mut t);
7375
| | ------------------------- recursive call site
7476
LL | | }

0 commit comments

Comments
 (0)