Skip to content

Commit 8eda90e

Browse files
committed
remove diverging type variables from fn check
The comment seems incorrect. Testing revealed that the examples in question still work (as well as some variants) even without the special casing here.
1 parent 694d3c8 commit 8eda90e

File tree

2 files changed

+13
-25
lines changed

2 files changed

+13
-25
lines changed

compiler/rustc_infer/src/infer/type_variable.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,11 @@ pub enum TypeVariableOriginKind {
129129
SubstitutionPlaceholder,
130130
AutoDeref,
131131
AdjustmentType,
132-
DivergingFn,
132+
133+
/// In type check, when we are type checking a function that
134+
/// returns `-> dyn Foo`, we substitute a type variable for the
135+
/// return type for diagnostic purposes.
136+
DynReturnFn,
133137
LatticeVariable,
134138
}
135139

compiler/rustc_typeck/src/check/check.rs

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -218,32 +218,16 @@ pub(super) fn check_fn<'a, 'tcx>(
218218
// we saw and assigning it to the expected return type. This isn't
219219
// really expected to fail, since the coercions would have failed
220220
// earlier when trying to find a LUB.
221-
//
222-
// However, the behavior around `!` is sort of complex. In the
223-
// event that the `actual_return_ty` comes back as `!`, that
224-
// indicates that the fn either does not return or "returns" only
225-
// values of type `!`. In this case, if there is an expected
226-
// return type that is *not* `!`, that should be ok. But if the
227-
// return type is being inferred, we want to "fallback" to `!`:
228-
//
229-
// let x = move || panic!();
230-
//
231-
// To allow for that, I am creating a type variable with diverging
232-
// fallback. This was deemed ever so slightly better than unifying
233-
// the return value with `!` because it allows for the caller to
234-
// make more assumptions about the return type (e.g., they could do
235-
//
236-
// let y: Option<u32> = Some(x());
237-
//
238-
// which would then cause this return type to become `u32`, not
239-
// `!`).
240221
let coercion = fcx.ret_coercion.take().unwrap().into_inner();
241222
let mut actual_return_ty = coercion.complete(&fcx);
242-
if actual_return_ty.is_never() {
243-
actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
244-
kind: TypeVariableOriginKind::DivergingFn,
245-
span,
246-
});
223+
debug!("actual_return_ty = {:?}", actual_return_ty);
224+
if let ty::Dynamic(..) = declared_ret_ty.kind() {
225+
// We have special-cased the case where the function is declared
226+
// `-> dyn Foo` and we don't actually relate it to the
227+
// `fcx.ret_coercion`, so just substitute a type variable.
228+
actual_return_ty =
229+
fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
230+
debug!("actual_return_ty replaced with {:?}", actual_return_ty);
247231
}
248232
fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
249233

0 commit comments

Comments
 (0)