Skip to content

Commit

Permalink
Auto merge of #60892 - davidtwco:issue-60622, r=oli-obk
Browse files Browse the repository at this point in the history
Checking generic args after late bound region err.

Fixes #60622.

This PR 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.
  • Loading branch information
bors committed May 17, 2019
2 parents 68fd80f + bff8a86 commit 3940146
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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);
}
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/test/ui/issue-60622.rs
Original file line number Diff line number Diff line change
@@ -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() {}
27 changes: 27 additions & 0 deletions src/test/ui/issue-60622.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 3940146

Please sign in to comment.