From: badumbatish <tanghocle...@gmail.com>

gcc/rust/ChangeLog:

        * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):
        Added noreturn checking for nevertype

gcc/testsuite/ChangeLog:

        * rust/compile/inline_asm_typecheck.rs: New test.
---
 .../typecheck/rust-hir-type-check-expr.cc     | 18 +++++++++-------
 .../rust/compile/inline_asm_typecheck.rs      | 21 +++++++++++++++++++
 2 files changed, 32 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/rust/compile/inline_asm_typecheck.rs

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index a9255fc69f2..ba22eaff441 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -623,10 +623,9 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
              && (((TyTy::InferType *) loop_context_type)->get_infer_kind ()
                  != TyTy::InferType::GENERAL));
 
-      infered = loop_context_type_infered
-                 ? loop_context_type
-                 : TyTy::TupleType::get_unit_type (
-                     expr.get_mappings ().get_hirid ());
+      infered = loop_context_type_infered ? loop_context_type
+                                         : TyTy::TupleType::get_unit_type (
+                                           expr.get_mappings ().get_hirid ());
     }
   else
     {
@@ -829,9 +828,14 @@ TypeCheckExpr::visit (HIR::InlineAsm &expr)
 {
   typecheck_inline_asm_operand (expr);
 
-  // TODO: Hoise out if we have noreturn as an option
+  // NOTE: Hoise out if we have noreturn as an option
   // to return a never type
-  infered = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
+  // TODO : new keyword for memory seems sooooo shaky
+  if (expr.options.count (AST::InlineAsmOption::NORETURN) == 1)
+    infered = new TyTy::NeverType (expr.get_mappings ().get_hirid ());
+  else
+    infered
+      = TyTy::TupleType::get_unit_type (expr.get_mappings ().get_hirid ());
 }
 
 void
@@ -1625,7 +1629,7 @@ TypeCheckExpr::visit (HIR::ClosureExpr &expr)
   TyTy::TyVar result_type
     = expr.has_return_type ()
        ? TyTy::TyVar (
-           TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
+         TypeCheckType::Resolve (expr.get_return_type ().get ())->get_ref ())
        : TyTy::TyVar::get_implicit_infer_var (expr.get_locus ());
 
   // resolve the block
diff --git a/gcc/testsuite/rust/compile/inline_asm_typecheck.rs 
b/gcc/testsuite/rust/compile/inline_asm_typecheck.rs
new file mode 100644
index 00000000000..22b7fb162c1
--- /dev/null
+++ b/gcc/testsuite/rust/compile/inline_asm_typecheck.rs
@@ -0,0 +1,21 @@
+#![feature(rustc_attrs)]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+
+fn main() {
+    let mut _num1: i32 = 10;
+    let mut _num2: i32 = 10;
+    unsafe {
+        // This demonstrates that asm!'s is inferred with a unit type is 
parsed correctly.
+        let _ = asm!("nop");
+
+        // This errors out per rust spec
+        //      The asm! block never returns, and its return type is defined 
as ! (never).
+        //      Behavior is undefined if execution falls through past the end 
of the asm code.
+        //      A noreturn asm block behaves just like a function which 
doesn't return; notably, local variables in scope are not dropped before it is 
invoked.
+        let _ = asm!("nop", options(noreturn));
+    }
+}
-- 
2.45.2

Reply via email to