From e5f22ff0fbedff23d884fe2456dae5a62a2bf295 Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Sat, 13 Nov 2021 18:45:03 -0500 Subject: [PATCH 1/3] Try to normalize associated types before processing obligations --- .../src/traits/fulfill.rs | 17 ++++ .../src/traits/project.rs | 90 ++++++++++++++++--- src/test/ui/associated-types/issue-59324.rs | 2 +- .../ui/associated-types/issue-59324.stderr | 11 ++- .../generic-associated-types/issue-90729.rs | 38 ++++++++ .../generic-associated-types/issue-93341.rs | 55 ++++++++++++ .../generic-associated-types/issue-93342.rs | 57 ++++++++++++ .../normalize-under-binder/issue-62529-1.rs | 4 +- .../issue-62529-1.stderr | 52 ----------- .../issue-71955.migrate.stderr | 78 +--------------- .../issue-71955.nll.stderr | 81 +++++++++++++++-- .../normalize-under-binder/issue-71955.rs | 15 +--- .../normalize-under-binder/issue-85455.rs | 3 +- .../normalize-under-binder/issue-85455.stderr | 13 ++- .../generic_duplicate_param_use9.rs | 2 +- .../generic_duplicate_param_use9.stderr | 9 +- .../ui/type-alias-impl-trait/issue-89686.rs | 3 +- .../type-alias-impl-trait/issue-89686.stderr | 24 +---- src/test/ui/unboxed-closures/issue-53448.rs | 3 +- .../ui/unboxed-closures/issue-53448.stderr | 20 ----- 20 files changed, 362 insertions(+), 215 deletions(-) create mode 100644 src/test/ui/generic-associated-types/issue-90729.rs create mode 100644 src/test/ui/generic-associated-types/issue-93341.rs create mode 100644 src/test/ui/generic-associated-types/issue-93342.rs delete mode 100644 src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr delete mode 100644 src/test/ui/unboxed-closures/issue-53448.stderr diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index b4b2e4cd04229..62c6c8454797a 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -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() { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index c32c73c638412..ea48fab1cebb8 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -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>, +) -> 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>, depth: usize, universes: Vec>, + /// 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>, ) -> 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>, + ) -> AssocTypeNormalizer<'a, 'b, 'tcx> { + AssocTypeNormalizer { + selcx, + param_env, + cause, + obligations, + depth, + universes: vec![], + eager_inference_replacement: false, + } } fn fold>(&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); diff --git a/src/test/ui/associated-types/issue-59324.rs b/src/test/ui/associated-types/issue-59324.rs index 9e68e9e77515b..162f9e00edd81 100644 --- a/src/test/ui/associated-types/issue-59324.rs +++ b/src/test/ui/associated-types/issue-59324.rs @@ -15,9 +15,9 @@ pub trait ThriftService: { 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(factory: dyn ThriftService<()>) {} diff --git a/src/test/ui/associated-types/issue-59324.stderr b/src/test/ui/associated-types/issue-59324.stderr index 2f430d3055e19..45d2dfb53757b 100644 --- a/src/test/ui/associated-types/issue-59324.stderr +++ b/src/test/ui/associated-types/issue-59324.stderr @@ -6,7 +6,7 @@ LL | | LL | | LL | | Service::OnlyFoo> ... | -LL | | ) -> Self::AssocType; +LL | | LL | | } | |_^ the trait `Foo` is not implemented for `Bug` | @@ -23,7 +23,7 @@ LL | | LL | | LL | | Service::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: | +++++ 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 | diff --git a/src/test/ui/generic-associated-types/issue-90729.rs b/src/test/ui/generic-associated-types/issue-90729.rs new file mode 100644 index 0000000000000..98295cce8d587 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-90729.rs @@ -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 { + _marker: PhantomData, +} + +impl Bytes +where + for<'a> T::Ref<'a>: AsBytes, +{ + pub fn new() -> Self { + Self { + _marker: PhantomData, + } + } +} + +fn main() { + let _b = Bytes::::new(); +} diff --git a/src/test/ui/generic-associated-types/issue-93341.rs b/src/test/ui/generic-associated-types/issue-93341.rs new file mode 100644 index 0000000000000..e96a768ecda8f --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-93341.rs @@ -0,0 +1,55 @@ +// check-pass + +#![feature(generic_associated_types)] +use std::marker::PhantomData; + +pub struct Id<'id>(PhantomData &'id ()>); + +fn new_id() -> Id<'static> { + Id(PhantomData) +} + +pub trait HasLifetime where { + type AtLifetime<'a>; +} + +pub struct ExistentialLifetime(S::AtLifetime<'static>); + +impl ExistentialLifetime { + pub fn new(f: F) -> ExistentialLifetime + 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 { + fn new_helper<'id>(id: Id<'id>) -> ExampleS<'id> { + ExampleS(id) + } + + ExistentialLifetime::::new(new_helper) +} + +fn broken1() -> ExistentialLifetime { + fn new_helper<'id>(id: Id<'id>) -> ::AtLifetime<'id> { + ExampleS(id) + } + + ExistentialLifetime::::new(new_helper) +} + +fn broken2() -> ExistentialLifetime { + ExistentialLifetime::::new(|id| ExampleS(id)) +} + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-93342.rs b/src/test/ui/generic-associated-types/issue-93342.rs new file mode 100644 index 0000000000000..d8d7adac95161 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-93342.rs @@ -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 +where + F: Fn(A::RefType<'_>, B::RefType<'_>) -> O, +{ + f: F, + _phantom: PhantomData<(A, B, O)>, +} + +impl BinaryExpression +where + F: Fn(A::RefType<'_>, B::RefType<'_>) -> O, +{ + pub fn new(f: F) -> Self { + Self { + f, + _phantom: PhantomData, + } + } +} + +fn main() { + BinaryExpression::::new(str_contains); +} diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs index 7c3c72e04cb78..c6f29fa59085d 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.rs @@ -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::>::new(), |value: &mut usize| { *value = 2; diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr deleted file mode 100644 index 01b14660b6531..0000000000000 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-62529-1.stderr +++ /dev/null @@ -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::>::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

(processor: P) -> Task - | ^ required by this bound in `task` -help: consider relaxing the implicit `Sized` restriction - | -LL | fn task(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::>::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

(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`. diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr index 7da6b029c26f0..e6ffe38ee92e8 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.migrate.stderr @@ -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,79 +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 - | -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: 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 @@ -88,5 +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: aborting due to 10 previous errors +error: aborting due to 2 previous errors diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr index c2feaa9128055..0f38f8e3283a2 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.nll.stderr @@ -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(&::Output) -> bool + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +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(&::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(&::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(&::Output) -> bool + | ^^^^ -error: aborting due to previous error +error: aborting due to 4 previous errors +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs index 3d6778b6942c5..4b7e207b96d49 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-71955.rs @@ -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 } diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs index 3a4d6c02a159f..fe319e6c8515c 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.rs @@ -6,7 +6,8 @@ trait SomeTrait<'a> { fn give_me_ice() { callee:: >::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>() { diff --git a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr index aaf45dc7ad564..13b68b072403a 100644 --- a/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr +++ b/src/test/ui/higher-rank-trait-bounds/normalize-under-binder/issue-85455.stderr @@ -9,6 +9,17 @@ help: consider restricting type parameter `T` LL | fn give_me_ice>() { | +++++++++++++++ -error: aborting due to previous error +error[E0277]: the trait bound `T: SomeTrait<'_>` is not satisfied + --> $DIR/issue-85455.rs:8:14 + | +LL | callee:: >::Associated>(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `SomeTrait<'_>` is not implemented for `T` + | +help: consider restricting type parameter `T` + | +LL | fn give_me_ice>() { + | +++++++++++++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs index 747081933172b..4baf198b12fae 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.rs @@ -5,7 +5,7 @@ use std::fmt::Debug; fn main() {} type Two = impl Debug; -//~^ ERROR the trait bound `A: Foo` is not satisfied in `(A, B, ::Bar)` +//~^ ERROR the trait bound `A: Foo` is not satisfied //~| ERROR `A` doesn't implement `Debug` //~| ERROR `B` doesn't implement `Debug` diff --git a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr index a8eb53a50e38b..43471f980b2af 100644 --- a/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_duplicate_param_use9.stderr @@ -10,13 +10,12 @@ note: previous use here LL | fn two(t: T, u: U) -> Two { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0277]: the trait bound `A: Foo` is not satisfied in `(A, B, ::Bar)` +error[E0277]: the trait bound `A: Foo` is not satisfied --> $DIR/generic_duplicate_param_use9.rs:7:18 | LL | type Two = impl Debug; - | ^^^^^^^^^^ within `(A, B, ::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, ::Bar)` help: consider restricting type parameter `A` | LL | type Two = impl Debug; @@ -28,7 +27,7 @@ error[E0277]: `A` doesn't implement `Debug` LL | type Two = 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, ::Bar)` + = note: required because of the requirements on the impl of `Debug` for `(A, B, _)` help: consider restricting type parameter `A` | LL | type Two = impl Debug; @@ -40,7 +39,7 @@ error[E0277]: `B` doesn't implement `Debug` LL | type Two = 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, ::Bar)` + = note: required because of the requirements on the impl of `Debug` for `(A, B, _)` help: consider restricting type parameter `B` | LL | type Two = impl Debug; diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.rs b/src/test/ui/type-alias-impl-trait/issue-89686.rs index 5878b26fddbc7..f058653dde338 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.rs +++ b/src/test/ui/type-alias-impl-trait/issue-89686.rs @@ -5,8 +5,7 @@ use std::future::Future; type G<'a, T> = impl Future; -//~^ ERROR: type mismatch resolving ` 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; diff --git a/src/test/ui/type-alias-impl-trait/issue-89686.stderr b/src/test/ui/type-alias-impl-trait/issue-89686.stderr index 19ed9a7476c1b..0df5a809ebb47 100644 --- a/src/test/ui/type-alias-impl-trait/issue-89686.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-89686.stderr @@ -1,22 +1,3 @@ -error[E0271]: type mismatch resolving ` as Future>::Output == ()` - --> $DIR/issue-89686.rs:7:17 - | -LL | type G<'a, T> = impl Future; - | ^^^^^^^^^^^^^^^^^^^^^^^^ 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(gen: T) -> impl Future - | ------------------------------- the found opaque type - | - = note: expected unit type `()` - found associated type ` as Future>::Output` - = help: consider constraining the associated type ` 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; | +++++++ -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`. diff --git a/src/test/ui/unboxed-closures/issue-53448.rs b/src/test/ui/unboxed-closures/issue-53448.rs index 5c82a56e77e14..ea1edf7d45073 100644 --- a/src/test/ui/unboxed-closures/issue-53448.rs +++ b/src/test/ui/unboxed-closures/issue-53448.rs @@ -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); } diff --git a/src/test/ui/unboxed-closures/issue-53448.stderr b/src/test/ui/unboxed-closures/issue-53448.stderr deleted file mode 100644 index 8f9d918fdba2b..0000000000000 --- a/src/test/ui/unboxed-closures/issue-53448.stderr +++ /dev/null @@ -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`. From b4ca2c0958004f7605d4a650603a4fc2df0e3e3b Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Fri, 25 Feb 2022 22:48:47 -0500 Subject: [PATCH 2/3] Bless issue-91130 test --- src/test/ui/generic-associated-types/issue-91139.rs | 3 ++- .../ui/generic-associated-types/issue-91139.stderr | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/generic-associated-types/issue-91139.stderr diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs index 5c4a7cf6ffc60..f08a9bf6c88f5 100644 --- a/src/test/ui/generic-associated-types/issue-91139.rs +++ b/src/test/ui/generic-associated-types/issue-91139.rs @@ -1,4 +1,4 @@ -// check-pass +// check-fail #![feature(generic_associated_types)] @@ -16,6 +16,7 @@ impl Foo for () { fn foo() { let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); + //~^ the parameter type `T` may not live long enough } pub fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.stderr new file mode 100644 index 0000000000000..270e256e4dd45 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-91139.stderr @@ -0,0 +1,10 @@ +error[E0311]: the parameter type `T` may not live long enough + --> $DIR/issue-91139.rs:19:12 + | +LL | fn foo() { + | - help: consider adding an explicit lifetime bound...: `T: 'a` +LL | let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + +error: aborting due to previous error + From 06067d94d8122ef079433fb40ef5e0f87ac7d55c Mon Sep 17 00:00:00 2001 From: Jack Huey <31162821+jackh726@users.noreply.github.com> Date: Mon, 7 Mar 2022 16:24:41 -0500 Subject: [PATCH 3/3] Bless test --- ...ssue-91139.stderr => issue-91139.migrate.stderr} | 2 +- src/test/ui/generic-associated-types/issue-91139.rs | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) rename src/test/ui/generic-associated-types/{issue-91139.stderr => issue-91139.migrate.stderr} (92%) diff --git a/src/test/ui/generic-associated-types/issue-91139.stderr b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr similarity index 92% rename from src/test/ui/generic-associated-types/issue-91139.stderr rename to src/test/ui/generic-associated-types/issue-91139.migrate.stderr index 270e256e4dd45..a27d811023834 100644 --- a/src/test/ui/generic-associated-types/issue-91139.stderr +++ b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr @@ -1,5 +1,5 @@ error[E0311]: the parameter type `T` may not live long enough - --> $DIR/issue-91139.rs:19:12 + --> $DIR/issue-91139.rs:27:12 | LL | fn foo() { | - help: consider adding an explicit lifetime bound...: `T: 'a` diff --git a/src/test/ui/generic-associated-types/issue-91139.rs b/src/test/ui/generic-associated-types/issue-91139.rs index f08a9bf6c88f5..78b2b63dadc5e 100644 --- a/src/test/ui/generic-associated-types/issue-91139.rs +++ b/src/test/ui/generic-associated-types/issue-91139.rs @@ -1,4 +1,13 @@ -// check-fail +// 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,7 +25,7 @@ impl Foo for () { fn foo() { let _: for<'a> fn(<() as Foo>::Type<'a>, &'a T) = |_, _| (); - //~^ the parameter type `T` may not live long enough + //[migrate]~^ the parameter type `T` may not live long enough } pub fn main() {}