about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2020-08-14 14:46:56 -0700
committerGitHub <noreply@github.com>2020-08-14 14:46:56 -0700
commit0c8c3b9079bb5213d846cc592e36d6f851d01bb7 (patch)
tree905b96fd5653814c1f57e21398e1e1581c74f1f3
parent2fb2af4f1d12bd65e0b58adf701f7598c51ca831 (diff)
parentb77c40e42d9249de3ac38829c8cfa22aa609e3a9 (diff)
downloadrust-0c8c3b9079bb5213d846cc592e36d6f851d01bb7.tar.gz
rust-0c8c3b9079bb5213d846cc592e36d6f851d01bb7.zip
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.
-rw-r--r--src/librustc_typeck/astconv.rs24
-rw-r--r--src/test/ui/suggestions/missing-lifetime-specifier.rs8
-rw-r--r--src/test/ui/suggestions/missing-lifetime-specifier.stderr72
3 files changed, 37 insertions, 67 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 2be100ae336..3093ddbeaf1 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 b09c1879d70..fe88d105c78 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<HashMap<i32, Vec<Vec<Qux<i32>>>>> = 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<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
diff --git a/src/test/ui/suggestions/missing-lifetime-specifier.stderr b/src/test/ui/suggestions/missing-lifetime-specifier.stderr
index 2630cf1affa..9838ac72ad7 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<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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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`.