Skip to content

Commit 054c577

Browse files
committed
Revert support for the never type partially
1 parent 7569e17 commit 054c577

10 files changed

+107
-104
lines changed

gcc/rust/typecheck/rust-hir-type-check-expr.h

+15-4
Original file line numberDiff line numberDiff line change
@@ -626,17 +626,28 @@ class TypeCheckExpr : public TypeCheckBase
626626
auto else_blk_resolved
627627
= TypeCheckExpr::Resolve (expr.get_else_block (), inside_loop);
628628

629-
infered = if_blk_resolved->unify (else_blk_resolved);
629+
if (if_blk_resolved->get_kind () == TyTy::NEVER)
630+
infered = else_blk_resolved;
631+
else if (else_blk_resolved->get_kind () == TyTy::NEVER)
632+
infered = if_blk_resolved;
633+
else
634+
infered = if_blk_resolved->unify (else_blk_resolved);
630635
}
631636

632637
void visit (HIR::IfExprConseqIf &expr) override
633638
{
634639
TypeCheckExpr::Resolve (expr.get_if_condition (), false);
635-
auto if_blk = TypeCheckExpr::Resolve (expr.get_if_block (), inside_loop);
636-
auto else_blk
640+
auto if_blk_resolved
641+
= TypeCheckExpr::Resolve (expr.get_if_block (), inside_loop);
642+
auto else_blk_resolved
637643
= TypeCheckExpr::Resolve (expr.get_conseq_if_expr (), inside_loop);
638644

639-
infered = if_blk->unify (else_blk);
645+
if (if_blk_resolved->get_kind () == TyTy::NEVER)
646+
infered = else_blk_resolved;
647+
else if (else_blk_resolved->get_kind () == TyTy::NEVER)
648+
infered = if_blk_resolved;
649+
else
650+
infered = if_blk_resolved->unify (else_blk_resolved);
640651
}
641652

642653
void visit (HIR::BlockExpr &expr) override;

gcc/rust/typecheck/rust-hir-type-check-item.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ class TypeCheckItem : public TypeCheckBase
8282

8383
context->pop_return_type ();
8484

85-
expected_ret_tyty->unify (block_expr_ty);
85+
if (block_expr_ty->get_kind () != TyTy::NEVER)
86+
expected_ret_tyty->unify (block_expr_ty);
8687
}
8788

8889
private:

gcc/rust/typecheck/rust-hir-type-check-stmt.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class TypeCheckStmt : public TypeCheckBase
4343
{
4444
infered = TypeCheckExpr::Resolve (stmt.get_expr (), inside_loop);
4545

46-
if (stmt.is_unit_check_needed ())
46+
if (stmt.is_unit_check_needed () && infered->get_kind () != TyTy::NEVER)
4747
{
4848
auto unit = new TyTy::TupleType (stmt.get_mappings ().get_hirid ());
4949
infered = unit->unify (infered);

gcc/rust/typecheck/rust-tyty-cmp.h

+1-35
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class BaseCmp : public TyVisitor
8484

8585
virtual void visit (StrType &) override { ok = false; }
8686

87-
virtual void visit (NeverType &) override { ok = true; }
87+
virtual void visit (NeverType &) override { ok = false; }
8888

8989
protected:
9090
BaseCmp (BaseType *base)
@@ -815,40 +815,6 @@ class NeverCmp : public BaseCmp
815815
public:
816816
NeverCmp (NeverType *base) : BaseCmp (base), base (base) {}
817817

818-
void visit (TupleType &type) override { ok = true; }
819-
820-
void visit (ADTType &type) override { ok = true; }
821-
822-
void visit (InferType &type) override { ok = true; }
823-
824-
void visit (FnType &type) override { ok = true; }
825-
826-
void visit (FnPtr &type) override { ok = true; }
827-
828-
void visit (ArrayType &type) override { ok = true; }
829-
830-
void visit (BoolType &type) override { ok = true; }
831-
832-
void visit (IntType &type) override { ok = true; }
833-
834-
void visit (UintType &type) override { ok = true; }
835-
836-
void visit (USizeType &type) override { ok = true; }
837-
838-
void visit (ISizeType &type) override { ok = true; }
839-
840-
void visit (FloatType &type) override { ok = true; }
841-
842-
void visit (ErrorType &type) override { ok = true; }
843-
844-
void visit (CharType &type) override { ok = true; }
845-
846-
void visit (ReferenceType &type) override { ok = true; }
847-
848-
void visit (ParamType &type) override { ok = true; }
849-
850-
void visit (StrType &type) override { ok = true; }
851-
852818
void visit (NeverType &type) override { ok = true; }
853819

854820
private:

gcc/rust/typecheck/rust-tyty-rules.h

+4-38
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,10 @@ class BaseRules : public TyVisitor
244244

245245
virtual void visit (NeverType &type) override
246246
{
247-
resolved = get_base ()->clone ();
247+
Location ref_locus = mappings->lookup_location (type.get_ref ());
248+
rust_error_at (ref_locus, "expected [%s] got [%s]",
249+
get_base ()->as_string ().c_str (),
250+
type.as_string ().c_str ());
248251
}
249252

250253
protected:
@@ -1099,43 +1102,6 @@ class NeverRules : public BaseRules
10991102
public:
11001103
NeverRules (NeverType *base) : BaseRules (base), base (base) {}
11011104

1102-
virtual void visit (TupleType &type) override { resolved = type.clone (); }
1103-
1104-
virtual void visit (ADTType &type) override { resolved = type.clone (); }
1105-
1106-
virtual void visit (InferType &type) override { resolved = type.clone (); }
1107-
1108-
virtual void visit (FnType &type) override { resolved = type.clone (); }
1109-
1110-
virtual void visit (FnPtr &type) override { resolved = type.clone (); }
1111-
1112-
virtual void visit (ArrayType &type) override { resolved = type.clone (); }
1113-
1114-
virtual void visit (BoolType &type) override { resolved = type.clone (); }
1115-
1116-
virtual void visit (IntType &type) override { resolved = type.clone (); }
1117-
1118-
virtual void visit (UintType &type) override { resolved = type.clone (); }
1119-
1120-
virtual void visit (USizeType &type) override { resolved = type.clone (); }
1121-
1122-
virtual void visit (ISizeType &type) override { resolved = type.clone (); }
1123-
1124-
virtual void visit (FloatType &type) override { resolved = type.clone (); }
1125-
1126-
virtual void visit (ErrorType &type) override { resolved = type.clone (); }
1127-
1128-
virtual void visit (CharType &type) override { resolved = type.clone (); }
1129-
1130-
virtual void visit (ReferenceType &type) override
1131-
{
1132-
resolved = type.clone ();
1133-
}
1134-
1135-
virtual void visit (ParamType &type) override { resolved = type.clone (); }
1136-
1137-
virtual void visit (StrType &type) override { resolved = type.clone (); }
1138-
11391105
virtual void visit (NeverType &type) override { resolved = type.clone (); }
11401106

11411107
private:

gcc/rust/typecheck/rust-tyty.h

+9
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,15 @@ class StrType : public BaseType
12191219
};
12201220

12211221
// https://doc.rust-lang.org/std/primitive.never.html
1222+
//
1223+
// Since the `!` type is really complicated and it is even still unstable
1224+
// in rustc, only fairly limited support for this type is introduced here.
1225+
// Unification between `!` and ANY other type (including `<T?>`) is simply
1226+
// not allowed. If it is needed, it should be handled manually. For example,
1227+
// unifying `!` with other types are very necessary when resolving types of
1228+
// `if/else` expressions.
1229+
//
1230+
// See related discussion at https://github.com/Rust-GCC/gccrs/pull/364
12221231
class NeverType : public BaseType
12231232
{
12241233
public:

gcc/testsuite/rust.test/compile/never_type1.rs

-23
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,18 @@
1-
fn test(x: i32) -> i32 {
1+
fn test1(x: i32) -> i32 {
22
// { dg-error "expected .i32. got .bool." "" { target *-*-*} .-1 }
33
return 1;
44
// { dg-warning "unreachable expression" "" { target *-*-* } .+1 }
55
true
66
}
77

8+
fn test2(x: bool) -> bool {
9+
// { dg-error "expected .bool. got ...." "" { target *-*-*} .-1 }
10+
return x;
11+
// { dg-warning "unreachable expression" "" { target *-*-* } .+1 }
12+
()
13+
}
14+
815
fn main() {
9-
let a = test(1);
16+
let a = test1(1);
17+
let a = test2(true);
1018
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// FIXME: Unimplemented features
2+
fn foo() -> ! { // { dg-error "unresolved type" }
3+
let a: !; // { dg-error "unresolved type" }
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
fn foo() -> i32 {
2+
let c;
3+
let d;
4+
5+
c = if false {
6+
return 1;
7+
} else {
8+
0.0
9+
};
10+
11+
d = if true {
12+
0.0;
13+
} else {
14+
return 1;
15+
};
16+
17+
0
18+
}
19+
20+
fn bar() -> i32 {
21+
let a;
22+
let b;
23+
24+
// FIXME: Unimplemented features
25+
a = if true { // { dg-error "expected .T.. got .!." }
26+
// { dg-error "type resolution failure in AssignmentExpr" "" { target { *-*-* } } .-1 }
27+
return 0;
28+
} else {
29+
return 0;
30+
};
31+
32+
// FIXME: Unimplemented features
33+
b = return 0; // { dg-error "expected .T.. got .!." }
34+
// { dg-error "type resolution failure in AssignmentExpr" "" { target { *-*-* } } .-1 }
35+
// { dg-warning "unreachable statement" "" { target { *-*-* } } .-2 }
36+
}
37+
38+
fn baz() -> i32 {
39+
let mut x = (1.0, return 1, 2.0);
40+
41+
x.1 = return 2;
42+
// { dg-warning "unreachable statement" "" { target { *-*-* } } .-1 }
43+
44+
x.1 = 3; // { dg-error "expected .!. got .<integer>." }
45+
// { dg-error "type resolution failure in AssignmentExpr" "" { target { *-*-* } } .-1 }
46+
// { dg-warning "unreachable statement" "" { target { *-*-* } } .-2 }
47+
48+
x.0 = -1.0;
49+
// { dg-warning "unreachable statement" "" { target { *-*-* } } .-1 }
50+
51+
// FIXME: Unimplemented features
52+
x.0 = return -1; // { dg-error "expected .<float>. got .!." }
53+
// { dg-error "type resolution failure in AssignmentExpr" "" { target { *-*-* } } .-1 }
54+
// { dg-warning "unreachable statement" "" { target { *-*-* } } .-2 }
55+
}
56+
57+
fn main() {
58+
foo();
59+
bar();
60+
baz();
61+
}

0 commit comments

Comments
 (0)