Auto merge of #90887 - jackh726:issue-90729, r=nikomatsakis

Try to normalize associated types before processing obligations

Closes #90729

r? `@nikomatsakis`
This commit is contained in:
bors 2022-03-08 00:53:41 +00:00
commit 67b3e81838
22 changed files with 383 additions and 216 deletions

View file

@ -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() {

View file

@ -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);

View file

@ -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<()>) {}

View file

@ -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
|

View 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();
}

View file

@ -0,0 +1,10 @@
error[E0311]: the parameter type `T` may not live long enough
--> $DIR/issue-91139.rs:27:12
|
LL | fn foo<T>() {
| - help: consider adding an explicit lifetime bound...: `T: 'a`
LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
error: aborting due to previous error

View file

@ -1,4 +1,13 @@
// check-pass
// revisions: migrate nll
//[nll]compile-flags: -Z borrowck=mir
// Since we are testing nll (and migration) explicitly as a separate
// revisions, don't worry about the --compare-mode=nll on this test.
// ignore-compare-mode-nll
//[nll] check-pass
//[migrate] check-fail
#![feature(generic_associated_types)]
@ -16,6 +25,7 @@ impl<T> Foo<T> for () {
fn foo<T>() {
let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| ();
//[migrate]~^ the parameter type `T` may not live long enough
}
pub fn main() {}

View 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() {}

View 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);
}

View file

@ -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;

View file

@ -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`.

View file

@ -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

View file

@ -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`.

View file

@ -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
}

View file

@ -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 (),)>>() {

View file

@ -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`.

View file

@ -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`

View file

@ -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;

View file

@ -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 = ()>;

View file

@ -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`.

View file

@ -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);
}

View file

@ -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`.