Pass the unadjusted type into the unsize_info function, which seems to be what it expects. Fixes #17322.
This commit is contained in:
parent
cf7df1e638
commit
ee9a7b60fa
|
@ -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> {
|
pub fn close_type<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||||
match ty.sty {
|
match ty.sty {
|
||||||
ty_open(ty) => mk_rptr(cx, ReStatic, mt {ty: ty, mutbl:ast::MutImmutable}),
|
ty_open(ty) => mk_rptr(cx, ReStatic, mt {ty: ty, mutbl:ast::MutImmutable}),
|
||||||
|
@ -5989,3 +5981,59 @@ impl DebruijnIndex {
|
||||||
DebruijnIndex { depth: self.depth + amount }
|
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,
|
node_id: ast::NodeId,
|
||||||
span: Span,
|
span: Span,
|
||||||
adj: ty::AutoAdjustment<'tcx>) {
|
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() {
|
if adj.is_identity() {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -194,8 +194,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
}
|
}
|
||||||
Some(adj) => { adj }
|
Some(adj) => { adj }
|
||||||
};
|
};
|
||||||
debug!("unadjusted datum for expr {}: {}",
|
debug!("unadjusted datum for expr {}: {}, adjustment={}",
|
||||||
expr.id, datum.to_string(bcx.ccx()));
|
expr.repr(bcx.tcx()),
|
||||||
|
datum.to_string(bcx.ccx()),
|
||||||
|
adjustment.repr(bcx.tcx()));
|
||||||
match adjustment {
|
match adjustment {
|
||||||
AdjustAddEnv(..) => {
|
AdjustAddEnv(..) => {
|
||||||
datum = unpack_datum!(bcx, add_env(bcx, expr, datum));
|
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) => {
|
&AutoPtr(_, _, ref a) | &AutoUnsafe(_, ref a) => {
|
||||||
debug!(" AutoPtr");
|
debug!(" AutoPtr");
|
||||||
match a {
|
match a {
|
||||||
&Some(box ref a) => datum = unpack_datum!(bcx,
|
&Some(box ref a) => {
|
||||||
apply_autoref(a, bcx, expr, datum)),
|
datum = unpack_datum!(bcx, apply_autoref(a, bcx, expr, datum));
|
||||||
_ => {}
|
}
|
||||||
|
&None => {}
|
||||||
}
|
}
|
||||||
unpack_datum!(bcx, ref_ptr(bcx, expr, datum))
|
unpack_datum!(bcx, ref_ptr(bcx, expr, datum))
|
||||||
}
|
}
|
||||||
|
@ -293,6 +296,10 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
expr: &ast::Expr,
|
expr: &ast::Expr,
|
||||||
datum: Datum<'tcx, Expr>)
|
datum: Datum<'tcx, Expr>)
|
||||||
-> DatumBlock<'blk, '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) {
|
if !ty::type_is_sized(bcx.tcx(), datum.ty) {
|
||||||
debug!("Taking address of unsized type {}",
|
debug!("Taking address of unsized type {}",
|
||||||
bcx.ty_to_string(datum.ty));
|
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
|
// Retrieve the information we are losing (making dynamic) in an unsizing
|
||||||
// adjustment.
|
// adjustment.
|
||||||
// When making a dtor, we need to do different things depending on the
|
// 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,
|
// 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
|
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
|
||||||
// borrowed reference then it should be T -> &T.
|
// borrowed reference then it should be T -> &T.
|
||||||
fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
kind: &ty::UnsizeKind<'tcx>,
|
kind: &ty::UnsizeKind<'tcx>,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
unsized_ty: Ty<'tcx>,
|
unadjusted_ty: Ty<'tcx>,
|
||||||
mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef {
|
mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef {
|
||||||
|
debug!("unsized_info(kind={}, id={}, unadjusted_ty={})",
|
||||||
|
kind, id, unadjusted_ty.repr(bcx.tcx()));
|
||||||
match kind {
|
match kind {
|
||||||
&ty::UnsizeLength(len) => C_uint(bcx.ccx(), len),
|
&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) => {
|
ty::ty_struct(_, ref substs) => {
|
||||||
let ty_substs = substs.types.get_slice(subst::TypeSpace);
|
let ty_substs = substs.types.get_slice(subst::TypeSpace);
|
||||||
// The dtor for a field treats it like a value, so mk_ty
|
// 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)
|
unsized_info(bcx, k, id, ty_substs[tp_index], |t| t)
|
||||||
}
|
}
|
||||||
_ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
|
_ => 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, .. }, _) => {
|
&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 =
|
let trait_ref =
|
||||||
Rc::new(ty::TraitRef { def_id: principal.def_id,
|
Rc::new(ty::TraitRef { def_id: principal.def_id,
|
||||||
substs: substs });
|
substs: substs });
|
||||||
let trait_ref = trait_ref.subst(bcx.tcx(), bcx.fcx.param_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,
|
PointerCast(bcx,
|
||||||
meth::get_vtable(bcx, box_ty, trait_ref),
|
meth::get_vtable(bcx, box_ty, trait_ref),
|
||||||
Type::vtable_ptr(bcx.ccx()))
|
Type::vtable_ptr(bcx.ccx()))
|
||||||
|
@ -350,7 +359,9 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
let datum_ty = datum.ty;
|
let datum_ty = datum.ty;
|
||||||
let unsized_ty = ty::unsize_ty(tcx, datum_ty, k, expr.span);
|
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);
|
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
|
// Closures for extracting and manipulating the data and payload parts of
|
||||||
// the fat pointer.
|
// the fat pointer.
|
||||||
let base = match k {
|
let base = match k {
|
||||||
|
@ -366,7 +377,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||||
let info = |bcx, _val| unsized_info(bcx,
|
let info = |bcx, _val| unsized_info(bcx,
|
||||||
k,
|
k,
|
||||||
expr.id,
|
expr.id,
|
||||||
ty::deref_or_dont(datum_ty),
|
datum_ty,
|
||||||
|t| ty::mk_rptr(tcx,
|
|t| ty::mk_rptr(tcx,
|
||||||
ty::ReStatic,
|
ty::ReStatic,
|
||||||
ty::mt{
|
ty::mt{
|
||||||
|
|
|
@ -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