Auto merge of #133559 - compiler-errors:structurally-resolve-adjust-for-branch, r=lcnr
Structurally resolve in `adjust_for_branches` r? lcnr
This commit is contained in:
commit
acf48426b6
8 changed files with 62 additions and 50 deletions
|
@ -57,7 +57,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// type in that case)
|
||||
let mut all_arms_diverge = Diverges::WarnedAlways;
|
||||
|
||||
let expected = orig_expected.adjust_for_branches(self);
|
||||
let expected =
|
||||
orig_expected.try_structurally_resolve_and_adjust_for_branches(self, expr.span);
|
||||
debug!(?expected);
|
||||
|
||||
let mut coercion = {
|
||||
|
|
|
@ -39,10 +39,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
|
|||
// an expected type. Otherwise, we might write parts of the type
|
||||
// when checking the 'then' block which are incompatible with the
|
||||
// 'else' branch.
|
||||
pub(super) fn adjust_for_branches(&self, fcx: &FnCtxt<'a, 'tcx>) -> Expectation<'tcx> {
|
||||
pub(super) fn try_structurally_resolve_and_adjust_for_branches(
|
||||
&self,
|
||||
fcx: &FnCtxt<'a, 'tcx>,
|
||||
span: Span,
|
||||
) -> Expectation<'tcx> {
|
||||
match *self {
|
||||
ExpectHasType(ety) => {
|
||||
let ety = fcx.shallow_resolve(ety);
|
||||
let ety = fcx.try_structurally_resolve_type(span, ety);
|
||||
if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
|
||||
}
|
||||
ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),
|
||||
|
|
|
@ -628,7 +628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
expr: &'tcx hir::Expr<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
|
||||
match ty.kind() {
|
||||
match self.try_structurally_resolve_type(expr.span, ty).kind() {
|
||||
ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => {
|
||||
if oprnd.is_syntactic_place_expr() {
|
||||
// Places may legitimately have unsized types.
|
||||
|
@ -1293,7 +1293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let cond_diverges = self.diverges.get();
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
||||
let expected = orig_expected.adjust_for_branches(self);
|
||||
let expected = orig_expected.try_structurally_resolve_and_adjust_for_branches(self, sp);
|
||||
let then_ty = self.check_expr_with_expectation(then_expr, expected);
|
||||
let then_diverges = self.diverges.get();
|
||||
self.diverges.set(Diverges::Maybe);
|
||||
|
@ -1354,8 +1354,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
rhs: &'tcx hir::Expr<'tcx>,
|
||||
span: Span,
|
||||
) -> Ty<'tcx> {
|
||||
let expected_ty = expected.coercion_target_type(self, expr.span);
|
||||
if expected_ty == self.tcx.types.bool {
|
||||
let expected_ty = expected.only_has_type(self);
|
||||
if expected_ty == Some(self.tcx.types.bool) {
|
||||
let guar = self.expr_assign_expected_bool_error(expr, lhs, rhs, span);
|
||||
return Ty::new_error(self.tcx, guar);
|
||||
}
|
||||
|
@ -1639,7 +1639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
let element_ty = if !args.is_empty() {
|
||||
let coerce_to = expected
|
||||
.to_option(self)
|
||||
.and_then(|uty| match *uty.kind() {
|
||||
.and_then(|uty| match *self.try_structurally_resolve_type(expr.span, uty).kind() {
|
||||
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
|
||||
_ => None,
|
||||
})
|
||||
|
|
|
@ -936,18 +936,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
// can be collated pretty easily if needed.
|
||||
|
||||
// Next special case: if there is only one "Incompatible" error, just emit that
|
||||
if let [
|
||||
if let &[
|
||||
Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(err))),
|
||||
] = &errors[..]
|
||||
{
|
||||
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
|
||||
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
|
||||
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
|
||||
let (provided_ty, provided_arg_span) = provided_arg_tys[provided_idx];
|
||||
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
|
||||
let mut err =
|
||||
self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *err);
|
||||
let mut err = self.err_ctxt().report_and_explain_type_error(trace, self.param_env, err);
|
||||
self.emit_coerce_suggestions(
|
||||
&mut err,
|
||||
provided_args[*provided_idx],
|
||||
provided_args[provided_idx],
|
||||
provided_ty,
|
||||
Expectation::rvalue_hint(self, expected_ty)
|
||||
.only_has_type(self)
|
||||
|
@ -982,7 +981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
self.suggest_ptr_null_mut(
|
||||
expected_ty,
|
||||
provided_ty,
|
||||
provided_args[*provided_idx],
|
||||
provided_args[provided_idx],
|
||||
&mut err,
|
||||
);
|
||||
|
||||
|
@ -992,7 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
call_ident,
|
||||
expected_ty,
|
||||
provided_ty,
|
||||
provided_args[*provided_idx],
|
||||
provided_args[provided_idx],
|
||||
is_method,
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue