about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2022-10-18 13:07:20 +1100
committerNicholas Nethercote <n.nethercote@gmail.com>2022-10-18 15:51:23 +1100
commit9a23f60f9c801dd0b4686cc75c6a9979bd8928fa (patch)
tree448ae0dd90b2574f41263fee1e607869b40058d2
parentdfa9d5c971d74aa5bdf6b99253fe4b7db39f9b67 (diff)
downloadrust-9a23f60f9c801dd0b4686cc75c6a9979bd8928fa.tar.gz
rust-9a23f60f9c801dd0b4686cc75c6a9979bd8928fa.zip
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.
-rw-r--r--compiler/rustc_ast/src/ast.rs7
-rw-r--r--src/test/ui/deriving/deriving-all-codegen.stdout2
-rw-r--r--src/test/ui/deriving/issue-103157.rs12
-rw-r--r--src/test/ui/deriving/issue-103157.stderr30
4 files changed, 49 insertions, 2 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 60b7f2e4c22..7112c267577 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<Symbol> {
-        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 6baa7317b12..56efc2a59ec 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<u32>;
         let _: ::core::clone::AssertParamIsClone<Option<u32>>;
+        let _: ::core::clone::AssertParamIsClone<Option<i32>>;
         *self
     }
 }
@@ -866,6 +867,7 @@ impl ::core::cmp::Eq for Mixed {
     fn assert_receiver_is_total_eq(&self) -> () {
         let _: ::core::cmp::AssertParamIsEq<u32>;
         let _: ::core::cmp::AssertParamIsEq<Option<u32>>;
+        let _: ::core::cmp::AssertParamIsEq<Option<i32>>;
     }
 }
 #[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 00000000000..52b4c7898d8
--- /dev/null
+++ b/src/test/ui/deriving/issue-103157.rs
@@ -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);
+}
diff --git a/src/test/ui/deriving/issue-103157.stderr b/src/test/ui/deriving/issue-103157.stderr
new file mode 100644
index 00000000000..ee3528fe106
--- /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<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`.