From bff8a86698195ba2d2798405d3535efdce2fccef Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 16 May 2019 22:00:27 +0100 Subject: [PATCH] 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. --- src/librustc_typeck/astconv.rs | 12 +++++++----- src/test/ui/issue-60622.rs | 18 ++++++++++++++++++ src/test/ui/issue-60622.stderr | 27 +++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/issue-60622.rs create mode 100644 src/test/ui/issue-60622.stderr diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index caefe12421155..4b052aec5fc2f 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 0000000000000..d6a0189c3e042 --- /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(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 0000000000000..0c337c315f161 --- /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 + +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`.