librustc: Remove cross-borrowing of Box<T> to &T from the language,

except where trait objects are involved.

Part of issue #15349, though I'm leaving it open for trait objects.
Cross borrowing for trait objects remains because it is needed until we
have DST.

This will break code like:

    fn foo(x: &int) { ... }

    let a = box 3i;
    foo(a);

Change this code to:

    fn foo(x: &int) { ... }

    let a = box 3i;
    foo(&*a);

[breaking-change]
This commit is contained in:
Patrick Walton 2014-07-07 16:35:15 -07:00
parent ca24abd4d2
commit de70d76373
72 changed files with 206 additions and 204 deletions

View File

@ -67,7 +67,7 @@ Now we can call `compute_distance()`:
# let on_the_stack : Point = Point{x: 3.0, y: 4.0};
# let on_the_heap : Box<Point> = box Point{x: 7.0, y: 9.0};
# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
compute_distance(&on_the_stack, on_the_heap);
compute_distance(&on_the_stack, &*on_the_heap);
~~~
Here, the `&` operator takes the address of the variable
@ -77,10 +77,9 @@ value. We also call this _borrowing_ the local variable
`on_the_stack`, because we have created an alias: that is, another
name for the same data.
In the case of `on_the_heap`, however, no explicit action is necessary.
The compiler will automatically convert a box point to a reference like &point.
This is another form of borrowing; in this case, the contents of the owned box
are being lent out.
Likewise, in the case of `owned_box`,
the `&` operator is used in conjunction with the `*` operator
to take a reference to the contents of the box.
Whenever a caller lends data to a callee, there are some limitations on what
the caller can do with the original. For example, if the contents of a

View File

@ -279,7 +279,7 @@ fn main() {
let origin = &Point { x: 0.0, y: 0.0 };
let p1 = box Point { x: 5.0, y: 3.0 };
println!("{}", compute_distance(origin, p1));
println!("{}", compute_distance(origin, &*p1));
}
~~~

View File

@ -3243,7 +3243,7 @@ enum List { Nil, Cons(uint, Box<List>) }
fn is_sorted(list: &List) -> bool {
match *list {
Nil | Cons(_, box Nil) => true,
Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(*r)
Cons(x, ref r @ box Cons(y, _)) => (x <= y) && is_sorted(&**r)
}
}

View File

@ -1470,7 +1470,7 @@ Now we can call `compute_distance()` in various ways:
# let on_the_stack : Point = Point { x: 3.0, y: 4.0 };
# let on_the_heap : Box<Point> = box Point { x: 7.0, y: 9.0 };
# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
compute_distance(&on_the_stack, on_the_heap);
compute_distance(&on_the_stack, &*on_the_heap);
~~~
Here the `&` operator is used to take the address of the variable
@ -1480,11 +1480,9 @@ reference. We also call this _borrowing_ the local variable
`on_the_stack`, because we are creating an alias: that is, another
route to the same data.
In the case of `owned_box`, however, no
explicit action is necessary. The compiler will automatically convert
a box `box point` to a reference like
`&point`. This is another form of borrowing; in this case, the
contents of the owned box are being lent out.
Likewise, in the case of `owned_box`,
the `&` operator is used in conjunction with the `*` operator
to take a reference to the contents of the box.
Whenever a value is borrowed, there are some limitations on what you
can do with the original. For example, if the contents of a variable

View File

@ -67,7 +67,7 @@ impl<T:PartialEq> PartialEq for Box<T> {
impl<T:PartialOrd> PartialOrd for Box<T> {
#[inline]
fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
(**self).partial_cmp(*other)
(**self).partial_cmp(&**other)
}
#[inline]
fn lt(&self, other: &Box<T>) -> bool { *(*self) < *(*other) }
@ -80,7 +80,9 @@ impl<T:PartialOrd> PartialOrd for Box<T> {
}
impl<T: Ord> Ord for Box<T> {
#[inline]
fn cmp(&self, other: &Box<T>) -> Ordering { (**self).cmp(*other) }
fn cmp(&self, other: &Box<T>) -> Ordering {
(**self).cmp(&**other)
}
}
impl<T: Eq> Eq for Box<T> {}

View File

@ -516,7 +516,7 @@ define_iterator! {
fn deref<'a, K, V>(node: &'a Option<Box<TreeNode<K, V>>>) -> *const TreeNode<K, V> {
match *node {
Some(ref n) => {
let n: &TreeNode<K, V> = *n;
let n: &TreeNode<K, V> = &**n;
n as *const TreeNode<K, V>
}
None => ptr::null()

View File

@ -623,7 +623,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
pprust::lit_to_string(lit)).as_slice());
pprust::lit_to_string(&*lit)).as_slice());
return None
}
}
@ -631,7 +631,7 @@ fn parse(cx: &mut ExtCtxt, tts: &[ast::TokenTree]) -> Option<String> {
_ => {
cx.span_err(entry.span, format!(
"expected string literal but got `{}`",
pprust::expr_to_string(entry)).as_slice());
pprust::expr_to_string(&*entry)).as_slice());
return None
}
};

View File

@ -799,7 +799,7 @@ fn print_flowgraph<W:io::Writer>(variants: Vec<borrowck_dot::Variant>,
let ty_cx = &analysis.ty_cx;
let cfg = match code {
blocks::BlockCode(block) => cfg::CFG::new(ty_cx, &*block),
blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, fn_like.body()),
blocks::FnLikeCode(fn_like) => cfg::CFG::new(ty_cx, &*fn_like.body()),
};
debug!("cfg: {:?}", cfg);

View File

@ -1248,7 +1248,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, &*m));
encode_method_argument_names(ebml_w, m.pe_fn_decl());
encode_method_argument_names(ebml_w, &*m.pe_fn_decl());
}
}

View File

@ -267,7 +267,7 @@ fn enc_sty(w: &mut MemWriter, cx: &ctxt, st: &ty::sty) {
}
ty::ty_closure(ref f) => {
mywrite!(w, "f");
enc_closure_ty(w, cx, *f);
enc_closure_ty(w, cx, &**f);
}
ty::ty_bare_fn(ref f) => {
mywrite!(w, "F");

View File

@ -1557,7 +1557,7 @@ fn test_simplification() {
return alist {eq_fn: eq_int, data: Vec::new()};
}
).unwrap();
let item_in = e::IIItemRef(item);
let item_in = e::IIItemRef(&*item);
let item_out = simplify_ast(item_in);
let item_exp = ast::IIItem(quote_item!(cx,
fn new_int_alist<B>() -> alist<int, B> {
@ -1566,7 +1566,8 @@ fn test_simplification() {
).unwrap());
match (item_out, item_exp) {
(ast::IIItem(item_out), ast::IIItem(item_exp)) => {
assert!(pprust::item_to_string(item_out) == pprust::item_to_string(item_exp));
assert!(pprust::item_to_string(&*item_out) ==
pprust::item_to_string(&*item_exp));
}
_ => fail!()
}

View File

@ -216,8 +216,13 @@ pub fn build_borrowck_dataflow_data_for_fn<'a>(
let p = input.fn_parts;
let dataflow_data = build_borrowck_dataflow_data(
&mut bccx, &p.kind, p.decl, input.cfg, p.body, p.span, p.id);
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
&p.kind,
&*p.decl,
input.cfg,
&*p.body,
p.span,
p.id);
(bccx, dataflow_data)
}

View File

@ -47,7 +47,9 @@ impl fmt::Show for Matrix {
let &Matrix(ref m) = self;
let pretty_printed_matrix: Vec<Vec<String>> = m.iter().map(|row| {
row.iter().map(|&pat| pat_to_string(pat)).collect::<Vec<String>>()
row.iter()
.map(|&pat| pat_to_string(&*pat))
.collect::<Vec<String>>()
}).collect();
let column_count = m.iter().map(|row| row.len()).max().unwrap_or(0u);

View File

@ -212,7 +212,7 @@ impl<'a> MarkSymbolVisitor<'a> {
visit::walk_trait_method(self, &*trait_method, ctxt);
}
ast_map::NodeMethod(method) => {
visit::walk_block(self, method.pe_body(), ctxt);
visit::walk_block(self, &*method.pe_body(), ctxt);
}
ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt);
@ -520,7 +520,9 @@ impl<'a> Visitor<()> for DeadVisitor<'a> {
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method {
ast::Provided(ref method) => visit::walk_block(self, method.pe_body(), ()),
ast::Provided(ref method) => {
visit::walk_block(self, &*method.pe_body(), ())
}
ast::Required(_) => ()
}
}

View File

@ -316,14 +316,14 @@ impl<'a> ReachableContext<'a> {
// Keep going, nothing to get exported
}
ast::Provided(ref method) => {
visit::walk_block(self, method.pe_body(), ())
visit::walk_block(self, &*method.pe_body(), ())
}
}
}
ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) {
visit::walk_block(self, method.pe_body(), ())
visit::walk_block(self, &*method.pe_body(), ())
}
}
// Nothing to recurse on for these

View File

@ -3707,7 +3707,7 @@ impl<'a> Resolver<'a> {
match ty_m.explicit_self.node {
SelfExplicit(ref typ, _) => {
this.resolve_type(*typ)
this.resolve_type(&**typ)
}
_ => {}
}
@ -4044,7 +4044,7 @@ impl<'a> Resolver<'a> {
rib_kind);
match method.pe_explicit_self().node {
SelfExplicit(ref typ, _) => self.resolve_type(*typ),
SelfExplicit(ref typ, _) => self.resolve_type(&**typ),
_ => {}
}

View File

@ -356,9 +356,10 @@ impl <'l> DxrVisitor<'l> {
for arg in method.pe_fn_decl().inputs.iter() {
self.visit_ty(&*arg.ty, e);
}
self.visit_ty(method.pe_fn_decl().output, e);
self.visit_ty(&*method.pe_fn_decl().output, e);
// walk the fn body
self.visit_block(method.pe_body(), DxrVisitorEnv::new_nested(method.id));
self.visit_block(&*method.pe_body(),
DxrVisitorEnv::new_nested(method.id));
self.process_generic_params(method.pe_generics(),
method.span,

View File

@ -491,7 +491,7 @@ fn enter_default<'a, 'b>(
// Collect all of the matches that can match against anything.
enter_match(bcx, dm, m, col, val, |pats| {
if pat_is_binding_or_wild(dm, pats[col]) {
if pat_is_binding_or_wild(dm, &*pats[col]) {
Some(Vec::from_slice(pats.slice_to(col)).append(pats.slice_from(col + 1)))
} else {
None
@ -546,8 +546,10 @@ fn enter_opt<'a, 'b>(
let _indenter = indenter();
let ctor = match opt {
&lit(x) => check_match::ConstantValue(const_eval::eval_const_expr(
bcx.tcx(), lit_to_expr(bcx.tcx(), &x))),
&lit(x) => {
check_match::ConstantValue(const_eval::eval_const_expr(
bcx.tcx(), &*lit_to_expr(bcx.tcx(), &x)))
}
&range(ref lo, ref hi) => check_match::ConstantRange(
const_eval::eval_const_expr(bcx.tcx(), &**lo),
const_eval::eval_const_expr(bcx.tcx(), &**hi)

View File

@ -68,8 +68,13 @@ pub fn trans_impl(ccx: &CrateContext,
for method in methods.iter() {
if method.pe_generics().ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id);
trans_fn(ccx, method.pe_fn_decl(), method.pe_body(),
llfn, &param_substs::empty(), method.id, []);
trans_fn(ccx,
&*method.pe_fn_decl(),
&*method.pe_body(),
llfn,
&param_substs::empty(),
method.id,
[]);
} else {
let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_method_helper(&mut v, &**method, ());

View File

@ -2038,7 +2038,7 @@ pub fn type_contents(cx: &ctxt, ty: t) -> TypeContents {
}
ty_closure(ref c) => {
closure_contents(cx, *c)
closure_contents(cx, &**c)
}
ty_box(typ) => {

View File

@ -1018,7 +1018,7 @@ fn determine_explicit_self_category<AC:AstConv,
}
ast::SelfUniq(_) => ty::ByBoxExplicitSelfCategory,
ast::SelfExplicit(ast_type, _) => {
let explicit_type = ast_ty_to_ty(this, rscope, ast_type);
let explicit_type = ast_ty_to_ty(this, rscope, &*ast_type);
{
let inference_context = infer::new_infer_ctxt(this.tcx());

View File

@ -764,7 +764,12 @@ fn check_method_body(ccx: &CrateCtxt,
let fty = ty::node_id_to_type(ccx.tcx, method.id);
check_bare_fn(ccx, method.pe_fn_decl(), method.pe_body(), method.id, fty, param_env);
check_bare_fn(ccx,
&*method.pe_fn_decl(),
&*method.pe_body(),
method.id,
fty,
param_env);
}
fn check_impl_methods_against_trait(ccx: &CrateCtxt,
@ -2370,7 +2375,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
// Shift is a special case: rhs must be uint, no matter what lhs is
check_expr_has_type(fcx, rhs, ty::mk_uint());
check_expr_has_type(fcx, &*rhs, ty::mk_uint());
fcx.write_ty(expr.id, lhs_t);
return;
}
@ -2957,7 +2962,7 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
}
ast::ExprLit(lit) => {
let typ = check_lit(fcx, lit, expected);
let typ = check_lit(fcx, &*lit, expected);
fcx.write_ty(id, typ);
}
ast::ExprBinary(op, ref lhs, ref rhs) => {
@ -3164,8 +3169,11 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
fcx.write_bot(id);
}
ast::ExprParen(a) => {
check_expr_with_expectation_and_lvalue_pref(fcx, a, expected, lvalue_pref);
fcx.write_ty(id, fcx.expr_ty(a));
check_expr_with_expectation_and_lvalue_pref(fcx,
&*a,
expected,
lvalue_pref);
fcx.write_ty(id, fcx.expr_ty(&*a));
}
ast::ExprAssign(ref lhs, ref rhs) => {
check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
@ -3326,8 +3334,8 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
Some(ref fs) if i < fs.len() => ExpectHasType(*fs.get(i)),
_ => NoExpectation
};
check_expr_with_expectation(fcx, *e, opt_hint);
let t = fcx.expr_ty(*e);
check_expr_with_expectation(fcx, &**e, opt_hint);
let t = fcx.expr_ty(&**e);
err_field = err_field || ty::type_is_error(t);
bot_field = bot_field || ty::type_is_bot(t);
t
@ -3674,8 +3682,8 @@ fn check_block_with_expected(fcx: &FnCtxt,
e.span,
"unreachable expression".to_string());
}
check_expr_with_expectation(fcx, e, expected);
let ety = fcx.expr_ty(e);
check_expr_with_expectation(fcx, &*e, expected);
let ety = fcx.expr_ty(&*e);
fcx.write_ty(blk.id, ety);
if any_err {
fcx.write_error(blk.id);

View File

@ -215,9 +215,15 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
&ast::Provided(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_def.generics,
&m.id, &m.pe_ident(), m.pe_explicit_self(),
m.pe_generics(), &m.pe_fn_style(), m.pe_fn_decl())
ccx,
trait_id,
&trait_def.generics,
&m.id,
&m.pe_ident(),
m.pe_explicit_self(),
m.pe_generics(),
&m.pe_fn_style(),
&*m.pe_fn_decl())
}
});
@ -383,7 +389,7 @@ fn convert_methods(ccx: &CrateCtxt,
m.pe_fn_style(),
untransformed_rcvr_ty,
*m.pe_explicit_self(),
m.pe_fn_decl());
&*m.pe_fn_decl());
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
@ -1295,7 +1301,7 @@ fn check_method_self_type<RS:RegionScope>(
explicit_self: &ast::ExplicitSelf) {
match explicit_self.node {
ast::SelfExplicit(ref ast_type, _) => {
let typ = crate_context.to_ty(rs, *ast_type);
let typ = crate_context.to_ty(rs, &**ast_type);
let base_type = match ty::get(typ).sty {
ty::ty_rptr(_, tm) => tm.ty,
ty::ty_uniq(typ) => typ,

View File

@ -76,7 +76,6 @@ use util::common::indenter;
use util::ppaux::Repr;
use syntax::abi;
use syntax::ast::MutImmutable;
use syntax::ast;
// Note: Coerce is not actually a combiner, in that it does not
@ -248,12 +247,7 @@ impl<'f> Coerce<'f> {
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let inner_ty = match *sty_a {
ty::ty_box(typ) | ty::ty_uniq(typ) => {
if mt_b.mutbl == ast::MutMutable {
return Err(ty::terr_mutability)
}
typ
}
ty::ty_box(_) | ty::ty_uniq(_) => return Err(ty::terr_mismatch),
ty::ty_rptr(_, mt_a) => mt_a.ty,
_ => {
return self.subtype(a, b);
@ -280,23 +274,9 @@ impl<'f> Coerce<'f> {
b.repr(self.get_ref().infcx.tcx));
match *sty_a {
ty::ty_uniq(t) => match ty::get(t).sty {
ty::ty_str => {}
_ => return self.subtype(a, b),
},
_ => {
return self.subtype(a, b);
}
};
let coercion = Coercion(self.get_ref().trace.clone());
let r_a = self.get_ref().infcx.next_region_var(coercion);
let a_borrowed = ty::mk_str_slice(self.get_ref().infcx.tcx, r_a, ast::MutImmutable);
if_ok!(self.subtype(a_borrowed, b));
Ok(Some(AutoDerefRef(AutoDerefRef {
autoderefs: 0,
autoref: Some(AutoBorrowVec(r_a, MutImmutable))
})))
ty::ty_uniq(_) => return Err(ty::terr_mismatch),
_ => return self.subtype(a, b),
}
}
pub fn coerce_borrowed_vector(&self,
@ -313,7 +293,8 @@ impl<'f> Coerce<'f> {
let coercion = Coercion(self.get_ref().trace.clone());
let r_borrow = self.get_ref().infcx.next_region_var(coercion);
let ty_inner = match *sty_a {
ty::ty_uniq(t) | ty::ty_ptr(ty::mt{ty: t, ..}) |
ty::ty_uniq(_) => return Err(ty::terr_mismatch),
ty::ty_ptr(ty::mt{ty: t, ..}) |
ty::ty_rptr(_, ty::mt{ty: t, ..}) => match ty::get(t).sty {
ty::ty_vec(mt, None) => mt.ty,
_ => {

View File

@ -552,7 +552,7 @@ pub fn super_tys<C:Combine>(this: &C, a: ty::t, b: ty::t) -> cres<ty::t> {
}
(&ty::ty_closure(ref a_fty), &ty::ty_closure(ref b_fty)) => {
this.closure_tys(*a_fty, *b_fty).and_then(|fty| {
this.closure_tys(&**a_fty, &**b_fty).and_then(|fty| {
Ok(ty::mk_closure(tcx, fty))
})
}

View File

@ -30,8 +30,8 @@ use middle::ty_fold::TypeFolder;
use middle::typeck::check::regionmanip::replace_late_bound_regions_in_fn_sig;
use middle::typeck::infer::coercion::Coerce;
use middle::typeck::infer::combine::{Combine, CombineFields, eq_tys};
use middle::typeck::infer::region_inference::{RegionVarBindings,
RegionSnapshot};
use middle::typeck::infer::region_inference::{RegionSnapshot};
use middle::typeck::infer::region_inference::{RegionVarBindings};
use middle::typeck::infer::resolve::{resolver};
use middle::typeck::infer::sub::Sub;
use middle::typeck::infer::lub::Lub;

View File

@ -174,7 +174,7 @@ impl<'a> Env<'a> {
assert!(idx < names.len());
for item in m.items.iter() {
if item.ident.user_string(this.tcx) == names[idx] {
return search(this, *item, idx+1, names);
return search(this, &**item, idx+1, names);
}
}
return None;

View File

@ -374,7 +374,7 @@ pub fn ty_to_string(cx: &ctxt, typ: t) -> String {
format!("({})", strs.connect(","))
}
ty_closure(ref f) => {
closure_to_string(cx, *f)
closure_to_string(cx, &**f)
}
ty_bare_fn(ref f) => {
bare_fn_to_string(cx, f.fn_style, f.abi, None, &f.sig)

View File

@ -954,7 +954,9 @@ impl<'a> MethodDef<'a> {
// expressions for referencing every field of every
// Self arg, assuming all are instances of VariantK.
// Build up code associated with such a case.
let substructure = EnumMatching(index, variant, field_tuples);
let substructure = EnumMatching(index,
&*variant,
field_tuples);
let arm_expr = self.call_substructure_method(
cx, trait_, type_ident, self_args, nonself_args,
&substructure);

View File

@ -166,14 +166,14 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
ast::ExprFnBlock(fn_decl, block) => {
let (rewritten_fn_decl, rewritten_block)
= expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
= expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
let new_node = ast::ExprFnBlock(rewritten_fn_decl, rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
}
ast::ExprProc(fn_decl, block) => {
let (rewritten_fn_decl, rewritten_block)
= expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
= expand_and_rename_fn_decl_and_block(&*fn_decl, block, fld);
let new_node = ast::ExprProc(rewritten_fn_decl, rewritten_block);
box(GC) ast::Expr{id:e.id, node: new_node, span: fld.new_span(e.span)}
}
@ -422,7 +422,7 @@ fn expand_item_underscore(item: &ast::Item_, fld: &mut MacroExpander) -> ast::It
match *item {
ast::ItemFn(decl, fn_style, abi, ref generics, body) => {
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(decl,body,fld);
= expand_and_rename_fn_decl_and_block(&*decl, body, fld);
let expanded_generics = fold::fold_generics(generics,fld);
ast::ItemFn(rewritten_fn_decl, fn_style, abi, expanded_generics, rewritten_body)
}
@ -572,7 +572,9 @@ fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
};
let expanded_stmt = match expand_mac_invoc(mac,&s.span,
|r|{r.make_stmt()},
|sts,mrk|{mark_stmt(sts,mrk)},
|sts,mrk| {
mark_stmt(&*sts,mrk)
},
fld) {
Some(stmt) => stmt,
None => {
@ -628,7 +630,7 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander)
// names, as well... but that should be okay, as long as
// the new names are gensyms for the old ones.
// generate fresh names, push them to a new pending list
let idents = pattern_bindings(expanded_pat);
let idents = pattern_bindings(&*expanded_pat);
let mut new_pending_renames =
idents.iter().map(|ident| (*ident, fresh_name(ident))).collect();
// rewrite the pattern using the new names (the old
@ -677,7 +679,7 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
// all of the pats must have the same set of bindings, so use the
// first one to extract them and generate new names:
let first_pat = expanded_pats.get(0);
let idents = pattern_bindings(*first_pat);
let idents = pattern_bindings(&**first_pat);
let new_renames =
idents.iter().map(|id| (*id,fresh_name(id))).collect();
// apply the renaming, but only to the PatIdents:
@ -732,7 +734,7 @@ fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
for arg in fn_decl.inputs.iter() {
pat_idents.visit_pat(arg.pat,());
pat_idents.visit_pat(&*arg.pat, ());
}
pat_idents.ident_accumulator
}
@ -910,7 +912,7 @@ fn expand_method(m: &ast::Method, fld: &mut MacroExpander) -> SmallVector<Gc<ast
match m.node {
ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
let (rewritten_fn_decl, rewritten_body)
= expand_and_rename_fn_decl_and_block(decl,body,fld);
= expand_and_rename_fn_decl_and_block(&*decl,body,fld);
SmallVector::one(box(GC) ast::Method {
attrs: m.attrs.iter().map(|a| fld.fold_attribute(*a)).collect(),
id: id,
@ -951,12 +953,12 @@ fn expand_and_rename_fn_decl_and_block(fn_decl: &ast::FnDecl, block: Gc<ast::Blo
fld: &mut MacroExpander)
-> (Gc<ast::FnDecl>, Gc<ast::Block>) {
let expanded_decl = fld.fold_fn_decl(fn_decl);
let idents = fn_decl_arg_bindings(expanded_decl);
let idents = fn_decl_arg_bindings(&*expanded_decl);
let renames =
idents.iter().map(|id : &ast::Ident| (*id,fresh_name(id))).collect();
// first, a renamer for the PatIdents, for the fn_decl:
let mut rename_pat_fld = PatIdentRenamer{renames: &renames};
let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(expanded_decl);
let rewritten_fn_decl = rename_pat_fld.fold_fn_decl(&*expanded_decl);
// now, a renamer for *all* idents, for the body:
let mut rename_fld = IdentRenamer{renames: &renames};
let rewritten_body = fld.fold_block(rename_fld.fold_block(block));
@ -999,7 +1001,7 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
}
fn fold_method(&mut self, method: Gc<ast::Method>) -> SmallVector<Gc<ast::Method>> {
expand_method(method, self)
expand_method(&*method, self)
}
fn new_span(&mut self, span: Span) -> Span {
@ -1660,7 +1662,7 @@ foo_module!()
fn pat_idents(){
let pat = string_to_pat(
"(a,Foo{x:c @ (b,9),y:Bar(4,d)})".to_string());
let idents = pattern_bindings(pat);
let idents = pattern_bindings(&*pat);
assert_eq!(idents, strs_to_idents(vec!("a","c","b","d")));
}

View File

@ -472,7 +472,7 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
.expect_one("expected fold to produce exactly one item")),
token::NtBlock(block) => token::NtBlock(fld.fold_block(block)),
token::NtStmt(stmt) =>
token::NtStmt(fld.fold_stmt(stmt)
token::NtStmt(fld.fold_stmt(&*stmt)
// this is probably okay, because the only folds likely
// to peek inside interpolated nodes will be renamings/markings,
// which map single items to single items
@ -483,8 +483,8 @@ fn fold_interpolated<T: Folder>(nt : &token::Nonterminal, fld: &mut T) -> token:
token::NtIdent(ref id, is_mod_name) =>
token::NtIdent(box fld.fold_ident(**id),is_mod_name),
token::NtMeta(meta_item) => token::NtMeta(fold_meta_item_(meta_item,fld)),
token::NtPath(ref path) => token::NtPath(box fld.fold_path(*path)),
token::NtTT(tt) => token::NtTT(box (GC) fold_tt(tt,fld)),
token::NtPath(ref path) => token::NtPath(box fld.fold_path(&**path)),
token::NtTT(tt) => token::NtTT(box (GC) fold_tt(&*tt,fld)),
// it looks to me like we can leave out the matchers: token::NtMatchers(matchers)
_ => (*nt).clone()
}

View File

@ -502,7 +502,9 @@ impl<'a> Parser<'a> {
inedible: &[token::Token]) {
debug!("commit_stmt {:?}", s);
let _s = s; // unused, but future checks might want to inspect `s`.
if self.last_token.as_ref().map_or(false, |t| is_ident_or_path(*t)) {
if self.last_token
.as_ref()
.map_or(false, |t| is_ident_or_path(&**t)) {
let expected = edible.iter().map(|x| (*x).clone()).collect::<Vec<_>>()
.append(inedible.as_slice());
self.check_for_erroneous_unit_struct_expecting(

View File

@ -1862,7 +1862,7 @@ impl<'a> State<'a> {
ast::SelfExplicit(ref typ, _) => {
try!(word(&mut self.s, "self"));
try!(self.word_space(":"));
try!(self.print_type(*typ));
try!(self.print_type(&**typ));
}
}
return Ok(true);

View File

@ -215,7 +215,7 @@ pub fn walk_explicit_self<E: Clone, V: Visitor<E>>(visitor: &mut V,
SelfRegion(ref lifetime, _, _) => {
visitor.visit_opt_lifetime_ref(explicit_self.span, lifetime, env)
}
SelfExplicit(ref typ, _) => visitor.visit_ty(*typ, env.clone()),
SelfExplicit(ref typ, _) => visitor.visit_ty(&**typ, env.clone()),
}
}
@ -565,8 +565,8 @@ pub fn walk_method_helper<E: Clone, V: Visitor<E>>(visitor: &mut V,
MethDecl(ident, ref generics, _, _, decl, body, _) => {
visitor.visit_ident(method.span, ident, env.clone());
visitor.visit_fn(&FkMethod(ident, generics, method),
decl,
body,
&*decl,
&*body,
method.span,
method.id,
env.clone());

View File

@ -79,7 +79,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
pub fn open(term: &str) -> Result<File, String> {
match get_dbpath_for_term(term) {
Some(x) => {
match File::open(x) {
match File::open(&*x) {
Ok(file) => Ok(file),
Err(e) => Err(format!("error opening file: {}", e)),
}

View File

@ -30,7 +30,7 @@ fn implicit() {
// evaluated, but it gets freed when evaluating the second
// argument!
add(
a,
&*a,
rewrite(&mut a)); //~ ERROR cannot borrow
}

View File

@ -30,7 +30,7 @@ fn implicit() {
// evaluated, but it gets moved when evaluating the second
// argument!
add(
a,
&*a,
a); //~ ERROR cannot move
}

View File

@ -28,5 +28,5 @@ fn main() {
let test = |foo: &Foo| {
ptr = box Foo { x: ptr.x + 1 };
};
test(ptr); //~ ERROR cannot borrow `*ptr`
test(&*ptr); //~ ERROR cannot borrow `*ptr`
}

View File

@ -31,7 +31,7 @@ fn loop_overarching_alias_mut() {
let mut x = &mut v;
**x += 1;
loop {
borrow(v); //~ ERROR cannot borrow
borrow(&*v); //~ ERROR cannot borrow
}
}
@ -41,7 +41,7 @@ fn block_overarching_alias_mut() {
let mut v = box 3;
let mut x = &mut v;
for _ in range(0i, 3) {
borrow(v); //~ ERROR cannot borrow
borrow(&*v); //~ ERROR cannot borrow
}
*x = box 5;
}
@ -105,7 +105,7 @@ fn while_aliased_mut_cond(cond: bool, cond2: bool) {
let mut x = &mut w;
while cond {
**x += 1;
borrow(v); //~ ERROR cannot borrow
borrow(&*v); //~ ERROR cannot borrow
if cond2 {
x = &mut v; //~ ERROR cannot borrow
}

View File

@ -14,7 +14,7 @@ fn borrow(v: &int, f: |x: &int|) {
fn box_imm() {
let mut v = box 3;
borrow(v,
borrow(&*v,
|w| { //~ ERROR cannot borrow `v` as mutable
v = box 4;
assert_eq!(*v, 3);

View File

@ -25,7 +25,7 @@ struct F { f: Box<int> }
pub fn main() {
let mut x = box(GC) F {f: box 3};
borrow(x.f, |b_x| {
borrow(&*x.f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);

View File

@ -25,7 +25,7 @@ struct F { f: Box<int> }
pub fn main() {
let mut x = box box(GC) F{f: box 3};
borrow(x.f, |b_x| {
borrow(&*x.f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);

View File

@ -23,7 +23,7 @@ fn borrow(x: &int, f: |x: &int|) {
pub fn main() {
let mut x = box(GC) 3;
borrow(x, |b_x| {
borrow(&*x, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x) as *const int, &(*b_x) as *const int);

View File

@ -25,7 +25,7 @@ struct F { f: Box<int> }
pub fn main() {
let mut x = box(GC) F {f: box 3};
borrow((*x).f, |b_x| {
borrow(&*(*x).f, |b_x| {
//~^ ERROR cannot borrow `x` as mutable because `*x.f` is also borrowed as immutable
assert_eq!(*b_x, 3);
assert_eq!(&(*x.f) as *const int, &(*b_x) as *const int);

View File

@ -13,13 +13,13 @@ fn borrow(_v: &int) {}
fn local() {
let mut v = box 3i;
borrow(v);
borrow(&*v);
}
fn local_rec() {
struct F { f: Box<int> }
let mut v = F {f: box 3};
borrow(v.f);
borrow(&*v.f);
}
fn local_recs() {
@ -27,26 +27,26 @@ fn local_recs() {
struct G { g: H }
struct H { h: Box<int> }
let mut v = F {f: G {g: H {h: box 3}}};
borrow(v.f.g.h);
borrow(&*v.f.g.h);
}
fn aliased_imm() {
let mut v = box 3i;
let _w = &v;
borrow(v);
borrow(&*v);
}
fn aliased_mut() {
let mut v = box 3i;
let _w = &mut v;
borrow(v); //~ ERROR cannot borrow `*v`
borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn aliased_other() {
let mut v = box 3i;
let mut w = box 4i;
let _x = &mut w;
borrow(v);
borrow(&*v);
}
fn aliased_other_reassign() {
@ -54,7 +54,7 @@ fn aliased_other_reassign() {
let mut w = box 4i;
let mut _x = &mut w;
_x = &mut v;
borrow(v); //~ ERROR cannot borrow `*v`
borrow(&*v); //~ ERROR cannot borrow `*v`
}
fn main() {

View File

@ -25,7 +25,7 @@ fn main() {
ptr = box Foo { x: ptr.x + 1 };
println!("access {}", foo.x);
};
test(ptr);
test(&*ptr);
//~^ ERROR: cannot borrow `*ptr` as immutable
}

View File

@ -33,7 +33,7 @@ fn make_a<'a>(p: &'a X) -> A<'a> {
fn make_make_a() -> A {
let b: Box<B> = box B {i:1};
let bb: &B = b; //~ ERROR does not live long enough
let bb: &B = &*b; //~ ERROR does not live long enough
make_a(bb)
}

View File

@ -1,17 +0,0 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![deny(unnecessary_allocation)]
fn f(_: &int) {}
fn main() {
f(box 1); //~ ERROR unnecessary allocation, use & instead
}

View File

@ -22,7 +22,7 @@ fn x_coord<'r>(p: &'r point) -> &'r int {
}
fn foo(p: Gc<point>) -> &int {
let xc = x_coord(p); //~ ERROR `*p` does not live long enough
let xc = x_coord(&*p); //~ ERROR `*p` does not live long enough
assert_eq!(*xc, 3);
return xc;
}

View File

@ -21,7 +21,7 @@ fn foo(cond: || -> bool, make_box: || -> Gc<int>) {
// Here we complain because the resulting region
// of this borrow is the fn body as a whole.
y = borrow(x); //~ ERROR `*x` does not live long enough
y = borrow(&*x); //~ ERROR `*x` does not live long enough
assert_eq!(*x, *y);
if cond() { break; }

View File

@ -42,7 +42,7 @@ fn make_make_a() -> A {
let b: Box<B> = box B {
i: 1,
};
let bb: &B = b; //~ ERROR `*b` does not live long enough
let bb: &B = &*b; //~ ERROR `*b` does not live long enough
make_a(bb)
}

View File

@ -1,3 +1,5 @@
// ignore-test
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
@ -17,6 +19,6 @@ struct Foo<'a> {
}
pub fn main() {
let f = Foo { x: box(GC) 3 }; //~ ERROR borrowed value does not live long enough
let f = Foo { x: &*(box(GC) 3) }; //~ ERROR borrowed value does not live long enough
assert_eq!(*f.x, 3);
}

View File

@ -120,46 +120,46 @@ use std::gc::{Gc, GC};
fn main() {
let bool_box: Gc<bool> = box(GC) true;
let bool_ref: &bool = bool_box;
let bool_ref: &bool = &*bool_box;
let int_box: Gc<int> = box(GC) -1;
let int_ref: &int = int_box;
let int_ref: &int = &*int_box;
let char_box: Gc<char> = box(GC) 'a';
let char_ref: &char = char_box;
let char_ref: &char = &*char_box;
let i8_box: Gc<i8> = box(GC) 68;
let i8_ref: &i8 = i8_box;
let i8_ref: &i8 = &*i8_box;
let i16_box: Gc<i16> = box(GC) -16;
let i16_ref: &i16 = i16_box;
let i16_ref: &i16 = &*i16_box;
let i32_box: Gc<i32> = box(GC) -32;
let i32_ref: &i32 = i32_box;
let i32_ref: &i32 = &*i32_box;
let i64_box: Gc<i64> = box(GC) -64;
let i64_ref: &i64 = i64_box;
let i64_ref: &i64 = &*i64_box;
let uint_box: Gc<uint> = box(GC) 1;
let uint_ref: &uint = uint_box;
let uint_ref: &uint = &*uint_box;
let u8_box: Gc<u8> = box(GC) 100;
let u8_ref: &u8 = u8_box;
let u8_ref: &u8 = &*u8_box;
let u16_box: Gc<u16> = box(GC) 16;
let u16_ref: &u16 = u16_box;
let u16_ref: &u16 = &*u16_box;
let u32_box: Gc<u32> = box(GC) 32;
let u32_ref: &u32 = u32_box;
let u32_ref: &u32 = &*u32_box;
let u64_box: Gc<u64> = box(GC) 64;
let u64_ref: &u64 = u64_box;
let u64_ref: &u64 = &*u64_box;
let f32_box: Gc<f32> = box(GC) 2.5;
let f32_ref: &f32 = f32_box;
let f32_ref: &f32 = &*f32_box;
let f64_box: Gc<f64> = box(GC) 3.5;
let f64_ref: &f64 = f64_box;
let f64_ref: &f64 = &*f64_box;
zzz(); // #break
}

View File

@ -100,12 +100,12 @@ fn main() {
let ref_to_unnamed: &SomeStruct = &SomeStruct { x: 11, y: 24.5 };
let managed_val = box(GC) SomeStruct { x: 12, y: 25.5 };
let managed_val_ref: &SomeStruct = managed_val;
let managed_val_ref: &SomeStruct = &*managed_val;
let managed_val_interior_ref_1: &int = &managed_val.x;
let managed_val_interior_ref_2: &f64 = &managed_val.y;
let unique_val = box SomeStruct { x: 13, y: 26.5 };
let unique_val_ref: &SomeStruct = unique_val;
let unique_val_ref: &SomeStruct = &*unique_val;
let unique_val_interior_ref_1: &int = &unique_val.x;
let unique_val_interior_ref_2: &f64 = &unique_val.y;

View File

@ -60,10 +60,10 @@ fn main() {
let ref_to_unnamed: &(i16, f32) = &(-15, -20f32);
let managed_val: Gc<(i16, f32)> = box(GC) (-16, -21f32);
let managed_val_ref: &(i16, f32) = managed_val;
let managed_val_ref: &(i16, f32) = &*managed_val;
let unique_val: Box<(i16, f32)> = box() (-17, -22f32);
let unique_val_ref: &(i16, f32) = unique_val;
let unique_val_ref: &(i16, f32) = &*unique_val;
zzz(); // #break
}

View File

@ -116,46 +116,46 @@
fn main() {
let bool_box: Box<bool> = box true;
let bool_ref: &bool = bool_box;
let bool_ref: &bool = &*bool_box;
let int_box: Box<int> = box -1;
let int_ref: &int = int_box;
let int_ref: &int = &*int_box;
let char_box: Box<char> = box 'a';
let char_ref: &char = char_box;
let char_ref: &char = &*char_box;
let i8_box: Box<i8> = box 68;
let i8_ref: &i8 = i8_box;
let i8_ref: &i8 = &*i8_box;
let i16_box: Box<i16> = box -16;
let i16_ref: &i16 = i16_box;
let i16_ref: &i16 = &*i16_box;
let i32_box: Box<i32> = box -32;
let i32_ref: &i32 = i32_box;
let i32_ref: &i32 = &*i32_box;
let i64_box: Box<i64> = box -64;
let i64_ref: &i64 = i64_box;
let i64_ref: &i64 = &*i64_box;
let uint_box: Box<uint> = box 1;
let uint_ref: &uint = uint_box;
let uint_ref: &uint = &*uint_box;
let u8_box: Box<u8> = box 100;
let u8_ref: &u8 = u8_box;
let u8_ref: &u8 = &*u8_box;
let u16_box: Box<u16> = box 16;
let u16_ref: &u16 = u16_box;
let u16_ref: &u16 = &*u16_box;
let u32_box: Box<u32> = box 32;
let u32_ref: &u32 = u32_box;
let u32_ref: &u32 = &*u32_box;
let u64_box: Box<u64> = box 64;
let u64_ref: &u64 = u64_box;
let u64_ref: &u64 = &*u64_box;
let f32_box: Box<f32> = box 2.5;
let f32_ref: &f32 = f32_box;
let f32_ref: &f32 = &*f32_box;
let f64_box: Box<f64> = box 3.5;
let f64_ref: &f64 = f64_box;
let f64_ref: &f64 = &*f64_box;
zzz(); // #break
}

View File

@ -58,7 +58,7 @@ fn main() {
let closure: proc() = proc() {
zzz(); // #break
do_something(&constant, &a_struct.a, owned);
do_something(&constant, &a_struct.a, &*owned);
};
closure();

View File

@ -15,7 +15,7 @@ use std::collections::Bitv;
fn bitv_test() {
let mut v1 = box Bitv::with_capacity(31, false);
let v2 = box Bitv::with_capacity(31, true);
v1.union(v2);
v1.union(&*v2);
}
pub fn main() {

View File

@ -12,15 +12,15 @@
fn borrow(_v: &int) {}
fn borrow_from_arg_imm_ref(v: Box<int>) {
borrow(v);
borrow(&*v);
}
fn borrow_from_arg_mut_ref(v: &mut Box<int>) {
borrow(*v);
borrow(&**v);
}
fn borrow_from_arg_copy(v: Box<int>) {
borrow(v);
borrow(&*v);
}
pub fn main() {

View File

@ -32,7 +32,7 @@ pub fn main() {
add_int(&mut *ints, 22);
add_int(&mut *ints, 44);
iter_ints(ints, |i| {
iter_ints(&*ints, |i| {
println!("int = {}", *i);
true
});

View File

@ -18,5 +18,5 @@ struct Rec { f: Gc<int> }
pub fn main() {
let rec = box(GC) Rec {f: box(GC) 22};
while *borrow(rec.f) == 23 {}
while *borrow(&*rec.f) == 23 {}
}

View File

@ -28,27 +28,27 @@ struct Innermost {
fn borrow(_v: &int) {}
fn box_mut(v: &mut Box<int>) {
borrow(*v); // OK: &mut -> &imm
borrow(&**v); // OK: &mut -> &imm
}
fn box_mut_rec(v: &mut Rec) {
borrow(v.f); // OK: &mut -> &imm
borrow(&*v.f); // OK: &mut -> &imm
}
fn box_mut_recs(v: &mut Outer) {
borrow(v.f.g.h); // OK: &mut -> &imm
borrow(&*v.f.g.h); // OK: &mut -> &imm
}
fn box_imm(v: &Box<int>) {
borrow(*v); // OK
borrow(&**v); // OK
}
fn box_imm_rec(v: &Rec) {
borrow(v.f); // OK
borrow(&*v.f); // OK
}
fn box_imm_recs(v: &Outer) {
borrow(v.f.g.h); // OK
borrow(&*v.f.g.h); // OK
}
pub fn main() {

View File

@ -18,7 +18,7 @@ use std::gc::GC;
pub fn main() {
let p = box(GC) 22u;
let r = foo(p);
let r = foo(&*p);
println!("r={}", r);
assert_eq!(r, 22u);
}

View File

@ -34,8 +34,7 @@ fn print_s(s: &S) {
pub fn main() {
let s: Box<S> = box S { s: 5 };
print_s(s);
print_s(&*s);
let t: Box<T> = s as Box<T>;
print_t(t);
}

View File

@ -22,7 +22,7 @@ struct Bar<'a> {
}
fn check(a: Gc<Foo>) {
let _ic = Bar{ b: a, a: box None };
let _ic = Bar{ b: &*a, a: box None };
}
pub fn main(){}

View File

@ -10,7 +10,7 @@
fn f() {
let a = box 1;
let b: &int = a;
let b: &int = &*a;
println!("{}", b);
}

View File

@ -10,7 +10,7 @@
fn f(x: Box<int>) {
let y: &int = x;
let y: &int = &*x;
println!("{}", *x);
println!("{}", *y);
}

View File

@ -18,7 +18,7 @@ fn foo(x: &uint) -> uint {
pub fn main() {
let p = box(GC) 22u;
let r = foo(p);
let r = foo(&*p);
println!("r={}", r);
assert_eq!(r, 22u);
}

View File

@ -14,6 +14,6 @@ fn foo(x: &uint) -> uint {
pub fn main() {
let p = box 3u;
let r = foo(p);
let r = foo(&*p);
assert_eq!(r, 3u);
}

View File

@ -17,5 +17,5 @@ fn bar(x: &uint) -> uint { *x }
pub fn main() {
let p = box(GC) 3u;
assert_eq!(bar(foo(p)), 3);
assert_eq!(bar(foo(&*p)), 3);
}

View File

@ -15,7 +15,7 @@ fn borrow<'r, T>(x: &'r T) -> &'r T {x}
pub fn main() {
let x = box(GC) 3i;
loop {
let y = borrow(x);
let y = borrow(&*x);
assert_eq!(*x, *y);
break;
}

View File

@ -20,6 +20,6 @@ fn x_coord<'r>(p: &'r Point) -> &'r int {
pub fn main() {
let p = box(GC) Point {x: 3, y: 4};
let xc = x_coord(p);
let xc = x_coord(&*p);
assert_eq!(*xc, 3);
}