Skip to content

Commit 6511ef3

Browse files
committed
Simplify code around expected argument types.
1 parent be25e78 commit 6511ef3

File tree

1 file changed

+49
-46
lines changed
  • src/librustc_typeck/check

1 file changed

+49
-46
lines changed

src/librustc_typeck/check/mod.rs

+49-46
Original file line numberDiff line numberDiff line change
@@ -2508,7 +2508,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25082508
sp: Span,
25092509
expr_sp: Span,
25102510
fn_inputs: &[Ty<'tcx>],
2511-
expected_arg_tys: &[Ty<'tcx>],
2511+
mut expected_arg_tys: &[Ty<'tcx>],
25122512
args: &'gcx [hir::Expr],
25132513
variadic: bool,
25142514
tuple_arguments: TupleArgumentsFlag,
@@ -2529,7 +2529,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25292529
self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
25302530
}
25312531

2532-
let mut expected_arg_tys = expected_arg_tys;
25332532
let expected_arg_count = fn_inputs.len();
25342533

25352534
let param_count_error = |expected_count: usize,
@@ -2616,6 +2615,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26162615
expected_arg_tys = &[];
26172616
self.err_args(supplied_arg_count)
26182617
};
2618+
// If there is no expectation, expect formal_tys.
2619+
let expected_arg_tys = if !expected_arg_tys.is_empty() {
2620+
expected_arg_tys
2621+
} else {
2622+
&formal_tys
2623+
};
26192624

26202625
debug!("check_argument_types: formal_tys={:?}",
26212626
formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
@@ -2667,23 +2672,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26672672

26682673
// The special-cased logic below has three functions:
26692674
// 1. Provide as good of an expected type as possible.
2670-
let expected = expected_arg_tys.get(i).map(|&ty| {
2671-
Expectation::rvalue_hint(self, ty)
2672-
});
2675+
let expected = Expectation::rvalue_hint(self, expected_arg_tys[i]);
26732676

2674-
let checked_ty = self.check_expr_with_expectation(
2675-
&arg,
2676-
expected.unwrap_or(ExpectHasType(formal_ty)));
2677+
let checked_ty = self.check_expr_with_expectation(&arg, expected);
26772678

26782679
// 2. Coerce to the most detailed type that could be coerced
26792680
// to, which is `expected_ty` if `rvalue_hint` returns an
26802681
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2681-
let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2682-
self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
2682+
let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
2683+
self.demand_coerce(&arg, checked_ty, coerce_ty);
26832684

26842685
// 3. Relate the expected type and the formal one,
26852686
// if the expected type was used for the coercion.
2686-
coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2687+
self.demand_suptype(arg.span, formal_ty, coerce_ty);
26872688
}
26882689
}
26892690

@@ -2878,45 +2879,47 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28782879
formal_args: &[Ty<'tcx>])
28792880
-> Vec<Ty<'tcx>> {
28802881
let formal_ret = self.resolve_type_vars_with_obligations(formal_ret);
2881-
let expected_args = expected_ret.only_has_type(self).and_then(|ret_ty| {
2882-
self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2883-
// Attempt to apply a subtyping relationship between the formal
2884-
// return type (likely containing type variables if the function
2885-
// is polymorphic) and the expected return type.
2886-
// No argument expectations are produced if unification fails.
2887-
let origin = self.misc(call_span);
2888-
let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
2889-
2890-
// FIXME(#27336) can't use ? here, Try::from_error doesn't default
2891-
// to identity so the resulting type is not constrained.
2892-
match ures {
2893-
Ok(ok) => {
2894-
// Process any obligations locally as much as
2895-
// we can. We don't care if some things turn
2896-
// out unconstrained or ambiguous, as we're
2897-
// just trying to get hints here.
2898-
self.save_and_restore_in_snapshot_flag(|_| {
2899-
let mut fulfill = TraitEngine::new(self.tcx);
2900-
for obligation in ok.obligations {
2901-
fulfill.register_predicate_obligation(self, obligation);
2902-
}
2903-
fulfill.select_where_possible(self)
2904-
}).map_err(|_| ())?;
2905-
}
2906-
Err(_) => return Err(()),
2882+
let ret_ty = match expected_ret.only_has_type(self) {
2883+
Some(ret) => ret,
2884+
None => return Vec::new()
2885+
};
2886+
let expect_args = self.fudge_regions_if_ok(&RegionVariableOrigin::Coercion(call_span), || {
2887+
// Attempt to apply a subtyping relationship between the formal
2888+
// return type (likely containing type variables if the function
2889+
// is polymorphic) and the expected return type.
2890+
// No argument expectations are produced if unification fails.
2891+
let origin = self.misc(call_span);
2892+
let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
2893+
2894+
// FIXME(#27336) can't use ? here, Try::from_error doesn't default
2895+
// to identity so the resulting type is not constrained.
2896+
match ures {
2897+
Ok(ok) => {
2898+
// Process any obligations locally as much as
2899+
// we can. We don't care if some things turn
2900+
// out unconstrained or ambiguous, as we're
2901+
// just trying to get hints here.
2902+
self.save_and_restore_in_snapshot_flag(|_| {
2903+
let mut fulfill = TraitEngine::new(self.tcx);
2904+
for obligation in ok.obligations {
2905+
fulfill.register_predicate_obligation(self, obligation);
2906+
}
2907+
fulfill.select_where_possible(self)
2908+
}).map_err(|_| ())?;
29072909
}
2910+
Err(_) => return Err(()),
2911+
}
29082912

2909-
// Record all the argument types, with the substitutions
2910-
// produced from the above subtyping unification.
2911-
Ok(formal_args.iter().map(|ty| {
2912-
self.resolve_type_vars_if_possible(ty)
2913-
}).collect())
2914-
}).ok()
2915-
}).unwrap_or(vec![]);
2913+
// Record all the argument types, with the substitutions
2914+
// produced from the above subtyping unification.
2915+
Ok(formal_args.iter().map(|ty| {
2916+
self.resolve_type_vars_if_possible(ty)
2917+
}).collect())
2918+
}).unwrap_or(Vec::new());
29162919
debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
29172920
formal_args, formal_ret,
2918-
expected_args, expected_ret);
2919-
expected_args
2921+
expect_args, expected_ret);
2922+
expect_args
29202923
}
29212924

29222925
// Checks a method call.

0 commit comments

Comments
 (0)