diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index bf4260c4631..6d9f6ece1c1 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3396,14 +3396,6 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option> { } } -pub fn deref_or_dont<'tcx>(ty: Ty<'tcx>) -> Ty<'tcx> { - match ty.sty { - ty_uniq(ty) => ty, - ty_rptr(_, mt) | ty_ptr(mt) => mt.ty, - _ => ty - } -} - pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { match ty.sty { ty_open(ty) => mk_rptr(cx, ReStatic, mt {ty: ty, mutbl:ast::MutImmutable}), @@ -5989,3 +5981,59 @@ impl DebruijnIndex { DebruijnIndex { depth: self.depth + amount } } } + +impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> { + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + match *self { + AdjustAddEnv(ref trait_store) => { + format!("AdjustAddEnv({})", trait_store) + } + AdjustDerefRef(ref data) => { + data.repr(tcx) + } + } + } +} + +impl<'tcx> Repr<'tcx> for UnsizeKind<'tcx> { + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + match *self { + UnsizeLength(n) => format!("UnsizeLength({})", n), + UnsizeStruct(ref k, n) => format!("UnsizeStruct({},{})", k.repr(tcx), n), + UnsizeVtable(ref a, ref b) => format!("UnsizeVtable({},{})", a.repr(tcx), b.repr(tcx)), + } + } +} + +impl<'tcx> Repr<'tcx> for AutoDerefRef<'tcx> { + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + format!("AutoDerefRef({}, {})", self.autoderefs, self.autoref.repr(tcx)) + } +} + +impl<'tcx> Repr<'tcx> for AutoRef<'tcx> { + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + match *self { + AutoPtr(a, b, ref c) => { + format!("AutoPtr({},{},{})", a.repr(tcx), b, c.repr(tcx)) + } + AutoUnsize(ref a) => { + format!("AutoUnsize({})", a.repr(tcx)) + } + AutoUnsizeUniq(ref a) => { + format!("AutoUnsizeUniq({})", a.repr(tcx)) + } + AutoUnsafe(ref a, ref b) => { + format!("AutoUnsafe({},{})", a, b.repr(tcx)) + } + } + } +} + +impl<'tcx> Repr<'tcx> for TyTrait<'tcx> { + fn repr(&self, tcx: &ctxt<'tcx>) -> String { + format!("TyTrait({},{})", + self.principal.repr(tcx), + self.bounds.repr(tcx)) + } +} diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 543eb44697c..adbcc073609 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1707,7 +1707,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { node_id: ast::NodeId, span: Span, adj: ty::AutoAdjustment<'tcx>) { - debug!("write_adjustment(node_id={}, adj={})", node_id, adj); + debug!("write_adjustment(node_id={}, adj={})", node_id, adj.repr(self.tcx())); if adj.is_identity() { return; diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 8ccc5983199..44c37793b4b 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -194,8 +194,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, } Some(adj) => { adj } }; - debug!("unadjusted datum for expr {}: {}", - expr.id, datum.to_string(bcx.ccx())); + debug!("unadjusted datum for expr {}: {}, adjustment={}", + expr.repr(bcx.tcx()), + datum.to_string(bcx.ccx()), + adjustment.repr(bcx.tcx())); match adjustment { AdjustAddEnv(..) => { datum = unpack_datum!(bcx, add_env(bcx, expr, datum)); @@ -265,9 +267,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, &AutoPtr(_, _, ref a) | &AutoUnsafe(_, ref a) => { debug!(" AutoPtr"); match a { - &Some(box ref a) => datum = unpack_datum!(bcx, - apply_autoref(a, bcx, expr, datum)), - _ => {} + &Some(box ref a) => { + datum = unpack_datum!(bcx, apply_autoref(a, bcx, expr, datum)); + } + &None => {} } unpack_datum!(bcx, ref_ptr(bcx, expr, datum)) } @@ -293,6 +296,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr, datum: Datum<'tcx, Expr>) -> DatumBlock<'blk, 'tcx, Expr> { + debug!("ref_ptr(expr={}, datum={})", + expr.repr(bcx.tcx()), + datum.to_string(bcx.ccx())); + if !ty::type_is_sized(bcx.tcx(), datum.ty) { debug!("Taking address of unsized type {}", bcx.ty_to_string(datum.ty)); @@ -307,18 +314,20 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, // Retrieve the information we are losing (making dynamic) in an unsizing // adjustment. // When making a dtor, we need to do different things depending on the - // ownership of the object.. mk_ty is a function for turning unsized_type + // ownership of the object.. mk_ty is a function for turning `unadjusted_ty` // into a type to be destructed. If we want to end up with a Box pointer, // then mk_ty should make a Box pointer (T -> Box), if we want a // borrowed reference then it should be T -> &T. fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, kind: &ty::UnsizeKind<'tcx>, id: ast::NodeId, - unsized_ty: Ty<'tcx>, + unadjusted_ty: Ty<'tcx>, mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef { + debug!("unsized_info(kind={}, id={}, unadjusted_ty={})", + kind, id, unadjusted_ty.repr(bcx.tcx())); match kind { &ty::UnsizeLength(len) => C_uint(bcx.ccx(), len), - &ty::UnsizeStruct(box ref k, tp_index) => match unsized_ty.sty { + &ty::UnsizeStruct(box ref k, tp_index) => match unadjusted_ty.sty { ty::ty_struct(_, ref substs) => { let ty_substs = substs.types.get_slice(subst::TypeSpace); // The dtor for a field treats it like a value, so mk_ty @@ -326,15 +335,15 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, unsized_info(bcx, k, id, ty_substs[tp_index], |t| t) } _ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}", - bcx.ty_to_string(unsized_ty)).as_slice()) + bcx.ty_to_string(unadjusted_ty)).as_slice()) }, &ty::UnsizeVtable(ty::TyTrait { ref principal, .. }, _) => { - let substs = principal.substs.with_self_ty(unsized_ty).erase_regions(); + let substs = principal.substs.with_self_ty(unadjusted_ty).erase_regions(); let trait_ref = Rc::new(ty::TraitRef { def_id: principal.def_id, substs: substs }); let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_substs); - let box_ty = mk_ty(unsized_ty); + let box_ty = mk_ty(unadjusted_ty); PointerCast(bcx, meth::get_vtable(bcx, box_ty, trait_ref), Type::vtable_ptr(bcx.ccx())) @@ -350,7 +359,9 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let tcx = bcx.tcx(); let datum_ty = datum.ty; let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span); + debug!("unsized_ty={}", unsized_ty.repr(bcx.tcx())); let dest_ty = ty::mk_open(tcx, unsized_ty); + debug!("dest_ty={}", unsized_ty.repr(bcx.tcx())); // Closures for extracting and manipulating the data and payload parts of // the fat pointer. let base = match k { @@ -366,7 +377,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let info = |bcx, _val| unsized_info(bcx, k, expr.id, - ty::deref_or_dont(datum_ty), + datum_ty, |t| ty::mk_rptr(tcx, ty::ReStatic, ty::mt{ diff --git a/src/test/run-pass/issue-17322.rs b/src/test/run-pass/issue-17322.rs new file mode 100644 index 00000000000..c5784154a2e --- /dev/null +++ b/src/test/run-pass/issue-17322.rs @@ -0,0 +1,20 @@ +// 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. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::io; + +fn f(wr: &mut Writer) { + wr.write_str("hello").ok().expect("failed"); +} + +fn main() { + let mut wr = box io::stdout() as Box; + f(&mut wr); +}