Skip to content

Commit 8ea5362

Browse files
committed
Avoid ICE on type error recovery
Fix #86756
1 parent 3cb1c11 commit 8ea5362

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

Diff for: compiler/rustc_typeck/src/astconv/mod.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2121
use rustc_hir::intravisit::{walk_generics, Visitor as _};
2222
use rustc_hir::lang_items::LangItem;
2323
use rustc_hir::{Constness, GenericArg, GenericArgs};
24-
use rustc_middle::ty::subst::{self, InternalSubsts, Subst, SubstsRef};
24+
use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
2525
use rustc_middle::ty::GenericParamDefKind;
2626
use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
2727
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
@@ -488,12 +488,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
488488
tcx.ty_error().into()
489489
} else {
490490
// This is a default type parameter.
491+
let substs = substs.unwrap();
492+
if substs.iter().any(|arg| match arg.unpack() {
493+
GenericArgKind::Type(ty) => ty.references_error(),
494+
_ => false,
495+
}) {
496+
// Avoid ICE #86756 when type error recovery goes awry.
497+
return tcx.ty_error().into();
498+
}
491499
self.astconv
492500
.normalize_ty(
493501
self.span,
494502
tcx.at(self.span).type_of(param.def_id).subst_spanned(
495503
tcx,
496-
substs.unwrap(),
504+
substs,
497505
Some(self.span),
498506
),
499507
)

Diff for: src/test/ui/issues/issue-86756.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
trait Foo<T, T = T> {}
2+
//~^ ERROR the name `T` is already used for a generic parameter in this item's generic parameters
3+
4+
fn eq<A, B>() {
5+
eq::<dyn, Foo>
6+
//~^ ERROR cannot find type `dyn` in this scope
7+
//~| ERROR missing generics for trait `Foo`
8+
//~| WARN trait objects without an explicit `dyn` are deprecated
9+
//~| WARN this is accepted in the current edition
10+
}
11+
12+
fn main() {}

Diff for: src/test/ui/issues/issue-86756.stderr

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
2+
--> $DIR/issue-86756.rs:1:14
3+
|
4+
LL | trait Foo<T, T = T> {}
5+
| - ^ already used
6+
| |
7+
| first use of `T`
8+
9+
error[E0412]: cannot find type `dyn` in this scope
10+
--> $DIR/issue-86756.rs:5:10
11+
|
12+
LL | fn eq<A, B>() {
13+
| - help: you might be missing a type parameter: `, dyn`
14+
LL | eq::<dyn, Foo>
15+
| ^^^ not found in this scope
16+
17+
warning: trait objects without an explicit `dyn` are deprecated
18+
--> $DIR/issue-86756.rs:5:15
19+
|
20+
LL | eq::<dyn, Foo>
21+
| ^^^ help: use `dyn`: `dyn Foo`
22+
|
23+
= note: `#[warn(bare_trait_objects)]` on by default
24+
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
25+
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
26+
27+
error[E0107]: missing generics for trait `Foo`
28+
--> $DIR/issue-86756.rs:5:15
29+
|
30+
LL | eq::<dyn, Foo>
31+
| ^^^ expected at least 1 generic argument
32+
|
33+
note: trait defined here, with at least 1 generic parameter: `T`
34+
--> $DIR/issue-86756.rs:1:7
35+
|
36+
LL | trait Foo<T, T = T> {}
37+
| ^^^ -
38+
help: add missing generic argument
39+
|
40+
LL | eq::<dyn, Foo<T>>
41+
| ^^^^^^
42+
43+
error: aborting due to 3 previous errors; 1 warning emitted
44+
45+
Some errors have detailed explanations: E0107, E0403, E0412.
46+
For more information about an error, try `rustc --explain E0107`.

0 commit comments

Comments
 (0)