1
Fork 0

Rollup merge of #81972 - matthewjasper:hrtb-error-cleanup, r=nikomatsakis

Placeholder lifetime error cleanup

- Remove note of trait definition
- Avoid repeating the same self type
- Use original region names when possible
- Use this error kind more often
- Print closure signatures when they are suppose to implement `Fn*` traits

Works towards #57374

r? ```@nikomatsakis```
This commit is contained in:
Dylan DPC 2021-02-17 23:51:18 +01:00 committed by GitHub
commit cdd93fd3e2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 283 additions and 451 deletions

View file

@ -43,7 +43,7 @@ impl<'cx, 'tcx> NiceRegionError<'cx, 'tcx> {
self.infcx.tcx self.infcx.tcx
} }
pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'cx>> { pub fn try_report_from_nll(&self) -> Option<DiagnosticBuilder<'tcx>> {
// Due to the improved diagnostics returned by the MIR borrow checker, only a subset of // Due to the improved diagnostics returned by the MIR borrow checker, only a subset of
// the nice region errors are required when running under the MIR borrow checker. // the nice region errors are required when running under the MIR borrow checker.
self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict()) self.try_report_named_anon_conflict().or_else(|| self.try_report_placeholder_conflict())

View file

@ -9,7 +9,7 @@ use rustc_middle::ty;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// When given a `ConcreteFailure` for a function with parameters containing a named region and /// When given a `ConcreteFailure` for a function with parameters containing a named region and
/// an anonymous region, emit an descriptive diagnostic error. /// an anonymous region, emit an descriptive diagnostic error.
pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'a>> { pub(super) fn try_report_named_anon_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
let (span, sub, sup) = self.regions()?; let (span, sub, sup) = self.regions()?;
debug!( debug!(

View file

@ -16,7 +16,7 @@ use std::fmt::{self, Write};
impl NiceRegionError<'me, 'tcx> { impl NiceRegionError<'me, 'tcx> {
/// When given a `ConcreteFailure` for a function with arguments containing a named region and /// When given a `ConcreteFailure` for a function with arguments containing a named region and
/// an anonymous region, emit a descriptive diagnostic error. /// an anonymous region, emit a descriptive diagnostic error.
pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'me>> { pub(super) fn try_report_placeholder_conflict(&self) -> Option<DiagnosticBuilder<'tcx>> {
match &self.error { match &self.error {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// NB. The ordering of cases in this match is very // NB. The ordering of cases in this match is very
@ -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), (!sup_region.has_name()).then_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), (!sub_region.has_name()).then_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
// | // |
@ -190,7 +186,8 @@ impl NiceRegionError<'me, 'tcx> {
// = note: Due to a where-clause on the function `all`, // = note: Due to a where-clause on the function `all`,
// = 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`.
fn try_report_placeholders_trait( #[instrument(level = "debug", skip(self))]
fn report_trait_placeholder_mismatch(
&self, &self,
vid: Option<ty::Region<'tcx>>, vid: Option<ty::Region<'tcx>>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
@ -199,28 +196,13 @@ impl NiceRegionError<'me, 'tcx> {
trait_def_id: DefId, trait_def_id: DefId,
expected_substs: SubstsRef<'tcx>, expected_substs: SubstsRef<'tcx>,
actual_substs: SubstsRef<'tcx>, actual_substs: SubstsRef<'tcx>,
) -> DiagnosticBuilder<'me> { ) -> DiagnosticBuilder<'tcx> {
debug!(
"try_report_placeholders_trait(\
vid={:?}, \
sub_placeholder={:?}, \
sup_placeholder={:?}, \
trait_def_id={:?}, \
expected_substs={:?}, \
actual_substs={:?})",
vid, sub_placeholder, sup_placeholder, trait_def_id, expected_substs, actual_substs
);
let span = cause.span(self.tcx()); let span = cause.span(self.tcx());
let msg = format!( let msg = format!(
"implementation of `{}` is not general enough", "implementation of `{}` is not general enough",
self.tcx().def_path_str(trait_def_id), self.tcx().def_path_str(trait_def_id),
); );
let mut err = self.tcx().sess.struct_span_err(span, &msg); let mut err = self.tcx().sess.struct_span_err(span, &msg);
err.span_label(
self.tcx().def_span(trait_def_id),
format!("trait `{}` defined here", self.tcx().def_path_str(trait_def_id)),
);
let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code { let leading_ellipsis = if let ObligationCauseCode::ItemObligation(def_id) = cause.code {
err.span_label(span, "doesn't satisfy where-clause"); err.span_label(span, "doesn't satisfy where-clause");
@ -285,17 +267,13 @@ impl NiceRegionError<'me, 'tcx> {
let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid; let any_self_ty_has_vid = actual_self_ty_has_vid || expected_self_ty_has_vid;
debug!("try_report_placeholders_trait: actual_has_vid={:?}", actual_has_vid);
debug!("try_report_placeholders_trait: expected_has_vid={:?}", expected_has_vid);
debug!("try_report_placeholders_trait: has_sub={:?}", has_sub);
debug!("try_report_placeholders_trait: has_sup={:?}", has_sup);
debug!( debug!(
"try_report_placeholders_trait: actual_self_ty_has_vid={:?}", ?actual_has_vid,
actual_self_ty_has_vid ?expected_has_vid,
); ?has_sub,
debug!( ?has_sup,
"try_report_placeholders_trait: expected_self_ty_has_vid={:?}", ?actual_self_ty_has_vid,
expected_self_ty_has_vid ?expected_self_ty_has_vid,
); );
self.explain_actual_impl_that_was_found( self.explain_actual_impl_that_was_found(
@ -388,6 +366,8 @@ impl NiceRegionError<'me, 'tcx> {
value: trait_ref, value: trait_ref,
}; };
let same_self_type = actual_trait_ref.self_ty() == expected_trait_ref.self_ty();
let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref); let mut expected_trait_ref = highlight_trait_ref(expected_trait_ref);
expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub); expected_trait_ref.highlight.maybe_highlighting_region(sub_placeholder, has_sub);
expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup); expected_trait_ref.highlight.maybe_highlighting_region(sup_placeholder, has_sup);
@ -403,7 +383,42 @@ impl NiceRegionError<'me, 'tcx> {
} }
}; };
let mut note = if passive_voice { let mut note = if same_self_type {
let mut self_ty = expected_trait_ref.map(|tr| tr.self_ty());
self_ty.highlight.maybe_highlighting_region(vid, actual_has_vid);
if self_ty.value.is_closure()
&& self
.tcx()
.fn_trait_kind_from_lang_item(expected_trait_ref.value.def_id)
.is_some()
{
let closure_sig = self_ty.map(|closure| {
if let ty::Closure(_, substs) = closure.kind() {
self.tcx().signature_unclosure(
substs.as_closure().sig(),
rustc_hir::Unsafety::Normal,
)
} else {
bug!("type is not longer closure");
}
});
format!(
"{}closure with signature `{}` must implement `{}`",
if leading_ellipsis { "..." } else { "" },
closure_sig,
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
} else {
format!(
"{}`{}` must implement `{}`",
if leading_ellipsis { "..." } else { "" },
self_ty,
expected_trait_ref.map(|tr| tr.print_only_trait_path()),
)
}
} else if passive_voice {
format!( format!(
"{}`{}` would have to be implemented for the type `{}`", "{}`{}` would have to be implemented for the type `{}`",
if leading_ellipsis { "..." } else { "" }, if leading_ellipsis { "..." } else { "" },
@ -449,7 +464,12 @@ impl NiceRegionError<'me, 'tcx> {
None => true, None => true,
}; };
let mut note = if passive_voice { let mut note = if same_self_type {
format!(
"...but it actually implements `{}`",
actual_trait_ref.map(|tr| tr.print_only_trait_path()),
)
} else if passive_voice {
format!( format!(
"...but `{}` is actually implemented for the type `{}`", "...but `{}` is actually implemented for the type `{}`",
actual_trait_ref.map(|tr| tr.print_only_trait_path()), actual_trait_ref.map(|tr| tr.print_only_trait_path()),

View file

@ -31,82 +31,47 @@ LL | bar::<IntStruct>();
error: implementation of `TheTrait` is not general enough error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:96:5 --> $DIR/associated-types-eq-hr.rs:96:5
| |
LL | / pub trait TheTrait<T> { LL | tuple_one::<Tuple>();
LL | | type A; | ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
LL | |
LL | | fn get(&self, t: T) -> Self::A;
LL | | }
| |_- trait `TheTrait` defined here
...
LL | tuple_one::<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: `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` = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:96:5 --> $DIR/associated-types-eq-hr.rs:96:5
| |
LL | / pub trait TheTrait<T> { LL | tuple_one::<Tuple>();
LL | | type A; | ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
LL | |
LL | | fn get(&self, t: T) -> Self::A;
LL | | }
| |_- trait `TheTrait` defined here
...
LL | tuple_one::<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: `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` = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:102:5 --> $DIR/associated-types-eq-hr.rs:102:5
| |
LL | / pub trait TheTrait<T> { LL | tuple_two::<Tuple>();
LL | | type A; | ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
LL | |
LL | | fn get(&self, t: T) -> Self::A;
LL | | }
| |_- trait `TheTrait` defined here
...
LL | tuple_two::<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: `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` = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:102:5 --> $DIR/associated-types-eq-hr.rs:102:5
| |
LL | / pub trait TheTrait<T> { LL | tuple_two::<Tuple>();
LL | | type A; | ^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
LL | |
LL | | fn get(&self, t: T) -> Self::A;
LL | | }
| |_- trait `TheTrait` defined here
...
LL | tuple_two::<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: `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` = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: implementation of `TheTrait` is not general enough error: implementation of `TheTrait` is not general enough
--> $DIR/associated-types-eq-hr.rs:112:5 --> $DIR/associated-types-eq-hr.rs:112:5
| |
LL | / pub trait TheTrait<T> { LL | tuple_four::<Tuple>();
LL | | type A; | ^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
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: `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` = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: aborting due to 7 previous errors error: aborting due to 7 previous errors

View file

@ -1,33 +1,24 @@
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:31:5 --> $DIR/auto-trait-regions.rs:31:5
| |
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen); LL | assert_foo(gen);
| ^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`... = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
= note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:31:5 --> $DIR/auto-trait-regions.rs:31:5
| |
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen); LL | assert_foo(gen);
| ^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo` would have to be implemented for the type `&'0 OnlyFooIfStaticRef`, for any lifetime `'0`... = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
= note: ...but `Foo` is actually implemented for the type `&'1 OnlyFooIfStaticRef`, for some specific lifetime `'1` = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:50:5 --> $DIR/auto-trait-regions.rs:50:5
| |
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen); LL | assert_foo(gen);
| ^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^ implementation of `Foo` is not general enough
| |
@ -37,9 +28,6 @@ LL | assert_foo(gen);
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/auto-trait-regions.rs:50:5 --> $DIR/auto-trait-regions.rs:50:5
| |
LL | auto trait Foo {}
| ----------------- trait `Foo` defined here
...
LL | assert_foo(gen); LL | assert_foo(gen);
| ^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^ implementation of `Foo` is not general enough
| |

View file

@ -3,9 +3,6 @@ error: implementation of `Foo` is not general enough
| |
LL | test::<FooS>(&mut 42); LL | test::<FooS>(&mut 42);
| ^^^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^^^ implementation of `Foo` is not general enough
...
LL | trait Foo<'a> {}
| ---------------- trait `Foo` defined here
| |
= note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`... = note: `FooS<'_>` must implement `Foo<'0>`, for any lifetime `'0`...
= note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1` = note: ...but `FooS<'_>` actually implements `Foo<'1>`, for some specific lifetime `'1`

View file

@ -1,9 +1,6 @@
error: implementation of `Deserialize` is not general enough error: implementation of `Deserialize` is not general enough
--> $DIR/hrtb-cache-issue-54302.rs:19:5 --> $DIR/hrtb-cache-issue-54302.rs:19:5
| |
LL | trait Deserialize<'de> {}
| ------------------------- trait `Deserialize` defined here
...
LL | assert_deserialize_owned::<&'static str>(); LL | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
| |

View file

@ -1,16 +1,11 @@
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/hrtb-conflate-regions.rs:27:10 --> $DIR/hrtb-conflate-regions.rs:27:10
| |
LL | / trait Foo<X> { LL | fn b() { want_foo2::<SomeStruct>(); }
LL | | fn foo(&self, x: X) { } | ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | fn b() { want_foo2::<SomeStruct>(); }
| ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`... = note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but `SomeStruct` actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2` = note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,14 +1,11 @@
error: implementation of `Trait` is not general enough error: implementation of `Trait` is not general enough
--> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5 --> $DIR/hrtb-exists-forall-trait-contravariant.rs:34:5
| |
LL | trait Trait<T> {}
| ----------------- trait `Trait` defined here
...
LL | foo::<()>(); LL | foo::<()>();
| ^^^^^^^^^ implementation of `Trait` is not general enough | ^^^^^^^^^ implementation of `Trait` is not general enough
| |
= note: `()` must implement `Trait<for<'b> fn(&'b u32)>` = note: `()` must implement `Trait<for<'b> fn(&'b u32)>`
= note: ...but `()` actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0` = note: ...but it actually implements `Trait<fn(&'0 u32)>`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,14 +1,11 @@
error: implementation of `Trait` is not general enough error: implementation of `Trait` is not general enough
--> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5 --> $DIR/hrtb-exists-forall-trait-invariant.rs:28:5
| |
LL | trait Trait<T> {}
| ----------------- trait `Trait` defined here
...
LL | foo::<()>(); LL | foo::<()>();
| ^^^^^^^^^ implementation of `Trait` is not general enough | ^^^^^^^^^ implementation of `Trait` is not general enough
| |
= note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>` = note: `()` must implement `Trait<for<'b> fn(Cell<&'b u32>)>`
= note: ...but `()` actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0` = note: ...but it actually implements `Trait<fn(Cell<&'0 u32>)>`, for some specific lifetime `'0`
error: aborting due to previous error error: aborting due to previous error

View file

@ -1,27 +1,17 @@
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:24:5 --> $DIR/hrtb-just-for-static.rs:24:5
| |
LL | / trait Foo<X> { LL | want_hrtb::<StaticInt>()
LL | | fn foo(&self, x: X) { } | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | want_hrtb::<StaticInt>()
| ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`... = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
= note: ...but `StaticInt` actually implements `Foo<&'1 isize>`, for some specific lifetime `'1` = note: ...but it actually implements `Foo<&'static isize>`
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/hrtb-just-for-static.rs:30:5 --> $DIR/hrtb-just-for-static.rs:30:5
| |
LL | / trait Foo<X> { LL | want_hrtb::<&'a u32>()
LL | | fn foo(&self, x: X) { } | ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | want_hrtb::<&'a u32>()
| ^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0`... = note: `Foo<&'0 isize>` would have to be implemented for the type `&'a u32`, for any lifetime `'0`...
= note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` = note: ...but `Foo<&'1 isize>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`

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<&'b isize>`
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<&'b isize>`
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,9 +1,6 @@
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/issue-46989.rs:38:5 --> $DIR/issue-46989.rs:38:5
| |
LL | trait Foo {}
| ------------ trait `Foo` defined here
...
LL | assert_foo::<fn(&i32)>(); LL | assert_foo::<fn(&i32)>();
| ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough | ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |

View file

@ -1,13 +1,8 @@
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:63:5 --> $DIR/issue-54302-cases.rs:63:5
| |
LL | / trait Foo<'x, T> { LL | <u32 as RefFoo<u32>>::ref_foo(a)
LL | | fn foo(self) -> &'x T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | <u32 as RefFoo<u32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`... = note: `Foo<'static, u32>` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`...
= note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` = note: ...but `Foo<'_, u32>` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1`
@ -15,13 +10,8 @@ LL | <u32 as RefFoo<u32>>::ref_foo(a)
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:69:5 --> $DIR/issue-54302-cases.rs:69:5
| |
LL | / trait Foo<'x, T> { LL | <i32 as RefFoo<i32>>::ref_foo(a)
LL | | fn foo(self) -> &'x T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | <i32 as RefFoo<i32>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`... = note: `Foo<'static, i32>` would have to be implemented for the type `&'0 i32`, for any lifetime `'0`...
= note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1` = note: ...but `Foo<'_, i32>` is actually implemented for the type `&'1 i32`, for some specific lifetime `'1`
@ -29,13 +19,8 @@ LL | <i32 as RefFoo<i32>>::ref_foo(a)
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:75:5 --> $DIR/issue-54302-cases.rs:75:5
| |
LL | / trait Foo<'x, T> { LL | <u64 as RefFoo<u64>>::ref_foo(a)
LL | | fn foo(self) -> &'x T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | <u64 as RefFoo<u64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`... = note: `Foo<'static, u64>` would have to be implemented for the type `&'0 u64`, for any lifetime `'0`...
= note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1` = note: ...but `Foo<'_, u64>` is actually implemented for the type `&'1 u64`, for some specific lifetime `'1`
@ -43,13 +28,8 @@ LL | <u64 as RefFoo<u64>>::ref_foo(a)
error: implementation of `Foo` is not general enough error: implementation of `Foo` is not general enough
--> $DIR/issue-54302-cases.rs:81:5 --> $DIR/issue-54302-cases.rs:81:5
| |
LL | / trait Foo<'x, T> { LL | <i64 as RefFoo<i64>>::ref_foo(a)
LL | | fn foo(self) -> &'x T; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
LL | | }
| |_- trait `Foo` defined here
...
LL | <i64 as RefFoo<i64>>::ref_foo(a)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
| |
= note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`... = note: `Foo<'static, i64>` would have to be implemented for the type `&'0 i64`, for any lifetime `'0`...
= note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1` = note: ...but `Foo<'_, i64>` is actually implemented for the type `&'1 i64`, for some specific lifetime `'1`

View file

@ -1,9 +1,6 @@
error: implementation of `Deserialize` is not general enough error: implementation of `Deserialize` is not general enough
--> $DIR/issue-54302.rs:13:5 --> $DIR/issue-54302.rs:13:5
| |
LL | trait Deserialize<'de> {}
| ------------------------- trait `Deserialize` defined here
...
LL | assert_deserialize_owned::<&'static str>(); LL | assert_deserialize_owned::<&'static str>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Deserialize` is not general enough
| |

View file

@ -1,13 +1,8 @@
error: implementation of `DistributedIteratorMulti` is not general enough error: implementation of `DistributedIteratorMulti` is not general enough
--> $DIR/issue-55731.rs:48:5 --> $DIR/issue-55731.rs:48:5
| |
LL | / trait DistributedIteratorMulti<Source> { LL | multi(Map {
LL | | type Item; | ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
LL | | }
| |_- trait `DistributedIteratorMulti` defined here
...
LL | multi(Map {
| ^^^^^ implementation of `DistributedIteratorMulti` is not general enough
| |
= note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`... = note: `DistributedIteratorMulti<&'0 ()>` would have to be implemented for the type `Cloned<&()>`, for any lifetime `'0`...
= note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1` = note: ...but `DistributedIteratorMulti<&'1 ()>` is actually implemented for the type `Cloned<&'1 ()>`, for some specific lifetime `'1`

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 with signature `fn(&'2 bool)` 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 with signature `fn(&'2 u32)` 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 &'a u32)` must implement `FnOnce<(*mut &'0 u32,)>`, for any lifetime `'0`...
found type `FnOnce<(*mut &'a u32,)>` = note: ...but it actually implements `FnOnce<(*mut &'a u32,)>`
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 &'a u32)` must implement `FnOnce<(*mut &'0 u32,)>`, for any lifetime `'0`...
found type `FnOnce<(*mut &'a u32,)>` = note: ...but it actually implements `FnOnce<(*mut &'a u32,)>`
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 with signature `fn(&'static X) -> &'static X` must implement `FnOnce<(&'0 X,)>`, for any lifetime `'0`...
found type `FnOnce<(&'static X,)>` = note: ...but it actually implements `FnOnce<(&'static X,)>`
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 with signature `fn(&'2 X) -> &X` 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 with signature `fn(&'2 X) -> &'2 X` 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 with signature `fn(&'2 X) -> &'2 X` 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`.

View file

@ -1,16 +1,11 @@
error: implementation of `Bar` is not general enough error: implementation of `Bar` is not general enough
--> $DIR/where-for-self-2.rs:23:5 --> $DIR/where-for-self-2.rs:23:5
| |
LL | / trait Bar { LL | foo(&X);
LL | | fn bar(&self); | ^^^ implementation of `Bar` is not general enough
LL | | }
| |_- trait `Bar` defined here
...
LL | foo(&X);
| ^^^ implementation of `Bar` is not general enough
| |
= note: `Bar` would have to be implemented for the type `&'0 u32`, for any lifetime `'0`... = note: `&'0 u32` must implement `Bar`, for any lifetime `'0`...
= note: ...but `Bar` is actually implemented for the type `&'1 u32`, for some specific lifetime `'1` = note: ...but `Bar` is actually implemented for the type `&'static u32`
error: aborting due to previous error error: aborting due to previous error