Try to normalize associated types before processing obligations
This commit is contained in:
parent
03918badd3
commit
e5f22ff0fb
20 changed files with 362 additions and 215 deletions
|
@ -346,6 +346,8 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
|
||||
let obligation = &mut pending_obligation.obligation;
|
||||
|
||||
debug!(?obligation, "process_obligation pre-resolve");
|
||||
|
||||
if obligation.predicate.has_infer_types_or_consts() {
|
||||
obligation.predicate =
|
||||
self.selcx.infcx().resolve_vars_if_possible(obligation.predicate);
|
||||
|
@ -355,6 +357,21 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
|
||||
let infcx = self.selcx.infcx();
|
||||
|
||||
if obligation.predicate.has_projections() {
|
||||
let mut obligations = Vec::new();
|
||||
let predicate = crate::traits::project::try_normalize_with_depth_to(
|
||||
self.selcx,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.predicate,
|
||||
&mut obligations,
|
||||
);
|
||||
if predicate != obligation.predicate {
|
||||
obligations.push(obligation.with(predicate));
|
||||
return ProcessResult::Changed(mk_pending(obligations));
|
||||
}
|
||||
}
|
||||
let binder = obligation.predicate.kind();
|
||||
match binder.no_bound_vars() {
|
||||
None => match binder.skip_binder() {
|
||||
|
|
|
@ -295,6 +295,32 @@ where
|
|||
result
|
||||
}
|
||||
|
||||
#[instrument(level = "info", skip(selcx, param_env, cause, obligations))]
|
||||
pub fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
value: T,
|
||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
debug!(obligations.len = obligations.len());
|
||||
let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement(
|
||||
selcx,
|
||||
param_env,
|
||||
cause,
|
||||
depth,
|
||||
obligations,
|
||||
);
|
||||
let result = ensure_sufficient_stack(|| normalizer.fold(value));
|
||||
debug!(?result, obligations.len = normalizer.obligations.len());
|
||||
debug!(?normalizer.obligations,);
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn needs_normalization<'tcx, T: TypeFoldable<'tcx>>(value: &T, reveal: Reveal) -> bool {
|
||||
match reveal {
|
||||
Reveal::UserFacing => value
|
||||
|
@ -314,6 +340,10 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
||||
depth: usize,
|
||||
universes: Vec<Option<ty::UniverseIndex>>,
|
||||
/// If true, when a projection is unable to be completed, an inference
|
||||
/// variable will be created and an obligation registered to project to that
|
||||
/// inference variable. Also, constants will be eagerly evaluated.
|
||||
eager_inference_replacement: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
|
@ -324,7 +354,33 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
depth: usize,
|
||||
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
||||
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes: vec![] }
|
||||
AssocTypeNormalizer {
|
||||
selcx,
|
||||
param_env,
|
||||
cause,
|
||||
obligations,
|
||||
depth,
|
||||
universes: vec![],
|
||||
eager_inference_replacement: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_without_eager_inference_replacement(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: usize,
|
||||
obligations: &'a mut Vec<PredicateObligation<'tcx>>,
|
||||
) -> AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
AssocTypeNormalizer {
|
||||
selcx,
|
||||
param_env,
|
||||
cause,
|
||||
obligations,
|
||||
depth,
|
||||
universes: vec![],
|
||||
eager_inference_replacement: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T {
|
||||
|
@ -428,14 +484,28 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
// there won't be bound vars there.
|
||||
|
||||
let data = data.super_fold_with(self);
|
||||
let normalized_ty = normalize_projection_type(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause.clone(),
|
||||
self.depth,
|
||||
&mut self.obligations,
|
||||
);
|
||||
let normalized_ty = if self.eager_inference_replacement {
|
||||
normalize_projection_type(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause.clone(),
|
||||
self.depth,
|
||||
&mut self.obligations,
|
||||
)
|
||||
} else {
|
||||
opt_normalize_projection_type(
|
||||
self.selcx,
|
||||
self.param_env,
|
||||
data,
|
||||
self.cause.clone(),
|
||||
self.depth,
|
||||
&mut self.obligations,
|
||||
)
|
||||
.ok()
|
||||
.flatten()
|
||||
.unwrap_or_else(|| ty::Term::Ty(ty.super_fold_with(self)))
|
||||
};
|
||||
debug!(
|
||||
?self.depth,
|
||||
?ty,
|
||||
|
@ -501,7 +571,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
|
||||
if self.selcx.tcx().lazy_normalization() {
|
||||
if self.selcx.tcx().lazy_normalization() || !self.eager_inference_replacement {
|
||||
constant
|
||||
} else {
|
||||
let constant = constant.super_fold_with(self);
|
||||
|
|
|
@ -15,9 +15,9 @@ pub trait ThriftService<Bug: NotFoo>:
|
|||
{
|
||||
fn get_service(
|
||||
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
|
||||
//~| ERROR the trait bound `Bug: Foo` is not satisfied
|
||||
&self,
|
||||
) -> Self::AssocType;
|
||||
//~^ the trait bound `Bug: Foo` is not satisfied
|
||||
}
|
||||
|
||||
fn with_factory<H>(factory: dyn ThriftService<()>) {}
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | |
|
|||
LL | |
|
||||
LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
|
||||
... |
|
||||
LL | | ) -> Self::AssocType;
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^ the trait `Foo` is not implemented for `Bug`
|
||||
|
|
||||
|
@ -23,7 +23,7 @@ LL | |
|
|||
LL | |
|
||||
LL | | Service<AssocType = <Bug as Foo>::OnlyFoo>
|
||||
... |
|
||||
LL | | ) -> Self::AssocType;
|
||||
LL | |
|
||||
LL | | }
|
||||
| |_^ the trait `Foo` is not implemented for `Bug`
|
||||
|
|
||||
|
@ -37,7 +37,6 @@ error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
|||
|
|
||||
LL | / fn get_service(
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | &self,
|
||||
LL | | ) -> Self::AssocType;
|
||||
| |_________________________^ the trait `Foo` is not implemented for `Bug`
|
||||
|
@ -48,10 +47,10 @@ LL | pub trait ThriftService<Bug: NotFoo + Foo>:
|
|||
| +++++
|
||||
|
||||
error[E0277]: the trait bound `Bug: Foo` is not satisfied
|
||||
--> $DIR/issue-59324.rs:16:8
|
||||
--> $DIR/issue-59324.rs:19:10
|
||||
|
|
||||
LL | fn get_service(
|
||||
| ^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
||||
LL | ) -> Self::AssocType;
|
||||
| ^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `Bug`
|
||||
|
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
|
|
38
src/test/ui/generic-associated-types/issue-90729.rs
Normal file
38
src/test/ui/generic-associated-types/issue-90729.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait Type {
|
||||
type Ref<'a>;
|
||||
}
|
||||
|
||||
pub trait AsBytes {}
|
||||
|
||||
impl AsBytes for &str {}
|
||||
|
||||
pub struct Utf8;
|
||||
|
||||
impl Type for Utf8 {
|
||||
type Ref<'a> = &'a str;
|
||||
}
|
||||
|
||||
pub struct Bytes<T: Type> {
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Type> Bytes<T>
|
||||
where
|
||||
for<'a> T::Ref<'a>: AsBytes,
|
||||
{
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _b = Bytes::<Utf8>::new();
|
||||
}
|
55
src/test/ui/generic-associated-types/issue-93341.rs
Normal file
55
src/test/ui/generic-associated-types/issue-93341.rs
Normal file
|
@ -0,0 +1,55 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct Id<'id>(PhantomData<fn(&'id ()) -> &'id ()>);
|
||||
|
||||
fn new_id() -> Id<'static> {
|
||||
Id(PhantomData)
|
||||
}
|
||||
|
||||
pub trait HasLifetime where {
|
||||
type AtLifetime<'a>;
|
||||
}
|
||||
|
||||
pub struct ExistentialLifetime<S: HasLifetime>(S::AtLifetime<'static>);
|
||||
|
||||
impl<S: HasLifetime> ExistentialLifetime<S> {
|
||||
pub fn new<F>(f: F) -> ExistentialLifetime<S>
|
||||
where for<'id> F: FnOnce(Id<'id>) -> S::AtLifetime<'id> {
|
||||
ExistentialLifetime(f(new_id()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct ExampleS<'id>(Id<'id>);
|
||||
|
||||
struct ExampleMarker;
|
||||
|
||||
impl HasLifetime for ExampleMarker {
|
||||
type AtLifetime<'id> = ExampleS<'id>;
|
||||
}
|
||||
|
||||
|
||||
fn broken0() -> ExistentialLifetime<ExampleMarker> {
|
||||
fn new_helper<'id>(id: Id<'id>) -> ExampleS<'id> {
|
||||
ExampleS(id)
|
||||
}
|
||||
|
||||
ExistentialLifetime::<ExampleMarker>::new(new_helper)
|
||||
}
|
||||
|
||||
fn broken1() -> ExistentialLifetime<ExampleMarker> {
|
||||
fn new_helper<'id>(id: Id<'id>) -> <ExampleMarker as HasLifetime>::AtLifetime<'id> {
|
||||
ExampleS(id)
|
||||
}
|
||||
|
||||
ExistentialLifetime::<ExampleMarker>::new(new_helper)
|
||||
}
|
||||
|
||||
fn broken2() -> ExistentialLifetime<ExampleMarker> {
|
||||
ExistentialLifetime::<ExampleMarker>::new(|id| ExampleS(id))
|
||||
}
|
||||
|
||||
fn main() {}
|
57
src/test/ui/generic-associated-types/issue-93342.rs
Normal file
57
src/test/ui/generic-associated-types/issue-93342.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(generic_associated_types)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait Scalar: 'static {
|
||||
type RefType<'a>: ScalarRef<'a>;
|
||||
}
|
||||
|
||||
pub trait ScalarRef<'a>: 'a {}
|
||||
|
||||
impl Scalar for i32 {
|
||||
type RefType<'a> = i32;
|
||||
}
|
||||
|
||||
impl Scalar for String {
|
||||
type RefType<'a> = &'a str;
|
||||
}
|
||||
|
||||
impl Scalar for bool {
|
||||
type RefType<'a> = i32;
|
||||
}
|
||||
|
||||
impl<'a> ScalarRef<'a> for bool {}
|
||||
|
||||
impl<'a> ScalarRef<'a> for i32 {}
|
||||
|
||||
impl<'a> ScalarRef<'a> for &'a str {}
|
||||
|
||||
fn str_contains(a: &str, b: &str) -> bool {
|
||||
a.contains(b)
|
||||
}
|
||||
|
||||
pub struct BinaryExpression<A: Scalar, B: Scalar, O: Scalar, F>
|
||||
where
|
||||
F: Fn(A::RefType<'_>, B::RefType<'_>) -> O,
|
||||
{
|
||||
f: F,
|
||||
_phantom: PhantomData<(A, B, O)>,
|
||||
}
|
||||
|
||||
impl<A: Scalar, B: Scalar, O: Scalar, F> BinaryExpression<A, B, O, F>
|
||||
where
|
||||
F: Fn(A::RefType<'_>, B::RefType<'_>) -> O,
|
||||
{
|
||||
pub fn new(f: F) -> Self {
|
||||
Self {
|
||||
f,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
BinaryExpression::<String, String, bool, _>::new(str_contains);
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
// check-pass
|
||||
|
||||
// FamilyType (GAT workaround)
|
||||
pub trait FamilyLt<'a> {
|
||||
type Out;
|
||||
|
@ -78,8 +80,6 @@ where P: Execute + 'static {
|
|||
|
||||
fn main() {
|
||||
task(annotate(
|
||||
//~^ the size
|
||||
//~^^ the trait bound
|
||||
Annotate::<RefMutFamily<usize>>::new(),
|
||||
|value: &mut usize| {
|
||||
*value = 2;
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
|
||||
--> $DIR/issue-62529-1.rs:80:10
|
||||
|
|
||||
LL | task(annotate(
|
||||
| _____----_^
|
||||
| | |
|
||||
| | required by a bound introduced by this call
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | Annotate::<RefMutFamily<usize>>::new(),
|
||||
... |
|
||||
LL | | }
|
||||
LL | | ));
|
||||
| |_____^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `impl Execute`
|
||||
note: required by a bound in `task`
|
||||
--> $DIR/issue-62529-1.rs:69:9
|
||||
|
|
||||
LL | fn task<P>(processor: P) -> Task
|
||||
| ^ required by this bound in `task`
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | fn task<P: ?Sized>(processor: P) -> Task
|
||||
| ++++++++
|
||||
|
||||
error[E0277]: the trait bound `impl Execute: Execute` is not satisfied
|
||||
--> $DIR/issue-62529-1.rs:80:10
|
||||
|
|
||||
LL | task(annotate(
|
||||
| _____----_^
|
||||
| | |
|
||||
| | required by a bound introduced by this call
|
||||
LL | |
|
||||
LL | |
|
||||
LL | | Annotate::<RefMutFamily<usize>>::new(),
|
||||
... |
|
||||
LL | | }
|
||||
LL | | ));
|
||||
| |_____^ the trait `Execute` is not implemented for `impl Execute`
|
||||
|
|
||||
note: required by a bound in `task`
|
||||
--> $DIR/issue-62529-1.rs:70:10
|
||||
|
|
||||
LL | fn task<P>(processor: P) -> Task
|
||||
| ---- required by a bound in this
|
||||
LL | where P: Execute + 'static {
|
||||
| ^^^^^^^ required by this bound in `task`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
|
@ -1,5 +1,5 @@
|
|||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:57:5
|
||||
--> $DIR/issue-71955.rs:54:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
@ -8,43 +8,7 @@ LL | foo(bar, "string", |s| s.len() == 5);
|
|||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:57:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:57:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:57:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:57:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, &'a str) {bar}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:63:5
|
||||
--> $DIR/issue-71955.rs:58:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
@ -52,41 +16,5 @@ LL | foo(baz, "string", |s| s.0.len() == 5);
|
|||
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:63:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:63:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:63:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: implementation of `Parser` is not general enough
|
||||
--> $DIR/issue-71955.rs:63:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^ implementation of `Parser` is not general enough
|
||||
|
|
||||
= note: `for<'a> fn(&'a str) -> (&'a str, Wrapper<'a>) {baz}` must implement `Parser<'0>`, for any lifetime `'0`...
|
||||
= note: ...but it actually implements `Parser<'1>`, for some specific lifetime `'1`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -1,8 +1,79 @@
|
|||
error: fatal error triggered by #[rustc_error]
|
||||
--> $DIR/issue-71955.rs:47:1
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-71955.rs:54:5
|
||||
|
|
||||
LL | fn main() {
|
||||
| ^^^^^^^^^
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r, 's> FnOnce<(&'r &'s str,)>`
|
||||
found type `for<'r> FnOnce<(&'r &str,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-71955.rs:54:24
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-71955.rs:34:9
|
||||
|
|
||||
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-71955.rs:54:5
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `FnOnce<(&&str,)>`
|
||||
found type `for<'r> FnOnce<(&'r &str,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-71955.rs:54:24
|
||||
|
|
||||
LL | foo(bar, "string", |s| s.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-71955.rs:34:44
|
||||
|
|
||||
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-71955.rs:58:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `for<'r, 's> FnOnce<(&'r Wrapper<'s>,)>`
|
||||
found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-71955.rs:58:24
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-71955.rs:34:9
|
||||
|
|
||||
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-71955.rs:58:5
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
|
||||
|
|
||||
= note: expected type `FnOnce<(&Wrapper<'_>,)>`
|
||||
found type `for<'r> FnOnce<(&'r Wrapper<'_>,)>`
|
||||
note: this closure does not fulfill the lifetime requirements
|
||||
--> $DIR/issue-71955.rs:58:24
|
||||
|
|
||||
LL | foo(baz, "string", |s| s.0.len() == 5);
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
note: the lifetime requirement is introduced here
|
||||
--> $DIR/issue-71955.rs:34:44
|
||||
|
|
||||
LL | F2: FnOnce(&<F1 as Parser>::Output) -> bool
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
@ -42,10 +42,7 @@ where
|
|||
|
||||
struct Wrapper<'a>(&'a str);
|
||||
|
||||
// Because nll currently succeeds and migrate doesn't
|
||||
#[rustc_error]
|
||||
fn main() {
|
||||
//[nll]~^ fatal
|
||||
fn bar<'a>(s: &'a str) -> (&'a str, &'a str) {
|
||||
(&s[..1], &s[..])
|
||||
}
|
||||
|
@ -56,14 +53,10 @@ fn main() {
|
|||
|
||||
foo(bar, "string", |s| s.len() == 5);
|
||||
//[migrate]~^ ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[nll]~^^ ERROR mismatched types
|
||||
//[nll]~| ERROR mismatched types
|
||||
foo(baz, "string", |s| s.0.len() == 5);
|
||||
//[migrate]~^ ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[migrate]~| ERROR implementation of `Parser` is not general enough
|
||||
//[nll]~^^ ERROR mismatched types
|
||||
//[nll]~| ERROR mismatched types
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@ trait SomeTrait<'a> {
|
|||
|
||||
fn give_me_ice<T>() {
|
||||
callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
|
||||
//~^ ERROR: the trait bound `T: SomeTrait<'_>` is not satisfied
|
||||
//~^ ERROR the trait bound `T: SomeTrait<'_>` is not satisfied [E0277]
|
||||
//~| ERROR the trait bound `T: SomeTrait<'_>` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn callee<T: Fn<(&'static (),)>>() {
|
||||
|
|
|
@ -9,6 +9,17 @@ help: consider restricting type parameter `T`
|
|||
LL | fn give_me_ice<T: SomeTrait<'_>>() {
|
||||
| +++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0277]: the trait bound `T: SomeTrait<'_>` is not satisfied
|
||||
--> $DIR/issue-85455.rs:8:14
|
||||
|
|
||||
LL | callee::<fn(&()) -> <T as SomeTrait<'_>>::Associated>();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `SomeTrait<'_>` is not implemented for `T`
|
||||
|
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn give_me_ice<T: SomeTrait<'_>>() {
|
||||
| +++++++++++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::fmt::Debug;
|
|||
fn main() {}
|
||||
|
||||
type Two<A, B> = impl Debug;
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied in `(A, B, <A as Foo>::Bar)`
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied
|
||||
//~| ERROR `A` doesn't implement `Debug`
|
||||
//~| ERROR `B` doesn't implement `Debug`
|
||||
|
||||
|
|
|
@ -10,13 +10,12 @@ note: previous use here
|
|||
LL | fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `A: Foo` is not satisfied in `(A, B, <A as Foo>::Bar)`
|
||||
error[E0277]: the trait bound `A: Foo` is not satisfied
|
||||
--> $DIR/generic_duplicate_param_use9.rs:7:18
|
||||
|
|
||||
LL | type Two<A, B> = impl Debug;
|
||||
| ^^^^^^^^^^ within `(A, B, <A as Foo>::Bar)`, the trait `Foo` is not implemented for `A`
|
||||
| ^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
||||
|
|
||||
= note: required because it appears within the type `(A, B, <A as Foo>::Bar)`
|
||||
help: consider restricting type parameter `A`
|
||||
|
|
||||
LL | type Two<A: Foo, B> = impl Debug;
|
||||
|
@ -28,7 +27,7 @@ error[E0277]: `A` doesn't implement `Debug`
|
|||
LL | type Two<A, B> = impl Debug;
|
||||
| ^^^^^^^^^^ `A` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Debug` for `(A, B, <A as Foo>::Bar)`
|
||||
= note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
|
||||
help: consider restricting type parameter `A`
|
||||
|
|
||||
LL | type Two<A: std::fmt::Debug, B> = impl Debug;
|
||||
|
@ -40,7 +39,7 @@ error[E0277]: `B` doesn't implement `Debug`
|
|||
LL | type Two<A, B> = impl Debug;
|
||||
| ^^^^^^^^^^ `B` cannot be formatted using `{:?}` because it doesn't implement `Debug`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Debug` for `(A, B, <A as Foo>::Bar)`
|
||||
= note: required because of the requirements on the impl of `Debug` for `(A, B, _)`
|
||||
help: consider restricting type parameter `B`
|
||||
|
|
||||
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
use std::future::Future;
|
||||
|
||||
type G<'a, T> = impl Future<Output = ()>;
|
||||
//~^ ERROR: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
//~| ERROR: the trait bound `T: Trait` is not satisfied
|
||||
//~^ ERROR: the trait bound `T: Trait` is not satisfied
|
||||
|
||||
trait Trait {
|
||||
type F: Future<Output = ()>;
|
||||
|
|
|
@ -1,22 +1,3 @@
|
|||
error[E0271]: type mismatch resolving `<impl Future<Output = [async output]> as Future>::Output == ()`
|
||||
--> $DIR/issue-89686.rs:7:17
|
||||
|
|
||||
LL | type G<'a, T> = impl Future<Output = ()>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found associated type
|
||||
...
|
||||
LL | async move { self.f().await }
|
||||
| ------------------ the found `async` block
|
||||
|
|
||||
::: $SRC_DIR/core/src/future/mod.rs:LL:COL
|
||||
|
|
||||
LL | pub const fn from_generator<T>(gen: T) -> impl Future<Output = T::Return>
|
||||
| ------------------------------- the found opaque type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found associated type `<impl Future<Output = [async output]> as Future>::Output`
|
||||
= help: consider constraining the associated type `<impl Future<Output = [async output]> as Future>::Output` to `()`
|
||||
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
|
||||
|
||||
error[E0277]: the trait bound `T: Trait` is not satisfied
|
||||
--> $DIR/issue-89686.rs:7:17
|
||||
|
|
||||
|
@ -28,7 +9,6 @@ help: consider restricting type parameter `T`
|
|||
LL | type G<'a, T: Trait> = impl Future<Output = ()>;
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
Some errors have detailed explanations: E0271, E0277.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// check-pass
|
||||
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
trait Lt<'a> {
|
||||
|
@ -10,6 +12,5 @@ impl<'a> Lt<'a> for () {
|
|||
fn main() {
|
||||
let v: <() as Lt<'_>>::T = ();
|
||||
let f: &mut dyn FnMut<(_,), Output = ()> = &mut |_: <() as Lt<'_>>::T| {};
|
||||
//~^ ERROR: the size for values of type `<() as Lt<'_>>::T` cannot be known
|
||||
f(v);
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
error[E0277]: the size for values of type `<() as Lt<'_>>::T` cannot be known at compilation time
|
||||
--> $DIR/issue-53448.rs:12:54
|
||||
|
|
||||
LL | let f: &mut dyn FnMut<(_,), Output = ()> = &mut |_: <() as Lt<'_>>::T| {};
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `<() as Lt<'_>>::T`
|
||||
= help: unsized fn params are gated as an unstable feature
|
||||
help: consider further restricting the associated type
|
||||
|
|
||||
LL | fn main() where <() as Lt<'_>>::T: Sized {
|
||||
| ++++++++++++++++++++++++++++++
|
||||
help: function arguments must have a statically known size, borrowed types always have a known size
|
||||
|
|
||||
LL | let f: &mut dyn FnMut<(_,), Output = ()> = &mut |_: &<() as Lt<'_>>::T| {};
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Reference in a new issue