From: Pierre-Emmanuel Patry <[email protected]>
gcc/rust/ChangeLog:
* typecheck/rust-coercion.cc (TypeCoercionRules::do_coercion):
Move nevertype coercion from here...
(TypeCoercionRules::coerce_never): ... to here.
* typecheck/rust-coercion.h: Add function prototype.
Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
gcc/rust/typecheck/rust-coercion.cc | 75 +++++++++++++++--------------
gcc/rust/typecheck/rust-coercion.h | 1 +
2 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/gcc/rust/typecheck/rust-coercion.cc
b/gcc/rust/typecheck/rust-coercion.cc
index aa9675afa01..cf285956d16 100644
--- a/gcc/rust/typecheck/rust-coercion.cc
+++ b/gcc/rust/typecheck/rust-coercion.cc
@@ -61,44 +61,9 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
// see:
//
https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
- // handle never
- //
https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
if (receiver->get_kind () == TyTy::TypeKind::NEVER)
{
- // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
- // type variable, we want `?T` to fallback to `!` if not
- // otherwise constrained. An example where this arises:
- //
- // let _: Option<?T> = Some({ return; });
- //
- // here, we would coerce from `!` to `?T`.
- if (expected->has_substitutions_defined () && !expected->is_concrete ())
- {
- location_t locus = mappings.lookup_location (receiver->get_ref ());
- TyTy::TyVar implicit_var
- = TyTy::TyVar::get_implicit_infer_var (locus);
- try_result = CoercionResult{{}, implicit_var.get_tyty ()};
- }
- else
- {
- bool expected_is_infer_var
- = expected->get_kind () == TyTy::TypeKind::INFER;
- bool expected_is_general_infer_var
- = expected_is_infer_var
- && (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
- == TyTy::InferType::InferTypeKind::GENERAL);
-
- // FIXME this 'expected_is_general_infer_var' case needs to eventually
- // should go away see: compile/never_type_err1.rs
- //
- // I think we need inference obligations to say that yes we have a
- // general inference variable but we add the oligation to the expected
- // type that it could default to '!'
- if (expected_is_general_infer_var)
- try_result = CoercionResult{{}, receiver};
- else
- try_result = CoercionResult{{}, expected->clone ()};
- }
+ try_result = coerce_never (receiver);
return true;
}
@@ -169,6 +134,44 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
return !try_result.is_error ();
}
+TypeCoercionRules::CoercionResult
+TypeCoercionRules::coerce_never (TyTy::BaseType *receiver)
+{
+ // handle never
+ //
https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
+
+ // Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
+ // type variable, we want `?T` to fallback to `!` if not
+ // otherwise constrained. An example where this arises:
+ //
+ // let _: Option<?T> = Some({ return; });
+ //
+ // here, we would coerce from `!` to `?T`.
+ if (expected->has_substitutions_defined () && !expected->is_concrete ())
+ {
+ location_t locus = mappings.lookup_location (receiver->get_ref ());
+ TyTy::TyVar implicit_var = TyTy::TyVar::get_implicit_infer_var (locus);
+ return CoercionResult{{}, implicit_var.get_tyty ()};
+ }
+
+ bool expected_is_infer_var = expected->get_kind () == TyTy::TypeKind::INFER;
+ bool expected_is_general_infer_var
+ = expected_is_infer_var
+ && (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
+ == TyTy::InferType::InferTypeKind::GENERAL);
+
+ // FIXME this 'expected_is_general_infer_var' case needs to eventually
+ // should go away see: compile/never_type_err1.rs
+ //
+ // I think we need inference obligations to say that yes we have a
+ // general inference variable but we add the oligation to the expected
+ // type that it could default to '!'
+ if (expected_is_general_infer_var)
+ return CoercionResult{{}, receiver};
+ else
+ return CoercionResult{{}, expected->clone ()};
+}
+
TypeCoercionRules::CoercionResult
TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
TyTy::PointerType *expected,
diff --git a/gcc/rust/typecheck/rust-coercion.h
b/gcc/rust/typecheck/rust-coercion.h
index 3a74794c924..864f48ad58b 100644
--- a/gcc/rust/typecheck/rust-coercion.h
+++ b/gcc/rust/typecheck/rust-coercion.h
@@ -58,6 +58,7 @@ public:
bool allow_autoderef,
bool is_cast_site = false);
+ CoercionResult coerce_never (TyTy::BaseType *receiver);
CoercionResult coerce_unsafe_ptr (TyTy::BaseType *receiver,
TyTy::PointerType *expected,
Mutability mutability);
--
2.50.1