about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2019-05-16 22:00:27 +0100
committerDavid Wood <david@davidtw.co>2019-05-17 09:12:40 +0100
commitbff8a86698195ba2d2798405d3535efdce2fccef (patch)
tree4791a63441241e5de62c85e26b992d4868a2d70c
parent7158ed9cbea805adf8161d3deaadba2f85b7692e (diff)
downloadrust-bff8a86698195ba2d2798405d3535efdce2fccef.tar.gz
rust-bff8a86698195ba2d2798405d3535efdce2fccef.zip
Checking generic args after late bound region err.
This commit fixes an ICE that occurs when a late bound region error is
emitted and that resulted in the rest of the generic arguments of a
function not being checked.

For example, you could specify a generic type parameter `T` in a function
call `foo<'_, T>()` to a function that doesn't have a generic type
parameter.

Since an error wasn't emitted from the function, compilation
continued to parts of typeck that didn't expect a generic type argument
in a call for a function that didn't have any generic type arguments.
-rw-r--r--src/librustc_typeck/astconv.rs12
-rw-r--r--src/test/ui/issue-60622.rs18
-rw-r--r--src/test/ui/issue-60622.stderr27
3 files changed, 52 insertions, 5 deletions
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index caefe124211..4b052aec5fc 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -290,6 +290,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
         }
 
         // Prohibit explicit lifetime arguments if late-bound lifetime parameters are present.
+        let mut reported_late_bound_region_err = None;
         if !infer_lifetimes {
             if let Some(span_late) = def.has_late_bound_regions {
                 let msg = "cannot specify lifetime arguments explicitly \
@@ -301,13 +302,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                     let mut err = tcx.sess.struct_span_err(span, msg);
                     err.span_note(span_late, note);
                     err.emit();
-                    return (true, None);
+                    reported_late_bound_region_err = Some(true);
                 } else {
                     let mut multispan = MultiSpan::from_span(span);
                     multispan.push_span_label(span_late, note.to_string());
                     tcx.lint_hir(lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS,
                                  args.args[0].id(), multispan, msg);
-                    return (false, None);
+                    reported_late_bound_region_err = Some(false);
                 }
             }
         }
@@ -325,7 +326,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
             // For kinds without defaults (i.e., lifetimes), `required == permitted`.
             // For other kinds (i.e., types), `permitted` may be greater than `required`.
             if required <= provided && provided <= permitted {
-                return (false, None);
+                return (reported_late_bound_region_err.unwrap_or(false), None);
             }
 
             // Unfortunately lifetime and type parameter mismatches are typically styled
@@ -380,7 +381,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
              potential_assoc_types)
         };
 
-        if !infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes {
+        if reported_late_bound_region_err.is_none()
+            && (!infer_lifetimes || arg_counts.lifetimes > param_counts.lifetimes) {
             check_kind_count(
                 "lifetime",
                 param_counts.lifetimes,
@@ -410,7 +412,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
                 arg_counts.lifetimes,
             )
         } else {
-            (false, None)
+            (reported_late_bound_region_err.unwrap_or(false), None)
         }
     }
 
diff --git a/src/test/ui/issue-60622.rs b/src/test/ui/issue-60622.rs
new file mode 100644
index 00000000000..d6a0189c3e0
--- /dev/null
+++ b/src/test/ui/issue-60622.rs
@@ -0,0 +1,18 @@
+// ignore-tidy-linelength
+
+#![deny(warnings)]
+
+struct Borked {}
+
+impl Borked {
+    fn a(&self) {}
+}
+
+fn run_wild<T>(b: &Borked) {
+    b.a::<'_, T>();
+    //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+    //~^^ ERROR wrong number of type arguments: expected 0, found 1
+    //~^^^ WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+}
+
+fn main() {}
diff --git a/src/test/ui/issue-60622.stderr b/src/test/ui/issue-60622.stderr
new file mode 100644
index 00000000000..0c337c315f1
--- /dev/null
+++ b/src/test/ui/issue-60622.stderr
@@ -0,0 +1,27 @@
+error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present
+  --> $DIR/issue-60622.rs:12:11
+   |
+LL |     fn a(&self) {}
+   |          - the late bound lifetime parameter is introduced here
+...
+LL |     b.a::<'_, T>();
+   |           ^^
+   |
+note: lint level defined here
+  --> $DIR/issue-60622.rs:3:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: #[deny(late_bound_lifetime_arguments)] implied by #[deny(warnings)]
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #42868 <https://github.com/rust-lang/rust/issues/42868>
+
+error[E0107]: wrong number of type arguments: expected 0, found 1
+  --> $DIR/issue-60622.rs:12:15
+   |
+LL |     b.a::<'_, T>();
+   |               ^ unexpected type argument
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0107`.