auto merge of #18746 : nikomatsakis/rust/issue-17322-unsized_ty, r=ncr
Pass the unadjusted type into the unsize_info function, which seems to be what it expects. Fixes #17322. r? @nick29581 Full disclosure: still running make check locally ;)
This commit is contained in:
commit
3e9414463e
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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{
|
||||
|
20
src/test/run-pass/issue-17322.rs
Normal file
20
src/test/run-pass/issue-17322.rs
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user