Pass the unadjusted type into the unsize_info function, which seems to be what it expects. Fixes #17322.

This commit is contained in:
Niko Matsakis 2014-11-07 15:18:08 -05:00
parent cf7df1e638
commit ee9a7b60fa
4 changed files with 100 additions and 21 deletions

View File

@ -3396,14 +3396,6 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
}
}
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))
}
}

View File

@ -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;

View File

@ -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<T>), 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{

View File

@ -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 <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.
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<Writer + 'static>;
f(&mut wr);
}