Skip to content

Commit 0c8c3b9

Browse files
authored
Rollup merge of #75511 - estebank:elide-trait-object-lt-error, r=lcnr
Do not emit E0228 when it is implied by E0106 Emit E0288 (lifetime bound for trait object cannot be deduced) only on bare trait objects. When the trait object is in the form of `&dyn Trait`, E0106 (missing lifetime specifier) will have been emitted, making the former redundant.
2 parents 2fb2af4 + b77c40e commit 0c8c3b9

File tree

3 files changed

+37
-67
lines changed

3 files changed

+37
-67
lines changed

src/librustc_typeck/astconv.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -1623,6 +1623,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
16231623
span: Span,
16241624
trait_bounds: &[hir::PolyTraitRef<'_>],
16251625
lifetime: &hir::Lifetime,
1626+
borrowed: bool,
16261627
) -> Ty<'tcx> {
16271628
let tcx = self.tcx();
16281629

@@ -1837,15 +1838,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
18371838
self.ast_region_to_region(lifetime, None)
18381839
} else {
18391840
self.re_infer(None, span).unwrap_or_else(|| {
1840-
// FIXME: these can be redundant with E0106, but not always.
1841-
struct_span_err!(
1841+
let mut err = struct_span_err!(
18421842
tcx.sess,
18431843
span,
18441844
E0228,
18451845
"the lifetime bound for this object type cannot be deduced \
18461846
from context; please supply an explicit bound"
1847-
)
1848-
.emit();
1847+
);
1848+
if borrowed {
1849+
// We will have already emitted an error E0106 complaining about a
1850+
// missing named lifetime in `&dyn Trait`, so we elide this one.
1851+
err.delay_as_bug();
1852+
} else {
1853+
err.emit();
1854+
}
18491855
tcx.lifetimes.re_static
18501856
})
18511857
}
@@ -2873,6 +2879,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28732879
/// Parses the programmer's textual representation of a type into our
28742880
/// internal notion of a type.
28752881
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
2882+
self.ast_ty_to_ty_inner(ast_ty, false)
2883+
}
2884+
2885+
/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
2886+
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
2887+
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
28762888
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})", ast_ty.hir_id, ast_ty, ast_ty.kind);
28772889

28782890
let tcx = self.tcx();
@@ -2885,7 +2897,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28852897
hir::TyKind::Rptr(ref region, ref mt) => {
28862898
let r = self.ast_region_to_region(region, None);
28872899
debug!("ast_ty_to_ty: r={:?}", r);
2888-
let t = self.ast_ty_to_ty(&mt.ty);
2900+
let t = self.ast_ty_to_ty_inner(&mt.ty, true);
28892901
tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
28902902
}
28912903
hir::TyKind::Never => tcx.types.never,
@@ -2903,7 +2915,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
29032915
))
29042916
}
29052917
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
2906-
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
2918+
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
29072919
}
29082920
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
29092921
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);

src/test/ui/suggestions/missing-lifetime-specifier.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ thread_local! {
2525
//~| ERROR missing lifetime specifier
2626
//~| ERROR missing lifetime specifier
2727
//~| ERROR missing lifetime specifier
28-
//~| ERROR the lifetime bound for this object type cannot be deduced from context
29-
//~| ERROR the lifetime bound for this object type cannot be deduced from context
3028
}
3129
thread_local! {
3230
static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
@@ -39,8 +37,6 @@ thread_local! {
3937
//~| ERROR missing lifetime specifier
4038
//~| ERROR missing lifetime specifier
4139
//~| ERROR missing lifetime specifier
42-
//~| ERROR the lifetime bound for this object type cannot be deduced from context
43-
//~| ERROR the lifetime bound for this object type cannot be deduced from context
4440
}
4541

4642
thread_local! {
@@ -52,9 +48,7 @@ thread_local! {
5248
}
5349
thread_local! {
5450
static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
55-
//~^ ERROR the lifetime bound for this object type cannot be deduced from context
56-
//~| ERROR the lifetime bound for this object type cannot be deduced from context
57-
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
51+
//~^ ERROR wrong number of lifetime arguments: expected 2, found 1
5852
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
5953
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
6054
//~| ERROR wrong number of lifetime arguments: expected 2, found 1

src/test/ui/suggestions/missing-lifetime-specifier.stderr

+18-54
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = Ref
7171
| ^^^^^^^^^^^^^^^^^^^^^
7272

7373
error[E0106]: missing lifetime specifiers
74-
--> $DIR/missing-lifetime-specifier.rs:32:48
74+
--> $DIR/missing-lifetime-specifier.rs:30:48
7575
|
7676
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
7777
| ^ expected 2 lifetime parameters
@@ -83,7 +83,7 @@ LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
8383
| ^^^^^^^^^^^^^^^^^
8484

8585
error[E0106]: missing lifetime specifiers
86-
--> $DIR/missing-lifetime-specifier.rs:32:48
86+
--> $DIR/missing-lifetime-specifier.rs:30:48
8787
|
8888
LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
8989
| ^ expected 2 lifetime parameters
@@ -95,7 +95,7 @@ LL | static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
9595
| ^^^^^^^^^^^^^^^^^
9696

9797
error[E0106]: missing lifetime specifier
98-
--> $DIR/missing-lifetime-specifier.rs:37:44
98+
--> $DIR/missing-lifetime-specifier.rs:35:44
9999
|
100100
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
101101
| ^ expected named lifetime parameter
@@ -107,7 +107,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
107107
| ^^^^^^^^
108108

109109
error[E0106]: missing lifetime specifiers
110-
--> $DIR/missing-lifetime-specifier.rs:37:49
110+
--> $DIR/missing-lifetime-specifier.rs:35:49
111111
|
112112
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
113113
| ^ expected 2 lifetime parameters
@@ -119,7 +119,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
119119
| ^^^^^^^^^^^^^^^^^
120120

121121
error[E0106]: missing lifetime specifier
122-
--> $DIR/missing-lifetime-specifier.rs:37:44
122+
--> $DIR/missing-lifetime-specifier.rs:35:44
123123
|
124124
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
125125
| ^ expected named lifetime parameter
@@ -131,7 +131,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<i32>>>>> = RefCell:
131131
| ^^^^^^^^
132132

133133
error[E0106]: missing lifetime specifiers
134-
--> $DIR/missing-lifetime-specifier.rs:37:49
134+
--> $DIR/missing-lifetime-specifier.rs:35:49
135135
|
136136
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
137137
| ^ expected 2 lifetime parameters
@@ -143,7 +143,7 @@ LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>>
143143
| ^^^^^^^^^^^^^^^^^
144144

145145
error[E0106]: missing lifetime specifier
146-
--> $DIR/missing-lifetime-specifier.rs:54:44
146+
--> $DIR/missing-lifetime-specifier.rs:50:44
147147
|
148148
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
149149
| ^ expected named lifetime parameter
@@ -155,7 +155,7 @@ LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> =
155155
| ^^^^^^^^
156156

157157
error[E0106]: missing lifetime specifier
158-
--> $DIR/missing-lifetime-specifier.rs:54:44
158+
--> $DIR/missing-lifetime-specifier.rs:50:44
159159
|
160160
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
161161
| ^ expected named lifetime parameter
@@ -166,91 +166,55 @@ help: consider using the `'static` lifetime
166166
LL | static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
167167
| ^^^^^^^^
168168

169-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
170-
--> $DIR/missing-lifetime-specifier.rs:23:45
171-
|
172-
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
173-
| ^^^
174-
175-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
176-
--> $DIR/missing-lifetime-specifier.rs:23:45
177-
|
178-
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
179-
| ^^^
180-
181-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
182-
--> $DIR/missing-lifetime-specifier.rs:37:45
183-
|
184-
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
185-
| ^^^^^^^^
186-
187-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
188-
--> $DIR/missing-lifetime-specifier.rs:37:45
189-
|
190-
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
191-
| ^^^^^^^^
192-
193169
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
194-
--> $DIR/missing-lifetime-specifier.rs:47:44
170+
--> $DIR/missing-lifetime-specifier.rs:43:44
195171
|
196172
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
197173
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
198174

199175
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
200-
--> $DIR/missing-lifetime-specifier.rs:47:44
176+
--> $DIR/missing-lifetime-specifier.rs:43:44
201177
|
202178
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
203179
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
204180

205181
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
206-
--> $DIR/missing-lifetime-specifier.rs:47:44
182+
--> $DIR/missing-lifetime-specifier.rs:43:44
207183
|
208184
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
209185
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
210186

211187
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
212-
--> $DIR/missing-lifetime-specifier.rs:47:44
188+
--> $DIR/missing-lifetime-specifier.rs:43:44
213189
|
214190
LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
215191
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
216192

217193
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
218-
--> $DIR/missing-lifetime-specifier.rs:54:45
194+
--> $DIR/missing-lifetime-specifier.rs:50:45
219195
|
220196
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
221197
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
222198

223199
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
224-
--> $DIR/missing-lifetime-specifier.rs:54:45
200+
--> $DIR/missing-lifetime-specifier.rs:50:45
225201
|
226202
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
227203
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
228204

229-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
230-
--> $DIR/missing-lifetime-specifier.rs:54:45
231-
|
232-
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
233-
| ^^^^^^^^^^^^^^^^^
234-
235205
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
236-
--> $DIR/missing-lifetime-specifier.rs:54:45
206+
--> $DIR/missing-lifetime-specifier.rs:50:45
237207
|
238208
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
239209
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
240210

241-
error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
242-
--> $DIR/missing-lifetime-specifier.rs:54:45
243-
|
244-
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
245-
| ^^^^^^^^^^^^^^^^^
246-
247211
error[E0107]: wrong number of lifetime arguments: expected 2, found 1
248-
--> $DIR/missing-lifetime-specifier.rs:54:45
212+
--> $DIR/missing-lifetime-specifier.rs:50:45
249213
|
250214
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
251215
| ^^^^^^^^^^^^^^^^^ expected 2 lifetime arguments
252216

253-
error: aborting due to 28 previous errors
217+
error: aborting due to 22 previous errors
254218

255-
Some errors have detailed explanations: E0106, E0107, E0228.
219+
Some errors have detailed explanations: E0106, E0107.
256220
For more information about an error, try `rustc --explain E0106`.

0 commit comments

Comments
 (0)