Auto merge of #119849 - lcnr:eagerly-instantiate-binders, r=compiler-errors

more eagerly instantiate binders

The old solver sometimes incorrectly used `sub`, change it to explicitly instantiate binders and use `eq` instead. While doing so I also moved the instantiation before the normalize calls. This caused some observable changes, will explain these inline. This PR therefore requires a crater run and an FCP.

r? types
This commit is contained in:
bors 2024-03-14 18:58:53 +00:00
commit fd27e8745f
56 changed files with 531 additions and 415 deletions

View File

@ -618,6 +618,7 @@ pub enum SelectionError<'tcx> {
OpaqueTypeAutoTraitLeakageUnknown(DefId),
}
// FIXME(@lcnr): The `Binder` here should be unnecessary. Just use `TraitRef` instead.
#[derive(Clone, Debug, TypeVisitable)]
pub struct SignatureMismatchData<'tcx> {
pub found_trait_ref: ty::PolyTraitRef<'tcx>,

View File

@ -3409,6 +3409,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.dcx().try_steal_replace_and_emit_err(self.tcx.def_span(def_id), StashKey::Cycle, err)
}
// FIXME(@lcnr): This function could be changed to trait `TraitRef` directly
// instead of using a `Binder`.
fn report_signature_mismatch_error(
&self,
obligation: &PredicateObligation<'tcx>,

View File

@ -165,7 +165,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate =
self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
debug!(?placeholder_trait_predicate);
// The bounds returned by `item_bounds` may contain duplicates after
// normalization, so try to deduplicate when possible to avoid
@ -184,8 +183,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
selcx.infcx.probe(|_| {
match selcx.match_normalize_trait_ref(
obligation,
bound.to_poly_trait_ref(),
placeholder_trait_predicate.trait_ref,
bound.to_poly_trait_ref(),
) {
Ok(None) => {
candidates.vec.push(ProjectionCandidate(idx));
@ -881,8 +880,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx.probe(|_| {
self.match_normalize_trait_ref(
obligation,
upcast_trait_ref,
placeholder_trait_predicate.trait_ref,
upcast_trait_ref,
)
.is_ok()
})

View File

@ -9,7 +9,7 @@
use rustc_ast::Mutability;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_hir::lang_items::LangItem;
use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::HigherRankedType;
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{BuiltinImplSource, SignatureMismatchData};
use rustc_middle::ty::{
@ -161,8 +161,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let placeholder_trait_predicate =
self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let candidate_predicate = self
.for_each_item_bound(
placeholder_self_ty,
@ -182,6 +180,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.expect("projection candidate is not a trait predicate")
.map_bound(|t| t.trait_ref);
let candidate = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
candidate,
);
let mut obligations = Vec::new();
let candidate = normalize_with_depth_to(
self,
@ -195,7 +198,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligations.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
.eq(DefineOpaqueTypes::No, placeholder_trait_predicate, candidate)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)?,
);
@ -499,7 +502,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
let ty::Dynamic(data, ..) = *self_ty.kind() else {
span_bug!(obligation.cause.span, "object candidate with non-object");
};
@ -520,19 +522,24 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let unnormalized_upcast_trait_ref =
supertraits.nth(index).expect("supertraits iterator no longer has as many elements");
let upcast_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
unnormalized_upcast_trait_ref,
);
let upcast_trait_ref = normalize_with_depth_to(
self,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth + 1,
unnormalized_upcast_trait_ref,
upcast_trait_ref,
&mut nested,
);
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, obligation_trait_ref, upcast_trait_ref)
.eq(DefineOpaqueTypes::No, trait_predicate.trait_ref, upcast_trait_ref)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)?,
);
@ -1021,7 +1028,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
self_ty_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
let obligation_trait_ref = obligation.predicate.to_poly_trait_ref();
let obligation_trait_ref =
self.infcx.enter_forall_and_leak_universe(obligation.predicate.to_poly_trait_ref());
let self_ty_trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
self_ty_trait_ref,
);
// Normalize the obligation and expected trait refs together, because why not
let Normalized { obligations: nested, value: (obligation_trait_ref, expected_trait_ref) } =
ensure_sufficient_stack(|| {
@ -1037,15 +1050,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// needed to define opaque types for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref)
.eq(DefineOpaqueTypes::Yes, obligation_trait_ref, expected_trait_ref)
.map(|InferOk { mut obligations, .. }| {
obligations.extend(nested);
obligations
})
.map_err(|terr| {
SignatureMismatch(Box::new(SignatureMismatchData {
expected_trait_ref: obligation_trait_ref,
found_trait_ref: expected_trait_ref,
expected_trait_ref: ty::Binder::dummy(obligation_trait_ref),
found_trait_ref: ty::Binder::dummy(expected_trait_ref),
terr,
}))
})

View File

@ -33,6 +33,7 @@ use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::BoundRegionConversionTime;
use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType;
use rustc_infer::infer::DefineOpaqueTypes;
use rustc_infer::traits::TraitObligation;
use rustc_middle::dep_graph::dep_kinds;
@ -42,7 +43,7 @@ use rustc_middle::ty::_match::MatchAgainstFreshVars;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::GenericArgsRef;
use rustc_middle::ty::{self, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate};
use rustc_middle::ty::{self, PolyProjectionPredicate, ToPredicate};
use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_span::symbol::sym;
use rustc_span::Symbol;
@ -1651,15 +1652,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn match_normalize_trait_ref(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
trait_bound: ty::PolyTraitRef<'tcx>,
placeholder_trait_ref: ty::TraitRef<'tcx>,
) -> Result<Option<ty::PolyTraitRef<'tcx>>, ()> {
trait_bound: ty::PolyTraitRef<'tcx>,
) -> Result<Option<ty::TraitRef<'tcx>>, ()> {
debug_assert!(!placeholder_trait_ref.has_escaping_bound_vars());
if placeholder_trait_ref.def_id != trait_bound.def_id() {
// Avoid unnecessary normalization
return Err(());
}
let trait_bound = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
trait_bound,
);
let Normalized { value: trait_bound, obligations: _ } = ensure_sufficient_stack(|| {
normalize_with_depth(
self,
@ -1671,7 +1677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
});
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, ty::Binder::dummy(placeholder_trait_ref), trait_bound)
.eq(DefineOpaqueTypes::No, placeholder_trait_ref, trait_bound)
.map(|InferOk { obligations: _, value: () }| {
// This method is called within a probe, so we can't have
// inference variables and placeholders escape.
@ -1683,7 +1689,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
})
.map_err(|_| ())
}
fn where_clause_may_apply<'o>(
&mut self,
stack: &TraitObligationStack<'o, 'tcx>,
@ -1733,7 +1738,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let is_match = self
.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, obligation.predicate, infer_projection)
.eq(DefineOpaqueTypes::No, obligation.predicate, infer_projection)
.is_ok_and(|InferOk { obligations, value: () }| {
self.evaluate_predicates_recursively(
TraitObligationStackList::empty(&ProvisionalEvaluationCache::default()),
@ -2533,7 +2538,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(
.eq(
DefineOpaqueTypes::No,
upcast_principal.map_bound(|trait_ref| {
ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
@ -2571,7 +2576,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
nested.extend(
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, source_projection, target_projection)
.eq(DefineOpaqueTypes::No, source_projection, target_projection)
.map_err(|_| SelectionError::Unimplemented)?
.into_obligations(),
);
@ -2615,9 +2620,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligation: &PolyTraitObligation<'tcx>,
poly_trait_ref: ty::PolyTraitRef<'tcx>,
) -> Result<Vec<PredicateObligation<'tcx>>, ()> {
let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
let trait_ref = self.infcx.instantiate_binder_with_fresh_vars(
obligation.cause.span,
HigherRankedType,
poly_trait_ref,
);
self.infcx
.at(&obligation.cause, obligation.param_env)
.sup(DefineOpaqueTypes::No, obligation.predicate.to_poly_trait_ref(), poly_trait_ref)
.eq(DefineOpaqueTypes::No, predicate.trait_ref, trait_ref)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| ())
}

View File

@ -320,6 +320,7 @@ fn vtable_entries<'tcx>(
}
/// Find slot base for trait methods within vtable entries of another trait
// FIXME(@lcnr): This isn't a query, so why does it take a tuple as its argument.
pub(super) fn vtable_trait_first_method_offset<'tcx>(
tcx: TyCtxt<'tcx>,
key: (

View File

@ -1107,7 +1107,6 @@
"ui/generic-associated-types/issue-92954.rs",
"ui/generic-associated-types/issue-93141.rs",
"ui/generic-associated-types/issue-93262.rs",
"ui/generic-associated-types/issue-93340.rs",
"ui/generic-associated-types/issue-93341.rs",
"ui/generic-associated-types/issue-93342.rs",
"ui/generic-associated-types/issue-93874.rs",

View File

@ -0,0 +1,24 @@
//@ check-pass
// We try to prove `T::Rigid: Into<?0>` and have 2 candidates from where-clauses:
//
// - `Into<String>`
// - `Into<<T::Rigid as Elaborate>::Assoc>`
//
// This causes ambiguity unless we normalize the alias in the second candidate
// to detect that they actually result in the same constraints.
trait Trait {
type Rigid: Elaborate<Assoc = String> + Into<String>;
}
trait Elaborate: Into<Self::Assoc> {
type Assoc;
}
fn impls<T: Into<U>, U>(_: T) {}
fn test<P: Trait>(rigid: P::Rigid) {
impls(rigid);
}
fn main() {}

View File

@ -0,0 +1,27 @@
// We try to prove `for<'b> T::Rigid: Bound<'b, ?0>` and have 2 candidates from where-clauses:
//
// - `for<'a> Bound<'a, String>`
// - `for<'a> Bound<'a, <T::Rigid as Elaborate>::Assoc>`
//
// This causes ambiguity unless we normalize the alias in the second candidate
// to detect that they actually result in the same constraints. We currently
// fail to detect that the constraints from these bounds are equal and error
// with ambiguity.
trait Bound<'a, U> {}
trait Trait {
type Rigid: Elaborate<Assoc = String> + for<'a> Bound<'a, String>;
}
trait Elaborate: for<'a> Bound<'a, Self::Assoc> {
type Assoc;
}
fn impls<T: for<'b> Bound<'b, U>, U>(_: T) {}
fn test<P: Trait>(rigid: P::Rigid) {
impls(rigid);
//~^ ERROR type annotations needed
}
fn main() {}

View File

@ -0,0 +1,20 @@
error[E0283]: type annotations needed
--> $DIR/dedup-normalized-2-higher-ranked.rs:23:5
|
LL | impls(rigid);
| ^^^^^ cannot infer type of the type parameter `U` declared on the function `impls`
|
= note: cannot satisfy `for<'b> <P as Trait>::Rigid: Bound<'b, _>`
note: required by a bound in `impls`
--> $DIR/dedup-normalized-2-higher-ranked.rs:20:13
|
LL | fn impls<T: for<'b> Bound<'b, U>, U>(_: T) {}
| ^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls`
help: consider specifying the generic arguments
|
LL | impls::<<P as Trait>::Rigid, U>(rigid);
| ++++++++++++++++++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -7,7 +7,7 @@ LL | #![feature(return_type_notation)]
= note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0308]: mismatched types
error: implementation of `Send` is not general enough
--> $DIR/issue-110963-early.rs:14:5
|
LL | / spawn(async move {
@ -16,17 +16,12 @@ LL | | if !hc.check().await {
LL | | log_health_check_failure().await;
LL | | }
LL | | });
| |______^ one type is more general than the other
| |______^ implementation of `Send` is not general enough
|
= note: expected trait `Send`
found trait `for<'a> Send`
note: the lifetime requirement is introduced here
--> $DIR/issue-110963-early.rs:34:17
|
LL | F: Future + Send + 'static,
| ^^^^
= note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`...
= note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `Send` is not general enough
--> $DIR/issue-110963-early.rs:14:5
|
LL | / spawn(async move {
@ -35,17 +30,11 @@ LL | | if !hc.check().await {
LL | | log_health_check_failure().await;
LL | | }
LL | | });
| |______^ one type is more general than the other
| |______^ implementation of `Send` is not general enough
|
= note: expected trait `Send`
found trait `for<'a> Send`
note: the lifetime requirement is introduced here
--> $DIR/issue-110963-early.rs:34:17
|
LL | F: Future + Send + 'static,
| ^^^^
= note: `Send` would have to be implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'0>() }`, for any two lifetimes `'0` and `'1`...
= note: ...but `Send` is actually implemented for the type `impl Future<Output = bool> { <HC as HealthCheck>::check<'2>() }`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0308`.

View File

@ -8,7 +8,7 @@ LL | foo(move |x| v);
| expected due to this
|
= note: expected closure signature `fn(_) -> _`
found closure signature `for<'a> fn(&'a _) -> _`
found closure signature `fn(&_) -> _`
note: closure inferred to have a different signature due to this bound
--> $DIR/multiple-fn-bounds.rs:1:11
|

View File

@ -13,5 +13,5 @@ fn main() {
*arg = true;
};
test(gen);
//~^ ERROR mismatched types
//~^ ERROR implementation of `Coroutine` is not general enough
}

View File

@ -1,17 +1,11 @@
error[E0308]: mismatched types
error: implementation of `Coroutine` is not general enough
--> $DIR/resume-arg-late-bound.rs:15:5
|
LL | test(gen);
| ^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^ implementation of `Coroutine` is not general enough
|
= note: expected trait `for<'a> Coroutine<&'a mut bool>`
found trait `Coroutine<&mut bool>`
note: the lifetime requirement is introduced here
--> $DIR/resume-arg-late-bound.rs:8:17
|
LL | fn test(a: impl for<'a> Coroutine<&'a mut bool>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: `{coroutine@$DIR/resume-arg-late-bound.rs:11:15: 11:31}` must implement `Coroutine<&'1 mut bool>`, for any lifetime `'1`...
= note: ...but it actually implements `Coroutine<&'2 mut bool>`, for some specific lifetime `'2`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,48 @@
error[E0283]: type annotations needed
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
LL | cmp_eq
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
|
= note: cannot satisfy `_: Scalar`
note: required by a bound in `cmp_eq`
--> $DIR/ambig-hr-projection-issue-93340.rs:9:22
|
LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
| ^^^^^^ required by this bound in `cmp_eq`
help: consider specifying the generic arguments
|
LL | cmp_eq::<A, B, O>
| +++++++++++
error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}`
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
LL | cmp_eq
| ^^^^^^
error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}`
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
LL | cmp_eq
| ^^^^^^
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0275]: overflow evaluating the requirement `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> _ {cmp_eq::<O, ..., ...>} <: ...`
--> $DIR/ambig-hr-projection-issue-93340.rs:14:51
|
LL | ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
| ___________________________________________________^
LL | |
LL | | cmp_eq
LL | |
LL | |
LL | |
LL | | }
| |_^
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0275, E0283.
For more information about an error, try `rustc --explain E0275`.

View File

@ -0,0 +1,20 @@
error[E0283]: type annotations needed
--> $DIR/ambig-hr-projection-issue-93340.rs:16:5
|
LL | cmp_eq
| ^^^^^^ cannot infer type of the type parameter `A` declared on the function `cmp_eq`
|
= note: cannot satisfy `_: Scalar`
note: required by a bound in `cmp_eq`
--> $DIR/ambig-hr-projection-issue-93340.rs:9:22
|
LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
| ^^^^^^ required by this bound in `cmp_eq`
help: consider specifying the generic arguments
|
LL | cmp_eq::<A, B, O>
| +++++++++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0283`.

View File

@ -0,0 +1,22 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
pub trait Scalar: 'static {
type RefType<'a>: ScalarRef<'a>;
}
pub trait ScalarRef<'a>: 'a {}
fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
todo!()
}
fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
//[next]~^ ERROR overflow evaluating the requirement
cmp_eq
//~^ ERROR type annotations needed
//[next]~| ERROR overflow evaluating the requirement
//[next]~| ERROR overflow evaluating the requirement
}
fn main() {}

View File

@ -1,26 +1,21 @@
error[E0631]: type mismatch in function arguments
error[E0283]: type annotations needed
--> $DIR/issue-88382.rs:26:40
|
LL | do_something(SomeImplementation(), test);
| ------------ ^^^^ expected due to this
| |
| required by a bound introduced by this call
...
| ^^^^ cannot infer type of the type parameter `I` declared on the function `test`
|
= note: cannot satisfy `_: Iterable`
= help: the trait `Iterable` is implemented for `SomeImplementation`
note: required by a bound in `test`
--> $DIR/issue-88382.rs:29:16
|
LL | fn test<'a, I: Iterable>(_: &mut I::Iterator<'a>) {}
| ------------------------------------------------- found signature defined here
| ^^^^^^^^ required by this bound in `test`
help: consider specifying the generic argument
|
= note: expected function signature `for<'a> fn(&'a mut std::iter::Empty<usize>) -> _`
found function signature `for<'a, 'b> fn(&'b mut <_ as Iterable>::Iterator<'a>) -> _`
note: required by a bound in `do_something`
--> $DIR/issue-88382.rs:20:48
|
LL | fn do_something<I: Iterable>(i: I, mut f: impl for<'a> Fn(&mut I::Iterator<'a>)) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `do_something`
help: consider wrapping the function in a closure
|
LL | do_something(SomeImplementation(), |arg0: &mut std::iter::Empty<usize>| test(/* &mut <_ as Iterable>::Iterator<'_> */));
| ++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++
LL | do_something(SomeImplementation(), test::<I>);
| +++++
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0631`.
For more information about this error, try `rustc --explain E0283`.

View File

@ -1,3 +1,5 @@
//@ revisions: old next
//@[next] compile-flags: -Znext-solver
//@ check-pass
pub trait Scalar: 'static {
@ -12,7 +14,7 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
cmp_eq
cmp_eq::<A, B, O>
}
fn main() {}

View File

@ -10,5 +10,5 @@ fn id(x: &String) -> &String {
fn main() {
assert_all::<_, &String>(id);
//~^ mismatched types
//~^ ERROR implementation of `FnMut` is not general enough
}

View File

@ -1,12 +1,11 @@
error[E0308]: mismatched types
error: implementation of `FnMut` is not general enough
--> $DIR/higher-ranked-lifetime-error.rs:12:5
|
LL | assert_all::<_, &String>(id);
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnMut` is not general enough
|
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
found trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
= note: `for<'a> fn(&'a String) -> &'a String {id}` must implement `FnMut<(&String,)>`
= note: ...but it actually implements `FnMut<(&'0 String,)>`, for some specific lifetime `'0`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -6,17 +6,17 @@
// an error, but the regression test is here to ensure
// that it does not ICE. See discussion on #74889 for details.
pub trait T {
pub trait Trait {
fn t<F: Fn()>(&self, _: F) {}
}
pub fn crash<V>(v: &V)
where
for<'a> &'a V: T + 'static,
for<'a> &'a V: Trait + 'static,
{
v.t(|| {});
//~^ ERROR: higher-ranked lifetime error
//~| ERROR: higher-ranked lifetime error
//~^ ERROR: implementation of `Trait` is not general enough
//~| ERROR: implementation of `Trait` is not general enough
//~| ERROR: higher-ranked lifetime error
}

View File

@ -1,18 +1,20 @@
error: higher-ranked lifetime error
error: implementation of `Trait` is not general enough
--> $DIR/issue-59311.rs:17:5
|
LL | v.t(|| {});
| ^^^^^^^^^^
| ^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed`
= note: `Trait` would have to be implemented for the type `&'a V`
= note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0`
error: higher-ranked lifetime error
error: implementation of `Trait` is not general enough
--> $DIR/issue-59311.rs:17:5
|
LL | v.t(|| {});
| ^^^^^^^^^^
| ^^^^^^^^^^ implementation of `Trait` is not general enough
|
= note: could not prove `{closure@$DIR/issue-59311.rs:17:9: 17:11} well-formed`
= note: `Trait` would have to be implemented for the type `&'a V`
= note: ...but `Trait` is actually implemented for the type `&'0 V`, for some specific lifetime `'0`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: higher-ranked lifetime error

View File

@ -43,9 +43,9 @@ fn main() {
}
foo(bar, "string", |s| s.len() == 5);
//~^ ERROR mismatched types
//~| ERROR mismatched types
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
foo(baz, "string", |s| s.0.len() == 5);
//~^ ERROR mismatched types
//~| ERROR mismatched types
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
}

View File

@ -1,79 +1,40 @@
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-71955.rs:45:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a &'b str)`
found trait `for<'a> FnOnce(&'a &str)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-71955.rs:45:24
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-71955.rs:25:9
|
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-71955.rs:45:5
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a &'b str)`
found trait `for<'a> FnOnce(&'a &str)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-71955.rs:45:24
|
LL | foo(bar, "string", |s| s.len() == 5);
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-71955.rs:25:44
|
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
| ^^^^
= note: closure with signature `for<'a> fn(&'a &'2 str) -> bool` must implement `FnOnce<(&&'1 str,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&&'2 str,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-71955.rs:48:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a Wrapper<'b>)`
found trait `for<'a> FnOnce(&'a Wrapper<'_>)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-71955.rs:48:24
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-71955.rs:25:9
|
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-71955.rs:48:5
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a Wrapper<'b>)`
found trait `for<'a> FnOnce(&'a Wrapper<'_>)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-71955.rs:48:24
|
LL | foo(baz, "string", |s| s.0.len() == 5);
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-71955.rs:25:44
|
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
| ^^^^
= note: closure with signature `for<'a> fn(&'a Wrapper<'2>) -> bool` must implement `FnOnce<(&Wrapper<'1>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&Wrapper<'2>,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -1,5 +1,6 @@
//@ check-pass
// Found in a crater run on #118553
// Related to Bevy regression #115559, found in
// a crater run on #118553.
pub trait QueryBase {
type Db;
@ -17,11 +18,17 @@ pub struct QueryTable<'me, Q, DB> {
_marker: Option<&'me ()>,
}
impl<'me, Q> QueryTable<'me, Q, <Q as QueryBase>::Db> // projection is important
// ^^^ removing 'me (and in QueryTable) gives a different error
impl<'me, Q> QueryTable<'me, Q, <Q as QueryBase>::Db>
where
Q: for<'f> AsyncQueryFunction<'f>,
{
// When borrowchechking this function we normalize `<Q as QueryBase>::Db` in the
// function signature to `<Self as QueryFunction<'?x>>::SendDb`, where `'?x` is an
// unconstrained region variable. We then addd `<Self as QueryFunction<'?x>>::SendDb: 'a`
// as an implied bound. We currently a structural equality to decide whether this bound
// should be used to prove the bound `<Self as QueryFunction<'?x>>::SendDb: 'a`. For this
// to work we may have to structurally resolve regions as the actually used vars may
// otherwise be semantically equal but structurally different.
pub fn get_async<'a>(&'a mut self) {
panic!();
}

View File

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

View File

@ -1,91 +1,21 @@
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-105675.rs:5:5
|
LL | thing(f);
| ^^^^^^^^ one type is more general than the other
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)`
found trait `for<'a> FnOnce(&u32, &'a u32, u32)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-105675.rs:4:13
|
LL | let f = | _ , y: &u32 , z | ();
| ^^^^^^^^^^^^^^^^^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-105675.rs:1:18
|
LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying the type of the closure parameters
|
LL | let f = |_: &_, y: &u32, z| ();
| ~~~~~~~~~~~~~~~~~~~
= note: closure with signature `for<'a> fn(&'2 u32, &'a u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-105675.rs:5:5
|
LL | thing(f);
| ^^^^^^^^ one type is more general than the other
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)`
found trait `for<'a> FnOnce(&u32, &'a u32, u32)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-105675.rs:4:13
|
LL | let f = | _ , y: &u32 , z | ();
| ^^^^^^^^^^^^^^^^^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-105675.rs:1:18
|
LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched types
--> $DIR/issue-105675.rs:9:5
|
LL | thing(f);
| ^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)`
found trait `FnOnce(&u32, &u32, u32)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-105675.rs:8:13
|
LL | let f = | x, y: _ , z: u32 | ();
| ^^^^^^^^^^^^^^^^^^^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-105675.rs:1:18
|
LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^
help: consider specifying the type of the closure parameters
|
LL | let f = |x: &_, y: &_, z: u32| ();
| ~~~~~~~~~~~~~~~~~~~~~~
error[E0308]: mismatched types
--> $DIR/issue-105675.rs:9:5
|
LL | thing(f);
| ^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a, 'b> FnOnce(&'a u32, &'b u32, u32)`
found trait `FnOnce(&u32, &u32, u32)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-105675.rs:8:13
|
LL | let f = | x, y: _ , z: u32 | ();
| ^^^^^^^^^^^^^^^^^^^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-105675.rs:1:18
|
LL | fn thing(x: impl FnOnce(&u32, &u32, u32)) {}
| ^^^^^^^^^^^^^^^^^^^^^^^
= note: closure with signature `for<'a> fn(&'2 u32, &'a u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider specifying the type of the closure parameters
|
LL | let f = |x: &_, y: &_, z: u32| ();
| ~~~~~~~~~~~~~~~~~~~~~~
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-105675.rs:9:5
@ -105,6 +35,25 @@ LL | thing(f);
= note: closure with signature `fn(&u32, &'2 u32, u32)` must implement `FnOnce<(&u32, &'1 u32, u32)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&u32, &'2 u32, u32)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-105675.rs:9:5
|
LL | thing(f);
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 u32, &u32, u32)` must implement `FnOnce<(&'1 u32, &u32, u32)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u32, &u32, u32)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-105675.rs:9:5
|
LL | thing(f);
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&u32, &'2 u32, u32)` must implement `FnOnce<(&u32, &'1 u32, u32)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&u32, &'2 u32, u32)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -7,7 +7,7 @@ fn take_foo(_: impl Foo) {}
fn main() {
take_foo(|a| a);
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types
//~| ERROR implementation of `Fn` is not general enough
take_foo(|a: &i32| a);
//~^ ERROR lifetime may not live long enough
//~| ERROR mismatched types

View File

@ -25,28 +25,14 @@ LL | take_foo(|a| a);
= note: closure with signature `fn(&'2 i32) -> &i32` must implement `FnOnce<(&'1 i32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 i32,)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/issue-79187-2.rs:8:5
|
LL | take_foo(|a| a);
| ^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a> Fn(&'a i32)`
found trait `Fn(&i32)`
note: this closure does not fulfill the lifetime requirements
--> $DIR/issue-79187-2.rs:8:14
|
LL | take_foo(|a| a);
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/issue-79187-2.rs:5:21
|
LL | fn take_foo(_: impl Foo) {}
| ^^^
help: consider specifying the type of the closure parameters
|
LL | take_foo(|a: &_| a);
| ~~~~~~~
= note: closure with signature `fn(&'2 i32) -> &i32` must implement `Fn<(&'1 i32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&'2 i32,)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
--> $DIR/issue-79187-2.rs:11:5

View File

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

View File

@ -1,26 +1,3 @@
error[E0308]: mismatched types
--> $DIR/issue-79187.rs:5:5
|
LL | thing(f);
| ^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> FnOnce(&'a u32)`
found trait `FnOnce(&u32)`
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)) {}
| ^^^^^^^^^^^^
help: consider specifying the type of the closure parameters
|
LL | let f = |_: &_| ();
| ~~~~~~~
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-79187.rs:5:5
|
@ -30,6 +7,15 @@ LL | thing(f);
= note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/issue-79187.rs:5:5
|
LL | thing(f);
| ^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 u32)` must implement `FnOnce<(&'1 u32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 u32,)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -13,6 +13,6 @@ fn g<T>(data: &[T]) {
//~^ ERROR the parameter type
//~| ERROR the parameter type
//~| ERROR the parameter type
//~| ERROR mismatched types
//~| ERROR implementation of `FnOnce` is not general
//~| ERROR implementation of `Fn` is not general enough
}

View File

@ -42,19 +42,14 @@ help: consider adding an explicit lifetime bound
LL | fn g<T: 'static>(data: &[T]) {
| +++++++++
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/issue_74400.rs:12:5
|
LL | f(data, identity)
| ^^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a> Fn(&'a T)`
found trait `Fn(&T)`
note: the lifetime requirement is introduced here
--> $DIR/issue_74400.rs:8:34
|
LL | fn f<T, S>(data: &[T], key: impl Fn(&T) -> S) {
| ^^^^^^^^^^^
= note: `fn(&'2 T) -> &'2 T {identity::<&'2 T>}` must implement `Fn<(&'1 T,)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&'2 T,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/issue_74400.rs:12:5
@ -67,5 +62,4 @@ LL | f(data, identity)
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0308, E0310.
For more information about an error, try `rustc --explain E0308`.
For more information about this error, try `rustc --explain E0310`.

View File

@ -24,7 +24,7 @@ LL | let _ = (-10..=10).find(|x: &&&i32| x.signum() == 0);
| expected due to this
|
= note: expected closure signature `for<'a> fn(&'a {integer}) -> _`
found closure signature `for<'a, 'b, 'c> fn(&'a &'b &'c i32) -> _`
found closure signature `fn(&&&i32) -> _`
note: required by a bound in `find`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider adjusting the signature so it does not borrow its argument

View File

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

View File

@ -24,7 +24,7 @@ LL | a.iter().map(|_: &(u16, u16)| 45);
| expected due to this
|
= note: expected closure signature `fn(&(u32, u32)) -> _`
found closure signature `for<'a> fn(&'a (u16, u16)) -> _`
found closure signature `fn(&(u16, u16)) -> _`
note: required by a bound in `map`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
@ -63,19 +63,14 @@ note: due to current limitations in the borrow checker, this implies a `'static`
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/closure-arg-type-mismatch.rs:10:5
|
LL | baz(f);
| ^^^^^^ one type is more general than the other
| ^^^^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a> Fn(*mut &'a u32)`
found trait `Fn(*mut &u32)`
note: the lifetime requirement is introduced here
--> $DIR/closure-arg-type-mismatch.rs:8:11
|
LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
| ^^^^^^^^^^^^^
= note: `fn(*mut &'2 u32)` must implement `Fn<(*mut &'1 u32,)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(*mut &'2 u32,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/closure-arg-type-mismatch.rs:10:5
@ -88,5 +83,5 @@ LL | baz(f);
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0308, E0521, E0631.
For more information about an error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0521, E0631.
For more information about an error, try `rustc --explain E0521`.

View File

@ -7,8 +7,8 @@ fn baz<T: Foo>(_: T) {}
fn main() {
baz(|_| ());
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types
//~| ERROR implementation of `Fn` is not general enough
baz(|x| ());
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR mismatched types
//~| ERROR implementation of `Fn` is not general enough
}

View File

@ -7,28 +7,14 @@ LL | baz(|_| ());
= note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/closure-mismatch.rs:8:5
|
LL | baz(|_| ());
| ^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a> Fn(&'a ())`
found trait `Fn(&())`
note: this closure does not fulfill the lifetime requirements
--> $DIR/closure-mismatch.rs:8:9
|
LL | baz(|_| ());
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/closure-mismatch.rs:5:11
|
LL | fn baz<T: Foo>(_: T) {}
| ^^^
help: consider specifying the type of the closure parameters
|
LL | baz(|_: &_| ());
| ~~~~~~~
= note: closure with signature `fn(&'2 ())` must implement `Fn<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/closure-mismatch.rs:11:5
@ -39,29 +25,14 @@ LL | baz(|x| ());
= note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/closure-mismatch.rs:11:5
|
LL | baz(|x| ());
| ^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a> Fn(&'a ())`
found trait `Fn(&())`
note: this closure does not fulfill the lifetime requirements
--> $DIR/closure-mismatch.rs:11:9
|
LL | baz(|x| ());
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/closure-mismatch.rs:5:11
|
LL | fn baz<T: Foo>(_: T) {}
| ^^^
help: consider specifying the type of the closure parameters
|
LL | baz(|x: &_| ());
| ~~~~~~~
= note: closure with signature `fn(&'2 ())` must implement `Fn<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&'2 (),)>`, for some specific lifetime `'2`
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -10,7 +10,7 @@ LL | apply(&3, takes_mut);
| required by a bound introduced by this call
|
= note: expected function signature `fn(&{integer}) -> _`
found function signature `for<'a> fn(&'a mut isize) -> _`
found function signature `fn(&mut isize) -> _`
note: required by a bound in `apply`
--> $DIR/fn-variance-1.rs:5:37
|
@ -33,7 +33,7 @@ LL | apply(&mut 3, takes_imm);
| required by a bound introduced by this call
|
= note: expected function signature `fn(&mut {integer}) -> _`
found function signature `for<'a> fn(&'a isize) -> _`
found function signature `fn(&isize) -> _`
note: required by a bound in `apply`
--> $DIR/fn-variance-1.rs:5:37
|

View File

@ -7,7 +7,7 @@ LL | once::<&str>("str").fuse().filter(|a: &str| true).count();
| expected due to this
|
= note: expected closure signature `for<'a> fn(&'a &_) -> _`
found closure signature `for<'a> fn(&'a _) -> _`
found closure signature `fn(&_) -> _`
note: required by a bound in `filter`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
help: consider adjusting the signature so it borrows its argument

View File

@ -10,7 +10,7 @@ LL | let _has_inference_vars: Option<i32> = Some(0).map(deref_int);
| required by a bound introduced by this call
|
= note: expected function signature `fn({integer}) -> _`
found function signature `for<'a> fn(&'a i32) -> _`
found function signature `fn(&i32) -> _`
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure

View File

@ -10,7 +10,7 @@ LL | let _ = produces_string().and_then(takes_str_but_too_many_refs);
| required by a bound introduced by this call
|
= note: expected function signature `fn(String) -> _`
found function signature `for<'a, 'b> fn(&'a &'b str) -> _`
found function signature `fn(&&str) -> _`
note: required by a bound in `Option::<T>::and_then`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure
@ -69,7 +69,7 @@ LL | let _ = Some(TypeWithoutDeref).and_then(takes_str_but_too_many_refs);
| required by a bound introduced by this call
|
= note: expected function signature `fn(TypeWithoutDeref) -> _`
found function signature `for<'a, 'b> fn(&'a &'b str) -> _`
found function signature `fn(&&str) -> _`
note: required by a bound in `Option::<T>::and_then`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure

View File

@ -10,7 +10,7 @@ LL | let _: Option<()> = produces_string().and_then(takes_str);
| required by a bound introduced by this call
|
= note: expected function signature `fn(String) -> _`
found function signature `for<'a> fn(&'a str) -> _`
found function signature `fn(&str) -> _`
note: required by a bound in `Option::<T>::and_then`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure
@ -34,7 +34,7 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str);
| required by a bound introduced by this call
|
= note: expected function signature `fn(String) -> _`
found function signature `for<'a> fn(&'a str) -> _`
found function signature `fn(&str) -> _`
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure
@ -58,7 +58,7 @@ LL | let _: Option<Option<()>> = produces_string().map(takes_str_mut);
| required by a bound introduced by this call
|
= note: expected function signature `fn(String) -> _`
found function signature `for<'a> fn(&'a mut str) -> _`
found function signature `fn(&mut str) -> _`
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure
@ -82,7 +82,7 @@ LL | let _ = produces_string().and_then(generic_ref);
| required by a bound introduced by this call
|
= note: expected function signature `fn(String) -> _`
found function signature `for<'a> fn(&'a _) -> _`
found function signature `fn(&_) -> _`
note: required by a bound in `Option::<T>::and_then`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure

View File

@ -31,8 +31,8 @@ fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> {
fn main() {
let callback = |_| {};
accept(callback);
//~^ ERROR mismatched types
//~| ERROR mismatched types
//~^ ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR higher-ranked subtype error

View File

@ -1,26 +1,3 @@
error[E0308]: mismatched types
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
|
LL | accept(callback);
| ^^^^^^^^^^^^^^^^ one type is more general than the other
|
= note: expected trait `for<'a> FnOnce(&'a ())`
found trait `FnOnce(&())`
note: this closure does not fulfill the lifetime requirements
--> $DIR/missing-universe-cause-issue-114907.rs:32:20
|
LL | let callback = |_| {};
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/missing-universe-cause-issue-114907.rs:27:14
|
LL | fn accept<C: FnOnce(&())>(_: C) -> Handshake<HandshakeCallback<C>> {
| ^^^^^^^^^^^
help: consider specifying the type of the closure parameters
|
LL | let callback = |_: &_| {};
| ~~~~~~~
error: implementation of `FnOnce` is not general enough
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
|
@ -40,28 +17,25 @@ LL | accept(callback);
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0308]: mismatched types
error: implementation of `FnOnce` is not general enough
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
|
LL | accept(callback);
| ^^^^^^^^^^^^^^^^ one type is more general than the other
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: expected trait `for<'a> FnOnce(&'a ())`
found trait `FnOnce(&())`
note: this closure does not fulfill the lifetime requirements
--> $DIR/missing-universe-cause-issue-114907.rs:32:20
= note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: implementation of `FnOnce` is not general enough
--> $DIR/missing-universe-cause-issue-114907.rs:33:5
|
LL | let callback = |_| {};
| ^^^
note: the lifetime requirement is introduced here
--> $DIR/missing-universe-cause-issue-114907.rs:20:21
LL | accept(callback);
| ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
LL | struct Handshake<R: Role> {
| ^^^^
help: consider specifying the type of the closure parameters
|
LL | let callback = |_: &_| {};
| ~~~~~~~
= note: closure with signature `fn(&'2 ())` must implement `FnOnce<(&'1 (),)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 (),)>`, for some specific lifetime `'2`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: higher-ranked subtype error
--> $DIR/missing-universe-cause-issue-114907.rs:33:21
@ -79,4 +53,3 @@ LL | accept(callback);
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -26,8 +26,8 @@ static SOME_STRUCT: &SomeStruct = &SomeStruct {
foo: &Foo { bools: &[false, true] },
bar: &Bar { bools: &[true, true] },
f: &id,
//~^ ERROR mismatched types
//~| ERROR mismatched types
//~^ ERROR implementation of `Fn` is not general enough
//~| ERROR implementation of `Fn` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
//~| ERROR implementation of `FnOnce` is not general enough
};

View File

@ -1,21 +1,20 @@
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ one type is more general than the other
| ^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a, 'b> Fn(&'a Foo<'b>)`
found trait `Fn(&Foo<'_>)`
= note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `Fn<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
error[E0308]: mismatched types
error: implementation of `Fn` is not general enough
--> $DIR/rfc1623-2.rs:28:8
|
LL | f: &id,
| ^^^ one type is more general than the other
| ^^^ implementation of `Fn` is not general enough
|
= note: expected trait `for<'a, 'b> Fn(&'a Foo<'b>)`
found trait `Fn(&Foo<'_>)`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
= note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `Fn<(&'a Foo<'1>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `Fn<(&Foo<'2>,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough
--> $DIR/rfc1623-2.rs:28:8
@ -37,4 +36,3 @@ LL | f: &id,
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -10,7 +10,7 @@ LL | trader.set_closure(closure);
| required by a bound introduced by this call
|
= note: expected closure signature `for<'a, 'b> fn(&'a mut Trader<'b>) -> _`
found closure signature `for<'a> fn(Trader<'a>) -> _`
found closure signature `fn(Trader<'_>) -> _`
note: required by a bound in `Trader::<'a>::set_closure`
--> $DIR/late-bound-in-borrow-closure-sugg.rs:15:50
|

View File

@ -0,0 +1,22 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
found existential trait ref `for<'a> Supertrait<'a, 'a>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ok.rs:17:5
|
LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
| ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
LL | x
| ^ expected trait `Supertrait`, found trait `Subtrait`
|
= note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,19 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// We should be able to instantiate a binder during trait upcasting.
// This test could be `check-pass`, but we should make sure that we
// do so in both trait solvers.
#![feature(trait_upcasting)]
#![crate_type = "rlib"]
trait Supertrait<'a, 'b> {}
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
impl<'a> Supertrait<'a, 'a> for () {}
impl<'a> Subtrait<'a, 'a> for () {}
fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
x //~ ERROR mismatched types
//[current]~^ ERROR mismatched types
}

View File

@ -0,0 +1,22 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | x
| ^ one type is more general than the other
|
= note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/higher-ranked-upcasting-ub.rs:22:5
|
LL | fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
| ----------------------------------- expected `&dyn for<'a, 'b> Supertrait<'a, 'b>` because of return type
LL | x
| ^ expected trait `Supertrait`, found trait `Subtrait`
|
= note: expected reference `&dyn for<'a, 'b> Supertrait<'a, 'b>`
found reference `&dyn for<'a> Subtrait<'a, 'a>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -0,0 +1,37 @@
//@ revisions: current next
//@ ignore-compare-mode-next-solver (explicit revisions)
//@[next] compile-flags: -Znext-solver
// We previously wrongly instantiated binders during trait upcasting,
// allowing the super trait to be more generic than the sub trait.
// This was unsound.
#![feature(trait_upcasting)]
trait Supertrait<'a, 'b> {
fn cast(&self, x: &'a str) -> &'b str;
}
trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
impl<'a> Supertrait<'a, 'a> for () {
fn cast(&self, x: &'a str) -> &'a str {
x
}
}
impl<'a> Subtrait<'a, 'a> for () {}
fn unsound(x: &dyn for<'a> Subtrait<'a, 'a>) -> &dyn for<'a, 'b> Supertrait<'a, 'b> {
x //~ ERROR mismatched types
//[current]~^ ERROR mismatched types
}
fn transmute<'a, 'b>(x: &'a str) -> &'b str {
unsound(&()).cast(x)
}
fn main() {
let x;
{
let mut temp = String::from("hello there");
x = transmute(temp.as_str());
}
println!("{x}");
}

View File

@ -27,7 +27,7 @@ LL | self.map(Insertable::values).unwrap_or_default()
| required by a bound introduced by this call
|
= note: expected function signature `fn(T) -> _`
found function signature `for<'a> fn(&'a _) -> _`
found function signature `fn(&_) -> _`
note: required by a bound in `Option::<T>::map`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider wrapping the function in a closure