Skip to content

Commit 1b60b86

Browse files
committed
Put nevertype cercion into it's own function
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]>
1 parent fa30123 commit 1b60b86

File tree

2 files changed

+40
-36
lines changed

2 files changed

+40
-36
lines changed

gcc/rust/typecheck/rust-coercion.cc

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -61,44 +61,9 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
6161
// see:
6262
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
6363

64-
// handle never
65-
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
6664
if (receiver->get_kind () == TyTy::TypeKind::NEVER)
6765
{
68-
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
69-
// type variable, we want `?T` to fallback to `!` if not
70-
// otherwise constrained. An example where this arises:
71-
//
72-
// let _: Option<?T> = Some({ return; });
73-
//
74-
// here, we would coerce from `!` to `?T`.
75-
if (expected->has_substitutions_defined () && !expected->is_concrete ())
76-
{
77-
location_t locus = mappings.lookup_location (receiver->get_ref ());
78-
TyTy::TyVar implicit_var
79-
= TyTy::TyVar::get_implicit_infer_var (locus);
80-
try_result = CoercionResult{{}, implicit_var.get_tyty ()};
81-
}
82-
else
83-
{
84-
bool expected_is_infer_var
85-
= expected->get_kind () == TyTy::TypeKind::INFER;
86-
bool expected_is_general_infer_var
87-
= expected_is_infer_var
88-
&& (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
89-
== TyTy::InferType::InferTypeKind::GENERAL);
90-
91-
// FIXME this 'expected_is_general_infer_var' case needs to eventually
92-
// should go away see: compile/never_type_err1.rs
93-
//
94-
// I think we need inference obligations to say that yes we have a
95-
// general inference variable but we add the oligation to the expected
96-
// type that it could default to '!'
97-
if (expected_is_general_infer_var)
98-
try_result = CoercionResult{{}, receiver};
99-
else
100-
try_result = CoercionResult{{}, expected->clone ()};
101-
}
66+
try_result = coerce_never (receiver);
10267
return true;
10368
}
10469

@@ -169,6 +134,44 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
169134
return !try_result.is_error ();
170135
}
171136

137+
TypeCoercionRules::CoercionResult
138+
TypeCoercionRules::coerce_never (TyTy::BaseType *receiver)
139+
{
140+
// handle never
141+
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
142+
143+
// Subtle: If we are coercing from `!` to `?T`, where `?T` is an unbound
144+
// type variable, we want `?T` to fallback to `!` if not
145+
// otherwise constrained. An example where this arises:
146+
//
147+
// let _: Option<?T> = Some({ return; });
148+
//
149+
// here, we would coerce from `!` to `?T`.
150+
if (expected->has_substitutions_defined () && !expected->is_concrete ())
151+
{
152+
location_t locus = mappings.lookup_location (receiver->get_ref ());
153+
TyTy::TyVar implicit_var = TyTy::TyVar::get_implicit_infer_var (locus);
154+
return CoercionResult{{}, implicit_var.get_tyty ()};
155+
}
156+
157+
bool expected_is_infer_var = expected->get_kind () == TyTy::TypeKind::INFER;
158+
bool expected_is_general_infer_var
159+
= expected_is_infer_var
160+
&& (static_cast<TyTy::InferType *> (expected)->get_infer_kind ()
161+
== TyTy::InferType::InferTypeKind::GENERAL);
162+
163+
// FIXME this 'expected_is_general_infer_var' case needs to eventually
164+
// should go away see: compile/never_type_err1.rs
165+
//
166+
// I think we need inference obligations to say that yes we have a
167+
// general inference variable but we add the oligation to the expected
168+
// type that it could default to '!'
169+
if (expected_is_general_infer_var)
170+
return CoercionResult{{}, receiver};
171+
else
172+
return CoercionResult{{}, expected->clone ()};
173+
}
174+
172175
TypeCoercionRules::CoercionResult
173176
TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
174177
TyTy::PointerType *expected,

gcc/rust/typecheck/rust-coercion.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class TypeCoercionRules : protected AutoderefCycle
5858
bool allow_autoderef,
5959
bool is_cast_site = false);
6060

61+
CoercionResult coerce_never (TyTy::BaseType *receiver);
6162
CoercionResult coerce_unsafe_ptr (TyTy::BaseType *receiver,
6263
TyTy::PointerType *expected,
6364
Mutability mutability);

0 commit comments

Comments
 (0)