Skip to content

Commit

Permalink
Checking generic args after late bound region err.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
davidtwco committed May 17, 2019
1 parent 7158ed9 commit bff8a86
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
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
@@ -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
@@ -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 bff8a86

Please sign in to comment.