diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index f89daf033f6cd..58ed5688b5479 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -164,7 +164,7 @@ pub fn clause_obligations<'tcx>( wf.compute(ty.into()); } ty::ClauseKind::Projection(t) => { - wf.compute_projection(t.projection_ty); + wf.compute_alias(t.projection_ty); wf.compute(match t.term.unpack() { ty::TermKind::Ty(ty) => ty.into(), ty::TermKind::Const(c) => c.into(), @@ -396,36 +396,17 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.out.extend(obligations); } - self.out.extend( - trait_ref - .args - .iter() - .enumerate() - .filter(|(_, arg)| { - matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..)) - }) - .filter(|(_, arg)| !arg.has_escaping_bound_vars()) - .map(|(i, arg)| { - let mut cause = traits::ObligationCause::misc(self.span, self.body_id); - // The first arg is the self ty - use the correct span for it. - if i == 0 { - if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = - item.map(|i| &i.kind) - { - cause.span = self_ty.span; - } - } - traits::Obligation::with_depth( - tcx, - cause, - depth, - param_env, - ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed( - arg, - ))), - ) - }), - ); + if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) = item.map(|i| &i.kind) { + // FIXME: Could generalize this hack. + let span = std::mem::replace(&mut self.span, self_ty.span); + // make sure that the trait ref is WF. + trait_ref.args[0].visit_with(self); + self.span = span; + (&trait_ref.args[1..]).visit_with(self); + } else { + // make sure that the trait ref is WF. + trait_ref.visit_with(self); + } } // Compute the obligations that are required for `trait_ref` to be WF, @@ -436,9 +417,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { } } - /// Pushes the obligations required for `trait_ref::Item` to be WF + /// Pushes the obligations required for an alias (except inherent) to be WF /// into `self.out`. - fn compute_projection(&mut self, data: ty::AliasTy<'tcx>) { + fn compute_alias(&mut self, data: ty::AliasTy<'tcx>) { // A projection is well-formed if // // (a) its predicates hold (*) @@ -463,9 +444,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { let obligations = self.nominal_obligations(data.def_id, data.args); self.out.extend(obligations); - self.compute_projection_args(data.args); + // Make sure that projection args are WF. + data.visit_with(self); } + /// Pushes the obligations required for an inherent alias to be WF + /// into `self.out`. + // FIXME(inherent_associated_types): Merge this function with `fn compute_alias`. fn compute_inherent_projection(&mut self, data: ty::AliasTy<'tcx>) { // An inherent projection is well-formed if // @@ -490,33 +475,8 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { self.out.extend(obligations); } - self.compute_projection_args(data.args); - } - - fn compute_projection_args(&mut self, args: GenericArgsRef<'tcx>) { - let tcx = self.tcx(); - let cause = self.cause(traits::WellFormed(None)); - let param_env = self.param_env; - let depth = self.recursion_depth; - - self.out.extend( - args.iter() - .filter(|arg| { - matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..)) - }) - .filter(|arg| !arg.has_escaping_bound_vars()) - .map(|arg| { - traits::Obligation::with_depth( - tcx, - cause.clone(), - depth, - param_env, - ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed( - arg, - ))), - ) - }), - ); + // Make sure that projection args are WF. + data.visit_with(self); } fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { @@ -688,8 +648,8 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // Simple cases that are WF if their type args are WF. } - ty::Alias(ty::Projection, data) => { - self.compute_projection(data); + ty::Alias(ty::Projection | ty::Opaque | ty::Weak, data) => { + self.compute_alias(data); return; // Subtree handled by compute_projection. } ty::Alias(ty::Inherent, data) => { @@ -791,21 +751,6 @@ impl<'a, 'tcx> TypeVisitor> for WfPredicates<'a, 'tcx> { // types appearing in the fn signature. } - ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { - // All of the requirements on type parameters - // have already been checked for `impl Trait` in - // return position. We do need to check type-alias-impl-trait though. - if self.tcx().is_type_alias_impl_trait(def_id) { - let obligations = self.nominal_obligations(def_id, args); - self.out.extend(obligations); - } - } - - ty::Alias(ty::Weak, ty::AliasTy { def_id, args, .. }) => { - let obligations = self.nominal_obligations(def_id, args); - self.out.extend(obligations); - } - ty::Dynamic(data, r, _) => { // WfObject // diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs index ff265e576b90f..84bc39d926307 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.rs @@ -9,6 +9,7 @@ impl Foo for Bar { //~^ ERROR: the trait bound `impl Foo: Foo` is not satisfied [E0277] //~| ERROR: the trait bound `Bar: Foo` is not satisfied [E0277] //~| ERROR: impl has stricter requirements than trait + //~| ERROR: the trait bound `F2: Foo` is not satisfied self } } diff --git a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr index 12725c3456fd5..fbf82a24b5015 100644 --- a/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr +++ b/tests/ui/impl-trait/in-trait/return-dont-satisfy-bounds.stderr @@ -11,6 +11,22 @@ note: required by a bound in `Foo::{synthetic#0}` LL | fn foo(self) -> impl Foo; | ^^^^^^ required by this bound in `Foo::{synthetic#0}` +error[E0277]: the trait bound `F2: Foo` is not satisfied + --> $DIR/return-dont-satisfy-bounds.rs:8:34 + | +LL | fn foo>(self) -> impl Foo { + | ^^^^^^^^^^^^ the trait `Foo` is not implemented for `F2` + | +note: required by a bound in `>::foo` + --> $DIR/return-dont-satisfy-bounds.rs:8:16 + | +LL | fn foo>(self) -> impl Foo { + | ^^^^^^^ required by this bound in `>::foo` +help: consider further restricting this bound + | +LL | fn foo + Foo>(self) -> impl Foo { + | +++++++++ + error[E0276]: impl has stricter requirements than trait --> $DIR/return-dont-satisfy-bounds.rs:8:16 | @@ -32,7 +48,7 @@ LL | self = help: the trait `Foo` is implemented for `Bar` = help: for that trait implementation, expected `char`, found `u8` -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0276, E0277. For more information about an error, try `rustc --explain E0276`. diff --git a/tests/ui/implied-bounds/from-trait-impl.stderr b/tests/ui/implied-bounds/from-trait-impl.stderr index 4151d206ae25f..a456c5a230761 100644 --- a/tests/ui/implied-bounds/from-trait-impl.stderr +++ b/tests/ui/implied-bounds/from-trait-impl.stderr @@ -7,13 +7,13 @@ LL | fn func1(foo: Foo<(&str,)>) { = note: type must satisfy the static lifetime error[E0310]: the parameter type `X` may not live long enough - --> $DIR/from-trait-impl.rs:20:23 + --> $DIR/from-trait-impl.rs:20:9 | LL | impl TestTrait for [Foo<(X,)>; 1] {} - | ^^^^^^^^^^^^^^ - | | - | the parameter type `X` must be valid for the static lifetime... - | ...so that the type `X` will meet its required lifetime bounds + | ^^^^^^^^^ + | | + | the parameter type `X` must be valid for the static lifetime... + | ...so that the type `X` will meet its required lifetime bounds | help: consider adding an explicit lifetime bound | diff --git a/tests/ui/inference/issue-80409.no-compat.stderr b/tests/ui/inference/issue-80409.no-compat.stderr deleted file mode 100644 index 523ca229b06f4..0000000000000 --- a/tests/ui/inference/issue-80409.no-compat.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ImpliedOutlivesBounds { ty: &'?2 mut StateContext<'?3, usize> } } - --> $DIR/issue-80409.rs:49:30 - | -LL | builder.state().on_entry(|_| {}); - | ^^^ - | -note: - --> $DIR/issue-80409.rs:49:30 - | -LL | builder.state().on_entry(|_| {}); - | ^^^ - -query stack during panic: -end of query stack diff --git a/tests/ui/inference/issue-80409.rs b/tests/ui/inference/issue-80409.rs index dfb84563e6d80..0979c21e3ee14 100644 --- a/tests/ui/inference/issue-80409.rs +++ b/tests/ui/inference/issue-80409.rs @@ -1,19 +1,3 @@ -// This should not pass, because `usize: Fsm` does not hold. However, it currently ICEs. - -// ignore-tidy-linelength - -//@ revisions: compat no-compat -//@[compat] check-pass -//@[no-compat] compile-flags: -Zno-implied-bounds-compat -//@[no-compat] check-fail -//@[no-compat] known-bug: #80409 -//@[no-compat] failure-status: 101 -//@[no-compat] normalize-stderr-test "delayed at.*" -> "" -//@[no-compat] normalize-stderr-test "note: .*\n\n" -> "" -//@[no-compat] normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" -//@[no-compat] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " -//@[no-compat] rustc-env:RUST_BACKTRACE=0 - #![allow(unreachable_code, unused)] use std::marker::PhantomData; @@ -34,6 +18,7 @@ struct FsmStateBuilder { impl FsmStateBuilder { fn on_entry)>(&self, _action: TAction) {} + //~^ ERROR the trait bound `TFsm: Fsm` is not satisfied } trait Fsm { diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs index 85eeb5d4c901e..eab436fa3419d 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.rs @@ -7,6 +7,7 @@ async fn wrapper(f: F) //~^ ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` //~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` +//~| ERROR: expected a `FnOnce(&'a mut i32)` closure, found `i32` where F:, for<'a> >::Output: Future + 'a, diff --git a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr index 578ba149baf3f..e9f97d1d93bde 100644 --- a/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr +++ b/tests/ui/lifetimes/issue-76168-hr-outlives-3.stderr @@ -5,7 +5,7 @@ LL | / async fn wrapper(f: F) LL | | LL | | LL | | -LL | | where +... | LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` @@ -27,7 +27,7 @@ LL | / async fn wrapper(f: F) LL | | LL | | LL | | -LL | | where +... | LL | | F:, LL | | for<'a> >::Output: Future + 'a, | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` @@ -35,7 +35,22 @@ LL | | for<'a> >::Output: Future + 'a = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` - --> $DIR/issue-76168-hr-outlives-3.rs:13:1 + --> $DIR/issue-76168-hr-outlives-3.rs:6:1 + | +LL | / async fn wrapper(f: F) +LL | | +LL | | +LL | | +... | +LL | | F:, +LL | | for<'a> >::Output: Future + 'a, + | |__________________________________________________________________________^ expected an `FnOnce(&'a mut i32)` closure, found `i32` + | + = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: expected a `FnOnce(&'a mut i32)` closure, found `i32` + --> $DIR/issue-76168-hr-outlives-3.rs:14:1 | LL | / { LL | | @@ -46,6 +61,6 @@ LL | | } | = help: the trait `for<'a> FnOnce<(&'a mut i32,)>` is not implemented for `i32` -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/trait-bounds/unsized-bound.stderr b/tests/ui/trait-bounds/unsized-bound.stderr index c8049ebee1173..ed7299b933102 100644 --- a/tests/ui/trait-bounds/unsized-bound.stderr +++ b/tests/ui/trait-bounds/unsized-bound.stderr @@ -1,3 +1,18 @@ +error[E0277]: the size for values of type `A` cannot be known at compilation time + --> $DIR/unsized-bound.rs:2:30 + | +LL | impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `Sized` + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} +LL + impl Trait<(A, B)> for (A, B) where B: ?Sized, {} + | + error[E0277]: the size for values of type `B` cannot be known at compilation time --> $DIR/unsized-bound.rs:2:30 | @@ -23,18 +38,29 @@ LL | trait Trait {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/unsized-bound.rs:2:30 + --> $DIR/unsized-bound.rs:5:52 | -LL | impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} - | - ^^^^^^ doesn't have a size known at compile-time - | | - | this type parameter needs to be `Sized` +LL | impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time | = note: only the last element of a tuple may have a dynamically sized type help: consider removing the `?Sized` bound to make the type parameter `Sized` | -LL - impl Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {} -LL + impl Trait<(A, B)> for (A, B) where B: ?Sized, {} +LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} +LL + impl Trait<(A, B, C)> for (A, B, C) {} + | + +error[E0277]: the size for values of type `B` cannot be known at compilation time + --> $DIR/unsized-bound.rs:5:52 + | +LL | impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} + | - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: only the last element of a tuple may have a dynamically sized type +help: consider removing the `?Sized` bound to make the type parameter `Sized` + | +LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} +LL + impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} | error[E0277]: the size for values of type `C` cannot be known at compilation time @@ -62,29 +88,18 @@ LL | trait Trait {} | ++++++++ error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/unsized-bound.rs:5:52 - | -LL | impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} - | - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time - | - = note: only the last element of a tuple may have a dynamically sized type -help: consider removing the `?Sized` bound to make the type parameter `Sized` - | -LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} -LL + impl Trait<(A, B, C)> for (A, B, C) {} - | - -error[E0277]: the size for values of type `B` cannot be known at compilation time - --> $DIR/unsized-bound.rs:5:52 + --> $DIR/unsized-bound.rs:10:47 | -LL | impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} - | - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time +LL | impl Trait2<(A, B)> for (A, B) {} + | - ^^^^^^ doesn't have a size known at compile-time + | | + | this type parameter needs to be `Sized` | = note: only the last element of a tuple may have a dynamically sized type help: consider removing the `?Sized` bound to make the type parameter `Sized` | -LL - impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} -LL + impl Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {} +LL - impl Trait2<(A, B)> for (A, B) {} +LL + impl Trait2<(A, B)> for (A, B) {} | error[E0277]: the size for values of type `B` cannot be known at compilation time @@ -111,21 +126,6 @@ help: consider relaxing the implicit `Sized` restriction LL | trait Trait2 {} | ++++++++ -error[E0277]: the size for values of type `A` cannot be known at compilation time - --> $DIR/unsized-bound.rs:10:47 - | -LL | impl Trait2<(A, B)> for (A, B) {} - | - ^^^^^^ doesn't have a size known at compile-time - | | - | this type parameter needs to be `Sized` - | - = note: only the last element of a tuple may have a dynamically sized type -help: consider removing the `?Sized` bound to make the type parameter `Sized` - | -LL - impl Trait2<(A, B)> for (A, B) {} -LL + impl Trait2<(A, B)> for (A, B) {} - | - error[E0277]: the size for values of type `A` cannot be known at compilation time --> $DIR/unsized-bound.rs:14:23 | diff --git a/tests/ui/traits/copy-impl-cannot-normalize.stderr b/tests/ui/traits/copy-impl-cannot-normalize.stderr index a98bb47f54fc1..a1b13d126c69f 100644 --- a/tests/ui/traits/copy-impl-cannot-normalize.stderr +++ b/tests/ui/traits/copy-impl-cannot-normalize.stderr @@ -2,18 +2,16 @@ error[E0277]: the trait bound `T: TraitFoo` is not satisfied --> $DIR/copy-impl-cannot-normalize.rs:22:18 | LL | impl Copy for Foo {} - | ^^^^^^ the trait `TraitFoo` is not implemented for `T`, which is required by `Foo: Clone` + | ^^^^^^ the trait `TraitFoo` is not implemented for `T` | -note: required for `Foo` to implement `Clone` - --> $DIR/copy-impl-cannot-normalize.rs:12:9 +note: required by a bound in `Foo` + --> $DIR/copy-impl-cannot-normalize.rs:7:8 | -LL | impl Clone for Foo - | ^^^^^ ^^^^^^ +LL | struct Foo + | --- required by a bound in this struct LL | where LL | T: TraitFoo, - | -------- unsatisfied trait bound introduced here -note: required by a bound in `Copy` - --> $SRC_DIR/core/src/marker.rs:LL:COL + | ^^^^^^^^ required by this bound in `Foo` help: consider restricting type parameter `T` | LL | impl Copy for Foo {} diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr index 74a0a90885da5..a14c11f426c82 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-2.stderr @@ -19,12 +19,6 @@ error[E0275]: overflow evaluating the requirement `<() as A>::Assoc: A` LL | Self::Assoc: A, | ^^^^ -error[E0275]: overflow evaluating the requirement `<() as A>::Assoc well-formed` - --> $DIR/normalize-param-env-2.rs:24:22 - | -LL | Self::Assoc: A, - | ^^^^ - error[E0275]: overflow evaluating the requirement `(): A` --> $DIR/normalize-param-env-2.rs:27:10 | @@ -46,6 +40,6 @@ LL | where LL | Self::Assoc: A, | ^^^^ required by this bound in `A::f` -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr index e91a48f62aec3..2f41330d99121 100644 --- a/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr +++ b/tests/ui/traits/next-solver/normalize/normalize-param-env-4.next.stderr @@ -4,12 +4,6 @@ error[E0275]: overflow evaluating the requirement `::Assoc: Trait` LL | ::Assoc: Trait, | ^^^^^ -error[E0275]: overflow evaluating the requirement `::Assoc well-formed` - --> $DIR/normalize-param-env-4.rs:19:26 - | -LL | ::Assoc: Trait, - | ^^^^^ - error[E0275]: overflow evaluating the requirement `T: Trait` --> $DIR/normalize-param-env-4.rs:32:19 | @@ -22,6 +16,6 @@ note: required by a bound in `impls_trait` LL | fn impls_trait() {} | ^^^^^ required by this bound in `impls_trait` -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0275`. diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr index 6c259621466d3..40e16dde6e4a4 100644 --- a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -7,6 +7,27 @@ LL | #![feature(non_lifetime_binders)] = note: see issue #108185 for more information = note: `#[warn(incomplete_features)]` on by default +error[E0309]: the placeholder type `!1_"F"` may not live long enough + --> $DIR/type-match-with-late-bound.rs:8:1 + | +LL | async fn walk2<'a, T: 'a>(_: T) + | ^ -- the placeholder type `!1_"F"` must be valid for the lifetime `'a` as defined here... + | _| + | | +LL | | where +LL | | for F: 'a, + | |_________________^ ...so that the type `F` will meet its required lifetime bounds... + | +note: ...that is required by this bound + --> $DIR/type-match-with-late-bound.rs:10:15 + | +LL | for F: 'a, + | ^^ +help: consider adding an explicit lifetime bound + | +LL | for F: 'a, !1_"F": 'a + | ~~~~~~~~~~~~ + error[E0309]: the placeholder type `!1_"F"` may not live long enough --> $DIR/type-match-with-late-bound.rs:11:1 | @@ -35,6 +56,6 @@ help: consider adding an explicit lifetime bound LL | for F: 'a, !2_"F": 'a | ~~~~~~~~~~~~ -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0309`.