Fix TyKind::is_simple_path.

PR #98758 introduced code to avoid redundant assertions in derived code
like this:
```
let _: ::core::clone::AssertParamIsClone<u32>;
let _: ::core::clone::AssertParamIsClone<u32>;
```
But the predicate `is_simple_path` introduced as part of this failed to
account for generic arguments. Therefore the deriving code erroneously
considers types like `Option<bool>` and `Option<f32>` to be the same.

This commit fixes `is_simple_path`.

Fixes #103157.
This commit is contained in:
Nicholas Nethercote 2022-10-18 13:07:20 +11:00
parent dfa9d5c971
commit 9a23f60f9c
4 changed files with 49 additions and 2 deletions

View File

@ -2060,8 +2060,11 @@ pub fn is_unit(&self) -> bool {
} }
pub fn is_simple_path(&self) -> Option<Symbol> { pub fn is_simple_path(&self) -> Option<Symbol> {
if let TyKind::Path(None, Path { segments, .. }) = &self && segments.len() == 1 { if let TyKind::Path(None, Path { segments, .. }) = &self
Some(segments[0].ident.name) && let [segment] = &segments[..]
&& segment.args.is_none()
{
Some(segment.ident.name)
} else { } else {
None None
} }

View File

@ -799,6 +799,7 @@ impl ::core::clone::Clone for Mixed {
fn clone(&self) -> Mixed { fn clone(&self) -> Mixed {
let _: ::core::clone::AssertParamIsClone<u32>; let _: ::core::clone::AssertParamIsClone<u32>;
let _: ::core::clone::AssertParamIsClone<Option<u32>>; let _: ::core::clone::AssertParamIsClone<Option<u32>>;
let _: ::core::clone::AssertParamIsClone<Option<i32>>;
*self *self
} }
} }
@ -866,6 +867,7 @@ impl ::core::cmp::Eq for Mixed {
fn assert_receiver_is_total_eq(&self) -> () { fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<u32>; let _: ::core::cmp::AssertParamIsEq<u32>;
let _: ::core::cmp::AssertParamIsEq<Option<u32>>; let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
} }
} }
#[automatically_derived] #[automatically_derived]

View File

@ -0,0 +1,12 @@
// check-fail
#[derive(PartialEq, Eq)]
pub enum Value {
Boolean(Option<bool>),
Float(Option<f64>), //~ ERROR the trait bound `f64: Eq` is not satisfied
}
fn main() {
let a = Value::Float(Some(f64::NAN));
assert!(a == a);
}

View File

@ -0,0 +1,30 @@
error[E0277]: the trait bound `f64: Eq` is not satisfied
--> $DIR/issue-103157.rs:6:11
|
LL | #[derive(PartialEq, Eq)]
| -- in this derive macro expansion
...
LL | Float(Option<f64>),
| ^^^^^^^^^^^ the trait `Eq` is not implemented for `f64`
|
= help: the following other types implement trait `Eq`:
i128
i16
i32
i64
i8
isize
u128
u16
and 4 others
= note: required for `Option<f64>` to implement `Eq`
note: required by a bound in `AssertParamIsEq`
--> $SRC_DIR/core/src/cmp.rs:LL:COL
|
LL | pub struct AssertParamIsEq<T: Eq + ?Sized> {
| ^^ required by this bound in `AssertParamIsEq`
= note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.