1
Fork 0

Report "nice" placeholder errors more often

If we have a cause containing `ValuePairs::PolyTraitRefs` but neither
TraitRef has any escaping bound regions then we report the same error as
for `ValuePairs::TraitRefs`.
This commit is contained in:
Matthew Jasper 2021-02-09 22:59:32 +00:00
parent daab6db1a0
commit 94c11dfe78
19 changed files with 181 additions and 263 deletions

View file

@ -30,157 +30,153 @@ impl NiceRegionError<'me, 'tcx> {
Some(RegionResolutionError::SubSupConflict( Some(RegionResolutionError::SubSupConflict(
vid, vid,
_, _,
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sub_placeholder @ ty::RePlaceholder(_), sub_placeholder @ ty::RePlaceholder(_),
_, _,
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause, cause,
Some(sub_placeholder), Some(sub_placeholder),
Some(sup_placeholder), Some(sup_placeholder),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::SubSupConflict( Some(RegionResolutionError::SubSupConflict(
vid, vid,
_, _,
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sub_placeholder @ ty::RePlaceholder(_), sub_placeholder @ ty::RePlaceholder(_),
_, _,
_, _,
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause, cause,
Some(sub_placeholder), Some(sub_placeholder),
None, None,
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::SubSupConflict( Some(RegionResolutionError::SubSupConflict(
vid, vid,
_, _,
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
_, _,
_, _,
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::SubSupConflict( Some(RegionResolutionError::SubSupConflict(
vid, vid,
_, _,
_, _,
_, _,
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::UpperBoundUniverseConflict( Some(RegionResolutionError::UpperBoundUniverseConflict(
vid, vid,
_, _,
_, _,
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sup_placeholder @ ty::RePlaceholder(_), sup_placeholder @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(self.tcx().mk_region(ty::ReVar(*vid))), Some(self.tcx().mk_region(ty::ReVar(*vid))),
cause, cause,
None, None,
Some(*sup_placeholder), Some(*sup_placeholder),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sub_region @ ty::RePlaceholder(_), sub_region @ ty::RePlaceholder(_),
sup_region @ ty::RePlaceholder(_), sup_region @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
None, None,
cause, cause,
Some(*sub_region), Some(*sub_region),
Some(*sup_region), Some(*sup_region),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sub_region @ ty::RePlaceholder(_), sub_region @ ty::RePlaceholder(_),
sup_region, sup_region,
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(sup_region), Some(sup_region),
cause, cause,
Some(*sub_region), Some(*sub_region),
None, None,
expected.def_id, values,
expected.substs, ),
found.substs,
)),
Some(RegionResolutionError::ConcreteFailure( Some(RegionResolutionError::ConcreteFailure(
SubregionOrigin::Subtype(box TypeTrace { SubregionOrigin::Subtype(box TypeTrace { cause, values }),
cause,
values: ValuePairs::TraitRefs(ExpectedFound { expected, found }),
}),
sub_region, sub_region,
sup_region @ ty::RePlaceholder(_), sup_region @ ty::RePlaceholder(_),
)) if expected.def_id == found.def_id => Some(self.try_report_placeholders_trait( )) => self.try_report_trait_placeholder_mismatch(
Some(sub_region), Some(sub_region),
cause, cause,
None, None,
Some(*sup_region), Some(*sup_region),
expected.def_id, values,
expected.substs, ),
found.substs,
)),
_ => None, _ => None,
} }
} }
fn try_report_trait_placeholder_mismatch(
&self,
vid: Option<ty::Region<'tcx>>,
cause: &ObligationCause<'tcx>,
sub_placeholder: Option<ty::Region<'tcx>>,
sup_placeholder: Option<ty::Region<'tcx>>,
value_pairs: &ValuePairs<'tcx>,
) -> Option<DiagnosticBuilder<'tcx>> {
let (expected_substs, found_substs, trait_def_id) = match value_pairs {
ValuePairs::TraitRefs(ExpectedFound { expected, found })
if expected.def_id == found.def_id =>
{
(expected.substs, found.substs, expected.def_id)
}
ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
if expected.def_id() == found.def_id() =>
{
// It's possible that the placeholders come from a binder
// outside of this value pair. Use `no_bound_vars` as a
// simple heuristic for that.
(expected.no_bound_vars()?.substs, found.no_bound_vars()?.substs, expected.def_id())
}
_ => return None,
};
Some(self.report_trait_placeholder_mismatch(
vid,
cause,
sub_placeholder,
sup_placeholder,
trait_def_id,
expected_substs,
found_substs,
))
}
// error[E0308]: implementation of `Foo` does not apply to enough lifetimes // error[E0308]: implementation of `Foo` does not apply to enough lifetimes
// --> /home/nmatsakis/tmp/foo.rs:12:5 // --> /home/nmatsakis/tmp/foo.rs:12:5
// | // |
@ -191,7 +187,7 @@ impl NiceRegionError<'me, 'tcx> {
// = note: `T` must implement `...` for any two lifetimes `'1` and `'2`. // = note: `T` must implement `...` for any two lifetimes `'1` and `'2`.
// = note: However, the type `T` only implements `...` for some specific lifetime `'2`. // = note: However, the type `T` only implements `...` for some specific lifetime `'2`.
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn try_report_placeholders_trait( fn report_trait_placeholder_mismatch(
&self, &self,
vid: Option<ty::Region<'tcx>>, vid: Option<ty::Region<'tcx>>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,

View file

@ -1,11 +1,11 @@
warning: function cannot return without recursing warning: function cannot return without recursing
--> $DIR/hrtb-perfect-forwarding.rs:22:1 --> $DIR/hrtb-perfect-forwarding.rs:16:1
| |
LL | / fn no_hrtb<'b,T>(mut t: T) LL | / fn no_hrtb<'b, T>(mut t: T)
LL | | where T : Bar<&'b isize> LL | | where
LL | | T: Bar<&'b isize>,
LL | | { LL | | {
LL | | // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that ... |
LL | | // `&mut T : Bar<&'b isize>`.
LL | | no_hrtb(&mut t); LL | | no_hrtb(&mut t);
| | --------------- recursive call site | | --------------- recursive call site
LL | | } LL | | }
@ -15,12 +15,12 @@ LL | | }
= help: a `loop` may express intention better if this is on purpose = help: a `loop` may express intention better if this is on purpose
warning: function cannot return without recursing warning: function cannot return without recursing
--> $DIR/hrtb-perfect-forwarding.rs:30:1 --> $DIR/hrtb-perfect-forwarding.rs:25:1
| |
LL | / fn bar_hrtb<T>(mut t: T) LL | / fn bar_hrtb<T>(mut t: T)
LL | | where T : for<'b> Bar<&'b isize> LL | | where
LL | | T: for<'b> Bar<&'b isize>,
LL | | { LL | | {
LL | | // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
... | ... |
LL | | bar_hrtb(&mut t); LL | | bar_hrtb(&mut t);
| | ---------------- recursive call site | | ---------------- recursive call site
@ -30,25 +30,26 @@ LL | | }
= help: a `loop` may express intention better if this is on purpose = help: a `loop` may express intention better if this is on purpose
warning: function cannot return without recursing warning: function cannot return without recursing
--> $DIR/hrtb-perfect-forwarding.rs:39:1 --> $DIR/hrtb-perfect-forwarding.rs:35:1
| |
LL | / fn foo_hrtb_bar_not<'b,T>(mut t: T) LL | / fn foo_hrtb_bar_not<'b, T>(mut t: T)
LL | | where T : for<'a> Foo<&'a isize> + Bar<&'b isize> LL | | where
LL | | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
LL | | { LL | | {
LL | | // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
... | ... |
LL | | foo_hrtb_bar_not(&mut t); LL | | foo_hrtb_bar_not(&mut t);
| | ------------------------ recursive call site | | ------------------------ recursive call site
LL | | LL | |
LL | |
LL | | } LL | | }
| |_^ cannot return without recursing | |_^ cannot return without recursing
| |
= help: a `loop` may express intention better if this is on purpose = help: a `loop` may express intention better if this is on purpose
error: lifetime may not live long enough error: lifetime may not live long enough
--> $DIR/hrtb-perfect-forwarding.rs:46:5 --> $DIR/hrtb-perfect-forwarding.rs:43:5
| |
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T) LL | fn foo_hrtb_bar_not<'b, T>(mut t: T)
| -- lifetime `'b` defined here | -- lifetime `'b` defined here
... ...
LL | foo_hrtb_bar_not(&mut t); LL | foo_hrtb_bar_not(&mut t);
@ -57,18 +58,19 @@ LL | foo_hrtb_bar_not(&mut t);
= help: consider replacing `'b` with `'static` = help: consider replacing `'b` with `'static`
error: higher-ranked subtype error error: higher-ranked subtype error
--> $DIR/hrtb-perfect-forwarding.rs:46:5 --> $DIR/hrtb-perfect-forwarding.rs:43:5
| |
LL | foo_hrtb_bar_not(&mut t); LL | foo_hrtb_bar_not(&mut t);
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
warning: function cannot return without recursing warning: function cannot return without recursing
--> $DIR/hrtb-perfect-forwarding.rs:50:1 --> $DIR/hrtb-perfect-forwarding.rs:48:1
| |
LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T) LL | / fn foo_hrtb_bar_hrtb<T>(mut t: T)
LL | | where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> LL | | where
LL | | T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
LL | | { LL | | {
LL | | // OK -- now we have `T : for<'b> Bar&'b isize>`. LL | | // OK -- now we have `T : for<'b> Bar<&'b isize>`.
LL | | foo_hrtb_bar_hrtb(&mut t); LL | | foo_hrtb_bar_hrtb(&mut t);
| | ------------------------- recursive call site | | ------------------------- recursive call site
LL | | } LL | | }

View file

@ -2,25 +2,20 @@
// is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730. // is being applied to `for<'a> Foo<&'a mut X>`. Issue #19730.
trait Foo<X> { trait Foo<X> {
fn foo(&mut self, x: X) { } fn foo(&mut self, x: X) {}
} }
trait Bar<X> { trait Bar<X> {
fn bar(&mut self, x: X) { } fn bar(&mut self, x: X) {}
} }
impl<'a,X,F> Foo<X> for &'a mut F impl<'a, X, F> Foo<X> for &'a mut F where F: Foo<X> + Bar<X> {}
where F : Foo<X> + Bar<X>
{
}
impl<'a,X,F> Bar<X> for &'a mut F impl<'a, X, F> Bar<X> for &'a mut F where F: Bar<X> {}
where F : Bar<X>
{
}
fn no_hrtb<'b,T>(mut t: T) fn no_hrtb<'b, T>(mut t: T)
where T : Bar<&'b isize> where
T: Bar<&'b isize>,
{ {
// OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that // OK -- `T : Bar<&'b isize>`, and thus the impl above ensures that
// `&mut T : Bar<&'b isize>`. // `&mut T : Bar<&'b isize>`.
@ -28,7 +23,8 @@ fn no_hrtb<'b,T>(mut t: T)
} }
fn bar_hrtb<T>(mut t: T) fn bar_hrtb<T>(mut t: T)
where T : for<'b> Bar<&'b isize> where
T: for<'b> Bar<&'b isize>,
{ {
// OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above // OK -- `T : for<'b> Bar<&'b isize>`, and thus the impl above
// ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an // ensures that `&mut T : for<'b> Bar<&'b isize>`. This is an
@ -36,22 +32,25 @@ fn bar_hrtb<T>(mut t: T)
bar_hrtb(&mut t); bar_hrtb(&mut t);
} }
fn foo_hrtb_bar_not<'b,T>(mut t: T) fn foo_hrtb_bar_not<'b, T>(mut t: T)
where T : for<'a> Foo<&'a isize> + Bar<&'b isize> where
T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
{ {
// Not OK -- The forwarding impl for `Foo` requires that `Bar` also // Not OK -- The forwarding impl for `Foo` requires that `Bar` also
// be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a // be implemented. Thus to satisfy `&mut T : for<'a> Foo<&'a
// isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where // isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
// clause only specifies `T : Bar<&'b isize>`. // clause only specifies `T : Bar<&'b isize>`.
foo_hrtb_bar_not(&mut t); //~ ERROR mismatched types foo_hrtb_bar_not(&mut t);
//~| ERROR mismatched types //~^ ERROR implementation of `Bar` is not general enough
//~| ERROR implementation of `Bar` is not general enough
} }
fn foo_hrtb_bar_hrtb<T>(mut t: T) fn foo_hrtb_bar_hrtb<T>(mut t: T)
where T : for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize> where
T: for<'a> Foo<&'a isize> + for<'b> Bar<&'b isize>,
{ {
// OK -- now we have `T : for<'b> Bar&'b isize>`. // OK -- now we have `T : for<'b> Bar<&'b isize>`.
foo_hrtb_bar_hrtb(&mut t); foo_hrtb_bar_hrtb(&mut t);
} }
fn main() { } fn main() {}

View file

@ -1,41 +1,20 @@
error[E0308]: mismatched types error: implementation of `Bar` is not general enough
--> $DIR/hrtb-perfect-forwarding.rs:46:5 --> $DIR/hrtb-perfect-forwarding.rs:43:5
| |
LL | foo_hrtb_bar_not(&mut t); LL | foo_hrtb_bar_not(&mut t);
| ^^^^^^^^^^^^^^^^ lifetime mismatch | ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
| |
= note: expected type `Bar<&'a isize>` = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
found type `Bar<&'b isize>` = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
note: the required lifetime does not necessarily outlive the lifetime `'b` as defined on the function body at 39:21
--> $DIR/hrtb-perfect-forwarding.rs:39:21
|
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
| ^^
note: the lifetime requirement is introduced here
--> $DIR/hrtb-perfect-forwarding.rs:40:15
|
LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
| ^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types error: implementation of `Bar` is not general enough
--> $DIR/hrtb-perfect-forwarding.rs:46:5 --> $DIR/hrtb-perfect-forwarding.rs:43:5
| |
LL | foo_hrtb_bar_not(&mut t); LL | foo_hrtb_bar_not(&mut t);
| ^^^^^^^^^^^^^^^^ lifetime mismatch | ^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
| |
= note: expected type `Bar<&'a isize>` = note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
found type `Bar<&'b isize>` = note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
note: the lifetime `'b` as defined on the function body at 39:21 doesn't meet the lifetime requirements
--> $DIR/hrtb-perfect-forwarding.rs:39:21
|
LL | fn foo_hrtb_bar_not<'b,T>(mut t: T)
| ^^
note: the lifetime requirement is introduced here
--> $DIR/hrtb-perfect-forwarding.rs:40:15
|
LL | where T : for<'a> Foo<&'a isize> + Bar<&'b isize>
| ^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View file

@ -1,5 +1,5 @@
error: higher-ranked subtype error error: higher-ranked subtype error
--> $DIR/issue-57843.rs:23:9 --> $DIR/issue-57843.rs:25:9
| |
LL | Foo(Box::new(|_| ())); LL | Foo(Box::new(|_| ()));
| ^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^

View file

@ -11,7 +11,9 @@ trait ClonableFn<T> {
} }
impl<T, F: 'static> ClonableFn<T> for F impl<T, F: 'static> ClonableFn<T> for F
where F: Fn(T) + Clone { where
F: Fn(T) + Clone,
{
fn clone(&self) -> Box<dyn Fn(T)> { fn clone(&self) -> Box<dyn Fn(T)> {
Box::new(self.clone()) Box::new(self.clone())
} }
@ -20,5 +22,5 @@ where F: Fn(T) + Clone {
struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>); struct Foo(Box<dyn for<'a> ClonableFn<&'a bool>>);
fn main() { fn main() {
Foo(Box::new(|_| ())); //~ ERROR mismatched types Foo(Box::new(|_| ())); //~ ERROR implementation of `FnOnce` is not general enough
} }

View file

@ -1,17 +1,11 @@
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57843.rs:23:9 --> $DIR/issue-57843.rs:25:9
| |
LL | Foo(Box::new(|_| ())); LL | Foo(Box::new(|_| ()));
| ^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&'a bool,)>` = note: `[closure@$DIR/issue-57843.rs:25:18: 25:24]` must implement `FnOnce<(&'1 bool,)>`, for any lifetime `'1`...
found type `FnOnce<(&bool,)>` = note: ...but it actually implements `FnOnce<(&'2 bool,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57843.rs:23:18
|
LL | Foo(Box::new(|_| ()));
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -2,5 +2,5 @@ fn thing(x: impl FnOnce(&u32)) {}
fn main() { fn main() {
let f = |_| (); let f = |_| ();
thing(f); //~ERROR mismatched types thing(f); //~ERROR implementation of `FnOnce` is not general enough
} }

View file

@ -1,22 +1,11 @@
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-79187.rs:5:5 --> $DIR/issue-79187.rs:5:5
| |
LL | thing(f); LL | thing(f);
| ^^^^^ lifetime mismatch | ^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&u32,)>` = note: `[closure@$DIR/issue-79187.rs:4:13: 4:19]` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
found type `FnOnce<(&u32,)>` = note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-79187.rs:4:13
|
LL | let f = |_| ();
| ^^^^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-79187.rs:1:18
|
LL | fn thing(x: impl FnOnce(&u32)) {}
| ^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -8,8 +8,8 @@ fn main() {
fn baz<F: Fn(*mut &u32)>(_: F) {} fn baz<F: Fn(*mut &u32)>(_: F) {}
fn _test<'a>(f: fn(*mut &'a u32)) { fn _test<'a>(f: fn(*mut &'a u32)) {
baz(f); baz(f);
//~^ ERROR mismatched types //~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types //~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types //~| ERROR mismatched types
//~| ERROR mismatched types //~| ERROR mismatched types
} }

View file

@ -41,24 +41,14 @@ note: the lifetime requirement is introduced here
LL | fn baz<F: Fn(*mut &u32)>(_: F) {} LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/closure-arg-type-mismatch.rs:10:5 --> $DIR/closure-arg-type-mismatch.rs:10:5
| |
LL | baz(f); LL | baz(f);
| ^^^ lifetime mismatch | ^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(*mut &u32,)>` = note: `fn(*mut &'2 u32)` must implement `FnOnce<(*mut &'1 u32,)>`, for any lifetime `'1`...
found type `FnOnce<(*mut &'a u32,)>` = note: ...but it actually implements `FnOnce<(*mut &'2 u32,)>`, for some specific lifetime `'2`
note: the required lifetime does not necessarily outlive the lifetime `'a` as defined on the function body at 9:10
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
| ^^
note: the lifetime requirement is introduced here
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/closure-arg-type-mismatch.rs:10:5 --> $DIR/closure-arg-type-mismatch.rs:10:5
@ -79,24 +69,14 @@ note: the lifetime requirement is introduced here
LL | fn baz<F: Fn(*mut &u32)>(_: F) {} LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/closure-arg-type-mismatch.rs:10:5 --> $DIR/closure-arg-type-mismatch.rs:10:5
| |
LL | baz(f); LL | baz(f);
| ^^^ lifetime mismatch | ^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(*mut &u32,)>` = note: `fn(*mut &'2 u32)` must implement `FnOnce<(*mut &'1 u32,)>`, for any lifetime `'1`...
found type `FnOnce<(*mut &'a u32,)>` = note: ...but it actually implements `FnOnce<(*mut &'2 u32,)>`, for some specific lifetime `'2`
note: the lifetime `'a` as defined on the function body at 9:10 doesn't meet the lifetime requirements
--> $DIR/closure-arg-type-mismatch.rs:9:10
|
LL | fn _test<'a>(f: fn(*mut &'a u32)) {
| ^^
note: the lifetime requirement is introduced here
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -22,7 +22,7 @@ static SOME_STRUCT: &SomeStruct = &SomeStruct {
foo: &Foo { bools: &[false, true] }, foo: &Foo { bools: &[false, true] },
bar: &Bar { bools: &[true, true] }, bar: &Bar { bools: &[true, true] },
f: &id, f: &id,
//~^ ERROR mismatched types //~^ ERROR implementation of `FnOnce` is not general enough
}; };
// very simple test for a 'static static with default lifetime // very simple test for a 'static static with default lifetime

View file

@ -1,12 +1,11 @@
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/rfc1623.rs:24:8 --> $DIR/rfc1623.rs:24:8
| |
LL | f: &id, LL | f: &id,
| ^^^ one type is more general than the other | ^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&'a Foo<'b>,)>` = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
found type `FnOnce<(&Foo<'_>,)>` = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -24,19 +24,14 @@ note: this closure does not fulfill the lifetime requirements
LL | |x| x LL | |x| x
| ^^^^^ | ^^^^^
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
| |
LL | type Bar = impl Baz<Self, Self>; LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&X,)>` = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
found type `FnOnce<(&'static X,)>` = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57611-trait-alias.rs:25:9
|
LL | |x| x
| ^^^^^
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -15,9 +15,9 @@ struct X;
impl Foo for X { impl Foo for X {
type Bar = impl Baz<Self, Self>; type Bar = impl Baz<Self, Self>;
//~^ ERROR mismatched types //~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types //~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types //~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types //~| ERROR mismatched types
//~| ERROR mismatched types //~| ERROR mismatched types

View file

@ -1,16 +1,11 @@
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
| |
LL | type Bar = impl Baz<Self, Self>; LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&X,)>` = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
found type `FnOnce<(&X,)>` = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57611-trait-alias.rs:25:9
|
LL | |x| x
| ^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
@ -26,19 +21,14 @@ note: this closure does not fulfill the lifetime requirements
LL | |x| x LL | |x| x
| ^^^^^ | ^^^^^
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
| |
LL | type Bar = impl Baz<Self, Self>; LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&X,)>` = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
found type `FnOnce<(&'<empty> X,)>` = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57611-trait-alias.rs:25:9
|
LL | |x| x
| ^^^^^
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
@ -54,19 +44,14 @@ note: this closure does not fulfill the lifetime requirements
LL | |x| x LL | |x| x
| ^^^^^ | ^^^^^
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-57611-trait-alias.rs:17:16 --> $DIR/issue-57611-trait-alias.rs:17:16
| |
LL | type Bar = impl Baz<Self, Self>; LL | type Bar = impl Baz<Self, Self>;
| ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&X,)>` = note: `[closure@$DIR/issue-57611-trait-alias.rs:25:9: 25:14]` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`...
found type `FnOnce<(&'<empty> X,)>` = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-57611-trait-alias.rs:25:9
|
LL | |x| x
| ^^^^^
error: aborting due to 5 previous errors error: aborting due to 5 previous errors

View file

@ -1,5 +1,5 @@
error: higher-ranked subtype error error: higher-ranked subtype error
--> $DIR/issue-30906.rs:15:5 --> $DIR/issue-30906.rs:18:5
| |
LL | test(Compose(f, |_| {})); LL | test(Compose(f, |_| {}));
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -2,9 +2,12 @@
fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {} fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
struct Compose<F,G>(F,G); struct Compose<F, G>(F, G);
impl<T,F,G> FnOnce<(T,)> for Compose<F,G> impl<T, F, G> FnOnce<(T,)> for Compose<F, G>
where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> { where
F: FnOnce<(T,)>,
G: FnOnce<(F::Output,)>,
{
type Output = G::Output; type Output = G::Output;
extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output { extern "rust-call" fn call_once(self, (x,): (T,)) -> G::Output {
(self.1)((self.0)(x)) (self.1)((self.0)(x))
@ -12,7 +15,8 @@ where F: FnOnce<(T,)>, G: FnOnce<(F::Output,)> {
} }
fn bad<T>(f: fn(&'static str) -> T) { fn bad<T>(f: fn(&'static str) -> T) {
test(Compose(f, |_| {})); //~ ERROR: mismatched types test(Compose(f, |_| {}));
//~^ ERROR: implementation of `FnOnce` is not general enough
} }
fn main() {} fn main() {}

View file

@ -1,17 +1,11 @@
error[E0308]: mismatched types error: implementation of `FnOnce` is not general enough
--> $DIR/issue-30906.rs:15:5 --> $DIR/issue-30906.rs:18:5
| |
LL | test(Compose(f, |_| {})); LL | test(Compose(f, |_| {}));
| ^^^^ lifetime mismatch | ^^^^ implementation of `FnOnce` is not general enough
| |
= note: expected type `FnOnce<(&'x str,)>` = note: `fn(&'2 str) -> T` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
found type `FnOnce<(&str,)>` = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`
note: the lifetime requirement is introduced here
--> $DIR/issue-30906.rs:3:12
|
LL | fn test<F: for<'x> FnOnce<(&'x str,)>>(_: F) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.