Skip to content

Emit warning when bound is trivially false #100090

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 67 additions & 23 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ use rustc_hir::ItemKind;
use rustc_infer::infer::outlives::env::{OutlivesEnvironment, RegionBoundPairs};
use rustc_infer::infer::outlives::obligations::TypeOutlives;
use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::Normalized;
use rustc_infer::traits::{Normalized, TraitEngine, TraitEngineExt as _};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
@@ -27,7 +27,8 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
use rustc_trait_selection::traits::query::normalize::AtExt;
use rustc_trait_selection::traits::query::NoSolution;
use rustc_trait_selection::traits::{
self, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
self, FulfillmentContext, ObligationCause, ObligationCauseCode, ObligationCtxt,
SelectionContext, WellFormedLoc,
};

use std::cell::LazyCell;
@@ -1817,7 +1818,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
/// Feature gates RFC 2056 -- trivial bounds, checking for global bounds that
/// aren't true.
fn check_false_global_bounds(&mut self) {
let tcx = self.ocx.infcx.tcx;
let tcx = self.infcx.tcx;
let mut span = self.span;
let empty_env = ty::ParamEnv::empty();

@@ -1833,33 +1834,76 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
if let ty::PredicateKind::WellFormed(..) = obligation.predicate.kind().skip_binder() {
continue;
}
let pred = obligation.predicate;
// Match the existing behavior.
if pred.is_global() && !pred.has_late_bound_regions() {
let pred = self.normalize(span, None, pred);
let hir_node = tcx.hir().find(self.body_id);

// only use the span of the predicate clause (#90869)
let pred = obligation.predicate;

if let Some(hir::Generics { predicates, .. }) =
hir_node.and_then(|node| node.generics())
{
let obligation_span = obligation.cause.span();

span = predicates
.iter()
// There seems to be no better way to find out which predicate we are in
.find(|pred| pred.span().contains(obligation_span))
.map(|pred| pred.span())
.unwrap_or(obligation_span);
}
// only use the span of the predicate clause (#90869)
let hir_node = tcx.hir().find(self.body_id);
if let Some(hir::Generics { predicates, .. }) =
hir_node.and_then(|node| node.generics())
{
let obligation_span = obligation.cause.span();
span = predicates
.iter()
// There seems to be no better way to find out which predicate we are in
.find(|pred| pred.span().contains(obligation_span))
.map(|pred| pred.span())
.unwrap_or(obligation_span);
}

// Match the existing behavior.
if pred.is_global() && !pred.has_late_bound_regions() {
let normalized_pred = self.normalize(span, None, pred);
let obligation = traits::Obligation::new(
traits::ObligationCause::new(span, self.body_id, traits::TrivialBound),
empty_env,
pred,
normalized_pred,
);
self.ocx.register_obligation(obligation);
self.register_obligation(obligation);
} else {
self.infcx.probe(|_| {
// Manually normalize because `wfcx.normalize` may report errors
let Normalized { value: normalized_pred, obligations } = traits::normalize(
&mut SelectionContext::new(self.infcx),
self.param_env,
ObligationCause::dummy(),
pred,
);
if normalized_pred.is_global() {
let mut fulfill_cx = FulfillmentContext::new_in_snapshot();
fulfill_cx.register_predicate_obligations(self.infcx, obligations);
fulfill_cx.register_predicate_obligation(
self.infcx,
traits::Obligation::new(
traits::ObligationCause::new(
span,
self.body_id,
traits::TrivialBound,
),
empty_env,
normalized_pred,
),
);
if !fulfill_cx.select_all_or_error(self.infcx).is_empty() {
let mut diag = self.tcx()
.sess
.struct_span_warn(
span,
format!("the where-clause bound `{pred}` is impossible to satisfy"),
);
diag.span_label(
self.span,
"this item cannot be referenced without causing an error",
);
if self.infcx.tcx.sess.opts.unstable_features.is_nightly_build() {
diag.help(
"add `#![feature(trivial_bounds)]` to the crate attributes to allow it",
);
}
diag.emit();
}
}
});
}
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,32 @@
warning: the where-clause bound `for<'a> <Parameterized<'a> as Foo>::Item == &'a i32` is impossible to satisfy
--> $DIR/bound-lifetime-in-binding-only.rs:67:19
|
LL | fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
| _- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | |
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: the where-clause bound `for<'a> Parameterized<'a>: Foo` is impossible to satisfy
--> $DIR/bound-lifetime-in-binding-only.rs:67:19
|
LL | fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
| _- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | |
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error: fatal error triggered by #[rustc_error]
--> $DIR/bound-lifetime-in-binding-only.rs:71:1
--> $DIR/bound-lifetime-in-binding-only.rs:73:1
|
LL | fn main() { }
| ^^^^^^^^^

error: aborting due to previous error
error: aborting due to previous error; 2 warnings emitted

Original file line number Diff line number Diff line change
@@ -65,6 +65,8 @@ fn ok2<T: for<'a,'b> Fn<(&'b Parameterized<'a>,), Output=&'a i32>>() {

#[cfg(ok)]
fn ok3<T>() where for<'a> Parameterized<'a>: Foo<Item=&'a i32> {
//[ok]~^ WARNING the where-clause bound
//[ok]~| WARNING the where-clause bound
}

#[rustc_error]
2 changes: 1 addition & 1 deletion src/test/ui/associated-types/issue-59324.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ pub trait ThriftService<Bug: NotFoo>:
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
//~| ERROR the trait bound `Bug: Foo` is not satisfied
Service<AssocType = <Bug as Foo>::OnlyFoo>
{
{
fn get_service(
//~^ ERROR the trait bound `Bug: Foo` is not satisfied
&self,
1 change: 1 addition & 0 deletions src/test/ui/associated-types/issue-69398.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ pub trait Broken {
impl<T> Broken for T {
type Assoc = ();
fn broken(&self) where Self::Assoc: Foo {
//~^ WARNING the where-clause bound
let _x: <Self::Assoc as Foo>::Bar;
}
}
14 changes: 14 additions & 0 deletions src/test/ui/associated-types/issue-69398.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a bit unfortunate that the bound we say is not the bound that's written.

--> $DIR/issue-69398.rs:14:28
|
LL | fn broken(&self) where Self::Assoc: Foo {
| _____- ^^^^^^^^^^^^^^^^
LL | |
LL | | let _x: <Self::Assoc as Foo>::Bar;
LL | | }
| |_____- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 1 warning emitted

3 changes: 3 additions & 0 deletions src/test/ui/consts/issue-67696-const-prop-ice.rs
Original file line number Diff line number Diff line change
@@ -11,6 +11,9 @@ trait A {

impl A for [fn(&())] {
fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
//~^ WARNING the where-clause bound
//~| WARNING the where-clause bound
//~| WARNING the where-clause bound
}

impl A for i32 {
26 changes: 26 additions & 0 deletions src/test/ui/consts/issue-67696-const-prop-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
warning: the where-clause bound `[for<'r> fn(&'r ())]: Copy` is impossible to satisfy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is certainly not great.

--> $DIR/issue-67696-const-prop-ice.rs:13:33
|
LL | fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
| ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: the where-clause bound `[for<'r> fn(&'r ())]: Clone` is impossible to satisfy
--> $DIR/issue-67696-const-prop-ice.rs:13:33
|
LL | fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
| ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: the where-clause bound `[for<'r> fn(&'r ())]: Sized` is impossible to satisfy
--> $DIR/issue-67696-const-prop-ice.rs:13:33
|
LL | fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) }
| ----------------------------^^^^^^^^^^------------------- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 3 warnings emitted

1 change: 1 addition & 0 deletions src/test/ui/feature-gates/feature-gate-trivial_bounds.rs
Original file line number Diff line number Diff line change
@@ -63,6 +63,7 @@ fn return_str() -> str where str: Sized { //~ ERROR
// This is currently accepted because the function pointer isn't
// considered global.
fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
//~^ WARNING the where-clause bound
x.test();
}

14 changes: 13 additions & 1 deletion src/test/ui/feature-gates/feature-gate-trivial_bounds.stderr
Original file line number Diff line number Diff line change
@@ -113,6 +113,18 @@ LL | fn return_str() -> str where str: Sized {
= help: see issue #48214
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable

error: aborting due to 11 previous errors
warning: the where-clause bound `for<'r> fn(&'r ()): Foo` is impossible to satisfy
--> $DIR/feature-gate-trivial_bounds.rs:65:32
|
LL | fn global_hr(x: fn(&())) where fn(&()): Foo { // OK
| _- ^^^^^^^^^^^^
LL | |
LL | | x.test();
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error: aborting due to 11 previous errors; 1 warning emitted

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
trait StackContext
where
Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
//~^ WARNING the where-clause bound
{
type Dispatcher;
}
@@ -26,6 +27,7 @@ where
struct EthernetWorker<C>(C)
where
Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
//~^ WARNING the where-clause bound
impl<C> EthernetWorker<C> {}
//~^ ERROR: is not satisfied [E0277]

Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is impossible to satisfy
--> $DIR/issue-89118.rs:9:5
|
LL | / trait StackContext
LL | | where
LL | | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | | {
LL | | type Dispatcher;
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
--> $DIR/issue-89118.rs:19:8
--> $DIR/issue-89118.rs:20:8
|
LL | C: StackContext,
| ^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -18,8 +33,18 @@ LL | where
LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`

warning: the where-clause bound `for<'a> Ctx<()>: BufferUdpStateContext<&'a ()>` is impossible to satisfy
--> $DIR/issue-89118.rs:29:5
|
LL | / struct EthernetWorker<C>(C)
LL | | where
LL | | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
| |_____^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
--> $DIR/issue-89118.rs:29:9
--> $DIR/issue-89118.rs:31:9
|
LL | impl<C> EthernetWorker<C> {}
| ^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -30,7 +55,7 @@ note: required because of the requirements on the impl of `for<'a> BufferUdpStat
LL | impl<B: BufferMut, C> BufferUdpStateContext<B> for C {}
| ^^^^^^^^^^^^^^^^^^^^^^^^ ^
note: required by a bound in `EthernetWorker`
--> $DIR/issue-89118.rs:28:14
--> $DIR/issue-89118.rs:29:14
|
LL | struct EthernetWorker<C>(C)
| -------------- required by a bound in this
@@ -39,7 +64,7 @@ LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker`

error[E0277]: the trait bound `for<'a> &'a (): BufferMut` is not satisfied
--> $DIR/issue-89118.rs:22:20
--> $DIR/issue-89118.rs:23:20
|
LL | type Handler = Ctx<C::Dispatcher>;
| ^^^^^^^^^^^^^^^^^^ the trait `for<'a> BufferMut` is not implemented for `&'a ()`
@@ -58,6 +83,6 @@ LL | where
LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext`

error: aborting due to 3 previous errors
error: aborting due to 3 previous errors; 2 warnings emitted

For more information about this error, try `rustc --explain E0277`.
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-36839.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ pub trait Broken {
impl<T> Broken for T {
type Assoc = ();
fn broken(&self) where Self::Assoc: Foo {
//~^ WARNING the where-clause bound
let _x: <Self::Assoc as Foo>::Bar;
}
}
14 changes: 14 additions & 0 deletions src/test/ui/issues/issue-36839.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
--> $DIR/issue-36839.rs:14:28
|
LL | fn broken(&self) where Self::Assoc: Foo {
| _____- ^^^^^^^^^^^^^^^^
LL | |
LL | | let _x: <Self::Assoc as Foo>::Bar;
LL | | }
| |_____- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 1 warning emitted

1 change: 1 addition & 0 deletions src/test/ui/issues/issue-39970.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ impl<'a> Array<'a> for () {
impl Visit for () where
//(): for<'a> Array<'a, Element=&'a ()>, // No ICE
(): for<'a> Array<'a, Element=()>, // ICE
//~^ WARNING the where-clause bound
{}

fn main() {
17 changes: 15 additions & 2 deletions src/test/ui/issues/issue-39970.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
warning: the where-clause bound `for<'a> <() as Array<'a>>::Element == ()` is impossible to satisfy
--> $DIR/issue-39970.rs:15:5
|
LL | / impl Visit for () where
LL | | //(): for<'a> Array<'a, Element=&'a ()>, // No ICE
LL | | (): for<'a> Array<'a, Element=()>, // ICE
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | | {}
| |__- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error[E0271]: type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
--> $DIR/issue-39970.rs:19:5
--> $DIR/issue-39970.rs:20:5
|
LL | <() as Visit>::visit();
| ^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `for<'a> <() as Array<'a>>::Element == ()`
@@ -15,6 +28,6 @@ note: required because of the requirements on the impl of `Visit` for `()`
LL | impl Visit for () where
| ^^^^^ ^^

error: aborting due to previous error
error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0271`.
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-42796.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ impl<T, Smoke> Mirror<Smoke> for T {
}

pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy {
//~^ WARNING the where-clause bound
loop { drop(victim); }
}

16 changes: 14 additions & 2 deletions src/test/ui/issues/issue-42796.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
warning: the where-clause bound `<String as Mirror<S>>::Image: Copy` is impossible to satisfy
--> $DIR/issue-42796.rs:9:40
|
LL | pub fn poison<S>(victim: String) where <String as Mirror<S>>::Image: Copy {
| _- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | | loop { drop(victim); }
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

error[E0382]: borrow of moved value: `s`
--> $DIR/issue-42796.rs:18:20
--> $DIR/issue-42796.rs:19:20
|
LL | let s = "Hello!".to_owned();
| - move occurs because `s` has type `String`, which does not implement the `Copy` trait
@@ -11,6 +23,6 @@ LL | println!("{}", s);
|
= note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error
error: aborting due to previous error; 1 warning emitted

For more information about this error, try `rustc --explain E0382`.
3 changes: 2 additions & 1 deletion src/test/ui/issues/issue-50714-1.rs
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
extern crate std;

#[start]
fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq { //~ ERROR [E0647]
fn start(_: isize, _: *const *const u8) -> isize where fn(&()): Eq {
//~^ ERROR start function is not allowed to have a `where` clause
0
}
7 changes: 6 additions & 1 deletion src/test/ui/issues/issue-50714.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
// Regression test for issue 50714, make sure that this isn't a linker error.

fn main() where fn(&()): Eq {} //~ ERROR [E0646]
fn main()
where
//~^ ERROR `main` function is not allowed to have a `where` clause
fn(&()): Eq,
{
}
8 changes: 5 additions & 3 deletions src/test/ui/issues/issue-50714.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error[E0646]: `main` function is not allowed to have a `where` clause
--> $DIR/issue-50714.rs:3:11
--> $DIR/issue-50714.rs:4:1
|
LL | fn main() where fn(&()): Eq {}
| ^^^^^^^^^^^^^^^^^ `main` cannot have a `where` clause
LL | / where
LL | |
LL | | fn(&()): Eq,
| |________________^ `main` cannot have a `where` clause

error: aborting due to previous error

1 change: 1 addition & 0 deletions src/test/ui/mir/issue-91745.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ pub trait Broken {
impl<T> Broken for T {
type Assoc = ();
fn broken(&self) where Self::Assoc: Foo {
//~^ WARNING the where-clause bound
let _x: <Self::Assoc as Foo>::Bar;
}
}
14 changes: 14 additions & 0 deletions src/test/ui/mir/issue-91745.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
warning: the where-clause bound `<T as Broken>::Assoc: Foo` is impossible to satisfy
--> $DIR/issue-91745.rs:14:28
|
LL | fn broken(&self) where Self::Assoc: Foo {
| _____- ^^^^^^^^^^^^^^^^
LL | |
LL | | let _x: <Self::Assoc as Foo>::Bar;
LL | | }
| |_____- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 1 warning emitted

1 change: 1 addition & 0 deletions src/test/ui/trait-bounds/issue-94680.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ fn main() {
pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
where
for<'any> &'any mut T: Clone,
//~^ WARNING the where-clause bound
{
(it.clone(), it)
}
17 changes: 17 additions & 0 deletions src/test/ui/trait-bounds/issue-94680.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the where-clause bound `for<'any> &'any mut (): Clone` is impossible to satisfy
--> $DIR/issue-94680.rs:9:13
|
LL | / pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
LL | | where
LL | | for<'any> &'any mut T: Clone,
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
LL | | {
LL | | (it.clone(), it)
LL | | }
| |_________- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 1 warning emitted

1 change: 1 addition & 0 deletions src/test/ui/trait-bounds/issue-94999.rs
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ impl Holds for X {
impl<Q> Clone for X
where
<S as Identity<Q>>::T: Clone,
//~^ WARNING the where-clause bound
X: Holds<Q = Q>,
{
fn clone(&self) -> Self {
17 changes: 17 additions & 0 deletions src/test/ui/trait-bounds/issue-94999.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
warning: the where-clause bound `<S as Identity<Q>>::T: Clone` is impossible to satisfy
--> $DIR/issue-94999.rs:26:5
|
LL | / impl<Q> Clone for X
LL | | where
LL | | <S as Identity<Q>>::T: Clone,
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | |
... |
LL | | }
LL | | }
| |_- this item cannot be referenced without causing an error
|
= help: add `#![feature(trivial_bounds)]` to the crate attributes to allow it

warning: 1 warning emitted