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:
bors 2024-12-06 04:55:35 +00:00
commit acf48426b6
8 changed files with 62 additions and 50 deletions

View File

@ -57,7 +57,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// type in that case) // type in that case)
let mut all_arms_diverge = Diverges::WarnedAlways; 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); debug!(?expected);
let mut coercion = { let mut coercion = {

View File

@ -39,10 +39,14 @@ impl<'a, 'tcx> Expectation<'tcx> {
// an expected type. Otherwise, we might write parts of the type // an expected type. Otherwise, we might write parts of the type
// when checking the 'then' block which are incompatible with the // when checking the 'then' block which are incompatible with the
// 'else' branch. // '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 { match *self {
ExpectHasType(ety) => { 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 } if !ety.is_ty_var() { ExpectHasType(ety) } else { NoExpectation }
} }
ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety), ExpectRvalueLikeUnsized(ety) => ExpectRvalueLikeUnsized(ety),

View File

@ -628,7 +628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { 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, _) => { ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => {
if oprnd.is_syntactic_place_expr() { if oprnd.is_syntactic_place_expr() {
// Places may legitimately have unsized types. // Places may legitimately have unsized types.
@ -1293,7 +1293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let cond_diverges = self.diverges.get(); let cond_diverges = self.diverges.get();
self.diverges.set(Diverges::Maybe); 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_ty = self.check_expr_with_expectation(then_expr, expected);
let then_diverges = self.diverges.get(); let then_diverges = self.diverges.get();
self.diverges.set(Diverges::Maybe); self.diverges.set(Diverges::Maybe);
@ -1354,8 +1354,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs: &'tcx hir::Expr<'tcx>, rhs: &'tcx hir::Expr<'tcx>,
span: Span, span: Span,
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let expected_ty = expected.coercion_target_type(self, expr.span); let expected_ty = expected.only_has_type(self);
if expected_ty == self.tcx.types.bool { if expected_ty == Some(self.tcx.types.bool) {
let guar = self.expr_assign_expected_bool_error(expr, lhs, rhs, span); let guar = self.expr_assign_expected_bool_error(expr, lhs, rhs, span);
return Ty::new_error(self.tcx, guar); 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 element_ty = if !args.is_empty() {
let coerce_to = expected let coerce_to = expected
.to_option(self) .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), ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
_ => None, _ => None,
}) })

View File

@ -936,18 +936,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// can be collated pretty easily if needed. // can be collated pretty easily if needed.
// Next special case: if there is only one "Incompatible" error, just emit that // 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))), Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(err))),
] = &errors[..] ] = &errors[..]
{ {
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx]; let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_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 trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
let mut err = let mut err = self.err_ctxt().report_and_explain_type_error(trace, self.param_env, err);
self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *err);
self.emit_coerce_suggestions( self.emit_coerce_suggestions(
&mut err, &mut err,
provided_args[*provided_idx], provided_args[provided_idx],
provided_ty, provided_ty,
Expectation::rvalue_hint(self, expected_ty) Expectation::rvalue_hint(self, expected_ty)
.only_has_type(self) .only_has_type(self)
@ -982,7 +981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.suggest_ptr_null_mut( self.suggest_ptr_null_mut(
expected_ty, expected_ty,
provided_ty, provided_ty,
provided_args[*provided_idx], provided_args[provided_idx],
&mut err, &mut err,
); );
@ -992,7 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
call_ident, call_ident,
expected_ty, expected_ty,
provided_ty, provided_ty,
provided_args[*provided_idx], provided_args[provided_idx],
is_method, is_method,
); );

View File

@ -1,22 +1,9 @@
error[E0283]: type annotations needed error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
--> $DIR/auto-trait-selection-freeze.rs:19:16 --> $DIR/auto-trait-selection-freeze.rs:19:5
| |
LL | if false { is_trait(foo()) } else { Default::default() } LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ ----- type must be known at this point | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
| |
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
= note: cannot satisfy `_: Trait<_>`
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection-freeze.rs:11:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
| ++++++++
error: aborting due to 1 previous error error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`. For more information about this error, try `rustc --explain E0284`.

View File

@ -1,22 +1,9 @@
error[E0283]: type annotations needed error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
--> $DIR/auto-trait-selection.rs:15:16 --> $DIR/auto-trait-selection.rs:15:5
| |
LL | if false { is_trait(foo()) } else { Default::default() } LL | if false { is_trait(foo()) } else { Default::default() }
| ^^^^^^^^ ----- type must be known at this point | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
| |
| cannot infer type of the type parameter `T` declared on the function `is_trait`
|
= note: cannot satisfy `_: Trait<_>`
note: required by a bound in `is_trait`
--> $DIR/auto-trait-selection.rs:7:16
|
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
| ^^^^^^^^ required by this bound in `is_trait`
help: consider specifying the generic arguments
|
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
| ++++++++
error: aborting due to 1 previous error error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`. For more information about this error, try `rustc --explain E0284`.

View File

@ -0,0 +1,26 @@
//@ check-pass
//@ compile-flags: -Znext-solver
trait Mirror {
type Assoc;
}
impl<T> Mirror for T {
type Assoc = T;
}
fn id<T>(t: T) -> T { t }
trait Foo {}
impl Foo for i32 {}
impl Foo for u32 {}
fn main() {
// Make sure we resolve expected pointee of addr-of.
id::<<&&dyn Foo as Mirror>::Assoc>(&id(&1));
// Make sure we resolve expected element of array.
id::<<[Box<dyn Foo>; 2] as Mirror>::Assoc>([Box::new(1i32), Box::new(1u32)]);
// Make sure we resolve expected element of tuple.
id::<<(Box<dyn Foo>,) as Mirror>::Assoc>((Box::new(1i32),));
}

View File

@ -0,0 +1,8 @@
//@ compile-flags: -Znext-solver
//@ check-pass
pub fn repro() -> impl FnMut() {
if true { || () } else { || () }
}
fn main() {}