Auto merge of #50395 - Zoxc:small-tys, r=michaelwoerister
Optimize layout of TypeVariants This makes references to `Slice` use thin pointers by storing the slice length in the slice itself. `GeneratorInterior` is replaced by storing the movability of generators in `TyGenerator` and the interior witness is stored in `GeneratorSubsts` (which is just a wrapper around `&'tcx Substs`, like `ClosureSubsts`). Finally the fields of `TypeAndMut` is stored inline in `TyRef`. These changes combine to reduce `TypeVariants` from 48 bytes to 24 bytes on x86_64. r? @michaelwoerister
This commit is contained in:
commit
0a223d139c
84 changed files with 615 additions and 537 deletions
|
@ -483,10 +483,10 @@ for mir::AggregateKind<'gcx> {
|
|||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
mir::AggregateKind::Generator(def_id, ref substs, ref interior) => {
|
||||
mir::AggregateKind::Generator(def_id, ref substs, movability) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
interior.hash_stable(hcx, hasher);
|
||||
movability.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -517,8 +517,7 @@ for ::middle::const_val::ErrKind<'gcx> {
|
|||
}
|
||||
|
||||
impl_stable_hash_for!(struct ty::ClosureSubsts<'tcx> { substs });
|
||||
|
||||
impl_stable_hash_for!(struct ty::GeneratorInterior<'tcx> { witness, movable });
|
||||
impl_stable_hash_for!(struct ty::GeneratorSubsts<'tcx> { substs });
|
||||
|
||||
impl_stable_hash_for!(struct ty::GenericPredicates<'tcx> {
|
||||
parent,
|
||||
|
@ -889,9 +888,10 @@ for ty::TypeVariants<'gcx>
|
|||
TyRawPtr(pointee_ty) => {
|
||||
pointee_ty.hash_stable(hcx, hasher);
|
||||
}
|
||||
TyRef(region, pointee_ty) => {
|
||||
TyRef(region, pointee_ty, mutbl) => {
|
||||
region.hash_stable(hcx, hasher);
|
||||
pointee_ty.hash_stable(hcx, hasher);
|
||||
mutbl.hash_stable(hcx, hasher);
|
||||
}
|
||||
TyFnDef(def_id, substs) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
|
@ -908,10 +908,10 @@ for ty::TypeVariants<'gcx>
|
|||
def_id.hash_stable(hcx, hasher);
|
||||
closure_substs.hash_stable(hcx, hasher);
|
||||
}
|
||||
TyGenerator(def_id, closure_substs, interior) => {
|
||||
TyGenerator(def_id, generator_substs, movability) => {
|
||||
def_id.hash_stable(hcx, hasher);
|
||||
closure_substs.hash_stable(hcx, hasher);
|
||||
interior.hash_stable(hcx, hasher);
|
||||
generator_substs.hash_stable(hcx, hasher);
|
||||
movability.hash_stable(hcx, hasher);
|
||||
}
|
||||
TyGeneratorWitness(types) => {
|
||||
types.hash_stable(hcx, hasher)
|
||||
|
@ -1315,11 +1315,11 @@ for traits::VtableGeneratorData<'gcx, N> where N: HashStable<StableHashingContex
|
|||
hcx: &mut StableHashingContext<'a>,
|
||||
hasher: &mut StableHasher<W>) {
|
||||
let traits::VtableGeneratorData {
|
||||
closure_def_id,
|
||||
generator_def_id,
|
||||
substs,
|
||||
ref nested,
|
||||
} = *self;
|
||||
closure_def_id.hash_stable(hcx, hasher);
|
||||
generator_def_id.hash_stable(hcx, hasher);
|
||||
substs.hash_stable(hcx, hasher);
|
||||
nested.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
|
|
@ -665,7 +665,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn push_ty_ref<'tcx>(
|
||||
r: &ty::Region<'tcx>,
|
||||
tnm: &ty::TypeAndMut<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
mutbl: hir::Mutability,
|
||||
s: &mut DiagnosticStyledString,
|
||||
) {
|
||||
let r = &format!("{}", r);
|
||||
|
@ -673,13 +674,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
"&{}{}{}",
|
||||
r,
|
||||
if r == "" { "" } else { " " },
|
||||
if tnm.mutbl == hir::MutMutable {
|
||||
if mutbl == hir::MutMutable {
|
||||
"mut "
|
||||
} else {
|
||||
""
|
||||
}
|
||||
));
|
||||
s.push_normal(format!("{}", tnm.ty));
|
||||
s.push_normal(format!("{}", ty));
|
||||
}
|
||||
|
||||
match (&t1.sty, &t2.sty) {
|
||||
|
@ -803,24 +804,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
// When finding T != &T, highlight only the borrow
|
||||
(&ty::TyRef(r1, ref tnm1), _) if equals(&tnm1.ty, &t2) => {
|
||||
(&ty::TyRef(r1, ref_ty1, mutbl1), _) if equals(&ref_ty1, &t2) => {
|
||||
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
|
||||
push_ty_ref(&r1, tnm1, &mut values.0);
|
||||
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
|
||||
values.1.push_normal(format!("{}", t2));
|
||||
values
|
||||
}
|
||||
(_, &ty::TyRef(r2, ref tnm2)) if equals(&t1, &tnm2.ty) => {
|
||||
(_, &ty::TyRef(r2, ref_ty2, mutbl2)) if equals(&t1, &ref_ty2) => {
|
||||
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
|
||||
values.0.push_normal(format!("{}", t1));
|
||||
push_ty_ref(&r2, tnm2, &mut values.1);
|
||||
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
|
||||
values
|
||||
}
|
||||
|
||||
// When encountering &T != &mut T, highlight only the borrow
|
||||
(&ty::TyRef(r1, ref tnm1), &ty::TyRef(r2, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => {
|
||||
(&ty::TyRef(r1, ref_ty1, mutbl1),
|
||||
&ty::TyRef(r2, ref_ty2, mutbl2)) if equals(&ref_ty1, &ref_ty2) => {
|
||||
let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
|
||||
push_ty_ref(&r1, tnm1, &mut values.0);
|
||||
push_ty_ref(&r2, tnm2, &mut values.1);
|
||||
push_ty_ref(&r1, ref_ty1, mutbl1, &mut values.0);
|
||||
push_ty_ref(&r2, ref_ty2, mutbl2, &mut values.1);
|
||||
values
|
||||
}
|
||||
|
||||
|
|
|
@ -456,7 +456,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
// make sure that the thing we are pointing out stays valid
|
||||
// for the lifetime `scope_r` of the resulting ptr:
|
||||
let expr_ty = return_if_err!(self.mc.expr_ty(expr));
|
||||
if let ty::TyRef(r, _) = expr_ty.sty {
|
||||
if let ty::TyRef(r, _, _) = expr_ty.sty {
|
||||
let bk = ty::BorrowKind::from_mutbl(m);
|
||||
self.borrow_expr(&base, r, bk, AddrOf);
|
||||
}
|
||||
|
@ -859,7 +859,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
|||
// It is also a borrow or copy/move of the value being matched.
|
||||
match bm {
|
||||
ty::BindByReference(m) => {
|
||||
if let ty::TyRef(r, _) = pat_ty.sty {
|
||||
if let ty::TyRef(r, _, _) = pat_ty.sty {
|
||||
let bk = ty::BorrowKind::from_mutbl(m);
|
||||
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
|
||||
}
|
||||
|
|
|
@ -1012,7 +1012,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||
let base_ty = self.expr_ty_adjusted(base)?;
|
||||
|
||||
let (region, mutbl) = match base_ty.sty {
|
||||
ty::TyRef(region, mt) => (region, mt.mutbl),
|
||||
ty::TyRef(region, _, mutbl) => (region, mutbl),
|
||||
_ => {
|
||||
span_bug!(expr.span, "cat_overloaded_place: base is not a reference")
|
||||
}
|
||||
|
@ -1046,8 +1046,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
|
|||
let ptr = match base_cmt.ty.sty {
|
||||
ty::TyAdt(def, ..) if def.is_box() => Unique,
|
||||
ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
|
||||
ty::TyRef(r, mt) => {
|
||||
let bk = ty::BorrowKind::from_mutbl(mt.mutbl);
|
||||
ty::TyRef(r, _, mutbl) => {
|
||||
let bk = ty::BorrowKind::from_mutbl(mutbl);
|
||||
if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) }
|
||||
}
|
||||
ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
|
||||
|
|
|
@ -27,9 +27,8 @@ use hir::def_id::DefId;
|
|||
use mir::visit::MirVisitable;
|
||||
use mir::interpret::{Value, PrimVal, EvalErrorKind};
|
||||
use ty::subst::{Subst, Substs};
|
||||
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, Region, Ty, TyCtxt, GeneratorInterior};
|
||||
use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
|
||||
use ty::TypeAndMut;
|
||||
use util::ppaux;
|
||||
use std::slice;
|
||||
use hir::{self, InlineAsm};
|
||||
|
@ -1641,7 +1640,7 @@ pub enum AggregateKind<'tcx> {
|
|||
Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option<usize>),
|
||||
|
||||
Closure(DefId, ClosureSubsts<'tcx>),
|
||||
Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>),
|
||||
Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
|
||||
|
@ -1905,9 +1904,8 @@ pub fn print_miri_value<W: Write>(value: Value, ty: Ty, f: &mut W) -> fmt::Resul
|
|||
write!(f, "{:?}", ::std::char::from_u32(n as u32).unwrap()),
|
||||
(Value::ByVal(PrimVal::Undef), &TyFnDef(did, _)) =>
|
||||
write!(f, "{}", item_path_str(did)),
|
||||
(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)), &TyRef(_, TypeAndMut {
|
||||
ty: &ty::TyS { sty: TyStr, .. }, ..
|
||||
})) => {
|
||||
(Value::ByValPair(PrimVal::Ptr(ptr), PrimVal::Bytes(len)),
|
||||
&TyRef(_, &ty::TyS { sty: TyStr, .. }, _)) => {
|
||||
ty::tls::with(|tcx| {
|
||||
let alloc = tcx
|
||||
.interpret_interner
|
||||
|
@ -2375,10 +2373,8 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
|||
AggregateKind::Adt(def, v, substs.fold_with(folder), n),
|
||||
AggregateKind::Closure(id, substs) =>
|
||||
AggregateKind::Closure(id, substs.fold_with(folder)),
|
||||
AggregateKind::Generator(id, substs, interior) =>
|
||||
AggregateKind::Generator(id,
|
||||
substs.fold_with(folder),
|
||||
interior.fold_with(folder)),
|
||||
AggregateKind::Generator(id, substs, movablity) =>
|
||||
AggregateKind::Generator(id, substs.fold_with(folder), movablity),
|
||||
};
|
||||
Aggregate(kind, fields.fold_with(folder))
|
||||
}
|
||||
|
@ -2405,8 +2401,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
|
|||
AggregateKind::Tuple => false,
|
||||
AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor),
|
||||
AggregateKind::Closure(_, substs) => substs.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, interior) => substs.visit_with(visitor) ||
|
||||
interior.visit_with(visitor),
|
||||
AggregateKind::Generator(_, substs, _) => substs.visit_with(visitor),
|
||||
}) || fields.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,10 +184,10 @@ impl<'tcx> Rvalue<'tcx> {
|
|||
tcx.type_of(def.did).subst(tcx, substs)
|
||||
}
|
||||
AggregateKind::Closure(did, substs) => {
|
||||
tcx.mk_closure_from_closure_substs(did, substs)
|
||||
tcx.mk_closure(did, substs)
|
||||
}
|
||||
AggregateKind::Generator(did, substs, interior) => {
|
||||
tcx.mk_generator(did, substs, interior)
|
||||
AggregateKind::Generator(did, substs, movability) => {
|
||||
tcx.mk_generator(did, substs, movability)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
use hir::def_id::DefId;
|
||||
use ty::subst::Substs;
|
||||
use ty::{CanonicalTy, ClosureSubsts, Region, Ty, GeneratorInterior};
|
||||
use ty::{CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty};
|
||||
use mir::*;
|
||||
use syntax_pos::Span;
|
||||
|
||||
|
@ -243,10 +243,10 @@ macro_rules! make_mir_visitor {
|
|||
self.super_closure_substs(substs);
|
||||
}
|
||||
|
||||
fn visit_generator_interior(&mut self,
|
||||
interior: & $($mutability)* GeneratorInterior<'tcx>,
|
||||
fn visit_generator_substs(&mut self,
|
||||
substs: & $($mutability)* GeneratorSubsts<'tcx>,
|
||||
_: Location) {
|
||||
self.super_generator_interior(interior);
|
||||
self.super_generator_substs(substs);
|
||||
}
|
||||
|
||||
fn visit_local_decl(&mut self,
|
||||
|
@ -595,11 +595,10 @@ macro_rules! make_mir_visitor {
|
|||
self.visit_closure_substs(closure_substs, location);
|
||||
}
|
||||
AggregateKind::Generator(ref $($mutability)* def_id,
|
||||
ref $($mutability)* closure_substs,
|
||||
ref $($mutability)* interior) => {
|
||||
ref $($mutability)* generator_substs,
|
||||
_movability) => {
|
||||
self.visit_def_id(def_id, location);
|
||||
self.visit_closure_substs(closure_substs, location);
|
||||
self.visit_generator_interior(interior, location);
|
||||
self.visit_generator_substs(generator_substs, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -786,8 +785,8 @@ macro_rules! make_mir_visitor {
|
|||
fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) {
|
||||
}
|
||||
|
||||
fn super_generator_interior(&mut self,
|
||||
_interior: & $($mutability)* GeneratorInterior<'tcx>) {
|
||||
fn super_generator_substs(&mut self,
|
||||
_substs: & $($mutability)* GeneratorSubsts<'tcx>) {
|
||||
}
|
||||
|
||||
fn super_closure_substs(&mut self,
|
||||
|
|
|
@ -878,9 +878,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
let mut trait_type = trait_ref.self_ty();
|
||||
|
||||
for refs_remaining in 0..refs_number {
|
||||
if let ty::TypeVariants::TyRef(_, ty::TypeAndMut{ ty: t_type, mutbl: _ }) =
|
||||
trait_type.sty {
|
||||
|
||||
if let ty::TypeVariants::TyRef(_, t_type, _) = trait_type.sty {
|
||||
trait_type = t_type;
|
||||
|
||||
let substs = self.tcx.mk_substs_trait(trait_type, &[]);
|
||||
|
|
|
@ -482,8 +482,8 @@ pub struct VtableImplData<'tcx, N> {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable)]
|
||||
pub struct VtableGeneratorData<'tcx, N> {
|
||||
pub closure_def_id: DefId,
|
||||
pub substs: ty::ClosureSubsts<'tcx>,
|
||||
pub generator_def_id: DefId,
|
||||
pub substs: ty::GeneratorSubsts<'tcx>,
|
||||
/// Nested obligations. This can be non-empty if the generator
|
||||
/// signature contains associated types.
|
||||
pub nested: Vec<N>
|
||||
|
@ -991,7 +991,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
|
|||
nested: p.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
VtableGenerator(c) => VtableGenerator(VtableGeneratorData {
|
||||
closure_def_id: c.closure_def_id,
|
||||
generator_def_id: c.generator_def_id,
|
||||
substs: c.substs,
|
||||
nested: c.nested.into_iter().map(f).collect(),
|
||||
}),
|
||||
|
|
|
@ -1288,7 +1288,7 @@ fn confirm_generator_candidate<'cx, 'gcx, 'tcx>(
|
|||
vtable: VtableGeneratorData<'tcx, PredicateObligation<'tcx>>)
|
||||
-> Progress<'tcx>
|
||||
{
|
||||
let gen_sig = vtable.substs.generator_poly_sig(vtable.closure_def_id, selcx.tcx());
|
||||
let gen_sig = vtable.substs.poly_sig(vtable.generator_def_id, selcx.tcx());
|
||||
let Normalized {
|
||||
value: gen_sig,
|
||||
obligations
|
||||
|
|
|
@ -2174,14 +2174,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
|
||||
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
||||
ty::TyChar | ty::TyRawPtr(..) | ty::TyNever |
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => {
|
||||
ty::TyRef(_, _, hir::MutImmutable) => {
|
||||
// Implementations provided in libcore
|
||||
None
|
||||
}
|
||||
|
||||
ty::TyDynamic(..) | ty::TyStr | ty::TySlice(..) |
|
||||
ty::TyGenerator(..) | ty::TyGeneratorWitness(..) | ty::TyForeign(..) |
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutMutable }) => {
|
||||
ty::TyRef(_, _, hir::MutMutable) => {
|
||||
Never
|
||||
}
|
||||
|
||||
|
@ -2270,7 +2270,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: element_ty, ..}) |
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: element_ty, ..}) => {
|
||||
ty::TyRef(_, element_ty, _) => {
|
||||
vec![element_ty]
|
||||
},
|
||||
|
||||
|
@ -2287,8 +2287,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
substs.upvar_tys(def_id, self.tcx()).collect()
|
||||
}
|
||||
|
||||
ty::TyGenerator(def_id, ref substs, interior) => {
|
||||
substs.upvar_tys(def_id, self.tcx()).chain(iter::once(interior.witness)).collect()
|
||||
ty::TyGenerator(def_id, ref substs, _) => {
|
||||
let witness = substs.witness(def_id, self.tcx());
|
||||
substs.upvar_tys(def_id, self.tcx()).chain(iter::once(witness)).collect()
|
||||
}
|
||||
|
||||
ty::TyGeneratorWitness(types) => {
|
||||
|
@ -2762,18 +2763,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
// touch bound regions, they just capture the in-scope
|
||||
// type/region parameters
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||
let (closure_def_id, substs) = match self_ty.sty {
|
||||
let (generator_def_id, substs) = match self_ty.sty {
|
||||
ty::TyGenerator(id, substs, _) => (id, substs),
|
||||
_ => bug!("closure candidate for non-closure {:?}", obligation)
|
||||
};
|
||||
|
||||
debug!("confirm_generator_candidate({:?},{:?},{:?})",
|
||||
obligation,
|
||||
closure_def_id,
|
||||
generator_def_id,
|
||||
substs);
|
||||
|
||||
let trait_ref =
|
||||
self.generator_trait_ref_unnormalized(obligation, closure_def_id, substs);
|
||||
self.generator_trait_ref_unnormalized(obligation, generator_def_id, substs);
|
||||
let Normalized {
|
||||
value: trait_ref,
|
||||
mut obligations
|
||||
|
@ -2783,8 +2784,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
obligation.recursion_depth+1,
|
||||
&trait_ref);
|
||||
|
||||
debug!("confirm_generator_candidate(closure_def_id={:?}, trait_ref={:?}, obligations={:?})",
|
||||
closure_def_id,
|
||||
debug!("confirm_generator_candidate(generator_def_id={:?}, \
|
||||
trait_ref={:?}, obligations={:?})",
|
||||
generator_def_id,
|
||||
trait_ref,
|
||||
obligations);
|
||||
|
||||
|
@ -2795,7 +2797,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
trait_ref)?);
|
||||
|
||||
Ok(VtableGeneratorData {
|
||||
closure_def_id: closure_def_id,
|
||||
generator_def_id: generator_def_id,
|
||||
substs: substs.clone(),
|
||||
nested: obligations
|
||||
})
|
||||
|
@ -3301,10 +3303,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
fn generator_trait_ref_unnormalized(&mut self,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
closure_def_id: DefId,
|
||||
substs: ty::ClosureSubsts<'tcx>)
|
||||
substs: ty::GeneratorSubsts<'tcx>)
|
||||
-> ty::PolyTraitRef<'tcx>
|
||||
{
|
||||
let gen_sig = substs.generator_poly_sig(closure_def_id, self.tcx());
|
||||
let gen_sig = substs.poly_sig(closure_def_id, self.tcx());
|
||||
|
||||
// (1) Feels icky to skip the binder here, but OTOH we know
|
||||
// that the self-type is an generator type and hence is
|
||||
|
|
|
@ -83,8 +83,8 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableImplData<'tcx, N> {
|
|||
|
||||
impl<'tcx, N: fmt::Debug> fmt::Debug for traits::VtableGeneratorData<'tcx, N> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "VtableGenerator(closure_def_id={:?}, substs={:?}, nested={:?})",
|
||||
self.closure_def_id,
|
||||
write!(f, "VtableGenerator(generator_def_id={:?}, substs={:?}, nested={:?})",
|
||||
self.generator_def_id,
|
||||
self.substs,
|
||||
self.nested)
|
||||
}
|
||||
|
@ -294,13 +294,13 @@ impl<'a, 'tcx> Lift<'tcx> for traits::Vtable<'a, ()> {
|
|||
}
|
||||
traits::VtableAutoImpl(t) => Some(traits::VtableAutoImpl(t)),
|
||||
traits::VtableGenerator(traits::VtableGeneratorData {
|
||||
closure_def_id,
|
||||
generator_def_id,
|
||||
substs,
|
||||
nested
|
||||
}) => {
|
||||
tcx.lift(&substs).map(|substs| {
|
||||
traits::VtableGenerator(traits::VtableGeneratorData {
|
||||
closure_def_id: closure_def_id,
|
||||
generator_def_id: generator_def_id,
|
||||
substs: substs,
|
||||
nested: nested
|
||||
})
|
||||
|
@ -373,7 +373,7 @@ BraceStructTypeFoldableImpl! {
|
|||
|
||||
BraceStructTypeFoldableImpl! {
|
||||
impl<'tcx, N> TypeFoldable<'tcx> for traits::VtableGeneratorData<'tcx, N> {
|
||||
closure_def_id, substs, nested
|
||||
generator_def_id, substs, nested
|
||||
} where N: TypeFoldable<'tcx>
|
||||
}
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ pub enum CastTy<'tcx> {
|
|||
/// Function Pointers
|
||||
FnPtr,
|
||||
/// Raw pointers
|
||||
Ptr(&'tcx ty::TypeAndMut<'tcx>),
|
||||
Ptr(ty::TypeAndMut<'tcx>),
|
||||
/// References
|
||||
RPtr(&'tcx ty::TypeAndMut<'tcx>),
|
||||
RPtr(ty::TypeAndMut<'tcx>),
|
||||
}
|
||||
|
||||
/// Cast Kind. See RFC 401 (or librustc_typeck/check/cast.rs)
|
||||
|
@ -69,8 +69,8 @@ impl<'tcx> CastTy<'tcx> {
|
|||
ty::TyFloat(_) => Some(CastTy::Float),
|
||||
ty::TyAdt(d,_) if d.is_enum() && d.is_payloadfree() =>
|
||||
Some(CastTy::Int(IntTy::CEnum)),
|
||||
ty::TyRawPtr(ref mt) => Some(CastTy::Ptr(mt)),
|
||||
ty::TyRef(_, ref mt) => Some(CastTy::RPtr(mt)),
|
||||
ty::TyRawPtr(mt) => Some(CastTy::Ptr(mt)),
|
||||
ty::TyRef(_, ty, mutbl) => Some(CastTy::RPtr(ty::TypeAndMut { ty, mutbl })),
|
||||
ty::TyFnPtr(..) => Some(CastTy::FnPtr),
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ use traits;
|
|||
use traits::{Clause, Clauses, Goal, Goals};
|
||||
use ty::{self, Ty, TypeAndMut};
|
||||
use ty::{TyS, TypeVariants, Slice};
|
||||
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const};
|
||||
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
|
||||
use ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
|
||||
use ty::RegionKind;
|
||||
use ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid};
|
||||
|
@ -2351,7 +2351,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> {
|
||||
self.mk_ty(TyRef(r, tm))
|
||||
self.mk_ty(TyRef(r, tm.ty, tm.mutbl))
|
||||
}
|
||||
|
||||
pub fn mk_mut_ref(self, r: Region<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
|
@ -2436,26 +2436,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
}))
|
||||
}
|
||||
|
||||
pub fn mk_closure(self,
|
||||
closure_id: DefId,
|
||||
substs: ClosureSubsts<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
self.mk_closure_from_closure_substs(closure_id, substs)
|
||||
}
|
||||
|
||||
pub fn mk_closure_from_closure_substs(self,
|
||||
closure_id: DefId,
|
||||
closure_substs: ClosureSubsts<'tcx>)
|
||||
pub fn mk_closure(self, closure_id: DefId, closure_substs: ClosureSubsts<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
self.mk_ty(TyClosure(closure_id, closure_substs))
|
||||
}
|
||||
|
||||
pub fn mk_generator(self,
|
||||
id: DefId,
|
||||
closure_substs: ClosureSubsts<'tcx>,
|
||||
interior: GeneratorInterior<'tcx>)
|
||||
generator_substs: GeneratorSubsts<'tcx>,
|
||||
movability: hir::GeneratorMovability)
|
||||
-> Ty<'tcx> {
|
||||
self.mk_ty(TyGenerator(id, closure_substs, interior))
|
||||
self.mk_ty(TyGenerator(id, generator_substs, movability))
|
||||
}
|
||||
|
||||
pub fn mk_generator_witness(self, types: ty::Binder<&'tcx Slice<Ty<'tcx>>>) -> Ty<'tcx> {
|
||||
|
|
|
@ -189,20 +189,17 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
|
|||
}
|
||||
ty::TySlice(_) => "slice".to_string(),
|
||||
ty::TyRawPtr(_) => "*-ptr".to_string(),
|
||||
ty::TyRef(region, tymut) => {
|
||||
ty::TyRef(region, ty, mutbl) => {
|
||||
let tymut = ty::TypeAndMut { ty, mutbl };
|
||||
let tymut_string = tymut.to_string();
|
||||
if tymut_string == "_" || //unknown type name,
|
||||
tymut_string.len() > 10 || //name longer than saying "reference",
|
||||
region.to_string() != "" //... or a complex type
|
||||
{
|
||||
match tymut {
|
||||
ty::TypeAndMut{mutbl, ..} => {
|
||||
format!("{}reference", match mutbl {
|
||||
hir::Mutability::MutMutable => "mutable ",
|
||||
_ => ""
|
||||
})
|
||||
}
|
||||
}
|
||||
format!("{}reference", match mutbl {
|
||||
hir::Mutability::MutMutable => "mutable ",
|
||||
_ => ""
|
||||
})
|
||||
} else {
|
||||
format!("&{}", tymut_string)
|
||||
}
|
||||
|
|
|
@ -80,11 +80,11 @@ pub fn simplify_type<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
|||
ty::TyDynamic(ref trait_info, ..) => {
|
||||
trait_info.principal().map(|p| TraitSimplifiedType(p.def_id()))
|
||||
}
|
||||
ty::TyRef(_, mt) => {
|
||||
ty::TyRef(_, ty, _) => {
|
||||
// since we introduce auto-refs during method lookup, we
|
||||
// just treat &T and T as equivalent from the point of
|
||||
// view of possibly unifying
|
||||
simplify_type(tcx, mt.ty, can_simplify_params)
|
||||
simplify_type(tcx, ty, can_simplify_params)
|
||||
}
|
||||
ty::TyFnDef(def_id, _) |
|
||||
ty::TyClosure(def_id, _) => {
|
||||
|
|
|
@ -87,11 +87,10 @@ impl FlagComputation {
|
|||
}
|
||||
}
|
||||
|
||||
&ty::TyGenerator(_, ref substs, ref interior) => {
|
||||
&ty::TyGenerator(_, ref substs, _) => {
|
||||
self.add_flags(TypeFlags::HAS_TY_CLOSURE);
|
||||
self.add_flags(TypeFlags::HAS_LOCAL_NAMES);
|
||||
self.add_substs(&substs.substs);
|
||||
self.add_ty(interior.witness);
|
||||
}
|
||||
|
||||
&ty::TyGeneratorWitness(ref ts) => {
|
||||
|
@ -174,9 +173,9 @@ impl FlagComputation {
|
|||
self.add_ty(m.ty);
|
||||
}
|
||||
|
||||
&ty::TyRef(r, ref m) => {
|
||||
&ty::TyRef(r, ty, _) => {
|
||||
self.add_region(r);
|
||||
self.add_ty(m.ty);
|
||||
self.add_ty(ty);
|
||||
}
|
||||
|
||||
&ty::TyTuple(ref ts) => {
|
||||
|
|
|
@ -269,8 +269,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
_ => DefIdForest::empty()
|
||||
}
|
||||
}
|
||||
TyRef(_, ref tm) => {
|
||||
tm.ty.uninhabited_from(visited, tcx)
|
||||
TyRef(_, ty, _) => {
|
||||
ty.uninhabited_from(visited, tcx)
|
||||
}
|
||||
|
||||
_ => DefIdForest::empty(),
|
||||
|
|
|
@ -270,10 +270,10 @@ fn resolve_associated_item<'a, 'tcx>(
|
|||
let substs = tcx.erase_regions(&substs);
|
||||
Some(ty::Instance::new(def_id, substs))
|
||||
}
|
||||
traits::VtableGenerator(closure_data) => {
|
||||
traits::VtableGenerator(generator_data) => {
|
||||
Some(Instance {
|
||||
def: ty::InstanceDef::Item(closure_data.closure_def_id),
|
||||
substs: closure_data.substs.substs
|
||||
def: ty::InstanceDef::Item(generator_data.generator_def_id),
|
||||
substs: generator_data.substs.substs
|
||||
})
|
||||
}
|
||||
traits::VtableClosure(closure_data) => {
|
||||
|
@ -356,8 +356,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
|
|||
.unwrap().def_id;
|
||||
let def = ty::InstanceDef::ClosureOnceShim { call_once };
|
||||
|
||||
let self_ty = tcx.mk_closure_from_closure_substs(
|
||||
closure_did, substs);
|
||||
let self_ty = tcx.mk_closure(closure_did, substs);
|
||||
|
||||
let sig = substs.closure_sig(closure_did, tcx);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
||||
|
|
|
@ -360,8 +360,9 @@ pub fn characteristic_def_id_of_type(ty: Ty) -> Option<DefId> {
|
|||
ty::TyArray(subty, _) |
|
||||
ty::TySlice(subty) => characteristic_def_id_of_type(subty),
|
||||
|
||||
ty::TyRawPtr(mt) |
|
||||
ty::TyRef(_, mt) => characteristic_def_id_of_type(mt.ty),
|
||||
ty::TyRawPtr(mt) => characteristic_def_id_of_type(mt.ty),
|
||||
|
||||
ty::TyRef(_, ty, _) => characteristic_def_id_of_type(ty),
|
||||
|
||||
ty::TyTuple(ref tys) => tys.iter()
|
||||
.filter_map(|ty| characteristic_def_id_of_type(ty))
|
||||
|
|
|
@ -501,7 +501,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
}
|
||||
|
||||
// Potentially-fat pointers.
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
|
||||
ty::TyRef(_, pointee, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||
let mut data_ptr = scalar_unit(Pointer);
|
||||
if !ty.is_unsafe_ptr() {
|
||||
|
@ -1262,7 +1262,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
|
|||
};
|
||||
|
||||
match ty.sty {
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
|
||||
ty::TyRef(_, pointee, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||
let non_zero = !ty.is_unsafe_ptr();
|
||||
let tail = tcx.struct_tail(pointee);
|
||||
|
@ -1560,7 +1560,7 @@ impl<'a, 'tcx, C> TyLayoutMethods<'tcx, C> for Ty<'tcx>
|
|||
}
|
||||
|
||||
// Potentially-fat pointers.
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
|
||||
ty::TyRef(_, pointee, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||
assert!(i < 2);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ use hir;
|
|||
pub use self::sty::{Binder, CanonicalVar, DebruijnIndex};
|
||||
pub use self::sty::{FnSig, GenSig, PolyFnSig, PolyGenSig};
|
||||
pub use self::sty::{InferTy, ParamTy, ProjectionTy, ExistentialPredicate};
|
||||
pub use self::sty::{ClosureSubsts, GeneratorInterior, TypeAndMut};
|
||||
pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
|
||||
pub use self::sty::{TraitRef, TypeVariants, PolyTraitRef};
|
||||
pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
|
||||
pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
|
||||
|
@ -514,7 +514,7 @@ impl<'tcx> TyS<'tcx> {
|
|||
TypeVariants::TyInfer(InferTy::FloatVar(_)) |
|
||||
TypeVariants::TyInfer(InferTy::FreshIntTy(_)) |
|
||||
TypeVariants::TyInfer(InferTy::FreshFloatTy(_)) => true,
|
||||
TypeVariants::TyRef(_, x) => x.ty.is_primitive_ty(),
|
||||
TypeVariants::TyRef(_, x, _) => x.is_primitive_ty(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -415,16 +415,15 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
Ok(tcx.mk_dynamic(relation.relate(a_obj, b_obj)?, region_bound))
|
||||
}
|
||||
|
||||
(&ty::TyGenerator(a_id, a_substs, a_interior),
|
||||
&ty::TyGenerator(b_id, b_substs, b_interior))
|
||||
(&ty::TyGenerator(a_id, a_substs, movability),
|
||||
&ty::TyGenerator(b_id, b_substs, _))
|
||||
if a_id == b_id =>
|
||||
{
|
||||
// All TyGenerator types with the same id represent
|
||||
// the (anonymous) type of the same generator expression. So
|
||||
// all of their regions should be equated.
|
||||
let substs = relation.relate(&a_substs, &b_substs)?;
|
||||
let interior = relation.relate(&a_interior, &b_interior)?;
|
||||
Ok(tcx.mk_generator(a_id, substs, interior))
|
||||
Ok(tcx.mk_generator(a_id, substs, movability))
|
||||
}
|
||||
|
||||
(&ty::TyGeneratorWitness(a_types), &ty::TyGeneratorWitness(b_types)) =>
|
||||
|
@ -446,7 +445,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
// the (anonymous) type of the same closure expression. So
|
||||
// all of their regions should be equated.
|
||||
let substs = relation.relate(&a_substs, &b_substs)?;
|
||||
Ok(tcx.mk_closure_from_closure_substs(a_id, substs))
|
||||
Ok(tcx.mk_closure(a_id, substs))
|
||||
}
|
||||
|
||||
(&ty::TyRawPtr(ref a_mt), &ty::TyRawPtr(ref b_mt)) =>
|
||||
|
@ -455,10 +454,12 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
|
|||
Ok(tcx.mk_ptr(mt))
|
||||
}
|
||||
|
||||
(&ty::TyRef(a_r, ref a_mt), &ty::TyRef(b_r, ref b_mt)) =>
|
||||
(&ty::TyRef(a_r, a_ty, a_mutbl), &ty::TyRef(b_r, b_ty, b_mutbl)) =>
|
||||
{
|
||||
let r = relation.relate_with_variance(ty::Contravariant, &a_r, &b_r)?;
|
||||
let mt = relation.relate(a_mt, b_mt)?;
|
||||
let a_mt = ty::TypeAndMut { ty: a_ty, mutbl: a_mutbl };
|
||||
let b_mt = ty::TypeAndMut { ty: b_ty, mutbl: b_mutbl };
|
||||
let mt = relation.relate(&a_mt, &b_mt)?;
|
||||
Ok(tcx.mk_ref(r, mt))
|
||||
}
|
||||
|
||||
|
@ -607,20 +608,19 @@ impl<'tcx> Relate<'tcx> for ty::ClosureSubsts<'tcx> {
|
|||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
let substs = relate_substs(relation, None, a.substs, b.substs)?;
|
||||
Ok(ty::ClosureSubsts { substs: substs })
|
||||
Ok(ty::ClosureSubsts { substs })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::GeneratorInterior<'tcx> {
|
||||
impl<'tcx> Relate<'tcx> for ty::GeneratorSubsts<'tcx> {
|
||||
fn relate<'a, 'gcx, R>(relation: &mut R,
|
||||
a: &ty::GeneratorInterior<'tcx>,
|
||||
b: &ty::GeneratorInterior<'tcx>)
|
||||
-> RelateResult<'tcx, ty::GeneratorInterior<'tcx>>
|
||||
a: &ty::GeneratorSubsts<'tcx>,
|
||||
b: &ty::GeneratorSubsts<'tcx>)
|
||||
-> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>>
|
||||
where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
|
||||
{
|
||||
assert_eq!(a.movable, b.movable);
|
||||
let witness = relation.relate(&a.witness, &b.witness)?;
|
||||
Ok(ty::GeneratorInterior { witness, movable: a.movable })
|
||||
let substs = relate_substs(relation, None, a.substs, b.substs)?;
|
||||
Ok(ty::GeneratorSubsts { substs })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -304,16 +304,16 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ClosureSubsts<'a> {
|
|||
type Lifted = ty::ClosureSubsts<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&self.substs).map(|substs| {
|
||||
ty::ClosureSubsts { substs: substs }
|
||||
ty::ClosureSubsts { substs }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorInterior<'a> {
|
||||
type Lifted = ty::GeneratorInterior<'tcx>;
|
||||
impl<'a, 'tcx> Lift<'tcx> for ty::GeneratorSubsts<'a> {
|
||||
type Lifted = ty::GeneratorSubsts<'tcx>;
|
||||
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&self.witness).map(|witness| {
|
||||
ty::GeneratorInterior { witness, movable: self.movable }
|
||||
tcx.lift(&self.substs).map(|substs| {
|
||||
ty::GeneratorSubsts { substs }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -864,11 +864,14 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||
ty::TyFnDef(def_id, substs.fold_with(folder))
|
||||
}
|
||||
ty::TyFnPtr(f) => ty::TyFnPtr(f.fold_with(folder)),
|
||||
ty::TyRef(ref r, tm) => {
|
||||
ty::TyRef(r.fold_with(folder), tm.fold_with(folder))
|
||||
ty::TyRef(ref r, ty, mutbl) => {
|
||||
ty::TyRef(r.fold_with(folder), ty.fold_with(folder), mutbl)
|
||||
}
|
||||
ty::TyGenerator(did, substs, interior) => {
|
||||
ty::TyGenerator(did, substs.fold_with(folder), interior.fold_with(folder))
|
||||
ty::TyGenerator(did, substs, movability) => {
|
||||
ty::TyGenerator(
|
||||
did,
|
||||
substs.fold_with(folder),
|
||||
movability)
|
||||
}
|
||||
ty::TyGeneratorWitness(types) => ty::TyGeneratorWitness(types.fold_with(folder)),
|
||||
ty::TyClosure(did, substs) => ty::TyClosure(did, substs.fold_with(folder)),
|
||||
|
@ -901,9 +904,9 @@ impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
|
|||
ty::TyTuple(ts) => ts.visit_with(visitor),
|
||||
ty::TyFnDef(_, substs) => substs.visit_with(visitor),
|
||||
ty::TyFnPtr(ref f) => f.visit_with(visitor),
|
||||
ty::TyRef(r, ref tm) => r.visit_with(visitor) || tm.visit_with(visitor),
|
||||
ty::TyGenerator(_did, ref substs, ref interior) => {
|
||||
substs.visit_with(visitor) || interior.visit_with(visitor)
|
||||
ty::TyRef(r, ty, _) => r.visit_with(visitor) || ty.visit_with(visitor),
|
||||
ty::TyGenerator(_did, ref substs, _) => {
|
||||
substs.visit_with(visitor)
|
||||
}
|
||||
ty::TyGeneratorWitness(ref types) => types.visit_with(visitor),
|
||||
ty::TyClosure(_did, ref substs) => substs.visit_with(visitor),
|
||||
|
@ -980,8 +983,8 @@ BraceStructTypeFoldableImpl! {
|
|||
}
|
||||
|
||||
BraceStructTypeFoldableImpl! {
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorInterior<'tcx> {
|
||||
witness, movable,
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::GeneratorSubsts<'tcx> {
|
||||
substs,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ pub enum TypeVariants<'tcx> {
|
|||
|
||||
/// A reference; a pointer with an associated lifetime. Written as
|
||||
/// `&'a mut T` or `&'a T`.
|
||||
TyRef(Region<'tcx>, TypeAndMut<'tcx>),
|
||||
TyRef(Region<'tcx>, Ty<'tcx>, hir::Mutability),
|
||||
|
||||
/// The anonymous type of a function declaration/definition. Each
|
||||
/// function has a unique type.
|
||||
|
@ -139,7 +139,7 @@ pub enum TypeVariants<'tcx> {
|
|||
|
||||
/// The anonymous type of a generator. Used to represent the type of
|
||||
/// `|a| yield a`.
|
||||
TyGenerator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>),
|
||||
TyGenerator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
|
||||
|
||||
/// A type representin the types stored inside a generator.
|
||||
/// This should only appear in GeneratorInteriors.
|
||||
|
@ -328,37 +328,6 @@ impl<'tcx> ClosureSubsts<'tcx> {
|
|||
self.split(def_id, tcx).closure_sig_ty
|
||||
}
|
||||
|
||||
/// Returns the type representing the yield type of the generator.
|
||||
pub fn generator_yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
|
||||
self.closure_kind_ty(def_id, tcx)
|
||||
}
|
||||
|
||||
/// Returns the type representing the return type of the generator.
|
||||
pub fn generator_return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
|
||||
self.closure_sig_ty(def_id, tcx)
|
||||
}
|
||||
|
||||
/// Return the "generator signature", which consists of its yield
|
||||
/// and return types.
|
||||
///
|
||||
/// NB. Some bits of the code prefers to see this wrapped in a
|
||||
/// binder, but it never contains bound regions. Probably this
|
||||
/// function should be removed.
|
||||
pub fn generator_poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> {
|
||||
ty::Binder::dummy(self.generator_sig(def_id, tcx))
|
||||
}
|
||||
|
||||
/// Return the "generator signature", which consists of its yield
|
||||
/// and return types.
|
||||
pub fn generator_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> {
|
||||
ty::GenSig {
|
||||
yield_ty: self.generator_yield_ty(def_id, tcx),
|
||||
return_ty: self.generator_return_ty(def_id, tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ClosureSubsts<'tcx> {
|
||||
/// Returns the closure kind for this closure; only usable outside
|
||||
/// of an inference context, because in that context we know that
|
||||
/// there are no type variables.
|
||||
|
@ -381,7 +350,84 @@ impl<'tcx> ClosureSubsts<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct GeneratorSubsts<'tcx> {
|
||||
pub substs: &'tcx Substs<'tcx>,
|
||||
}
|
||||
|
||||
struct SplitGeneratorSubsts<'tcx> {
|
||||
yield_ty: Ty<'tcx>,
|
||||
return_ty: Ty<'tcx>,
|
||||
witness: Ty<'tcx>,
|
||||
upvar_kinds: &'tcx [Kind<'tcx>],
|
||||
}
|
||||
|
||||
impl<'tcx> GeneratorSubsts<'tcx> {
|
||||
fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitGeneratorSubsts<'tcx> {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
let parent_len = generics.parent_count();
|
||||
SplitGeneratorSubsts {
|
||||
yield_ty: self.substs.type_at(parent_len),
|
||||
return_ty: self.substs.type_at(parent_len + 1),
|
||||
witness: self.substs.type_at(parent_len + 2),
|
||||
upvar_kinds: &self.substs[parent_len + 3..],
|
||||
}
|
||||
}
|
||||
|
||||
/// This describes the types that can be contained in a generator.
|
||||
/// It will be a type variable initially and unified in the last stages of typeck of a body.
|
||||
/// It contains a tuple of all the types that could end up on a generator frame.
|
||||
/// The state transformation MIR pass may only produce layouts which mention types
|
||||
/// in this tuple. Upvars are not counted here.
|
||||
pub fn witness(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).witness
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) ->
|
||||
impl Iterator<Item=Ty<'tcx>> + 'tcx
|
||||
{
|
||||
let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
|
||||
upvar_kinds.iter().map(|t| {
|
||||
if let UnpackedKind::Type(ty) = t.unpack() {
|
||||
ty
|
||||
} else {
|
||||
bug!("upvar should be type")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the type representing the yield type of the generator.
|
||||
pub fn yield_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).yield_ty
|
||||
}
|
||||
|
||||
/// Returns the type representing the return type of the generator.
|
||||
pub fn return_ty(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> Ty<'tcx> {
|
||||
self.split(def_id, tcx).return_ty
|
||||
}
|
||||
|
||||
/// Return the "generator signature", which consists of its yield
|
||||
/// and return types.
|
||||
///
|
||||
/// NB. Some bits of the code prefers to see this wrapped in a
|
||||
/// binder, but it never contains bound regions. Probably this
|
||||
/// function should be removed.
|
||||
pub fn poly_sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> PolyGenSig<'tcx> {
|
||||
ty::Binder::dummy(self.sig(def_id, tcx))
|
||||
}
|
||||
|
||||
/// Return the "generator signature", which consists of its yield
|
||||
/// and return types.
|
||||
pub fn sig(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> GenSig<'tcx> {
|
||||
ty::GenSig {
|
||||
yield_ty: self.yield_ty(def_id, tcx),
|
||||
return_ty: self.return_ty(def_id, tcx),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
|
||||
/// This returns the types of the MIR locals which had to be stored across suspension points.
|
||||
/// It is calculated in rustc_mir::transform::generator::StateTransform.
|
||||
/// All the types here must be in the tuple in GeneratorInterior.
|
||||
|
@ -412,15 +458,29 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// This describes the types that can be contained in a generator.
|
||||
/// It will be a type variable initially and unified in the last stages of typeck of a body.
|
||||
/// It contains a tuple of all the types that could end up on a generator frame.
|
||||
/// The state transformation MIR pass may only produce layouts which mention types in this tuple.
|
||||
/// Upvars are not counted here.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
|
||||
pub struct GeneratorInterior<'tcx> {
|
||||
pub witness: Ty<'tcx>,
|
||||
pub movable: bool,
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum UpvarSubsts<'tcx> {
|
||||
Closure(ClosureSubsts<'tcx>),
|
||||
Generator(GeneratorSubsts<'tcx>),
|
||||
}
|
||||
|
||||
impl<'tcx> UpvarSubsts<'tcx> {
|
||||
#[inline]
|
||||
pub fn upvar_tys(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) ->
|
||||
impl Iterator<Item=Ty<'tcx>> + 'tcx
|
||||
{
|
||||
let upvar_kinds = match self {
|
||||
UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds,
|
||||
UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds,
|
||||
};
|
||||
upvar_kinds.iter().map(|t| {
|
||||
if let UnpackedKind::Type(ty) = t.unpack() {
|
||||
ty
|
||||
} else {
|
||||
bug!("upvar should be type")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
|
||||
|
@ -1332,7 +1392,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
|
||||
pub fn is_slice(&self) -> bool {
|
||||
match self.sty {
|
||||
TyRawPtr(mt) | TyRef(_, mt) => match mt.ty.sty {
|
||||
TyRawPtr(TypeAndMut { ty, .. }) | TyRef(_, ty, _) => match ty.sty {
|
||||
TySlice(_) | TyStr => true,
|
||||
_ => false,
|
||||
},
|
||||
|
@ -1381,11 +1441,8 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
|
||||
pub fn is_mutable_pointer(&self) -> bool {
|
||||
match self.sty {
|
||||
TyRawPtr(tnm) | TyRef(_, tnm) => if let hir::Mutability::MutMutable = tnm.mutbl {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
},
|
||||
TyRawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) |
|
||||
TyRef(_, _, hir::Mutability::MutMutable) => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
@ -1538,7 +1595,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
mutbl: hir::MutImmutable,
|
||||
})
|
||||
},
|
||||
TyRef(_, mt) => Some(mt),
|
||||
TyRef(_, ty, mutbl) => Some(TypeAndMut { ty, mutbl }),
|
||||
TyRawPtr(mt) if explicit => Some(mt),
|
||||
_ => None,
|
||||
}
|
||||
|
@ -1592,7 +1649,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
/// ignores late-bound regions binders.
|
||||
pub fn regions(&self) -> Vec<ty::Region<'tcx>> {
|
||||
match self.sty {
|
||||
TyRef(region, _) => {
|
||||
TyRef(region, _, _) => {
|
||||
vec![region]
|
||||
}
|
||||
TyDynamic(ref obj, region) => {
|
||||
|
@ -1605,8 +1662,9 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
|
|||
TyAdt(_, substs) | TyAnon(_, substs) => {
|
||||
substs.regions().collect()
|
||||
}
|
||||
TyClosure(_, ref substs) | TyGenerator(_, ref substs, _) => {
|
||||
substs.substs.regions().collect()
|
||||
TyClosure(_, ClosureSubsts { ref substs }) |
|
||||
TyGenerator(_, GeneratorSubsts { ref substs }, _) => {
|
||||
substs.regions().collect()
|
||||
}
|
||||
TyProjection(ref data) => {
|
||||
data.substs.regions().collect()
|
||||
|
|
|
@ -201,7 +201,7 @@ impl<'tcx> ty::ParamEnv<'tcx> {
|
|||
// Now libcore provides that impl.
|
||||
ty::TyUint(_) | ty::TyInt(_) | ty::TyBool | ty::TyFloat(_) |
|
||||
ty::TyChar | ty::TyRawPtr(..) | ty::TyNever |
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: _, mutbl: hir::MutImmutable }) => return Ok(()),
|
||||
ty::TyRef(_, _, hir::MutImmutable) => return Ok(()),
|
||||
|
||||
ty::TyAdt(adt, substs) => (adt, substs),
|
||||
|
||||
|
@ -664,8 +664,8 @@ impl<'a, 'gcx, 'tcx, W> TypeVisitor<'tcx> for TypeIdHasher<'a, 'gcx, 'tcx, W>
|
|||
_ => bug!("arrays should not have {:?} as length", n)
|
||||
}
|
||||
}
|
||||
TyRawPtr(m) |
|
||||
TyRef(_, m) => self.hash(m.mutbl),
|
||||
TyRawPtr(m) => self.hash(m.mutbl),
|
||||
TyRef(_, _, mutbl) => self.hash(mutbl),
|
||||
TyClosure(def_id, _) |
|
||||
TyGenerator(def_id, _, _) |
|
||||
TyAnon(def_id, _) |
|
||||
|
@ -1141,7 +1141,7 @@ impl<'tcx> ExplicitSelf<'tcx> {
|
|||
|
||||
match self_arg_ty.sty {
|
||||
_ if is_self_ty(self_arg_ty) => ByValue,
|
||||
ty::TyRef(region, ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => {
|
||||
ty::TyRef(region, ty, mutbl) if is_self_ty(ty) => {
|
||||
ByReference(region, mutbl)
|
||||
}
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, mutbl }) if is_self_ty(ty) => {
|
||||
|
|
|
@ -92,9 +92,12 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
|||
ty::TySlice(ty) => {
|
||||
stack.push(ty);
|
||||
}
|
||||
ty::TyRawPtr(ref mt) | ty::TyRef(_, ref mt) => {
|
||||
ty::TyRawPtr(ref mt) => {
|
||||
stack.push(mt.ty);
|
||||
}
|
||||
ty::TyRef(_, ty, _) => {
|
||||
stack.push(ty);
|
||||
}
|
||||
ty::TyProjection(ref data) => {
|
||||
stack.extend(data.substs.types().rev());
|
||||
}
|
||||
|
@ -118,8 +121,7 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
|
|||
ty::TyClosure(_, ref substs) => {
|
||||
stack.extend(substs.substs.types().rev());
|
||||
}
|
||||
ty::TyGenerator(_, ref substs, ref interior) => {
|
||||
stack.push(interior.witness);
|
||||
ty::TyGenerator(_, ref substs, _) => {
|
||||
stack.extend(substs.substs.types().rev());
|
||||
}
|
||||
ty::TyGeneratorWitness(ts) => {
|
||||
|
|
|
@ -298,9 +298,9 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
ty::TyRef(r, mt) => {
|
||||
ty::TyRef(r, rty, _) => {
|
||||
// WfReference
|
||||
if !r.has_escaping_regions() && !mt.ty.has_escaping_regions() {
|
||||
if !r.has_escaping_regions() && !rty.has_escaping_regions() {
|
||||
let cause = self.cause(traits::ReferenceOutlivesReferent(ty));
|
||||
self.out.push(
|
||||
traits::Obligation::new(
|
||||
|
@ -308,7 +308,7 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
|
|||
param_env,
|
||||
ty::Predicate::TypeOutlives(
|
||||
ty::Binder::dummy(
|
||||
ty::OutlivesPredicate(mt.ty, r)))));
|
||||
ty::OutlivesPredicate(rty, r)))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -995,14 +995,6 @@ define_print! {
|
|||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
('tcx) ty::GeneratorInterior<'tcx>, (self, f, cx) {
|
||||
display {
|
||||
self.witness.print(f, cx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
('tcx) ty::TypeVariants<'tcx>, (self, f, cx) {
|
||||
display {
|
||||
|
@ -1019,14 +1011,14 @@ define_print! {
|
|||
})?;
|
||||
tm.ty.print(f, cx)
|
||||
}
|
||||
TyRef(r, ref tm) => {
|
||||
TyRef(r, ty, mutbl) => {
|
||||
write!(f, "&")?;
|
||||
let s = r.print_to_string(cx);
|
||||
write!(f, "{}", s)?;
|
||||
if !s.is_empty() {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
tm.print(f, cx)
|
||||
ty::TypeAndMut { ty, mutbl }.print(f, cx)
|
||||
}
|
||||
TyNever => write!(f, "!"),
|
||||
TyTuple(ref tys) => {
|
||||
|
@ -1110,9 +1102,10 @@ define_print! {
|
|||
})
|
||||
}
|
||||
TyStr => write!(f, "str"),
|
||||
TyGenerator(did, substs, interior) => ty::tls::with(|tcx| {
|
||||
TyGenerator(did, substs, movability) => ty::tls::with(|tcx| {
|
||||
let upvar_tys = substs.upvar_tys(did, tcx);
|
||||
if interior.movable {
|
||||
let witness = substs.witness(did, tcx);
|
||||
if movability == hir::GeneratorMovability::Movable {
|
||||
write!(f, "[generator")?;
|
||||
} else {
|
||||
write!(f, "[static generator")?;
|
||||
|
@ -1145,7 +1138,7 @@ define_print! {
|
|||
}
|
||||
}
|
||||
|
||||
print!(f, cx, write(" "), print(interior), write("]"))
|
||||
print!(f, cx, write(" "), print(witness), write("]"))
|
||||
}),
|
||||
TyGeneratorWitness(types) => {
|
||||
ty::tls::with(|tcx| cx.in_binder(f, tcx, &types, tcx.lift(&types)))
|
||||
|
|
|
@ -1173,9 +1173,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MutableTransmutes {
|
|||
let msg = "mutating transmuted &mut T from &T may cause undefined behavior, \
|
||||
consider instead using an UnsafeCell";
|
||||
match get_transmute_from_to(cx, expr) {
|
||||
Some((&ty::TyRef(_, from_mt), &ty::TyRef(_, to_mt))) => {
|
||||
if to_mt.mutbl == hir::Mutability::MutMutable &&
|
||||
from_mt.mutbl == hir::Mutability::MutImmutable {
|
||||
Some((&ty::TyRef(_, _, from_mt), &ty::TyRef(_, _, to_mt))) => {
|
||||
if to_mt == hir::Mutability::MutMutable &&
|
||||
from_mt == hir::Mutability::MutImmutable {
|
||||
cx.span_lint(MUTABLE_TRANSMUTES, expr.span, msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -662,8 +662,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
|||
help: Some("consider using a struct instead"),
|
||||
},
|
||||
|
||||
ty::TyRawPtr(ref m) |
|
||||
ty::TyRef(_, ref m) => self.check_type_for_ffi(cache, m.ty),
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
|
||||
ty::TyRef(_, ty, _) => self.check_type_for_ffi(cache, ty),
|
||||
|
||||
ty::TyArray(ty, _) => self.check_type_for_ffi(cache, ty),
|
||||
|
||||
|
|
|
@ -773,8 +773,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
format!("{}", def.non_enum_variant().fields[field.index()].name)
|
||||
},
|
||||
ty::TyTuple(_) => format!("{}", field.index()),
|
||||
ty::TyRef(_, tnm) | ty::TyRawPtr(tnm) => {
|
||||
self.describe_field_from_ty(&tnm.ty, field)
|
||||
ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
|
||||
self.describe_field_from_ty(&ty, field)
|
||||
}
|
||||
ty::TyArray(ty, _) | ty::TySlice(ty) => self.describe_field_from_ty(&ty, field),
|
||||
ty::TyClosure(def_id, _) | ty::TyGenerator(def_id, _, _) => {
|
||||
|
|
|
@ -835,10 +835,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
tys.iter().cloned().enumerate()
|
||||
.for_each(|field| drop_field(self, field));
|
||||
}
|
||||
// Closures and generators also have disjoint fields, but they are only
|
||||
// directly accessed in the body of the closure/generator.
|
||||
// Closures also have disjoint fields, but they are only
|
||||
// directly accessed in the body of the closure.
|
||||
ty::TyClosure(def, substs)
|
||||
| ty::TyGenerator(def, substs, ..)
|
||||
if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty()
|
||||
=> {
|
||||
substs.upvar_tys(def, self.tcx).enumerate()
|
||||
.for_each(|field| drop_field(self, field));
|
||||
}
|
||||
// Generators also have disjoint fields, but they are only
|
||||
// directly accessed in the body of the generator.
|
||||
ty::TyGenerator(def, substs, _)
|
||||
if *drop_place == Place::Local(Local::new(1)) && !self.mir.upvar_decls.is_empty()
|
||||
=> {
|
||||
substs.upvar_tys(def, self.tcx).enumerate()
|
||||
|
@ -1906,8 +1913,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
|
||||
// Check the kind of deref to decide
|
||||
match base_ty.sty {
|
||||
ty::TyRef(_, tnm) => {
|
||||
match tnm.mutbl {
|
||||
ty::TyRef(_, _, mutbl) => {
|
||||
match mutbl {
|
||||
// Shared borrowed data is never mutable
|
||||
hir::MutImmutable => Err(place),
|
||||
// Mutably borrowed data is mutable, but only if we have a
|
||||
|
@ -2341,13 +2348,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
(
|
||||
ProjectionElem::Deref,
|
||||
ty::TyRef(
|
||||
_,
|
||||
ty::TypeAndMut {
|
||||
ty: _,
|
||||
mutbl: hir::MutImmutable,
|
||||
},
|
||||
),
|
||||
ty::TyRef( _, _, hir::MutImmutable),
|
||||
_,
|
||||
) => {
|
||||
// the borrow goes through a dereference of a shared reference.
|
||||
|
|
|
@ -20,7 +20,7 @@ use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue};
|
|||
use rustc::mir::{Local, PlaceProjection, ProjectionElem, Statement, Terminator};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts};
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts};
|
||||
|
||||
use super::region_infer::{Cause, RegionInferenceContext};
|
||||
use super::ToRegionVid;
|
||||
|
@ -97,6 +97,13 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
|
|||
self.super_ty(ty);
|
||||
}
|
||||
|
||||
/// We sometimes have `generator_substs` within an rvalue, or within a
|
||||
/// call. Make them live at the location where they appear.
|
||||
fn visit_generator_substs(&mut self, substs: &GeneratorSubsts<'tcx>, location: Location) {
|
||||
self.add_regular_live_constraint(*substs, location, Cause::LiveOther(location));
|
||||
self.super_generator_substs(substs);
|
||||
}
|
||||
|
||||
/// We sometimes have `closure_substs` within an rvalue, or within a
|
||||
/// call. Make them live at the location where they appear.
|
||||
fn visit_closure_substs(&mut self, substs: &ClosureSubsts<'tcx>, location: Location) {
|
||||
|
@ -263,7 +270,7 @@ impl<'cx, 'cg, 'gcx, 'tcx> ConstraintGeneration<'cx, 'cg, 'gcx, 'tcx> {
|
|||
|
||||
debug!("add_reborrow_constraint - base_ty = {:?}", base_ty);
|
||||
match base_ty.sty {
|
||||
ty::TyRef(ref_region, ty::TypeAndMut { ty: _, mutbl }) => {
|
||||
ty::TyRef(ref_region, _, mutbl) => {
|
||||
let span = self.mir.source_info(location).span;
|
||||
self.regioncx.add_outlives(
|
||||
span,
|
||||
|
|
|
@ -30,12 +30,11 @@ impl<'gcx, 'tcx> RegionInferenceContext<'tcx> {
|
|||
&substs.substs[..]
|
||||
));
|
||||
}
|
||||
DefiningTy::Generator(def_id, substs, interior) => {
|
||||
DefiningTy::Generator(def_id, substs, _) => {
|
||||
err.note(&format!(
|
||||
"defining type: {:?} with closure substs {:#?} and interior {:?}",
|
||||
"defining type: {:?} with generator substs {:#?}",
|
||||
def_id,
|
||||
&substs.substs[..],
|
||||
interior
|
||||
&substs.substs[..]
|
||||
));
|
||||
}
|
||||
DefiningTy::FnDef(def_id, substs) => {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorInterior, Ty, TypeFoldable};
|
||||
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
|
||||
use rustc::mir::{BasicBlock, Local, Location, Mir, Statement, StatementKind};
|
||||
use rustc::mir::visit::{MutVisitor, TyContext};
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
|
@ -90,19 +90,19 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
|
|||
*constant = self.renumber_regions(ty_context, &*constant);
|
||||
}
|
||||
|
||||
fn visit_generator_interior(&mut self,
|
||||
interior: &mut GeneratorInterior<'tcx>,
|
||||
location: Location) {
|
||||
fn visit_generator_substs(&mut self,
|
||||
substs: &mut GeneratorSubsts<'tcx>,
|
||||
location: Location) {
|
||||
debug!(
|
||||
"visit_generator_interior(interior={:?}, location={:?})",
|
||||
interior,
|
||||
"visit_generator_substs(substs={:?}, location={:?})",
|
||||
substs,
|
||||
location,
|
||||
);
|
||||
|
||||
let ty_context = TyContext::Location(location);
|
||||
*interior = self.renumber_regions(ty_context, interior);
|
||||
*substs = self.renumber_regions(ty_context, substs);
|
||||
|
||||
debug!("visit_generator_interior: interior={:?}", interior);
|
||||
debug!("visit_generator_substs: substs={:?}", substs);
|
||||
}
|
||||
|
||||
fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: Location) {
|
||||
|
|
|
@ -22,13 +22,13 @@
|
|||
//! The code in this file doesn't *do anything* with those results; it
|
||||
//! just returns them for other code to use.
|
||||
|
||||
use rustc::hir::{BodyOwnerKind, HirId};
|
||||
use rustc::hir::{self, BodyOwnerKind, HirId};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
|
||||
use rustc::infer::region_constraints::GenericKind;
|
||||
use rustc::infer::outlives::bounds::{self, OutlivesBound};
|
||||
use rustc::infer::outlives::free_region_map::FreeRegionRelations;
|
||||
use rustc::ty::{self, RegionVid, Ty, TyCtxt};
|
||||
use rustc::ty::{self, RegionVid, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
|
||||
use rustc::ty::fold::TypeFoldable;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
|
@ -116,7 +116,7 @@ pub enum DefiningTy<'tcx> {
|
|||
/// The MIR is a generator. The signature is that generators take
|
||||
/// no parameters and return the result of
|
||||
/// `ClosureSubsts::generator_return_ty`.
|
||||
Generator(DefId, ty::ClosureSubsts<'tcx>, ty::GeneratorInterior<'tcx>),
|
||||
Generator(DefId, ty::GeneratorSubsts<'tcx>, hir::GeneratorMovability),
|
||||
|
||||
/// The MIR is a fn item with the given def-id and substs. The signature
|
||||
/// of the function can be bound then with the `fn_sig` query.
|
||||
|
@ -509,7 +509,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
|||
|
||||
let yield_ty = match defining_ty {
|
||||
DefiningTy::Generator(def_id, substs, _) => {
|
||||
Some(substs.generator_yield_ty(def_id, self.infcx.tcx))
|
||||
Some(substs.yield_ty(def_id, self.infcx.tcx))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
@ -550,8 +550,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
|||
|
||||
match defining_ty.sty {
|
||||
ty::TyClosure(def_id, substs) => DefiningTy::Closure(def_id, substs),
|
||||
ty::TyGenerator(def_id, substs, interior) => {
|
||||
DefiningTy::Generator(def_id, substs, interior)
|
||||
ty::TyGenerator(def_id, substs, movability) => {
|
||||
DefiningTy::Generator(def_id, substs, movability)
|
||||
}
|
||||
ty::TyFnDef(def_id, substs) => DefiningTy::FnDef(def_id, substs),
|
||||
_ => span_bug!(
|
||||
|
@ -587,7 +587,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
|||
let closure_base_def_id = tcx.closure_base_def_id(self.mir_def_id);
|
||||
let identity_substs = Substs::identity_for_item(gcx, closure_base_def_id);
|
||||
let fr_substs = match defining_ty {
|
||||
DefiningTy::Closure(_, substs) | DefiningTy::Generator(_, substs, _) => {
|
||||
DefiningTy::Closure(_, ClosureSubsts { ref substs }) |
|
||||
DefiningTy::Generator(_, GeneratorSubsts { ref substs }, _) => {
|
||||
// In the case of closures, we rely on the fact that
|
||||
// the first N elements in the ClosureSubsts are
|
||||
// inherited from the `closure_base_def_id`.
|
||||
|
@ -595,9 +596,9 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
|||
// `identity_substs`, we will get only those regions
|
||||
// that correspond to early-bound regions declared on
|
||||
// the `closure_base_def_id`.
|
||||
assert!(substs.substs.len() >= identity_substs.len());
|
||||
assert_eq!(substs.substs.regions().count(), identity_substs.regions().count());
|
||||
substs.substs
|
||||
assert!(substs.len() >= identity_substs.len());
|
||||
assert_eq!(substs.regions().count(), identity_substs.regions().count());
|
||||
substs
|
||||
}
|
||||
|
||||
DefiningTy::FnDef(_, substs) | DefiningTy::Const(_, substs) => substs,
|
||||
|
@ -648,10 +649,10 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
DefiningTy::Generator(def_id, substs, interior) => {
|
||||
DefiningTy::Generator(def_id, substs, movability) => {
|
||||
assert_eq!(self.mir_def_id, def_id);
|
||||
let output = substs.generator_return_ty(def_id, tcx);
|
||||
let generator_ty = tcx.mk_generator(def_id, substs, interior);
|
||||
let output = substs.return_ty(def_id, tcx);
|
||||
let generator_ty = tcx.mk_generator(def_id, substs, movability);
|
||||
let inputs_and_output = self.infcx.tcx.intern_type_list(&[generator_ty, output]);
|
||||
ty::Binder::dummy(inputs_and_output)
|
||||
}
|
||||
|
|
|
@ -156,10 +156,8 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
|
|||
ty::TyRawPtr(_) |
|
||||
ty::TyRef(
|
||||
_, /*rgn*/
|
||||
ty::TypeAndMut {
|
||||
ty: _,
|
||||
mutbl: hir::MutImmutable,
|
||||
},
|
||||
_, /*ty*/
|
||||
hir::MutImmutable
|
||||
) => {
|
||||
// don't continue traversing over derefs of raw pointers or shared borrows.
|
||||
self.next = None;
|
||||
|
@ -168,10 +166,8 @@ impl<'cx, 'gcx, 'tcx> Iterator for Prefixes<'cx, 'gcx, 'tcx> {
|
|||
|
||||
ty::TyRef(
|
||||
_, /*rgn*/
|
||||
ty::TypeAndMut {
|
||||
ty: _,
|
||||
mutbl: hir::MutMutable,
|
||||
},
|
||||
_, /*ty*/
|
||||
hir::MutMutable,
|
||||
) => {
|
||||
self.next = Some(&proj.base);
|
||||
return Some(cursor);
|
||||
|
|
|
@ -18,7 +18,7 @@ use build::expr::category::{Category, RvalueFunc};
|
|||
use hair::*;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::middle::region;
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::{self, Ty, UpvarSubsts};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::interpret::{Value, PrimVal, EvalErrorKind};
|
||||
use syntax_pos::Span;
|
||||
|
@ -185,27 +185,32 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
|
||||
block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields))
|
||||
}
|
||||
ExprKind::Closure { closure_id, substs, upvars, interior } => { // see (*) above
|
||||
ExprKind::Closure { closure_id, substs, upvars, movability } => {
|
||||
// see (*) above
|
||||
let mut operands: Vec<_> =
|
||||
upvars.into_iter()
|
||||
.map(|upvar| unpack!(block = this.as_operand(block, scope, upvar)))
|
||||
.collect();
|
||||
let result = if let Some(interior) = interior {
|
||||
// Add the state operand since it follows the upvars in the generator
|
||||
// struct. See librustc_mir/transform/generator.rs for more details.
|
||||
operands.push(Operand::Constant(box Constant {
|
||||
span: expr_span,
|
||||
ty: this.hir.tcx().types.u32,
|
||||
literal: Literal::Value {
|
||||
value: this.hir.tcx().mk_const(ty::Const {
|
||||
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(0))),
|
||||
ty: this.hir.tcx().types.u32
|
||||
}),
|
||||
},
|
||||
}));
|
||||
box AggregateKind::Generator(closure_id, substs, interior)
|
||||
} else {
|
||||
box AggregateKind::Closure(closure_id, substs)
|
||||
let result = match substs {
|
||||
UpvarSubsts::Generator(substs) => {
|
||||
let movability = movability.unwrap();
|
||||
// Add the state operand since it follows the upvars in the generator
|
||||
// struct. See librustc_mir/transform/generator.rs for more details.
|
||||
operands.push(Operand::Constant(box Constant {
|
||||
span: expr_span,
|
||||
ty: this.hir.tcx().types.u32,
|
||||
literal: Literal::Value {
|
||||
value: this.hir.tcx().mk_const(ty::Const {
|
||||
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(0))),
|
||||
ty: this.hir.tcx().types.u32
|
||||
}),
|
||||
},
|
||||
}));
|
||||
box AggregateKind::Generator(closure_id, substs, movability)
|
||||
}
|
||||
UpvarSubsts::Closure(substs) => {
|
||||
box AggregateKind::Closure(closure_id, substs)
|
||||
}
|
||||
};
|
||||
block.and(Rvalue::Aggregate(result, operands))
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
|
|||
// array, so we can call `<[u8]>::eq` rather than having to find an
|
||||
// `<[u8; N]>::eq`.
|
||||
let unsize = |ty: Ty<'tcx>| match ty.sty {
|
||||
ty::TyRef(region, tam) => match tam.ty.sty {
|
||||
ty::TyRef(region, rty, _) => match rty.sty {
|
||||
ty::TyArray(inner_ty, n) => Some((region, inner_ty, n)),
|
||||
_ => None,
|
||||
},
|
||||
|
|
|
@ -130,7 +130,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
|
|||
let (yield_ty, return_ty) = if body.is_generator {
|
||||
let gen_sig = match ty.sty {
|
||||
ty::TyGenerator(gen_def_id, gen_substs, ..) =>
|
||||
gen_substs.generator_sig(gen_def_id, tcx),
|
||||
gen_substs.sig(gen_def_id, tcx),
|
||||
_ =>
|
||||
span_bug!(tcx.hir.span(id), "generator w/o generator type: {:?}", ty),
|
||||
};
|
||||
|
|
|
@ -283,7 +283,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
|
||||
hir::ExprAddrOf(mutbl, ref expr) => {
|
||||
let region = match expr_ty.sty {
|
||||
ty::TyRef(r, _) => r,
|
||||
ty::TyRef(r, _, _) => r,
|
||||
_ => span_bug!(expr.span, "type of & not region"),
|
||||
};
|
||||
ExprKind::Borrow {
|
||||
|
@ -470,9 +470,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
|
||||
hir::ExprClosure(..) => {
|
||||
let closure_ty = cx.tables().expr_ty(expr);
|
||||
let (def_id, substs, interior) = match closure_ty.sty {
|
||||
ty::TyClosure(def_id, substs) => (def_id, substs, None),
|
||||
ty::TyGenerator(def_id, substs, interior) => (def_id, substs, Some(interior)),
|
||||
let (def_id, substs, movability) = match closure_ty.sty {
|
||||
ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs), None),
|
||||
ty::TyGenerator(def_id, substs, movability) => {
|
||||
(def_id, UpvarSubsts::Generator(substs), Some(movability))
|
||||
}
|
||||
_ => {
|
||||
span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty);
|
||||
}
|
||||
|
@ -487,7 +489,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
closure_id: def_id,
|
||||
substs,
|
||||
upvars,
|
||||
interior,
|
||||
movability,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,13 +987,13 @@ fn overloaded_place<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
|
|||
// Reconstruct the output assuming it's a reference with the
|
||||
// same region and mutability as the receiver. This holds for
|
||||
// `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
|
||||
let (region, mt) = match recv_ty.sty {
|
||||
ty::TyRef(region, mt) => (region, mt),
|
||||
let (region, mutbl) = match recv_ty.sty {
|
||||
ty::TyRef(region, _, mutbl) => (region, mutbl),
|
||||
_ => span_bug!(expr.span, "overloaded_place: receiver is not a reference"),
|
||||
};
|
||||
let ref_ty = cx.tcx.mk_ref(region, ty::TypeAndMut {
|
||||
ty: place_ty,
|
||||
mutbl: mt.mutbl,
|
||||
mutbl,
|
||||
});
|
||||
|
||||
// construct the complete expression `foo()` for the overloaded call,
|
||||
|
|
|
@ -18,7 +18,7 @@ use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp};
|
|||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::region;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior};
|
||||
use rustc::ty::{AdtDef, UpvarSubsts, Region, Ty};
|
||||
use rustc::hir;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
@ -266,9 +266,9 @@ pub enum ExprKind<'tcx> {
|
|||
},
|
||||
Closure {
|
||||
closure_id: DefId,
|
||||
substs: ClosureSubsts<'tcx>,
|
||||
substs: UpvarSubsts<'tcx>,
|
||||
upvars: Vec<ExprRef<'tcx>>,
|
||||
interior: Option<GeneratorInterior<'tcx>>,
|
||||
movability: Option<hir::GeneratorMovability>,
|
||||
},
|
||||
Literal {
|
||||
literal: Literal<'tcx>,
|
||||
|
|
|
@ -46,13 +46,13 @@ struct LiteralExpander;
|
|||
impl<'tcx> PatternFolder<'tcx> for LiteralExpander {
|
||||
fn fold_pattern(&mut self, pat: &Pattern<'tcx>) -> Pattern<'tcx> {
|
||||
match (&pat.ty.sty, &*pat.kind) {
|
||||
(&ty::TyRef(_, mt), &PatternKind::Constant { ref value }) => {
|
||||
(&ty::TyRef(_, rty, _), &PatternKind::Constant { ref value }) => {
|
||||
Pattern {
|
||||
ty: pat.ty,
|
||||
span: pat.span,
|
||||
kind: box PatternKind::Deref {
|
||||
subpattern: Pattern {
|
||||
ty: mt.ty,
|
||||
ty: rty,
|
||||
span: pat.span,
|
||||
kind: box PatternKind::Constant { value: value.clone() },
|
||||
}
|
||||
|
@ -907,7 +907,7 @@ fn constructor_sub_pattern_tys<'a, 'tcx: 'a>(cx: &MatchCheckCtxt<'a, 'tcx>,
|
|||
ConstantValue(_) => vec![],
|
||||
_ => bug!("bad slice pattern {:?} {:?}", ctor, ty)
|
||||
},
|
||||
ty::TyRef(_, ref ty_and_mut) => vec![ty_and_mut.ty],
|
||||
ty::TyRef(_, rty, _) => vec![rty],
|
||||
ty::TyAdt(adt, substs) => {
|
||||
if adt.is_box() {
|
||||
// Use T as the sub pattern type of Box<T>.
|
||||
|
|
|
@ -238,9 +238,9 @@ impl<'tcx> fmt::Display for Pattern<'tcx> {
|
|||
PatternKind::Deref { ref subpattern } => {
|
||||
match self.ty.sty {
|
||||
ty::TyAdt(def, _) if def.is_box() => write!(f, "box ")?,
|
||||
ty::TyRef(_, mt) => {
|
||||
ty::TyRef(_, _, mutbl) => {
|
||||
write!(f, "&")?;
|
||||
if mt.mutbl == hir::MutMutable {
|
||||
if mutbl == hir::MutMutable {
|
||||
write!(f, "mut ")?;
|
||||
}
|
||||
}
|
||||
|
@ -424,13 +424,13 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
PatKind::Slice(ref prefix, ref slice, ref suffix) => {
|
||||
let ty = self.tables.node_id_to_type(pat.hir_id);
|
||||
match ty.sty {
|
||||
ty::TyRef(_, mt) =>
|
||||
ty::TyRef(_, ty, _) =>
|
||||
PatternKind::Deref {
|
||||
subpattern: Pattern {
|
||||
ty: mt.ty,
|
||||
ty,
|
||||
span: pat.span,
|
||||
kind: Box::new(self.slice_or_array_pattern(
|
||||
pat.span, mt.ty, prefix, slice, suffix))
|
||||
pat.span, ty, prefix, slice, suffix))
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -469,7 +469,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
PatKind::Binding(_, id, ref name, ref sub) => {
|
||||
let var_ty = self.tables.node_id_to_type(pat.hir_id);
|
||||
let region = match var_ty.sty {
|
||||
ty::TyRef(r, _) => Some(r),
|
||||
ty::TyRef(r, _, _) => Some(r),
|
||||
_ => None,
|
||||
};
|
||||
let bm = *self.tables.pat_binding_modes().get(pat.hir_id)
|
||||
|
@ -490,8 +490,8 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
|
|||
// A ref x pattern is the same node used for x, and as such it has
|
||||
// x's type, which is &T, where we want T (the type being matched).
|
||||
if let ty::BindByReference(_) = bm {
|
||||
if let ty::TyRef(_, mt) = ty.sty {
|
||||
ty = mt.ty;
|
||||
if let ty::TyRef(_, rty, _) = ty.sty {
|
||||
ty = rty;
|
||||
} else {
|
||||
bug!("`ref {}` has wrong type {}", name.node, ty);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use rustc::middle::const_val::{ConstVal, ErrKind};
|
|||
use rustc::mir;
|
||||
use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout};
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty, TyCtxt, TypeAndMut};
|
||||
use rustc::ty::maps::TyCtxtAt;
|
||||
use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||
use rustc::middle::const_val::FrameInfo;
|
||||
|
@ -778,8 +778,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
|
||||
pub(super) fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool {
|
||||
match ty.sty {
|
||||
ty::TyRawPtr(ref tam) |
|
||||
ty::TyRef(_, ref tam) => !self.type_is_sized(tam.ty),
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
|
||||
ty::TyRef(_, ty, _) => !self.type_is_sized(ty),
|
||||
ty::TyAdt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()),
|
||||
_ => false,
|
||||
}
|
||||
|
@ -1262,8 +1262,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
|
||||
ty::TyFnPtr(_) => PrimValKind::FnPtr,
|
||||
|
||||
ty::TyRef(_, ref tam) |
|
||||
ty::TyRawPtr(ref tam) if self.type_is_sized(tam.ty) => PrimValKind::Ptr,
|
||||
ty::TyRef(_, ty, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) if self.type_is_sized(ty) => {
|
||||
PrimValKind::Ptr
|
||||
}
|
||||
|
||||
ty::TyAdt(def, _) if def.is_box() => PrimValKind::Ptr,
|
||||
|
||||
|
@ -1403,8 +1405,10 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
}
|
||||
|
||||
ty::TyFnPtr(_) => self.memory.read_ptr_sized(ptr, ptr_align)?,
|
||||
ty::TyRef(_, ref tam) |
|
||||
ty::TyRawPtr(ref tam) => return self.read_ptr(ptr, ptr_align, tam.ty).map(Some),
|
||||
ty::TyRef(_, rty, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty: rty, .. }) => {
|
||||
return self.read_ptr(ptr, ptr_align, rty).map(Some)
|
||||
}
|
||||
|
||||
ty::TyAdt(def, _) => {
|
||||
if def.is_box() {
|
||||
|
@ -1504,10 +1508,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
dst_layout: TyLayout<'tcx>,
|
||||
) -> EvalResult<'tcx> {
|
||||
match (&src_layout.ty.sty, &dst_layout.ty.sty) {
|
||||
(&ty::TyRef(_, ref s), &ty::TyRef(_, ref d)) |
|
||||
(&ty::TyRef(_, ref s), &ty::TyRawPtr(ref d)) |
|
||||
(&ty::TyRawPtr(ref s), &ty::TyRawPtr(ref d)) => {
|
||||
self.unsize_into_ptr(src, src_layout.ty, dst, dst_layout.ty, s.ty, d.ty)
|
||||
(&ty::TyRef(_, s, _), &ty::TyRef(_, d, _)) |
|
||||
(&ty::TyRef(_, s, _), &ty::TyRawPtr(TypeAndMut { ty: d, .. })) |
|
||||
(&ty::TyRawPtr(TypeAndMut { ty: s, .. }),
|
||||
&ty::TyRawPtr(TypeAndMut { ty: d, .. })) => {
|
||||
self.unsize_into_ptr(src, src_layout.ty, dst, dst_layout.ty, s, d)
|
||||
}
|
||||
(&ty::TyAdt(def_a, _), &ty::TyAdt(def_b, _)) => {
|
||||
assert_eq!(def_a, def_b);
|
||||
|
|
|
@ -369,8 +369,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
|||
let val = self.read_place(base)?;
|
||||
|
||||
let pointee_type = match base_ty.sty {
|
||||
ty::TyRawPtr(ref tam) |
|
||||
ty::TyRef(_, ref tam) => tam.ty,
|
||||
ty::TyRawPtr(ref tam) => tam.ty,
|
||||
ty::TyRef(_, ty, _) => ty,
|
||||
ty::TyAdt(def, _) if def.is_box() => base_ty.boxed_ty(),
|
||||
_ => bug!("can only deref pointer types"),
|
||||
};
|
||||
|
|
|
@ -199,7 +199,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
|||
// mutability of raw pointers.
|
||||
// TODO: Should not be allowed when fat pointers are involved.
|
||||
(&ty::TyRawPtr(_), &ty::TyRawPtr(_)) => true,
|
||||
(&ty::TyRef(_, _), &ty::TyRef(_, _)) => {
|
||||
(&ty::TyRef(_, _, _), &ty::TyRef(_, _, _)) => {
|
||||
ty.is_mutable_pointer() == real_ty.is_mutable_pointer()
|
||||
}
|
||||
// rule out everything else
|
||||
|
|
|
@ -844,9 +844,9 @@ fn find_vtable_types_for_unsizing<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
};
|
||||
|
||||
match (&source_ty.sty, &target_ty.sty) {
|
||||
(&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) |
|
||||
(&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
|
||||
(&ty::TyRef(_, a, _),
|
||||
&ty::TyRef(_, b, _)) |
|
||||
(&ty::TyRef(_, a, _),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) |
|
||||
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
|
|
|
@ -18,7 +18,7 @@ use monomorphize::Instance;
|
|||
use rustc::hir;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::session::config::OptLevel;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty, TyCtxt, ClosureSubsts, GeneratorSubsts};
|
||||
use rustc::ty::subst::Substs;
|
||||
use syntax::ast;
|
||||
use syntax::attr::InlineAttr;
|
||||
|
@ -302,7 +302,7 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
|||
|
||||
self.push_type_name(inner_type, output);
|
||||
},
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
|
||||
ty::TyRef(_, inner_type, mutbl) => {
|
||||
output.push('&');
|
||||
if mutbl == hir::MutMutable {
|
||||
output.push_str("mut ");
|
||||
|
@ -376,11 +376,11 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> {
|
|||
self.push_type_name(sig.output(), output);
|
||||
}
|
||||
},
|
||||
ty::TyGenerator(def_id, ref closure_substs, _) |
|
||||
ty::TyClosure(def_id, ref closure_substs) => {
|
||||
ty::TyGenerator(def_id, GeneratorSubsts { ref substs }, _) |
|
||||
ty::TyClosure(def_id, ClosureSubsts { ref substs }) => {
|
||||
self.push_def_path(def_id, output);
|
||||
let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
|
||||
let substs = closure_substs.substs.truncate_to(self.tcx, generics);
|
||||
let substs = substs.truncate_to(self.tcx, generics);
|
||||
self.push_type_params(substs, iter::empty(), output);
|
||||
}
|
||||
ty::TyError |
|
||||
|
|
|
@ -84,8 +84,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
|
|||
.unwrap().def_id;
|
||||
let def = ty::InstanceDef::ClosureOnceShim { call_once };
|
||||
|
||||
let self_ty = tcx.mk_closure_from_closure_substs(
|
||||
closure_did, substs);
|
||||
let self_ty = tcx.mk_closure(closure_did, substs);
|
||||
|
||||
let sig = substs.closure_sig(closure_did, tcx);
|
||||
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
|
||||
|
|
|
@ -44,14 +44,14 @@ fn place_context<'a, 'tcx, D>(
|
|||
// A Deref projection may restrict the context, this depends on the type
|
||||
// being deref'd.
|
||||
let context = match ty.sty {
|
||||
ty::TyRef(re, tam) => {
|
||||
ty::TyRef(re, _, mutbl) => {
|
||||
let re = match re {
|
||||
&RegionKind::ReScope(ce) => Some(ce),
|
||||
&RegionKind::ReErased =>
|
||||
bug!("AddValidation pass must be run before erasing lifetimes"),
|
||||
_ => None
|
||||
};
|
||||
(re, tam.mutbl)
|
||||
(re, mutbl)
|
||||
}
|
||||
ty::TyRawPtr(_) =>
|
||||
// There is no guarantee behind even a mutable raw pointer,
|
||||
|
|
|
@ -54,12 +54,6 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
|
|||
*substs = self.tcx.erase_regions(substs);
|
||||
}
|
||||
|
||||
fn visit_closure_substs(&mut self,
|
||||
substs: &mut ty::ClosureSubsts<'tcx>,
|
||||
_: Location) {
|
||||
*substs = self.tcx.erase_regions(substs);
|
||||
}
|
||||
|
||||
fn visit_statement(&mut self,
|
||||
block: BasicBlock,
|
||||
statement: &mut Statement<'tcx>,
|
||||
|
|
|
@ -64,7 +64,7 @@ use rustc::hir::def_id::DefId;
|
|||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior};
|
||||
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
|
||||
use rustc::ty::subst::Substs;
|
||||
use util::dump_mir;
|
||||
use util::liveness::{self, LivenessMode};
|
||||
|
@ -464,7 +464,8 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
upvars: Vec<Ty<'tcx>>,
|
||||
interior: GeneratorInterior<'tcx>,
|
||||
interior: Ty<'tcx>,
|
||||
movable: bool,
|
||||
mir: &mut Mir<'tcx>)
|
||||
-> (HashMap<Local, (Ty<'tcx>, usize)>,
|
||||
GeneratorLayout<'tcx>,
|
||||
|
@ -474,11 +475,11 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
|
||||
mir,
|
||||
source,
|
||||
interior.movable);
|
||||
movable);
|
||||
// Erase regions from the types passed in from typeck so we can compare them with
|
||||
// MIR types
|
||||
let allowed_upvars = tcx.erase_regions(&upvars);
|
||||
let allowed = match interior.witness.sty {
|
||||
let allowed = match interior.sty {
|
||||
ty::TyGeneratorWitness(s) => tcx.erase_late_bound_regions(&s),
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -853,9 +854,11 @@ impl MirPass for StateTransform {
|
|||
let gen_ty = mir.local_decls.raw[1].ty;
|
||||
|
||||
// Get the interior types and substs which typeck computed
|
||||
let (upvars, interior) = match gen_ty.sty {
|
||||
ty::TyGenerator(_, substs, interior) => {
|
||||
(substs.upvar_tys(def_id, tcx).collect(), interior)
|
||||
let (upvars, interior, movable) = match gen_ty.sty {
|
||||
ty::TyGenerator(_, substs, movability) => {
|
||||
(substs.upvar_tys(def_id, tcx).collect(),
|
||||
substs.witness(def_id, tcx),
|
||||
movability == hir::GeneratorMovability::Movable)
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
|
@ -874,7 +877,13 @@ impl MirPass for StateTransform {
|
|||
// Extract locals which are live across suspension point into `layout`
|
||||
// `remap` gives a mapping from local indices onto generator struct indices
|
||||
// `storage_liveness` tells us which locals have live storage at suspension points
|
||||
let (remap, layout, storage_liveness) = compute_layout(tcx, source, upvars, interior, mir);
|
||||
let (remap, layout, storage_liveness) = compute_layout(
|
||||
tcx,
|
||||
source,
|
||||
upvars,
|
||||
interior,
|
||||
movable,
|
||||
mir);
|
||||
|
||||
let state_field = mir.upvar_decls.len();
|
||||
|
||||
|
|
|
@ -780,7 +780,10 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
|
|||
fn open_drop<'a>(&mut self) -> BasicBlock {
|
||||
let ty = self.place_ty(self.place);
|
||||
match ty.sty {
|
||||
ty::TyClosure(def_id, substs) |
|
||||
ty::TyClosure(def_id, substs) => {
|
||||
let tys : Vec<_> = substs.upvar_tys(def_id, self.tcx()).collect();
|
||||
self.open_drop_for_tuple(&tys)
|
||||
}
|
||||
// Note that `elaborate_drops` only drops the upvars of a generator,
|
||||
// and this is ok because `open_drop` here can only be reached
|
||||
// within that own generator's resume function.
|
||||
|
|
|
@ -418,11 +418,11 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> {
|
|||
self.push(&format!("+ substs: {:#?}", substs));
|
||||
}
|
||||
|
||||
AggregateKind::Generator(def_id, substs, interior) => {
|
||||
AggregateKind::Generator(def_id, substs, movability) => {
|
||||
self.push(&format!("generator"));
|
||||
self.push(&format!("+ def_id: {:?}", def_id));
|
||||
self.push(&format!("+ substs: {:#?}", substs));
|
||||
self.push(&format!("+ interior: {:?}", interior));
|
||||
self.push(&format!("+ movability: {:?}", movability));
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
|
|
@ -193,7 +193,7 @@ fn dtorck_constraint_for_ty<'a, 'gcx, 'tcx>(
|
|||
.map(|ty| dtorck_constraint_for_ty(tcx, span, for_ty, depth + 1, ty))
|
||||
.collect(),
|
||||
|
||||
ty::TyGenerator(def_id, substs, _interior) => {
|
||||
ty::TyGenerator(def_id, substs, _movability) => {
|
||||
// rust-lang/rust#49918: types can be constructed, stored
|
||||
// in the interior, and sit idle when generator yields
|
||||
// (and is subsequently dropped).
|
||||
|
|
|
@ -228,9 +228,9 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
|||
) -> (ValueRef, ValueRef) {
|
||||
debug!("unsize_thin_ptr: {:?} => {:?}", src_ty, dst_ty);
|
||||
match (&src_ty.sty, &dst_ty.sty) {
|
||||
(&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRef(_, ty::TypeAndMut { ty: b, .. })) |
|
||||
(&ty::TyRef(_, ty::TypeAndMut { ty: a, .. }),
|
||||
(&ty::TyRef(_, a, _),
|
||||
&ty::TyRef(_, b, _)) |
|
||||
(&ty::TyRef(_, a, _),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) |
|
||||
(&ty::TyRawPtr(ty::TypeAndMut { ty: a, .. }),
|
||||
&ty::TyRawPtr(ty::TypeAndMut { ty: b, .. })) => {
|
||||
|
|
|
@ -423,7 +423,7 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
}
|
||||
ty::TyGenerator(def_id, substs, _) => {
|
||||
let tcx = cx.tcx;
|
||||
let sig = substs.generator_poly_sig(def_id, cx.tcx);
|
||||
let sig = substs.poly_sig(def_id, cx.tcx);
|
||||
|
||||
let env_region = ty::ReLateBound(ty::DebruijnIndex::new(1), ty::BrEnv);
|
||||
let env_ty = tcx.mk_mut_ref(tcx.mk_region(env_region), ty);
|
||||
|
|
|
@ -555,7 +555,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
false)
|
||||
}
|
||||
ty::TyRawPtr(ty::TypeAndMut{ty, ..}) |
|
||||
ty::TyRef(_, ty::TypeAndMut{ty, ..}) => {
|
||||
ty::TyRef(_, ty, _) => {
|
||||
match ptr_metadata(ty) {
|
||||
Ok(res) => res,
|
||||
Err(metadata) => return metadata,
|
||||
|
@ -591,7 +591,7 @@ pub fn type_metadata<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
unique_type_id,
|
||||
usage_site_span).finalize(cx)
|
||||
}
|
||||
ty::TyGenerator(def_id, substs, _) => {
|
||||
ty::TyGenerator(def_id, substs, _) => {
|
||||
let upvar_tys : Vec<_> = substs.field_tys(def_id, cx.tcx).map(|t| {
|
||||
cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t)
|
||||
}).collect();
|
||||
|
|
|
@ -80,7 +80,7 @@ pub fn push_debuginfo_type_name<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||
output.push('*');
|
||||
}
|
||||
},
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: inner_type, mutbl }) => {
|
||||
ty::TyRef(_, inner_type, mutbl) => {
|
||||
if !cpp_like_names {
|
||||
output.push('&');
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use common::{C_i32, C_null};
|
|||
use libc::c_uint;
|
||||
use llvm::{self, ValueRef, BasicBlockRef};
|
||||
use llvm::debuginfo::DIScope;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::{self, Ty, TypeFoldable, UpvarSubsts};
|
||||
use rustc::ty::layout::{LayoutOf, TyLayout};
|
||||
use rustc::mir::{self, Mir};
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -571,15 +571,17 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||
|
||||
// Or is it the closure environment?
|
||||
let (closure_layout, env_ref) = match arg.layout.ty.sty {
|
||||
ty::TyRef(_, mt) | ty::TyRawPtr(mt) => (bx.cx.layout_of(mt.ty), true),
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) |
|
||||
ty::TyRef(_, ty, _) => (bx.cx.layout_of(ty), true),
|
||||
_ => (arg.layout, false)
|
||||
};
|
||||
|
||||
let upvar_tys = match closure_layout.ty.sty {
|
||||
ty::TyClosure(def_id, substs) |
|
||||
ty::TyGenerator(def_id, substs, _) => substs.upvar_tys(def_id, tcx),
|
||||
let (def_id, upvar_substs) = match closure_layout.ty.sty {
|
||||
ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
|
||||
ty::TyGenerator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
|
||||
_ => bug!("upvar_decls with non-closure arg0 type `{}`", closure_layout.ty)
|
||||
};
|
||||
let upvar_tys = upvar_substs.upvar_tys(def_id, tcx);
|
||||
|
||||
// Store the pointer to closure data in an alloca for debuginfo
|
||||
// because that's what the llvm.dbg.declare intrinsic expects.
|
||||
|
@ -614,8 +616,8 @@ fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||
// a pointer in an alloca for debuginfo atm.
|
||||
let mut ops = if env_ref || true { &ops[..] } else { &ops[1..] };
|
||||
|
||||
let ty = if let (true, &ty::TyRef(_, mt)) = (decl.by_ref, &ty.sty) {
|
||||
mt.ty
|
||||
let ty = if let (true, &ty::TyRef(_, ty, _)) = (decl.by_ref, &ty.sty) {
|
||||
ty
|
||||
} else {
|
||||
ops = &ops[..ops.len() - 1];
|
||||
ty
|
||||
|
|
|
@ -250,7 +250,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||
return llty;
|
||||
}
|
||||
let llty = match self.ty.sty {
|
||||
ty::TyRef(_, ty::TypeAndMut { ty, .. }) |
|
||||
ty::TyRef(_, ty, _) |
|
||||
ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
|
||||
cx.layout_of(ty).llvm_type(cx).ptr_to()
|
||||
}
|
||||
|
@ -418,11 +418,11 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
ty::TyRef(_, mt) if offset.bytes() == 0 => {
|
||||
let (size, align) = cx.size_and_align_of(mt.ty);
|
||||
ty::TyRef(_, ty, mt) if offset.bytes() == 0 => {
|
||||
let (size, align) = cx.size_and_align_of(ty);
|
||||
|
||||
let kind = match mt.mutbl {
|
||||
hir::MutImmutable => if cx.type_is_freeze(mt.ty) {
|
||||
let kind = match mt {
|
||||
hir::MutImmutable => if cx.type_is_freeze(ty) {
|
||||
PointerKind::Frozen
|
||||
} else {
|
||||
PointerKind::Shared
|
||||
|
|
|
@ -84,9 +84,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
expected = loop {
|
||||
debug!("inspecting {:?} with type {:?}", exp_ty, exp_ty.sty);
|
||||
match exp_ty.sty {
|
||||
ty::TypeVariants::TyRef(_, ty::TypeAndMut{
|
||||
ty: inner_ty, mutbl: inner_mutability,
|
||||
}) => {
|
||||
ty::TypeVariants::TyRef(_, inner_ty, inner_mutability) => {
|
||||
debug!("current discriminant is TyRef, inserting implicit deref");
|
||||
// Preserve the reference type. We'll need it later during HAIR lowering.
|
||||
pat_adjustments.push(exp_ty);
|
||||
|
@ -152,8 +150,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
if let hir::ExprLit(ref lt) = lt.node {
|
||||
if let ast::LitKind::ByteStr(_) = lt.node {
|
||||
let expected_ty = self.structurally_resolved_type(pat.span, expected);
|
||||
if let ty::TyRef(_, mt) = expected_ty.sty {
|
||||
if let ty::TySlice(_) = mt.ty.sty {
|
||||
if let ty::TyRef(_, r_ty, _) = expected_ty.sty {
|
||||
if let ty::TySlice(_) = r_ty.sty {
|
||||
pat_ty = tcx.mk_imm_ref(tcx.types.re_static,
|
||||
tcx.mk_slice(tcx.types.u8))
|
||||
}
|
||||
|
@ -334,8 +332,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// hack detailed in (*) below.
|
||||
debug!("check_pat_walk: expected={:?}", expected);
|
||||
let (rptr_ty, inner_ty) = match expected.sty {
|
||||
ty::TyRef(_, mt) if mt.mutbl == mutbl => {
|
||||
(expected, mt.ty)
|
||||
ty::TyRef(_, r_ty, r_mutbl) if r_mutbl == mutbl => {
|
||||
(expected, r_ty)
|
||||
}
|
||||
_ => {
|
||||
let inner_ty = self.next_ty_var(
|
||||
|
@ -408,7 +406,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
tcx.sess, pat.span, E0529,
|
||||
"expected an array or slice, found `{}`",
|
||||
expected_ty);
|
||||
if let ty::TyRef(_, ty::TypeAndMut { mutbl: _, ty }) = expected_ty.sty {
|
||||
if let ty::TyRef(_, ty, _) = expected_ty.sty {
|
||||
match ty.sty {
|
||||
ty::TyArray(..) | ty::TySlice(..) => {
|
||||
err.help("the semantics of slice patterns changed \
|
||||
|
|
|
@ -177,10 +177,10 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
|
|||
self.fcx.try_overloaded_deref(self.span, source, needs)
|
||||
.and_then(|InferOk { value: method, obligations: o }| {
|
||||
obligations.extend(o);
|
||||
if let ty::TyRef(region, mt) = method.sig.output().sty {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.output().sty {
|
||||
Some(OverloadedDeref {
|
||||
region,
|
||||
mutbl: mt.mutbl,
|
||||
mutbl,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -175,8 +175,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let method = self.register_infer_ok_obligations(ok);
|
||||
let mut autoref = None;
|
||||
if borrow {
|
||||
if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mt.mutbl {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mutbl {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// For initial two-phase borrow
|
||||
|
|
|
@ -46,7 +46,7 @@ use lint;
|
|||
use rustc::hir;
|
||||
use rustc::session::Session;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TypeFoldable};
|
||||
use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut};
|
||||
use rustc::ty::adjustment::AllowTwoPhase;
|
||||
use rustc::ty::cast::{CastKind, CastTy};
|
||||
use rustc::ty::subst::Substs;
|
||||
|
@ -319,7 +319,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
fcx.resolve_type_vars_if_possible(&self.expr_ty),
|
||||
tstr);
|
||||
match self.expr_ty.sty {
|
||||
ty::TyRef(_, ty::TypeAndMut { mutbl: mt, .. }) => {
|
||||
ty::TyRef(_, _, mt) => {
|
||||
let mtstr = match mt {
|
||||
hir::MutMutable => "mut ",
|
||||
hir::MutImmutable => "",
|
||||
|
@ -511,8 +511,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
fn check_ptr_ptr_cast(&self,
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
m_expr: &'tcx ty::TypeAndMut<'tcx>,
|
||||
m_cast: &'tcx ty::TypeAndMut<'tcx>)
|
||||
m_expr: ty::TypeAndMut<'tcx>,
|
||||
m_cast: ty::TypeAndMut<'tcx>)
|
||||
-> Result<CastKind, CastError> {
|
||||
debug!("check_ptr_ptr_cast m_expr={:?} m_cast={:?}", m_expr, m_cast);
|
||||
// ptr-ptr cast. vtables must match.
|
||||
|
@ -552,7 +552,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
fn check_fptr_ptr_cast(&self,
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
m_cast: &'tcx ty::TypeAndMut<'tcx>)
|
||||
m_cast: ty::TypeAndMut<'tcx>)
|
||||
-> Result<CastKind, CastError> {
|
||||
// fptr-ptr cast. must be to thin ptr
|
||||
|
||||
|
@ -565,7 +565,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
fn check_ptr_addr_cast(&self,
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
m_expr: &'tcx ty::TypeAndMut<'tcx>)
|
||||
m_expr: ty::TypeAndMut<'tcx>)
|
||||
-> Result<CastKind, CastError> {
|
||||
// ptr-addr cast. must be from thin ptr
|
||||
|
||||
|
@ -578,8 +578,8 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
fn check_ref_cast(&self,
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
m_expr: &'tcx ty::TypeAndMut<'tcx>,
|
||||
m_cast: &'tcx ty::TypeAndMut<'tcx>)
|
||||
m_expr: ty::TypeAndMut<'tcx>,
|
||||
m_cast: ty::TypeAndMut<'tcx>)
|
||||
-> Result<CastKind, CastError> {
|
||||
// array-ptr-cast.
|
||||
|
||||
|
@ -603,7 +603,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
|
||||
fn check_addr_ptr_cast(&self,
|
||||
fcx: &FnCtxt<'a, 'gcx, 'tcx>,
|
||||
m_cast: &'tcx ty::TypeAndMut<'tcx>)
|
||||
m_cast: TypeAndMut<'tcx>)
|
||||
-> Result<CastKind, CastError> {
|
||||
// ptr-addr cast. pointer must be thin.
|
||||
match fcx.pointer_kind(m_cast.ty, self.span)? {
|
||||
|
|
|
@ -113,23 +113,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
.next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span))
|
||||
},
|
||||
);
|
||||
let substs = ty::ClosureSubsts { substs };
|
||||
let closure_type = self.tcx.mk_closure(expr_def_id, substs);
|
||||
|
||||
if let Some(GeneratorTypes { yield_ty, interior }) = generator_types {
|
||||
if let Some(GeneratorTypes { yield_ty, interior, movability }) = generator_types {
|
||||
let substs = ty::GeneratorSubsts { substs };
|
||||
self.demand_eqtype(
|
||||
expr.span,
|
||||
yield_ty,
|
||||
substs.generator_yield_ty(expr_def_id, self.tcx),
|
||||
substs.yield_ty(expr_def_id, self.tcx),
|
||||
);
|
||||
self.demand_eqtype(
|
||||
expr.span,
|
||||
liberated_sig.output(),
|
||||
substs.generator_return_ty(expr_def_id, self.tcx),
|
||||
substs.return_ty(expr_def_id, self.tcx),
|
||||
);
|
||||
return self.tcx.mk_generator(expr_def_id, substs, interior);
|
||||
self.demand_eqtype(
|
||||
expr.span,
|
||||
interior,
|
||||
substs.witness(expr_def_id, self.tcx),
|
||||
);
|
||||
return self.tcx.mk_generator(expr_def_id, substs, movability);
|
||||
}
|
||||
|
||||
let substs = ty::ClosureSubsts { substs };
|
||||
let closure_type = self.tcx.mk_closure(expr_def_id, substs);
|
||||
|
||||
debug!(
|
||||
"check_closure: expr.id={:?} closure_type={:?}",
|
||||
expr.id, closure_type
|
||||
|
|
|
@ -214,7 +214,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
|
||||
}
|
||||
|
||||
ty::TyRef(r_b, mt_b) => {
|
||||
ty::TyRef(r_b, ty, mutbl) => {
|
||||
let mt_b = ty::TypeAndMut { ty, mutbl };
|
||||
return self.coerce_borrowed_pointer(a, b, r_b, mt_b);
|
||||
}
|
||||
|
||||
|
@ -266,7 +267,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
// yield.
|
||||
|
||||
let (r_a, mt_a) = match a.sty {
|
||||
ty::TyRef(r_a, mt_a) => {
|
||||
ty::TyRef(r_a, ty, mutbl) => {
|
||||
let mt_a = ty::TypeAndMut { ty, mutbl };
|
||||
coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
|
||||
(r_a, mt_a)
|
||||
}
|
||||
|
@ -427,7 +429,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
// Now apply the autoref. We have to extract the region out of
|
||||
// the final ref type we got.
|
||||
let r_borrow = match ty.sty {
|
||||
ty::TyRef(r_borrow, _) => r_borrow,
|
||||
ty::TyRef(r_borrow, _, _) => r_borrow,
|
||||
_ => span_bug!(span, "expected a ref type, got {:?}", ty),
|
||||
};
|
||||
let mutbl = match mt_b.mutbl {
|
||||
|
@ -471,12 +473,12 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
|
||||
// Handle reborrows before selecting `Source: CoerceUnsized<Target>`.
|
||||
let reborrow = match (&source.sty, &target.sty) {
|
||||
(&ty::TyRef(_, mt_a), &ty::TyRef(_, mt_b)) => {
|
||||
coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
|
||||
(&ty::TyRef(_, ty_a, mutbl_a), &ty::TyRef(_, _, mutbl_b)) => {
|
||||
coerce_mutbls(mutbl_a, mutbl_b)?;
|
||||
|
||||
let coercion = Coercion(self.cause.span);
|
||||
let r_borrow = self.next_region_var(coercion);
|
||||
let mutbl = match mt_b.mutbl {
|
||||
let mutbl = match mutbl_b {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// We don't allow two-phase borrows here, at least for initial
|
||||
|
@ -487,26 +489,26 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
};
|
||||
Some((Adjustment {
|
||||
kind: Adjust::Deref(None),
|
||||
target: mt_a.ty
|
||||
target: ty_a
|
||||
}, Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(r_borrow, mutbl)),
|
||||
target: self.tcx.mk_ref(r_borrow, ty::TypeAndMut {
|
||||
mutbl: mt_b.mutbl,
|
||||
ty: mt_a.ty
|
||||
mutbl: mutbl_b,
|
||||
ty: ty_a
|
||||
})
|
||||
}))
|
||||
}
|
||||
(&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) => {
|
||||
coerce_mutbls(mt_a.mutbl, mt_b.mutbl)?;
|
||||
(&ty::TyRef(_, ty_a, mt_a), &ty::TyRawPtr(ty::TypeAndMut { mutbl: mt_b, .. })) => {
|
||||
coerce_mutbls(mt_a, mt_b)?;
|
||||
|
||||
Some((Adjustment {
|
||||
kind: Adjust::Deref(None),
|
||||
target: mt_a.ty
|
||||
target: ty_a
|
||||
}, Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b.mutbl)),
|
||||
kind: Adjust::Borrow(AutoBorrow::RawPtr(mt_b)),
|
||||
target: self.tcx.mk_ptr(ty::TypeAndMut {
|
||||
mutbl: mt_b.mutbl,
|
||||
ty: mt_a.ty
|
||||
mutbl: mt_b,
|
||||
ty: ty_a
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
@ -719,7 +721,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
|
|||
debug!("coerce_unsafe_ptr(a={:?}, b={:?})", a, b);
|
||||
|
||||
let (is_ref, mt_a) = match a.sty {
|
||||
ty::TyRef(_, mt) => (true, mt),
|
||||
ty::TyRef(_, ty, mutbl) => (true, ty::TypeAndMut { ty, mutbl }),
|
||||
ty::TyRawPtr(mt) => (false, mt),
|
||||
_ => {
|
||||
return self.unify_and(a, b, identity);
|
||||
|
@ -886,12 +888,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. }
|
||||
] => {
|
||||
match self.node_ty(expr.hir_id).sty {
|
||||
ty::TyRef(_, mt_orig) => {
|
||||
ty::TyRef(_, _, mt_orig) => {
|
||||
let mutbl_adj: hir::Mutability = mutbl_adj.into();
|
||||
// Reborrow that we can safely ignore, because
|
||||
// the next adjustment can only be a Deref
|
||||
// which will be merged into it.
|
||||
mutbl_adj == mt_orig.mutbl
|
||||
mutbl_adj == mt_orig
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
|
|
@ -216,7 +216,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
expected: Ty<'tcx>)
|
||||
-> Option<(&'static str, String)> {
|
||||
match (&expected.sty, &checked_ty.sty) {
|
||||
(&ty::TyRef(_, exp), &ty::TyRef(_, check)) => match (&exp.ty.sty, &check.ty.sty) {
|
||||
(&ty::TyRef(_, exp, _), &ty::TyRef(_, check, _)) => match (&exp.sty, &check.sty) {
|
||||
(&ty::TyStr, &ty::TyArray(arr, _)) |
|
||||
(&ty::TyStr, &ty::TySlice(arr)) if arr == self.tcx.types.u8 => {
|
||||
if let hir::ExprLit(_) = expr.node {
|
||||
|
@ -241,7 +241,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
_ => None,
|
||||
},
|
||||
(&ty::TyRef(_, mutability), _) => {
|
||||
(&ty::TyRef(_, _, mutability), _) => {
|
||||
// Check if it can work when put into a ref. For example:
|
||||
//
|
||||
// ```
|
||||
|
@ -250,7 +250,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// let x = 0u32;
|
||||
// bar(&x); // error, expected &mut
|
||||
// ```
|
||||
let ref_ty = match mutability.mutbl {
|
||||
let ref_ty = match mutability {
|
||||
hir::Mutability::MutMutable => self.tcx.mk_mut_ref(
|
||||
self.tcx.mk_region(ty::ReStatic),
|
||||
checked_ty),
|
||||
|
@ -266,7 +266,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
hir::ExprCast(_, _) | hir::ExprBinary(_, _, _) => format!("({})", src),
|
||||
_ => src,
|
||||
};
|
||||
return Some(match mutability.mutbl {
|
||||
return Some(match mutability {
|
||||
hir::Mutability::MutMutable => {
|
||||
("consider mutably borrowing here", format!("&mut {}", sugg_expr))
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
None
|
||||
}
|
||||
(_, &ty::TyRef(_, checked)) => {
|
||||
(_, &ty::TyRef(_, checked, _)) => {
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest adding a `*`, or removing
|
||||
// a `&`.
|
||||
|
@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// (But, also check check the `expn_info()` to see if this is
|
||||
// a macro; if so, it's hard to extract the text and make a good
|
||||
// suggestion, so don't bother.)
|
||||
if self.infcx.can_sub(self.param_env, checked.ty, &expected).is_ok() &&
|
||||
if self.infcx.can_sub(self.param_env, checked, &expected).is_ok() &&
|
||||
expr.span.ctxt().outer().expn_info().is_none() {
|
||||
match expr.node {
|
||||
// Maybe remove `&`?
|
||||
|
@ -299,7 +299,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// Maybe add `*`? Only if `T: Copy`.
|
||||
_ => {
|
||||
if !self.infcx.type_moves_by_default(self.param_env,
|
||||
checked.ty,
|
||||
checked,
|
||||
expr.span) {
|
||||
let sp = self.sess().codemap().call_span_if_macro(expr.span);
|
||||
if let Ok(code) = self.tcx.sess.codemap().span_to_snippet(sp) {
|
||||
|
|
|
@ -17,7 +17,7 @@ use rustc::hir::def_id::DefId;
|
|||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||
use rustc::hir::{self, Pat, PatKind, Expr};
|
||||
use rustc::middle::region;
|
||||
use rustc::ty::{self, Ty, GeneratorInterior};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use syntax_pos::Span;
|
||||
use super::FnCtxt;
|
||||
|
@ -85,7 +85,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
|
|||
pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
||||
def_id: DefId,
|
||||
body_id: hir::BodyId,
|
||||
interior: GeneratorInterior<'tcx>) {
|
||||
interior: Ty<'tcx>) {
|
||||
let body = fcx.tcx.hir.body(body_id);
|
||||
let mut visitor = InteriorVisitor {
|
||||
fcx,
|
||||
|
@ -135,7 +135,7 @@ pub fn resolve_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>,
|
|||
witness, body.value.span);
|
||||
|
||||
// Unify the type variable inside the generator with the new witness
|
||||
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior.witness, witness) {
|
||||
match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(interior, witness) {
|
||||
Ok(ok) => fcx.register_infer_ok_obligations(ok),
|
||||
_ => bug!(),
|
||||
}
|
||||
|
|
|
@ -462,10 +462,10 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
if let Adjust::Deref(Some(ref mut deref)) = adjustment.kind {
|
||||
if let Some(ok) = self.try_overloaded_deref(expr.span, source, needs) {
|
||||
let method = self.register_infer_ok_obligations(ok);
|
||||
if let ty::TyRef(region, mt) = method.sig.output().sty {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.output().sty {
|
||||
*deref = OverloadedDeref {
|
||||
region,
|
||||
mutbl: mt.mutbl
|
||||
mutbl,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -521,8 +521,8 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
|||
debug!("convert_place_op_to_mutable: method={:?}", method);
|
||||
self.write_method_call(expr.hir_id, method);
|
||||
|
||||
let (region, mutbl) = if let ty::TyRef(r, mt) = method.sig.inputs()[0].sty {
|
||||
(r, mt.mutbl)
|
||||
let (region, mutbl) = if let ty::TyRef(r, _, mutbl) = method.sig.inputs()[0].sty {
|
||||
(r, mutbl)
|
||||
} else {
|
||||
span_bug!(expr.span, "input to place op is not a ref?");
|
||||
};
|
||||
|
|
|
@ -917,9 +917,9 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
pick.autoderefs = step.autoderefs;
|
||||
|
||||
// Insert a `&*` or `&mut *` if this is a reference type:
|
||||
if let ty::TyRef(_, mt) = step.self_ty.sty {
|
||||
if let ty::TyRef(_, _, mutbl) = step.self_ty.sty {
|
||||
pick.autoderefs += 1;
|
||||
pick.autoref = Some(mt.mutbl);
|
||||
pick.autoref = Some(mutbl);
|
||||
}
|
||||
|
||||
pick
|
||||
|
|
|
@ -208,7 +208,7 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
|
||||
deferred_cast_checks: RefCell<Vec<cast::CastCheck<'tcx>>>,
|
||||
|
||||
deferred_generator_interiors: RefCell<Vec<(hir::BodyId, ty::GeneratorInterior<'tcx>)>>,
|
||||
deferred_generator_interiors: RefCell<Vec<(hir::BodyId, Ty<'tcx>)>>,
|
||||
|
||||
// Anonymized types found in explicit return types and their
|
||||
// associated fresh inference variable. Writeback resolves these
|
||||
|
@ -1009,7 +1009,10 @@ struct GeneratorTypes<'tcx> {
|
|||
yield_ty: ty::Ty<'tcx>,
|
||||
|
||||
/// Types that are captured (see `GeneratorInterior` for more).
|
||||
interior: ty::GeneratorInterior<'tcx>
|
||||
interior: ty::Ty<'tcx>,
|
||||
|
||||
/// Indicates if the generator is movable or static (immovable)
|
||||
movability: hir::GeneratorMovability,
|
||||
}
|
||||
|
||||
/// Helper used for fns and closures. Does the grungy work of checking a function
|
||||
|
@ -1084,13 +1087,13 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
|
|||
// This ensures that all nested generators appear before the entry of this generator.
|
||||
// resolve_generator_interiors relies on this property.
|
||||
let gen_ty = if can_be_generator.is_some() && body.is_generator {
|
||||
let witness = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
|
||||
let interior = ty::GeneratorInterior {
|
||||
witness,
|
||||
movable: can_be_generator.unwrap() == hir::GeneratorMovability::Movable,
|
||||
};
|
||||
let interior = fcx.next_ty_var(TypeVariableOrigin::MiscVariable(span));
|
||||
fcx.deferred_generator_interiors.borrow_mut().push((body.id(), interior));
|
||||
Some(GeneratorTypes { yield_ty: fcx.yield_ty.unwrap(), interior: interior })
|
||||
Some(GeneratorTypes {
|
||||
yield_ty: fcx.yield_ty.unwrap(),
|
||||
interior,
|
||||
movability: can_be_generator.unwrap(),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -2390,8 +2393,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let method = self.register_infer_ok_obligations(ok);
|
||||
|
||||
let mut adjustments = autoderef.adjust_steps(needs);
|
||||
if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mt.mutbl {
|
||||
if let ty::TyRef(region, _, r_mutbl) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match r_mutbl {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// Indexing can be desugared to a method call,
|
||||
|
@ -2404,7 +2407,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
adjustments.push(Adjustment {
|
||||
kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
|
||||
target: self.tcx.mk_ref(region, ty::TypeAndMut {
|
||||
mutbl: mt.mutbl,
|
||||
mutbl: r_mutbl,
|
||||
ty: adjusted_ty
|
||||
})
|
||||
});
|
||||
|
@ -3612,8 +3615,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
} else if let Some(ok) = self.try_overloaded_deref(
|
||||
expr.span, oprnd_t, needs) {
|
||||
let method = self.register_infer_ok_obligations(ok);
|
||||
if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mt.mutbl {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mutbl {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// (It shouldn't actually matter for unary ops whether
|
||||
|
@ -3657,14 +3660,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
hir::ExprAddrOf(mutbl, ref oprnd) => {
|
||||
let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| {
|
||||
match ty.sty {
|
||||
ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
|
||||
ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => {
|
||||
if self.is_place_expr(&oprnd) {
|
||||
// Places may legitimately have unsized types.
|
||||
// For example, dereferences of a fat pointer and
|
||||
// the last field of a struct can be unsized.
|
||||
ExpectHasType(mt.ty)
|
||||
ExpectHasType(ty)
|
||||
} else {
|
||||
Expectation::rvalue_hint(self, mt.ty)
|
||||
Expectation::rvalue_hint(self, ty)
|
||||
}
|
||||
}
|
||||
_ => NoExpectation
|
||||
|
|
|
@ -197,8 +197,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
Ok(method) => {
|
||||
let by_ref_binop = !op.node.is_by_value();
|
||||
if is_assign == IsAssign::Yes || by_ref_binop {
|
||||
if let ty::TyRef(region, mt) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mt.mutbl {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[0].sty {
|
||||
let mutbl = match mutbl {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// Allow two-phase borrows for binops in initial deployment
|
||||
|
@ -214,8 +214,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
if by_ref_binop {
|
||||
if let ty::TyRef(region, mt) = method.sig.inputs()[1].sty {
|
||||
let mutbl = match mt.mutbl {
|
||||
if let ty::TyRef(region, _, mutbl) = method.sig.inputs()[1].sty {
|
||||
let mutbl = match mutbl {
|
||||
hir::MutImmutable => AutoBorrowMutability::Immutable,
|
||||
hir::MutMutable => AutoBorrowMutability::Mutable {
|
||||
// Allow two-phase borrows for binops in initial deployment
|
||||
|
@ -262,12 +262,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
op.node.as_str(),
|
||||
lhs_ty);
|
||||
|
||||
if let TypeVariants::TyRef(_, ref ty_mut) = lhs_ty.sty {
|
||||
if let TypeVariants::TyRef(_, rty, _) = lhs_ty.sty {
|
||||
if {
|
||||
!self.infcx.type_moves_by_default(self.param_env,
|
||||
ty_mut.ty,
|
||||
rty,
|
||||
lhs_expr.span) &&
|
||||
self.lookup_op_method(ty_mut.ty,
|
||||
self.lookup_op_method(rty,
|
||||
&[rhs_ty],
|
||||
Op::Binary(op, is_assign))
|
||||
.is_ok()
|
||||
|
@ -341,8 +341,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// If this function returns true it means a note was printed, so we don't need
|
||||
// to print the normal "implementation of `std::ops::Add` might be missing" note
|
||||
match (&lhs_ty.sty, &rhs_ty.sty) {
|
||||
(&TyRef(_, ref l_ty), &TyRef(_, ref r_ty))
|
||||
if l_ty.ty.sty == TyStr && r_ty.ty.sty == TyStr => {
|
||||
(&TyRef(_, l_ty, _), &TyRef(_, r_ty, _))
|
||||
if l_ty.sty == TyStr && r_ty.sty == TyStr => {
|
||||
err.span_label(expr.span,
|
||||
"`+` can't be used to concatenate two `&str` strings");
|
||||
match codemap.span_to_snippet(lhs_expr.span) {
|
||||
|
@ -353,8 +353,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
true
|
||||
}
|
||||
(&TyRef(_, ref l_ty), &TyAdt(..))
|
||||
if l_ty.ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => {
|
||||
(&TyRef(_, l_ty, _), &TyAdt(..))
|
||||
if l_ty.sty == TyStr && &format!("{:?}", rhs_ty) == "std::string::String" => {
|
||||
err.span_label(expr.span,
|
||||
"`+` can't be used to concatenate a `&str` with a `String`");
|
||||
match codemap.span_to_snippet(lhs_expr.span) {
|
||||
|
|
|
@ -588,7 +588,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
// For overloaded derefs, base_ty is the input to `Deref::deref`,
|
||||
// but it's a reference type uing the same region as the output.
|
||||
let base_ty = self.resolve_expr_type_adjusted(base);
|
||||
if let ty::TyRef(r_ptr, _) = base_ty.sty {
|
||||
if let ty::TyRef(r_ptr, _, _) = base_ty.sty {
|
||||
self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
|
||||
}
|
||||
|
||||
|
@ -701,11 +701,11 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
from_ty,
|
||||
to_ty);
|
||||
match (&from_ty.sty, &to_ty.sty) {
|
||||
/*From:*/ (&ty::TyRef(from_r, ref from_mt),
|
||||
/*To: */ &ty::TyRef(to_r, ref to_mt)) => {
|
||||
/*From:*/ (&ty::TyRef(from_r, from_ty, _),
|
||||
/*To: */ &ty::TyRef(to_r, to_ty, _)) => {
|
||||
// Target cannot outlive source, naturally.
|
||||
self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r);
|
||||
self.walk_cast(cast_expr, from_mt.ty, to_mt.ty);
|
||||
self.walk_cast(cast_expr, from_ty, to_ty);
|
||||
}
|
||||
|
||||
/*From:*/ (_,
|
||||
|
@ -913,8 +913,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
self.ty_to_string(indexed_ty));
|
||||
|
||||
let r_index_expr = ty::ReScope(region::Scope::Node(index_expr.hir_id.local_id));
|
||||
if let ty::TyRef(r_ptr, mt) = indexed_ty.sty {
|
||||
match mt.ty.sty {
|
||||
if let ty::TyRef(r_ptr, r_ty, _) = indexed_ty.sty {
|
||||
match r_ty.sty {
|
||||
ty::TySlice(_) | ty::TyStr => {
|
||||
self.sub_regions(infer::IndexSlice(index_expr.span),
|
||||
self.tcx.mk_region(r_index_expr), r_ptr);
|
||||
|
@ -1086,7 +1086,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
|||
id, mutbl, cmt_borrowed);
|
||||
|
||||
let rptr_ty = self.resolve_node_type(id);
|
||||
if let ty::TyRef(r, _) = rptr_ty.sty {
|
||||
if let ty::TyRef(r, _, _) = rptr_ty.sty {
|
||||
debug!("rptr_ty={}", rptr_ty);
|
||||
self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ use middle::expr_use_visitor as euv;
|
|||
use middle::mem_categorization as mc;
|
||||
use middle::mem_categorization::Categorization;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
use rustc::ty::{self, Ty, TyCtxt, UpvarSubsts};
|
||||
use rustc::infer::UpvarRegion;
|
||||
use syntax::ast;
|
||||
use syntax_pos::Span;
|
||||
|
@ -74,11 +74,11 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
|
|||
|
||||
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {
|
||||
match expr.node {
|
||||
hir::ExprClosure(cc, _, body_id, _, gen) => {
|
||||
hir::ExprClosure(cc, _, body_id, _, _) => {
|
||||
let body = self.fcx.tcx.hir.body(body_id);
|
||||
self.visit_body(body);
|
||||
self.fcx
|
||||
.analyze_closure(expr.id, expr.hir_id, expr.span, body, cc, gen);
|
||||
.analyze_closure(expr.id, expr.hir_id, expr.span, body, cc);
|
||||
}
|
||||
|
||||
_ => {}
|
||||
|
@ -96,7 +96,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
span: Span,
|
||||
body: &hir::Body,
|
||||
capture_clause: hir::CaptureClause,
|
||||
gen: Option<hir::GeneratorMovability>,
|
||||
) {
|
||||
/*!
|
||||
* Analysis starting point.
|
||||
|
@ -109,8 +108,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
);
|
||||
|
||||
// Extract the type of the closure.
|
||||
let (closure_def_id, closure_substs) = match self.node_ty(closure_hir_id).sty {
|
||||
ty::TyClosure(def_id, substs) | ty::TyGenerator(def_id, substs, _) => (def_id, substs),
|
||||
let (closure_def_id, substs) = match self.node_ty(closure_hir_id).sty {
|
||||
ty::TyClosure(def_id, substs) => (def_id, UpvarSubsts::Closure(substs)),
|
||||
ty::TyGenerator(def_id, substs, _) => (def_id, UpvarSubsts::Generator(substs)),
|
||||
ref t => {
|
||||
span_bug!(
|
||||
span,
|
||||
|
@ -121,10 +121,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
};
|
||||
|
||||
let infer_kind = if gen.is_some() {
|
||||
false
|
||||
let infer_kind = if let UpvarSubsts::Closure(closure_substs) = substs{
|
||||
if self.closure_kind(closure_def_id, closure_substs).is_none() {
|
||||
Some(closure_substs)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
self.closure_kind(closure_def_id, closure_substs).is_none()
|
||||
None
|
||||
};
|
||||
|
||||
self.tcx.with_freevars(closure_node_id, |freevars| {
|
||||
|
@ -172,7 +176,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
&self.tables.borrow(),
|
||||
).consume_body(body);
|
||||
|
||||
if infer_kind {
|
||||
if let Some(closure_substs) = infer_kind {
|
||||
// Unify the (as yet unbound) type variable in the closure
|
||||
// substs with the kind we inferred.
|
||||
let inferred_kind = delegate.current_closure_kind;
|
||||
|
@ -208,14 +212,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
// Equate the type variables for the upvars with the actual types.
|
||||
let final_upvar_tys = self.final_upvar_tys(closure_node_id);
|
||||
debug!(
|
||||
"analyze_closure: id={:?} closure_substs={:?} final_upvar_tys={:?}",
|
||||
"analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}",
|
||||
closure_node_id,
|
||||
closure_substs,
|
||||
substs,
|
||||
final_upvar_tys
|
||||
);
|
||||
for (upvar_ty, final_upvar_ty) in closure_substs
|
||||
.upvar_tys(closure_def_id, self.tcx)
|
||||
.zip(final_upvar_tys)
|
||||
for (upvar_ty, final_upvar_ty) in substs.upvar_tys(closure_def_id, self.tcx)
|
||||
.zip(final_upvar_tys)
|
||||
{
|
||||
self.demand_suptype(span, upvar_ty, final_upvar_ty);
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
|
||||
match tables.expr_ty_adjusted(&base).sty {
|
||||
// All valid indexing looks like this
|
||||
ty::TyRef(_, ty::TypeAndMut { ty: ref base_ty, .. }) => {
|
||||
ty::TyRef(_, base_ty, _) => {
|
||||
let index_ty = tables.expr_ty_adjusted(&index);
|
||||
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
|
||||
|
||||
|
|
|
@ -223,12 +223,18 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
|
|||
(mt_a.ty, mt_b.ty, unsize_trait, None)
|
||||
};
|
||||
let (source, target, trait_def_id, kind) = match (&source.sty, &target.sty) {
|
||||
(&ty::TyRef(r_a, mt_a), &ty::TyRef(r_b, mt_b)) => {
|
||||
(&ty::TyRef(r_a, ty_a, mutbl_a), &ty::TyRef(r_b, ty_b, mutbl_b)) => {
|
||||
infcx.sub_regions(infer::RelateObjectBound(span), r_b, r_a);
|
||||
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
||||
let mt_b = ty::TypeAndMut { ty: ty_b, mutbl: mutbl_b };
|
||||
check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ref(r_b, ty))
|
||||
}
|
||||
|
||||
(&ty::TyRef(_, mt_a), &ty::TyRawPtr(mt_b)) |
|
||||
(&ty::TyRef(_, ty_a, mutbl_a), &ty::TyRawPtr(mt_b)) => {
|
||||
let mt_a = ty::TypeAndMut { ty: ty_a, mutbl: mutbl_a };
|
||||
check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty))
|
||||
}
|
||||
|
||||
(&ty::TyRawPtr(mt_a), &ty::TyRawPtr(mt_b)) => {
|
||||
check_mutbl(mt_a, mt_b, &|ty| gcx.mk_imm_ptr(ty))
|
||||
}
|
||||
|
|
|
@ -933,38 +933,36 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
// provide junk type parameter defs - the only place that
|
||||
// cares about anything but the length is instantiation,
|
||||
// and we don't do that for closures.
|
||||
if let NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) = node {
|
||||
// add a dummy parameter for the closure kind
|
||||
types.push(ty::TypeParameterDef {
|
||||
index: type_start,
|
||||
name: Symbol::intern("<closure_kind>").as_interned_str(),
|
||||
def_id,
|
||||
has_default: false,
|
||||
object_lifetime_default: rl::Set1::Empty,
|
||||
pure_wrt_drop: false,
|
||||
synthetic: None,
|
||||
});
|
||||
if let NodeExpr(&hir::Expr { node: hir::ExprClosure(.., gen), .. }) = node {
|
||||
let dummy_args = if gen.is_some() {
|
||||
&["<yield_ty>", "<return_ty>", "<witness>"][..]
|
||||
} else {
|
||||
&["<closure_kind>", "<closure_signature>"][..]
|
||||
};
|
||||
|
||||
// add a dummy parameter for the closure signature
|
||||
types.push(ty::TypeParameterDef {
|
||||
index: type_start + 1,
|
||||
name: Symbol::intern("<closure_signature>").as_interned_str(),
|
||||
def_id,
|
||||
has_default: false,
|
||||
object_lifetime_default: rl::Set1::Empty,
|
||||
pure_wrt_drop: false,
|
||||
synthetic: None,
|
||||
});
|
||||
|
||||
tcx.with_freevars(node_id, |fv| {
|
||||
types.extend(fv.iter().zip(2..).map(|(_, i)| ty::TypeParameterDef {
|
||||
index: type_start + i,
|
||||
name: Symbol::intern("<upvar>").as_interned_str(),
|
||||
for (i, &arg) in dummy_args.iter().enumerate() {
|
||||
types.push(ty::TypeParameterDef {
|
||||
index: type_start + i as u32,
|
||||
name: Symbol::intern(arg).as_interned_str(),
|
||||
def_id,
|
||||
has_default: false,
|
||||
object_lifetime_default: rl::Set1::Empty,
|
||||
pure_wrt_drop: false,
|
||||
synthetic: None,
|
||||
});
|
||||
}
|
||||
|
||||
tcx.with_freevars(node_id, |fv| {
|
||||
types.extend(fv.iter().zip((dummy_args.len() as u32)..).map(|(_, i)| {
|
||||
ty::TypeParameterDef {
|
||||
index: type_start + i,
|
||||
name: Symbol::intern("<upvar>").as_interned_str(),
|
||||
def_id,
|
||||
has_default: false,
|
||||
object_lifetime_default: rl::Set1::Empty,
|
||||
pure_wrt_drop: false,
|
||||
synthetic: None,
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -149,8 +149,8 @@ fn insert_required_predicates_to_be_wf<'tcx>(
|
|||
// a predicate requirement of T: 'a (T outlives 'a).
|
||||
//
|
||||
// We also want to calculate potential predicates for the T
|
||||
ty::TyRef(region, mt) => {
|
||||
insert_outlives_predicate(tcx, mt.ty.into(), region, required_predicates);
|
||||
ty::TyRef(region, rty, _) => {
|
||||
insert_outlives_predicate(tcx, rty.into(), region, required_predicates);
|
||||
}
|
||||
|
||||
// For each TyAdt (struct/enum/union) type `Foo<'a, T>`, we
|
||||
|
|
|
@ -272,10 +272,10 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||
bug!("Unexpected closure type in variance computation");
|
||||
}
|
||||
|
||||
ty::TyRef(region, ref mt) => {
|
||||
ty::TyRef(region, ty, mutbl) => {
|
||||
let contra = self.contravariant(variance);
|
||||
self.add_constraints_from_region(current, region, contra);
|
||||
self.add_constraints_from_mt(current, mt, variance);
|
||||
self.add_constraints_from_mt(current, &ty::TypeAndMut { ty, mutbl }, variance);
|
||||
}
|
||||
|
||||
ty::TyArray(typ, _) |
|
||||
|
|
|
@ -1480,7 +1480,7 @@ impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
|
|||
for ty_s in trait_ref.input_types().skip(1) {
|
||||
if let ty::TyTuple(ts) = ty_s.sty {
|
||||
for &ty_s in ts {
|
||||
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
||||
if let ty::TyRef(ref reg, _, _) = ty_s.sty {
|
||||
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
||||
debug!(" hit an ReLateBound {:?}", reg);
|
||||
if let Some(lt) = reg.clean(cx) {
|
||||
|
@ -2231,8 +2231,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
|||
let self_arg_ty = *sig.input(0).skip_binder();
|
||||
if self_arg_ty == self_ty {
|
||||
decl.inputs.values[0].type_ = Generic(String::from("Self"));
|
||||
} else if let ty::TyRef(_, mt) = self_arg_ty.sty {
|
||||
if mt.ty == self_ty {
|
||||
} else if let ty::TyRef(_, ty, _) = self_arg_ty.sty {
|
||||
if ty == self_ty {
|
||||
match decl.inputs.values[0].type_ {
|
||||
BorrowedRef{ref mut type_, ..} => {
|
||||
**type_ = Generic(String::from("Self"))
|
||||
|
@ -2786,10 +2786,10 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
|
|||
Array(box ty.clean(cx), n)
|
||||
}
|
||||
ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)),
|
||||
ty::TyRef(r, mt) => BorrowedRef {
|
||||
ty::TyRef(r, ty, mutbl) => BorrowedRef {
|
||||
lifetime: r.clean(cx),
|
||||
mutability: mt.mutbl.clean(cx),
|
||||
type_: box mt.ty.clean(cx),
|
||||
mutability: mutbl.clean(cx),
|
||||
type_: box ty.clean(cx),
|
||||
},
|
||||
ty::TyFnDef(..) |
|
||||
ty::TyFnPtr(_) => {
|
||||
|
|
Loading…
Add table
Reference in a new issue