Struct rustc_builtin_macros::deriving::generic::MethodDef [−][src]
pub struct MethodDef<'a> {
pub name: Symbol,
pub generics: Bounds,
pub explicit_self: Option<Option<PtrTy>>,
pub args: Vec<(Ty, Symbol)>,
pub ret_ty: Ty,
pub attributes: Vec<Attribute>,
pub is_unsafe: bool,
pub unify_fieldless_variants: bool,
pub combine_substructure: RefCell<Box<dyn FnMut(&mut ExtCtxt<'_>, Span, &Substructure<'_>) -> P<Expr> + 'a>>,
}
Fields
name: Symbol
name of the method
generics: Bounds
List of generics, e.g., R: rand::Rng
explicit_self: Option<Option<PtrTy>>
Whether there is a self argument (outer Option) i.e., whether this is a static function, and whether it is a pointer (inner Option)
args: Vec<(Ty, Symbol)>
Arguments other than the self argument
ret_ty: Ty
Returns type
attributes: Vec<Attribute>
is_unsafe: bool
unify_fieldless_variants: bool
Can we combine fieldless variants for enums into a single match arm?
combine_substructure: RefCell<Box<dyn FnMut(&mut ExtCtxt<'_>, Span, &Substructure<'_>) -> P<Expr> + 'a>>
Implementations
fn call_substructure_method(
&self,
cx: &mut ExtCtxt<'_>,
trait_: &TraitDef<'_>,
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>],
fields: &SubstructureFields<'_>
) -> P<Expr>
fn get_ret_ty(
&self,
cx: &mut ExtCtxt<'_>,
trait_: &TraitDef<'_>,
generics: &Generics,
type_ident: Ident
) -> P<Ty>
fn split_self_nonself_args(
&self,
cx: &mut ExtCtxt<'_>,
trait_: &TraitDef<'_>,
type_ident: Ident,
generics: &Generics
) -> (Option<ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<Ty>)>)
fn create_method(
&self,
cx: &mut ExtCtxt<'_>,
trait_: &TraitDef<'_>,
type_ident: Ident,
generics: &Generics,
explicit_self: Option<ExplicitSelf>,
arg_types: Vec<(Ident, P<Ty>)>,
body: P<Expr>
) -> P<AssocItem>
#[derive(PartialEq)]
struct A { x: i32, y: i32 }
// equivalent to:
impl PartialEq for A {
fn eq(&self, other: &A) -> bool {
match *self {
A {x: ref __self_0_0, y: ref __self_0_1} => {
match *other {
A {x: ref __self_1_0, y: ref __self_1_1} => {
__self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1)
}
}
}
}
}
}
// or if A is repr(packed) - note fields are matched by-value
// instead of by-reference.
impl PartialEq for A {
fn eq(&self, other: &A) -> bool {
match *self {
A {x: __self_0_0, y: __self_0_1} => {
match other {
A {x: __self_1_0, y: __self_1_1} => {
__self_0_0.eq(&__self_1_0) && __self_0_1.eq(&__self_1_1)
}
}
}
}
}
}
fn expand_static_struct_method_body(
&self,
cx: &mut ExtCtxt<'_>,
trait_: &TraitDef<'_>,
struct_def: &VariantData,
type_ident: Ident,
self_args: &[P<Expr>],
nonself_args: &[P<Expr>]
) -> P<Expr>
#[derive(PartialEq)]
enum A {
A1,
A2(i32)
}
// is equivalent to
impl PartialEq for A {
fn eq(&self, other: &A) -> ::bool {
match (&*self, &*other) {
(&A1, &A1) => true,
(&A2(ref self_0),
&A2(ref __arg_1_0)) => (*self_0).eq(&(*__arg_1_0)),
_ => {
let __self_vi = match *self { A1(..) => 0, A2(..) => 1 };
let __arg_1_vi = match *other { A1(..) => 0, A2(..) => 1 };
false
}
}
}
}
(Of course __self_vi
and __arg_1_vi
are unused for
PartialEq
, and those subcomputations will hopefully be removed
as their results are unused. The point of __self_vi
and
__arg_1_vi
is for PartialOrd
; see #15503.)
Creates a match for a tuple of all self_args
, where either all
variants match, or it falls into a catch-all for when one variant
does not match.
There are N + 1 cases because is a case for each of the N
variants where all of the variants match, and one catch-all for
when one does not match.
As an optimization we generate code which checks whether all variants
match first which makes llvm see that C-like enums can be compiled into
a simple equality check (for PartialEq).
The catch-all handler is provided access the variant index values
for each of the self-args, carried in precomputed variables.
let __self0_vi = std::intrinsics::discriminant_value(&self);
let __self1_vi = std::intrinsics::discriminant_value(&arg1);
let __self2_vi = std::intrinsics::discriminant_value(&arg2);
if __self0_vi == __self1_vi && __self0_vi == __self2_vi && ... {
match (...) {
(Variant1, Variant1, ...) => Body1
(Variant2, Variant2, ...) => Body2,
...
_ => ::core::intrinsics::unreachable()
}
}
else {
... // catch-all remainder can inspect above variant index values.
}
Auto Trait Implementations
impl<'a> !RefUnwindSafe for MethodDef<'a>
impl<'a> !UnwindSafe for MethodDef<'a>
Blanket Implementations
Layout
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference’s “Type Layout” chapter for details on type layout guarantees.
Size: 192 bytes