From 72421bfb0c2a2a0209fbc96bb9a7d332589661d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E6=9D=B0=E5=8F=8B=20Jieyou=20Xu=20=28Joe=29?= Date: Thu, 8 Jun 2023 16:14:54 +0800 Subject: [PATCH] Fix debug ICE for extern type with where clauses --- .../rustc_ast_passes/src/ast_validation.rs | 20 ++++++-- ...363-extern-item-where-clauses-debug-ice.rs | 10 ++++ ...extern-item-where-clauses-debug-ice.stderr | 47 +++++++++++++++++++ tests/ui/parser/foreign-ty-semantic-fail.rs | 1 + .../ui/parser/foreign-ty-semantic-fail.stderr | 13 ++++- 5 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs create mode 100644 tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 04ed276787652..a0979bbda5452 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -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, @@ -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) { @@ -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) => { diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs new file mode 100644 index 0000000000000..17e08f511d71f --- /dev/null +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs @@ -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() {} diff --git a/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr new file mode 100644 index 0000000000000..bdc6755038aa4 --- /dev/null +++ b/tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr @@ -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 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`. diff --git a/tests/ui/parser/foreign-ty-semantic-fail.rs b/tests/ui/parser/foreign-ty-semantic-fail.rs index 96b15232b10d0..4d30086e76536 100644 --- a/tests/ui/parser/foreign-ty-semantic-fail.rs +++ b/tests/ui/parser/foreign-ty-semantic-fail.rs @@ -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 } diff --git a/tests/ui/parser/foreign-ty-semantic-fail.stderr b/tests/ui/parser/foreign-ty-semantic-fail.stderr index 588e4966aaeb5..2b400dfea3bfa 100644 --- a/tests/ui/parser/foreign-ty-semantic-fail.stderr +++ b/tests/ui/parser/foreign-ty-semantic-fail.stderr @@ -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