Skip to content

Commit 180534f

Browse files
committed
Remove use of expr_ty from coercions code
1 parent bd66148 commit 180534f

File tree

5 files changed

+37
-26
lines changed

5 files changed

+37
-26
lines changed

src/librustc_typeck/check/_match.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -419,11 +419,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
419419
}
420420
_ => result_ty
421421
};
422+
423+
let mut arm_tys = Vec::new();
422424
for (i, arm) in arms.iter().enumerate() {
423425
if let Some(ref e) = arm.guard {
424426
self.check_expr_has_type(e, tcx.types.bool);
425427
}
426428
let arm_ty = self.check_expr_with_expectation(&arm.body, expected);
429+
arm_tys.push(arm_ty);
427430

428431
if result_ty.references_error() || arm_ty.references_error() {
429432
result_ty = tcx.types.err;
@@ -453,10 +456,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
453456
})
454457
} else if i == 0 {
455458
// Special-case the first arm, as it has no "previous expressions".
456-
self.try_coerce(&arm.body, coerce_first)
459+
self.try_coerce(&arm.body, arm_ty, coerce_first)
457460
} else {
458-
let prev_arms = || arms[..i].iter().map(|arm| &*arm.body);
459-
self.try_find_coercion_lub(origin, prev_arms, result_ty, &arm.body)
461+
let prev_arms = || arms[..i].iter().map(|arm| &*arm.body)
462+
.zip(arm_tys.iter().cloned());
463+
self.try_find_coercion_lub(origin, prev_arms, result_ty, &arm.body, arm_ty)
460464
};
461465

462466
result_ty = match result {

src/librustc_typeck/check/cast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
321321
(None, Some(t_cast)) => {
322322
if let ty::TyFnDef(.., f) = self.expr_ty.sty {
323323
// Attempt a coercion to a fn pointer type.
324-
let res = fcx.try_coerce(self.expr, fcx.tcx.mk_fn_ptr(f));
324+
let res = fcx.try_coerce(self.expr, self.expr_ty, fcx.tcx.mk_fn_ptr(f));
325325
if !res.is_ok() {
326326
return Err(CastError::NonScalar);
327327
}
@@ -471,7 +471,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
471471
}
472472

473473
fn try_coercion_cast(&self, fcx: &FnCtxt<'a, 'gcx, 'tcx>) -> bool {
474-
fcx.try_coerce(self.expr, self.cast_ty).is_ok()
474+
fcx.try_coerce(self.expr, self.expr_ty, self.cast_ty).is_ok()
475475
}
476476

477477
}

src/librustc_typeck/check/coercion.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -630,9 +630,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
630630
/// The expressions *must not* have any pre-existing adjustments.
631631
pub fn try_coerce(&self,
632632
expr: &hir::Expr,
633+
expr_ty: Ty<'tcx>,
633634
target: Ty<'tcx>)
634635
-> RelateResult<'tcx, Ty<'tcx>> {
635-
let source = self.resolve_type_vars_with_obligations(self.expr_ty(expr));
636+
let source = self.resolve_type_vars_with_obligations(expr_ty);
636637
debug!("coercion::try({:?}: {:?} -> {:?})", expr, source, target);
637638

638639
let mut coerce = Coerce::new(self, TypeOrigin::ExprAssignable(expr.span));
@@ -658,14 +659,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
658659
origin: TypeOrigin,
659660
exprs: E,
660661
prev_ty: Ty<'tcx>,
661-
new: &'b hir::Expr)
662+
new: &'b hir::Expr,
663+
new_ty: Ty<'tcx>)
662664
-> RelateResult<'tcx, Ty<'tcx>>
663665
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
664666
where E: Fn() -> I,
665-
I: IntoIterator<Item=&'b hir::Expr> {
667+
I: IntoIterator<Item=(&'b hir::Expr, Ty<'tcx>)> {
666668

667669
let prev_ty = self.resolve_type_vars_with_obligations(prev_ty);
668-
let new_ty = self.resolve_type_vars_with_obligations(self.expr_ty(new));
670+
let new_ty = self.resolve_type_vars_with_obligations(new_ty);
669671
debug!("coercion::try_find_lub({:?}, {:?})", prev_ty, new_ty);
670672

671673
let trace = TypeTrace::types(origin, true, prev_ty, new_ty);
@@ -701,7 +703,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
701703
}
702704

703705
// Reify both sides and return the reified fn pointer type.
704-
for expr in exprs().into_iter().chain(Some(new)) {
706+
for (expr, _) in exprs().into_iter().chain(Some((new, new_ty))) {
705707
// No adjustments can produce a fn item, so this should never trip.
706708
assert!(!self.tables.borrow().adjustments.contains_key(&expr.id));
707709
self.write_adjustment(expr.id, AdjustReifyFnPointer);
@@ -735,13 +737,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
735737
// Then try to coerce the previous expressions to the type of the new one.
736738
// This requires ensuring there are no coercions applied to *any* of the
737739
// previous expressions, other than noop reborrows (ignoring lifetimes).
738-
for expr in exprs() {
740+
for (expr, expr_ty) in exprs() {
739741
let noop = match self.tables.borrow().adjustments.get(&expr.id) {
740742
Some(&AdjustDerefRef(AutoDerefRef {
741743
autoderefs: 1,
742744
autoref: Some(AutoPtr(_, mutbl_adj)),
743745
unsize: None
744-
})) => match self.expr_ty(expr).sty {
746+
})) => match expr_ty.sty {
745747
ty::TyRef(_, mt_orig) => {
746748
// Reborrow that we can safely ignore.
747749
mutbl_adj == mt_orig.mutbl
@@ -765,7 +767,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
765767
}
766768
}
767769

768-
match self.commit_if_ok(|_| apply(&mut coerce, &exprs, prev_ty, new_ty)) {
770+
match self.commit_if_ok(|_| apply(&mut coerce,
771+
&|| exprs().into_iter().map(|(e, _)| e),
772+
prev_ty, new_ty)) {
769773
Err(_) => {
770774
// Avoid giving strange errors on failed attempts.
771775
if let Some(e) = first_error {
@@ -783,7 +787,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
783787
}
784788
Ok((ty, adjustment)) => {
785789
if !adjustment.is_identity() {
786-
for expr in exprs() {
790+
for (expr, _) in exprs() {
787791
let previous = self.tables.borrow().adjustments.get(&expr.id).cloned();
788792
if let Some(AdjustNeverToAny(_)) = previous {
789793
self.write_adjustment(expr.id, AdjustNeverToAny(ty));

src/librustc_typeck/check/demand.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5353
}
5454

5555
// Checks that the type of `expr` can be coerced to `expected`.
56-
pub fn demand_coerce(&self, expr: &hir::Expr, expected: Ty<'tcx>) {
56+
pub fn demand_coerce(&self, expr: &hir::Expr, checked_ty: Ty<'tcx>, expected: Ty<'tcx>) {
5757
let expected = self.resolve_type_vars_with_obligations(expected);
58-
if let Err(e) = self.try_coerce(expr, expected) {
58+
if let Err(e) = self.try_coerce(expr, checked_ty, expected) {
5959
let origin = TypeOrigin::Misc(expr.span);
60-
let expr_ty = self.resolve_type_vars_with_obligations(self.expr_ty(expr));
60+
let expr_ty = self.resolve_type_vars_with_obligations(checked_ty);
6161
self.report_mismatched_types(origin, expected, expr_ty, e);
6262
}
6363
}

src/librustc_typeck/check/mod.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2567,13 +2567,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
25672567
Expectation::rvalue_hint(self, ty)
25682568
});
25692569

2570-
self.check_expr_with_expectation(&arg,
2571-
expected.unwrap_or(ExpectHasType(formal_ty)));
2570+
let checked_ty = self.check_expr_with_expectation(&arg,
2571+
expected.unwrap_or(ExpectHasType(formal_ty)));
25722572
// 2. Coerce to the most detailed type that could be coerced
25732573
// to, which is `expected_ty` if `rvalue_hint` returns an
25742574
// `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
25752575
let coerce_ty = expected.and_then(|e| e.only_has_type(self));
2576-
self.demand_coerce(&arg, coerce_ty.unwrap_or(formal_ty));
2576+
self.demand_coerce(&arg, checked_ty, coerce_ty.unwrap_or(formal_ty));
25772577

25782578
// 3. Relate the expected type and the formal one,
25792579
// if the expected type was used for the coercion.
@@ -2715,7 +2715,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
27152715
expr: &'gcx hir::Expr,
27162716
expected: Ty<'tcx>) -> Ty<'tcx> {
27172717
let ty = self.check_expr_with_hint(expr, expected);
2718-
self.demand_coerce(expr, expected);
2718+
self.demand_coerce(expr, ty, expected);
27192719
ty
27202720
}
27212721

@@ -2861,8 +2861,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
28612861
// Only try to coerce-unify if we have a then expression
28622862
// to assign coercions to, otherwise it's () or diverging.
28632863
let result = if let Some(ref then) = then_blk.expr {
2864-
let res = self.try_find_coercion_lub(origin, || Some(&**then),
2865-
then_ty, else_expr);
2864+
let res = self.try_find_coercion_lub(origin, || Some((&**then, then_ty)),
2865+
then_ty, else_expr, else_ty);
28662866

28672867
// In case we did perform an adjustment, we have to update
28682868
// the type of the block, because old trans still uses it.
@@ -3594,16 +3594,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
35943594
let mut unified = self.next_ty_var();
35953595
let coerce_to = uty.unwrap_or(unified);
35963596

3597+
let mut arg_tys = Vec::new();
35973598
for (i, e) in args.iter().enumerate() {
35983599
let e_ty = self.check_expr_with_hint(e, coerce_to);
3600+
arg_tys.push(e_ty);
35993601
let origin = TypeOrigin::Misc(e.span);
36003602

36013603
// Special-case the first element, as it has no "previous expressions".
36023604
let result = if i == 0 {
3603-
self.try_coerce(e, coerce_to)
3605+
self.try_coerce(e, e_ty, coerce_to)
36043606
} else {
3605-
let prev_elems = || args[..i].iter().map(|e| &**e);
3606-
self.try_find_coercion_lub(origin, prev_elems, unified, e)
3607+
let prev_elems = || args[..i].iter().map(|e| &**e)
3608+
.zip(arg_tys.iter().cloned());
3609+
self.try_find_coercion_lub(origin, prev_elems, unified, e, e_ty)
36073610
};
36083611

36093612
match result {

0 commit comments

Comments
 (0)