From 692bc5b3ca777363759b760f7c67084a719dc2b6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 18 Oct 2022 13:07:20 +1100 Subject: [PATCH] Fix `TyKind::is_simple_path`. PR #98758 introduced code to avoid redundant assertions in derived code like this: ``` let _: ::core::clone::AssertParamIsClone; let _: ::core::clone::AssertParamIsClone; ``` 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` and `Option` to be the same. This commit fixes `is_simple_path`. Fixes #103157. (cherry picked from commit 9a23f60f9c801dd0b4686cc75c6a9979bd8928fa) --- compiler/rustc_ast/src/ast.rs | 7 +++-- .../ui/deriving/deriving-all-codegen.stdout | 2 ++ src/test/ui/deriving/issue-103157.rs | 12 ++++++++ src/test/ui/deriving/issue-103157.stderr | 30 +++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/deriving/issue-103157.rs create mode 100644 src/test/ui/deriving/issue-103157.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 6c514c75a500c..df94b70d27894 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2060,8 +2060,11 @@ impl TyKind { } pub fn is_simple_path(&self) -> Option { - if let TyKind::Path(None, Path { segments, .. }) = &self && segments.len() == 1 { - Some(segments[0].ident.name) + if let TyKind::Path(None, Path { segments, .. }) = &self + && let [segment] = &segments[..] + && segment.args.is_none() + { + Some(segment.ident.name) } else { None } diff --git a/src/test/ui/deriving/deriving-all-codegen.stdout b/src/test/ui/deriving/deriving-all-codegen.stdout index 6baa7317b12bb..56efc2a59ecb8 100644 --- a/src/test/ui/deriving/deriving-all-codegen.stdout +++ b/src/test/ui/deriving/deriving-all-codegen.stdout @@ -799,6 +799,7 @@ impl ::core::clone::Clone for Mixed { fn clone(&self) -> Mixed { let _: ::core::clone::AssertParamIsClone; let _: ::core::clone::AssertParamIsClone>; + let _: ::core::clone::AssertParamIsClone>; *self } } @@ -866,6 +867,7 @@ impl ::core::cmp::Eq for Mixed { fn assert_receiver_is_total_eq(&self) -> () { let _: ::core::cmp::AssertParamIsEq; let _: ::core::cmp::AssertParamIsEq>; + let _: ::core::cmp::AssertParamIsEq>; } } #[automatically_derived] diff --git a/src/test/ui/deriving/issue-103157.rs b/src/test/ui/deriving/issue-103157.rs new file mode 100644 index 0000000000000..52b4c7898d87b --- /dev/null +++ b/src/test/ui/deriving/issue-103157.rs @@ -0,0 +1,12 @@ +// check-fail + +#[derive(PartialEq, Eq)] +pub enum Value { + Boolean(Option), + Float(Option), //~ ERROR the trait bound `f64: Eq` is not satisfied +} + +fn main() { + let a = Value::Float(Some(f64::NAN)); + assert!(a == a); +} diff --git a/src/test/ui/deriving/issue-103157.stderr b/src/test/ui/deriving/issue-103157.stderr new file mode 100644 index 0000000000000..ee3528fe1062d --- /dev/null +++ b/src/test/ui/deriving/issue-103157.stderr @@ -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), + | ^^^^^^^^^^^ 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` to implement `Eq` +note: required by a bound in `AssertParamIsEq` + --> $SRC_DIR/core/src/cmp.rs:LL:COL + | +LL | pub struct AssertParamIsEq { + | ^^ 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`.