Skip to content

Commit

Permalink
auto merge of #18483 : eddyb/rust/safe-ty, r=nikomatsakis
Browse files Browse the repository at this point in the history
After more than a month of sitting on this patch, rebasing and tracking down some nasty bugs (there's might be still one out there, but it only manifested in `middle::trans::reflect` which is now gone), I'd like to merge it as it is.

This changeset makes middle::ty safe, linking the lifetime of a type to the type context it was created in.
It's a prerequisite for introducing function-local type contexts to localize types with inference variables, in order to (potentially) free hundreds of MBs from rustc's memory usage peak.
  • Loading branch information
bors committed Nov 19, 2014
2 parents e09d986 + bf0766a commit cf7df1e
Show file tree
Hide file tree
Showing 99 changed files with 5,115 additions and 4,974 deletions.
24 changes: 13 additions & 11 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ use self::MethodContext::*;

use metadata::csearch;
use middle::def::*;
use middle::ty::{mod, Ty};
use middle::typeck::astconv::ast_ty_to_ty;
use middle::typeck::infer;
use middle::{typeck, ty, def, pat_util, stability};
use middle::typeck::{mod, infer};
use middle::{def, pat_util, stability};
use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
use util::ppaux::{ty_to_string};
use util::nodemap::{FnvHashMap, NodeSet};
Expand Down Expand Up @@ -99,7 +100,7 @@ impl LintPass for UnusedCasts {
match e.node {
ast::ExprCast(ref expr, ref ty) => {
let t_t = ast_ty_to_ty(cx, &infer::new_infer_ctxt(cx.tcx), &**ty);
if ty::get(ty::expr_ty(cx.tcx, &**expr)).sty == ty::get(t_t).sty {
if ty::expr_ty(cx.tcx, &**expr) == t_t {
cx.span_lint(UNUSED_TYPECASTS, ty.span, "unnecessary type cast");
}
}
Expand Down Expand Up @@ -155,7 +156,7 @@ impl LintPass for TypeLimits {
},
_ => {
let t = ty::expr_ty(cx.tcx, &**expr);
match ty::get(t).sty {
match t.sty {
ty::ty_uint(_) => {
cx.span_lint(UNSIGNED_NEGATION, e.span,
"negation of unsigned int variable may \
Expand All @@ -180,7 +181,7 @@ impl LintPass for TypeLimits {
}

if is_shift_binop(binop) {
let opt_ty_bits = match ty::get(ty::expr_ty(cx.tcx, &**l)).sty {
let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty {
ty::ty_int(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
ty::ty_uint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
_ => None
Expand All @@ -205,7 +206,7 @@ impl LintPass for TypeLimits {
}
},
ast::ExprLit(ref lit) => {
match ty::get(ty::expr_ty(cx.tcx, e)).sty {
match ty::expr_ty(cx.tcx, e).sty {
ty::ty_int(t) => {
match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
Expand Down Expand Up @@ -343,7 +344,7 @@ impl LintPass for TypeLimits {
// Normalize the binop so that the literal is always on the RHS in
// the comparison
let norm_binop = if swap { rev_binop(binop) } else { binop };
match ty::get(ty::expr_ty(tcx, expr)).sty {
match ty::expr_ty(tcx, expr).sty {
ty::ty_int(int_ty) => {
let (min, max) = int_ty_range(int_ty);
let lit_val: i64 = match lit.node {
Expand Down Expand Up @@ -473,10 +474,11 @@ declare_lint!(BOX_POINTERS, Allow,
pub struct BoxPointers;

impl BoxPointers {
fn check_heap_type(&self, cx: &Context, span: Span, ty: ty::t) {
fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) {
let mut n_uniq = 0i;
ty::fold_ty(cx.tcx, ty, |t| {
match ty::get(t).sty {
match t.sty {
ty::ty_uniq(_) |
ty::ty_closure(box ty::ClosureTy {
store: ty::UniqTraitStore,
Expand Down Expand Up @@ -576,7 +578,7 @@ impl LintPass for RawPointerDeriving {
}
let did = match item.node {
ast::ItemImpl(..) => {
match ty::get(ty::node_id_to_type(cx.tcx, item.id)).sty {
match ty::node_id_to_type(cx.tcx, item.id).sty {
ty::ty_enum(did, _) => did,
ty::ty_struct(did, _) => did,
_ => return,
Expand Down Expand Up @@ -738,7 +740,7 @@ impl LintPass for UnusedResults {

let t = ty::expr_ty(cx.tcx, expr);
let mut warned = false;
match ty::get(t).sty {
match t.sty {
ty::ty_tup(ref tys) if tys.is_empty() => return,
ty::ty_bool => return,
ty::ty_struct(did, _) |
Expand Down
14 changes: 7 additions & 7 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use self::TargetLint::*;

use middle::privacy::ExportedItems;
use middle::subst;
use middle::ty;
use middle::ty::{mod, Ty};
use middle::typeck::astconv::AstConv;
use middle::typeck::infer;
use session::{early_error, Session};
Expand Down Expand Up @@ -546,30 +546,30 @@ impl<'a, 'tcx> Context<'a, 'tcx> {
impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> { self.tcx }

fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype {
fn get_item_ty(&self, id: ast::DefId) -> ty::Polytype<'tcx> {
ty::lookup_item_type(self.tcx, id)
}

fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef> {
fn get_trait_def(&self, id: ast::DefId) -> Rc<ty::TraitDef<'tcx>> {
ty::lookup_trait_def(self.tcx, id)
}

fn ty_infer(&self, _span: Span) -> ty::t {
fn ty_infer(&self, _span: Span) -> Ty<'tcx> {
infer::new_infer_ctxt(self.tcx).next_ty_var()
}

fn associated_types_of_trait_are_valid(&self, _: ty::t, _: ast::DefId)
fn associated_types_of_trait_are_valid(&self, _: Ty<'tcx>, _: ast::DefId)
-> bool {
// FIXME(pcwalton): This is wrong.
true
}

fn associated_type_binding(&self,
_: Span,
_: Option<ty::t>,
_: Option<Ty<'tcx>>,
trait_id: ast::DefId,
associated_type_id: ast::DefId)
-> ty::t {
-> Ty<'tcx> {
// FIXME(pcwalton): This is wrong.
let trait_def = self.get_trait_def(trait_id);
let index = ty::associated_type_parameter_index(self.tcx,
Expand Down
41 changes: 22 additions & 19 deletions src/librustc/metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId)
decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node)
}

pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
-> Vec<Rc<ty::VariantInfo>> {
pub fn get_enum_variants<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> Vec<Rc<ty::VariantInfo<'tcx>>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx)
Expand All @@ -137,8 +137,8 @@ pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId)
decoder::get_impl_items(&*cdata, impl_def_id.node)
}

pub fn get_impl_or_trait_item(tcx: &ty::ctxt, def: ast::DefId)
-> ty::ImplOrTraitItem {
pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
-> ty::ImplOrTraitItem<'tcx> {
let cdata = tcx.sess.cstore.get_crate_data(def.krate);
decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
&*cdata,
Expand Down Expand Up @@ -166,15 +166,17 @@ pub fn get_item_variances(cstore: &cstore::CStore,
decoder::get_item_variances(&*cdata, def.node)
}

pub fn get_provided_trait_methods(tcx: &ty::ctxt,
def: ast::DefId)
-> Vec<Rc<ty::Method>> {
pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> Vec<Rc<ty::Method<'tcx>>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
}

pub fn get_supertraits(tcx: &ty::ctxt, def: ast::DefId) -> Vec<Rc<ty::TraitRef>> {
pub fn get_supertraits<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> Vec<Rc<ty::TraitRef<'tcx>>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_supertraits(&*cdata, def.node, tcx)
Expand Down Expand Up @@ -213,22 +215,22 @@ pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashM
decoder::get_struct_field_attrs(&*cdata)
}

pub fn get_type(tcx: &ty::ctxt,
def: ast::DefId)
-> ty::Polytype {
pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> ty::Polytype<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_type(&*cdata, def.node, tcx)
}

pub fn get_trait_def(tcx: &ty::ctxt, def: ast::DefId) -> ty::TraitDef {
pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDef<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_trait_def(&*cdata, def.node, tcx)
}

pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,
def: ast::DefId) -> ty::Polytype {
pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId,
def: ast::DefId) -> ty::Polytype<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(class_id.krate);
let all_items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items);
Expand All @@ -255,17 +257,18 @@ pub fn get_field_type(tcx: &ty::ctxt, class_id: ast::DefId,

// Given a def_id for an impl, return the trait it implements,
// if there is one.
pub fn get_impl_trait(tcx: &ty::ctxt,
def: ast::DefId) -> Option<Rc<ty::TraitRef>> {
pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> Option<Rc<ty::TraitRef<'tcx>>> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_impl_trait(&*cdata, def.node, tcx)
}

// Given a def_id for an impl, return information about its vtables
pub fn get_impl_vtables(tcx: &ty::ctxt,
def: ast::DefId)
-> typeck::vtable_res {
pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>,
def: ast::DefId)
-> typeck::vtable_res<'tcx> {
let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate);
decoder::get_impl_vtables(&*cdata, def.node, tcx)
Expand Down
Loading

0 comments on commit cf7df1e

Please sign in to comment.