Skip to content

Commit 0900c2f

Browse files
committed
Normalize obligations for closure confirmation
1 parent ad02dc4 commit 0900c2f

18 files changed

+349
-79
lines changed

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,7 @@ pub trait PrettyPrinter<'tcx>:
721721
p!(print_def_path(did, substs));
722722
if !substs.as_closure().is_valid() {
723723
p!(" closure_substs=(unavailable)");
724+
p!(write(" substs={:?}", substs));
724725
} else {
725726
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
726727
p!(

compiler/rustc_trait_selection/src/traits/project.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1747,7 +1747,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
17471747
ty: ret_type,
17481748
});
17491749

1750-
confirm_param_env_candidate(selcx, obligation, predicate, false)
1750+
confirm_param_env_candidate(selcx, obligation, predicate, true)
17511751
}
17521752

17531753
fn confirm_param_env_candidate<'cx, 'tcx>(
@@ -1767,8 +1767,18 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
17671767
);
17681768

17691769
let cache_projection = cache_entry.projection_ty;
1770-
let obligation_projection = obligation.predicate;
17711770
let mut nested_obligations = Vec::new();
1771+
let obligation_projection = obligation.predicate;
1772+
let obligation_projection = ensure_sufficient_stack(|| {
1773+
normalize_with_depth_to(
1774+
selcx,
1775+
obligation.param_env,
1776+
obligation.cause.clone(),
1777+
obligation.recursion_depth + 1,
1778+
obligation_projection,
1779+
&mut nested_obligations,
1780+
)
1781+
});
17721782
let cache_projection = if potentially_unnormalized_candidate {
17731783
ensure_sufficient_stack(|| {
17741784
normalize_with_depth_to(
@@ -1784,6 +1794,8 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
17841794
cache_projection
17851795
};
17861796

1797+
debug!(?cache_projection, ?obligation_projection);
1798+
17871799
match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
17881800
Ok(InferOk { value: _, obligations }) => {
17891801
nested_obligations.extend(obligations);

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -619,23 +619,37 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
619619
_ => bug!("closure candidate for non-closure {:?}", obligation),
620620
};
621621

622+
let obligation_predicate = obligation.predicate.to_poly_trait_ref();
623+
let Normalized { value: obligation_predicate, mut obligations } =
624+
ensure_sufficient_stack(|| {
625+
normalize_with_depth(
626+
self,
627+
obligation.param_env,
628+
obligation.cause.clone(),
629+
obligation.recursion_depth + 1,
630+
obligation_predicate,
631+
)
632+
});
633+
622634
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
623-
let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
624-
normalize_with_depth(
625-
self,
626-
obligation.param_env,
627-
obligation.cause.clone(),
628-
obligation.recursion_depth + 1,
629-
trait_ref,
630-
)
631-
});
635+
let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
636+
ensure_sufficient_stack(|| {
637+
normalize_with_depth(
638+
self,
639+
obligation.param_env,
640+
obligation.cause.clone(),
641+
obligation.recursion_depth + 1,
642+
trait_ref,
643+
)
644+
});
632645

633646
debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
634647

648+
obligations.extend(trait_ref_obligations);
635649
obligations.extend(self.confirm_poly_trait_refs(
636650
obligation.cause.clone(),
637651
obligation.param_env,
638-
obligation.predicate.to_poly_trait_ref(),
652+
obligation_predicate,
639653
trait_ref,
640654
)?);
641655

src/test/ui/closures/print/closure-print-generic-trim-off-verbose-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | let c1 : () = c;
99
| expected due to this
1010
|
1111
= note: expected unit type `()`
12-
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable)]`
12+
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#27t, extern "rust-call" fn(()), _#28t]]`
1313
help: use parentheses to call this closure
1414
|
1515
LL | let c1 : () = c();

src/test/ui/closures/print/closure-print-generic-verbose-2.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ LL | let c1 : () = c;
99
| expected due to this
1010
|
1111
= note: expected unit type `()`
12-
found closure `[f<T>::{closure#0} closure_substs=(unavailable)]`
12+
found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#27t, extern "rust-call" fn(()), _#28t]]`
1313
help: use parentheses to call this closure
1414
|
1515
LL | let c1 : () = c();

src/test/ui/closures/print/closure-print-verbose.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
77
| expected due to this
88
|
99
= note: expected fn pointer `fn(u8) -> u8`
10-
found closure `[main::{closure#0} closure_substs=(unavailable)]`
10+
found closure `[main::{closure#0} closure_substs=(unavailable) substs=[i8, extern "rust-call" fn((u8,)) -> u8, _#6t]]`
1111
note: closures can only be coerced to `fn` types if they do not capture any variables
1212
--> $DIR/closure-print-verbose.rs:10:39
1313
|

src/test/ui/issues/issue-44005.rs renamed to src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-44005.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
pub trait Foo<'a> {
24
type Bar;
35
fn foo(&'a self) -> Self::Bar;
@@ -24,7 +26,6 @@ pub fn catalyst(x: &i32) {
2426

2527
pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
2628
uncallable(x, |y| f(y));
27-
//~^ type mismatch
2829
}
2930

3031
fn main() {}

src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ where P: Execute + 'static {
7777
}
7878

7979
fn main() {
80-
task(annotate( //~ type mismatch
80+
task(annotate(
8181
//~^ the size
8282
//~^^ the trait bound
8383
Annotate::<RefMutFamily<usize>>::new(),

src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,3 @@
1-
error[E0631]: type mismatch in closure arguments
2-
--> $DIR/issue-62529-1.rs:80:10
3-
|
4-
LL | task(annotate(
5-
| ^^^^^^^^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
6-
...
7-
LL | |value: &mut usize| {
8-
| ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
9-
|
10-
note: required by a bound in `annotate`
11-
--> $DIR/issue-62529-1.rs:44:8
12-
|
13-
LL | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
14-
| -------- required by a bound in this
15-
LL | where
16-
LL | F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
17-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`
18-
191
error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
202
--> $DIR/issue-62529-1.rs:80:10
213
|
@@ -61,7 +43,6 @@ LL | fn task<P>(processor: P) -> Task
6143
LL | where P: Execute + 'static {
6244
| ^^^^^^^ required by this bound in `task`
6345

64-
error: aborting due to 3 previous errors
46+
error: aborting due to 2 previous errors
6547

66-
Some errors have detailed explanations: E0277, E0631.
67-
For more information about an error, try `rustc --explain E0277`.
48+
For more information about this error, try `rustc --explain E0277`.

src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-70120.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
pub trait MyTrait<'a> {
24
type Output: 'a;
35
fn gimme_value(&self) -> Self::Output;
@@ -23,7 +25,7 @@ where
2325

2426
fn main() {
2527
let struc = MyStruct;
26-
meow(struc, |foo| { //~ type mismatch
28+
meow(struc, |foo| {
2729
println!("{:?}", foo);
2830
})
2931
}

0 commit comments

Comments
 (0)