mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 11:23:03 +00:00
rustc: Implement dereference via unary '*' for structs. r=nmatsakis
This commit is contained in:
parent
4165edff22
commit
65d4dbeb12
@ -651,6 +651,41 @@ impl Datum {
|
||||
}
|
||||
};
|
||||
}
|
||||
ty::ty_class(did, ref substs) => {
|
||||
// Check whether this struct is a newtype struct.
|
||||
let fields = ty::class_items_as_fields(ccx.tcx, did, substs);
|
||||
if fields.len() != 1 || fields[0].ident !=
|
||||
syntax::parse::token::special_idents::unnamed_field {
|
||||
return None;
|
||||
}
|
||||
|
||||
let ty = fields[0].mt.ty;
|
||||
return match self.mode {
|
||||
ByRef => {
|
||||
// Recast lv.val as a pointer to the newtype rather
|
||||
// than a pointer to the struct type.
|
||||
// XXX: This isn't correct for structs with
|
||||
// destructors.
|
||||
Some(Datum {
|
||||
val: GEPi(bcx, self.val, [0, 0, 0]),
|
||||
ty: ty,
|
||||
mode: ByRef,
|
||||
source: FromLvalue
|
||||
})
|
||||
}
|
||||
ByValue => {
|
||||
// Actually, this case cannot happen right now,
|
||||
// because structs are never immediate. But in
|
||||
// principle, newtype'd immediate values should be
|
||||
// immediate, and in that case the * would be a no-op
|
||||
// except for changing the type, so I am putting this
|
||||
// code in place here to do the right thing if this
|
||||
// change ever goes through.
|
||||
assert ty::type_is_immediate(ty);
|
||||
Some(Datum {ty: ty, ..self})
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => { // not derefable.
|
||||
return None;
|
||||
}
|
||||
|
@ -2597,6 +2597,16 @@ fn deref_sty(cx: ctxt, sty: &sty, expl: bool) -> Option<mt> {
|
||||
}
|
||||
}
|
||||
|
||||
ty_class(did, ref substs) => {
|
||||
let fields = class_items_as_fields(cx, did, substs);
|
||||
if fields.len() == 1 && fields[0].ident ==
|
||||
syntax::parse::token::special_idents::unnamed_field {
|
||||
Some({ty: fields[0].mt.ty, mutbl: ast::m_imm})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
@ -1768,6 +1768,12 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
||||
with a single variant which has a \
|
||||
single argument");
|
||||
}
|
||||
ty::ty_class(*) => {
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
~"can only dereference structs with one anonymous \
|
||||
field");
|
||||
}
|
||||
_ => {
|
||||
tcx.sess.span_err(
|
||||
expr.span,
|
||||
|
7
src/test/run-pass/struct-deref.rs
Normal file
7
src/test/run-pass/struct-deref.rs
Normal file
@ -0,0 +1,7 @@
|
||||
struct Foo(int);
|
||||
|
||||
fn main() {
|
||||
let x: Foo = Foo(2);
|
||||
assert *x == 2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user