Skip to content

Commit 72421bf

Browse files
committed
Fix debug ICE for extern type with where clauses
1 parent 37998ab commit 72421bf

5 files changed

+85
-6
lines changed

compiler/rustc_ast_passes/src/ast_validation.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> {
364364
self.err_handler().emit_err(errors::BoundInContext { span, ctx });
365365
}
366366

367-
fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
367+
fn check_foreign_ty_genericless(
368+
&self,
369+
generics: &Generics,
370+
before_where_clause: &TyAliasWhereClause,
371+
after_where_clause: &TyAliasWhereClause,
372+
) {
368373
let cannot_have = |span, descr, remove_descr| {
369374
self.err_handler().emit_err(errors::ExternTypesCannotHave {
370375
span,
@@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> {
378383
cannot_have(generics.span, "generic parameters", "generic parameters");
379384
}
380385

381-
if !generics.where_clause.predicates.is_empty() {
382-
cannot_have(where_span, "`where` clauses", "`where` clause");
383-
}
386+
let check_where_clause = |where_clause: &TyAliasWhereClause| {
387+
if let TyAliasWhereClause(true, where_clause_span) = where_clause {
388+
cannot_have(*where_clause_span, "`where` clauses", "`where` clause");
389+
}
390+
};
391+
392+
check_where_clause(before_where_clause);
393+
check_where_clause(after_where_clause);
384394
}
385395

386396
fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
@@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
10391049
self.check_defaultness(fi.span, *defaultness);
10401050
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
10411051
self.check_type_no_bounds(bounds, "`extern` blocks");
1042-
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
1052+
self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1);
10431053
self.check_foreign_item_ascii_only(fi.ident);
10441054
}
10451055
ForeignItemKind::Static(_, _, body) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
extern "C" {
2+
type Item = [T] where [T]: Sized;
3+
//~^ incorrect `type` inside `extern` block
4+
//~| `type`s inside `extern` blocks cannot have `where` clauses
5+
//~| cannot find type `T` in this scope
6+
//~| cannot find type `T` in this scope
7+
//~| extern types are experimental
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error: incorrect `type` inside `extern` block
2+
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:10
3+
|
4+
LL | extern "C" {
5+
| ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body
6+
LL | type Item = [T] where [T]: Sized;
7+
| ^^^^ --- the invalid body
8+
| |
9+
| cannot have a body
10+
|
11+
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
12+
13+
error: `type`s inside `extern` blocks cannot have `where` clauses
14+
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:21
15+
|
16+
LL | extern "C" {
17+
| ---------- `extern` block begins here
18+
LL | type Item = [T] where [T]: Sized;
19+
| ^^^^^^^^^^^^^^^^ help: remove the `where` clause
20+
|
21+
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
22+
23+
error[E0412]: cannot find type `T` in this scope
24+
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28
25+
|
26+
LL | type Item = [T] where [T]: Sized;
27+
| ^ not found in this scope
28+
29+
error[E0412]: cannot find type `T` in this scope
30+
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18
31+
|
32+
LL | type Item = [T] where [T]: Sized;
33+
| ^ not found in this scope
34+
35+
error[E0658]: extern types are experimental
36+
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:5
37+
|
38+
LL | type Item = [T] where [T]: Sized;
39+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40+
|
41+
= note: see issue #43467 <https://github.com/rust-lang/rust/issues/43467> for more information
42+
= help: add `#![feature(extern_types)]` to the crate attributes to enable
43+
44+
error: aborting due to 5 previous errors
45+
46+
Some errors have detailed explanations: E0412, E0658.
47+
For more information about an error, try `rustc --explain E0412`.

tests/ui/parser/foreign-ty-semantic-fail.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ extern "C" {
1515
//~^ ERROR incorrect `type` inside `extern` block
1616

1717
type E: where;
18+
//~^ ERROR `type`s inside `extern` blocks cannot have `where` clauses
1819
}

tests/ui/parser/foreign-ty-semantic-fail.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,16 @@ LL | type D = u8;
6161
|
6262
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
6363

64-
error: aborting due to 6 previous errors
64+
error: `type`s inside `extern` blocks cannot have `where` clauses
65+
--> $DIR/foreign-ty-semantic-fail.rs:17:13
66+
|
67+
LL | extern "C" {
68+
| ---------- `extern` block begins here
69+
...
70+
LL | type E: where;
71+
| ^^^^^ help: remove the `where` clause
72+
|
73+
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
74+
75+
error: aborting due to 7 previous errors
6576

0 commit comments

Comments
 (0)