@@ -61,44 +61,9 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
61
61
// see:
62
62
// https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs
63
63
64
- // handle never
65
- // https://github.com/rust-lang/rust/blob/7eac88abb2e57e752f3302f02be5f3ce3d7adfb4/compiler/rustc_typeck/src/check/coercion.rs#L155
66
64
if (receiver->get_kind () == TyTy::TypeKind::NEVER)
67
65
{
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);
102
67
return true ;
103
68
}
104
69
@@ -169,6 +134,44 @@ TypeCoercionRules::do_coercion (TyTy::BaseType *receiver)
169
134
return !try_result.is_error ();
170
135
}
171
136
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
+
172
175
TypeCoercionRules::CoercionResult
173
176
TypeCoercionRules::coerce_unsafe_ptr (TyTy::BaseType *receiver,
174
177
TyTy::PointerType *expected,
0 commit comments