about summary refs log tree commit diff
diff options
context:
space:
mode:
author许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-08 16:14:54 +0800
committer许杰友 Jieyou Xu (Joe) <jieyouxu@outlook.com>2023-06-12 15:15:45 +0800
commit72421bfb0c2a2a0209fbc96bb9a7d332589661d9 (patch)
tree00c01db2169402a330a332ba04a719560be09810
parent37998ab508d5d9fa0d465d7b535dc673087dda8f (diff)
downloadrust-72421bfb0c2a2a0209fbc96bb9a7d332589661d9.tar.gz
rust-72421bfb0c2a2a0209fbc96bb9a7d332589661d9.zip
Fix debug ICE for extern type with where clauses
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs20
-rw-r--r--tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.rs10
-rw-r--r--tests/ui/extern/issue-112363-extern-item-where-clauses-debug-ice.stderr47
-rw-r--r--tests/ui/parser/foreign-ty-semantic-fail.rs1
-rw-r--r--tests/ui/parser/foreign-ty-semantic-fail.stderr13
5 files changed, 85 insertions, 6 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 04ed2767876..a0979bbda54 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<Span>) {
@@ -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 00000000000..17e08f511d7
--- /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 00000000000..bdc6755038a
--- /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 <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`.
diff --git a/tests/ui/parser/foreign-ty-semantic-fail.rs b/tests/ui/parser/foreign-ty-semantic-fail.rs
index 96b15232b10..4d30086e765 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 588e4966aae..2b400dfea3b 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