diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2be100ae33662..3093ddbeaf1ae 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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(); @@ -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 }) } @@ -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(); @@ -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, @@ -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); diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.rs b/src/test/ui/suggestions/missing-lifetime-specifier.rs index b09c1879d7015..fe88d105c78bf 100644 --- a/src/test/ui/suggestions/missing-lifetime-specifier.rs +++ b/src/test/ui/suggestions/missing-lifetime-specifier.rs @@ -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>>>> = RefCell::new(HashMap::new()); @@ -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! { @@ -52,9 +48,7 @@ thread_local! { } thread_local! { static f: RefCell>>>> = 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 diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr index 2630cf1affae6..9838ac72ad767 100644 --- a/src/test/ui/suggestions/missing-lifetime-specifier.stderr +++ b/src/test/ui/suggestions/missing-lifetime-specifier.stderr @@ -71,7 +71,7 @@ LL | static b: RefCell>>>> = Ref | ^^^^^^^^^^^^^^^^^^^^^ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:32:48 + --> $DIR/missing-lifetime-specifier.rs:30:48 | LL | static c: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -83,7 +83,7 @@ LL | static c: RefCell>>>> = | ^^^^^^^^^^^^^^^^^ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:32:48 + --> $DIR/missing-lifetime-specifier.rs:30:48 | LL | static c: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -95,7 +95,7 @@ LL | static c: RefCell>>>> = | ^^^^^^^^^^^^^^^^^ error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:37:44 + --> $DIR/missing-lifetime-specifier.rs:35:44 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -107,7 +107,7 @@ LL | static d: RefCell>>>> = RefCell: | ^^^^^^^^ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:37:49 + --> $DIR/missing-lifetime-specifier.rs:35:49 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -119,7 +119,7 @@ LL | static d: RefCell>>>> | ^^^^^^^^^^^^^^^^^ error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:37:44 + --> $DIR/missing-lifetime-specifier.rs:35:44 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -131,7 +131,7 @@ LL | static d: RefCell>>>> = RefCell: | ^^^^^^^^ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:37:49 + --> $DIR/missing-lifetime-specifier.rs:35:49 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -143,7 +143,7 @@ LL | static d: RefCell>>>> | ^^^^^^^^^^^^^^^^^ error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:54:44 + --> $DIR/missing-lifetime-specifier.rs:50:44 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -155,7 +155,7 @@ LL | static f: RefCell>>>> = | ^^^^^^^^ error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:54:44 + --> $DIR/missing-lifetime-specifier.rs:50:44 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -166,91 +166,55 @@ help: consider using the `'static` lifetime LL | static f: RefCell>>>> = 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>>> = 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>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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>>>> = 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`.