Skip to content

Commit e5776c6

Browse files
Use already resolved self_ty in confirm_fn_pointer_candidate
1 parent 57ee5cf commit e5776c6

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
626626
// the signature, as evidenced by how we treat it during projection.
627627
// The safe thing to do here is to liberate it, though, which should
628628
// have no worse effect than skipping the binder here.
629-
let liberated_fn_ty = self.infcx.replace_bound_vars_with_placeholders(obligation.self_ty());
629+
let liberated_fn_ty =
630+
self.infcx.replace_bound_vars_with_placeholders(obligation.predicate.rebind(self_ty));
630631
let output_ty = self
631632
.infcx
632633
.replace_bound_vars_with_placeholders(liberated_fn_ty.fn_sig(self.tcx()).output());

Diff for: src/test/ui/function-pointer/issue-102289.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// check-pass
2+
3+
pub(crate) trait Parser: Sized {
4+
type Output;
5+
fn parse(&mut self, _input: &str) -> Result<(), ()> {
6+
loop {}
7+
}
8+
fn map<F, B>(self, _f: F) -> Map<Self, F>
9+
where
10+
F: FnMut(Self::Output) -> B,
11+
{
12+
todo!()
13+
}
14+
}
15+
16+
pub(crate) struct Chainl1<P, Op>(P, Op);
17+
impl<P, Op> Parser for Chainl1<P, Op>
18+
where
19+
P: Parser,
20+
Op: Parser,
21+
Op::Output: FnOnce(P::Output, P::Output) -> P::Output,
22+
{
23+
type Output = P::Output;
24+
}
25+
pub(crate) fn chainl1<P, Op>(_parser: P, _op: Op) -> Chainl1<P, Op>
26+
where
27+
P: Parser,
28+
Op: Parser,
29+
Op::Output: FnOnce(P::Output, P::Output) -> P::Output,
30+
{
31+
loop {}
32+
}
33+
34+
pub(crate) struct Map<P, F>(P, F);
35+
impl<A, B, P, F> Parser for Map<P, F>
36+
where
37+
P: Parser<Output = A>,
38+
F: FnMut(A) -> B,
39+
{
40+
type Output = B;
41+
}
42+
43+
impl Parser for u32 {
44+
type Output = ();
45+
}
46+
47+
pub fn chainl1_error_consume() {
48+
fn first<T, U>(t: T, _: U) -> T {
49+
t
50+
}
51+
let _ = chainl1(1, 1.map(|_| first)).parse("");
52+
}
53+
54+
fn main() {}

0 commit comments

Comments
 (0)