Skip to content

Commit acf4842

Browse files
committed
Auto merge of #133559 - compiler-errors:structurally-resolve-adjust-for-branch, r=lcnr
Structurally resolve in `adjust_for_branches` r? lcnr
2 parents 706141b + 0cf9370 commit acf4842

File tree

8 files changed

+62
-50
lines changed

8 files changed

+62
-50
lines changed

compiler/rustc_hir_typeck/src/_match.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ 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 =
61+
orig_expected.try_structurally_resolve_and_adjust_for_branches(self, expr.span);
6162
debug!(?expected);
6263

6364
let mut coercion = {

compiler/rustc_hir_typeck/src/expectation.rs

+6-2
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 try_structurally_resolve_and_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),

compiler/rustc_hir_typeck/src/expr.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
628628
expr: &'tcx hir::Expr<'tcx>,
629629
) -> Ty<'tcx> {
630630
let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
631-
match ty.kind() {
631+
match self.try_structurally_resolve_type(expr.span, ty).kind() {
632632
ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => {
633633
if oprnd.is_syntactic_place_expr() {
634634
// Places may legitimately have unsized types.
@@ -1293,7 +1293,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12931293
let cond_diverges = self.diverges.get();
12941294
self.diverges.set(Diverges::Maybe);
12951295

1296-
let expected = orig_expected.adjust_for_branches(self);
1296+
let expected = orig_expected.try_structurally_resolve_and_adjust_for_branches(self, sp);
12971297
let then_ty = self.check_expr_with_expectation(then_expr, expected);
12981298
let then_diverges = self.diverges.get();
12991299
self.diverges.set(Diverges::Maybe);
@@ -1354,8 +1354,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
13541354
rhs: &'tcx hir::Expr<'tcx>,
13551355
span: Span,
13561356
) -> Ty<'tcx> {
1357-
let expected_ty = expected.coercion_target_type(self, expr.span);
1358-
if expected_ty == self.tcx.types.bool {
1357+
let expected_ty = expected.only_has_type(self);
1358+
if expected_ty == Some(self.tcx.types.bool) {
13591359
let guar = self.expr_assign_expected_bool_error(expr, lhs, rhs, span);
13601360
return Ty::new_error(self.tcx, guar);
13611361
}
@@ -1639,7 +1639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16391639
let element_ty = if !args.is_empty() {
16401640
let coerce_to = expected
16411641
.to_option(self)
1642-
.and_then(|uty| match *uty.kind() {
1642+
.and_then(|uty| match *self.try_structurally_resolve_type(expr.span, uty).kind() {
16431643
ty::Array(ty, _) | ty::Slice(ty) => Some(ty),
16441644
_ => None,
16451645
})

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -936,18 +936,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
936936
// can be collated pretty easily if needed.
937937

938938
// Next special case: if there is only one "Incompatible" error, just emit that
939-
if let [
939+
if let &[
940940
Error::Invalid(provided_idx, expected_idx, Compatibility::Incompatible(Some(err))),
941941
] = &errors[..]
942942
{
943-
let (formal_ty, expected_ty) = formal_and_expected_inputs[*expected_idx];
944-
let (provided_ty, provided_arg_span) = provided_arg_tys[*provided_idx];
943+
let (formal_ty, expected_ty) = formal_and_expected_inputs[expected_idx];
944+
let (provided_ty, provided_arg_span) = provided_arg_tys[provided_idx];
945945
let trace = mk_trace(provided_arg_span, (formal_ty, expected_ty), provided_ty);
946-
let mut err =
947-
self.err_ctxt().report_and_explain_type_error(trace, self.param_env, *err);
946+
let mut err = self.err_ctxt().report_and_explain_type_error(trace, self.param_env, err);
948947
self.emit_coerce_suggestions(
949948
&mut err,
950-
provided_args[*provided_idx],
949+
provided_args[provided_idx],
951950
provided_ty,
952951
Expectation::rvalue_hint(self, expected_ty)
953952
.only_has_type(self)
@@ -982,7 +981,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
982981
self.suggest_ptr_null_mut(
983982
expected_ty,
984983
provided_ty,
985-
provided_args[*provided_idx],
984+
provided_args[provided_idx],
986985
&mut err,
987986
);
988987

@@ -992,7 +991,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
992991
call_ident,
993992
expected_ty,
994993
provided_ty,
995-
provided_args[*provided_idx],
994+
provided_args[provided_idx],
996995
is_method,
997996
);
998997

Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
1-
error[E0283]: type annotations needed
2-
--> $DIR/auto-trait-selection-freeze.rs:19:16
1+
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
2+
--> $DIR/auto-trait-selection-freeze.rs:19:5
33
|
44
LL | if false { is_trait(foo()) } else { Default::default() }
5-
| ^^^^^^^^ ----- type must be known at this point
6-
| |
7-
| cannot infer type of the type parameter `T` declared on the function `is_trait`
8-
|
9-
= note: cannot satisfy `_: Trait<_>`
10-
note: required by a bound in `is_trait`
11-
--> $DIR/auto-trait-selection-freeze.rs:11:16
12-
|
13-
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
14-
| ^^^^^^^^ required by this bound in `is_trait`
15-
help: consider specifying the generic arguments
16-
|
17-
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
18-
| ++++++++
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
196

207
error: aborting due to 1 previous error
218

22-
For more information about this error, try `rustc --explain E0283`.
9+
For more information about this error, try `rustc --explain E0284`.
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
1-
error[E0283]: type annotations needed
2-
--> $DIR/auto-trait-selection.rs:15:16
1+
error[E0284]: type annotations needed: cannot satisfy `impl Sized == _`
2+
--> $DIR/auto-trait-selection.rs:15:5
33
|
44
LL | if false { is_trait(foo()) } else { Default::default() }
5-
| ^^^^^^^^ ----- type must be known at this point
6-
| |
7-
| cannot infer type of the type parameter `T` declared on the function `is_trait`
8-
|
9-
= note: cannot satisfy `_: Trait<_>`
10-
note: required by a bound in `is_trait`
11-
--> $DIR/auto-trait-selection.rs:7:16
12-
|
13-
LL | fn is_trait<T: Trait<U>, U: Default>(_: T) -> U {
14-
| ^^^^^^^^ required by this bound in `is_trait`
15-
help: consider specifying the generic arguments
16-
|
17-
LL | if false { is_trait::<T, U>(foo()) } else { Default::default() }
18-
| ++++++++
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `impl Sized == _`
196

207
error: aborting due to 1 previous error
218

22-
For more information about this error, try `rustc --explain E0283`.
9+
For more information about this error, try `rustc --explain E0284`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ check-pass
2+
//@ compile-flags: -Znext-solver
3+
4+
trait Mirror {
5+
type Assoc;
6+
}
7+
impl<T> Mirror for T {
8+
type Assoc = T;
9+
}
10+
11+
fn id<T>(t: T) -> T { t }
12+
13+
trait Foo {}
14+
impl Foo for i32 {}
15+
impl Foo for u32 {}
16+
17+
fn main() {
18+
// Make sure we resolve expected pointee of addr-of.
19+
id::<<&&dyn Foo as Mirror>::Assoc>(&id(&1));
20+
21+
// Make sure we resolve expected element of array.
22+
id::<<[Box<dyn Foo>; 2] as Mirror>::Assoc>([Box::new(1i32), Box::new(1u32)]);
23+
24+
// Make sure we resolve expected element of tuple.
25+
id::<<(Box<dyn Foo>,) as Mirror>::Assoc>((Box::new(1i32),));
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
pub fn repro() -> impl FnMut() {
5+
if true { || () } else { || () }
6+
}
7+
8+
fn main() {}

0 commit comments

Comments
 (0)