Normalize obligations for closure confirmation
This commit is contained in:
parent
347d503333
commit
cacc3ee801
17 changed files with 263 additions and 87 deletions
|
@ -744,6 +744,7 @@ pub trait PrettyPrinter<'tcx>:
|
||||||
p!(print_def_path(did, substs));
|
p!(print_def_path(did, substs));
|
||||||
if !substs.as_closure().is_valid() {
|
if !substs.as_closure().is_valid() {
|
||||||
p!(" closure_substs=(unavailable)");
|
p!(" closure_substs=(unavailable)");
|
||||||
|
p!(write(" substs={:?}", substs));
|
||||||
} else {
|
} else {
|
||||||
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
|
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
|
||||||
p!(
|
p!(
|
||||||
|
|
|
@ -1734,7 +1734,7 @@ fn confirm_callable_candidate<'cx, 'tcx>(
|
||||||
ty: ret_type,
|
ty: ret_type,
|
||||||
});
|
});
|
||||||
|
|
||||||
confirm_param_env_candidate(selcx, obligation, predicate, false)
|
confirm_param_env_candidate(selcx, obligation, predicate, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_param_env_candidate<'cx, 'tcx>(
|
fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||||
|
@ -1754,8 +1754,18 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let cache_projection = cache_entry.projection_ty;
|
let cache_projection = cache_entry.projection_ty;
|
||||||
let obligation_projection = obligation.predicate;
|
|
||||||
let mut nested_obligations = Vec::new();
|
let mut nested_obligations = Vec::new();
|
||||||
|
let obligation_projection = obligation.predicate;
|
||||||
|
let obligation_projection = ensure_sufficient_stack(|| {
|
||||||
|
normalize_with_depth_to(
|
||||||
|
selcx,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
obligation_projection,
|
||||||
|
&mut nested_obligations,
|
||||||
|
)
|
||||||
|
});
|
||||||
let cache_projection = if potentially_unnormalized_candidate {
|
let cache_projection = if potentially_unnormalized_candidate {
|
||||||
ensure_sufficient_stack(|| {
|
ensure_sufficient_stack(|| {
|
||||||
normalize_with_depth_to(
|
normalize_with_depth_to(
|
||||||
|
@ -1771,6 +1781,8 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
|
||||||
cache_projection
|
cache_projection
|
||||||
};
|
};
|
||||||
|
|
||||||
|
debug!(?cache_projection, ?obligation_projection);
|
||||||
|
|
||||||
match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
|
match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
|
||||||
Ok(InferOk { value: _, obligations }) => {
|
Ok(InferOk { value: _, obligations }) => {
|
||||||
nested_obligations.extend(obligations);
|
nested_obligations.extend(obligations);
|
||||||
|
|
|
@ -620,23 +620,37 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
_ => bug!("closure candidate for non-closure {:?}", obligation),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let obligation_predicate = obligation.predicate.to_poly_trait_ref();
|
||||||
|
let Normalized { value: obligation_predicate, mut obligations } =
|
||||||
|
ensure_sufficient_stack(|| {
|
||||||
|
normalize_with_depth(
|
||||||
|
self,
|
||||||
|
obligation.param_env,
|
||||||
|
obligation.cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
|
obligation_predicate,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
|
let trait_ref = self.closure_trait_ref_unnormalized(obligation, substs);
|
||||||
let Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
|
let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
|
||||||
normalize_with_depth(
|
ensure_sufficient_stack(|| {
|
||||||
self,
|
normalize_with_depth(
|
||||||
obligation.param_env,
|
self,
|
||||||
obligation.cause.clone(),
|
obligation.param_env,
|
||||||
obligation.recursion_depth + 1,
|
obligation.cause.clone(),
|
||||||
trait_ref,
|
obligation.recursion_depth + 1,
|
||||||
)
|
trait_ref,
|
||||||
});
|
)
|
||||||
|
});
|
||||||
|
|
||||||
debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
|
debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
|
||||||
|
|
||||||
|
obligations.extend(trait_ref_obligations);
|
||||||
obligations.extend(self.confirm_poly_trait_refs(
|
obligations.extend(self.confirm_poly_trait_refs(
|
||||||
obligation.cause.clone(),
|
obligation.cause.clone(),
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
obligation.predicate.to_poly_trait_ref(),
|
obligation_predicate,
|
||||||
trait_ref,
|
trait_ref,
|
||||||
)?);
|
)?);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable)]`
|
found closure `[mod1::f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
|
||||||
help: use parentheses to call this closure
|
help: use parentheses to call this closure
|
||||||
|
|
|
|
||||||
LL | let c1 : () = c();
|
LL | let c1 : () = c();
|
||||||
|
|
|
@ -9,7 +9,7 @@ LL | let c1 : () = c;
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected unit type `()`
|
= note: expected unit type `()`
|
||||||
found closure `[f<T>::{closure#0} closure_substs=(unavailable)]`
|
found closure `[f<T>::{closure#0} closure_substs=(unavailable) substs=[T, _#25t, extern "rust-call" fn(()), _#26t]]`
|
||||||
help: use parentheses to call this closure
|
help: use parentheses to call this closure
|
||||||
|
|
|
|
||||||
LL | let c1 : () = c();
|
LL | let c1 : () = c();
|
||||||
|
|
|
@ -7,7 +7,7 @@ LL | let foo: fn(u8) -> u8 = |v: u8| { a += v; a };
|
||||||
| expected due to this
|
| expected due to this
|
||||||
|
|
|
|
||||||
= note: expected fn pointer `fn(u8) -> u8`
|
= note: expected fn pointer `fn(u8) -> u8`
|
||||||
found closure `[main::{closure#0} closure_substs=(unavailable)]`
|
found closure `[main::{closure#0} closure_substs=(unavailable) substs=[i8, extern "rust-call" fn((u8,)) -> u8, _#6t]]`
|
||||||
note: closures can only be coerced to `fn` types if they do not capture any variables
|
note: closures can only be coerced to `fn` types if they do not capture any variables
|
||||||
--> $DIR/closure-print-verbose.rs:10:39
|
--> $DIR/closure-print-verbose.rs:10:39
|
||||||
|
|
|
|
||||||
|
|
19
src/test/ui/generic-associated-types/issue-88459.rs
Normal file
19
src/test/ui/generic-associated-types/issue-88459.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(generic_associated_types)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Assoc<'a>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f<T: Trait>(_: T, _: impl Fn(T::Assoc<'_>)) {}
|
||||||
|
|
||||||
|
struct Type;
|
||||||
|
|
||||||
|
impl Trait for Type {
|
||||||
|
type Assoc<'a> = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
f(Type, |_|());
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
pub trait Foo<'a> {
|
pub trait Foo<'a> {
|
||||||
type Bar;
|
type Bar;
|
||||||
fn foo(&'a self) -> Self::Bar;
|
fn foo(&'a self) -> Self::Bar;
|
||||||
|
@ -24,7 +26,6 @@ pub fn catalyst(x: &i32) {
|
||||||
|
|
||||||
pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
|
pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
|
||||||
uncallable(x, |y| f(y));
|
uncallable(x, |y| f(y));
|
||||||
//~^ type mismatch
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
|
@ -77,7 +77,7 @@ where P: Execute + 'static {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
task(annotate( //~ type mismatch
|
task(annotate(
|
||||||
//~^ the size
|
//~^ the size
|
||||||
//~^^ the trait bound
|
//~^^ the trait bound
|
||||||
Annotate::<RefMutFamily<usize>>::new(),
|
Annotate::<RefMutFamily<usize>>::new(),
|
||||||
|
|
|
@ -1,29 +1,3 @@
|
||||||
error[E0631]: type mismatch in closure arguments
|
|
||||||
--> $DIR/issue-62529-1.rs:80:10
|
|
||||||
|
|
|
||||||
LL | task(annotate(
|
|
||||||
| _____----_^
|
|
||||||
| | |
|
|
||||||
| | required by a bound introduced by this call
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | Annotate::<RefMutFamily<usize>>::new(),
|
|
||||||
LL | | |value: &mut usize| {
|
|
||||||
| | ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
|
|
||||||
LL | | *value = 2;
|
|
||||||
LL | | }
|
|
||||||
LL | | ));
|
|
||||||
| |_____^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
|
|
||||||
|
|
|
||||||
note: required by a bound in `annotate`
|
|
||||||
--> $DIR/issue-62529-1.rs:44:8
|
|
||||||
|
|
|
||||||
LL | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
|
|
||||||
| -------- required by a bound in this
|
|
||||||
LL | where
|
|
||||||
LL | F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`
|
|
||||||
|
|
||||||
error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
|
error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
|
||||||
--> $DIR/issue-62529-1.rs:80:10
|
--> $DIR/issue-62529-1.rs:80:10
|
||||||
|
|
|
|
||||||
|
@ -73,7 +47,6 @@ LL | fn task<P>(processor: P) -> Task
|
||||||
LL | where P: Execute + 'static {
|
LL | where P: Execute + 'static {
|
||||||
| ^^^^^^^ required by this bound in `task`
|
| ^^^^^^^ required by this bound in `task`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0631.
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
pub trait MyTrait<'a> {
|
pub trait MyTrait<'a> {
|
||||||
type Output: 'a;
|
type Output: 'a;
|
||||||
fn gimme_value(&self) -> Self::Output;
|
fn gimme_value(&self) -> Self::Output;
|
||||||
|
@ -23,7 +25,7 @@ where
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let struc = MyStruct;
|
let struc = MyStruct;
|
||||||
meow(struc, |foo| { //~ type mismatch
|
meow(struc, |foo| {
|
||||||
println!("{:?}", foo);
|
println!("{:?}", foo);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
error[E0631]: type mismatch in closure arguments
|
|
||||||
--> $DIR/issue-70120.rs:26:5
|
|
||||||
|
|
|
||||||
LL | meow(struc, |foo| {
|
|
||||||
| ^^^^ ----- found signature of `for<'r> fn(&'r usize) -> _`
|
|
||||||
| |
|
|
||||||
| expected signature of `for<'any2> fn(<MyStruct as MyTrait<'any2>>::Output) -> _`
|
|
||||||
|
|
|
||||||
note: required by a bound in `meow`
|
|
||||||
--> $DIR/issue-70120.rs:18:8
|
|
||||||
|
|
|
||||||
LL | fn meow<T, F>(t: T, f: F)
|
|
||||||
| ---- required by a bound in this
|
|
||||||
...
|
|
||||||
LL | F: for<'any2> Fn(<T as MyTrait<'any2>>::Output),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `meow`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0631`.
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:52:5
|
||||||
|
|
|
||||||
|
LL | foo(bar, "string", |s| s.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:52:5
|
||||||
|
|
|
||||||
|
LL | foo(bar, "string", |s| s.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:52:5
|
||||||
|
|
|
||||||
|
LL | foo(bar, "string", |s| s.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:52:5
|
||||||
|
|
|
||||||
|
LL | foo(bar, "string", |s| s.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:52:5
|
||||||
|
|
|
||||||
|
LL | foo(bar, "string", |s| s.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:58:5
|
||||||
|
|
|
||||||
|
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:58:5
|
||||||
|
|
|
||||||
|
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:58:5
|
||||||
|
|
|
||||||
|
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:58:5
|
||||||
|
|
|
||||||
|
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: implementation of `Parser` is not general enough
|
||||||
|
--> $DIR/issue-71955.rs:58:5
|
||||||
|
|
|
||||||
|
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
| ^^^ implementation of `Parser` is not general enough
|
||||||
|
|
|
||||||
|
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||||
|
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||||
|
|
||||||
|
error: aborting due to 10 previous errors
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
error: fatal error triggered by #[rustc_error]
|
||||||
|
--> $DIR/issue-71955.rs:42:1
|
||||||
|
|
|
||||||
|
LL | fn main() {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
// ignore-compare-mode-nll
|
||||||
|
// revisions: migrate nll
|
||||||
|
// [nll]compile-flags: -Zborrowck=mir
|
||||||
|
// check-fail
|
||||||
|
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
trait Parser<'s> {
|
||||||
|
type Output;
|
||||||
|
|
||||||
|
fn call(&self, input: &'s str) -> (&'s str, Self::Output);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'s, F, T> Parser<'s> for F
|
||||||
|
where F: Fn(&'s str) -> (&'s str, T) {
|
||||||
|
type Output = T;
|
||||||
|
fn call(&self, input: &'s str) -> (&'s str, T) {
|
||||||
|
self(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<F1, F2>(
|
||||||
|
f1: F1,
|
||||||
|
base: &'static str,
|
||||||
|
f2: F2
|
||||||
|
)
|
||||||
|
where
|
||||||
|
F1: for<'a> Parser<'a>,
|
||||||
|
F2: FnOnce(&<F1 as Parser>::Output) -> bool
|
||||||
|
{
|
||||||
|
let s: String = base.to_owned();
|
||||||
|
let str_ref = s.as_ref();
|
||||||
|
let (remaining, produced) = f1.call(str_ref);
|
||||||
|
assert!(f2(&produced));
|
||||||
|
assert_eq!(remaining.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Wrapper<'a>(&'a str);
|
||||||
|
|
||||||
|
// Because nll currently succeeds and migrate doesn't
|
||||||
|
#[rustc_error]
|
||||||
|
fn main() {
|
||||||
|
//[nll]~^ fatal
|
||||||
|
fn bar<'a>(s: &'a str) -> (&'a str, &'a str) {
|
||||||
|
(&s[..1], &s[..])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn baz<'a>(s: &'a str) -> (&'a str, Wrapper<'a>) {
|
||||||
|
(&s[..1], Wrapper(&s[..]))
|
||||||
|
}
|
||||||
|
|
||||||
|
foo(bar, "string", |s| s.len() == 5);
|
||||||
|
//[migrate]~^ ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
foo(baz, "string", |s| s.0.len() == 5);
|
||||||
|
//[migrate]~^ ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
trait A<'a> {
|
||||||
|
type B;
|
||||||
|
fn b(self) -> Self::B;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct T;
|
||||||
|
struct S<'a>(PhantomData<&'a ()>);
|
||||||
|
|
||||||
|
impl<'a> A<'a> for T {
|
||||||
|
type B = S<'a>;
|
||||||
|
fn b(self) -> Self::B {
|
||||||
|
S(PhantomData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn s<TT, F>(t: TT, f: F)
|
||||||
|
where
|
||||||
|
TT: for<'a> A<'a>,
|
||||||
|
F: for<'a> FnOnce(<TT as A<'a>>::B)
|
||||||
|
{
|
||||||
|
f(t.b());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
s(T, |_| {});
|
||||||
|
}
|
|
@ -1,20 +0,0 @@
|
||||||
error[E0631]: type mismatch in closure arguments
|
|
||||||
--> $DIR/issue-44005.rs:26:5
|
|
||||||
|
|
|
||||||
LL | uncallable(x, |y| f(y));
|
|
||||||
| ^^^^^^^^^^ -------- found signature of `for<'r> fn(&'r i32) -> _`
|
|
||||||
| |
|
|
||||||
| expected signature of `for<'a> fn(<&i32 as Foo<'a>>::Bar) -> _`
|
|
||||||
|
|
|
||||||
note: required by a bound in `uncallable`
|
|
||||||
--> $DIR/issue-44005.rs:16:8
|
|
||||||
|
|
|
||||||
LL | pub fn uncallable<T, F>(x: T, f: F)
|
|
||||||
| ---------- required by a bound in this
|
|
||||||
...
|
|
||||||
LL | F: for<'a> Fn(<T as Foo<'a>>::Bar),
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `uncallable`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0631`.
|
|
Loading…
Add table
Add a link
Reference in a new issue