p!(print_def_path(did, substs));
if !substs.as_closure().is_valid() {
p!(" closure_substs=(unavailable)");
+ p!(write(" substs={:?}", substs));
} else {
p!(" closure_kind_ty=", print(substs.as_closure().kind_ty()));
p!(
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>(
);
let cache_projection = cache_entry.projection_ty;
- let obligation_projection = obligation.predicate;
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 {
ensure_sufficient_stack(|| {
normalize_with_depth_to(
cache_projection
};
+ debug!(?cache_projection, ?obligation_projection);
+
match infcx.at(cause, param_env).eq(cache_projection, obligation_projection) {
Ok(InferOk { value: _, obligations }) => {
nested_obligations.extend(obligations);
_ => 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 Normalized { value: trait_ref, mut obligations } = ensure_sufficient_stack(|| {
- normalize_with_depth(
- self,
- obligation.param_env,
- obligation.cause.clone(),
- obligation.recursion_depth + 1,
- trait_ref,
- )
- });
+ let Normalized { value: trait_ref, obligations: trait_ref_obligations } =
+ ensure_sufficient_stack(|| {
+ normalize_with_depth(
+ self,
+ obligation.param_env,
+ obligation.cause.clone(),
+ obligation.recursion_depth + 1,
+ trait_ref,
+ )
+ });
debug!(?closure_def_id, ?trait_ref, ?obligations, "confirm closure candidate obligations");
+ obligations.extend(trait_ref_obligations);
obligations.extend(self.confirm_poly_trait_refs(
obligation.cause.clone(),
obligation.param_env,
- obligation.predicate.to_poly_trait_ref(),
+ obligation_predicate,
trait_ref,
)?);
| expected due to this
|
= 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
|
LL | let c1 : () = c();
| expected due to this
|
= 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
|
LL | let c1 : () = c();
| expected due to this
|
= 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
--> $DIR/closure-print-verbose.rs:10:39
|
--- /dev/null
+// 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, |_|());
+}
--- /dev/null
+// check-pass
+
+pub trait Foo<'a> {
+ type Bar;
+ fn foo(&'a self) -> Self::Bar;
+}
+
+impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
+ type Bar = &'a T;
+ fn foo(&'a self) -> &'a T {
+ self
+ }
+}
+
+pub fn uncallable<T, F>(x: T, f: F)
+where
+ T: for<'a> Foo<'a>,
+ F: for<'a> Fn(<T as Foo<'a>>::Bar),
+{
+ f(x.foo());
+}
+
+pub fn catalyst(x: &i32) {
+ broken(x, |_| {})
+}
+
+pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
+ uncallable(x, |y| f(y));
+}
+
+fn main() {}
}
fn main() {
- task(annotate( //~ type mismatch
+ task(annotate(
//~^ the size
//~^^ the trait bound
Annotate::<RefMutFamily<usize>>::new(),
-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
--> $DIR/issue-62529-1.rs:80:10
|
LL | where P: Execute + 'static {
| ^^^^^^^ 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 an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
+// check-pass
+
pub trait MyTrait<'a> {
type Output: 'a;
fn gimme_value(&self) -> Self::Output;
fn main() {
let struc = MyStruct;
- meow(struc, |foo| { //~ type mismatch
+ meow(struc, |foo| {
println!("{:?}", foo);
})
}
+++ /dev/null
-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`.
--- /dev/null
+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
+
--- /dev/null
+error: fatal error triggered by #[rustc_error]
+ --> $DIR/issue-71955.rs:42:1
+ |
+LL | fn main() {
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
--- /dev/null
+// 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
+}
--- /dev/null
+// 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, |_| {});
+}
+++ /dev/null
-pub trait Foo<'a> {
- type Bar;
- fn foo(&'a self) -> Self::Bar;
-}
-
-impl<'a, 'b, T: 'a> Foo<'a> for &'b T {
- type Bar = &'a T;
- fn foo(&'a self) -> &'a T {
- self
- }
-}
-
-pub fn uncallable<T, F>(x: T, f: F)
-where
- T: for<'a> Foo<'a>,
- F: for<'a> Fn(<T as Foo<'a>>::Bar),
-{
- f(x.foo());
-}
-
-pub fn catalyst(x: &i32) {
- broken(x, |_| {})
-}
-
-pub fn broken<F: Fn(&i32)>(x: &i32, f: F) {
- uncallable(x, |y| f(y));
- //~^ type mismatch
-}
-
-fn main() {}
+++ /dev/null
-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`.