Skip to content

Commit

Permalink
Do not emit E0228 when it is implied by E0106
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
estebank committed Aug 14, 2020
1 parent 3df25ae commit b77c40e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 67 deletions.
24 changes: 18 additions & 6 deletions src/librustc_typeck/astconv.rs
Expand Up @@ -1623,6 +1623,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span: Span,
trait_bounds: &[hir::PolyTraitRef<'_>],
lifetime: &hir::Lifetime,
borrowed: bool,
) -> Ty<'tcx> {
let tcx = self.tcx();

Expand Down Expand Up @@ -1837,15 +1838,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
self.ast_region_to_region(lifetime, None)
} else {
self.re_infer(None, span).unwrap_or_else(|| {
// FIXME: these can be redundant with E0106, but not always.
struct_span_err!(
let mut err = struct_span_err!(
tcx.sess,
span,
E0228,
"the lifetime bound for this object type cannot be deduced \
from context; please supply an explicit bound"
)
.emit();
);
if borrowed {
// We will have already emitted an error E0106 complaining about a
// missing named lifetime in `&dyn Trait`, so we elide this one.
err.delay_as_bug();
} else {
err.emit();
}
tcx.lifetimes.re_static
})
}
Expand Down Expand Up @@ -2873,6 +2879,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Parses the programmer's textual representation of a type into our
/// internal notion of a type.
pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
self.ast_ty_to_ty_inner(ast_ty, false)
}

/// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
/// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
debug!("ast_ty_to_ty(id={:?}, ast_ty={:?} ty_ty={:?})", ast_ty.hir_id, ast_ty, ast_ty.kind);

let tcx = self.tcx();
Expand All @@ -2885,7 +2897,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
hir::TyKind::Rptr(ref region, ref mt) => {
let r = self.ast_region_to_region(region, None);
debug!("ast_ty_to_ty: r={:?}", r);
let t = self.ast_ty_to_ty(&mt.ty);
let t = self.ast_ty_to_ty_inner(&mt.ty, true);
tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
}
hir::TyKind::Never => tcx.types.never,
Expand All @@ -2903,7 +2915,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
))
}
hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime)
self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
}
hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
Expand Down
8 changes: 1 addition & 7 deletions src/test/ui/suggestions/missing-lifetime-specifier.rs
Expand Up @@ -25,8 +25,6 @@ thread_local! {
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}
thread_local! {
static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
Expand All @@ -39,8 +37,6 @@ thread_local! {
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR missing lifetime specifier
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
}

thread_local! {
Expand All @@ -52,9 +48,7 @@ thread_local! {
}
thread_local! {
static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
//~^ ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR the lifetime bound for this object type cannot be deduced from context
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~^ ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
//~| ERROR wrong number of lifetime arguments: expected 2, found 1
Expand Down
72 changes: 18 additions & 54 deletions src/test/ui/suggestions/missing-lifetime-specifier.stderr
Expand Up @@ -71,7 +71,7 @@ LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar<'static, 'static>>>>> = Ref
| ^^^^^^^^^^^^^^^^^^^^^

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

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

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

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

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

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

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

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

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:23:45
|
LL | static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
| ^^^

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:37:45
|
LL | static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^

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

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

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

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

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

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

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^

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

error[E0228]: the lifetime bound for this object type cannot be deduced from context; please supply an explicit bound
--> $DIR/missing-lifetime-specifier.rs:54:45
|
LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
| ^^^^^^^^^^^^^^^^^

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

error: aborting due to 28 previous errors
error: aborting due to 22 previous errors

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

0 comments on commit b77c40e

Please sign in to comment.