Skip to content

Commit

Permalink
der-derive: avoid type inference when using default
Browse files Browse the repository at this point in the history
This is another take on #1441. This is intended to make sure we can
still continue to use `Default::default` and not break future releases
by mistake.
  • Loading branch information
baloo committed Jul 9, 2024
1 parent 886988b commit 9f1f711
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 6 deletions.
15 changes: 9 additions & 6 deletions der/derive/src/sequence/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl SequenceField {
!attrs.optional,
"`default`, and `optional` are mutually exclusive"
);
lowerer.apply_default(&self.ident, default);
lowerer.apply_default(&self.ident, default, &self.field_type);
}

lowerer.into_tokens()
Expand Down Expand Up @@ -189,14 +189,17 @@ impl LowerFieldEncoder {
}

/// Handle default value for a type.
fn apply_default(&mut self, ident: &Ident, default: &Path) {
fn apply_default(&mut self, ident: &Ident, default: &Path, field_type: &Type) {
let encoder = &self.encoder;

self.encoder = quote! {
if &self.#ident == &#default() {
None
} else {
Some(#encoder)
{
let default_value: #field_type = #default();
if &self.#ident == &default_value {
None
} else {
Some(#encoder)
}
}
};
}
Expand Down
56 changes: 56 additions & 0 deletions der/tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,3 +461,59 @@ mod sequence {
);
}
}

mod infer_default {
//! When another crate might define a PartialEq for another type, the use of
//! `default="Default::default"` in the der derivation will not provide enough
//! information for `der_derive` crate to figure out.
//!
//! This provides a reproduction for that case. This is intended to fail when we
//! compile tests.
//! ```
//! error[E0282]: type annotations needed
//! --> der/tests/derive.rs:480:26
//! |
//!480 | #[asn1(default = "Default::default")]
//! | ^^^^^^^^^^^^^^^^^^ cannot infer type
//!
//!error[E0283]: type annotations needed
//! --> der/tests/derive.rs:478:14
//! |
//!478 | #[derive(Sequence)]
//! | ^^^^^^^^ cannot infer type
//! |
//!note: multiple `impl`s satisfying `bool: PartialEq<_>` found
//! --> der/tests/derive.rs:472:5
//! |
//!472 | impl PartialEq<BooleanIsh> for bool {
//! | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! = note: and another `impl` found in the `core` crate:
//! - impl<host> PartialEq for bool
//! where the constant `host` has type `bool`;
//! = note: required for `&bool` to implement `PartialEq<&_>`
//! = note: this error originates in the derive macro `Sequence` (in Nightly builds, run with -Z macro-backtrace for more info)
//! ```
use der::Sequence;

struct BooleanIsh;

impl PartialEq<BooleanIsh> for bool {
fn eq(&self, _other: &BooleanIsh) -> bool {
unimplemented!("This is only here to mess up the compiler's type inference")
}
}

#[derive(Sequence)]
struct Foo {
#[asn1(default = "Default::default")]
pub use_default_default: bool,

#[asn1(default = "something_true")]
pub use_custom: bool,
}

fn something_true() -> bool {
todo!()
}
}

0 comments on commit 9f1f711

Please sign in to comment.