Skip to content

Commit ebb8ff9

Browse files
nikomatsakisMark-Simulacrum
authored andcommitted
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 2ee8914 commit ebb8ff9

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
@@ -241,32 +241,16 @@ pub(super) fn check_fn<'a, 'tcx>(
241241
// we saw and assigning it to the expected return type. This isn't
242242
// really expected to fail, since the coercions would have failed
243243
// earlier when trying to find a LUB.
244-
//
245-
// However, the behavior around `!` is sort of complex. In the
246-
// event that the `actual_return_ty` comes back as `!`, that
247-
// indicates that the fn either does not return or "returns" only
248-
// values of type `!`. In this case, if there is an expected
249-
// return type that is *not* `!`, that should be ok. But if the
250-
// return type is being inferred, we want to "fallback" to `!`:
251-
//
252-
// let x = move || panic!();
253-
//
254-
// To allow for that, I am creating a type variable with diverging
255-
// fallback. This was deemed ever so slightly better than unifying
256-
// the return value with `!` because it allows for the caller to
257-
// make more assumptions about the return type (e.g., they could do
258-
//
259-
// let y: Option<u32> = Some(x());
260-
//
261-
// which would then cause this return type to become `u32`, not
262-
// `!`).
263244
let coercion = fcx.ret_coercion.take().unwrap().into_inner();
264245
let mut actual_return_ty = coercion.complete(&fcx);
265-
if actual_return_ty.is_never() {
266-
actual_return_ty = fcx.next_diverging_ty_var(TypeVariableOrigin {
267-
kind: TypeVariableOriginKind::DivergingFn,
268-
span,
269-
});
246+
debug!("actual_return_ty = {:?}", actual_return_ty);
247+
if let ty::Dynamic(..) = declared_ret_ty.kind() {
248+
// We have special-cased the case where the function is declared
249+
// `-> dyn Foo` and we don't actually relate it to the
250+
// `fcx.ret_coercion`, so just substitute a type variable.
251+
actual_return_ty =
252+
fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
253+
debug!("actual_return_ty replaced with {:?}", actual_return_ty);
270254
}
271255
fcx.demand_suptype(span, revealed_ret_ty, actual_return_ty);
272256

0 commit comments

Comments
 (0)