Skip to content

Commit

Permalink
Fix TyKind::is_simple_path.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nnethercote committed Oct 18, 2022
1 parent dfa9d5c commit 9a23f60
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 2 deletions.
7 changes: 5 additions & 2 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/deriving/deriving-all-codegen.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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]
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/deriving/issue-103157.rs
Original file line number Diff line number Diff line change
@@ -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);
}
30 changes: 30 additions & 0 deletions src/test/ui/deriving/issue-103157.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 9a23f60

Please sign in to comment.