Auto merge of #32346 - nikomatsakis:no-erased-regions, r=eddyb
Remove `ErasedRegions` from substs This commit removes the `ErasedRegions` enum from `Substs`. Instead, in trans, we just generate a vector of `ReStatic` of suitable length. The goal is both general cleanup and to help pave the way for a glorious future where erasure is used in type check. r? @eddyb One concern: might be nice to do some profiling. Not sure the best way to do that. Perhaps I'll investigate running nrc's test suite locally.
This commit is contained in:
commit
d7a71687ef
@ -11,7 +11,6 @@
|
||||
// Type substitutions.
|
||||
|
||||
pub use self::ParamSpace::*;
|
||||
pub use self::RegionSubsts::*;
|
||||
|
||||
use middle::cstore;
|
||||
use middle::def_id::DefId;
|
||||
@ -34,16 +33,7 @@ use syntax::codemap::{Span, DUMMY_SP};
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Substs<'tcx> {
|
||||
pub types: VecPerParamSpace<Ty<'tcx>>,
|
||||
pub regions: RegionSubsts,
|
||||
}
|
||||
|
||||
/// Represents the values to use when substituting lifetime parameters.
|
||||
/// If the value is `ErasedRegions`, then this subst is occurring during
|
||||
/// trans, and all region parameters will be replaced with `ty::ReStatic`.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
pub enum RegionSubsts {
|
||||
ErasedRegions,
|
||||
NonerasedRegions(VecPerParamSpace<ty::Region>)
|
||||
pub regions: VecPerParamSpace<ty::Region>,
|
||||
}
|
||||
|
||||
impl<'tcx> Substs<'tcx> {
|
||||
@ -51,7 +41,7 @@ impl<'tcx> Substs<'tcx> {
|
||||
r: VecPerParamSpace<ty::Region>)
|
||||
-> Substs<'tcx>
|
||||
{
|
||||
Substs { types: t, regions: NonerasedRegions(r) }
|
||||
Substs { types: t, regions: r }
|
||||
}
|
||||
|
||||
pub fn new_type(t: Vec<Ty<'tcx>>,
|
||||
@ -71,32 +61,15 @@ impl<'tcx> Substs<'tcx> {
|
||||
VecPerParamSpace::new(r, Vec::new(), Vec::new()))
|
||||
}
|
||||
|
||||
pub fn erased(t: VecPerParamSpace<Ty<'tcx>>) -> Substs<'tcx>
|
||||
{
|
||||
Substs { types: t, regions: ErasedRegions }
|
||||
}
|
||||
|
||||
pub fn empty() -> Substs<'tcx> {
|
||||
Substs {
|
||||
types: VecPerParamSpace::empty(),
|
||||
regions: NonerasedRegions(VecPerParamSpace::empty()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_empty() -> Substs<'tcx> {
|
||||
Substs {
|
||||
types: VecPerParamSpace::empty(),
|
||||
regions: ErasedRegions
|
||||
regions: VecPerParamSpace::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_noop(&self) -> bool {
|
||||
let regions_is_noop = match self.regions {
|
||||
ErasedRegions => false, // may be used to canonicalize
|
||||
NonerasedRegions(ref regions) => regions.is_empty(),
|
||||
};
|
||||
|
||||
regions_is_noop && self.types.is_empty()
|
||||
self.regions.is_empty() && self.types.is_empty()
|
||||
}
|
||||
|
||||
pub fn type_for_def(&self, ty_param_def: &ty::TypeParameterDef) -> Ty<'tcx> {
|
||||
@ -115,26 +88,9 @@ impl<'tcx> Substs<'tcx> {
|
||||
}
|
||||
|
||||
pub fn erase_regions(self) -> Substs<'tcx> {
|
||||
let Substs { types, regions: _ } = self;
|
||||
Substs { types: types, regions: ErasedRegions }
|
||||
}
|
||||
|
||||
/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
|
||||
/// to easily access the set of region substitutions.
|
||||
pub fn regions<'a>(&'a self) -> &'a VecPerParamSpace<ty::Region> {
|
||||
match self.regions {
|
||||
ErasedRegions => panic!("Erased regions only expected in trans"),
|
||||
NonerasedRegions(ref r) => r
|
||||
}
|
||||
}
|
||||
|
||||
/// Since ErasedRegions are only to be used in trans, most of the compiler can use this method
|
||||
/// to easily access the set of region substitutions.
|
||||
pub fn mut_regions<'a>(&'a mut self) -> &'a mut VecPerParamSpace<ty::Region> {
|
||||
match self.regions {
|
||||
ErasedRegions => panic!("Erased regions only expected in trans"),
|
||||
NonerasedRegions(ref mut r) => r
|
||||
}
|
||||
let Substs { types, regions } = self;
|
||||
let regions = regions.map(|_| ty::ReStatic);
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
pub fn with_method(self,
|
||||
@ -144,7 +100,7 @@ impl<'tcx> Substs<'tcx> {
|
||||
{
|
||||
let Substs { types, regions } = self;
|
||||
let types = types.with_slice(FnSpace, &m_types);
|
||||
let regions = regions.map(|r| r.with_slice(FnSpace, &m_regions));
|
||||
let regions = regions.with_slice(FnSpace, &m_regions);
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
@ -154,27 +110,23 @@ impl<'tcx> Substs<'tcx> {
|
||||
{
|
||||
let Substs { types, regions } = self.clone();
|
||||
let types = types.with_slice(FnSpace, meth_substs.types.get_slice(FnSpace));
|
||||
let regions = regions.map(|r| {
|
||||
r.with_slice(FnSpace, meth_substs.regions().get_slice(FnSpace))
|
||||
});
|
||||
let regions = regions.with_slice(FnSpace, meth_substs.regions.get_slice(FnSpace));
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
pub fn with_method_from_subst(self, other: &Substs<'tcx>) -> Substs<'tcx> {
|
||||
let Substs { types, regions } = self;
|
||||
let types = types.with_slice(FnSpace, other.types.get_slice(FnSpace));
|
||||
let regions = regions.map(|r| {
|
||||
r.with_slice(FnSpace, other.regions().get_slice(FnSpace))
|
||||
});
|
||||
let regions = regions.with_slice(FnSpace, other.regions.get_slice(FnSpace));
|
||||
Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
/// Creates a trait-ref out of this substs, ignoring the FnSpace substs
|
||||
pub fn to_trait_ref(&self, tcx: &TyCtxt<'tcx>, trait_id: DefId)
|
||||
-> ty::TraitRef<'tcx> {
|
||||
let Substs { mut types, regions } = self.clone();
|
||||
let Substs { mut types, mut regions } = self.clone();
|
||||
types.truncate(FnSpace, 0);
|
||||
let regions = regions.map(|mut r| { r.truncate(FnSpace, 0); r });
|
||||
regions.truncate(FnSpace, 0);
|
||||
|
||||
ty::TraitRef {
|
||||
def_id: trait_id,
|
||||
@ -212,24 +164,6 @@ impl<'tcx> Decodable for &'tcx Substs<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl RegionSubsts {
|
||||
pub fn map<F>(self, op: F) -> RegionSubsts where
|
||||
F: FnOnce(VecPerParamSpace<ty::Region>) -> VecPerParamSpace<ty::Region>,
|
||||
{
|
||||
match self {
|
||||
ErasedRegions => ErasedRegions,
|
||||
NonerasedRegions(r) => NonerasedRegions(op(r))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_erased(&self) -> bool {
|
||||
match *self {
|
||||
ErasedRegions => true,
|
||||
NonerasedRegions(_) => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// ParamSpace
|
||||
|
||||
@ -664,26 +598,22 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
|
||||
// the specialized routine `ty::replace_late_regions()`.
|
||||
match r {
|
||||
ty::ReEarlyBound(data) => {
|
||||
match self.substs.regions {
|
||||
ErasedRegions => ty::ReStatic,
|
||||
NonerasedRegions(ref regions) =>
|
||||
match regions.opt_get(data.space, data.index as usize) {
|
||||
Some(&r) => {
|
||||
self.shift_region_through_binders(r)
|
||||
}
|
||||
None => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
self.tcx().sess.span_bug(
|
||||
span,
|
||||
&format!("Type parameter out of range \
|
||||
when substituting in region {} (root type={:?}) \
|
||||
(space={:?}, index={})",
|
||||
data.name,
|
||||
self.root_ty,
|
||||
data.space,
|
||||
data.index));
|
||||
}
|
||||
}
|
||||
match self.substs.regions.opt_get(data.space, data.index as usize) {
|
||||
Some(&r) => {
|
||||
self.shift_region_through_binders(r)
|
||||
}
|
||||
None => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
self.tcx().sess.span_bug(
|
||||
span,
|
||||
&format!("Region parameter out of range \
|
||||
when substituting in region {} (root type={:?}) \
|
||||
(space={:?}, index={})",
|
||||
data.name,
|
||||
self.root_ty,
|
||||
data.space,
|
||||
data.index));
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => r
|
||||
|
@ -102,14 +102,6 @@ pub fn translate_substs<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
|
||||
specialization_graph::Node::Trait(..) => source_trait_ref.substs.clone(),
|
||||
};
|
||||
|
||||
// retain erasure mode
|
||||
// NB: this must happen before inheriting method generics below
|
||||
let target_substs = if source_substs.regions.is_erased() {
|
||||
target_substs.erase_regions()
|
||||
} else {
|
||||
target_substs
|
||||
};
|
||||
|
||||
// directly inherent the method generics, since those do not vary across impls
|
||||
infcx.tcx.mk_substs(target_substs.with_method_from_subst(source_substs))
|
||||
}
|
||||
|
@ -194,13 +194,8 @@ impl FlagComputation {
|
||||
|
||||
fn add_substs(&mut self, substs: &subst::Substs) {
|
||||
self.add_tys(substs.types.as_slice());
|
||||
match substs.regions {
|
||||
subst::ErasedRegions => {}
|
||||
subst::NonerasedRegions(ref regions) => {
|
||||
for &r in regions {
|
||||
self.add_region(r);
|
||||
}
|
||||
}
|
||||
for &r in &substs.regions {
|
||||
self.add_region(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
fn fold_substs(&mut self,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> subst::Substs<'tcx> {
|
||||
subst::Substs { regions: subst::ErasedRegions,
|
||||
subst::Substs { regions: substs.regions.fold_with(self),
|
||||
types: substs.types.fold_with(self) }
|
||||
}
|
||||
}
|
||||
|
@ -2605,7 +2605,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
|
||||
Substs {
|
||||
types: types,
|
||||
regions: subst::NonerasedRegions(regions)
|
||||
regions: regions,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! type equality, etc.
|
||||
|
||||
use middle::def_id::DefId;
|
||||
use middle::subst::{ErasedRegions, NonerasedRegions, ParamSpace, Substs};
|
||||
use middle::subst::{ParamSpace, Substs};
|
||||
use middle::ty::{self, Ty, TyCtxt, TypeFoldable};
|
||||
use middle::ty::error::{ExpectedFound, TypeError};
|
||||
use std::rc::Rc;
|
||||
@ -156,23 +156,15 @@ pub fn relate_substs<'a,'tcx:'a,R>(relation: &mut R,
|
||||
substs.types.replace(space, tps);
|
||||
}
|
||||
|
||||
match (&a_subst.regions, &b_subst.regions) {
|
||||
(&ErasedRegions, _) | (_, &ErasedRegions) => {
|
||||
substs.regions = ErasedRegions;
|
||||
}
|
||||
|
||||
(&NonerasedRegions(ref a), &NonerasedRegions(ref b)) => {
|
||||
for &space in &ParamSpace::all() {
|
||||
let a_regions = a.get_slice(space);
|
||||
let b_regions = b.get_slice(space);
|
||||
let r_variances = variances.map(|v| v.regions.get_slice(space));
|
||||
let regions = relate_region_params(relation,
|
||||
r_variances,
|
||||
a_regions,
|
||||
b_regions)?;
|
||||
substs.mut_regions().replace(space, regions);
|
||||
}
|
||||
}
|
||||
for &space in &ParamSpace::all() {
|
||||
let a_regions = a_subst.regions.get_slice(space);
|
||||
let b_regions = b_subst.regions.get_slice(space);
|
||||
let r_variances = variances.map(|v| v.regions.get_slice(space));
|
||||
let regions = relate_region_params(relation,
|
||||
r_variances,
|
||||
a_regions,
|
||||
b_regions)?;
|
||||
substs.regions.replace(space, regions);
|
||||
}
|
||||
|
||||
Ok(substs)
|
||||
|
@ -487,14 +487,7 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Region {
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
let regions = match self.regions {
|
||||
subst::ErasedRegions => subst::ErasedRegions,
|
||||
subst::NonerasedRegions(ref regions) => {
|
||||
subst::NonerasedRegions(regions.fold_with(folder))
|
||||
}
|
||||
};
|
||||
|
||||
subst::Substs { regions: regions,
|
||||
subst::Substs { regions: self.regions.fold_with(folder),
|
||||
types: self.types.fold_with(folder) }
|
||||
}
|
||||
|
||||
@ -503,10 +496,7 @@ impl<'tcx> TypeFoldable<'tcx> for subst::Substs<'tcx> {
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.types.visit_with(visitor) || match self.regions {
|
||||
subst::ErasedRegions => false,
|
||||
subst::NonerasedRegions(ref regions) => regions.visit_with(visitor),
|
||||
}
|
||||
self.types.visit_with(visitor) || self.regions.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1204,18 +1204,18 @@ impl<'tcx> TyS<'tcx> {
|
||||
TyTrait(ref obj) => {
|
||||
let mut v = vec![obj.bounds.region_bound];
|
||||
v.extend_from_slice(obj.principal.skip_binder()
|
||||
.substs.regions().as_slice());
|
||||
.substs.regions.as_slice());
|
||||
v
|
||||
}
|
||||
TyEnum(_, substs) |
|
||||
TyStruct(_, substs) => {
|
||||
substs.regions().as_slice().to_vec()
|
||||
substs.regions.as_slice().to_vec()
|
||||
}
|
||||
TyClosure(_, ref substs) => {
|
||||
substs.func_substs.regions().as_slice().to_vec()
|
||||
substs.func_substs.regions.as_slice().to_vec()
|
||||
}
|
||||
TyProjection(ref data) => {
|
||||
data.trait_ref.substs.regions().as_slice().to_vec()
|
||||
data.trait_ref.substs.regions.as_slice().to_vec()
|
||||
}
|
||||
TyFnDef(..) |
|
||||
TyFnPtr(_) |
|
||||
|
@ -104,17 +104,9 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
||||
};
|
||||
|
||||
if verbose {
|
||||
match substs.regions {
|
||||
subst::ErasedRegions => {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
write!(f, "..")?;
|
||||
}
|
||||
subst::NonerasedRegions(ref regions) => {
|
||||
for region in regions {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
write!(f, "{:?}", region)?;
|
||||
}
|
||||
}
|
||||
for region in &substs.regions {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
write!(f, "{:?}", region)?;
|
||||
}
|
||||
for &ty in &substs.types {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
@ -136,23 +128,18 @@ pub fn parameterized<GG>(f: &mut fmt::Formatter,
|
||||
}
|
||||
}
|
||||
|
||||
match substs.regions {
|
||||
subst::ErasedRegions => { }
|
||||
subst::NonerasedRegions(ref regions) => {
|
||||
for &r in regions {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
let s = r.to_string();
|
||||
if s.is_empty() {
|
||||
// This happens when the value of the region
|
||||
// parameter is not easily serialized. This may be
|
||||
// because the user omitted it in the first place,
|
||||
// or because it refers to some block in the code,
|
||||
// etc. I'm not sure how best to serialize this.
|
||||
write!(f, "'_")?;
|
||||
} else {
|
||||
write!(f, "{}", s)?;
|
||||
}
|
||||
}
|
||||
for &r in &substs.regions {
|
||||
start_or_continue(f, "<", ", ")?;
|
||||
let s = r.to_string();
|
||||
if s.is_empty() {
|
||||
// This happens when the value of the region
|
||||
// parameter is not easily serialized. This may be
|
||||
// because the user omitted it in the first place,
|
||||
// or because it refers to some block in the code,
|
||||
// etc. I'm not sure how best to serialize this.
|
||||
write!(f, "'_")?;
|
||||
} else {
|
||||
write!(f, "{}", s)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,15 +380,6 @@ impl<'tcx> fmt::Debug for ty::ItemSubsts<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for subst::RegionSubsts {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
subst::ErasedRegions => write!(f, "erased"),
|
||||
subst::NonerasedRegions(ref regions) => write!(f, "{:?}", regions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::TraitRef<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
// when printing out the debug representation, we don't need
|
||||
|
@ -29,7 +29,6 @@ use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::{self, Span};
|
||||
|
||||
use rustc_front::hir;
|
||||
use rustc_front::intravisit::{self, Visitor};
|
||||
use rustc_front::util::is_shift_binop;
|
||||
|
||||
register_long_diagnostics! {
|
||||
@ -403,16 +402,6 @@ fn is_repr_nullable_ptr<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
false
|
||||
}
|
||||
|
||||
fn ast_ty_to_normalized<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
id: ast::NodeId)
|
||||
-> Ty<'tcx> {
|
||||
let tty = match tcx.ast_ty_to_ty_cache.borrow().get(&id) {
|
||||
Some(&t) => t,
|
||||
None => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
|
||||
};
|
||||
infer::normalize_associated_type(tcx, &tty)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
/// Check if the given type is "ffi-safe" (has a stable, well-defined
|
||||
/// representation which can be exported to C code).
|
||||
@ -604,10 +593,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_def(&mut self, sp: Span, id: ast::NodeId) {
|
||||
let tty = ast_ty_to_normalized(self.cx.tcx, id);
|
||||
fn check_type_for_ffi_and_report_errors(&mut self, sp: Span, ty: Ty<'tcx>) {
|
||||
// it is only OK to use this function because extern fns cannot have
|
||||
// any generic types right now:
|
||||
let ty = infer::normalize_associated_type(self.cx.tcx, &ty);
|
||||
|
||||
match ImproperCTypesVisitor::check_type_for_ffi(self, &mut FnvHashSet(), tty) {
|
||||
match self.check_type_for_ffi(&mut FnvHashSet(), ty) {
|
||||
FfiResult::FfiSafe => {}
|
||||
FfiResult::FfiUnsafe(s) => {
|
||||
self.cx.span_lint(IMPROPER_CTYPES, sp, s);
|
||||
@ -628,26 +619,29 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
|
||||
fn visit_ty(&mut self, ty: &hir::Ty) {
|
||||
match ty.node {
|
||||
hir::TyPath(..) |
|
||||
hir::TyBareFn(..) => self.check_def(ty.span, ty.id),
|
||||
hir::TyVec(..) => {
|
||||
self.cx.span_lint(IMPROPER_CTYPES, ty.span,
|
||||
"found Rust slice type in foreign module, consider \
|
||||
using a raw pointer instead");
|
||||
}
|
||||
hir::TyFixedLengthVec(ref ty, _) => self.visit_ty(ty),
|
||||
hir::TyTup(..) => {
|
||||
self.cx.span_lint(IMPROPER_CTYPES, ty.span,
|
||||
"found Rust tuple type in foreign module; \
|
||||
consider using a struct instead`")
|
||||
}
|
||||
_ => intravisit::walk_ty(self, ty)
|
||||
fn check_foreign_fn(&mut self, id: ast::NodeId, decl: &hir::FnDecl) {
|
||||
let def_id = self.cx.tcx.map.local_def_id(id);
|
||||
let scheme = self.cx.tcx.lookup_item_type(def_id);
|
||||
let sig = scheme.ty.fn_sig();
|
||||
let sig = self.cx.tcx.erase_late_bound_regions(&sig);
|
||||
|
||||
for (&input_ty, input_hir) in sig.inputs.iter().zip(&decl.inputs) {
|
||||
self.check_type_for_ffi_and_report_errors(input_hir.ty.span, &input_ty);
|
||||
}
|
||||
|
||||
if let hir::Return(ref ret_hir) = decl.output {
|
||||
let ret_ty = sig.output.unwrap();
|
||||
if !ret_ty.is_nil() {
|
||||
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_foreign_static(&mut self, id: ast::NodeId, span: Span) {
|
||||
let def_id = self.cx.tcx.map.local_def_id(id);
|
||||
let scheme = self.cx.tcx.lookup_item_type(def_id);
|
||||
self.check_type_for_ffi_and_report_errors(span, scheme.ty);
|
||||
}
|
||||
}
|
||||
|
||||
@ -662,29 +656,17 @@ impl LintPass for ImproperCTypes {
|
||||
|
||||
impl LateLintPass for ImproperCTypes {
|
||||
fn check_item(&mut self, cx: &LateContext, it: &hir::Item) {
|
||||
fn check_ty(cx: &LateContext, ty: &hir::Ty) {
|
||||
let mut vis = ImproperCTypesVisitor { cx: cx };
|
||||
vis.visit_ty(ty);
|
||||
}
|
||||
|
||||
fn check_foreign_fn(cx: &LateContext, decl: &hir::FnDecl) {
|
||||
for input in &decl.inputs {
|
||||
check_ty(cx, &input.ty);
|
||||
}
|
||||
if let hir::Return(ref ret_ty) = decl.output {
|
||||
let tty = ast_ty_to_normalized(cx.tcx, ret_ty.id);
|
||||
if !tty.is_nil() {
|
||||
check_ty(cx, &ret_ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut vis = ImproperCTypesVisitor { cx: cx };
|
||||
if let hir::ItemForeignMod(ref nmod) = it.node {
|
||||
if nmod.abi != Abi::RustIntrinsic && nmod.abi != Abi::PlatformIntrinsic {
|
||||
for ni in &nmod.items {
|
||||
match ni.node {
|
||||
hir::ForeignItemFn(ref decl, _) => check_foreign_fn(cx, &decl),
|
||||
hir::ForeignItemStatic(ref t, _) => check_ty(cx, &t)
|
||||
hir::ForeignItemFn(ref decl, _) => {
|
||||
vis.check_foreign_fn(ni.id, decl);
|
||||
}
|
||||
hir::ForeignItemStatic(ref ty, _) => {
|
||||
vis.check_foreign_static(ni.id, ty.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -144,22 +144,11 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
|
||||
}
|
||||
|
||||
pub fn parse_substs(&mut self) -> subst::Substs<'tcx> {
|
||||
let regions = self.parse_region_substs();
|
||||
let regions = self.parse_vec_per_param_space(|this| this.parse_region());
|
||||
let types = self.parse_vec_per_param_space(|this| this.parse_ty());
|
||||
subst::Substs { types: types, regions: regions }
|
||||
}
|
||||
|
||||
fn parse_region_substs(&mut self) -> subst::RegionSubsts {
|
||||
match self.next() {
|
||||
'e' => subst::ErasedRegions,
|
||||
'n' => {
|
||||
subst::NonerasedRegions(
|
||||
self.parse_vec_per_param_space(|this| this.parse_region()))
|
||||
}
|
||||
_ => panic!("parse_bound_region: bad input")
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bound_region(&mut self) -> ty::BoundRegion {
|
||||
match self.next() {
|
||||
'a' => {
|
||||
|
@ -246,24 +246,12 @@ fn enc_vec_per_param_space<'a, 'tcx, T, F>(w: &mut Cursor<Vec<u8>>,
|
||||
|
||||
pub fn enc_substs<'a, 'tcx>(w: &mut Cursor<Vec<u8>>, cx: &ctxt<'a, 'tcx>,
|
||||
substs: &subst::Substs<'tcx>) {
|
||||
enc_region_substs(w, cx, &substs.regions);
|
||||
enc_vec_per_param_space(w, cx, &substs.regions,
|
||||
|w, cx, &r| enc_region(w, cx, r));
|
||||
enc_vec_per_param_space(w, cx, &substs.types,
|
||||
|w, cx, &ty| enc_ty(w, cx, ty));
|
||||
}
|
||||
|
||||
fn enc_region_substs(w: &mut Cursor<Vec<u8>>, cx: &ctxt, substs: &subst::RegionSubsts) {
|
||||
match *substs {
|
||||
subst::ErasedRegions => {
|
||||
write!(w, "e");
|
||||
}
|
||||
subst::NonerasedRegions(ref regions) => {
|
||||
write!(w, "n");
|
||||
enc_vec_per_param_space(w, cx, regions,
|
||||
|w, cx, &r| enc_region(w, cx, r));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enc_region(w: &mut Cursor<Vec<u8>>, cx: &ctxt, r: ty::Region) {
|
||||
match r {
|
||||
ty::ReLateBound(id, br) => {
|
||||
|
@ -673,9 +673,11 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
|
||||
source_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>)
|
||||
-> CustomCoerceUnsized {
|
||||
let trait_substs = Substs::erased(subst::VecPerParamSpace::new(vec![target_ty],
|
||||
vec![source_ty],
|
||||
Vec::new()));
|
||||
let trait_substs = Substs::new(subst::VecPerParamSpace::new(vec![target_ty],
|
||||
vec![source_ty],
|
||||
Vec::new()),
|
||||
subst::VecPerParamSpace::empty());
|
||||
|
||||
let trait_ref = ty::Binder(ty::TraitRef {
|
||||
def_id: ccx.tcx().lang_items.coerce_unsized_trait().unwrap(),
|
||||
substs: ccx.tcx().mk_substs(trait_substs)
|
||||
@ -1824,10 +1826,8 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1);
|
||||
|
||||
if collector::collecting_debug_information(ccx) {
|
||||
ccx.record_translation_item_as_generated(TransItem::Fn(Instance {
|
||||
def: def_id,
|
||||
params: ¶m_substs.types
|
||||
}))
|
||||
ccx.record_translation_item_as_generated(
|
||||
TransItem::Fn(Instance::new(def_id, param_substs)));
|
||||
}
|
||||
|
||||
let _icx = push_ctxt("trans_closure");
|
||||
@ -2259,8 +2259,8 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
||||
// compilation unit that references the item, so it will still get
|
||||
// translated everywhere it's needed.
|
||||
for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) {
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let def_id = tcx.map.local_def_id(item.id);
|
||||
let empty_substs = ccx.empty_substs_for_def_id(def_id);
|
||||
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
|
||||
trans_fn(ccx, &decl, &body, llfn, empty_substs, item.id);
|
||||
set_global_section(ccx, llfn, item);
|
||||
@ -2298,8 +2298,8 @@ pub fn trans_item(ccx: &CrateContext, item: &hir::Item) {
|
||||
if sig.generics.ty_params.is_empty() {
|
||||
let trans_everywhere = attr::requests_inline(&impl_item.attrs);
|
||||
for (ref ccx, is_origin) in ccx.maybe_iter(trans_everywhere) {
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let def_id = tcx.map.local_def_id(impl_item.id);
|
||||
let empty_substs = ccx.empty_substs_for_def_id(def_id);
|
||||
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
|
||||
trans_fn(ccx, &sig.decl, body, llfn, empty_substs, impl_item.id);
|
||||
update_linkage(ccx, llfn, Some(impl_item.id),
|
||||
@ -2389,7 +2389,7 @@ pub fn create_entry_wrapper(ccx: &CrateContext, sp: Span, main_llfn: ValueRef) {
|
||||
Ok(id) => id,
|
||||
Err(s) => ccx.sess().fatal(&s)
|
||||
};
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
|
||||
let start_fn = Callee::def(ccx, start_def_id, empty_substs).reify(ccx).val;
|
||||
let args = {
|
||||
let opaque_rust_main =
|
||||
|
@ -383,7 +383,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>(
|
||||
let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty);
|
||||
|
||||
//
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let empty_substs = tcx.mk_substs(Substs::empty());
|
||||
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
||||
block_arena = TypedArena::new();
|
||||
fcx = FunctionContext::new(ccx, llfn, fn_ty, None, empty_substs, &block_arena);
|
||||
|
@ -144,10 +144,7 @@ fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
// duplicate declarations
|
||||
let tcx = ccx.tcx();
|
||||
let substs = tcx.erase_regions(substs);
|
||||
let instance = Instance {
|
||||
def: closure_id,
|
||||
params: &substs.func_substs.types
|
||||
};
|
||||
let instance = Instance::new(closure_id, &substs.func_substs);
|
||||
|
||||
if let Some(&llfn) = ccx.instances().borrow().get(&instance) {
|
||||
debug!("get_or_create_closure_declaration(): found closure {:?}: {:?}",
|
||||
|
@ -241,7 +241,7 @@ impl<'tcx> Hash for TransItem<'tcx> {
|
||||
TransItem::Fn(instance) => {
|
||||
1u8.hash(s);
|
||||
instance.def.hash(s);
|
||||
(instance.params as *const _ as usize).hash(s);
|
||||
(instance.substs as *const _ as usize).hash(s);
|
||||
}
|
||||
TransItem::Static(node_id) => {
|
||||
2u8.hash(s);
|
||||
@ -285,7 +285,6 @@ fn collect_roots<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
mode: mode,
|
||||
output: &mut roots,
|
||||
enclosing_item: None,
|
||||
trans_empty_substs: ccx.tcx().mk_substs(Substs::trans_empty()),
|
||||
};
|
||||
|
||||
ccx.tcx().map.krate().visit_all_items(&mut visitor);
|
||||
@ -331,10 +330,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
|
||||
ccx: ccx,
|
||||
mir: &mir,
|
||||
output: &mut neighbors,
|
||||
param_substs: ccx.tcx().mk_substs(Substs {
|
||||
types: instance.params.clone(),
|
||||
regions: subst::ErasedRegions
|
||||
})
|
||||
param_substs: instance.substs
|
||||
};
|
||||
|
||||
visitor.visit_mir(&mir);
|
||||
@ -437,7 +433,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
||||
let exchange_malloc_fn_trans_item =
|
||||
create_fn_trans_item(self.ccx,
|
||||
exchange_malloc_fn_def_id,
|
||||
&Substs::trans_empty(),
|
||||
&Substs::empty(),
|
||||
self.param_substs);
|
||||
|
||||
self.output.push(exchange_malloc_fn_trans_item);
|
||||
@ -569,8 +565,8 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let exchange_free_fn_trans_item =
|
||||
create_fn_trans_item(ccx,
|
||||
exchange_free_fn_def_id,
|
||||
&Substs::trans_empty(),
|
||||
&Substs::trans_empty());
|
||||
&Substs::empty(),
|
||||
&Substs::empty());
|
||||
|
||||
output.push(exchange_free_fn_trans_item);
|
||||
}
|
||||
@ -592,7 +588,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
.unwrap();
|
||||
|
||||
let self_type_substs = ccx.tcx().mk_substs(
|
||||
Substs::trans_empty().with_self_ty(ty));
|
||||
Substs::empty().with_self_ty(ty));
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
def_id: drop_trait_def_id,
|
||||
@ -608,7 +604,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
let trans_item = create_fn_trans_item(ccx,
|
||||
destructor_did,
|
||||
substs,
|
||||
&Substs::trans_empty());
|
||||
&Substs::empty());
|
||||
output.push(trans_item);
|
||||
}
|
||||
}
|
||||
@ -875,10 +871,9 @@ fn create_fn_trans_item<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
fn_substs);
|
||||
let concrete_substs = ccx.tcx().erase_regions(&concrete_substs);
|
||||
|
||||
let trans_item = TransItem::Fn(Instance {
|
||||
def: def_id,
|
||||
params: &ccx.tcx().mk_substs(concrete_substs).types,
|
||||
});
|
||||
let trans_item =
|
||||
TransItem::Fn(Instance::new(def_id,
|
||||
&ccx.tcx().mk_substs(concrete_substs)));
|
||||
|
||||
return trans_item;
|
||||
}
|
||||
@ -914,7 +909,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
Some(create_fn_trans_item(ccx,
|
||||
impl_method.method.def_id,
|
||||
&impl_method.substs,
|
||||
&Substs::trans_empty()))
|
||||
&Substs::empty()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@ -938,7 +933,6 @@ struct RootCollector<'b, 'a: 'b, 'tcx: 'a + 'b> {
|
||||
mode: TransItemCollectionMode,
|
||||
output: &'b mut Vec<TransItem<'tcx>>,
|
||||
enclosing_item: Option<&'tcx hir::Item>,
|
||||
trans_empty_substs: &'tcx Substs<'tcx>
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||
@ -962,7 +956,6 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||
if self.mode == TransItemCollectionMode::Eager {
|
||||
create_trans_items_for_default_impls(self.ccx,
|
||||
item,
|
||||
self.trans_empty_substs,
|
||||
self.output);
|
||||
}
|
||||
}
|
||||
@ -1049,7 +1042,6 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
|
||||
|
||||
fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
item: &'tcx hir::Item,
|
||||
trans_empty_substs: &'tcx Substs<'tcx>,
|
||||
output: &mut Vec<TransItem<'tcx>>) {
|
||||
match item.node {
|
||||
hir::ItemImpl(_,
|
||||
@ -1098,10 +1090,11 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
}
|
||||
|
||||
if can_have_local_instance(ccx, default_impl.def_id) {
|
||||
let empty_substs = ccx.tcx().mk_substs(ccx.tcx().erase_regions(mth.substs));
|
||||
let item = create_fn_trans_item(ccx,
|
||||
default_impl.def_id,
|
||||
callee_substs,
|
||||
trans_empty_substs);
|
||||
empty_substs);
|
||||
output.push(item);
|
||||
}
|
||||
}
|
||||
@ -1328,7 +1321,7 @@ fn push_instance_as_string<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
instance: Instance<'tcx>,
|
||||
output: &mut String) {
|
||||
push_item_name(ccx, instance.def, output);
|
||||
push_type_params(ccx, instance.params, &[], output);
|
||||
push_type_params(ccx, &instance.substs.types, &[], output);
|
||||
}
|
||||
|
||||
fn def_id_to_string(ccx: &CrateContext, def_id: DefId) -> String {
|
||||
@ -1386,7 +1379,7 @@ impl<'tcx> TransItem<'tcx> {
|
||||
TransItem::Fn(instance) => {
|
||||
format!("Fn({:?}, {})",
|
||||
instance.def,
|
||||
instance.params as *const _ as usize)
|
||||
instance.substs as *const _ as usize)
|
||||
}
|
||||
TransItem::Static(id) => {
|
||||
format!("Static({:?})", id)
|
||||
|
@ -272,7 +272,7 @@ fn get_const_val<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
param_substs: &'tcx Substs<'tcx>)
|
||||
-> Result<ValueRef, ConstEvalFailure> {
|
||||
let expr = get_const_expr(ccx, def_id, ref_expr, param_substs);
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
|
||||
match get_const_expr_as_global(ccx, expr, ConstQualif::empty(), empty_substs, TrueConst::Yes) {
|
||||
Err(Runtime(err)) => {
|
||||
ccx.tcx().sess.span_err(expr.span, &err.description());
|
||||
@ -1148,7 +1148,7 @@ pub fn trans_static(ccx: &CrateContext,
|
||||
let def_id = ccx.tcx().map.local_def_id(id);
|
||||
let datum = get_static(ccx, def_id);
|
||||
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
|
||||
let (v, _) = const_expr(
|
||||
ccx,
|
||||
expr,
|
||||
|
@ -28,7 +28,7 @@ use trans::mir::CachedMir;
|
||||
use trans::monomorphize::Instance;
|
||||
use trans::collector::{TransItem, TransItemState};
|
||||
use trans::type_::{Type, TypeNames};
|
||||
use middle::subst::Substs;
|
||||
use middle::subst::{Substs, VecPerParamSpace};
|
||||
use middle::ty::{self, Ty, TyCtxt};
|
||||
use session::config::NoDebugInfo;
|
||||
use session::Session;
|
||||
@ -551,7 +551,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
self.local
|
||||
}
|
||||
|
||||
|
||||
/// Get a (possibly) different `CrateContext` from the same
|
||||
/// `SharedCrateContext`.
|
||||
pub fn rotate(&self) -> CrateContext<'b, 'tcx> {
|
||||
@ -856,6 +855,21 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
|
||||
codegen_items.insert(cgi, TransItemState::NotPredictedButGenerated);
|
||||
}
|
||||
}
|
||||
|
||||
/// Given the def-id of some item that has no type parameters, make
|
||||
/// a suitable "empty substs" for it.
|
||||
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
|
||||
let scheme = self.tcx().lookup_item_type(item_def_id);
|
||||
self.empty_substs_for_scheme(&scheme)
|
||||
}
|
||||
|
||||
pub fn empty_substs_for_scheme(&self, scheme: &ty::TypeScheme<'tcx>)
|
||||
-> &'tcx Substs<'tcx> {
|
||||
assert!(scheme.generics.types.is_empty());
|
||||
self.tcx().mk_substs(
|
||||
Substs::new(VecPerParamSpace::empty(),
|
||||
scheme.generics.regions.map(|_| ty::ReStatic)))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TypeOfDepthLock<'a, 'tcx: 'a>(&'a LocalCrateContext<'tcx>);
|
||||
|
@ -176,7 +176,7 @@ pub fn trans_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
hir::ExprPath(..) => {
|
||||
match bcx.def(expr.id) {
|
||||
Def::Const(did) | Def::AssociatedConst(did) => {
|
||||
let empty_substs = bcx.tcx().mk_substs(Substs::trans_empty());
|
||||
let empty_substs = bcx.tcx().mk_substs(Substs::empty());
|
||||
let const_expr = consts::get_const_expr(bcx.ccx(), did, expr,
|
||||
empty_substs);
|
||||
// Temporarily get cleanup scopes out of the way,
|
||||
|
@ -267,7 +267,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let _s = StatRecorder::new(ccx, format!("drop {:?}", t));
|
||||
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
|
||||
let (arena, fcx): (TypedArena<_>, FunctionContext);
|
||||
arena = TypedArena::new();
|
||||
fcx = FunctionContext::new(ccx, llfn, fn_ty, None, empty_substs, &arena);
|
||||
@ -358,7 +358,7 @@ fn trans_struct_drop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
let trait_ref = ty::Binder(ty::TraitRef {
|
||||
def_id: tcx.lang_items.drop_trait().unwrap(),
|
||||
substs: tcx.mk_substs(Substs::trans_empty().with_self_ty(t))
|
||||
substs: tcx.mk_substs(Substs::empty().with_self_ty(t))
|
||||
});
|
||||
let vtbl = match fulfill_obligation(bcx.ccx(), DUMMY_SP, trait_ref) {
|
||||
traits::VtableImpl(data) => data,
|
||||
|
@ -70,7 +70,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
|
||||
// performance.
|
||||
AvailableExternallyLinkage
|
||||
};
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let empty_substs = tcx.mk_substs(Substs::empty());
|
||||
let def_id = tcx.map.local_def_id(item.id);
|
||||
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
|
||||
SetLinkage(llfn, linkage);
|
||||
@ -144,8 +144,8 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId) -> Option<DefId> {
|
||||
let impl_tpt = tcx.lookup_item_type(impl_did);
|
||||
if impl_tpt.generics.types.is_empty() &&
|
||||
sig.generics.ty_params.is_empty() {
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let def_id = tcx.map.local_def_id(impl_item.id);
|
||||
let empty_substs = ccx.empty_substs_for_def_id(def_id);
|
||||
let llfn = Callee::def(ccx, def_id, empty_substs).reify(ccx).val;
|
||||
trans_fn(ccx,
|
||||
&sig.decl,
|
||||
|
@ -1298,7 +1298,7 @@ fn gen_fn<'a, 'tcx>(fcx: &FunctionContext<'a, 'tcx>,
|
||||
sig: ty::Binder(sig)
|
||||
});
|
||||
let llfn = declare::define_internal_fn(ccx, name, rust_fn_ty);
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
|
||||
let empty_substs = ccx.tcx().mk_substs(Substs::empty());
|
||||
let (fcx, block_arena);
|
||||
block_arena = TypedArena::new();
|
||||
fcx = FunctionContext::new(ccx, llfn, fn_ty, None, empty_substs, &block_arena);
|
||||
|
@ -15,7 +15,7 @@ use back::link;
|
||||
use llvm::{ValueRef, get_params};
|
||||
use middle::def_id::DefId;
|
||||
use middle::infer;
|
||||
use middle::subst::{Subst, Substs};
|
||||
use middle::subst::{FnSpace, Subst, Substs};
|
||||
use middle::subst;
|
||||
use middle::traits::{self, ProjectionMode};
|
||||
use trans::abi::FnType;
|
||||
@ -92,7 +92,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>,
|
||||
let function_name = link::mangle_internal_name_by_type_and_seq(ccx, method_ty, "object_shim");
|
||||
let llfn = declare::define_internal_fn(ccx, &function_name, method_ty);
|
||||
|
||||
let empty_substs = tcx.mk_substs(Substs::trans_empty());
|
||||
let empty_substs = tcx.mk_substs(Substs::empty());
|
||||
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
|
||||
block_arena = TypedArena::new();
|
||||
fcx = FunctionContext::new(ccx, llfn, fn_ty, None, empty_substs, &block_arena);
|
||||
@ -268,9 +268,17 @@ pub fn get_vtable_methods<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
debug!("get_vtable_methods: trait_method_type={:?}",
|
||||
trait_method_type);
|
||||
|
||||
// the method may have some early-bound lifetimes, add
|
||||
// regions for those
|
||||
let num_dummy_regions = trait_method_type.generics.regions.len(FnSpace);
|
||||
let dummy_regions = vec![ty::ReStatic; num_dummy_regions];
|
||||
let method_substs = substs.clone()
|
||||
.with_method(vec![], dummy_regions);
|
||||
let method_substs = tcx.mk_substs(method_substs);
|
||||
|
||||
// The substitutions we have are on the impl, so we grab
|
||||
// the method type from the impl to substitute into.
|
||||
let mth = get_impl_method(tcx, impl_id, substs, name);
|
||||
let mth = get_impl_method(tcx, impl_id, method_substs, name);
|
||||
|
||||
debug!("get_vtable_methods: mth={:?}", mth);
|
||||
|
||||
|
@ -45,10 +45,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
let _icx = push_ctxt("monomorphic_fn");
|
||||
|
||||
let instance = Instance {
|
||||
def: fn_id,
|
||||
params: &psubsts.types
|
||||
};
|
||||
let instance = Instance::new(fn_id, psubsts);
|
||||
|
||||
let item_ty = ccx.tcx().lookup_item_type(fn_id).ty;
|
||||
|
||||
@ -179,26 +176,24 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Instance<'tcx> {
|
||||
pub def: DefId,
|
||||
pub params: &'tcx subst::VecPerParamSpace<Ty<'tcx>>
|
||||
pub substs: &'tcx Substs<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Display for Instance<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let substs = Substs {
|
||||
types: self.params.clone(),
|
||||
regions: subst::ErasedRegions
|
||||
};
|
||||
ppaux::parameterized(f, &substs, self.def, ppaux::Ns::Value, &[],
|
||||
ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[],
|
||||
|tcx| tcx.lookup_item_type(self.def).generics)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, substs: &'tcx Substs<'tcx>)
|
||||
-> Instance<'tcx> {
|
||||
assert!(substs.regions.iter().all(|&r| r == ty::ReStatic));
|
||||
Instance { def: def_id, substs: substs }
|
||||
}
|
||||
pub fn mono(tcx: &TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||
Instance {
|
||||
def: def_id,
|
||||
params: &tcx.mk_substs(Substs::trans_empty()).types
|
||||
}
|
||||
Instance::new(def_id, &tcx.mk_substs(Substs::empty()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ fn create_substs_for_ast_path<'tcx>(
|
||||
decl_generics, self_ty, types_provided,
|
||||
region_substs);
|
||||
|
||||
assert_eq!(region_substs.regions().len(TypeSpace), decl_generics.regions.len(TypeSpace));
|
||||
assert_eq!(region_substs.regions.len(TypeSpace), decl_generics.regions.len(TypeSpace));
|
||||
assert!(region_substs.types.is_empty());
|
||||
|
||||
// Convert the type parameters supplied by the user.
|
||||
|
@ -180,7 +180,7 @@ pub fn compare_impl_method<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_to_impl_substs
|
||||
.subst(tcx, impl_to_skol_substs)
|
||||
.with_method(impl_to_skol_substs.types.get_slice(subst::FnSpace).to_vec(),
|
||||
impl_to_skol_substs.regions().get_slice(subst::FnSpace).to_vec());
|
||||
impl_to_skol_substs.regions.get_slice(subst::FnSpace).to_vec());
|
||||
debug!("compare_impl_method: trait_to_skol_substs={:?}",
|
||||
trait_to_skol_substs);
|
||||
|
||||
@ -439,7 +439,7 @@ pub fn compare_const_impl<'tcx>(tcx: &TyCtxt<'tcx>,
|
||||
trait_to_impl_substs
|
||||
.subst(tcx, impl_to_skol_substs)
|
||||
.with_method(impl_to_skol_substs.types.get_slice(subst::FnSpace).to_vec(),
|
||||
impl_to_skol_substs.regions().get_slice(subst::FnSpace).to_vec());
|
||||
impl_to_skol_substs.regions.get_slice(subst::FnSpace).to_vec());
|
||||
debug!("compare_const_impl: trait_to_skol_substs={:?}",
|
||||
trait_to_skol_substs);
|
||||
|
||||
|
@ -334,7 +334,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
.generics.regions.get_slice(subst::FnSpace));
|
||||
|
||||
let subst::Substs { types, regions } = substs;
|
||||
let regions = regions.map(|r| r.with_slice(subst::FnSpace, &method_regions));
|
||||
let regions = regions.with_slice(subst::FnSpace, &method_regions);
|
||||
let mut final_substs = subst::Substs { types: types, regions: regions };
|
||||
|
||||
if num_supplied_types == 0 {
|
||||
|
@ -505,11 +505,11 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
assert_eq!(m.generics.types.get_slice(subst::TypeSpace).len(),
|
||||
trait_ref.substs.types.get_slice(subst::TypeSpace).len());
|
||||
assert_eq!(m.generics.regions.get_slice(subst::TypeSpace).len(),
|
||||
trait_ref.substs.regions().get_slice(subst::TypeSpace).len());
|
||||
trait_ref.substs.regions.get_slice(subst::TypeSpace).len());
|
||||
assert_eq!(m.generics.types.get_slice(subst::SelfSpace).len(),
|
||||
trait_ref.substs.types.get_slice(subst::SelfSpace).len());
|
||||
assert_eq!(m.generics.regions.get_slice(subst::SelfSpace).len(),
|
||||
trait_ref.substs.regions().get_slice(subst::SelfSpace).len());
|
||||
trait_ref.substs.regions.get_slice(subst::SelfSpace).len());
|
||||
}
|
||||
|
||||
// Because this trait derives from a where-clause, it
|
||||
@ -1194,7 +1194,7 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
|
||||
// method yet. So create fresh variables here for those too,
|
||||
// if there are any.
|
||||
assert_eq!(substs.types.len(subst::FnSpace), 0);
|
||||
assert_eq!(substs.regions().len(subst::FnSpace), 0);
|
||||
assert_eq!(substs.regions.len(subst::FnSpace), 0);
|
||||
|
||||
if self.mode == Mode::Path {
|
||||
return impl_ty;
|
||||
|
@ -4431,7 +4431,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
assert_eq!(substs.types.len(space), type_defs.len(space));
|
||||
|
||||
adjust_region_parameters(fcx, span, space, region_defs, &mut substs);
|
||||
assert_eq!(substs.regions().len(space), region_defs.len(space));
|
||||
assert_eq!(substs.regions.len(space), region_defs.len(space));
|
||||
}
|
||||
|
||||
// The things we are substituting into the type should not contain
|
||||
@ -4459,7 +4459,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
let impl_scheme = fcx.tcx().lookup_item_type(impl_def_id);
|
||||
assert_eq!(substs.types.len(subst::TypeSpace),
|
||||
impl_scheme.generics.types.len(subst::TypeSpace));
|
||||
assert_eq!(substs.regions().len(subst::TypeSpace),
|
||||
assert_eq!(substs.regions.len(subst::TypeSpace),
|
||||
impl_scheme.generics.regions.len(subst::TypeSpace));
|
||||
|
||||
let impl_ty = fcx.instantiate_type_scheme(span, &substs, &impl_scheme.ty);
|
||||
@ -4550,11 +4550,11 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
|
||||
{
|
||||
let region_count = region_defs.len(space);
|
||||
assert_eq!(substs.regions().len(space), 0);
|
||||
assert_eq!(substs.regions.len(space), 0);
|
||||
for (i, lifetime) in data.lifetimes.iter().enumerate() {
|
||||
let r = ast_region_to_region(fcx.tcx(), lifetime);
|
||||
if i < region_count {
|
||||
substs.mut_regions().push(space, r);
|
||||
substs.regions.push(space, r);
|
||||
} else if i == region_count {
|
||||
span_err!(fcx.tcx().sess, lifetime.span, E0088,
|
||||
"too many lifetime parameters provided: \
|
||||
@ -4563,7 +4563,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
if region_count == 1 {""} else {"s"},
|
||||
data.lifetimes.len(),
|
||||
if data.lifetimes.len() == 1 {""} else {"s"});
|
||||
substs.mut_regions().truncate(space, 0);
|
||||
substs.regions.truncate(space, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -4686,7 +4686,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
defs: &VecPerParamSpace<ty::RegionParameterDef>,
|
||||
substs: &mut Substs)
|
||||
{
|
||||
let provided_len = substs.mut_regions().len(space);
|
||||
let provided_len = substs.regions.len(space);
|
||||
let desired = defs.get_slice(space);
|
||||
|
||||
// Enforced by `push_explicit_parameters_from_segment_to_substs()`.
|
||||
@ -4694,7 +4694,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
|
||||
// If nothing was provided, just use inference variables.
|
||||
if provided_len == 0 {
|
||||
substs.mut_regions().replace(
|
||||
substs.regions.replace(
|
||||
space,
|
||||
fcx.infcx().region_vars_for_defs(span, desired));
|
||||
return;
|
||||
@ -4715,7 +4715,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
provided_len,
|
||||
if provided_len == 1 {""} else {"s"});
|
||||
|
||||
substs.mut_regions().replace(
|
||||
substs.regions.replace(
|
||||
space,
|
||||
fcx.infcx().region_vars_for_defs(span, desired));
|
||||
}
|
||||
|
@ -1496,7 +1496,7 @@ pub fn substs_wf_in_scope<'a,'tcx>(rcx: &mut Rcx<'a,'tcx>,
|
||||
|
||||
let origin = infer::ParameterInScope(origin, expr_span);
|
||||
|
||||
for ®ion in substs.regions() {
|
||||
for ®ion in &substs.regions {
|
||||
rcx.fcx.mk_subr(origin.clone(), expr_region, region);
|
||||
}
|
||||
|
||||
@ -1624,7 +1624,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
// edges, which winds up enforcing the same condition.
|
||||
let needs_infer = {
|
||||
projection_ty.trait_ref.substs.types.iter().any(|t| t.needs_infer()) ||
|
||||
projection_ty.trait_ref.substs.regions().iter().any(|r| r.needs_infer())
|
||||
projection_ty.trait_ref.substs.regions.iter().any(|r| r.needs_infer())
|
||||
};
|
||||
if env_bounds.is_empty() && needs_infer {
|
||||
debug!("projection_must_outlive: no declared bounds");
|
||||
@ -1633,7 +1633,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
type_must_outlive(rcx, origin.clone(), component_ty, region);
|
||||
}
|
||||
|
||||
for &r in projection_ty.trait_ref.substs.regions() {
|
||||
for &r in &projection_ty.trait_ref.substs.regions {
|
||||
rcx.fcx.mk_subr(origin.clone(), region, r);
|
||||
}
|
||||
|
||||
@ -1650,7 +1650,7 @@ fn projection_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
|
||||
if !env_bounds.is_empty() && env_bounds[1..].iter().all(|b| *b == env_bounds[0]) {
|
||||
let unique_bound = env_bounds[0];
|
||||
debug!("projection_must_outlive: unique declared bound = {:?}", unique_bound);
|
||||
if projection_ty.trait_ref.substs.regions()
|
||||
if projection_ty.trait_ref.substs.regions
|
||||
.iter()
|
||||
.any(|r| env_bounds.contains(r))
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ fn parameters_for_type_shallow<'tcx>(ty: Ty<'tcx>) -> Vec<Parameter> {
|
||||
}
|
||||
|
||||
fn parameters_for_regions_in_substs(substs: &subst::Substs) -> Vec<Parameter> {
|
||||
substs.regions()
|
||||
substs.regions
|
||||
.iter()
|
||||
.filter_map(|r| parameters_for_region(r))
|
||||
.collect()
|
||||
|
@ -477,7 +477,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
||||
self.declared_variance(p.def_id, def_id,
|
||||
RegionParam, p.space, p.index as usize);
|
||||
let variance_i = self.xform(variance, variance_decl);
|
||||
let substs_r = *substs.regions().get(p.space, p.index as usize);
|
||||
let substs_r = *substs.regions.get(p.space, p.index as usize);
|
||||
self.add_constraints_from_region(generics, substs_r, variance_i);
|
||||
}
|
||||
}
|
||||
|
@ -606,7 +606,7 @@ impl<'tcx> Clean<(Vec<TyParamBound>, Vec<TypeBinding>)> for ty::ExistentialBound
|
||||
|
||||
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>,
|
||||
bindings: Vec<TypeBinding>, substs: &subst::Substs) -> PathParameters {
|
||||
let lifetimes = substs.regions().get_slice(subst::TypeSpace)
|
||||
let lifetimes = substs.regions.get_slice(subst::TypeSpace)
|
||||
.iter()
|
||||
.filter_map(|v| v.clean(cx))
|
||||
.collect();
|
||||
@ -739,7 +739,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
||||
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for subst::Substs<'tcx> {
|
||||
fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
|
||||
let mut v = Vec::new();
|
||||
v.extend(self.regions().iter().filter_map(|r| r.clean(cx)).map(RegionBound));
|
||||
v.extend(self.regions.iter().filter_map(|r| r.clean(cx)).map(RegionBound));
|
||||
v.extend(self.types.iter().map(|t| TraitBound(PolyTrait {
|
||||
trait_: t.clean(cx),
|
||||
lifetimes: vec![]
|
||||
|
Loading…
x
Reference in New Issue
Block a user