Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix debug ICE for extern type with where clauses #112416

Merged
merged 1 commit into from
Jun 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions compiler/rustc_ast_passes/src/ast_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,12 @@ impl<'a> AstValidator<'a> {
self.err_handler().emit_err(errors::BoundInContext { span, ctx });
}

fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) {
fn check_foreign_ty_genericless(
&self,
generics: &Generics,
before_where_clause: &TyAliasWhereClause,
after_where_clause: &TyAliasWhereClause,
) {
let cannot_have = |span, descr, remove_descr| {
self.err_handler().emit_err(errors::ExternTypesCannotHave {
span,
Expand All @@ -378,9 +383,14 @@ impl<'a> AstValidator<'a> {
cannot_have(generics.span, "generic parameters", "generic parameters");
}

if !generics.where_clause.predicates.is_empty() {
cannot_have(where_span, "`where` clauses", "`where` clause");
}
let check_where_clause = |where_clause: &TyAliasWhereClause| {
if let TyAliasWhereClause(true, where_clause_span) = where_clause {
cannot_have(*where_clause_span, "`where` clauses", "`where` clause");
}
};

check_where_clause(before_where_clause);
check_where_clause(after_where_clause);
}

fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Span>) {
Expand Down Expand Up @@ -1039,7 +1049,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.check_defaultness(fi.span, *defaultness);
self.check_foreign_kind_bodyless(fi.ident, "type", ty.as_ref().map(|b| b.span));
self.check_type_no_bounds(bounds, "`extern` blocks");
self.check_foreign_ty_genericless(generics, where_clauses.0.1);
self.check_foreign_ty_genericless(generics, &where_clauses.0, &where_clauses.1);
self.check_foreign_item_ascii_only(fi.ident);
}
ForeignItemKind::Static(_, _, body) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
extern "C" {
type Item = [T] where [T]: Sized;
//~^ incorrect `type` inside `extern` block
//~| `type`s inside `extern` blocks cannot have `where` clauses
//~| cannot find type `T` in this scope
//~| cannot find type `T` in this scope
//~| extern types are experimental
}

fn main() {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
error: incorrect `type` inside `extern` block
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:10
|
LL | extern "C" {
| ---------- `extern` blocks define existing foreign types and types inside of them cannot have a body
LL | type Item = [T] where [T]: Sized;
| ^^^^ --- the invalid body
| |
| cannot have a body
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error: `type`s inside `extern` blocks cannot have `where` clauses
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:21
|
LL | extern "C" {
| ---------- `extern` block begins here
LL | type Item = [T] where [T]: Sized;
| ^^^^^^^^^^^^^^^^ help: remove the `where` clause
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

error[E0412]: cannot find type `T` in this scope
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:28
|
LL | type Item = [T] where [T]: Sized;
| ^ not found in this scope

error[E0412]: cannot find type `T` in this scope
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:18
|
LL | type Item = [T] where [T]: Sized;
| ^ not found in this scope

error[E0658]: extern types are experimental
--> $DIR/issue-112363-extern-item-where-clauses-debug-ice.rs:2:5
|
LL | type Item = [T] where [T]: Sized;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #43467 <https://github.com/rust-lang/rust/issues/43467> for more information
= help: add `#![feature(extern_types)]` to the crate attributes to enable

error: aborting due to 5 previous errors

Some errors have detailed explanations: E0412, E0658.
For more information about an error, try `rustc --explain E0412`.
1 change: 1 addition & 0 deletions tests/ui/parser/foreign-ty-semantic-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ extern "C" {
//~^ ERROR incorrect `type` inside `extern` block

type E: where;
//~^ ERROR `type`s inside `extern` blocks cannot have `where` clauses
}
13 changes: 12 additions & 1 deletion tests/ui/parser/foreign-ty-semantic-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,16 @@ LL | type D = u8;
|
= note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html

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

error: aborting due to 7 previous errors