Skip to content

Commit 83a6b38

Browse files
committed
Auto merge of rust-lang#133559 - compiler-errors:structurally-resolve-adjust-for-branch, r=<try>
Structurally resolve before `adjust_for_branches` r? lcnr
2 parents a45391f + 28c13d2 commit 83a6b38

25 files changed

+220
-176
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5757
// type in that case)
5858
let mut all_arms_diverge = Diverges::WarnedAlways;
5959

60-
let expected = orig_expected.adjust_for_branches(self);
60+
let expected = orig_expected.adjust_for_branches(self, expr.span);
6161
debug!(?expected);
6262

6363
let mut coercion = {
@@ -86,7 +86,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8686
let arm_ty = self.check_expr_with_expectation(arm.body, expected);
8787
all_arms_diverge &= self.diverges.get();
8888
let tail_defines_return_position_impl_trait =
89-
self.return_position_impl_trait_from_match_expectation(orig_expected);
89+
self.return_position_impl_trait_from_match_expectation(orig_expected, expr.span);
9090

9191
let (arm_block_id, arm_span) = if let hir::ExprKind::Block(blk, _) = arm.body.kind {
9292
(Some(blk.hir_id), self.find_block_span(blk))
@@ -586,8 +586,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
586586
pub(crate) fn return_position_impl_trait_from_match_expectation(
587587
&self,
588588
expectation: Expectation<'tcx>,
589+
span: Span,
589590
) -> Option<LocalDefId> {
590-
let expected_ty = expectation.to_option(self)?;
591+
let expected_ty = expectation.structurally_resolve(self, span)?;
591592
let (def_id, args) = match *expected_ty.kind() {
592593
// FIXME: Could also check that the RPIT is not defined
593594
ty::Alias(ty::Opaque, alias_ty) => (alias_ty.def_id.as_local()?, alias_ty.args),

compiler/rustc_hir_typeck/src/callee.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
573573
// We didn't record the in scope traits during late resolution
574574
// so we need to probe AllTraits unfortunately
575575
ProbeScope::AllTraits,
576-
expected.only_has_type(self),
576+
expected.structurally_resolve_hard_expectation(self, call_expr.span),
577577
) else {
578578
return;
579579
};

compiler/rustc_hir_typeck/src/closure.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5757
// It's always helpful for inference if we know the kind of
5858
// closure sooner rather than later, so first examine the expected
5959
// type, and see if can glean a closure kind from there.
60-
let (expected_sig, expected_kind) = match expected.to_option(self) {
61-
Some(ty) => self.deduce_closure_signature(
62-
self.try_structurally_resolve_type(expr_span, ty),
63-
closure.kind,
64-
),
60+
let (expected_sig, expected_kind) = match expected.structurally_resolve(self, expr_span) {
61+
Some(ty) => self.deduce_closure_signature(ty, closure.kind),
6562
None => (None, None),
6663
};
6764

compiler/rustc_hir_typeck/src/expectation.rs

+20-24
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
3939
// an expected type. Otherwise, we might write parts of the type
4040
// when checking the 'then' block which are incompatible with the
4141
// 'else' branch.
42-
pub(super) fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
42+
pub(super) fn adjust_for_branches(
43+
&self,
44+
fcx: &FnCtxt<'a, 'tcx>,
45+
span: Span,
46+
) -> Expectation<'tcx> {
4347
match *self {
4448
ExpectHasType(ety) => {
45-
let ety = fcx.shallow_resolve(ety);
49+
let ety = fcx.try_structurally_resolve_type(span, ety);
4650
if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
4751
}
4852
ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
@@ -77,39 +81,31 @@ impl<'a, 'tcx> Expectation<'tcx> {
7781
}
7882
}
7983

80-
/// Resolves `expected` by a single level if it is a variable. If
81-
/// there is no expected type or resolution is not possible (e.g.,
82-
/// no constraints yet present), just returns `self`.
83-
fn resolve(self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
84+
pub(super) fn structurally_resolve(
85+
self,
86+
fcx: &FnCtxt<'a, 'tcx>,
87+
span: Span,
88+
) -> Option<Ty<'tcx>> {
8489
match self {
85-
NoExpectation => NoExpectation,
86-
ExpectCastableToType(t) => ExpectCastableToType(fcx.resolve_vars_if_possible(t)),
87-
ExpectHasType(t) => ExpectHasType(fcx.resolve_vars_if_possible(t)),
88-
ExpectRvalueLikeUnsized(t) => ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(t)),
89-
}
90-
}
91-
92-
pub(super) fn to_option(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
93-
match self.resolve(fcx) {
9490
NoExpectation => None,
95-
ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => Some(ty),
91+
ExpectCastableToType(ty) | ExpectHasType(ty) | ExpectRvalueLikeUnsized(ty) => {
92+
Some(fcx.try_structurally_resolve_type(span, ty))
93+
}
9694
}
9795
}
9896

9997
/// It sometimes happens that we want to turn an expectation into
10098
/// a **hard constraint** (i.e., something that must be satisfied
10199
/// for the program to type-check). `only_has_type` will return
102100
/// such a constraint, if it exists.
103-
pub(super) fn only_has_type(self, fcx: &FnCtxt<'a, 'tcx>) -> Option<Ty<'tcx>> {
101+
pub(super) fn structurally_resolve_hard_expectation(
102+
self,
103+
fcx: &FnCtxt<'a, 'tcx>,
104+
span: Span,
105+
) -> Option<Ty<'tcx>> {
104106
match self {
105-
ExpectHasType(ty) => Some(fcx.resolve_vars_if_possible(ty)),
107+
ExpectHasType(ty) => Some(fcx.try_structurally_resolve_type(span, ty)),
106108
NoExpectation | ExpectCastableToType(_) | ExpectRvalueLikeUnsized(_) => None,
107109
}
108110
}
109-
110-
/// Like `only_has_type`, but instead of returning `None` if no
111-
/// hard constraint exists, creates a fresh type variable.
112-
pub(super) fn coercion_target_type(self, fcx: &FnCtxt<'a, 'tcx>, span: Span) -> Ty<'tcx> {
113-
self.only_has_type(fcx).unwrap_or_else(|| fcx.next_ty_var(span))
114-
}
115111
}

compiler/rustc_hir_typeck/src/expr.rs

+46-38
Original file line numberDiff line numberDiff line change
@@ -628,21 +628,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628628
expected: Expectation<'tcx>,
629629
expr: &'tcx hir::Expr<'tcx>,
630630
) -> Ty<'tcx> {
631-
let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
632-
match ty.kind() {
633-
ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => {
634-
if oprnd.is_syntactic_place_expr() {
635-
// Places may legitimately have unsized types.
636-
// For example, dereferences of a wide pointer and
637-
// the last field of a struct can be unsized.
638-
ExpectHasType(*ty)
639-
} else {
640-
Expectation::rvalue_hint(self, *ty)
631+
let hint = expected.structurally_resolve_hard_expectation(self, expr.span).map_or(
632+
NoExpectation,
633+
|ty| {
634+
match ty.kind() {
635+
ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => {
636+
if oprnd.is_syntactic_place_expr() {
637+
// Places may legitimately have unsized types.
638+
// For example, dereferences of a wide pointer and
639+
// the last field of a struct can be unsized.
640+
ExpectHasType(*ty)
641+
} else {
642+
Expectation::rvalue_hint(self, *ty)
643+
}
641644
}
645+
_ => NoExpectation,
642646
}
643-
_ => NoExpectation,
644-
}
645-
});
647+
},
648+
);
646649
let ty =
647650
self.check_expr_with_expectation_and_needs(oprnd, hint, Needs::maybe_mut_place(mutbl));
648651

@@ -1294,7 +1297,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12941297
let cond_diverges = self.diverges.get();
12951298
self.diverges.set(Diverges::Maybe);
12961299

1297-
let expected = orig_expected.adjust_for_branches(self);
1300+
let expected = orig_expected.adjust_for_branches(self, sp);
12981301
let then_ty = self.check_expr_with_expectation(then_expr, expected);
12991302
let then_diverges = self.diverges.get();
13001303
self.diverges.set(Diverges::Maybe);
@@ -1305,7 +1308,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13051308
// `expected` if it represents a *hard* constraint
13061309
// (`only_has_type`); otherwise, we just go with a
13071310
// fresh type variable.
1308-
let coerce_to_ty = expected.coercion_target_type(self, sp);
1311+
let coerce_to_ty = expected
1312+
.structurally_resolve_hard_expectation(self, sp)
1313+
.unwrap_or_else(|| self.next_ty_var(sp));
13091314
let mut coerce: DynamicCoerceMany<'_> = CoerceMany::new(coerce_to_ty);
13101315

13111316
coerce.coerce(self, &self.misc(sp), then_expr, then_ty);
@@ -1315,7 +1320,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13151320
let else_diverges = self.diverges.get();
13161321

13171322
let tail_defines_return_position_impl_trait =
1318-
self.return_position_impl_trait_from_match_expectation(orig_expected);
1323+
self.return_position_impl_trait_from_match_expectation(orig_expected, sp);
13191324
let if_cause = self.if_cause(
13201325
sp,
13211326
cond_expr.span,
@@ -1355,8 +1360,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13551360
rhs: &'tcx hir::Expr<'tcx>,
13561361
span: Span,
13571362
) -> Ty<'tcx> {
1358-
let expected_ty = expected.coercion_target_type(self, expr.span);
1359-
if expected_ty == self.tcx.types.bool {
1363+
let expected_ty = expected.structurally_resolve_hard_expectation(self, expr.span);
1364+
if expected_ty == Some(self.tcx.types.bool) {
13601365
let guar = self.expr_assign_expected_bool_error(expr, lhs, rhs, span);
13611366
return Ty::new_error(self.tcx, guar);
13621367
}
@@ -1522,7 +1527,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
15221527
let coerce = match source {
15231528
// you can only use break with a value from a normal `loop { }`
15241529
hir::LoopSource::Loop => {
1525-
let coerce_to = expected.coercion_target_type(self, body.span);
1530+
let coerce_to = expected
1531+
.structurally_resolve_hard_expectation(self, body.span)
1532+
.unwrap_or_else(|| self.next_ty_var(body.span));
15261533
Some(CoerceMany::new(coerce_to))
15271534
}
15281535

@@ -1639,7 +1646,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16391646
) -> Ty<'tcx> {
16401647
let element_ty = if !args.is_empty() {
16411648
let coerce_to = expected
1642-
.to_option(self)
1649+
.structurally_resolve(self, expr.span)
16431650
.and_then(|uty| match *uty.kind() {
16441651
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
16451652
_ => None,
@@ -1824,13 +1831,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
18241831
expected: Expectation<'tcx>,
18251832
expr: &'tcx hir::Expr<'tcx>,
18261833
) -> Ty<'tcx> {
1827-
let flds = expected.only_has_type(self).and_then(|ty| {
1828-
let ty = self.try_structurally_resolve_type(expr.span, ty);
1829-
match ty.kind() {
1834+
let flds =
1835+
expected.structurally_resolve_hard_expectation(self, expr.span).and_then(|ty| match ty
1836+
.kind()
1837+
{
18301838
ty::Tuple(flds) => Some(&flds[..]),
18311839
_ => None,
1832-
}
1833-
});
1840+
});
18341841

18351842
let elt_ts_iter = elts.iter().enumerate().map(|(i, e)| match flds {
18361843
Some(fs) if i < fs.len() => {
@@ -1904,17 +1911,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19041911
let tcx = self.tcx;
19051912

19061913
let adt_ty = self.try_structurally_resolve_type(span, adt_ty);
1907-
let adt_ty_hint = expected.only_has_type(self).and_then(|expected| {
1908-
self.fudge_inference_if_ok(|| {
1909-
let ocx = ObligationCtxt::new(self);
1910-
ocx.sup(&self.misc(span), self.param_env, expected, adt_ty)?;
1911-
if !ocx.select_where_possible().is_empty() {
1912-
return Err(TypeError::Mismatch);
1913-
}
1914-
Ok(self.resolve_vars_if_possible(adt_ty))
1915-
})
1916-
.ok()
1917-
});
1914+
let adt_ty_hint =
1915+
expected.structurally_resolve_hard_expectation(self, expr.span).and_then(|expected| {
1916+
self.fudge_inference_if_ok(|| {
1917+
let ocx = ObligationCtxt::new(self);
1918+
ocx.sup(&self.misc(span), self.param_env, expected, adt_ty)?;
1919+
if !ocx.select_where_possible().is_empty() {
1920+
return Err(TypeError::Mismatch);
1921+
}
1922+
Ok(self.resolve_vars_if_possible(adt_ty))
1923+
})
1924+
.ok()
1925+
});
19181926
if let Some(adt_ty_hint) = adt_ty_hint {
19191927
// re-link the variables that the fudging above can create.
19201928
self.demand_eqtype(span, adt_ty_hint, adt_ty);
@@ -2682,7 +2690,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26822690
base_ty,
26832691
field,
26842692
did,
2685-
expected.only_has_type(self),
2693+
expected.structurally_resolve_hard_expectation(self, expr.span),
26862694
);
26872695
return Ty::new_error(self.tcx(), guar);
26882696
}
@@ -2693,7 +2701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
26932701
field,
26942702
base_ty,
26952703
expr.hir_id,
2696-
expected.only_has_type(self),
2704+
expected.structurally_resolve_hard_expectation(self, expr.span),
26972705
) {
26982706
self.ban_take_value_of_method(expr, base_ty, field)
26992707
} else if !base_ty.is_primitive_ty() {

0 commit comments

Comments
 (0)