1
Fork 0

remove snapshot calls from "match" operations during select

Motivation:

- we want to use leak-check sparingly, first off
- these calls were essentially the same as doing the check during subtyping
This commit is contained in:
Niko Matsakis 2020-05-22 17:48:07 +00:00
parent 1e00e1b6de
commit 70cf33fcca
16 changed files with 144 additions and 194 deletions

View file

@ -163,9 +163,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_ => return, _ => return,
} }
let result = self.infcx.probe(|snapshot| { let result = self
self.match_projection_obligation_against_definition_bounds(obligation, snapshot) .infcx
}); .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
if result { if result {
candidates.vec.push(ProjectionCandidate); candidates.vec.push(ProjectionCandidate);
@ -345,8 +345,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation.predicate.def_id(), obligation.predicate.def_id(),
obligation.predicate.skip_binder().trait_ref.self_ty(), obligation.predicate.skip_binder().trait_ref.self_ty(),
|impl_def_id| { |impl_def_id| {
self.infcx.probe(|snapshot| { self.infcx.probe(|_| {
if let Ok(_substs) = self.match_impl(impl_def_id, obligation, snapshot) { if let Ok(_substs) = self.match_impl(impl_def_id, obligation) {
candidates.vec.push(ImplCandidate(impl_def_id)); candidates.vec.push(ImplCandidate(impl_def_id));
} }
}); });

View file

@ -121,9 +121,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} }
fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) { fn confirm_projection_candidate(&mut self, obligation: &TraitObligation<'tcx>) {
self.infcx.commit_unconditionally(|snapshot| { self.infcx.commit_unconditionally(|_| {
let result = let result = self.match_projection_obligation_against_definition_bounds(obligation);
self.match_projection_obligation_against_definition_bounds(obligation, snapshot);
assert!(result); assert!(result);
}) })
} }
@ -265,8 +264,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// First, create the substitutions by matching the impl again, // First, create the substitutions by matching the impl again,
// this time not in a probe. // this time not in a probe.
self.infcx.commit_unconditionally(|snapshot| { self.infcx.commit_unconditionally(|_| {
let substs = self.rematch_impl(impl_def_id, obligation, snapshot); let substs = self.rematch_impl(impl_def_id, obligation);
debug!("confirm_impl_candidate: substs={:?}", substs); debug!("confirm_impl_candidate: substs={:?}", substs);
let cause = obligation.derived_cause(ImplDerivedObligation); let cause = obligation.derived_cause(ImplDerivedObligation);
ensure_sufficient_stack(|| { ensure_sufficient_stack(|| {

View file

@ -21,7 +21,7 @@ use super::{Normalized, ProjectionCacheKey};
use super::{ObligationCause, PredicateObligation, TraitObligation}; use super::{ObligationCause, PredicateObligation, TraitObligation};
use super::{Overflow, SelectionError, Unimplemented}; use super::{Overflow, SelectionError, Unimplemented};
use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, TypeFreshener}; use crate::infer::{InferCtxt, InferOk, TypeFreshener};
use crate::traits::error_reporting::InferCtxtExt; use crate::traits::error_reporting::InferCtxtExt;
use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::project::ProjectionCacheKeyExt;
use rustc_ast::attr; use rustc_ast::attr;
@ -1268,7 +1268,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn match_projection_obligation_against_definition_bounds( fn match_projection_obligation_against_definition_bounds(
&mut self, &mut self,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> bool { ) -> bool {
let poly_trait_predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate); let poly_trait_predicate = self.infcx().resolve_vars_if_possible(&obligation.predicate);
let (placeholder_trait_predicate, _) = let (placeholder_trait_predicate, _) =
@ -1299,12 +1298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if let ty::PredicateKind::Trait(bound, _) = bound.kind() { if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
let bound = bound.to_poly_trait_ref(); let bound = bound.to_poly_trait_ref();
if self.infcx.probe(|_| { if self.infcx.probe(|_| {
self.match_projection( self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref)
obligation,
bound,
placeholder_trait_predicate.trait_ref,
snapshot,
)
}) { }) {
return Some(bound); return Some(bound);
} }
@ -1321,12 +1315,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
None => false, None => false,
Some(bound) => { Some(bound) => {
// Repeat the successful match, if any, this time outside of a probe. // Repeat the successful match, if any, this time outside of a probe.
let result = self.match_projection( let result =
obligation, self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref);
bound,
placeholder_trait_predicate.trait_ref,
snapshot,
);
assert!(result); assert!(result);
true true
@ -1339,14 +1329,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
trait_bound: ty::PolyTraitRef<'tcx>, trait_bound: ty::PolyTraitRef<'tcx>,
placeholder_trait_ref: ty::TraitRef<'tcx>, placeholder_trait_ref: ty::TraitRef<'tcx>,
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> bool { ) -> bool {
debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars()); debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
self.infcx self.infcx
.at(&obligation.cause, obligation.param_env) .at(&obligation.cause, obligation.param_env)
.sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound)
.is_ok() .is_ok()
&& self.infcx.leak_check(false, snapshot).is_ok()
} }
fn evaluate_where_clause<'o>( fn evaluate_where_clause<'o>(
@ -1811,9 +1799,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> Normalized<'tcx, SubstsRef<'tcx>> { ) -> Normalized<'tcx, SubstsRef<'tcx>> {
match self.match_impl(impl_def_id, obligation, snapshot) { match self.match_impl(impl_def_id, obligation) {
Ok(substs) => substs, Ok(substs) => substs,
Err(()) => { Err(()) => {
bug!( bug!(
@ -1829,7 +1816,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self, &mut self,
impl_def_id: DefId, impl_def_id: DefId,
obligation: &TraitObligation<'tcx>, obligation: &TraitObligation<'tcx>,
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> { ) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
@ -1872,11 +1858,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?; .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
nested_obligations.extend(obligations); nested_obligations.extend(obligations);
if let Err(e) = self.infcx.leak_check(false, snapshot) {
debug!("match_impl: failed leak check due to `{}`", e);
return Err(());
}
if !self.intercrate if !self.intercrate
&& self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation
{ {

View file

@ -7,7 +7,7 @@ pub trait TheTrait<T> {
} }
struct IntStruct { struct IntStruct {
x: isize x: isize,
} }
impl<'a> TheTrait<&'a isize> for IntStruct { impl<'a> TheTrait<&'a isize> for IntStruct {
@ -19,7 +19,7 @@ impl<'a> TheTrait<&'a isize> for IntStruct {
} }
struct UintStruct { struct UintStruct {
x: isize x: isize,
} }
impl<'a> TheTrait<&'a isize> for UintStruct { impl<'a> TheTrait<&'a isize> for UintStruct {
@ -30,8 +30,7 @@ impl<'a> TheTrait<&'a isize> for UintStruct {
} }
} }
struct Tuple { struct Tuple {}
}
impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple { impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
type A = &'a isize; type A = &'a isize;
@ -42,37 +41,43 @@ impl<'a> TheTrait<(&'a isize, &'a isize)> for Tuple {
} }
fn foo<T>() fn foo<T>()
where T : for<'x> TheTrait<&'x isize, A = &'x isize> where
T: for<'x> TheTrait<&'x isize, A = &'x isize>,
{ {
// ok for IntStruct, but not UintStruct // ok for IntStruct, but not UintStruct
} }
fn bar<T>() fn bar<T>()
where T : for<'x> TheTrait<&'x isize, A = &'x usize> where
T: for<'x> TheTrait<&'x isize, A = &'x usize>,
{ {
// ok for UintStruct, but not IntStruct // ok for UintStruct, but not IntStruct
} }
fn tuple_one<T>() fn tuple_one<T>()
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> where
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
{ {
// not ok for tuple, two lifetimes and we pick first // not ok for tuple, two lifetimes and we pick first
} }
fn tuple_two<T>() fn tuple_two<T>()
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize> where
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
{ {
// not ok for tuple, two lifetimes and we pick second // not ok for tuple, two lifetimes and we pick second
} }
fn tuple_three<T>() fn tuple_three<T>()
where T : for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize> where
T: for<'x> TheTrait<(&'x isize, &'x isize), A = &'x isize>,
{ {
// ok for tuple // ok for tuple
} }
fn tuple_four<T>() fn tuple_four<T>()
where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)> where
T: for<'x, 'y> TheTrait<(&'x isize, &'y isize)>,
{ {
// not ok for tuple, two lifetimes, and lifetime matching is invariant // not ok for tuple, two lifetimes, and lifetime matching is invariant
} }
@ -89,14 +94,12 @@ pub fn call_bar() {
pub fn call_tuple_one() { pub fn call_tuple_one() {
tuple_one::<Tuple>(); tuple_one::<Tuple>();
//~^ ERROR not satisfied //~^ ERROR type mismatch
//~| ERROR type mismatch
} }
pub fn call_tuple_two() { pub fn call_tuple_two() {
tuple_two::<Tuple>(); tuple_two::<Tuple>();
//~^ ERROR not satisfied //~^ ERROR type mismatch
//~| ERROR type mismatch
} }
pub fn call_tuple_three() { pub fn call_tuple_three() {
@ -105,7 +108,7 @@ pub fn call_tuple_three() {
pub fn call_tuple_four() { pub fn call_tuple_four() {
tuple_four::<Tuple>(); tuple_four::<Tuple>();
//~^ ERROR not satisfied //~^ ERROR implementation of `TheTrait` is not general enough
} }
fn main() { } fn main() {}

View file

@ -1,10 +1,11 @@
error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize` error[E0271]: type mismatch resolving `for<'x> <UintStruct as TheTrait<&'x isize>>::A == &'x isize`
--> $DIR/associated-types-eq-hr.rs:82:5 --> $DIR/associated-types-eq-hr.rs:87:5
| |
LL | fn foo<T>() LL | fn foo<T>()
| --- required by a bound in this | --- required by a bound in this
LL | where T : for<'x> TheTrait<&'x isize, A = &'x isize> LL | where
| ------------- required by this bound in `foo` LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>,
| ------------- required by this bound in `foo`
... ...
LL | foo::<UintStruct>(); LL | foo::<UintStruct>();
| ^^^^^^^^^^^^^^^^^ expected `isize`, found `usize` | ^^^^^^^^^^^^^^^^^ expected `isize`, found `usize`
@ -13,12 +14,13 @@ LL | foo::<UintStruct>();
found reference `&usize` found reference `&usize`
error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize` error[E0271]: type mismatch resolving `for<'x> <IntStruct as TheTrait<&'x isize>>::A == &'x usize`
--> $DIR/associated-types-eq-hr.rs:86:5 --> $DIR/associated-types-eq-hr.rs:91:5
| |
LL | fn bar<T>() LL | fn bar<T>()
| --- required by a bound in this | --- required by a bound in this
LL | where T : for<'x> TheTrait<&'x isize, A = &'x usize> LL | where
| ------------- required by this bound in `bar` LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>,
| ------------- required by this bound in `bar`
... ...
LL | bar::<IntStruct>(); LL | bar::<IntStruct>();
| ^^^^^^^^^^^^^^^^ expected `usize`, found `isize` | ^^^^^^^^^^^^^^^^ expected `usize`, found `isize`
@ -26,71 +28,46 @@ LL | bar::<IntStruct>();
= note: expected reference `&usize` = note: expected reference `&usize`
found reference `&isize` found reference `&isize`
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
--> $DIR/associated-types-eq-hr.rs:91:17
|
LL | fn tuple_one<T>()
| --------- required by a bound in this
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>
| ---------------------------------------------------------- required by this bound in `tuple_one`
...
LL | tuple_one::<Tuple>();
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
|
= help: the following implementations were found:
<Tuple as TheTrait<(&'a isize, &'a isize)>>
error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize` error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'x isize`
--> $DIR/associated-types-eq-hr.rs:91:5 --> $DIR/associated-types-eq-hr.rs:96:5
| |
LL | fn tuple_one<T>() LL | fn tuple_one<T>()
| --------- required by a bound in this | --------- required by a bound in this
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'x isize> LL | where
| ------------- required by this bound in `tuple_one` LL | T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'x isize>,
| ------------- required by this bound in `tuple_one`
... ...
LL | tuple_one::<Tuple>(); LL | tuple_one::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied
--> $DIR/associated-types-eq-hr.rs:97:17
|
LL | fn tuple_two<T>()
| --------- required by a bound in this
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
| ---------------------------------------------------------- required by this bound in `tuple_two`
...
LL | tuple_two::<Tuple>();
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple`
|
= help: the following implementations were found:
<Tuple as TheTrait<(&'a isize, &'a isize)>>
error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
--> $DIR/associated-types-eq-hr.rs:97:5
|
LL | fn tuple_two<T>()
| --------- required by a bound in this
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>
| ------------- required by this bound in `tuple_two`
...
LL | tuple_two::<Tuple>();
| ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'x, found concrete lifetime
error[E0277]: the trait bound `for<'x, 'y> Tuple: TheTrait<(&'x isize, &'y isize)>` is not satisfied error[E0271]: type mismatch resolving `for<'x, 'y> <Tuple as TheTrait<(&'x isize, &'y isize)>>::A == &'y isize`
--> $DIR/associated-types-eq-hr.rs:107:18 --> $DIR/associated-types-eq-hr.rs:101:5
| |
LL | fn tuple_four<T>() LL | fn tuple_two<T>()
| ---------- required by a bound in this | --------- required by a bound in this
LL | where T : for<'x,'y> TheTrait<(&'x isize, &'y isize)> LL | where
| ------------------------------------------- required by this bound in `tuple_four` LL | T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
| ------------- required by this bound in `tuple_two`
... ...
LL | tuple_four::<Tuple>(); LL | tuple_two::<Tuple>();
| ^^^^^ the trait `for<'x, 'y> TheTrait<(&'x isize, &'y isize)>` is not implemented for `Tuple` | ^^^^^^^^^^^^^^^^^^ expected bound lifetime parameter 'y, found concrete lifetime
error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:110:5
| |
= help: the following implementations were found: LL | / pub trait TheTrait<T> {
<Tuple as TheTrait<(&'a isize, &'a isize)>> LL | | type A;
LL | |
LL | | fn get(&self, t: T) -> Self::A;
LL | | }
| |_- trait `TheTrait` defined here
...
LL | tuple_four::<Tuple>();
| ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
|
= note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but `Tuple` actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: aborting due to 7 previous errors error: aborting due to 5 previous errors
Some errors have detailed explanations: E0271, E0277. For more information about this error, try `rustc --explain E0271`.
For more information about an error, try `rustc --explain E0271`.

View file

@ -1,17 +1,16 @@
error[E0277]: the trait bound `for<'a, 'b> SomeStruct: Foo<(&'a isize, &'b isize)>` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/hrtb-conflate-regions.rs:27:22 --> $DIR/hrtb-conflate-regions.rs:27:10
| |
LL | fn want_foo2<T>() LL | / trait Foo<X> {
| --------- required by a bound in this LL | | fn foo(&self, x: X) { }
LL | where T : for<'a,'b> Foo<(&'a isize, &'b isize)> LL | | }
| -------------------------------------- required by this bound in `want_foo2` | |_- trait `Foo` defined here
... ...
LL | fn b() { want_foo2::<SomeStruct>(); } LL | fn b() { want_foo2::<SomeStruct>(); }
| ^^^^^^^^^^ the trait `for<'a, 'b> Foo<(&'a isize, &'b isize)>` is not implemented for `SomeStruct` | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
<SomeStruct as Foo<(&'a isize, &'a isize)>> = note: ...but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, 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 E0277`.

View file

@ -32,5 +32,5 @@ fn main() {
// NB. *However*, the reinstated leak-check gives an error here. // NB. *However*, the reinstated leak-check gives an error here.
foo::<()>(); foo::<()>();
//~^ ERROR not satisfied //~^ ERROR implementation of `Trait` is not general enough
} }

View file

@ -1,18 +1,14 @@
error[E0277]: the trait bound `(): Trait<for<'b> fn(&'b u32)>` is not satisfied error: implementation of `Trait` is not general enough
--> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:11 --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
| |
LL | fn foo<T>() LL | trait Trait<T> {}
| --- required by a bound in this | ----------------- trait `Trait` defined here
LL | where
LL | T: Trait<for<'b> fn(&'b u32)>,
| -------------------------- required by this bound in `foo`
... ...
LL | foo::<()>(); LL | foo::<()>();
| ^^ the trait `Trait<for<'b> fn(&'b u32)>` is not implemented for `()` | ^^^^^^^^^ implementation of `Trait` is not general enough
| |
= help: the following implementations were found: = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
<() as Trait<fn(&'a u32)>> = note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -25,5 +25,5 @@ fn main() {
// yielding `fn(&!b u32)`, in a fresh universe U1 // yielding `fn(&!b u32)`, in a fresh universe U1
// - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`. // - So we get `?a = !b` but the universe U0 assigned to `?a` cannot name `!b`.
foo::<()>(); //~ ERROR not satisfied foo::<()>(); //~ ERROR implementation of `Trait` is not general enough
} }

View file

@ -1,18 +1,14 @@
error[E0277]: the trait bound `(): Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not satisfied error: implementation of `Trait` is not general enough
--> $DIR/hrtb-exists-forall-trait-invariant.rs:28:11 --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
| |
LL | fn foo<T>() LL | trait Trait<T> {}
| --- required by a bound in this | ----------------- trait `Trait` defined here
LL | where
LL | T: Trait<for<'b> fn(Cell<&'b u32>)>,
| -------------------------------- required by this bound in `foo`
... ...
LL | foo::<()>(); LL | foo::<()>();
| ^^ the trait `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>` is not implemented for `()` | ^^^^^^^^^ implementation of `Trait` is not general enough
| |
= help: the following implementations were found: = note: `()` must implement `Trait<for<'b> fn(std::cell::Cell<&'b u32>)>`
<() as Trait<fn(std::cell::Cell<&'a u32>)>> = note: ...but `()` actually implements `Trait<fn(std::cell::Cell<&'0 u32>)>`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -1,31 +1,30 @@
error[E0277]: the trait bound `for<'a> StaticInt: Foo<&'a isize>` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:24:17 --> $DIR/hrtb-just-for-static.rs:24:5
| |
LL | fn want_hrtb<T>() LL | / trait Foo<X> {
| --------- required by a bound in this LL | | fn foo(&self, x: X) { }
LL | where T : for<'a> Foo<&'a isize> LL | | }
| ---------------------- required by this bound in `want_hrtb` | |_- trait `Foo` defined here
... ...
LL | want_hrtb::<StaticInt>() LL | want_hrtb::<StaticInt>()
| ^^^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `StaticInt` | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
<StaticInt as Foo<&'static isize>> = note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1`
error[E0277]: the trait bound `for<'a> &'a u32: Foo<&'a isize>` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:30:17 --> $DIR/hrtb-just-for-static.rs:30:5
| |
LL | fn want_hrtb<T>() LL | / trait Foo<X> {
| --------- required by a bound in this LL | | fn foo(&self, x: X) { }
LL | where T : for<'a> Foo<&'a isize> LL | | }
| ---------------------- required by this bound in `want_hrtb` | |_- trait `Foo` defined here
... ...
LL | want_hrtb::<&'a u32>() LL | want_hrtb::<&'a u32>()
| ^^^^^^^ the trait `for<'a> Foo<&'a isize>` is not implemented for `&'a u32` | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0`...
<&'a u32 as Foo<&'a isize>> = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -28,15 +28,13 @@
// //
// holds because 'a can be instantiated to 'empty. // holds because 'a can be instantiated to 'empty.
trait Foo { trait Foo {}
} impl<A> Foo for fn(A) {}
impl<A> Foo for fn(A) { }
fn assert_foo<T: Foo>() {} fn assert_foo<T: Foo>() {}
fn main() { fn main() {
assert_foo::<fn(&i32)>(); assert_foo::<fn(&i32)>();
//~^ ERROR the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied //~^ ERROR implementation of `Foo` is not general enough
} }

View file

@ -1,15 +1,14 @@
error[E0277]: the trait bound `for<'r> fn(&'r i32): Foo` is not satisfied error: implementation of `Foo` is not general enough
--> $DIR/issue-46989.rs:40:18 --> $DIR/issue-46989.rs:38:5
| |
LL | fn assert_foo<T: Foo>() {} LL | trait Foo {}
| --- required by this bound in `assert_foo` | ------------ trait `Foo` defined here
... ...
LL | assert_foo::<fn(&i32)>(); LL | assert_foo::<fn(&i32)>();
| ^^^^^^^^ the trait `Foo` is not implemented for `for<'r> fn(&'r i32)` | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= help: the following implementations were found: = note: `Foo` would have to be implemented for the type `for<'r> fn(&'r i32)`
<fn(A) as Foo> = note: ...but `Foo` is actually implemented for the type `fn(&'0 i32)`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -4,6 +4,8 @@ error[E0599]: no function or associated item named `make_g` found for fn pointer
LL | let x = <fn (&())>::make_g(); LL | let x = <fn (&())>::make_g();
| ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())` | ^^^^^^ function or associated item not found in `for<'r> fn(&'r ())`
| |
= note: the method `make_g` exists but the following trait bounds were not satisfied:
`for<'r> fn(&'r ()): X`
= help: items from traits can only be used if the trait is implemented and in scope = help: items from traits can only be used if the trait is implemented and in scope
note: `X` defines an item `make_g`, perhaps you need to implement it note: `X` defines an item `make_g`, perhaps you need to implement it
--> $DIR/issue-57362-2.rs:8:1 --> $DIR/issue-57362-2.rs:8:1

View file

@ -14,9 +14,11 @@ impl Bar for &'static u32 {
} }
fn foo<T>(x: &T) fn foo<T>(x: &T)
where for<'a> &'a T: Bar where
{} for<'a> &'a T: Bar,
{
}
fn main() { fn main() {
foo(&X); //~ ERROR trait bound foo(&X); //~ ERROR implementation of `Bar` is not general enough
} }

View file

@ -1,17 +1,16 @@
error[E0277]: the trait bound `for<'a> &'a _: Bar` is not satisfied error: implementation of `Bar` is not general enough
--> $DIR/where-for-self-2.rs:21:5 --> $DIR/where-for-self-2.rs:23:5
| |
LL | fn foo<T>(x: &T) LL | / trait Bar {
| --- required by a bound in this LL | | fn bar(&self);
LL | where for<'a> &'a T: Bar LL | | }
| --- required by this bound in `foo` | |_- trait `Bar` defined here
... ...
LL | foo(&X); LL | foo(&X);
| ^^^ the trait `for<'a> Bar` is not implemented for `&'a _` | ^^^ implementation of `Bar` is not general enough
| |
= help: the following implementations were found: = note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
<&'static u32 as Bar> = note: ...but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.