Skip to content

Commit 32c568d

Browse files
committed
resolve: Add "break rust" Easter egg
When we encounter a "break rust" statement, emit a funny error message and intentionally cause an ICE. This matches the corresponding Easter egg in rustc. As a GNU extension, "break gcc" is also supported. The conditions for this to happen are: * The break expression must be literally "rust" or "gcc". For instance, "break (rust)" will not trigger the Easter egg. * The name ("rust" or "gcc") must not be in scope; if it is, no error is emitted, and the compilation proceeds as usual. In other words, this only affects how GCC diagnoses programs that would fail to compile anyway. Closes #1996 gcc/rust/ChangeLog: * resolve/rust-ast-resolve-expr.cc: Add "break rust" Easter egg gcc/testsuite/ChangeLog: * rust/compile/break-rust1.rs: New test * rust/compile/break-rust2.rs: New test * rust/compile/break-rust3.rs: New test Signed-off-by: Sergey Bugaev <[email protected]>
1 parent c4fff19 commit 32c568d

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

gcc/rust/resolve/rust-ast-resolve-expr.cc

+17-1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ ResolveExpr::visit (AST::IdentifierExpr &expr)
120120
{
121121
resolver->insert_resolved_type (expr.get_node_id (), resolved_node);
122122
}
123+
else if (funny_error)
124+
{
125+
rust_error_at (expr.get_locus (), "oopsie woopsie! you broke GCC Rust");
126+
internal_error_no_backtrace ("you broke me");
127+
}
123128
else
124129
{
125130
rust_error_at (expr.get_locus (), "failed to find name: %s",
@@ -384,7 +389,18 @@ ResolveExpr::visit (AST::BreakExpr &expr)
384389
}
385390

386391
if (expr.has_break_expr ())
387-
ResolveExpr::go (expr.get_break_expr ().get (), prefix, canonical_prefix);
392+
{
393+
bool funny_error = false;
394+
AST::Expr &break_expr = *expr.get_break_expr ().get ();
395+
if (break_expr.get_ast_kind () == AST::Kind::IDENTIFIER)
396+
{
397+
std::string ident
398+
= static_cast<AST::IdentifierExpr &> (break_expr).as_string ();
399+
if (ident == "rust" || ident == "gcc")
400+
funny_error = true;
401+
}
402+
ResolveExpr::go (&break_expr, prefix, canonical_prefix, funny_error);
403+
}
388404
}
389405

390406
void
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
let rust = "crab";
3+
let res = loop {
4+
// { dg-warning "unused name" "" { target *-*-* } .-1 }
5+
break rust;
6+
};
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
break (rust);
3+
// { dg-error "failed to find name: rust" "" { target *-*-* } .-1 }
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
fn main() {
2+
break rust;
3+
// { dg-error "oopsie woopsie! you broke GCC Rust" "" { target *-*-* } .-1 }
4+
// { dg-ice "you broke me" }
5+
}

0 commit comments

Comments
 (0)