Skip to content

Commit 0a3eb5c

Browse files
committed
Simplify code around expected argument types.
1 parent ba5a5cf commit 0a3eb5c

File tree

1 file changed

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

1 file changed

+50
-49
lines changed

src/librustc_typeck/check/mod.rs

+50-49
Original file line numberDiff line numberDiff line change
@@ -2507,7 +2507,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25072507
sp: Span,
25082508
expr_sp: Span,
25092509
fn_inputs: &[Ty<'tcx>],
2510-
expected_arg_tys: &[Ty<'tcx>],
2510+
mut expected_arg_tys: &[Ty<'tcx>],
25112511
args: &'gcx [hir::Expr],
25122512
variadic: bool,
25132513
tuple_arguments: TupleArgumentsFlag,
@@ -2528,7 +2528,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25282528
self.register_wf_obligation(fn_input_ty, sp, traits::MiscObligation);
25292529
}
25302530

2531-
let mut expected_arg_tys = expected_arg_tys;
25322531
let expected_arg_count = fn_inputs.len();
25332532

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

26192624
debug!("check_argument_types: formal_tys={:?}",
26202625
formal_tys.iter().map(|t| self.ty_to_string(*t)).collect::<Vec<String>>());
@@ -2666,28 +2671,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
26662671

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

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

26772678
// 2. Coerce to the most detailed type that could be coerced
26782679
// to, which is `expected_ty` if `rvalue_hint` returns an
26792680
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2680-
let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2681+
let coerce_ty = expected.only_has_type(self).unwrap_or(formal_ty);
26812682
// We're processing function arguments so we definitely want to use
26822683
// two-phase borrows.
2683-
self.demand_coerce(&arg,
2684-
checked_ty,
2685-
coerce_ty.unwrap_or(formal_ty),
2686-
AllowTwoPhase::Yes);
2684+
self.demand_coerce(&arg, checked_ty, coerce_ty, AllowTwoPhase::Yes);
26872685

26882686
// 3. Relate the expected type and the formal one,
26892687
// if the expected type was used for the coercion.
2690-
coerce_ty.map(|ty| self.demand_suptype(arg.span, formal_ty, ty));
2688+
self.demand_suptype(arg.span, formal_ty, coerce_ty);
26912689
}
26922690
}
26932691

@@ -2834,6 +2832,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28342832
expr: &'gcx hir::Expr,
28352833
expected: Ty<'tcx>) -> Ty<'tcx> {
28362834
let ty = self.check_expr_with_hint(expr, expected);
2835+
// checks don't need two phase
28372836
self.demand_coerce(expr, ty, expected, AllowTwoPhase::No)
28382837
}
28392838

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

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-
}).ok()
2919-
}).unwrap_or(vec![]);
2915+
// Record all the argument types, with the substitutions
2916+
// produced from the above subtyping unification.
2917+
Ok(formal_args.iter().map(|ty| {
2918+
self.resolve_type_vars_if_possible(ty)
2919+
}).collect())
2920+
}).unwrap_or(Vec::new());
29202921
debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
29212922
formal_args, formal_ret,
2922-
expected_args, expected_ret);
2923-
expected_args
2923+
expect_args, expected_ret);
2924+
expect_args
29242925
}
29252926

29262927
// Checks a method call.

0 commit comments

Comments
 (0)