use metadata::decoder;
use metadata::tyencode;
use middle::def;
-use middle::ty::lookup_item_type;
use middle::ty::{self, Ty};
use middle::stability;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
fn encode_item_variances(rbml_w: &mut Encoder,
ecx: &EncodeContext,
id: NodeId) {
- let v = ty::item_variances(ecx.tcx, ast_util::local_def(id));
+ let v = ecx.tcx.item_variances(ast_util::local_def(id));
rbml_w.start_tag(tag_item_variances);
v.encode(rbml_w);
rbml_w.end_tag();
id: ast::NodeId) {
encode_bounds_and_type(rbml_w,
ecx,
- &ty::lookup_item_type(ecx.tcx, local_def(id)),
- &ty::lookup_predicates(ecx.tcx, local_def(id)));
+ &ecx.tcx.lookup_item_type(local_def(id)),
+ &ecx.tcx.lookup_predicates(local_def(id)));
}
fn encode_bounds_and_type<'a, 'tcx>(rbml_w: &mut Encoder,
let mut disr_val = 0;
let mut i = 0;
- let vi = ty::enum_variants(ecx.tcx,
- DefId { krate: ast::LOCAL_CRATE, node: id });
+ let vi = ecx.tcx.enum_variants(local_def(id));
for variant in variants {
let def_id = local_def(variant.node.id);
index.push(entry {
match variant.node.kind {
ast::TupleVariantKind(_) => {},
ast::StructVariantKind(_) => {
- let fields = ty::lookup_struct_fields(ecx.tcx, def_id);
+ let fields = ecx.tcx.lookup_struct_fields(def_id);
let idx = encode_info_for_struct(ecx,
rbml_w,
&fields[..],
encode_index(rbml_w, idx, write_i64);
}
}
- if (*vi)[i].disr_val != disr_val {
- encode_disr_val(ecx, rbml_w, (*vi)[i].disr_val);
- disr_val = (*vi)[i].disr_val;
+ let specified_disr_val = vi[i].disr_val;
+ if specified_disr_val != disr_val {
+ encode_disr_val(ecx, rbml_w, specified_disr_val);
+ disr_val = specified_disr_val;
}
encode_bounds_and_type_for_item(rbml_w, ecx, def_id.local_id());
Some(implementations) => {
for base_impl_did in implementations.iter() {
for &method_did in impl_items.get(base_impl_did).unwrap() {
- let impl_item = ty::impl_or_trait_item(
- ecx.tcx,
- method_did.def_id());
+ let impl_item = ecx.tcx.impl_or_trait_item(method_did.def_id());
if let ty::MethodTraitItem(ref m) = impl_item {
encode_reexported_static_method(rbml_w,
exp,
if let Some(impl_item) = impl_item_opt {
if let ast::MethodImplItem(ref sig, _) = impl_item.node {
encode_attributes(rbml_w, &impl_item.attrs);
- let scheme = ty::lookup_item_type(ecx.tcx, m.def_id);
+ let scheme = ecx.tcx.lookup_item_type(m.def_id);
let any_types = !scheme.generics.types.is_empty();
let needs_inline = any_types || is_default_impl ||
attr::requests_inline(&impl_item.attrs);
encode_attributes(rbml_w, &ii.attrs);
} else {
encode_predicates(rbml_w, ecx,
- &ty::lookup_predicates(ecx.tcx, associated_type.def_id),
+ &ecx.tcx.lookup_predicates(associated_type.def_id),
tag_item_generics);
}
rbml_w: &mut Encoder,
trait_def_id: DefId) {
assert!(ast_util::is_local(trait_def_id));
- let def = ty::lookup_trait_def(ecx.tcx, trait_def_id);
+ let def = ecx.tcx.lookup_trait_def(trait_def_id);
def.for_each_impl(ecx.tcx, |impl_def_id| {
rbml_w.start_tag(tag_items_data_item_extension_impl);
index);
}
ast::ItemStruct(ref struct_def, _) => {
- let fields = ty::lookup_struct_fields(tcx, def_id);
+ let fields = tcx.lookup_struct_fields(def_id);
/* First, encode the fields
These come first because we need to write them to make
encode_name(rbml_w, item.ident.name);
encode_unsafety(rbml_w, unsafety);
- let trait_ref = ty::impl_trait_ref(tcx, local_def(item.id)).unwrap();
+ let trait_ref = tcx.impl_trait_ref(local_def(item.id)).unwrap();
encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
rbml_w.end_tag();
}
}
rbml_w.end_tag();
}
- if let Some(trait_ref) = ty::impl_trait_ref(tcx, local_def(item.id)) {
+ if let Some(trait_ref) = tcx.impl_trait_ref(local_def(item.id)) {
encode_trait_ref(rbml_w, ecx, trait_ref, tag_item_trait_ref);
}
encode_path(rbml_w, path.clone());
pos: rbml_w.mark_stable_position(),
});
- match ty::impl_or_trait_item(tcx, trait_item_def_id.def_id()) {
+ match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
ty::ConstTraitItem(ref associated_const) => {
encode_info_for_associated_const(ecx,
rbml_w,
encode_def_id(rbml_w, def_id);
encode_family(rbml_w, 'I');
encode_item_variances(rbml_w, ecx, item.id);
- let trait_def = ty::lookup_trait_def(tcx, def_id);
- let trait_predicates = ty::lookup_predicates(tcx, def_id);
+ let trait_def = tcx.lookup_trait_def(def_id);
+ let trait_predicates = tcx.lookup_predicates(def_id);
encode_unsafety(rbml_w, trait_def.unsafety);
encode_paren_sugar(rbml_w, trait_def.paren_sugar);
- encode_defaulted(rbml_w, ty::trait_has_default_impl(tcx, def_id));
+ encode_defaulted(rbml_w, tcx.trait_has_default_impl(def_id));
encode_associated_type_names(rbml_w, &trait_def.associated_type_names);
encode_generics(rbml_w, ecx, &trait_def.generics, &trait_predicates,
tag_item_generics);
- encode_predicates(rbml_w, ecx, &ty::lookup_super_predicates(tcx, def_id),
+ encode_predicates(rbml_w, ecx, &tcx.lookup_super_predicates(def_id),
tag_item_super_predicates);
encode_trait_ref(rbml_w, ecx, trait_def.trait_ref, tag_item_trait_ref);
encode_name(rbml_w, item.ident.name);
encode_attributes(rbml_w, &item.attrs);
encode_visibility(rbml_w, vis);
encode_stability(rbml_w, stab);
- for &method_def_id in ty::trait_item_def_ids(tcx, def_id).iter() {
+ for &method_def_id in tcx.trait_item_def_ids(def_id).iter() {
rbml_w.start_tag(tag_item_trait_item);
match method_def_id {
ty::ConstTraitItemId(const_def_id) => {
rbml_w.end_tag();
// Now output the trait item info for each trait item.
- let r = ty::trait_item_def_ids(tcx, def_id);
+ let r = tcx.trait_item_def_ids(def_id);
for (i, &item_def_id) in r.iter().enumerate() {
assert_eq!(item_def_id.def_id().krate, ast::LOCAL_CRATE);
encode_stability(rbml_w, stab);
let trait_item_type =
- ty::impl_or_trait_item(tcx, item_def_id.def_id());
+ tcx.impl_or_trait_item(item_def_id.def_id());
let is_nonstatic_method;
match trait_item_type {
ty::ConstTraitItem(associated_const) => {
let method_call = ty::MethodCall::expr(call_expr.id);
let fn_ty = match self.tcx.method_map.borrow().get(&method_call) {
Some(method) => method.ty,
- None => ty::expr_ty_adjusted(self.tcx, func_or_rcvr)
+ None => self.tcx.expr_ty_adjusted(func_or_rcvr)
};
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
{
let param_env = match item_id {
Some(item_id) => ty::ParameterEnvironment::for_item(self.tcx, item_id),
- None => ty::empty_parameter_environment(self.tcx)
+ None => self.tcx.empty_parameter_environment()
};
f(&mut euv::ExprUseVisitor::new(self, ¶m_env))
}
fn_like.id());
self.add_qualif(qualif);
- if ty::type_contents(self.tcx, ret_ty).interior_unsafe() {
+ if ret_ty.type_contents(self.tcx).interior_unsafe() {
self.add_qualif(ConstQualif::MUTABLE_MEM);
}
}
fn check_static_mut_type(&self, e: &ast::Expr) {
- let node_ty = ty::node_id_to_type(self.tcx, e.id);
- let tcontents = ty::type_contents(self.tcx, node_ty);
+ let node_ty = self.tcx.node_id_to_type(e.id);
+ let tcontents = node_ty.type_contents(self.tcx);
let suffix = if tcontents.has_dtor() {
"destructors"
}
fn check_static_type(&self, e: &ast::Expr) {
- let ty = ty::node_id_to_type(self.tcx, e.id);
+ let ty = self.tcx.node_id_to_type(e.id);
let infcx = infer::new_infer_ctxt(self.tcx);
let mut fulfill_cx = traits::FulfillmentContext::new(false);
let cause = traits::ObligationCause::new(e.span, e.id, traits::SharedStatic);
fulfill_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
- let env = ty::empty_parameter_environment(self.tcx);
+ let env = self.tcx.empty_parameter_environment();
match fulfill_cx.select_all_or_error(&infcx, &env) {
Ok(()) => { },
Err(ref errors) => {
let mut outer = self.qualif;
self.qualif = ConstQualif::empty();
- let node_ty = ty::node_id_to_type(self.tcx, ex.id);
+ let node_ty = self.tcx.node_id_to_type(ex.id);
check_expr(self, ex, node_ty);
// Special-case some expressions to avoid certain flags bubbling up.
// initializer values (very bad).
// If the type doesn't have interior mutability, then `ConstQualif::MUTABLE_MEM` has
// propagated from another error, so erroring again would be just noise.
- let tc = ty::type_contents(self.tcx, node_ty);
+ let tc = node_ty.type_contents(self.tcx);
if self.qualif.intersects(ConstQualif::MUTABLE_MEM) && tc.interior_unsafe() {
outer = outer | ConstQualif::NOT_CONST;
if self.mode != Mode::Var {
e: &ast::Expr, node_ty: Ty<'tcx>) {
match node_ty.sty {
ty::TyStruct(did, _) |
- ty::TyEnum(did, _) if ty::has_dtor(v.tcx, did) => {
+ ty::TyEnum(did, _) if v.tcx.has_dtor(did) => {
v.add_qualif(ConstQualif::NEEDS_DROP);
if v.mode != Mode::Var {
v.tcx.sess.span_err(e.span,
}
}
ast::ExprUnary(op, ref inner) => {
- match ty::node_id_to_type(v.tcx, inner.id).sty {
+ match v.tcx.node_id_to_type(inner.id).sty {
ty::TyRawPtr(_) => {
assert!(op == ast::UnDeref);
}
}
ast::ExprBinary(op, ref lhs, _) => {
- match ty::node_id_to_type(v.tcx, lhs.id).sty {
+ match v.tcx.node_id_to_type(lhs.id).sty {
ty::TyRawPtr(_) => {
assert!(op.node == ast::BiEq || op.node == ast::BiNe ||
op.node == ast::BiLe || op.node == ast::BiLt ||
ast::ExprClosure(..) => {
// Paths in constant contexts cannot refer to local variables,
// as there are none, and thus closures can't have upvars there.
- if ty::with_freevars(v.tcx, e.id, |fv| !fv.is_empty()) {
+ if v.tcx.with_freevars(e.id, |fv| !fv.is_empty()) {
assert!(v.mode == Mode::Var,
"global closures can't capture anything");
v.add_qualif(ConstQualif::NOT_CONST);
use middle::expr_use_visitor::{JustWrite, LoanCause, MutateMode};
use middle::expr_use_visitor::WriteAndRead;
use middle::expr_use_visitor as euv;
-use middle::mem_categorization::cmt;
+use middle::mem_categorization::{cmt, Typer};
use middle::pat_util::*;
use middle::ty::*;
use middle::ty;
pub fn check_crate(tcx: &ty::ctxt) {
visit::walk_crate(&mut MatchCheckCtxt {
tcx: tcx,
- param_env: ty::empty_parameter_environment(tcx),
+ param_env: tcx.empty_parameter_environment(),
}, tcx.map.krate());
tcx.sess.abort_if_errors();
}
// Finally, check if the whole match expression is exhaustive.
// Check for empty enum, because is_useful only works on inhabited types.
- let pat_ty = node_id_to_type(cx.tcx, scrut.id);
+ let pat_ty = cx.tcx.node_id_to_type(scrut.id);
if inlined_arms.is_empty() {
- if !type_is_empty(cx.tcx, pat_ty) {
+ if !pat_ty.is_empty(cx.tcx) {
// We know the type is inhabited, so this must be wrong
span_err!(cx.tcx.sess, ex.span, E0002,
"non-exhaustive patterns: type {} is non-empty",
ast_util::walk_pat(pat, |p| {
match p.node {
ast::PatIdent(ast::BindByValue(ast::MutImmutable), ident, None) => {
- let pat_ty = ty::pat_ty(cx.tcx, p);
+ let pat_ty = cx.tcx.pat_ty(p);
if let ty::TyEnum(def_id, _) = pat_ty.sty {
let def = cx.tcx.def_map.borrow().get(&p.id).map(|d| d.full_def());
if let Some(DefLocal(_)) = def {
- if ty::enum_variants(cx.tcx, def_id).iter().any(|variant|
+ if cx.tcx.enum_variants(def_id).iter().any(|variant|
token::get_name(variant.name) == token::get_name(ident.node.name)
&& variant.args.is_empty()
) {
ty::TyEnum(cid, _) | ty::TyStruct(cid, _) => {
let (vid, is_structure) = match ctor {
&Variant(vid) =>
- (vid, ty::enum_variant_with_id(cx.tcx, cid, vid).arg_names.is_some()),
+ (vid, cx.tcx.enum_variant_with_id(cid, vid).arg_names.is_some()),
_ =>
- (cid, !ty::is_tuple_struct(cx.tcx, cid))
+ (cid, !cx.tcx.is_tuple_struct(cid))
};
if is_structure {
- let fields = ty::lookup_struct_fields(cx.tcx, vid);
+ let fields = cx.tcx.lookup_struct_fields(vid);
let field_pats: Vec<_> = fields.into_iter()
.zip(pats)
.filter(|&(_, ref pat)| pat.node != ast::PatWild(ast::PatWildSingle))
},
ty::TyEnum(eid, _) =>
- ty::enum_variants(cx.tcx, eid)
+ cx.tcx.enum_variants(eid)
.iter()
.map(|va| Variant(va.id))
.collect(),
let left_ty = if real_pat.id == DUMMY_NODE_ID {
cx.tcx.mk_nil()
} else {
- let left_ty = ty::pat_ty(cx.tcx, &*real_pat);
+ let left_ty = cx.tcx.pat_ty(&*real_pat);
match real_pat.node {
ast::PatIdent(ast::BindByRef(..), _, _) => {
},
ty::TyEnum(eid, _) => {
match *ctor {
- Variant(id) => enum_variant_with_id(cx.tcx, eid, id).args.len(),
+ Variant(id) => cx.tcx.enum_variant_with_id(eid, id).args.len(),
_ => unreachable!()
}
}
- ty::TyStruct(cid, _) => ty::lookup_struct_fields(cx.tcx, cid).len(),
+ ty::TyStruct(cid, _) => cx.tcx.lookup_struct_fields(cid).len(),
ty::TyArray(_, n) => n,
_ => 0
}
},
_ => {
// Assume this is a struct.
- match ty::ty_to_def_id(node_id_to_type(cx.tcx, pat_id)) {
+ match cx.tcx.node_id_to_type(pat_id).ty_to_def_id() {
None => {
cx.tcx.sess.span_bug(pat_span,
"struct pattern wasn't of a \
}
};
class_id.map(|variant_id| {
- let struct_fields = ty::lookup_struct_fields(cx.tcx, variant_id);
+ let struct_fields = cx.tcx.lookup_struct_fields(variant_id);
let args = struct_fields.iter().map(|sf| {
match pattern_fields.iter().find(|f| f.node.ident.name == sf.name) {
Some(ref f) => &*f.node.pat,
if pat_is_binding(def_map, &*p) {
match p.node {
ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
- let pat_ty = ty::node_id_to_type(tcx, p.id);
- if ty::type_moves_by_default(&cx.param_env, pat.span, pat_ty) {
+ let pat_ty = tcx.node_id_to_type(p.id);
+ if cx.param_env.type_moves_by_default(pat_ty, pat.span) {
check_move(p, sub.as_ref().map(|p| &**p));
}
}
cmt: mc::cmt<'tcx>,
_: euv::ConsumeMode) {
debug!("consume; cmt: {:?}; type: {:?}", *cmt, cmt.ty);
- if !ty::type_is_sized(Some(self.param_env), self.tcx, span, cmt.ty) {
+ if !cmt.ty.is_sized(self.param_env, span) {
span_err!(self.tcx.sess, span, E0161,
"cannot move a value of type {0}: the size of {0} cannot be statically determined",
cmt.ty);
// `resolve_trait_associated_const` will select an impl
// or the default.
Some(ref_id) => {
- let trait_id = ty::trait_of_item(tcx, def_id)
+ let trait_id = tcx.trait_of_item(def_id)
.unwrap();
- let substs = ty::node_id_item_substs(tcx, ref_id)
+ let substs = tcx.node_id_item_substs(ref_id)
.substs;
resolve_trait_associated_const(tcx, ti, trait_id,
substs)
// a trait-associated const if the caller gives us
// the expression that refers to it.
Some(ref_id) => {
- let substs = ty::node_id_item_substs(tcx, ref_id)
+ let substs = tcx.node_id_item_substs(ref_id)
.substs;
resolve_trait_associated_const(tcx, ti, trait_id,
substs).map(|e| e.id)
e: &Expr,
ty_hint: Option<Ty<'tcx>>) -> EvalResult {
eval_const_expr_with_substs(tcx, e, ty_hint, |id| {
- ty::node_id_item_substs(tcx, id).substs
+ tcx.node_id_item_substs(id).substs
})
}
where S: Fn(ast::NodeId) -> subst::Substs<'tcx> {
fn fromb(b: bool) -> ConstVal { Int(b as i64) }
- let ety = ty_hint.or_else(|| ty::expr_ty_opt(tcx, e));
+ let ety = ty_hint.or_else(|| tcx.expr_ty_opt(e));
// If type of expression itself is int or uint, normalize in these
// bindings so that isize/usize is mapped to a type with an
// FIXME (#23833): the type-hint can cause problems,
// e.g. `(i8::MAX + 1_i8) as u32` feeds in `u32` as result
// type to the sum, and thus no overflow is signaled.
- let base_hint = ty::expr_ty_opt(tcx, &**base).unwrap_or(ety);
+ let base_hint = tcx.expr_ty_opt(&**base).unwrap_or(ety);
let val = try!(eval_const_expr_partial(tcx, &**base, Some(base_hint)));
match cast_const(tcx, val, ety) {
Ok(val) => val,
let trait_ref = ty::Binder(ty::TraitRef { def_id: trait_id,
substs: trait_substs });
- ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
+ tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
- let param_env = ty::empty_parameter_environment(tcx);
+ let param_env = tcx.empty_parameter_environment();
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env);
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
trait_ref.to_poly_trait_predicate());
match selection {
traits::VtableImpl(ref impl_data) => {
- match ty::associated_consts(tcx, impl_data.impl_def_id)
+ match tcx.associated_consts(impl_data.impl_def_id)
.iter().find(|ic| ic.name == ti.ident.name) {
Some(ic) => lookup_const_by_id(tcx, ic.def_id, None),
None => match ti.node {
Some(method) => {
match method.origin {
ty::MethodStatic(def_id) => {
- match ty::provided_source(self.tcx, def_id) {
+ match self.tcx.provided_source(def_id) {
Some(p_did) => self.check_def_id(p_did),
None => self.check_def_id(def_id)
}
method_num: index,
..
}) => {
- let trait_item = ty::trait_item(self.tcx,
- trait_ref.def_id,
- index);
+ let trait_item = self.tcx.trait_item(trait_ref.def_id, index);
self.check_def_id(trait_item.def_id());
}
}
}
fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
- match ty::expr_ty_adjusted(self.tcx, lhs).sty {
+ match self.tcx.expr_ty_adjusted(lhs).sty {
ty::TyStruct(id, _) => {
- let fields = ty::lookup_struct_fields(self.tcx, id);
+ let fields = self.tcx.lookup_struct_fields(id);
let field_id = fields.iter()
.find(|field| field.name == name).unwrap().id;
self.live_symbols.insert(field_id.node);
}
fn handle_tup_field_access(&mut self, lhs: &ast::Expr, idx: usize) {
- match ty::expr_ty_adjusted(self.tcx, lhs).sty {
+ match self.tcx.expr_ty_adjusted(lhs).sty {
ty::TyStruct(id, _) => {
- let fields = ty::lookup_struct_fields(self.tcx, id);
+ let fields = self.tcx.lookup_struct_fields(id);
let field_id = fields[idx].id;
self.live_symbols.insert(field_id.node);
},
let id = match self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def() {
def::DefVariant(_, id, _) => id,
_ => {
- match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
- lhs.id)) {
+ match self.tcx.node_id_to_type(lhs.id).ty_to_def_id() {
None => {
self.tcx.sess.span_bug(lhs.span,
"struct pattern wasn't of a \
}
}
};
- let fields = ty::lookup_struct_fields(self.tcx, id);
+ let fields = self.tcx.lookup_struct_fields(id);
for pat in pats {
if let ast::PatWild(ast::PatWildSingle) = pat.node.pat.node {
continue;
fn should_warn_about_field(&mut self, node: &ast::StructField_) -> bool {
let is_named = node.ident().is_some();
- let field_type = ty::node_id_to_type(self.tcx, node.id);
- let is_marker_field = match ty::ty_to_def_id(field_type) {
+ let field_type = self.tcx.node_id_to_type(node.id);
+ let is_marker_field = match field_type.ty_to_def_id() {
Some(def_id) => self.tcx.lang_items.items().any(|(_, item)| *item == Some(def_id)),
_ => false
};
fn check_str_index(&mut self, e: &ast::Expr) {
let base_type = match e.node {
- ast::ExprIndex(ref base, _) => ty::node_id_to_type(self.tcx, base.id),
+ ast::ExprIndex(ref base, _) => self.tcx.node_id_to_type(base.id),
_ => return
};
debug!("effect: checking index with base type {:?}",
}
}
ast::ExprCall(ref base, _) => {
- let base_type = ty::node_id_to_type(self.tcx, base.id);
+ let base_type = self.tcx.node_id_to_type(base.id);
debug!("effect: call case, base type is {:?}",
base_type);
if type_is_unsafe_function(base_type) {
}
}
ast::ExprUnary(ast::UnDeref, ref base) => {
- let base_type = ty::node_id_to_type(self.tcx, base.id);
+ let base_type = self.tcx.node_id_to_type(base.id);
debug!("effect: unary case, base type is {:?}",
base_type);
if let ty::TyRawPtr(_) = base_type.sty {
self.require_unsafe(expr.span, "use of inline assembly");
}
ast::ExprPath(..) => {
- if let def::DefStatic(_, true) = ty::resolve_expr(self.tcx, expr) {
+ if let def::DefStatic(_, true) = self.tcx.resolve_expr(expr) {
self.require_unsafe(expr.span, "use of mutable static");
}
}
fn from_method_id(tcx: &ty::ctxt, method_id: ast::DefId)
-> OverloadedCallType {
- let method_descriptor = match ty::impl_or_trait_item(tcx, method_id) {
+ let method_descriptor = match tcx.impl_or_trait_item(method_id) {
ty::MethodTraitItem(ref method_descriptor) => {
(*method_descriptor).clone()
}
}
ty::ImplContainer(impl_id) => impl_id,
};
- let trait_ref = match ty::impl_trait_ref(tcx, impl_id) {
+ let trait_ref = match tcx.impl_trait_ref(impl_id) {
None => {
tcx.sess.bug("statically resolved overloaded call impl \
didn't implement a trait?!")
// 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.typer.node_ty(expr.id));
- let r = ty::ty_region(self.tcx(), expr.span, expr_ty);
- let bk = ty::BorrowKind::from_mutbl(m);
- self.borrow_expr(&**base, r, bk, AddrOf);
+ if let ty::TyRef(&r, _) = expr_ty.sty {
+ let bk = ty::BorrowKind::from_mutbl(m);
+ self.borrow_expr(&**base, r, bk, AddrOf);
+ }
}
ast::ExprInlineAsm(ref ia) => {
// expression that will actually be used
let with_fields = match with_cmt.ty.sty {
ty::TyStruct(did, substs) => {
- ty::struct_fields(self.tcx(), did, substs)
+ self.tcx().struct_fields(did, substs)
}
_ => {
// the base expression should always evaluate to a
// the method call infrastructure should have
// replaced all late-bound regions with variables:
let self_ty = method_ty.fn_sig().input(0);
- let self_ty = ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap();
+ let self_ty = self.tcx().no_late_bound_regions(&self_ty).unwrap();
let (m, r) = match self_ty.sty {
ty::TyRef(r, ref m) => (m.mutbl, r),
// This is always an rvalue, since we are producing a new
// (temporary) indirection.
- let adj_ty =
- ty::adjust_ty_for_autoref(self.tcx(),
- cmt_base_ty,
- opt_autoref);
+ let adj_ty = cmt_base_ty.adjust_for_autoref(self.tcx(), opt_autoref);
self.mc.cat_rvalue_node(expr.id, expr.span, adj_ty)
}
// It is also a borrow or copy/move of the value being matched.
match pat.node {
ast::PatIdent(ast::BindByRef(m), _, _) => {
- let (r, bk) = {
- (ty::ty_region(tcx, pat.span, pat_ty),
- ty::BorrowKind::from_mutbl(m))
- };
- delegate.borrow(pat.id, pat.span, cmt_pat,
- r, bk, RefBinding);
+ 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);
+ }
}
ast::PatIdent(ast::BindByValue(_), _, _) => {
let mode = copy_or_move(typer, &cmt_pat, PatBindingMove);
Some(def::DefVariant(enum_did, variant_did, _is_struct)) => {
let downcast_cmt =
- if ty::enum_is_univariant(tcx, enum_did) {
+ if tcx.enum_is_univariant(enum_did) {
cmt_pat
} else {
let cmt_pat_ty = cmt_pat.ty;
fn walk_captures(&mut self, closure_expr: &ast::Expr) {
debug!("walk_captures({:?})", closure_expr);
- ty::with_freevars(self.tcx(), closure_expr.id, |freevars| {
+ self.tcx().with_freevars(closure_expr.id, |freevars| {
for freevar in freevars {
let id_var = freevar.def.def_id().node;
let upvar_id = ty::UpvarId { var_id: id_var,
move_reason: MoveReason)
-> ConsumeMode
{
- if typer.type_moves_by_default(cmt.span, cmt.ty) {
+ if typer.type_moves_by_default(cmt.ty, cmt.span) {
Move(move_reason)
} else {
Copy
ty::TyEnum(def_id, substs) |
ty::TyStruct(def_id, substs) => {
- let item_scheme = ty::lookup_item_type(self.tcx(), def_id);
+ let item_scheme = self.tcx().lookup_item_type(def_id);
self.accumulate_from_adt(ty, def_id, &item_scheme.generics, substs)
}
substs: &Substs<'tcx>)
{
let predicates =
- ty::lookup_predicates(self.tcx(), def_id).instantiate(self.tcx(), substs);
+ self.tcx().lookup_predicates(def_id).instantiate(self.tcx(), substs);
let predicates = match self.fully_normalize(&predicates) {
Ok(predicates) => predicates,
Err(ErrorReported) => { return; }
ty::Predicate::Equate(..) => { }
ty::Predicate::Projection(..) => { }
ty::Predicate::RegionOutlives(ref data) => {
- match ty::no_late_bound_regions(self.tcx(), data) {
+ match self.tcx().no_late_bound_regions(data) {
None => { }
Some(ty::OutlivesPredicate(r_a, r_b)) => {
self.push_sub_region_constraint(Some(ty), r_b, r_a);
}
}
ty::Predicate::TypeOutlives(ref data) => {
- match ty::no_late_bound_regions(self.tcx(), data) {
+ match self.tcx().no_late_bound_regions(data) {
None => { }
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
self.stack.push((r_b, Some(ty)));
.map(|pred| Implication::Predicate(def_id, pred));
self.out.extend(obligations);
- let variances = ty::item_variances(self.tcx(), def_id);
+ let variances = self.tcx().item_variances(def_id);
for (®ion, &variance) in substs.regions().iter().zip(&variances.regions) {
match variance {
data);
for poly_trait_ref in traits::supertraits(self.tcx(), data.to_poly_trait_ref()) {
- match ty::no_late_bound_regions(self.tcx(), &poly_trait_ref) {
+ match self.tcx().no_late_bound_regions(&poly_trait_ref) {
Some(trait_ref) => { self.accumulate_from_assoc_types(trait_ref); }
None => { }
}
trait_ref);
let trait_def_id = trait_ref.def_id;
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_def_id);
let assoc_type_projections: Vec<_> =
trait_def.associated_type_names
.iter()
let mut predicates = others.to_predicates(tcx, open_ty);
predicates.extend(trait_refs.iter().map(|t| t.to_predicate()));
- ty::required_region_bounds(tcx, open_ty, predicates)
+ tcx.required_region_bounds(open_ty, predicates)
}
-> RelateResult<'tcx, ty::Binder<T>>
where T: Relate<'a,'tcx>
{
- let a1 = ty::erase_late_bound_regions(self.tcx(), a);
- let b1 = ty::erase_late_bound_regions(self.tcx(), b);
+ let a1 = self.tcx().erase_late_bound_regions(a);
+ let b1 = self.tcx().erase_late_bound_regions(b);
let c = try!(self.relate(&a1, &b1));
Ok(ty::Binder(c))
}
use syntax::print::pprust;
use syntax::ptr::P;
-pub fn note_and_explain_region(tcx: &ty::ctxt,
- prefix: &str,
- region: ty::Region,
- suffix: &str) {
- fn item_scope_tag(item: &ast::Item) -> &'static str {
- match item.node {
- ast::ItemImpl(..) => "impl",
- ast::ItemStruct(..) => "struct",
- ast::ItemEnum(..) => "enum",
- ast::ItemTrait(..) => "trait",
- ast::ItemFn(..) => "function body",
- _ => "item"
+impl<'tcx> ty::ctxt<'tcx> {
+ pub fn note_and_explain_region(&self,
+ prefix: &str,
+ region: ty::Region,
+ suffix: &str) {
+ fn item_scope_tag(item: &ast::Item) -> &'static str {
+ match item.node {
+ ast::ItemImpl(..) => "impl",
+ ast::ItemStruct(..) => "struct",
+ ast::ItemEnum(..) => "enum",
+ ast::ItemTrait(..) => "trait",
+ ast::ItemFn(..) => "function body",
+ _ => "item"
+ }
}
- }
-
- fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
- -> (String, Option<Span>) {
- let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
- (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
- Some(span))
- }
- let (description, span) = match region {
- ty::ReScope(scope) => {
- let new_string;
- let unknown_scope = || {
- format!("{}unknown scope: {:?}{}. Please report a bug.",
- prefix, scope, suffix)
- };
- let span = match scope.span(&tcx.map) {
- Some(s) => s,
- None => return tcx.sess.note(&unknown_scope())
- };
- let tag = match tcx.map.find(scope.node_id()) {
- Some(ast_map::NodeBlock(_)) => "block",
- Some(ast_map::NodeExpr(expr)) => match expr.node {
- ast::ExprCall(..) => "call",
- ast::ExprMethodCall(..) => "method call",
- ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
- ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
- ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
- ast::ExprMatch(..) => "match",
- _ => "expression",
- },
- Some(ast_map::NodeStmt(_)) => "statement",
- Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
- Some(_) | None => {
- return tcx.sess.span_note(span, &unknown_scope());
- }
- };
- let scope_decorated_tag = match scope {
- region::CodeExtent::Misc(_) => tag,
- region::CodeExtent::ParameterScope { .. } => {
- "scope of parameters for function"
- }
- region::CodeExtent::DestructionScope(_) => {
- new_string = format!("destruction scope surrounding {}", tag);
- &new_string[..]
- }
- region::CodeExtent::Remainder(r) => {
- new_string = format!("block suffix following statement {}",
- r.first_statement_index);
- &new_string[..]
- }
- };
- explain_span(tcx, scope_decorated_tag, span)
+ fn explain_span(tcx: &ty::ctxt, heading: &str, span: Span)
+ -> (String, Option<Span>) {
+ let lo = tcx.sess.codemap().lookup_char_pos_adj(span.lo);
+ (format!("the {} at {}:{}", heading, lo.line, lo.col.to_usize()),
+ Some(span))
}
- ty::ReFree(ref fr) => {
- let prefix = match fr.bound_region {
- ty::BrAnon(idx) => {
- format!("the anonymous lifetime #{} defined on", idx + 1)
- }
- ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
- _ => {
- format!("the lifetime {} as defined on",
- fr.bound_region)
- }
- };
+ let (description, span) = match region {
+ ty::ReScope(scope) => {
+ let new_string;
+ let unknown_scope = || {
+ format!("{}unknown scope: {:?}{}. Please report a bug.",
+ prefix, scope, suffix)
+ };
+ let span = match scope.span(&self.map) {
+ Some(s) => s,
+ None => return self.sess.note(&unknown_scope())
+ };
+ let tag = match self.map.find(scope.node_id()) {
+ Some(ast_map::NodeBlock(_)) => "block",
+ Some(ast_map::NodeExpr(expr)) => match expr.node {
+ ast::ExprCall(..) => "call",
+ ast::ExprMethodCall(..) => "method call",
+ ast::ExprMatch(_, _, ast::MatchSource::IfLetDesugar { .. }) => "if let",
+ ast::ExprMatch(_, _, ast::MatchSource::WhileLetDesugar) => "while let",
+ ast::ExprMatch(_, _, ast::MatchSource::ForLoopDesugar) => "for",
+ ast::ExprMatch(..) => "match",
+ _ => "expression",
+ },
+ Some(ast_map::NodeStmt(_)) => "statement",
+ Some(ast_map::NodeItem(it)) => item_scope_tag(&*it),
+ Some(_) | None => {
+ return self.sess.span_note(span, &unknown_scope());
+ }
+ };
+ let scope_decorated_tag = match scope {
+ region::CodeExtent::Misc(_) => tag,
+ region::CodeExtent::ParameterScope { .. } => {
+ "scope of parameters for function"
+ }
+ region::CodeExtent::DestructionScope(_) => {
+ new_string = format!("destruction scope surrounding {}", tag);
+ &new_string[..]
+ }
+ region::CodeExtent::Remainder(r) => {
+ new_string = format!("block suffix following statement {}",
+ r.first_statement_index);
+ &new_string[..]
+ }
+ };
+ explain_span(self, scope_decorated_tag, span)
+ }
- match tcx.map.find(fr.scope.node_id) {
- Some(ast_map::NodeBlock(ref blk)) => {
- let (msg, opt_span) = explain_span(tcx, "block", blk.span);
- (format!("{} {}", prefix, msg), opt_span)
- }
- Some(ast_map::NodeItem(it)) => {
- let tag = item_scope_tag(&*it);
- let (msg, opt_span) = explain_span(tcx, tag, it.span);
- (format!("{} {}", prefix, msg), opt_span)
- }
- Some(_) | None => {
- // this really should not happen
- (format!("{} unknown free region bounded by scope {:?}",
- prefix, fr.scope), None)
+ ty::ReFree(ref fr) => {
+ let prefix = match fr.bound_region {
+ ty::BrAnon(idx) => {
+ format!("the anonymous lifetime #{} defined on", idx + 1)
+ }
+ ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
+ _ => {
+ format!("the lifetime {} as defined on",
+ fr.bound_region)
+ }
+ };
+
+ match self.map.find(fr.scope.node_id) {
+ Some(ast_map::NodeBlock(ref blk)) => {
+ let (msg, opt_span) = explain_span(self, "block", blk.span);
+ (format!("{} {}", prefix, msg), opt_span)
+ }
+ Some(ast_map::NodeItem(it)) => {
+ let tag = item_scope_tag(&*it);
+ let (msg, opt_span) = explain_span(self, tag, it.span);
+ (format!("{} {}", prefix, msg), opt_span)
+ }
+ Some(_) | None => {
+ // this really should not happen
+ (format!("{} unknown free region bounded by scope {:?}",
+ prefix, fr.scope), None)
+ }
}
}
- }
- ty::ReStatic => ("the static lifetime".to_owned(), None),
+ ty::ReStatic => ("the static lifetime".to_owned(), None),
- ty::ReEmpty => ("the empty lifetime".to_owned(), None),
+ ty::ReEmpty => ("the empty lifetime".to_owned(), None),
- ty::ReEarlyBound(ref data) => {
- (format!("{}", token::get_name(data.name)), None)
- }
+ ty::ReEarlyBound(ref data) => {
+ (format!("{}", token::get_name(data.name)), None)
+ }
- // I believe these cases should not occur (except when debugging,
- // perhaps)
- ty::ReInfer(_) | ty::ReLateBound(..) => {
- (format!("lifetime {:?}", region), None)
+ // I believe these cases should not occur (except when debugging,
+ // perhaps)
+ ty::ReInfer(_) | ty::ReLateBound(..) => {
+ (format!("lifetime {:?}", region), None)
+ }
+ };
+ let message = format!("{}{}{}", prefix, description, suffix);
+ if let Some(span) = span {
+ self.sess.span_note(span, &message);
+ } else {
+ self.sess.note(&message);
}
- };
- let message = format!("{}{}{}", prefix, description, suffix);
- if let Some(span) = span {
- tcx.sess.span_note(span, &message);
- } else {
- tcx.sess.note(&message);
}
}
terr: &ty::type_err<'tcx>) {
let span = trace.origin.span();
self.report_type_error(trace, terr);
- ty::note_and_explain_type_err(self.tcx, terr, span);
+ self.tcx.note_and_explain_type_err(terr, span);
}
/// Returns a string of the form "expected `{}`, found `{}`", or None if this is a derived
&format!(
"consider adding an explicit lifetime bound for `{}`",
bound_kind));
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
&format!("{} must be valid for ", labeled_user_string),
sub,
"...");
span_err!(self.tcx.sess, span, E0312,
"lifetime of reference outlines \
lifetime of borrowed content...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"...the reference is valid for ",
sub,
"...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"...but the borrowed content is only valid for ",
sup,
"");
span_err!(self.tcx.sess, span, E0313,
"lifetime of borrowed pointer outlives \
lifetime of captured variable `{}`...",
- ty::local_var_name_str(self.tcx,
- upvar_id.var_id)
- .to_string());
- note_and_explain_region(
- self.tcx,
+ self.tcx.local_var_name_str(upvar_id.var_id));
+ self.tcx.note_and_explain_region(
"...the borrowed pointer is valid for ",
sub,
"...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
&format!("...but `{}` is only valid for ",
- ty::local_var_name_str(self.tcx,
- upvar_id.var_id)
- .to_string()),
+ self.tcx.local_var_name_str(upvar_id.var_id)),
sup,
"");
}
infer::InfStackClosure(span) => {
span_err!(self.tcx.sess, span, E0314,
"closure outlives stack frame");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"...the closure must be valid for ",
sub,
"...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"...but the closure's stack frame is only valid for ",
sup,
"");
infer::InvokeClosure(span) => {
span_err!(self.tcx.sess, span, E0315,
"cannot invoke closure outside of its lifetime");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the closure is only valid for ",
sup,
"");
self.tcx.sess.span_err(
span,
"dereference of reference outside its lifetime");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the reference is only valid for ",
sup,
"");
self.tcx.sess.span_err(
span,
&format!("captured variable `{}` does not \
- outlive the enclosing closure",
- ty::local_var_name_str(self.tcx,
- id).to_string()));
- note_and_explain_region(
- self.tcx,
+ outlive the enclosing closure",
+ self.tcx.local_var_name_str(id)));
+ self.tcx.note_and_explain_region(
"captured variable is valid for ",
sup,
"");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"closure is valid for ",
sub,
"");
infer::IndexSlice(span) => {
self.tcx.sess.span_err(span,
"index of slice outside its lifetime");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the slice is only valid for ",
sup,
"");
span,
"lifetime of the source pointer does not outlive \
lifetime bound of the object type");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"object type is valid for ",
sub,
"");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"source pointer is only valid for ",
sup,
"");
&format!("the type `{}` does not fulfill the \
required lifetime",
self.ty_to_string(ty)));
- note_and_explain_region(self.tcx,
+ self.tcx.note_and_explain_region(
"type must outlive ",
sub,
"");
self.tcx.sess.span_err(
span,
"lifetime bound not satisfied");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"lifetime parameter instantiated with ",
sup,
"");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"but lifetime parameter must outlive ",
sub,
"");
&format!("the type `{}` (provided as the value of \
a type parameter) is not valid at this point",
self.ty_to_string(ty)));
- note_and_explain_region(self.tcx,
+ self.tcx.note_and_explain_region(
"type must outlive ",
sub,
"");
span,
"lifetime of method receiver does not outlive \
the method call");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the receiver is only valid for ",
sup,
"");
span,
"lifetime of function argument does not outlive \
the function call");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the function argument is only valid for ",
sup,
"");
span,
"lifetime of return value does not outlive \
the function call");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the return value is only valid for ",
sup,
"");
span,
"lifetime of operand does not outlive \
the operation");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the operand is only valid for ",
sup,
"");
span,
"reference is not valid \
at the time of borrow");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the borrow is only valid for ",
sup,
"");
span,
"automatically reference is not valid \
at the time of borrow");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the automatic borrow is only valid for ",
sup,
"");
&format!("type of expression contains references \
that are not valid during the expression: `{}`",
self.ty_to_string(t)));
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"type is only valid for ",
sup,
"");
"unsafe use of destructor: destructor might be called \
while references are dead");
// FIXME (22171): terms "super/subregion" are suboptimal
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"superregion: ",
sup,
"");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"subregion: ",
sub,
"");
self.tcx.sess.span_err(
span,
"lifetime of variable does not enclose its declaration");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the variable is only valid for ",
sup,
"");
&format!("in type `{}`, reference has a longer lifetime \
than the data it references",
self.ty_to_string(ty)));
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"the pointer is valid for ",
sub,
"");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"but the referenced data is only valid for ",
sup,
"");
sup_region: Region) {
self.report_inference_failure(var_origin);
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"first, the lifetime cannot outlive ",
sup_region,
"...");
self.note_region_origin(&sup_origin);
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"but, the lifetime must be valid for ",
sub_region,
"...");
region2: Region) {
self.report_inference_failure(var_origin);
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"first, the lifetime must be contained by ",
region1,
"...");
self.note_region_origin(&origin1);
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"but, the lifetime must also be contained by ",
region2,
"...");
};
match a_def {
def::DefTy(did, _) | def::DefStruct(did) => {
- let generics = ty::lookup_item_type(self.tcx, did).generics;
+ let generics = self.tcx.lookup_item_type(did).generics;
let expected =
generics.regions.len(subst::TypeSpace) as u32;
}
infer::UpvarRegion(ref upvar_id, _) => {
format!(" for capture of `{}` by closure",
- ty::local_var_name_str(self.tcx, upvar_id.var_id).to_string())
+ self.tcx.local_var_name_str(upvar_id.var_id).to_string())
}
};
span,
&format!(
"...so that closure can access `{}`",
- ty::local_var_name_str(self.tcx, upvar_id.var_id)
+ self.tcx.local_var_name_str(upvar_id.var_id)
.to_string()))
}
infer::InfStackClosure(span) => {
span,
&format!("...so that captured variable `{}` \
does not outlive the enclosing closure",
- ty::local_var_name_str(
- self.tcx,
- id).to_string()));
+ self.tcx.local_var_name_str(id)));
}
infer::IndexSlice(span) => {
self.tcx.sess.span_note(
error_str));
if let Some(err) = err {
- ty::note_and_explain_type_err(self.tcx, err, sp)
+ self.tcx.note_and_explain_type_err(err, sp)
}
}
}
impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
fn def_id_is_transmute(&self, def_id: DefId) -> bool {
- let intrinsic = match ty::lookup_item_type(self.tcx, def_id).ty.sty {
+ let intrinsic = match self.tcx.lookup_item_type(def_id).ty.sty {
ty::TyBareFn(_, ref bfty) => bfty.abi == RustIntrinsic,
_ => return false
};
// In all cases, we keep the original unsubstituted types
// around for error reporting.
- let from_tc = ty::type_contents(self.tcx, from);
- let to_tc = ty::type_contents(self.tcx, to);
+ let from_tc = from.type_contents(self.tcx);
+ let to_tc = to.type_contents(self.tcx);
if from_tc.interior_param() || to_tc.interior_param() {
span_err!(self.tcx.sess, span, E0139,
"cannot transmute to or from a type that contains \
debug!("with_each_combination: space={:?}, index={}, param_ty={:?}",
space, index, param_ty);
- if !ty::type_is_sized(Some(param_env), self.tcx, span, param_ty) {
+ if !param_ty.is_sized(param_env, span) {
debug!("with_each_combination: param_ty is not known to be sized");
substs.types.get_mut_slice(space)[index] = self.dummy_unsized_ty;
fn visit_expr(&mut self, expr: &ast::Expr) {
if let ast::ExprPath(..) = expr.node {
- match ty::resolve_expr(self.tcx, expr) {
+ match self.tcx.resolve_expr(expr) {
DefFn(did, _) if self.def_id_is_transmute(did) => {
- let typ = ty::node_id_to_type(self.tcx, expr.id);
+ let typ = self.tcx.node_id_to_type(expr.id);
match typ.sty {
TyBareFn(_, ref bare_fn_ty) if bare_fn_ty.abi == RustIntrinsic => {
if let ty::FnConverging(to) = bare_fn_ty.sig.0.output {
// in better error messages than just pointing at the closure
// construction site.
let mut call_caps = Vec::new();
- ty::with_freevars(ir.tcx, expr.id, |freevars| {
+ ir.tcx.with_freevars(expr.id, |freevars| {
for fv in freevars {
if let DefLocal(rv) = fv.def {
let fv_ln = ir.add_live_node(FreeVarNode(fv.span));
ast::ExprCall(ref f, ref args) => {
let diverges = !self.ir.tcx.is_method_call(expr.id) &&
- ty::expr_ty_adjusted(self.ir.tcx, &**f).fn_ret().diverges();
+ self.ir.tcx.expr_ty_adjusted(&**f).fn_ret().diverges();
let succ = if diverges {
self.s.exit_ln
} else {
impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn fn_ret(&self, id: NodeId) -> ty::PolyFnOutput<'tcx> {
- let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
+ let fn_ty = self.ir.tcx.node_id_to_type(id);
match fn_ty.sty {
ty::TyClosure(closure_def_id, substs) =>
self.ir.tcx.closure_type(closure_def_id, substs).sig.output(),
{
// within the fn body, late-bound regions are liberated:
let fn_ret =
- ty::liberate_late_bound_regions(
- self.ir.tcx,
+ self.ir.tcx.liberate_late_bound_regions(
region::DestructionScopeData::new(body.id),
&self.fn_ret(id));
None if !body.stmts.is_empty() =>
match body.stmts.first().unwrap().node {
ast::StmtSemi(ref e, _) => {
- ty::expr_ty(self.ir.tcx, &**e) == t_ret
+ self.ir.tcx.expr_ty(&**e) == t_ret
},
_ => false
},
pub trait Typer<'tcx> : ty::ClosureTyper<'tcx> {
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>>;
- fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool;
+ fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool;
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>>;
fn node_method_origin(&self, method_call: ty::MethodCall)
-> Option<ty::MethodOrigin<'tcx>>;
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> McResult<Ty<'tcx>> {
let unadjusted_ty = try!(self.expr_ty(expr));
- Ok(ty::adjust_ty(self.tcx(), expr.span, expr.id, unadjusted_ty,
- self.typer.adjustments().borrow().get(&expr.id),
- |method_call| self.typer.node_method_ty(method_call)))
+ Ok(unadjusted_ty.adjust(
+ self.tcx(), expr.span, expr.id,
+ self.typer.adjustments().borrow().get(&expr.id),
+ |method_call| self.typer.node_method_ty(method_call)))
}
fn node_ty(&self, id: ast::NodeId) -> McResult<Ty<'tcx>> {
let base_cmt = match method_ty {
Some(method_ty) => {
let ref_ty =
- ty::no_late_bound_regions(
- self.tcx(), &method_ty.fn_ret()).unwrap().unwrap();
+ self.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap();
self.cat_rvalue_node(node.id(), node.span(), ref_ty)
}
None => base_cmt
// FIXME(#20649) -- why are we using the `self_ty` as the element type...?
let self_ty = method_ty.fn_sig().input(0);
- ty::no_late_bound_regions(self.tcx(), &self_ty).unwrap()
+ self.tcx().no_late_bound_regions(&self_ty).unwrap()
}
None => {
match base_cmt.ty.builtin_index() {
let cmt = match opt_def {
Some(def::DefVariant(enum_did, variant_did, _))
// univariant enums do not need downcasts
- if !ty::enum_is_univariant(self.tcx(), enum_did) => {
+ if !self.tcx().enum_is_univariant(enum_did) => {
self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did)
}
_ => cmt
// types are generated by method resolution and always have
// all late-bound regions fully instantiated, so we just want
// to skip past the binder.
- ty::no_late_bound_regions(self.tcx(), &method_ty.fn_ret())
+ self.tcx().no_late_bound_regions(&method_ty.fn_ret())
.unwrap()
.unwrap() // overloaded ops do not diverge, either
}
cat_static_item => write!(f, "static"),
cat_rvalue(r) => write!(f, "rvalue({:?})", r),
cat_local(id) => {
- let name = ty::tls::with(|tcx| ty::local_var_name_str(tcx, id));
+ let name = ty::tls::with(|tcx| tcx.local_var_name_str(id));
write!(f, "local({})", name)
}
cat_upvar(upvar) => {
}
pub fn def_to_path(tcx: &ty::ctxt, id: ast::DefId) -> ast::Path {
- ty::with_path(tcx, id, |path| ast::Path {
+ tcx.with_path(id, |path| ast::Path {
global: false,
segments: path.last().map(|elem| ast::PathSegment {
identifier: ast::Ident::new(elem.name()),
// items.
ast::ItemImpl(_, _, _, Some(ref t), _, ref impl_items) => {
let trait_did = tcx.def_map.borrow().get(&t.ref_id).unwrap().def_id();
- let trait_items = ty::trait_items(tcx, trait_did);
+ let trait_items = tcx.trait_items(trait_did);
for impl_item in impl_items {
let item = trait_items.iter().find(|item| {
method_num: index,
..
}) => {
- ty::trait_item(tcx, trait_ref.def_id, index).def_id()
+ tcx.trait_item(trait_ref.def_id, index).def_id()
}
}
}
}
ast::ExprField(ref base_e, ref field) => {
span = field.span;
- match ty::expr_ty_adjusted(tcx, base_e).sty {
+ match tcx.expr_ty_adjusted(base_e).sty {
ty::TyStruct(did, _) => {
- ty::lookup_struct_fields(tcx, did)
+ tcx.lookup_struct_fields(did)
.iter()
.find(|f| f.name == field.node.name)
.unwrap_or_else(|| {
}
ast::ExprTupField(ref base_e, ref field) => {
span = field.span;
- match ty::expr_ty_adjusted(tcx, base_e).sty {
+ match tcx.expr_ty_adjusted(base_e).sty {
ty::TyStruct(did, _) => {
- ty::lookup_struct_fields(tcx, did)
+ tcx.lookup_struct_fields(did)
.get(field.node)
.unwrap_or_else(|| {
tcx.sess.span_bug(field.span,
}
}
ast::ExprStruct(_, ref expr_fields, _) => {
- let type_ = ty::expr_ty(tcx, e);
+ let type_ = tcx.expr_ty(e);
match type_.sty {
ty::TyStruct(did, _) => {
- let struct_fields = ty::lookup_struct_fields(tcx, did);
+ let struct_fields = tcx.lookup_struct_fields(did);
// check the stability of each field that appears
// in the construction expression.
for field in expr_fields {
debug!("check_pat(pat = {:?})", pat);
if is_internal(tcx, pat.span) { return; }
- let did = match ty::pat_ty_opt(tcx, pat) {
+ let did = match tcx.pat_ty_opt(pat) {
Some(&ty::TyS { sty: ty::TyStruct(did, _), .. }) => did,
Some(_) | None => return,
};
- let struct_fields = ty::lookup_struct_fields(tcx, did);
+ let struct_fields = tcx.lookup_struct_fields(did);
match pat.node {
// Foo(a, b, c)
ast::PatEnum(_, Some(ref pat_fields)) => {
}
fn is_staged_api(tcx: &ty::ctxt, id: DefId) -> bool {
- match ty::trait_item_of_item(tcx, id) {
+ match tcx.trait_item_of_item(id) {
Some(ty::MethodTraitItemId(trait_method_id))
if trait_method_id != id => {
is_staged_api(tcx, trait_method_id)
debug!("lookup(id={:?})", id);
// is this definition the implementation of a trait method?
- match ty::trait_item_of_item(tcx, id) {
+ match tcx.trait_item_of_item(id) {
Some(ty::MethodTraitItemId(trait_method_id)) if trait_method_id != id => {
debug!("lookup: trait_method_id={:?}", trait_method_id);
return lookup(tcx, trait_method_id)
};
item_stab.or_else(|| {
- if ty::is_impl(tcx, id) {
- if let Some(trait_id) = ty::trait_id_of_impl(tcx, id) {
+ if tcx.is_impl(id) {
+ if let Some(trait_id) = tcx.trait_id_of_impl(id) {
// FIXME (#18969): for the time being, simply use the
// stability of the trait to determine the stability of any
// unmarked impls for it. See FIXME above for more details.
impl1_def_id,
impl2_def_id);
- let param_env = &ty::empty_parameter_environment(infcx.tcx);
+ let param_env = &infcx.tcx.empty_parameter_environment();
let selcx = &mut SelectionContext::intercrate(infcx, param_env);
infcx.probe(|_| {
overlap(selcx, impl1_def_id, impl2_def_id) || overlap(selcx, impl2_def_id, impl1_def_id)
// already
if
trait_ref.def_id.krate != ast::LOCAL_CRATE &&
- !ty::has_attr(tcx, trait_ref.def_id, "fundamental")
+ !tcx.has_attr(trait_ref.def_id, "fundamental")
{
debug!("trait_ref_is_knowable: trait is neither local nor fundamental");
return false;
let impl_substs =
&substs_fn(selcx.infcx(), DUMMY_SP, impl_def_id);
let impl_trait_ref =
- ty::impl_trait_ref(selcx.tcx(), impl_def_id).unwrap();
+ selcx.tcx().impl_trait_ref(impl_def_id).unwrap();
let impl_trait_ref =
impl_trait_ref.subst(selcx.tcx(), impl_substs);
let Normalized { value: impl_trait_ref, obligations: normalization_obligations1 } =
project::normalize(selcx, ObligationCause::dummy(), &impl_trait_ref);
- let predicates = ty::lookup_predicates(selcx.tcx(), impl_def_id);
+ let predicates = selcx.tcx().lookup_predicates(impl_def_id);
let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
let Normalized { value: predicates, obligations: normalization_obligations2 } =
project::normalize(selcx, ObligationCause::dummy(), &predicates);
// We only except this routine to be invoked on implementations
// of a trait, not inherent implementations.
- let trait_ref = ty::impl_trait_ref(tcx, impl_def_id).unwrap();
+ let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
debug!("orphan_check: trait_ref={:?}", trait_ref);
// If the *trait* is local to the crate, ok.
ty::TyBox(..) | ty::TyRef(..) =>
true,
ty::TyEnum(def_id, _) | ty::TyStruct(def_id, _) =>
- ty::has_attr(tcx, def_id, "fundamental"),
+ tcx.has_attr(def_id, "fundamental"),
ty::TyTrait(ref data) =>
- ty::has_attr(tcx, data.principal_def_id(), "fundamental"),
+ tcx.has_attr(data.principal_def_id(), "fundamental"),
_ =>
false
}
span: Span) -> Option<String> {
let def_id = trait_ref.def_id;
let mut report = None;
- for item in ty::get_attrs(infcx.tcx, def_id).iter() {
+ for item in infcx.tcx.get_attrs(def_id).iter() {
if item.check_name("rustc_on_unimplemented") {
let err_sp = if item.meta().span == DUMMY_SP {
span
} else {
item.meta().span
};
- let def = ty::lookup_trait_def(infcx.tcx, def_id);
+ let def = infcx.tcx.lookup_trait_def(def_id);
let trait_str = def.trait_ref.to_string();
if let Some(ref istring) = item.value_str() {
let mut generic_map = def.generics.types.iter_enumerated()
TraitNotObjectSafe(did) => {
span_err!(infcx.tcx.sess, obligation.cause.span, E0038,
"cannot convert to a trait object because trait `{}` is not object-safe",
- ty::item_path_str(infcx.tcx, did));
+ infcx.tcx.item_path_str(did));
for violation in object_safety_violations(infcx.tcx, did) {
match violation {
match *cause_code {
ObligationCauseCode::MiscObligation => { }
ObligationCauseCode::ItemObligation(item_def_id) => {
- let item_name = ty::item_path_str(tcx, item_def_id);
+ let item_name = tcx.item_path_str(item_def_id);
tcx.sess.span_note(
cause_span,
&format!("required by `{}`", item_name));
}
ObligationCauseCode::ClosureCapture(var_id, closure_span, builtin_bound) => {
let def_id = tcx.lang_items.from_builtin_kind(builtin_bound).unwrap();
- let trait_name = ty::item_path_str(tcx, def_id);
- let name = ty::local_var_name_str(tcx, var_id);
+ let trait_name = tcx.item_path_str(def_id);
+ let name = tcx.local_var_name_str(var_id);
span_note!(tcx.sess, closure_span,
"the closure that captures `{}` requires that all captured variables \
implement the trait `{}`",
// regions. If there are, we will call this obligation an
// error. Eventually we should be able to support some
// cases here, I imagine (e.g., `for<'a> int : 'a`).
- if ty::count_late_bound_regions(selcx.tcx(), binder) != 0 {
+ if selcx.tcx().count_late_bound_regions(binder) != 0 {
errors.push(
FulfillmentError::new(
obligation.clone(),
-> bool
{
// Because we query yes/no results frequently, we keep a cache:
- let def = ty::lookup_trait_def(tcx, trait_def_id);
+ let def = tcx.lookup_trait_def(trait_def_id);
let result = def.object_safety().unwrap_or_else(|| {
let result = object_safety_violations(tcx, trait_def_id).is_empty();
{
// Check methods for violations.
let mut violations: Vec<_> =
- ty::trait_items(tcx, trait_def_id).iter()
+ tcx.trait_items(trait_def_id).iter()
.flat_map(|item| {
match *item {
ty::MethodTraitItem(ref m) => {
trait_def_id: ast::DefId)
-> bool
{
- let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+ let trait_def = tcx.lookup_trait_def(trait_def_id);
let trait_ref = trait_def.trait_ref.clone();
let trait_ref = trait_ref.to_poly_trait_ref();
- let predicates = ty::lookup_super_predicates(tcx, trait_def_id);
+ let predicates = tcx.lookup_super_predicates(trait_def_id);
predicates
.predicates
.into_iter()
trait_def_id: ast::DefId)
-> bool
{
- let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
- let trait_predicates = ty::lookup_predicates(tcx, trait_def_id);
+ let trait_def = tcx.lookup_trait_def(trait_def_id);
+ let trait_predicates = tcx.lookup_predicates(trait_def_id);
generics_require_sized_self(tcx, &trait_def.generics, &trait_predicates)
}
};
// Search for a predicate like `Self : Sized` amongst the trait bounds.
- let free_substs = ty::construct_free_substs(tcx, generics, ast::DUMMY_NODE_ID);
+ let free_substs = tcx.construct_free_substs(generics, ast::DUMMY_NODE_ID);
let predicates = predicates.instantiate(tcx, &free_substs).predicates.into_vec();
elaborate_predicates(tcx, predicates)
.any(|predicate| {
// Compute supertraits of current trait lazily.
if supertraits.is_none() {
- let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
+ let trait_def = tcx.lookup_trait_def(trait_def_id);
let trait_ref = ty::Binder(trait_def.trait_ref.clone());
supertraits = Some(traits::supertraits(tcx, trait_ref).collect());
}
};
// If so, extract what we know from the trait and try to come up with a good answer.
- let trait_predicates = ty::lookup_predicates(selcx.tcx(), trait_ref.def_id);
+ let trait_predicates = selcx.tcx().lookup_predicates(trait_ref.def_id);
let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs);
let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates.into_vec());
assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
// It is not in the impl - get the default from the trait.
let trait_ref = obligation.predicate.trait_ref;
- for trait_item in ty::trait_items(selcx.tcx(), trait_ref.def_id).iter() {
+ for trait_item in selcx.tcx().trait_items(trait_ref.def_id).iter() {
if let &ty::TypeTraitItem(ref assoc_ty) = trait_item {
if assoc_ty.name == obligation.predicate.item_name {
if let Some(ty) = assoc_ty.ty {
match candidate {
ImplCandidate(def_id) => {
- match ty::trait_impl_polarity(self.tcx(), def_id) {
+ match self.tcx().trait_impl_polarity(def_id) {
Some(ast::ImplPolarity::Negative) => return Err(Unimplemented),
_ => {}
}
projection_trait_ref={:?}",
projection_trait_ref);
- let trait_predicates = ty::lookup_predicates(self.tcx(), projection_trait_ref.def_id);
+ let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id);
let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
debug!("match_projection_obligation_against_bounds_from_trait: \
bounds={:?}",
{
debug!("assemble_candidates_from_impls(obligation={:?})", obligation);
- let def = ty::lookup_trait_def(self.tcx(), obligation.predicate.def_id());
+ let def = self.tcx().lookup_trait_def(obligation.predicate.def_id());
def.for_each_relevant_impl(
self.tcx(),
let def_id = obligation.predicate.def_id();
- if ty::trait_has_default_impl(self.tcx(), def_id) {
+ if self.tcx().trait_has_default_impl(def_id) {
match self_ty.sty {
ty::TyTrait(..) => {
// For object types, we don't know what the closed
// object types, because it just lets you reflect
// onto the object type, not into the object's
// interior.
- if ty::has_attr(self.tcx(), def_id, "rustc_reflect_like") {
+ if self.tcx().has_attr(def_id, "rustc_reflect_like") {
candidates.vec.push(DefaultImplObjectCandidate(def_id));
}
}
// T: Trait
// so it seems ok if we (conservatively) fail to accept that `Unsize`
// obligation above. Should be possible to extend this in the future.
- let self_ty = match ty::no_late_bound_regions(self.tcx(), &obligation.self_ty()) {
+ let self_ty = match self.tcx().no_late_bound_regions(&obligation.self_ty()) {
Some(t) => t,
None => {
// Don't add any candidates if there are bound regions.
ty::TyStruct(def_id, substs) => {
let types: Vec<Ty> =
- ty::struct_fields(self.tcx(), def_id, substs).iter()
+ self.tcx().struct_fields(def_id, substs).iter()
.map(|f| f.mt.ty)
.collect();
nominal(bound, types)
ty::TyEnum(def_id, substs) => {
let types: Vec<Ty> =
- ty::substd_enum_variants(self.tcx(), def_id, substs)
+ self.tcx().substd_enum_variants(def_id, substs)
.iter()
.flat_map(|variant| &variant.args)
.cloned()
}
ty::TyStruct(def_id, substs) => {
- Some(ty::struct_fields(self.tcx(), def_id, substs).iter()
+ Some(self.tcx().struct_fields(def_id, substs).iter()
.map(|f| f.mt.ty)
.collect())
}
ty::TyEnum(def_id, substs) => {
- Some(ty::substd_enum_variants(self.tcx(), def_id, substs)
+ Some(self.tcx().substd_enum_variants(def_id, substs)
.iter()
.flat_map(|variant| &variant.args)
.map(|&ty| ty)
obligation,
trait_def_id);
- assert!(ty::has_attr(self.tcx(), trait_def_id, "rustc_reflect_like"));
+ assert!(self.tcx().has_attr(trait_def_id, "rustc_reflect_like"));
// OK to skip binder, it is reintroduced below
let self_ty = self.infcx.shallow_resolve(obligation.predicate.skip_binder().self_ty());
// reintroduce the two binding levels we skipped, then flatten into one
let all_types = ty::Binder(ty::Binder(all_types));
- let all_types = ty::flatten_late_bound_regions(self.tcx(), &all_types);
+ let all_types = self.tcx().flatten_late_bound_regions(&all_types);
self.vtable_default_impl(obligation, trait_def_id, all_types)
}
// assemble_candidates_for_unsizing should ensure there are no late bound
// regions here. See the comment there for more details.
let source = self.infcx.shallow_resolve(
- ty::no_late_bound_regions(tcx, &obligation.self_ty()).unwrap());
+ tcx.no_late_bound_regions(&obligation.self_ty()).unwrap());
let target = self.infcx.shallow_resolve(obligation.predicate.0.input_types()[0]);
debug!("confirm_builtin_unsize_candidate(source={:?}, target={:?})",
// Struct<T> -> Struct<U>.
(&ty::TyStruct(def_id, substs_a), &ty::TyStruct(_, substs_b)) => {
- let fields = ty::lookup_struct_fields(tcx, def_id).iter().map(|f| {
- ty::lookup_field_type_unsubstituted(tcx, def_id, f.id)
+ let fields = tcx.lookup_struct_fields(def_id).iter().map(|f| {
+ tcx.lookup_field_type_unsubstituted(def_id, f.id)
}).collect::<Vec<_>>();
// The last field of the structure has to exist and contain type parameters.
-> Result<(Normalized<'tcx, Substs<'tcx>>,
infer::SkolemizationMap), ()>
{
- let impl_trait_ref = ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap();
+ let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
// Before we create the substitutions and everything, first
// consider a "quick reject". This avoids creating more types
impl_def_id);
// Find the self type for the impl.
- let impl_self_ty = ty::lookup_item_type(self.tcx(), impl_def_id).ty;
+ let impl_self_ty = self.tcx().lookup_item_type(impl_def_id).ty;
let impl_self_ty = impl_self_ty.subst(self.tcx(), &impl_substs);
debug!("match_impl_self_types(obligation_self_ty={:?}, impl_self_ty={:?})",
{
debug!("impl_or_trait_obligations(def_id={:?})", def_id);
- let predicates = ty::lookup_predicates(self.tcx(), def_id);
+ let predicates = self.tcx().lookup_predicates(def_id);
let predicates = predicates.instantiate(self.tcx(), substs);
let predicates = normalize_with_depth(self, cause.clone(), recursion_depth, &predicates);
let mut predicates = self.infcx().plug_leaks(skol_map, snapshot, &predicates);
// regions before we throw things into the underlying set.
let normalized_pred = match *pred {
ty::Predicate::Trait(ref data) =>
- ty::Predicate::Trait(ty::anonymize_late_bound_regions(self.tcx, data)),
+ ty::Predicate::Trait(self.tcx.anonymize_late_bound_regions(data)),
ty::Predicate::Equate(ref data) =>
- ty::Predicate::Equate(ty::anonymize_late_bound_regions(self.tcx, data)),
+ ty::Predicate::Equate(self.tcx.anonymize_late_bound_regions(data)),
ty::Predicate::RegionOutlives(ref data) =>
- ty::Predicate::RegionOutlives(ty::anonymize_late_bound_regions(self.tcx, data)),
+ ty::Predicate::RegionOutlives(self.tcx.anonymize_late_bound_regions(data)),
ty::Predicate::TypeOutlives(ref data) =>
- ty::Predicate::TypeOutlives(ty::anonymize_late_bound_regions(self.tcx, data)),
+ ty::Predicate::TypeOutlives(self.tcx.anonymize_late_bound_regions(data)),
ty::Predicate::Projection(ref data) =>
- ty::Predicate::Projection(ty::anonymize_late_bound_regions(self.tcx, data)),
+ ty::Predicate::Projection(self.tcx.anonymize_late_bound_regions(data)),
};
self.set.insert(normalized_pred)
}
match *predicate {
ty::Predicate::Trait(ref data) => {
// Predicates declared on the trait.
- let predicates = ty::lookup_super_predicates(self.tcx, data.def_id());
+ let predicates = self.tcx.lookup_super_predicates(data.def_id());
let mut predicates: Vec<_> =
predicates.predicates
None => { return None; }
};
- let predicates = ty::lookup_super_predicates(self.tcx, def_id);
+ let predicates = self.tcx.lookup_super_predicates(def_id);
let visited = &mut self.visited;
self.stack.extend(
predicates.predicates
-> Substs<'tcx>
{
let tcx = infcx.tcx;
- let impl_generics = ty::lookup_item_type(tcx, impl_def_id).generics;
+ let impl_generics = tcx.lookup_item_type(impl_def_id).generics;
infcx.fresh_substs_for_generics(span, &impl_generics)
}
break;
}
- let trait_items = ty::trait_items(tcx, bound_ref.def_id());
+ let trait_items = tcx.trait_items(bound_ref.def_id());
for trait_item in trait_items.iter() {
match *trait_item {
ty::MethodTraitItem(_) => method_count += 1,
// count number of methods preceding the one we are selecting and
// add them to the total offset; skip over associated types.
- let trait_items = ty::trait_items(tcx, trait_def_id);
+ let trait_items = tcx.trait_items(trait_def_id);
for trait_item in trait_items.iter().take(method_offset_in_trait) {
match *trait_item {
ty::MethodTraitItem(_) => method_count += 1,
use middle::dependency_format;
use middle::fast_reject;
use middle::free_region::FreeRegionMap;
-use middle::infer::error_reporting::note_and_explain_region;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
use middle::mem_categorization as mc;
+use middle::mem_categorization::Typer;
use middle::region;
use middle::resolve_lifetime;
use middle::infer;
pub mt: mt<'tcx>
}
+
+
+// Enum information
+#[derive(Clone)]
+pub struct VariantInfo<'tcx> {
+ pub args: Vec<Ty<'tcx>>,
+ pub arg_names: Option<Vec<ast::Name>>,
+ pub ctor_ty: Option<Ty<'tcx>>,
+ pub name: ast::Name,
+ pub id: ast::DefId,
+ pub disr_val: Disr,
+ pub vis: Visibility
+}
+
+impl<'tcx> VariantInfo<'tcx> {
+
+ /// Creates a new VariantInfo from the corresponding ast representation.
+ ///
+ /// Does not do any caching of the value in the type context.
+ pub fn from_ast_variant(cx: &ctxt<'tcx>,
+ ast_variant: &ast::Variant,
+ discriminant: Disr) -> VariantInfo<'tcx> {
+ let ctor_ty = cx.node_id_to_type(ast_variant.node.id);
+
+ match ast_variant.node.kind {
+ ast::TupleVariantKind(ref args) => {
+ let arg_tys = if !args.is_empty() {
+ // the regions in the argument types come from the
+ // enum def'n, and hence will all be early bound
+ cx.no_late_bound_regions(&ctor_ty.fn_args()).unwrap()
+ } else {
+ Vec::new()
+ };
+
+ return VariantInfo {
+ args: arg_tys,
+ arg_names: None,
+ ctor_ty: Some(ctor_ty),
+ name: ast_variant.node.name.name,
+ id: ast_util::local_def(ast_variant.node.id),
+ disr_val: discriminant,
+ vis: ast_variant.node.vis
+ };
+ },
+ ast::StructVariantKind(ref struct_def) => {
+ let fields: &[StructField] = &struct_def.fields;
+
+ assert!(!fields.is_empty());
+
+ let arg_tys = struct_def.fields.iter()
+ .map(|field| cx.node_id_to_type(field.node.id)).collect();
+ let arg_names = fields.iter().map(|field| {
+ match field.node.kind {
+ NamedField(ident, _) => ident.name,
+ UnnamedField(..) => cx.sess.bug(
+ "enum_variants: all fields in struct must have a name")
+ }
+ }).collect();
+
+ return VariantInfo {
+ args: arg_tys,
+ arg_names: Some(arg_names),
+ ctor_ty: None,
+ name: ast_variant.node.name.name,
+ id: ast_util::local_def(ast_variant.node.id),
+ disr_val: discriminant,
+ vis: ast_variant.node.vis
+ };
+ }
+ }
+ }
+}
+
+#[derive(Copy, Clone)]
+pub enum DtorKind {
+ NoDtor,
+ TraitDtor(DefId, bool)
+}
+
+impl DtorKind {
+ pub fn is_present(&self) -> bool {
+ match *self {
+ TraitDtor(..) => true,
+ _ => false
+ }
+ }
+
+ pub fn has_drop_flag(&self) -> bool {
+ match self {
+ &NoDtor => false,
+ &TraitDtor(_, flag) => flag
+ }
+ }
+}
+
+trait IntTypeExt {
+ fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
+ fn i64_to_disr(&self, val: i64) -> Option<Disr>;
+ fn u64_to_disr(&self, val: u64) -> Option<Disr>;
+ fn disr_incr(&self, val: Disr) -> Option<Disr>;
+ fn disr_string(&self, val: Disr) -> String;
+ fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
+}
+
+impl IntTypeExt for attr::IntType {
+ fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
+ match *self {
+ SignedInt(ast::TyI8) => cx.types.i8,
+ SignedInt(ast::TyI16) => cx.types.i16,
+ SignedInt(ast::TyI32) => cx.types.i32,
+ SignedInt(ast::TyI64) => cx.types.i64,
+ SignedInt(ast::TyIs) => cx.types.isize,
+ UnsignedInt(ast::TyU8) => cx.types.u8,
+ UnsignedInt(ast::TyU16) => cx.types.u16,
+ UnsignedInt(ast::TyU32) => cx.types.u32,
+ UnsignedInt(ast::TyU64) => cx.types.u64,
+ UnsignedInt(ast::TyUs) => cx.types.usize,
+ }
+ }
+
+ fn i64_to_disr(&self, val: i64) -> Option<Disr> {
+ match *self {
+ SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
+ SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
+ SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
+ SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+
+ UnsignedInt(ast::TyUs) |
+ SignedInt(ast::TyIs) => unreachable!(),
+ }
+ }
+
+ fn u64_to_disr(&self, val: u64) -> Option<Disr> {
+ match *self {
+ SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
+ SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
+ SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
+ SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
+ UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+
+ UnsignedInt(ast::TyUs) |
+ SignedInt(ast::TyIs) => unreachable!(),
+ }
+ }
+
+ fn disr_incr(&self, val: Disr) -> Option<Disr> {
+ macro_rules! add1 {
+ ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
+ }
+ match *self {
+ // SignedInt repr means we *want* to reinterpret the bits
+ // treating the highest bit of Disr as a sign-bit, so
+ // cast to i64 before range-checking.
+ SignedInt(ast::TyI8) => add1!((val as i64).to_i8()),
+ SignedInt(ast::TyI16) => add1!((val as i64).to_i16()),
+ SignedInt(ast::TyI32) => add1!((val as i64).to_i32()),
+ SignedInt(ast::TyI64) => add1!(Some(val as i64)),
+
+ UnsignedInt(ast::TyU8) => add1!(val.to_u8()),
+ UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
+ UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
+ UnsignedInt(ast::TyU64) => add1!(Some(val)),
+
+ UnsignedInt(ast::TyUs) |
+ SignedInt(ast::TyIs) => unreachable!(),
+ }
+ }
+
+ // This returns a String because (1.) it is only used for
+ // rendering an error message and (2.) a string can represent the
+ // full range from `i64::MIN` through `u64::MAX`.
+ fn disr_string(&self, val: Disr) -> String {
+ match *self {
+ SignedInt(ast::TyI8) => format!("{}", val as i8 ),
+ SignedInt(ast::TyI16) => format!("{}", val as i16),
+ SignedInt(ast::TyI32) => format!("{}", val as i32),
+ SignedInt(ast::TyI64) => format!("{}", val as i64),
+ UnsignedInt(ast::TyU8) => format!("{}", val as u8 ),
+ UnsignedInt(ast::TyU16) => format!("{}", val as u16),
+ UnsignedInt(ast::TyU32) => format!("{}", val as u32),
+ UnsignedInt(ast::TyU64) => format!("{}", val as u64),
+
+ UnsignedInt(ast::TyUs) |
+ SignedInt(ast::TyIs) => unreachable!(),
+ }
+ }
+
+ fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
+ macro_rules! add1 {
+ ($e:expr) => { ($e).wrapping_add(1) as Disr }
+ }
+ let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
+ match *self {
+ SignedInt(ast::TyI8) => add1!(val as i8 ),
+ SignedInt(ast::TyI16) => add1!(val as i16),
+ SignedInt(ast::TyI32) => add1!(val as i32),
+ SignedInt(ast::TyI64) => add1!(val as i64),
+ UnsignedInt(ast::TyU8) => add1!(val as u8 ),
+ UnsignedInt(ast::TyU16) => add1!(val as u16),
+ UnsignedInt(ast::TyU32) => add1!(val as u32),
+ UnsignedInt(ast::TyU64) => add1!(val as u64),
+
+ UnsignedInt(ast::TyUs) |
+ SignedInt(ast::TyIs) => unreachable!(),
+ }
+ }
+}
+
#[derive(Clone, Copy, Debug)]
pub enum ImplOrTraitItemContainer {
TraitContainer(ast::DefId),
Bivariant, // T<A> <: T<B> -- e.g., unused type parameter
}
+impl fmt::Debug for Variance {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(match *self {
+ Covariant => "+",
+ Contravariant => "-",
+ Invariant => "o",
+ Bivariant => "*",
+ })
+ }
+}
+
#[derive(Copy, Clone)]
pub enum AutoAdjustment<'tcx> {
AdjustReifyFnPointer, // go from a fn-item type to a fn-pointer type
Some(ast_map::NodeTraitItem(..)) |
Some(ast_map::NodeVariant(..)) |
Some(ast_map::NodeStructCtor(..)) => {
- return write!(f, "{}", ty::item_path_str(tcx, def_id));
+ return write!(f, "{}", tcx.item_path_str(def_id));
}
_ => {}
}
pub type UpvarCaptureMap = FnvHashMap<UpvarId, UpvarCapture>;
+#[derive(Copy, Clone)]
+pub struct ClosureUpvar<'tcx> {
+ pub def: def::Def,
+ pub span: Span,
+ pub ty: Ty<'tcx>,
+}
+
impl Region {
pub fn is_bound(&self) -> bool {
match *self {
match impl_item.node {
ast::ConstImplItem(_, _) => {
let def_id = ast_util::local_def(id);
- let scheme = lookup_item_type(cx, def_id);
- let predicates = lookup_predicates(cx, def_id);
- construct_parameter_environment(cx,
- impl_item.span,
- &scheme.generics,
- &predicates,
- id)
+ let scheme = cx.lookup_item_type(def_id);
+ let predicates = cx.lookup_predicates(def_id);
+ cx.construct_parameter_environment(impl_item.span,
+ &scheme.generics,
+ &predicates,
+ id)
}
ast::MethodImplItem(_, ref body) => {
let method_def_id = ast_util::local_def(id);
- match ty::impl_or_trait_item(cx, method_def_id) {
+ match cx.impl_or_trait_item(method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
- construct_parameter_environment(
- cx,
+ cx.construct_parameter_environment(
impl_item.span,
method_generics,
method_bounds,
match *default {
Some(_) => {
let def_id = ast_util::local_def(id);
- let scheme = lookup_item_type(cx, def_id);
- let predicates = lookup_predicates(cx, def_id);
- construct_parameter_environment(cx,
- trait_item.span,
- &scheme.generics,
- &predicates,
- id)
+ let scheme = cx.lookup_item_type(def_id);
+ let predicates = cx.lookup_predicates(def_id);
+ cx.construct_parameter_environment(trait_item.span,
+ &scheme.generics,
+ &predicates,
+ id)
}
None => {
cx.sess.bug("ParameterEnvironment::from_item(): \
}
ast::MethodTraitItem(_, Some(ref body)) => {
let method_def_id = ast_util::local_def(id);
- match ty::impl_or_trait_item(cx, method_def_id) {
+ match cx.impl_or_trait_item(method_def_id) {
MethodTraitItem(ref method_ty) => {
let method_generics = &method_ty.generics;
let method_bounds = &method_ty.predicates;
- construct_parameter_environment(
- cx,
+ cx.construct_parameter_environment(
trait_item.span,
method_generics,
method_bounds,
ast::ItemFn(_, _, _, _, _, ref body) => {
// We assume this is a function.
let fn_def_id = ast_util::local_def(id);
- let fn_scheme = lookup_item_type(cx, fn_def_id);
- let fn_predicates = lookup_predicates(cx, fn_def_id);
-
- construct_parameter_environment(cx,
- item.span,
- &fn_scheme.generics,
- &fn_predicates,
- body.id)
+ let fn_scheme = cx.lookup_item_type(fn_def_id);
+ let fn_predicates = cx.lookup_predicates(fn_def_id);
+
+ cx.construct_parameter_environment(item.span,
+ &fn_scheme.generics,
+ &fn_predicates,
+ body.id)
}
ast::ItemEnum(..) |
ast::ItemStruct(..) |
ast::ItemConst(..) |
ast::ItemStatic(..) => {
let def_id = ast_util::local_def(id);
- let scheme = lookup_item_type(cx, def_id);
- let predicates = lookup_predicates(cx, def_id);
- construct_parameter_environment(cx,
- item.span,
- &scheme.generics,
- &predicates,
- id)
+ let scheme = cx.lookup_item_type(def_id);
+ let predicates = cx.lookup_predicates(def_id);
+ cx.construct_parameter_environment(item.span,
+ &scheme.generics,
+ &predicates,
+ id)
}
_ => {
cx.sess.span_bug(item.span,
}
}
}
+
+ pub fn can_type_implement_copy(&self, self_type: Ty<'tcx>, span: Span)
+ -> Result<(),CopyImplementationError> {
+ let tcx = self.tcx;
+
+ let did = match self_type.sty {
+ ty::TyStruct(struct_did, substs) => {
+ let fields = tcx.struct_fields(struct_did, substs);
+ for field in &fields {
+ if self.type_moves_by_default(field.mt.ty, span) {
+ return Err(FieldDoesNotImplementCopy(field.name))
+ }
+ }
+ struct_did
+ }
+ ty::TyEnum(enum_did, substs) => {
+ let enum_variants = tcx.enum_variants(enum_did);
+ for variant in enum_variants.iter() {
+ for variant_arg_type in &variant.args {
+ let substd_arg_type =
+ variant_arg_type.subst(tcx, substs);
+ if self.type_moves_by_default(substd_arg_type, span) {
+ return Err(VariantDoesNotImplementCopy(variant.name))
+ }
+ }
+ }
+ enum_did
+ }
+ _ => return Err(TypeIsStructural),
+ };
+
+ if tcx.has_dtor(did) {
+ return Err(TypeHasDestructor)
+ }
+
+ Ok(())
+ }
+}
+
+#[derive(Copy, Clone)]
+pub enum CopyImplementationError {
+ FieldDoesNotImplementCopy(ast::Name),
+ VariantDoesNotImplementCopy(ast::Name),
+ TypeIsStructural,
+ TypeHasDestructor,
}
/// A "type scheme", in ML terminology, is a type combined with some
pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: &ctxt<'tcx>, mut f: F) {
- ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
+ tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
for &impl_def_id in self.blanket_impls.borrow().iter() {
f(impl_def_id);
self_ty: Ty<'tcx>,
mut f: F)
{
- ty::populate_implementations_for_trait_if_necessary(tcx, self.trait_ref.def_id);
+ tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
for &impl_def_id in self.blanket_impls.borrow().iter() {
f(impl_def_id);
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
-> CommonTypes<'tcx>
{
+ let mut mk = |sty| ctxt::intern_ty(arena, interner, sty);
CommonTypes {
- bool: intern_ty(arena, interner, TyBool),
- char: intern_ty(arena, interner, TyChar),
- err: intern_ty(arena, interner, TyError),
- isize: intern_ty(arena, interner, TyInt(ast::TyIs)),
- i8: intern_ty(arena, interner, TyInt(ast::TyI8)),
- i16: intern_ty(arena, interner, TyInt(ast::TyI16)),
- i32: intern_ty(arena, interner, TyInt(ast::TyI32)),
- i64: intern_ty(arena, interner, TyInt(ast::TyI64)),
- usize: intern_ty(arena, interner, TyUint(ast::TyUs)),
- u8: intern_ty(arena, interner, TyUint(ast::TyU8)),
- u16: intern_ty(arena, interner, TyUint(ast::TyU16)),
- u32: intern_ty(arena, interner, TyUint(ast::TyU32)),
- u64: intern_ty(arena, interner, TyUint(ast::TyU64)),
- f32: intern_ty(arena, interner, TyFloat(ast::TyF32)),
- f64: intern_ty(arena, interner, TyFloat(ast::TyF64)),
- }
- }
-}
-
-/// Create a type context and call the closure with a `&ty::ctxt` reference
-/// to the context. The closure enforces that the type context and any interned
-/// value (types, substs, etc.) can only be used while `ty::tls` has a valid
-/// reference to the context, to allow formatting values that need it.
-pub fn with_ctxt<'tcx, F, R>(s: Session,
- arenas: &'tcx CtxtArenas<'tcx>,
- def_map: DefMap,
- named_region_map: resolve_lifetime::NamedRegionMap,
- map: ast_map::Map<'tcx>,
- freevars: RefCell<FreevarMap>,
- region_maps: RegionMaps,
- lang_items: middle::lang_items::LanguageItems,
- stability: stability::Index<'tcx>,
- f: F) -> (Session, R)
- where F: FnOnce(&ctxt<'tcx>) -> R
-{
- let mut interner = FnvHashMap();
- let common_types = CommonTypes::new(&arenas.type_, &mut interner);
-
- tls::enter(ctxt {
- arenas: arenas,
- interner: RefCell::new(interner),
- substs_interner: RefCell::new(FnvHashMap()),
- bare_fn_interner: RefCell::new(FnvHashMap()),
- region_interner: RefCell::new(FnvHashMap()),
- stability_interner: RefCell::new(FnvHashMap()),
- types: common_types,
- named_region_map: named_region_map,
- region_maps: region_maps,
- free_region_maps: RefCell::new(FnvHashMap()),
- item_variance_map: RefCell::new(DefIdMap()),
- variance_computed: Cell::new(false),
- sess: s,
- def_map: def_map,
- node_types: RefCell::new(FnvHashMap()),
- item_substs: RefCell::new(NodeMap()),
- impl_trait_refs: RefCell::new(DefIdMap()),
- trait_defs: RefCell::new(DefIdMap()),
- predicates: RefCell::new(DefIdMap()),
- super_predicates: RefCell::new(DefIdMap()),
- fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
- map: map,
- freevars: freevars,
- tcache: RefCell::new(DefIdMap()),
- rcache: RefCell::new(FnvHashMap()),
- tc_cache: RefCell::new(FnvHashMap()),
- ast_ty_to_ty_cache: RefCell::new(NodeMap()),
- enum_var_cache: RefCell::new(DefIdMap()),
- impl_or_trait_items: RefCell::new(DefIdMap()),
- trait_item_def_ids: RefCell::new(DefIdMap()),
- trait_items_cache: RefCell::new(DefIdMap()),
- ty_param_defs: RefCell::new(NodeMap()),
- adjustments: RefCell::new(NodeMap()),
- normalized_cache: RefCell::new(FnvHashMap()),
- lang_items: lang_items,
- provided_method_sources: RefCell::new(DefIdMap()),
- struct_fields: RefCell::new(DefIdMap()),
- destructor_for_type: RefCell::new(DefIdMap()),
- destructors: RefCell::new(DefIdSet()),
- inherent_impls: RefCell::new(DefIdMap()),
- impl_items: RefCell::new(DefIdMap()),
- used_unsafe: RefCell::new(NodeSet()),
- used_mut_nodes: RefCell::new(NodeSet()),
- populated_external_types: RefCell::new(DefIdSet()),
- populated_external_primitive_impls: RefCell::new(DefIdSet()),
- upvar_capture_map: RefCell::new(FnvHashMap()),
- extern_const_statics: RefCell::new(DefIdMap()),
- extern_const_variants: RefCell::new(DefIdMap()),
- extern_const_fns: RefCell::new(DefIdMap()),
- method_map: RefCell::new(FnvHashMap()),
- dependency_formats: RefCell::new(FnvHashMap()),
- closure_kinds: RefCell::new(DefIdMap()),
- closure_tys: RefCell::new(DefIdMap()),
- node_lint_levels: RefCell::new(FnvHashMap()),
- transmute_restrictions: RefCell::new(Vec::new()),
- stability: RefCell::new(stability),
- selection_cache: traits::SelectionCache::new(),
- repr_hint_cache: RefCell::new(DefIdMap()),
- const_qualif_map: RefCell::new(NodeMap()),
- custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
- cast_kinds: RefCell::new(NodeMap()),
- }, f)
-}
-
-// Type constructors
-
-impl<'tcx> ctxt<'tcx> {
- pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
- if let Some(substs) = self.substs_interner.borrow().get(&substs) {
- return *substs;
- }
-
- let substs = self.arenas.substs.alloc(substs);
- self.substs_interner.borrow_mut().insert(substs, substs);
- substs
- }
-
- /// Create an unsafe fn ty based on a safe fn ty.
- pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
- assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
- let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
- unsafety: ast::Unsafety::Unsafe,
- abi: bare_fn.abi,
- sig: bare_fn.sig.clone()
- });
- self.mk_fn(None, unsafe_fn_ty_a)
- }
-
- pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
- if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
- return *bare_fn;
- }
-
- let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
- self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
- bare_fn
- }
-
- pub fn mk_region(&self, region: Region) -> &'tcx Region {
- if let Some(region) = self.region_interner.borrow().get(®ion) {
- return *region;
- }
-
- let region = self.arenas.region.alloc(region);
- self.region_interner.borrow_mut().insert(region, region);
- region
- }
-
- pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
- *self.closure_kinds.borrow().get(&def_id).unwrap()
- }
-
- pub fn closure_type(&self,
- def_id: ast::DefId,
- substs: &subst::Substs<'tcx>)
- -> ty::ClosureTy<'tcx>
- {
- self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
- }
-
- pub fn type_parameter_def(&self,
- node_id: ast::NodeId)
- -> TypeParameterDef<'tcx>
- {
- self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
- }
-
- pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
- pat_util::pat_contains_ref_binding(&self.def_map, pat)
- }
-
- pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
- pat_util::arm_contains_ref_binding(&self.def_map, arm)
- }
-}
-
-fn intern_ty<'tcx>(type_arena: &'tcx TypedArena<TyS<'tcx>>,
- interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
- st: TypeVariants<'tcx>)
- -> Ty<'tcx>
-{
- match interner.get(&st) {
- Some(ty) => return *ty,
- _ => ()
- }
-
- let flags = FlagComputation::for_sty(&st);
-
- let ty = match () {
- () => type_arena.alloc(TyS { sty: st,
- flags: Cell::new(flags.flags),
- region_depth: flags.depth, }),
- };
-
- debug!("Interned type: {:?} Pointer: {:?}",
- ty, ty as *const TyS);
-
- interner.insert(InternedTy { ty: ty }, ty);
-
- ty
-}
+ bool: mk(TyBool),
+ char: mk(TyChar),
+ err: mk(TyError),
+ isize: mk(TyInt(ast::TyIs)),
+ i8: mk(TyInt(ast::TyI8)),
+ i16: mk(TyInt(ast::TyI16)),
+ i32: mk(TyInt(ast::TyI32)),
+ i64: mk(TyInt(ast::TyI64)),
+ usize: mk(TyUint(ast::TyUs)),
+ u8: mk(TyUint(ast::TyU8)),
+ u16: mk(TyUint(ast::TyU16)),
+ u32: mk(TyUint(ast::TyU32)),
+ u64: mk(TyUint(ast::TyU64)),
+ f32: mk(TyFloat(ast::TyF32)),
+ f64: mk(TyFloat(ast::TyF64)),
+ }
+ }
+}
struct FlagComputation {
flags: TypeFlags,
}
impl<'tcx> ctxt<'tcx> {
+ /// Create a type context and call the closure with a `&ty::ctxt` reference
+ /// to the context. The closure enforces that the type context and any interned
+ /// value (types, substs, etc.) can only be used while `ty::tls` has a valid
+ /// reference to the context, to allow formatting values that need it.
+ pub fn create_and_enter<F, R>(s: Session,
+ arenas: &'tcx CtxtArenas<'tcx>,
+ def_map: DefMap,
+ named_region_map: resolve_lifetime::NamedRegionMap,
+ map: ast_map::Map<'tcx>,
+ freevars: RefCell<FreevarMap>,
+ region_maps: RegionMaps,
+ lang_items: middle::lang_items::LanguageItems,
+ stability: stability::Index<'tcx>,
+ f: F) -> (Session, R)
+ where F: FnOnce(&ctxt<'tcx>) -> R
+ {
+ let mut interner = FnvHashMap();
+ let common_types = CommonTypes::new(&arenas.type_, &mut interner);
+
+ tls::enter(ctxt {
+ arenas: arenas,
+ interner: RefCell::new(interner),
+ substs_interner: RefCell::new(FnvHashMap()),
+ bare_fn_interner: RefCell::new(FnvHashMap()),
+ region_interner: RefCell::new(FnvHashMap()),
+ stability_interner: RefCell::new(FnvHashMap()),
+ types: common_types,
+ named_region_map: named_region_map,
+ region_maps: region_maps,
+ free_region_maps: RefCell::new(FnvHashMap()),
+ item_variance_map: RefCell::new(DefIdMap()),
+ variance_computed: Cell::new(false),
+ sess: s,
+ def_map: def_map,
+ node_types: RefCell::new(FnvHashMap()),
+ item_substs: RefCell::new(NodeMap()),
+ impl_trait_refs: RefCell::new(DefIdMap()),
+ trait_defs: RefCell::new(DefIdMap()),
+ predicates: RefCell::new(DefIdMap()),
+ super_predicates: RefCell::new(DefIdMap()),
+ fulfilled_predicates: RefCell::new(traits::FulfilledPredicates::new()),
+ map: map,
+ freevars: freevars,
+ tcache: RefCell::new(DefIdMap()),
+ rcache: RefCell::new(FnvHashMap()),
+ tc_cache: RefCell::new(FnvHashMap()),
+ ast_ty_to_ty_cache: RefCell::new(NodeMap()),
+ enum_var_cache: RefCell::new(DefIdMap()),
+ impl_or_trait_items: RefCell::new(DefIdMap()),
+ trait_item_def_ids: RefCell::new(DefIdMap()),
+ trait_items_cache: RefCell::new(DefIdMap()),
+ ty_param_defs: RefCell::new(NodeMap()),
+ adjustments: RefCell::new(NodeMap()),
+ normalized_cache: RefCell::new(FnvHashMap()),
+ lang_items: lang_items,
+ provided_method_sources: RefCell::new(DefIdMap()),
+ struct_fields: RefCell::new(DefIdMap()),
+ destructor_for_type: RefCell::new(DefIdMap()),
+ destructors: RefCell::new(DefIdSet()),
+ inherent_impls: RefCell::new(DefIdMap()),
+ impl_items: RefCell::new(DefIdMap()),
+ used_unsafe: RefCell::new(NodeSet()),
+ used_mut_nodes: RefCell::new(NodeSet()),
+ populated_external_types: RefCell::new(DefIdSet()),
+ populated_external_primitive_impls: RefCell::new(DefIdSet()),
+ upvar_capture_map: RefCell::new(FnvHashMap()),
+ extern_const_statics: RefCell::new(DefIdMap()),
+ extern_const_variants: RefCell::new(DefIdMap()),
+ extern_const_fns: RefCell::new(DefIdMap()),
+ method_map: RefCell::new(FnvHashMap()),
+ dependency_formats: RefCell::new(FnvHashMap()),
+ closure_kinds: RefCell::new(DefIdMap()),
+ closure_tys: RefCell::new(DefIdMap()),
+ node_lint_levels: RefCell::new(FnvHashMap()),
+ transmute_restrictions: RefCell::new(Vec::new()),
+ stability: RefCell::new(stability),
+ selection_cache: traits::SelectionCache::new(),
+ repr_hint_cache: RefCell::new(DefIdMap()),
+ const_qualif_map: RefCell::new(NodeMap()),
+ custom_coerce_unsized_kinds: RefCell::new(DefIdMap()),
+ cast_kinds: RefCell::new(NodeMap()),
+ }, f)
+ }
+
+ // Type constructors
+
+ pub fn mk_substs(&self, substs: Substs<'tcx>) -> &'tcx Substs<'tcx> {
+ if let Some(substs) = self.substs_interner.borrow().get(&substs) {
+ return *substs;
+ }
+
+ let substs = self.arenas.substs.alloc(substs);
+ self.substs_interner.borrow_mut().insert(substs, substs);
+ substs
+ }
+
+ /// Create an unsafe fn ty based on a safe fn ty.
+ pub fn safe_to_unsafe_fn_ty(&self, bare_fn: &BareFnTy<'tcx>) -> Ty<'tcx> {
+ assert_eq!(bare_fn.unsafety, ast::Unsafety::Normal);
+ let unsafe_fn_ty_a = self.mk_bare_fn(ty::BareFnTy {
+ unsafety: ast::Unsafety::Unsafe,
+ abi: bare_fn.abi,
+ sig: bare_fn.sig.clone()
+ });
+ self.mk_fn(None, unsafe_fn_ty_a)
+ }
+
+ pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
+ if let Some(bare_fn) = self.bare_fn_interner.borrow().get(&bare_fn) {
+ return *bare_fn;
+ }
+
+ let bare_fn = self.arenas.bare_fn.alloc(bare_fn);
+ self.bare_fn_interner.borrow_mut().insert(bare_fn, bare_fn);
+ bare_fn
+ }
+
+ pub fn mk_region(&self, region: Region) -> &'tcx Region {
+ if let Some(region) = self.region_interner.borrow().get(®ion) {
+ return *region;
+ }
+
+ let region = self.arenas.region.alloc(region);
+ self.region_interner.borrow_mut().insert(region, region);
+ region
+ }
+
+ pub fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+ *self.closure_kinds.borrow().get(&def_id).unwrap()
+ }
+
+ pub fn closure_type(&self,
+ def_id: ast::DefId,
+ substs: &subst::Substs<'tcx>)
+ -> ty::ClosureTy<'tcx>
+ {
+ self.closure_tys.borrow().get(&def_id).unwrap().subst(self, substs)
+ }
+
+ pub fn type_parameter_def(&self,
+ node_id: ast::NodeId)
+ -> TypeParameterDef<'tcx>
+ {
+ self.ty_param_defs.borrow().get(&node_id).unwrap().clone()
+ }
+
+ pub fn pat_contains_ref_binding(&self, pat: &ast::Pat) -> Option<ast::Mutability> {
+ pat_util::pat_contains_ref_binding(&self.def_map, pat)
+ }
+
+ pub fn arm_contains_ref_binding(&self, arm: &ast::Arm) -> Option<ast::Mutability> {
+ pat_util::arm_contains_ref_binding(&self.def_map, arm)
+ }
+
+ fn intern_ty(type_arena: &'tcx TypedArena<TyS<'tcx>>,
+ interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>,
+ st: TypeVariants<'tcx>)
+ -> Ty<'tcx> {
+ match interner.get(&st) {
+ Some(ty) => return *ty,
+ _ => ()
+ }
+
+ let flags = FlagComputation::for_sty(&st);
+
+ let ty = match () {
+ () => type_arena.alloc(TyS { sty: st,
+ flags: Cell::new(flags.flags),
+ region_depth: flags.depth, }),
+ };
+
+ debug!("Interned type: {:?} Pointer: {:?}",
+ ty, ty as *const TyS);
+
+ interner.insert(InternedTy { ty: ty }, ty);
+
+ ty
+ }
+
// Interns a type/name combination, stores the resulting box in cx.interner,
// and returns the box as cast to an unsafe ptr (see comments for Ty above).
pub fn mk_ty(&self, st: TypeVariants<'tcx>) -> Ty<'tcx> {
let mut interner = self.interner.borrow_mut();
- intern_ty(&self.arenas.type_, &mut *interner, st)
+ ctxt::intern_ty(&self.arenas.type_, &mut *interner, st)
}
pub fn mk_mach_int(&self, tm: ast::IntTy) -> Ty<'tcx> {
}
}
-// Folds types from the bottom up.
-pub fn fold_ty<'tcx, F>(cx: &ctxt<'tcx>, t0: Ty<'tcx>,
- fldop: F)
- -> Ty<'tcx> where
- F: FnMut(Ty<'tcx>) -> Ty<'tcx>,
-{
- let mut f = ty_fold::BottomUpFolder {tcx: cx, fldop: fldop};
- f.fold_ty(t0)
-}
-
impl ParamTy {
pub fn new(space: subst::ParamSpace,
index: u32,
}
}
+ pub fn is_empty(&self, cx: &ctxt) -> bool {
+ match self.sty {
+ TyEnum(did, _) => cx.enum_variants(did).is_empty(),
+ _ => false
+ }
+ }
+
pub fn is_ty_var(&self) -> bool {
match self.sty {
TyInfer(TyVar(_)) => true,
pub fn is_simd(&self, cx: &ctxt) -> bool {
match self.sty {
- TyStruct(did, _) => lookup_simd(cx, did),
+ TyStruct(did, _) => cx.lookup_simd(did),
_ => false
}
}
pub fn simd_type(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
match self.sty {
TyStruct(did, substs) => {
- let fields = lookup_struct_fields(cx, did);
- lookup_field_type(cx, did, fields[0].id, substs)
+ let fields = cx.lookup_struct_fields(did);
+ cx.lookup_field_type(did, fields[0].id, substs)
}
_ => panic!("simd_type called on invalid type")
}
pub fn simd_size(&self, cx: &ctxt) -> usize {
match self.sty {
TyStruct(did, _) => {
- let fields = lookup_struct_fields(cx, did);
- fields.len()
+ cx.lookup_struct_fields(did).len()
}
_ => panic!("simd_size called on invalid type")
}
_ => false,
}
}
+
+ pub fn ty_to_def_id(&self) -> Option<ast::DefId> {
+ match self.sty {
+ TyTrait(ref tt) => Some(tt.principal_def_id()),
+ TyStruct(id, _) |
+ TyEnum(id, _) |
+ TyClosure(id, _) => Some(id),
+ _ => None
+ }
+ }
}
/// Type contents is how the type checker reasons about kinds.
}
}
-pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
- return memoized(&cx.tc_cache, ty, |ty| {
- tc_ty(cx, ty, &mut FnvHashMap())
- });
+impl<'tcx> TyS<'tcx> {
+ pub fn type_contents(&'tcx self, cx: &ctxt<'tcx>) -> TypeContents {
+ return memoized(&cx.tc_cache, self, |ty| {
+ tc_ty(cx, ty, &mut FnvHashMap())
+ });
- fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
- ty: Ty<'tcx>,
- cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
- {
- // Subtle: Note that we are *not* using cx.tc_cache here but rather a
- // private cache for this walk. This is needed in the case of cyclic
- // types like:
- //
- // struct List { next: Box<Option<List>>, ... }
- //
- // When computing the type contents of such a type, we wind up deeply
- // recursing as we go. So when we encounter the recursive reference
- // to List, we temporarily use TC::None as its contents. Later we'll
- // patch up the cache with the correct value, once we've computed it
- // (this is basically a co-inductive process, if that helps). So in
- // the end we'll compute TC::OwnsOwned, in this case.
- //
- // The problem is, as we are doing the computation, we will also
- // compute an *intermediate* contents for, e.g., Option<List> of
- // TC::None. This is ok during the computation of List itself, but if
- // we stored this intermediate value into cx.tc_cache, then later
- // requests for the contents of Option<List> would also yield TC::None
- // which is incorrect. This value was computed based on the crutch
- // value for the type contents of list. The correct value is
- // TC::OwnsOwned. This manifested as issue #4821.
- match cache.get(&ty) {
- Some(tc) => { return *tc; }
- None => {}
- }
- match cx.tc_cache.borrow().get(&ty) { // Must check both caches!
- Some(tc) => { return *tc; }
- None => {}
- }
- cache.insert(ty, TC::None);
-
- let result = match ty.sty {
- // usize and isize are ffi-unsafe
- TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
- TC::ReachesFfiUnsafe
- }
-
- // Scalar and unique types are sendable, and durable
- TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) |
- TyBool | TyInt(_) | TyUint(_) | TyFloat(_) |
- TyBareFn(..) | ty::TyChar => {
- TC::None
- }
-
- TyBox(typ) => {
- TC::ReachesFfiUnsafe | match typ.sty {
- TyStr => TC::OwnsOwned,
- _ => tc_ty(cx, typ, cache).owned_pointer(),
+ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
+ ty: Ty<'tcx>,
+ cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
+ {
+ // Subtle: Note that we are *not* using cx.tc_cache here but rather a
+ // private cache for this walk. This is needed in the case of cyclic
+ // types like:
+ //
+ // struct List { next: Box<Option<List>>, ... }
+ //
+ // When computing the type contents of such a type, we wind up deeply
+ // recursing as we go. So when we encounter the recursive reference
+ // to List, we temporarily use TC::None as its contents. Later we'll
+ // patch up the cache with the correct value, once we've computed it
+ // (this is basically a co-inductive process, if that helps). So in
+ // the end we'll compute TC::OwnsOwned, in this case.
+ //
+ // The problem is, as we are doing the computation, we will also
+ // compute an *intermediate* contents for, e.g., Option<List> of
+ // TC::None. This is ok during the computation of List itself, but if
+ // we stored this intermediate value into cx.tc_cache, then later
+ // requests for the contents of Option<List> would also yield TC::None
+ // which is incorrect. This value was computed based on the crutch
+ // value for the type contents of list. The correct value is
+ // TC::OwnsOwned. This manifested as issue #4821.
+ match cache.get(&ty) {
+ Some(tc) => { return *tc; }
+ None => {}
+ }
+ match cx.tc_cache.borrow().get(&ty) { // Must check both caches!
+ Some(tc) => { return *tc; }
+ None => {}
+ }
+ cache.insert(ty, TC::None);
+
+ let result = match ty.sty {
+ // usize and isize are ffi-unsafe
+ TyUint(ast::TyUs) | TyInt(ast::TyIs) => {
+ TC::ReachesFfiUnsafe
}
- }
-
- TyTrait(box TraitTy { ref bounds, .. }) => {
- object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
- }
- TyRawPtr(ref mt) => {
- tc_ty(cx, mt.ty, cache).unsafe_pointer()
- }
+ // Scalar and unique types are sendable, and durable
+ TyInfer(ty::FreshIntTy(_)) | TyInfer(ty::FreshFloatTy(_)) |
+ TyBool | TyInt(_) | TyUint(_) | TyFloat(_) |
+ TyBareFn(..) | ty::TyChar => {
+ TC::None
+ }
- TyRef(r, ref mt) => {
- TC::ReachesFfiUnsafe | match mt.ty.sty {
- TyStr => borrowed_contents(*r, ast::MutImmutable),
- TyArray(..) |
- TySlice(_) => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r,
- mt.mutbl)),
- _ => tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)),
+ TyBox(typ) => {
+ TC::ReachesFfiUnsafe | tc_ty(cx, typ, cache).owned_pointer()
}
- }
- TyArray(ty, _) => {
- tc_ty(cx, ty, cache)
- }
+ TyTrait(box TraitTy { ref bounds, .. }) => {
+ object_contents(bounds) | TC::ReachesFfiUnsafe | TC::Nonsized
+ }
- TySlice(ty) => {
- tc_ty(cx, ty, cache) | TC::Nonsized
- }
- TyStr => TC::Nonsized,
+ TyRawPtr(ref mt) => {
+ tc_ty(cx, mt.ty, cache).unsafe_pointer()
+ }
- TyStruct(did, substs) => {
- let flds = struct_fields(cx, did, substs);
- let mut res =
- TypeContents::union(&flds[..],
- |f| tc_mt(cx, f.mt, cache));
+ TyRef(r, ref mt) => {
+ tc_ty(cx, mt.ty, cache).reference(borrowed_contents(*r, mt.mutbl)) |
+ TC::ReachesFfiUnsafe
+ }
- if !lookup_repr_hints(cx, did).contains(&attr::ReprExtern) {
- res = res | TC::ReachesFfiUnsafe;
+ TyArray(ty, _) => {
+ tc_ty(cx, ty, cache)
}
- if ty::has_dtor(cx, did) {
- res = res | TC::OwnsDtor;
+ TySlice(ty) => {
+ tc_ty(cx, ty, cache) | TC::Nonsized
}
- apply_lang_items(cx, did, res)
- }
+ TyStr => TC::Nonsized,
- TyClosure(did, substs) => {
- // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
- let param_env = ty::empty_parameter_environment(cx);
- let upvars = closure_upvars(¶m_env, did, substs).unwrap();
- TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
- }
+ TyStruct(did, substs) => {
+ let flds = cx.struct_fields(did, substs);
+ let mut res =
+ TypeContents::union(&flds[..],
+ |f| tc_mt(cx, f.mt, cache));
- TyTuple(ref tys) => {
- TypeContents::union(&tys[..],
- |ty| tc_ty(cx, *ty, cache))
- }
+ if !cx.lookup_repr_hints(did).contains(&attr::ReprExtern) {
+ res = res | TC::ReachesFfiUnsafe;
+ }
- TyEnum(did, substs) => {
- let variants = substd_enum_variants(cx, did, substs);
- let mut res =
- TypeContents::union(&variants[..], |variant| {
- TypeContents::union(&variant.args,
- |arg_ty| {
- tc_ty(cx, *arg_ty, cache)
- })
- });
+ if cx.has_dtor(did) {
+ res = res | TC::OwnsDtor;
+ }
+ apply_lang_items(cx, did, res)
+ }
- if ty::has_dtor(cx, did) {
- res = res | TC::OwnsDtor;
+ TyClosure(did, substs) => {
+ // FIXME(#14449): `borrowed_contents` below assumes `&mut` closure.
+ let param_env = cx.empty_parameter_environment();
+ let upvars = param_env.closure_upvars(did, substs).unwrap();
+ TypeContents::union(&upvars, |f| tc_ty(cx, &f.ty, cache))
}
- if !variants.is_empty() {
- let repr_hints = lookup_repr_hints(cx, did);
- if repr_hints.len() > 1 {
- // this is an error later on, but this type isn't safe
- res = res | TC::ReachesFfiUnsafe;
+ TyTuple(ref tys) => {
+ TypeContents::union(&tys[..],
+ |ty| tc_ty(cx, *ty, cache))
+ }
+
+ TyEnum(did, substs) => {
+ let variants = cx.substd_enum_variants(did, substs);
+ let mut res =
+ TypeContents::union(&variants[..], |variant| {
+ TypeContents::union(&variant.args,
+ |arg_ty| {
+ tc_ty(cx, *arg_ty, cache)
+ })
+ });
+
+ if cx.has_dtor(did) {
+ res = res | TC::OwnsDtor;
}
- match repr_hints.get(0) {
- Some(h) => if !h.is_ffi_safe() {
- res = res | TC::ReachesFfiUnsafe;
- },
- // ReprAny
- None => {
+ if !variants.is_empty() {
+ let repr_hints = cx.lookup_repr_hints(did);
+ if repr_hints.len() > 1 {
+ // this is an error later on, but this type isn't safe
res = res | TC::ReachesFfiUnsafe;
+ }
- // We allow ReprAny enums if they are eligible for
- // the nullable pointer optimization and the
- // contained type is an `extern fn`
+ match repr_hints.get(0) {
+ Some(h) => if !h.is_ffi_safe() {
+ res = res | TC::ReachesFfiUnsafe;
+ },
+ // ReprAny
+ None => {
+ res = res | TC::ReachesFfiUnsafe;
- if variants.len() == 2 {
- let mut data_idx = 0;
+ // We allow ReprAny enums if they are eligible for
+ // the nullable pointer optimization and the
+ // contained type is an `extern fn`
- if variants[0].args.is_empty() {
- data_idx = 1;
- }
+ if variants.len() == 2 {
+ let mut data_idx = 0;
- if variants[data_idx].args.len() == 1 {
- match variants[data_idx].args[0].sty {
- TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
- _ => { }
+ if variants[0].args.is_empty() {
+ data_idx = 1;
+ }
+
+ if variants[data_idx].args.len() == 1 {
+ match variants[data_idx].args[0].sty {
+ TyBareFn(..) => { res = res - TC::ReachesFfiUnsafe; }
+ _ => { }
+ }
}
}
}
}
}
+
+
+ apply_lang_items(cx, did, res)
}
+ TyProjection(..) |
+ TyParam(_) => {
+ TC::All
+ }
- apply_lang_items(cx, did, res)
- }
+ TyInfer(_) |
+ TyError => {
+ cx.sess.bug("asked to compute contents of error type");
+ }
+ };
- TyProjection(..) |
- TyParam(_) => {
- TC::All
- }
+ cache.insert(ty, result);
+ result
+ }
+
+ fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
+ mt: mt<'tcx>,
+ cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
+ {
+ let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
+ mc | tc_ty(cx, mt.ty, cache)
+ }
- TyInfer(_) |
- TyError => {
- cx.sess.bug("asked to compute contents of error type");
+ fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
+ -> TypeContents {
+ if Some(did) == cx.lang_items.unsafe_cell_type() {
+ tc | TC::InteriorUnsafe
+ } else {
+ tc
}
- };
+ }
- cache.insert(ty, result);
- result
+ /// Type contents due to containing a reference with
+ /// the region `region` and borrow kind `bk`.
+ fn borrowed_contents(region: ty::Region,
+ mutbl: ast::Mutability)
+ -> TypeContents {
+ let b = match mutbl {
+ ast::MutMutable => TC::ReachesMutable,
+ ast::MutImmutable => TC::None,
+ };
+ b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
+ }
+
+ fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
+ // These are the type contents of the (opaque) interior. We
+ // make no assumptions (other than that it cannot have an
+ // in-scope type parameter within, which makes no sense).
+ let mut tc = TC::All - TC::InteriorParam;
+ for bound in &bounds.builtin_bounds {
+ tc = tc - match bound {
+ BoundSync | BoundSend | BoundCopy => TC::None,
+ BoundSized => TC::Nonsized,
+ };
+ }
+ return tc;
+ }
}
- fn tc_mt<'tcx>(cx: &ctxt<'tcx>,
- mt: mt<'tcx>,
- cache: &mut FnvHashMap<Ty<'tcx>, TypeContents>) -> TypeContents
+ fn impls_bound<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
+ bound: ty::BuiltinBound,
+ span: Span)
+ -> bool
{
- let mc = TC::ReachesMutable.when(mt.mutbl == MutMutable);
- mc | tc_ty(cx, mt.ty, cache)
- }
+ let infcx = infer::new_infer_ctxt(param_env.tcx());
- fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
- -> TypeContents {
- if Some(did) == cx.lang_items.unsafe_cell_type() {
- tc | TC::InteriorUnsafe
- } else {
- tc
- }
- }
+ let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env,
+ self, bound, span);
- /// Type contents due to containing a reference with the region `region` and borrow kind `bk`
- fn borrowed_contents(region: ty::Region,
- mutbl: ast::Mutability)
- -> TypeContents {
- let b = match mutbl {
- ast::MutMutable => TC::ReachesMutable,
- ast::MutImmutable => TC::None,
- };
- b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
- }
-
- fn object_contents(bounds: &ExistentialBounds) -> TypeContents {
- // These are the type contents of the (opaque) interior. We
- // make no assumptions (other than that it cannot have an
- // in-scope type parameter within, which makes no sense).
- let mut tc = TC::All - TC::InteriorParam;
- for bound in &bounds.builtin_bounds {
- tc = tc - match bound {
- BoundSync | BoundSend | BoundCopy => TC::None,
- BoundSized => TC::Nonsized,
- };
- }
- return tc;
+ debug!("Ty::impls_bound({:?}, {:?}) = {:?}",
+ self, bound, is_impld);
+
+ is_impld
}
-}
-fn type_impls_bound<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
- tcx: &ctxt<'tcx>,
- ty: Ty<'tcx>,
- bound: ty::BuiltinBound,
- span: Span)
- -> bool
-{
- let pe;
- let param_env = match param_env {
- Some(e) => e,
- None => {
- pe = empty_parameter_environment(tcx);
- &pe
+ fn moves_by_default<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
+ span: Span) -> bool {
+ if self.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
+ return self.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
}
- };
- let infcx = infer::new_infer_ctxt(tcx);
- let is_impld = traits::type_known_to_meet_builtin_bound(&infcx, param_env, ty, bound, span);
+ assert!(!self.needs_infer());
- debug!("type_impls_bound({:?}, {:?}) = {:?}",
- ty,
- bound,
- is_impld);
+ // Fast-path for primitive types
+ let result = match self.sty {
+ TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
+ TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt {
+ mutbl: ast::MutImmutable, ..
+ }) => Some(false),
- is_impld
-}
+ TyStr | TyBox(..) | TyRef(_, mt {
+ mutbl: ast::MutMutable, ..
+ }) => Some(true),
-pub fn type_moves_by_default<'a,'tcx>(param_env: &ParameterEnvironment<'a,'tcx>,
- span: Span,
- ty: Ty<'tcx>)
- -> bool
-{
- if ty.flags.get().intersects(TypeFlags::MOVENESS_CACHED) {
- return ty.flags.get().intersects(TypeFlags::MOVES_BY_DEFAULT);
- }
-
- assert!(!ty.needs_infer());
-
- // Fast-path for primitive types
- let result = match ty.sty {
- TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
- TyRawPtr(..) | TyBareFn(..) | TyRef(_, mt {
- mutbl: ast::MutImmutable, ..
- }) => Some(false),
-
- TyStr | TyBox(..) | TyRef(_, mt {
- mutbl: ast::MutMutable, ..
- }) => Some(true),
-
- TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
- TyClosure(..) | TyEnum(..) | TyStruct(..) |
- TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
- }.unwrap_or_else(|| !type_impls_bound(Some(param_env),
- param_env.tcx,
- ty,
- ty::BoundCopy,
- span));
-
- if !ty.has_param_types() && !ty.has_self_ty() {
- ty.flags.set(ty.flags.get() | if result {
- TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
- } else {
- TypeFlags::MOVENESS_CACHED
- });
- }
+ TyArray(..) | TySlice(_) | TyTrait(..) | TyTuple(..) |
+ TyClosure(..) | TyEnum(..) | TyStruct(..) |
+ TyProjection(..) | TyParam(..) | TyInfer(..) | TyError => None
+ }.unwrap_or_else(|| !self.impls_bound(param_env, ty::BoundCopy, span));
- result
-}
+ if !self.has_param_types() && !self.has_self_ty() {
+ self.flags.set(self.flags.get() | if result {
+ TypeFlags::MOVENESS_CACHED | TypeFlags::MOVES_BY_DEFAULT
+ } else {
+ TypeFlags::MOVENESS_CACHED
+ });
+ }
-#[inline]
-pub fn type_is_sized<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
- tcx: &ctxt<'tcx>,
- span: Span,
- ty: Ty<'tcx>)
- -> bool
-{
- if ty.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
- let result = ty.flags.get().intersects(TypeFlags::IS_SIZED);
- return result;
+ result
}
- type_is_sized_uncached(param_env, tcx, span, ty)
-}
+ #[inline]
+ pub fn is_sized<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
+ span: Span) -> bool
+ {
+ if self.flags.get().intersects(TypeFlags::SIZEDNESS_CACHED) {
+ return self.flags.get().intersects(TypeFlags::IS_SIZED);
+ }
-fn type_is_sized_uncached<'a,'tcx>(param_env: Option<&ParameterEnvironment<'a,'tcx>>,
- tcx: &ctxt<'tcx>,
- span: Span,
- ty: Ty<'tcx>) -> bool {
- assert!(!ty.needs_infer());
+ self.is_sized_uncached(param_env, span)
+ }
- // Fast-path for primitive types
- let result = match ty.sty {
- TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
- TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
- TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
+ fn is_sized_uncached<'a>(&'tcx self, param_env: &ParameterEnvironment<'a,'tcx>,
+ span: Span) -> bool {
+ assert!(!self.needs_infer());
- TyStr | TyTrait(..) | TySlice(_) => Some(false),
+ // Fast-path for primitive types
+ let result = match self.sty {
+ TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
+ TyBox(..) | TyRawPtr(..) | TyRef(..) | TyBareFn(..) |
+ TyArray(..) | TyTuple(..) | TyClosure(..) => Some(true),
- TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
- TyInfer(..) | TyError => None
- }.unwrap_or_else(|| type_impls_bound(param_env, tcx, ty, ty::BoundSized, span));
+ TyStr | TyTrait(..) | TySlice(_) => Some(false),
- if !ty.has_param_types() && !ty.has_self_ty() {
- ty.flags.set(ty.flags.get() | if result {
- TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
- } else {
- TypeFlags::SIZEDNESS_CACHED
- });
- }
+ TyEnum(..) | TyStruct(..) | TyProjection(..) | TyParam(..) |
+ TyInfer(..) | TyError => None
+ }.unwrap_or_else(|| self.impls_bound(param_env, ty::BoundSized, span));
- result
-}
+ if !self.has_param_types() && !self.has_self_ty() {
+ self.flags.set(self.flags.get() | if result {
+ TypeFlags::SIZEDNESS_CACHED | TypeFlags::IS_SIZED
+ } else {
+ TypeFlags::SIZEDNESS_CACHED
+ });
+ }
-pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
- !type_contents(cx, ty).intersects(TC::ReachesFfiUnsafe)
-}
+ result
+ }
-// True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
-pub fn is_instantiable<'tcx>(cx: &ctxt<'tcx>, r_ty: Ty<'tcx>) -> bool {
- fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
- r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
- debug!("type_requires({:?}, {:?})?",
- r_ty, ty);
+ pub fn is_ffi_safe(&'tcx self, cx: &ctxt<'tcx>) -> bool {
+ !self.type_contents(cx).intersects(TC::ReachesFfiUnsafe)
+ }
- let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
+ // True if instantiating an instance of `r_ty` requires an instance of `r_ty`.
+ pub fn is_instantiable(&'tcx self, cx: &ctxt<'tcx>) -> bool {
+ fn type_requires<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
+ r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
+ debug!("type_requires({:?}, {:?})?",
+ r_ty, ty);
- debug!("type_requires({:?}, {:?})? {:?}",
- r_ty, ty, r);
- return r;
- }
+ let r = r_ty == ty || subtypes_require(cx, seen, r_ty, ty);
- fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
- r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
- debug!("subtypes_require({:?}, {:?})?",
- r_ty, ty);
+ debug!("type_requires({:?}, {:?})? {:?}",
+ r_ty, ty, r);
+ return r;
+ }
- let r = match ty.sty {
- // fixed length vectors need special treatment compared to
- // normal vectors, since they don't necessarily have the
- // possibility to have length zero.
- TyArray(_, 0) => false, // don't need no contents
- TyArray(ty, _) => type_requires(cx, seen, r_ty, ty),
+ fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
+ r_ty: Ty<'tcx>, ty: Ty<'tcx>) -> bool {
+ debug!("subtypes_require({:?}, {:?})?",
+ r_ty, ty);
- TyBool |
- TyChar |
- TyInt(_) |
- TyUint(_) |
- TyFloat(_) |
- TyStr |
- TyBareFn(..) |
- TyParam(_) |
- TyProjection(_) |
- TySlice(_) => {
- false
- }
- TyBox(typ) => {
- type_requires(cx, seen, r_ty, typ)
- }
- TyRef(_, ref mt) => {
- type_requires(cx, seen, r_ty, mt.ty)
- }
+ let r = match ty.sty {
+ // fixed length vectors need special treatment compared to
+ // normal vectors, since they don't necessarily have the
+ // possibility to have length zero.
+ TyArray(_, 0) => false, // don't need no contents
+ TyArray(ty, _) => type_requires(cx, seen, r_ty, ty),
- TyRawPtr(..) => {
- false // unsafe ptrs can always be NULL
- }
+ TyBool |
+ TyChar |
+ TyInt(_) |
+ TyUint(_) |
+ TyFloat(_) |
+ TyStr |
+ TyBareFn(..) |
+ TyParam(_) |
+ TyProjection(_) |
+ TySlice(_) => {
+ false
+ }
+ TyBox(typ) => {
+ type_requires(cx, seen, r_ty, typ)
+ }
+ TyRef(_, ref mt) => {
+ type_requires(cx, seen, r_ty, mt.ty)
+ }
- TyTrait(..) => {
- false
- }
+ TyRawPtr(..) => {
+ false // unsafe ptrs can always be NULL
+ }
- TyStruct(ref did, _) if seen.contains(did) => {
- false
- }
+ TyTrait(..) => {
+ false
+ }
- TyStruct(did, substs) => {
- seen.push(did);
- let fields = struct_fields(cx, did, substs);
- let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty));
- seen.pop().unwrap();
- r
- }
+ TyStruct(ref did, _) if seen.contains(did) => {
+ false
+ }
- TyError |
- TyInfer(_) |
- TyClosure(..) => {
- // this check is run on type definitions, so we don't expect to see
- // inference by-products or closure types
- cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
- }
+ TyStruct(did, substs) => {
+ seen.push(did);
+ let fields = cx.struct_fields(did, substs);
+ let r = fields.iter().any(|f| type_requires(cx, seen, r_ty, f.mt.ty));
+ seen.pop().unwrap();
+ r
+ }
- TyTuple(ref ts) => {
- ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
- }
+ TyError |
+ TyInfer(_) |
+ TyClosure(..) => {
+ // this check is run on type definitions, so we don't expect to see
+ // inference by-products or closure types
+ cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
+ }
- TyEnum(ref did, _) if seen.contains(did) => {
- false
- }
+ TyTuple(ref ts) => {
+ ts.iter().any(|ty| type_requires(cx, seen, r_ty, *ty))
+ }
- TyEnum(did, substs) => {
- seen.push(did);
- let vs = enum_variants(cx, did);
- let r = !vs.is_empty() && vs.iter().all(|variant| {
- variant.args.iter().any(|aty| {
- let sty = aty.subst(cx, substs);
- type_requires(cx, seen, r_ty, sty)
- })
- });
- seen.pop().unwrap();
- r
- }
- };
+ TyEnum(ref did, _) if seen.contains(did) => {
+ false
+ }
+
+ TyEnum(did, substs) => {
+ seen.push(did);
+ let vs = cx.enum_variants(did);
+ let r = !vs.is_empty() && vs.iter().all(|variant| {
+ variant.args.iter().any(|aty| {
+ let sty = aty.subst(cx, substs);
+ type_requires(cx, seen, r_ty, sty)
+ })
+ });
+ seen.pop().unwrap();
+ r
+ }
+ };
- debug!("subtypes_require({:?}, {:?})? {:?}",
- r_ty, ty, r);
+ debug!("subtypes_require({:?}, {:?})? {:?}",
+ r_ty, ty, r);
- return r;
- }
+ return r;
+ }
- let mut seen = Vec::new();
- !subtypes_require(cx, &mut seen, r_ty, r_ty)
+ let mut seen = Vec::new();
+ !subtypes_require(cx, &mut seen, self, self)
+ }
}
/// Describes whether a type is representable. For types that are not
SelfRecursive,
}
-/// Check whether a type is representable. This means it cannot contain unboxed
-/// structural recursion. This check is needed for structs and enums.
-pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
- -> Representability {
-
- // Iterate until something non-representable is found
- fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
- seen: &mut Vec<Ty<'tcx>>,
- iter: It)
- -> Representability {
- iter.fold(Representable,
- |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
- }
-
- fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
- seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
- -> Representability {
- match ty.sty {
- TyTuple(ref ts) => {
- find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
- }
- // Fixed-length vectors.
- // FIXME(#11924) Behavior undecided for zero-length vectors.
- TyArray(ty, _) => {
- is_type_structurally_recursive(cx, sp, seen, ty)
- }
- TyStruct(did, substs) => {
- let fields = struct_fields(cx, did, substs);
- find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
- }
- TyEnum(did, substs) => {
- let vs = enum_variants(cx, did);
- let iter = vs.iter()
- .flat_map(|variant| &variant.args)
- .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
+impl<'tcx> TyS<'tcx> {
+ /// Check whether a type is representable. This means it cannot contain unboxed
+ /// structural recursion. This check is needed for structs and enums.
+ pub fn is_representable(&'tcx self, cx: &ctxt<'tcx>, sp: Span) -> Representability {
+
+ // Iterate until something non-representable is found
+ fn find_nonrepresentable<'tcx, It: Iterator<Item=Ty<'tcx>>>(cx: &ctxt<'tcx>, sp: Span,
+ seen: &mut Vec<Ty<'tcx>>,
+ iter: It)
+ -> Representability {
+ iter.fold(Representable,
+ |r, ty| cmp::max(r, is_type_structurally_recursive(cx, sp, seen, ty)))
+ }
+
+ fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
+ seen: &mut Vec<Ty<'tcx>>, ty: Ty<'tcx>)
+ -> Representability {
+ match ty.sty {
+ TyTuple(ref ts) => {
+ find_nonrepresentable(cx, sp, seen, ts.iter().cloned())
+ }
+ // Fixed-length vectors.
+ // FIXME(#11924) Behavior undecided for zero-length vectors.
+ TyArray(ty, _) => {
+ is_type_structurally_recursive(cx, sp, seen, ty)
+ }
+ TyStruct(did, substs) => {
+ let fields = cx.struct_fields(did, substs);
+ find_nonrepresentable(cx, sp, seen, fields.iter().map(|f| f.mt.ty))
+ }
+ TyEnum(did, substs) => {
+ let vs = cx.enum_variants(did);
+ let iter = vs.iter()
+ .flat_map(|variant| &variant.args)
+ .map(|aty| { aty.subst_spanned(cx, substs, Some(sp)) });
- find_nonrepresentable(cx, sp, seen, iter)
- }
- TyClosure(..) => {
- // this check is run on type definitions, so we don't expect
- // to see closure types
- cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
+ find_nonrepresentable(cx, sp, seen, iter)
+ }
+ TyClosure(..) => {
+ // this check is run on type definitions, so we don't expect
+ // to see closure types
+ cx.sess.bug(&format!("requires check invoked on inapplicable type: {:?}", ty))
+ }
+ _ => Representable,
}
- _ => Representable,
}
- }
- fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
- match ty.sty {
- TyStruct(ty_did, _) | TyEnum(ty_did, _) => {
- ty_did == did
+ fn same_struct_or_enum_def_id(ty: Ty, did: DefId) -> bool {
+ match ty.sty {
+ TyStruct(ty_did, _) | TyEnum(ty_did, _) => {
+ ty_did == did
+ }
+ _ => false
}
- _ => false
}
- }
- fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
- match (&a.sty, &b.sty) {
- (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
- (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
- if did_a != did_b {
- return false;
- }
+ fn same_type<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
+ match (&a.sty, &b.sty) {
+ (&TyStruct(did_a, ref substs_a), &TyStruct(did_b, ref substs_b)) |
+ (&TyEnum(did_a, ref substs_a), &TyEnum(did_b, ref substs_b)) => {
+ if did_a != did_b {
+ return false;
+ }
- let types_a = substs_a.types.get_slice(subst::TypeSpace);
- let types_b = substs_b.types.get_slice(subst::TypeSpace);
+ let types_a = substs_a.types.get_slice(subst::TypeSpace);
+ let types_b = substs_b.types.get_slice(subst::TypeSpace);
- let mut pairs = types_a.iter().zip(types_b);
+ let mut pairs = types_a.iter().zip(types_b);
- pairs.all(|(&a, &b)| same_type(a, b))
- }
- _ => {
- a == b
+ pairs.all(|(&a, &b)| same_type(a, b))
+ }
+ _ => {
+ a == b
+ }
}
}
- }
- // Does the type `ty` directly (without indirection through a pointer)
- // contain any types on stack `seen`?
- fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
- seen: &mut Vec<Ty<'tcx>>,
- ty: Ty<'tcx>) -> Representability {
- debug!("is_type_structurally_recursive: {:?}", ty);
+ // Does the type `ty` directly (without indirection through a pointer)
+ // contain any types on stack `seen`?
+ fn is_type_structurally_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
+ seen: &mut Vec<Ty<'tcx>>,
+ ty: Ty<'tcx>) -> Representability {
+ debug!("is_type_structurally_recursive: {:?}", ty);
- match ty.sty {
- TyStruct(did, _) | TyEnum(did, _) => {
- {
- // Iterate through stack of previously seen types.
- let mut iter = seen.iter();
-
- // The first item in `seen` is the type we are actually curious about.
- // We want to return SelfRecursive if this type contains itself.
- // It is important that we DON'T take generic parameters into account
- // for this check, so that Bar<T> in this example counts as SelfRecursive:
- //
- // struct Foo;
- // struct Bar<T> { x: Bar<Foo> }
+ match ty.sty {
+ TyStruct(did, _) | TyEnum(did, _) => {
+ {
+ // Iterate through stack of previously seen types.
+ let mut iter = seen.iter();
+
+ // The first item in `seen` is the type we are actually curious about.
+ // We want to return SelfRecursive if this type contains itself.
+ // It is important that we DON'T take generic parameters into account
+ // for this check, so that Bar<T> in this example counts as SelfRecursive:
+ //
+ // struct Foo;
+ // struct Bar<T> { x: Bar<Foo> }
+
+ match iter.next() {
+ Some(&seen_type) => {
+ if same_struct_or_enum_def_id(seen_type, did) {
+ debug!("SelfRecursive: {:?} contains {:?}",
+ seen_type,
+ ty);
+ return SelfRecursive;
+ }
+ }
+ None => {}
+ }
- match iter.next() {
- Some(&seen_type) => {
- if same_struct_or_enum_def_id(seen_type, did) {
- debug!("SelfRecursive: {:?} contains {:?}",
+ // We also need to know whether the first item contains other types
+ // that are structurally recursive. If we don't catch this case, we
+ // will recurse infinitely for some inputs.
+ //
+ // It is important that we DO take generic parameters into account
+ // here, so that code like this is considered SelfRecursive, not
+ // ContainsRecursive:
+ //
+ // struct Foo { Option<Option<Foo>> }
+
+ for &seen_type in iter {
+ if same_type(ty, seen_type) {
+ debug!("ContainsRecursive: {:?} contains {:?}",
seen_type,
ty);
- return SelfRecursive;
+ return ContainsRecursive;
}
}
- None => {}
}
- // We also need to know whether the first item contains other types that
- // are structurally recursive. If we don't catch this case, we will recurse
- // infinitely for some inputs.
- //
- // It is important that we DO take generic parameters into account here,
- // so that code like this is considered SelfRecursive, not ContainsRecursive:
- //
- // struct Foo { Option<Option<Foo>> }
-
- for &seen_type in iter {
- if same_type(ty, seen_type) {
- debug!("ContainsRecursive: {:?} contains {:?}",
- seen_type,
- ty);
- return ContainsRecursive;
- }
- }
+ // For structs and enums, track all previously seen types by pushing them
+ // onto the 'seen' stack.
+ seen.push(ty);
+ let out = are_inner_types_recursive(cx, sp, seen, ty);
+ seen.pop();
+ out
+ }
+ _ => {
+ // No need to push in other cases.
+ are_inner_types_recursive(cx, sp, seen, ty)
}
-
- // For structs and enums, track all previously seen types by pushing them
- // onto the 'seen' stack.
- seen.push(ty);
- let out = are_inner_types_recursive(cx, sp, seen, ty);
- seen.pop();
- out
- }
- _ => {
- // No need to push in other cases.
- are_inner_types_recursive(cx, sp, seen, ty)
}
}
- }
- debug!("is_type_representable: {:?}", ty);
+ debug!("is_type_representable: {:?}", self);
- // To avoid a stack overflow when checking an enum variant or struct that
- // contains a different, structurally recursive type, maintain a stack
- // of seen types and check recursion for each of them (issues #3008, #3779).
- let mut seen: Vec<Ty> = Vec::new();
- let r = is_type_structurally_recursive(cx, sp, &mut seen, ty);
- debug!("is_type_representable: {:?} is {:?}", ty, r);
- r
-}
+ // To avoid a stack overflow when checking an enum variant or struct that
+ // contains a different, structurally recursive type, maintain a stack
+ // of seen types and check recursion for each of them (issues #3008, #3779).
+ let mut seen: Vec<Ty> = Vec::new();
+ let r = is_type_structurally_recursive(cx, sp, &mut seen, self);
+ debug!("is_type_representable: {:?} is {:?}", self, r);
+ r
+ }
-impl<'tcx> TyS<'tcx> {
pub fn is_trait(&self) -> bool {
match self.sty {
TyTrait(..) => true,
pub fn is_c_like_enum(&self, cx: &ctxt) -> bool {
match self.sty {
TyEnum(did, _) => {
- let variants = enum_variants(cx, did);
+ let variants = cx.enum_variants(did);
if variants.is_empty() {
false
} else {
_ => None
}
}
-}
-
-/// Returns the type of element at index `i` in tuple or tuple-like type `t`.
-/// For an enum `t`, `variant` is None only if `t` is a univariant enum.
-pub fn positional_element_ty<'tcx>(cx: &ctxt<'tcx>,
- ty: Ty<'tcx>,
- i: usize,
- variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
-
- match (&ty.sty, variant) {
- (&TyTuple(ref v), None) => v.get(i).cloned(),
-
-
- (&TyStruct(def_id, substs), None) => lookup_struct_fields(cx, def_id)
- .get(i)
- .map(|&t|lookup_item_type(cx, t.id).ty.subst(cx, substs)),
-
- (&TyEnum(def_id, substs), Some(variant_def_id)) => {
- let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
- variant_info.args.get(i).map(|t|t.subst(cx, substs))
- }
-
- (&TyEnum(def_id, substs), None) => {
- assert!(enum_is_univariant(cx, def_id));
- let enum_variants = enum_variants(cx, def_id);
- let variant_info = &(*enum_variants)[0];
- variant_info.args.get(i).map(|t|t.subst(cx, substs))
- }
-
- _ => None
- }
-}
-
-/// Returns the type of element at field `n` in struct or struct-like type `t`.
-/// For an enum `t`, `variant` must be some def id.
-pub fn named_element_ty<'tcx>(cx: &ctxt<'tcx>,
- ty: Ty<'tcx>,
- n: ast::Name,
- variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
-
- match (&ty.sty, variant) {
- (&TyStruct(def_id, substs), None) => {
- let r = lookup_struct_fields(cx, def_id);
- r.iter().find(|f| f.name == n)
- .map(|&f| lookup_field_type(cx, def_id, f.id, substs))
- }
- (&TyEnum(def_id, substs), Some(variant_def_id)) => {
- let variant_info = enum_variant_with_id(cx, def_id, variant_def_id);
- variant_info.arg_names.as_ref()
- .expect("must have struct enum variant if accessing a named fields")
- .iter().zip(&variant_info.args)
- .find(|&(&name, _)| name == n)
- .map(|(_name, arg_t)| arg_t.subst(cx, substs))
- }
- _ => None
- }
-}
-
-pub fn node_id_to_type<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Ty<'tcx> {
- match node_id_to_type_opt(cx, id) {
- Some(ty) => ty,
- None => cx.sess.bug(
- &format!("node_id_to_type: no type for node `{}`",
- cx.map.node_to_string(id)))
- }
-}
-
-pub fn node_id_to_type_opt<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> Option<Ty<'tcx>> {
- match cx.node_types.borrow().get(&id) {
- Some(&ty) => Some(ty),
- None => None
- }
-}
-
-pub fn node_id_item_substs<'tcx>(cx: &ctxt<'tcx>, id: ast::NodeId) -> ItemSubsts<'tcx> {
- match cx.item_substs.borrow().get(&id) {
- None => ItemSubsts::empty(),
- Some(ts) => ts.clone(),
- }
-}
-impl<'tcx> TyS<'tcx> {
pub fn fn_sig(&self) -> &'tcx PolyFnSig<'tcx> {
match self.sty {
TyBareFn(_, ref f) => &f.sig,
_ => false
}
}
-}
-
-pub fn ty_region(tcx: &ctxt,
- span: Span,
- ty: Ty) -> Region {
- match ty.sty {
- TyRef(r, _) => *r,
- ref s => {
- tcx.sess.span_bug(
- span,
- &format!("ty_region() invoked on an inappropriate ty: {:?}",
- s));
- }
- }
-}
-
-// Returns the type of a pattern as a monotype. Like @expr_ty, this function
-// doesn't provide type parameter substitutions.
-pub fn pat_ty<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Ty<'tcx> {
- return node_id_to_type(cx, pat.id);
-}
-pub fn pat_ty_opt<'tcx>(cx: &ctxt<'tcx>, pat: &ast::Pat) -> Option<Ty<'tcx>> {
- return node_id_to_type_opt(cx, pat.id);
-}
-
-
-// Returns the type of an expression as a monotype.
-//
-// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
-// some cases, we insert `AutoAdjustment` annotations such as auto-deref or
-// auto-ref. The type returned by this function does not consider such
-// adjustments. See `expr_ty_adjusted()` instead.
-//
-// NB (2): This type doesn't provide type parameter substitutions; e.g. if you
-// ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
-// instead of "fn(ty) -> T with T = isize".
-pub fn expr_ty<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
- return node_id_to_type(cx, expr.id);
-}
-
-pub fn expr_ty_opt<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Option<Ty<'tcx>> {
- return node_id_to_type_opt(cx, expr.id);
-}
-
-/// Returns the type of `expr`, considering any `AutoAdjustment`
-/// entry recorded for that expression.
-///
-/// It would almost certainly be better to store the adjusted ty in with
-/// the `AutoAdjustment`, but I opted not to do this because it would
-/// require serializing and deserializing the type and, although that's not
-/// hard to do, I just hate that code so much I didn't want to touch it
-/// unless it was to fix it properly, which seemed a distraction from the
-/// thread at hand! -nmatsakis
-pub fn expr_ty_adjusted<'tcx>(cx: &ctxt<'tcx>, expr: &ast::Expr) -> Ty<'tcx> {
- adjust_ty(cx, expr.span, expr.id, expr_ty(cx, expr),
- cx.adjustments.borrow().get(&expr.id),
- |method_call| cx.method_map.borrow().get(&method_call).map(|method| method.ty))
-}
-
-pub fn expr_span(cx: &ctxt, id: NodeId) -> Span {
- match cx.map.find(id) {
- Some(ast_map::NodeExpr(e)) => {
- e.span
- }
- Some(f) => {
- cx.sess.bug(&format!("Node id {} is not an expr: {:?}",
- id,
- f));
- }
- None => {
- cx.sess.bug(&format!("Node id {} is not present \
- in the node map", id));
- }
- }
-}
-pub fn local_var_name_str(cx: &ctxt, id: NodeId) -> InternedString {
- match cx.map.find(id) {
- Some(ast_map::NodeLocal(pat)) => {
- match pat.node {
- ast::PatIdent(_, ref path1, _) => {
- token::get_ident(path1.node)
- }
- _ => {
- cx.sess.bug(
- &format!("Variable id {} maps to {:?}, not local",
- id,
- pat));
- }
- }
- }
- r => {
- cx.sess.bug(&format!("Variable id {} maps to {:?}, not local",
- id,
- r));
+ /// See `expr_ty_adjusted`
+ pub fn adjust<F>(&'tcx self, cx: &ctxt<'tcx>,
+ span: Span,
+ expr_id: ast::NodeId,
+ adjustment: Option<&AutoAdjustment<'tcx>>,
+ mut method_type: F)
+ -> Ty<'tcx> where
+ F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
+ {
+ if let TyError = self.sty {
+ return self;
}
- }
-}
-
-/// See `expr_ty_adjusted`
-pub fn adjust_ty<'tcx, F>(cx: &ctxt<'tcx>,
- span: Span,
- expr_id: ast::NodeId,
- unadjusted_ty: Ty<'tcx>,
- adjustment: Option<&AutoAdjustment<'tcx>>,
- mut method_type: F)
- -> Ty<'tcx> where
- F: FnMut(MethodCall) -> Option<Ty<'tcx>>,
-{
- if let TyError = unadjusted_ty.sty {
- return unadjusted_ty;
- }
- return match adjustment {
- Some(adjustment) => {
- match *adjustment {
- AdjustReifyFnPointer => {
- match unadjusted_ty.sty {
- ty::TyBareFn(Some(_), b) => {
- cx.mk_fn(None, b)
- }
- _ => {
- cx.sess.bug(
- &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
- {:?}", unadjusted_ty));
+ return match adjustment {
+ Some(adjustment) => {
+ match *adjustment {
+ AdjustReifyFnPointer => {
+ match self.sty {
+ ty::TyBareFn(Some(_), b) => {
+ cx.mk_fn(None, b)
+ }
+ _ => {
+ cx.sess.bug(
+ &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
+ {:?}", self));
+ }
}
}
- }
- AdjustUnsafeFnPointer => {
- match unadjusted_ty.sty {
- ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
- ref b => {
- cx.sess.bug(
- &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
- {:?}",
- b));
+ AdjustUnsafeFnPointer => {
+ match self.sty {
+ ty::TyBareFn(None, b) => cx.safe_to_unsafe_fn_ty(b),
+ ref b => {
+ cx.sess.bug(
+ &format!("AdjustReifyFnPointer adjustment on non-fn-item: \
+ {:?}",
+ b));
+ }
}
- }
- }
-
- AdjustDerefRef(ref adj) => {
- let mut adjusted_ty = unadjusted_ty;
-
- if !adjusted_ty.references_error() {
- for i in 0..adj.autoderefs {
- let method_call = MethodCall::autoderef(expr_id, i as u32);
- match method_type(method_call) {
- Some(method_ty) => {
- // Overloaded deref operators have all late-bound
- // regions fully instantiated and coverge.
- let fn_ret =
- ty::no_late_bound_regions(cx,
- &method_ty.fn_ret()).unwrap();
- adjusted_ty = fn_ret.unwrap();
+ }
+
+ AdjustDerefRef(ref adj) => {
+ let mut adjusted_ty = self;
+
+ if !adjusted_ty.references_error() {
+ for i in 0..adj.autoderefs {
+ let method_call = MethodCall::autoderef(expr_id, i as u32);
+ match method_type(method_call) {
+ Some(method_ty) => {
+ // Overloaded deref operators have all late-bound
+ // regions fully instantiated and coverge.
+ let fn_ret =
+ cx.no_late_bound_regions(&method_ty.fn_ret()).unwrap();
+ adjusted_ty = fn_ret.unwrap();
+ }
+ None => {}
}
- None => {}
- }
- match adjusted_ty.builtin_deref(true) {
- Some(mt) => { adjusted_ty = mt.ty; }
- None => {
- cx.sess.span_bug(
- span,
- &format!("the {}th autoderef failed: {}",
- i,
- adjusted_ty)
- );
+ match adjusted_ty.builtin_deref(true) {
+ Some(mt) => { adjusted_ty = mt.ty; }
+ None => {
+ cx.sess.span_bug(
+ span,
+ &format!("the {}th autoderef failed: {}",
+ i,
+ adjusted_ty)
+ );
+ }
}
}
}
- }
- if let Some(target) = adj.unsize {
- target
- } else {
- adjust_ty_for_autoref(cx, adjusted_ty, adj.autoref)
+ if let Some(target) = adj.unsize {
+ target
+ } else {
+ adjusted_ty.adjust_for_autoref(cx, adj.autoref)
+ }
}
}
}
- }
- None => unadjusted_ty
- };
-}
-
-pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
- ty: Ty<'tcx>,
- autoref: Option<AutoRef<'tcx>>)
- -> Ty<'tcx> {
- match autoref {
- None => ty,
- Some(AutoPtr(r, m)) => {
- cx.mk_ref(r, mt { ty: ty, mutbl: m })
- }
- Some(AutoUnsafe(m)) => {
- cx.mk_ptr(mt { ty: ty, mutbl: m })
- }
+ None => self
+ };
}
-}
-pub fn resolve_expr(tcx: &ctxt, expr: &ast::Expr) -> def::Def {
- match tcx.def_map.borrow().get(&expr.id) {
- Some(def) => def.full_def(),
- None => {
- tcx.sess.span_bug(expr.span, &format!(
- "no def-map entry for expr {}", expr.id));
+ pub fn adjust_for_autoref(&'tcx self, cx: &ctxt<'tcx>,
+ autoref: Option<AutoRef<'tcx>>)
+ -> Ty<'tcx> {
+ match autoref {
+ None => self,
+ Some(AutoPtr(r, m)) => {
+ cx.mk_ref(r, mt { ty: self, mutbl: m })
+ }
+ Some(AutoUnsafe(m)) => {
+ cx.mk_ptr(mt { ty: self, mutbl: m })
+ }
}
}
-}
-pub fn expr_is_lval(tcx: &ctxt, expr: &ast::Expr) -> bool {
- match expr.node {
- ast::ExprPath(..) => {
- // We can't use resolve_expr here, as this needs to run on broken
- // programs. We don't need to through - associated items are all
- // rvalues.
- match tcx.def_map.borrow().get(&expr.id) {
- Some(&def::PathResolution {
- base_def: def::DefStatic(..), ..
- }) | Some(&def::PathResolution {
- base_def: def::DefUpvar(..), ..
- }) | Some(&def::PathResolution {
- base_def: def::DefLocal(..), ..
- }) => {
- true
+ fn sort_string(&self, cx: &ctxt) -> String {
+ match self.sty {
+ TyBool | TyChar | TyInt(_) |
+ TyUint(_) | TyFloat(_) | TyStr => self.to_string(),
+ TyTuple(ref tys) if tys.is_empty() => self.to_string(),
+
+ TyEnum(id, _) => format!("enum `{}`", cx.item_path_str(id)),
+ TyBox(_) => "box".to_string(),
+ TyArray(_, n) => format!("array of {} elements", n),
+ TySlice(_) => "slice".to_string(),
+ TyRawPtr(_) => "*-ptr".to_string(),
+ TyRef(_, _) => "&-ptr".to_string(),
+ TyBareFn(Some(_), _) => format!("fn item"),
+ TyBareFn(None, _) => "fn pointer".to_string(),
+ TyTrait(ref inner) => {
+ format!("trait {}", cx.item_path_str(inner.principal_def_id()))
+ }
+ TyStruct(id, _) => {
+ format!("struct `{}`", cx.item_path_str(id))
+ }
+ TyClosure(..) => "closure".to_string(),
+ TyTuple(_) => "tuple".to_string(),
+ TyInfer(TyVar(_)) => "inferred type".to_string(),
+ TyInfer(IntVar(_)) => "integral variable".to_string(),
+ TyInfer(FloatVar(_)) => "floating-point variable".to_string(),
+ TyInfer(FreshTy(_)) => "skolemized type".to_string(),
+ TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(),
+ TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
+ TyProjection(_) => "associated type".to_string(),
+ TyParam(ref p) => {
+ if p.space == subst::SelfSpace {
+ "Self".to_string()
+ } else {
+ "type parameter".to_string()
}
-
- Some(..) => false,
-
- None => tcx.sess.span_bug(expr.span, &format!(
- "no def for path {}", expr.id))
- }
- }
-
- ast::ExprUnary(ast::UnDeref, _) |
- ast::ExprField(..) |
- ast::ExprTupField(..) |
- ast::ExprIndex(..) => {
- true
- }
-
- ast::ExprCall(..) |
- ast::ExprMethodCall(..) |
- ast::ExprStruct(..) |
- ast::ExprRange(..) |
- ast::ExprTup(..) |
- ast::ExprIf(..) |
- ast::ExprMatch(..) |
- ast::ExprClosure(..) |
- ast::ExprBlock(..) |
- ast::ExprRepeat(..) |
- ast::ExprVec(..) |
- ast::ExprBreak(..) |
- ast::ExprAgain(..) |
- ast::ExprRet(..) |
- ast::ExprWhile(..) |
- ast::ExprLoop(..) |
- ast::ExprAssign(..) |
- ast::ExprInlineAsm(..) |
- ast::ExprAssignOp(..) |
- ast::ExprLit(_) |
- ast::ExprUnary(..) |
- ast::ExprBox(..) |
- ast::ExprAddrOf(..) |
- ast::ExprBinary(..) |
- ast::ExprCast(..) => {
- false
- }
-
- ast::ExprParen(ref e) => expr_is_lval(tcx, e),
-
- ast::ExprIfLet(..) |
- ast::ExprWhileLet(..) |
- ast::ExprForLoop(..) |
- ast::ExprMac(..) => {
- tcx.sess.span_bug(
- expr.span,
- "macro expression remains after expansion");
- }
- }
-}
-
-pub fn field_idx_strict(tcx: &ctxt, name: ast::Name, fields: &[field])
- -> usize {
- let mut i = 0;
- for f in fields { if f.name == name { return i; } i += 1; }
- tcx.sess.bug(&format!(
- "no field named `{}` found in the list of fields `{:?}`",
- token::get_name(name),
- fields.iter()
- .map(|f| token::get_name(f.name).to_string())
- .collect::<Vec<String>>()));
-}
-
-pub fn ty_sort_string(cx: &ctxt, ty: Ty) -> String {
- match ty.sty {
- TyBool | TyChar | TyInt(_) |
- TyUint(_) | TyFloat(_) | TyStr => ty.to_string(),
- TyTuple(ref tys) if tys.is_empty() => ty.to_string(),
-
- TyEnum(id, _) => format!("enum `{}`", item_path_str(cx, id)),
- TyBox(_) => "box".to_string(),
- TyArray(_, n) => format!("array of {} elements", n),
- TySlice(_) => "slice".to_string(),
- TyRawPtr(_) => "*-ptr".to_string(),
- TyRef(_, _) => "&-ptr".to_string(),
- TyBareFn(Some(_), _) => format!("fn item"),
- TyBareFn(None, _) => "fn pointer".to_string(),
- TyTrait(ref inner) => {
- format!("trait {}", item_path_str(cx, inner.principal_def_id()))
- }
- TyStruct(id, _) => {
- format!("struct `{}`", item_path_str(cx, id))
- }
- TyClosure(..) => "closure".to_string(),
- TyTuple(_) => "tuple".to_string(),
- TyInfer(TyVar(_)) => "inferred type".to_string(),
- TyInfer(IntVar(_)) => "integral variable".to_string(),
- TyInfer(FloatVar(_)) => "floating-point variable".to_string(),
- TyInfer(FreshTy(_)) => "skolemized type".to_string(),
- TyInfer(FreshIntTy(_)) => "skolemized integral type".to_string(),
- TyInfer(FreshFloatTy(_)) => "skolemized floating-point type".to_string(),
- TyProjection(_) => "associated type".to_string(),
- TyParam(ref p) => {
- if p.space == subst::SelfSpace {
- "Self".to_string()
- } else {
- "type parameter".to_string()
}
+ TyError => "type error".to_string(),
}
- TyError => "type error".to_string(),
}
}
-
/// Explains the source of a type err in a short, human readable way. This is meant to be placed
/// in parentheses after some larger message. You should also invoke `note_and_explain_type_err()`
/// afterwards to present additional details, particularly when it comes to lifetime-related
terr_sorts(values) => tls::with(|tcx| {
// A naive approach to making sure that we're not reporting silly errors such as:
// (expected closure, found closure).
- let expected_str = ty_sort_string(tcx, values.expected);
- let found_str = ty_sort_string(tcx, values.found);
+ let expected_str = values.expected.sort_string(tcx);
+ let found_str = values.found.sort_string(tcx);
if expected_str == found_str {
write!(f, "expected {}, found a different {}", expected_str, found_str)
} else {
}),
terr_traits(values) => tls::with(|tcx| {
write!(f, "expected trait `{}`, found trait `{}`",
- item_path_str(tcx, values.expected),
- item_path_str(tcx, values.found))
+ tcx.item_path_str(values.expected),
+ tcx.item_path_str(values.found))
}),
terr_builtin_bounds(values) => {
if values.expected.is_empty() {
}
}
-pub fn note_and_explain_type_err<'tcx>(cx: &ctxt<'tcx>, err: &type_err<'tcx>, sp: Span) {
- match *err {
- terr_regions_does_not_outlive(subregion, superregion) => {
- note_and_explain_region(cx, "", subregion, "...");
- note_and_explain_region(cx, "...does not necessarily outlive ",
- superregion, "");
- }
- terr_regions_not_same(region1, region2) => {
- note_and_explain_region(cx, "", region1, "...");
- note_and_explain_region(cx, "...is not the same lifetime as ",
- region2, "");
- }
- terr_regions_no_overlap(region1, region2) => {
- note_and_explain_region(cx, "", region1, "...");
- note_and_explain_region(cx, "...does not overlap ",
- region2, "");
- }
- terr_regions_insufficiently_polymorphic(_, conc_region) => {
- note_and_explain_region(cx,
- "concrete lifetime that was found is ",
- conc_region, "");
- }
- terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
- // don't bother to print out the message below for
- // inference variables, it's not very illuminating.
- }
- terr_regions_overly_polymorphic(_, conc_region) => {
- note_and_explain_region(cx,
- "expected concrete lifetime is ",
- conc_region, "");
- }
- terr_sorts(values) => {
- let expected_str = ty_sort_string(cx, values.expected);
- let found_str = ty_sort_string(cx, values.found);
- if expected_str == found_str && expected_str == "closure" {
- cx.sess.span_note(sp, &format!("no two closures, even if identical, have the same \
- type"));
- cx.sess.span_help(sp, &format!("consider boxing your closure and/or \
- using it as a trait object"));
- }
- }
- _ => {}
- }
-}
-
-pub fn provided_source(cx: &ctxt, id: ast::DefId) -> Option<ast::DefId> {
- cx.provided_method_sources.borrow().get(&id).cloned()
-}
-
-pub fn provided_trait_methods<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> Vec<Rc<Method<'tcx>>> {
- if is_local(id) {
- if let ItemTrait(_, _, _, ref ms) = cx.map.expect_item(id.node).node {
- ms.iter().filter_map(|ti| {
- if let ast::MethodTraitItem(_, Some(_)) = ti.node {
- match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
- MethodTraitItem(m) => Some(m),
- _ => {
- cx.sess.bug("provided_trait_methods(): \
- non-method item found from \
- looking up provided method?!")
- }
- }
- } else {
- None
- }
- }).collect()
- } else {
- cx.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
- }
- } else {
- csearch::get_provided_trait_methods(cx, id)
- }
-}
-
-pub fn associated_consts<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> Vec<Rc<AssociatedConst<'tcx>>> {
- if is_local(id) {
- match cx.map.expect_item(id.node).node {
- ItemTrait(_, _, _, ref tis) => {
- tis.iter().filter_map(|ti| {
- if let ast::ConstTraitItem(_, _) = ti.node {
- match impl_or_trait_item(cx, ast_util::local_def(ti.id)) {
- ConstTraitItem(ac) => Some(ac),
- _ => {
- cx.sess.bug("associated_consts(): \
- non-const item found from \
- looking up a constant?!")
- }
- }
- } else {
- None
- }
- }).collect()
- }
- ItemImpl(_, _, _, _, _, ref iis) => {
- iis.iter().filter_map(|ii| {
- if let ast::ConstImplItem(_, _) = ii.node {
- match impl_or_trait_item(cx, ast_util::local_def(ii.id)) {
- ConstTraitItem(ac) => Some(ac),
- _ => {
- cx.sess.bug("associated_consts(): \
- non-const item found from \
- looking up a constant?!")
- }
- }
- } else {
- None
- }
- }).collect()
- }
- _ => {
- cx.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
- or impl", id))
- }
- }
- } else {
- csearch::get_associated_consts(cx, id)
- }
-}
-
/// Helper for looking things up in the various maps that are populated during
/// typeck::collect (e.g., `cx.impl_or_trait_items`, `cx.tcache`, etc). All of
/// these share the pattern that if the id is local, it should have been loaded
v
}
-pub fn trait_item<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId, idx: usize)
- -> ImplOrTraitItem<'tcx> {
- let method_def_id = (*ty::trait_item_def_ids(cx, trait_did))[idx].def_id();
- impl_or_trait_item(cx, method_def_id)
-}
-
-pub fn trait_items<'tcx>(cx: &ctxt<'tcx>, trait_did: ast::DefId)
- -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
- let mut trait_items = cx.trait_items_cache.borrow_mut();
- match trait_items.get(&trait_did).cloned() {
- Some(trait_items) => trait_items,
- None => {
- let def_ids = ty::trait_item_def_ids(cx, trait_did);
- let items: Rc<Vec<ImplOrTraitItem>> =
- Rc::new(def_ids.iter()
- .map(|d| impl_or_trait_item(cx, d.def_id()))
- .collect());
- trait_items.insert(trait_did, items.clone());
- items
- }
- }
-}
-
-pub fn trait_impl_polarity<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> Option<ast::ImplPolarity> {
- if id.krate == ast::LOCAL_CRATE {
- match cx.map.find(id.node) {
- Some(ast_map::NodeItem(item)) => {
- match item.node {
- ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
- _ => None
- }
- }
- _ => None
- }
- } else {
- csearch::get_impl_polarity(cx, id)
- }
-}
-
-pub fn custom_coerce_unsized_kind<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
- -> CustomCoerceUnsized {
- memoized(&cx.custom_coerce_unsized_kinds, did, |did: DefId| {
- let (kind, src) = if did.krate != ast::LOCAL_CRATE {
- (csearch::get_custom_coerce_unsized_kind(cx, did), "external")
- } else {
- (None, "local")
- };
-
- match kind {
- Some(kind) => kind,
- None => {
- cx.sess.bug(&format!("custom_coerce_unsized_kind: \
- {} impl `{}` is missing its kind",
- src, item_path_str(cx, did)));
- }
- }
- })
-}
-
-pub fn impl_or_trait_item<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> ImplOrTraitItem<'tcx> {
- lookup_locally_or_in_crate_store(
- "impl_or_trait_items", id, &cx.impl_or_trait_items,
- || csearch::get_impl_or_trait_item(cx, id))
-}
-
-/// Returns the parameter index that the given associated type corresponds to.
-pub fn associated_type_parameter_index(cx: &ctxt,
- trait_def: &TraitDef,
- associated_type_id: ast::DefId)
- -> usize {
- for type_parameter_def in &trait_def.generics.types {
- if type_parameter_def.def_id == associated_type_id {
- return type_parameter_def.index as usize
+impl BorrowKind {
+ pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
+ match m {
+ ast::MutMutable => MutBorrow,
+ ast::MutImmutable => ImmBorrow,
}
}
- cx.sess.bug("couldn't find associated type parameter index")
-}
-
-pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId)
- -> Rc<Vec<ImplOrTraitItemId>> {
- lookup_locally_or_in_crate_store(
- "trait_item_def_ids", id, &cx.trait_item_def_ids,
- || Rc::new(csearch::get_trait_item_def_ids(&cx.sess.cstore, id)))
-}
-/// Returns the trait-ref corresponding to a given impl, or None if it is
-/// an inherent impl.
-pub fn impl_trait_ref<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> Option<TraitRef<'tcx>>
-{
- lookup_locally_or_in_crate_store(
- "impl_trait_refs", id, &cx.impl_trait_refs,
- || csearch::get_impl_trait(cx, id))
-}
-
-/// Returns whether this DefId refers to an impl
-pub fn is_impl<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId) -> bool {
- if id.krate == ast::LOCAL_CRATE {
- if let Some(ast_map::NodeItem(
- &ast::Item { node: ast::ItemImpl(..), .. })) = cx.map.find(id.node) {
- true
- } else {
- false
+ /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
+ /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
+ /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
+ /// question.
+ pub fn to_mutbl_lossy(self) -> ast::Mutability {
+ match self {
+ MutBorrow => ast::MutMutable,
+ ImmBorrow => ast::MutImmutable,
+
+ // We have no type corresponding to a unique imm borrow, so
+ // use `&mut`. It gives all the capabilities of an `&uniq`
+ // and hence is a safe "over approximation".
+ UniqueImmBorrow => ast::MutMutable,
}
- } else {
- csearch::is_impl(&cx.sess.cstore, id)
}
-}
-pub fn trait_ref_to_def_id(tcx: &ctxt, tr: &ast::TraitRef) -> ast::DefId {
- tcx.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
-}
-
-pub fn try_add_builtin_trait(
- tcx: &ctxt,
- trait_def_id: ast::DefId,
- builtin_bounds: &mut EnumSet<BuiltinBound>)
- -> bool
-{
- //! Checks whether `trait_ref` refers to one of the builtin
- //! traits, like `Send`, and adds the corresponding
- //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
- //! is a builtin trait.
-
- match tcx.lang_items.to_builtin_kind(trait_def_id) {
- Some(bound) => { builtin_bounds.insert(bound); true }
- None => false
- }
-}
-
-pub fn ty_to_def_id(ty: Ty) -> Option<ast::DefId> {
- match ty.sty {
- TyTrait(ref tt) =>
- Some(tt.principal_def_id()),
- TyStruct(id, _) |
- TyEnum(id, _) |
- TyClosure(id, _) =>
- Some(id),
- _ =>
- None
+ pub fn to_user_str(&self) -> &'static str {
+ match *self {
+ MutBorrow => "mutable",
+ ImmBorrow => "immutable",
+ UniqueImmBorrow => "uniquely immutable",
+ }
}
}
-// Enum information
-#[derive(Clone)]
-pub struct VariantInfo<'tcx> {
- pub args: Vec<Ty<'tcx>>,
- pub arg_names: Option<Vec<ast::Name>>,
- pub ctor_ty: Option<Ty<'tcx>>,
- pub name: ast::Name,
- pub id: ast::DefId,
- pub disr_val: Disr,
- pub vis: Visibility
-}
+impl<'tcx> ctxt<'tcx> {
+ /// Returns the type of element at index `i` in tuple or tuple-like type `t`.
+ /// For an enum `t`, `variant` is None only if `t` is a univariant enum.
+ pub fn positional_element_ty(&self,
+ ty: Ty<'tcx>,
+ i: usize,
+ variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
-impl<'tcx> VariantInfo<'tcx> {
+ match (&ty.sty, variant) {
+ (&TyTuple(ref v), None) => v.get(i).cloned(),
- /// Creates a new VariantInfo from the corresponding ast representation.
- ///
- /// Does not do any caching of the value in the type context.
- pub fn from_ast_variant(cx: &ctxt<'tcx>,
- ast_variant: &ast::Variant,
- discriminant: Disr) -> VariantInfo<'tcx> {
- let ctor_ty = node_id_to_type(cx, ast_variant.node.id);
- match ast_variant.node.kind {
- ast::TupleVariantKind(ref args) => {
- let arg_tys = if !args.is_empty() {
- // the regions in the argument types come from the
- // enum def'n, and hence will all be early bound
- ty::no_late_bound_regions(cx, &ctor_ty.fn_args()).unwrap()
- } else {
- Vec::new()
- };
+ (&TyStruct(def_id, substs), None) => self.lookup_struct_fields(def_id)
+ .get(i)
+ .map(|&t| self.lookup_item_type(t.id).ty.subst(self, substs)),
- return VariantInfo {
- args: arg_tys,
- arg_names: None,
- ctor_ty: Some(ctor_ty),
- name: ast_variant.node.name.name,
- id: ast_util::local_def(ast_variant.node.id),
- disr_val: discriminant,
- vis: ast_variant.node.vis
- };
- },
- ast::StructVariantKind(ref struct_def) => {
- let fields: &[StructField] = &struct_def.fields;
+ (&TyEnum(def_id, substs), Some(variant_def_id)) => {
+ let variant_info = self.enum_variant_with_id(def_id, variant_def_id);
+ variant_info.args.get(i).map(|t|t.subst(self, substs))
+ }
- assert!(!fields.is_empty());
+ (&TyEnum(def_id, substs), None) => {
+ assert!(self.enum_is_univariant(def_id));
+ let enum_variants = self.enum_variants(def_id);
+ let variant_info = &enum_variants[0];
+ variant_info.args.get(i).map(|t|t.subst(self, substs))
+ }
- let arg_tys = struct_def.fields.iter()
- .map(|field| node_id_to_type(cx, field.node.id)).collect();
- let arg_names = fields.iter().map(|field| {
- match field.node.kind {
- NamedField(ident, _) => ident.name,
- UnnamedField(..) => cx.sess.bug(
- "enum_variants: all fields in struct must have a name")
- }
- }).collect();
+ _ => None
+ }
+ }
- return VariantInfo {
- args: arg_tys,
- arg_names: Some(arg_names),
- ctor_ty: None,
- name: ast_variant.node.name.name,
- id: ast_util::local_def(ast_variant.node.id),
- disr_val: discriminant,
- vis: ast_variant.node.vis
- };
+ /// Returns the type of element at field `n` in struct or struct-like type `t`.
+ /// For an enum `t`, `variant` must be some def id.
+ pub fn named_element_ty(&self,
+ ty: Ty<'tcx>,
+ n: ast::Name,
+ variant: Option<ast::DefId>) -> Option<Ty<'tcx>> {
+
+ match (&ty.sty, variant) {
+ (&TyStruct(def_id, substs), None) => {
+ let r = self.lookup_struct_fields(def_id);
+ r.iter().find(|f| f.name == n)
+ .map(|&f| self.lookup_field_type(def_id, f.id, substs))
}
+ (&TyEnum(def_id, substs), Some(variant_def_id)) => {
+ let variant_info = self.enum_variant_with_id(def_id, variant_def_id);
+ variant_info.arg_names.as_ref()
+ .expect("must have struct enum variant if accessing a named fields")
+ .iter().zip(&variant_info.args)
+ .find(|&(&name, _)| name == n)
+ .map(|(_name, arg_t)| arg_t.subst(self, substs))
+ }
+ _ => None
}
}
-}
-
-pub fn substd_enum_variants<'tcx>(cx: &ctxt<'tcx>,
- id: ast::DefId,
- substs: &Substs<'tcx>)
- -> Vec<Rc<VariantInfo<'tcx>>> {
- enum_variants(cx, id).iter().map(|variant_info| {
- let substd_args = variant_info.args.iter()
- .map(|aty| aty.subst(cx, substs)).collect::<Vec<_>>();
- let substd_ctor_ty = variant_info.ctor_ty.subst(cx, substs);
+ pub fn node_id_to_type(&self, id: ast::NodeId) -> Ty<'tcx> {
+ match self.node_id_to_type_opt(id) {
+ Some(ty) => ty,
+ None => self.sess.bug(
+ &format!("node_id_to_type: no type for node `{}`",
+ self.map.node_to_string(id)))
+ }
+ }
- Rc::new(VariantInfo {
- args: substd_args,
- ctor_ty: substd_ctor_ty,
- ..(**variant_info).clone()
- })
- }).collect()
-}
+ pub fn node_id_to_type_opt(&self, id: ast::NodeId) -> Option<Ty<'tcx>> {
+ self.node_types.borrow().get(&id).cloned()
+ }
-pub fn item_path_str(cx: &ctxt, id: ast::DefId) -> String {
- with_path(cx, id, |path| ast_map::path_to_string(path)).to_string()
-}
+ pub fn node_id_item_substs(&self, id: ast::NodeId) -> ItemSubsts<'tcx> {
+ match self.item_substs.borrow().get(&id) {
+ None => ItemSubsts::empty(),
+ Some(ts) => ts.clone(),
+ }
+ }
-#[derive(Copy, Clone)]
-pub enum DtorKind {
- NoDtor,
- TraitDtor(DefId, bool)
-}
+ // Returns the type of a pattern as a monotype. Like @expr_ty, this function
+ // doesn't provide type parameter substitutions.
+ pub fn pat_ty(&self, pat: &ast::Pat) -> Ty<'tcx> {
+ self.node_id_to_type(pat.id)
+ }
+ pub fn pat_ty_opt(&self, pat: &ast::Pat) -> Option<Ty<'tcx>> {
+ self.node_id_to_type_opt(pat.id)
+ }
-impl DtorKind {
- pub fn is_present(&self) -> bool {
- match *self {
- TraitDtor(..) => true,
- _ => false
- }
+ // Returns the type of an expression as a monotype.
+ //
+ // NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
+ // some cases, we insert `AutoAdjustment` annotations such as auto-deref or
+ // auto-ref. The type returned by this function does not consider such
+ // adjustments. See `expr_ty_adjusted()` instead.
+ //
+ // NB (2): This type doesn't provide type parameter substitutions; e.g. if you
+ // ask for the type of "id" in "id(3)", it will return "fn(&isize) -> isize"
+ // instead of "fn(ty) -> T with T = isize".
+ pub fn expr_ty(&self, expr: &ast::Expr) -> Ty<'tcx> {
+ self.node_id_to_type(expr.id)
}
- pub fn has_drop_flag(&self) -> bool {
- match self {
- &NoDtor => false,
- &TraitDtor(_, flag) => flag
- }
+ pub fn expr_ty_opt(&self, expr: &ast::Expr) -> Option<Ty<'tcx>> {
+ self.node_id_to_type_opt(expr.id)
}
-}
-/* If struct_id names a struct with a dtor. */
-pub fn ty_dtor(cx: &ctxt, struct_id: DefId) -> DtorKind {
- match cx.destructor_for_type.borrow().get(&struct_id) {
- Some(&method_def_id) => {
- let flag = !has_attr(cx, struct_id, "unsafe_no_drop_flag");
+ /// Returns the type of `expr`, considering any `AutoAdjustment`
+ /// entry recorded for that expression.
+ ///
+ /// It would almost certainly be better to store the adjusted ty in with
+ /// the `AutoAdjustment`, but I opted not to do this because it would
+ /// require serializing and deserializing the type and, although that's not
+ /// hard to do, I just hate that code so much I didn't want to touch it
+ /// unless it was to fix it properly, which seemed a distraction from the
+ /// thread at hand! -nmatsakis
+ pub fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx> {
+ self.expr_ty(expr)
+ .adjust(self, expr.span, expr.id,
+ self.adjustments.borrow().get(&expr.id),
+ |method_call| {
+ self.method_map.borrow().get(&method_call).map(|method| method.ty)
+ })
+ }
- TraitDtor(method_def_id, flag)
+ pub fn expr_span(&self, id: NodeId) -> Span {
+ match self.map.find(id) {
+ Some(ast_map::NodeExpr(e)) => {
+ e.span
+ }
+ Some(f) => {
+ self.sess.bug(&format!("Node id {} is not an expr: {:?}",
+ id, f));
+ }
+ None => {
+ self.sess.bug(&format!("Node id {} is not present \
+ in the node map", id));
+ }
}
- None => NoDtor,
}
-}
-pub fn has_dtor(cx: &ctxt, struct_id: DefId) -> bool {
- cx.destructor_for_type.borrow().contains_key(&struct_id)
-}
-
-pub fn with_path<T, F>(cx: &ctxt, id: ast::DefId, f: F) -> T where
- F: FnOnce(ast_map::PathElems) -> T,
-{
- if id.krate == ast::LOCAL_CRATE {
- cx.map.with_path(id.node, f)
- } else {
- f(csearch::get_item_path(cx, id).iter().cloned().chain(LinkedPath::empty()))
+ pub fn local_var_name_str(&self, id: NodeId) -> InternedString {
+ match self.map.find(id) {
+ Some(ast_map::NodeLocal(pat)) => {
+ match pat.node {
+ ast::PatIdent(_, ref path1, _) => {
+ token::get_ident(path1.node)
+ }
+ _ => {
+ self.sess.bug(&format!("Variable id {} maps to {:?}, not local",
+ id, pat));
+ }
+ }
+ }
+ r => {
+ self.sess.bug(&format!("Variable id {} maps to {:?}, not local",
+ id, r));
+ }
+ }
}
-}
-pub fn enum_is_univariant(cx: &ctxt, id: ast::DefId) -> bool {
- enum_variants(cx, id).len() == 1
-}
+ pub fn resolve_expr(&self, expr: &ast::Expr) -> def::Def {
+ match self.def_map.borrow().get(&expr.id) {
+ Some(def) => def.full_def(),
+ None => {
+ self.sess.span_bug(expr.span, &format!(
+ "no def-map entry for expr {}", expr.id));
+ }
+ }
+ }
+
+ pub fn expr_is_lval(&self, expr: &ast::Expr) -> bool {
+ match expr.node {
+ ast::ExprPath(..) => {
+ // We can't use resolve_expr here, as this needs to run on broken
+ // programs. We don't need to through - associated items are all
+ // rvalues.
+ match self.def_map.borrow().get(&expr.id) {
+ Some(&def::PathResolution {
+ base_def: def::DefStatic(..), ..
+ }) | Some(&def::PathResolution {
+ base_def: def::DefUpvar(..), ..
+ }) | Some(&def::PathResolution {
+ base_def: def::DefLocal(..), ..
+ }) => {
+ true
+ }
-pub fn type_is_empty(cx: &ctxt, ty: Ty) -> bool {
- match ty.sty {
- TyEnum(did, _) => (*enum_variants(cx, did)).is_empty(),
- _ => false
- }
-}
+ Some(..) => false,
-trait IntTypeExt {
- fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx>;
- fn i64_to_disr(&self, val: i64) -> Option<Disr>;
- fn u64_to_disr(&self, val: u64) -> Option<Disr>;
- fn disr_incr(&self, val: Disr) -> Option<Disr>;
- fn disr_string(&self, val: Disr) -> String;
- fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr;
-}
+ None => self.sess.span_bug(expr.span, &format!(
+ "no def for path {}", expr.id))
+ }
+ }
-impl IntTypeExt for attr::IntType {
- fn to_ty<'tcx>(&self, cx: &ctxt<'tcx>) -> Ty<'tcx> {
- match *self {
- SignedInt(ast::TyI8) => cx.types.i8,
- SignedInt(ast::TyI16) => cx.types.i16,
- SignedInt(ast::TyI32) => cx.types.i32,
- SignedInt(ast::TyI64) => cx.types.i64,
- SignedInt(ast::TyIs) => cx.types.isize,
- UnsignedInt(ast::TyU8) => cx.types.u8,
- UnsignedInt(ast::TyU16) => cx.types.u16,
- UnsignedInt(ast::TyU32) => cx.types.u32,
- UnsignedInt(ast::TyU64) => cx.types.u64,
- UnsignedInt(ast::TyUs) => cx.types.usize,
+ ast::ExprUnary(ast::UnDeref, _) |
+ ast::ExprField(..) |
+ ast::ExprTupField(..) |
+ ast::ExprIndex(..) => {
+ true
+ }
+
+ ast::ExprCall(..) |
+ ast::ExprMethodCall(..) |
+ ast::ExprStruct(..) |
+ ast::ExprRange(..) |
+ ast::ExprTup(..) |
+ ast::ExprIf(..) |
+ ast::ExprMatch(..) |
+ ast::ExprClosure(..) |
+ ast::ExprBlock(..) |
+ ast::ExprRepeat(..) |
+ ast::ExprVec(..) |
+ ast::ExprBreak(..) |
+ ast::ExprAgain(..) |
+ ast::ExprRet(..) |
+ ast::ExprWhile(..) |
+ ast::ExprLoop(..) |
+ ast::ExprAssign(..) |
+ ast::ExprInlineAsm(..) |
+ ast::ExprAssignOp(..) |
+ ast::ExprLit(_) |
+ ast::ExprUnary(..) |
+ ast::ExprBox(..) |
+ ast::ExprAddrOf(..) |
+ ast::ExprBinary(..) |
+ ast::ExprCast(..) => {
+ false
+ }
+
+ ast::ExprParen(ref e) => self.expr_is_lval(e),
+
+ ast::ExprIfLet(..) |
+ ast::ExprWhileLet(..) |
+ ast::ExprForLoop(..) |
+ ast::ExprMac(..) => {
+ self.sess.span_bug(
+ expr.span,
+ "macro expression remains after expansion");
+ }
+ }
+ }
+
+ pub fn field_idx_strict(&self, name: ast::Name, fields: &[field])
+ -> usize {
+ let mut i = 0;
+ for f in fields { if f.name == name { return i; } i += 1; }
+ self.sess.bug(&format!(
+ "no field named `{}` found in the list of fields `{:?}`",
+ token::get_name(name),
+ fields.iter()
+ .map(|f| token::get_name(f.name).to_string())
+ .collect::<Vec<String>>()));
+ }
+
+ pub fn note_and_explain_type_err(&self, err: &type_err<'tcx>, sp: Span) {
+ match *err {
+ terr_regions_does_not_outlive(subregion, superregion) => {
+ self.note_and_explain_region("", subregion, "...");
+ self.note_and_explain_region("...does not necessarily outlive ",
+ superregion, "");
+ }
+ terr_regions_not_same(region1, region2) => {
+ self.note_and_explain_region("", region1, "...");
+ self.note_and_explain_region("...is not the same lifetime as ",
+ region2, "");
+ }
+ terr_regions_no_overlap(region1, region2) => {
+ self.note_and_explain_region("", region1, "...");
+ self.note_and_explain_region("...does not overlap ",
+ region2, "");
+ }
+ terr_regions_insufficiently_polymorphic(_, conc_region) => {
+ self.note_and_explain_region("concrete lifetime that was found is ",
+ conc_region, "");
+ }
+ terr_regions_overly_polymorphic(_, ty::ReInfer(ty::ReVar(_))) => {
+ // don't bother to print out the message below for
+ // inference variables, it's not very illuminating.
+ }
+ terr_regions_overly_polymorphic(_, conc_region) => {
+ self.note_and_explain_region("expected concrete lifetime is ",
+ conc_region, "");
+ }
+ terr_sorts(values) => {
+ let expected_str = values.expected.sort_string(self);
+ let found_str = values.found.sort_string(self);
+ if expected_str == found_str && expected_str == "closure" {
+ self.sess.span_note(sp,
+ &format!("no two closures, even if identical, have the same type"));
+ self.sess.span_help(sp,
+ &format!("consider boxing your closure and/or \
+ using it as a trait object"));
+ }
+ }
+ _ => {}
}
}
- fn i64_to_disr(&self, val: i64) -> Option<Disr> {
- match *self {
- SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
- SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
- SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
- SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
- UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
- UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
- UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
- UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+ pub fn provided_source(&self, id: ast::DefId) -> Option<ast::DefId> {
+ self.provided_method_sources.borrow().get(&id).cloned()
+ }
- UnsignedInt(ast::TyUs) |
- SignedInt(ast::TyIs) => unreachable!(),
+ pub fn provided_trait_methods(&self, id: ast::DefId) -> Vec<Rc<Method<'tcx>>> {
+ if is_local(id) {
+ if let ItemTrait(_, _, _, ref ms) = self.map.expect_item(id.node).node {
+ ms.iter().filter_map(|ti| {
+ if let ast::MethodTraitItem(_, Some(_)) = ti.node {
+ match self.impl_or_trait_item(ast_util::local_def(ti.id)) {
+ MethodTraitItem(m) => Some(m),
+ _ => {
+ self.sess.bug("provided_trait_methods(): \
+ non-method item found from \
+ looking up provided method?!")
+ }
+ }
+ } else {
+ None
+ }
+ }).collect()
+ } else {
+ self.sess.bug(&format!("provided_trait_methods: `{:?}` is not a trait", id))
+ }
+ } else {
+ csearch::get_provided_trait_methods(self, id)
+ }
+ }
+
+ pub fn associated_consts(&self, id: ast::DefId) -> Vec<Rc<AssociatedConst<'tcx>>> {
+ if is_local(id) {
+ match self.map.expect_item(id.node).node {
+ ItemTrait(_, _, _, ref tis) => {
+ tis.iter().filter_map(|ti| {
+ if let ast::ConstTraitItem(_, _) = ti.node {
+ match self.impl_or_trait_item(ast_util::local_def(ti.id)) {
+ ConstTraitItem(ac) => Some(ac),
+ _ => {
+ self.sess.bug("associated_consts(): \
+ non-const item found from \
+ looking up a constant?!")
+ }
+ }
+ } else {
+ None
+ }
+ }).collect()
+ }
+ ItemImpl(_, _, _, _, _, ref iis) => {
+ iis.iter().filter_map(|ii| {
+ if let ast::ConstImplItem(_, _) = ii.node {
+ match self.impl_or_trait_item(ast_util::local_def(ii.id)) {
+ ConstTraitItem(ac) => Some(ac),
+ _ => {
+ self.sess.bug("associated_consts(): \
+ non-const item found from \
+ looking up a constant?!")
+ }
+ }
+ } else {
+ None
+ }
+ }).collect()
+ }
+ _ => {
+ self.sess.bug(&format!("associated_consts: `{:?}` is not a trait \
+ or impl", id))
+ }
+ }
+ } else {
+ csearch::get_associated_consts(self, id)
}
}
- fn u64_to_disr(&self, val: u64) -> Option<Disr> {
- match *self {
- SignedInt(ast::TyI8) => val.to_i8() .map(|v| v as Disr),
- SignedInt(ast::TyI16) => val.to_i16() .map(|v| v as Disr),
- SignedInt(ast::TyI32) => val.to_i32() .map(|v| v as Disr),
- SignedInt(ast::TyI64) => val.to_i64() .map(|v| v as Disr),
- UnsignedInt(ast::TyU8) => val.to_u8() .map(|v| v as Disr),
- UnsignedInt(ast::TyU16) => val.to_u16() .map(|v| v as Disr),
- UnsignedInt(ast::TyU32) => val.to_u32() .map(|v| v as Disr),
- UnsignedInt(ast::TyU64) => val.to_u64() .map(|v| v as Disr),
+ pub fn trait_item(&self, trait_did: ast::DefId, idx: usize) -> ImplOrTraitItem<'tcx> {
+ let method_def_id = self.trait_item_def_ids(trait_did)[idx].def_id();
+ self.impl_or_trait_item(method_def_id)
+ }
- UnsignedInt(ast::TyUs) |
- SignedInt(ast::TyIs) => unreachable!(),
+ pub fn trait_items(&self, trait_did: ast::DefId) -> Rc<Vec<ImplOrTraitItem<'tcx>>> {
+ let mut trait_items = self.trait_items_cache.borrow_mut();
+ match trait_items.get(&trait_did).cloned() {
+ Some(trait_items) => trait_items,
+ None => {
+ let def_ids = self.trait_item_def_ids(trait_did);
+ let items: Rc<Vec<ImplOrTraitItem>> =
+ Rc::new(def_ids.iter()
+ .map(|d| self.impl_or_trait_item(d.def_id()))
+ .collect());
+ trait_items.insert(trait_did, items.clone());
+ items
+ }
}
}
- fn disr_incr(&self, val: Disr) -> Option<Disr> {
- macro_rules! add1 {
- ($e:expr) => { $e.and_then(|v|v.checked_add(1)).map(|v| v as Disr) }
+ pub fn trait_impl_polarity(&self, id: ast::DefId) -> Option<ast::ImplPolarity> {
+ if id.krate == ast::LOCAL_CRATE {
+ match self.map.find(id.node) {
+ Some(ast_map::NodeItem(item)) => {
+ match item.node {
+ ast::ItemImpl(_, polarity, _, _, _, _) => Some(polarity),
+ _ => None
+ }
+ }
+ _ => None
+ }
+ } else {
+ csearch::get_impl_polarity(self, id)
}
- match *self {
- // SignedInt repr means we *want* to reinterpret the bits
- // treating the highest bit of Disr as a sign-bit, so
- // cast to i64 before range-checking.
- SignedInt(ast::TyI8) => add1!((val as i64).to_i8()),
- SignedInt(ast::TyI16) => add1!((val as i64).to_i16()),
- SignedInt(ast::TyI32) => add1!((val as i64).to_i32()),
- SignedInt(ast::TyI64) => add1!(Some(val as i64)),
+ }
- UnsignedInt(ast::TyU8) => add1!(val.to_u8()),
- UnsignedInt(ast::TyU16) => add1!(val.to_u16()),
- UnsignedInt(ast::TyU32) => add1!(val.to_u32()),
- UnsignedInt(ast::TyU64) => add1!(Some(val)),
+ pub fn custom_coerce_unsized_kind(&self, did: ast::DefId) -> CustomCoerceUnsized {
+ memoized(&self.custom_coerce_unsized_kinds, did, |did: DefId| {
+ let (kind, src) = if did.krate != ast::LOCAL_CRATE {
+ (csearch::get_custom_coerce_unsized_kind(self, did), "external")
+ } else {
+ (None, "local")
+ };
- UnsignedInt(ast::TyUs) |
- SignedInt(ast::TyIs) => unreachable!(),
+ match kind {
+ Some(kind) => kind,
+ None => {
+ self.sess.bug(&format!("custom_coerce_unsized_kind: \
+ {} impl `{}` is missing its kind",
+ src, self.item_path_str(did)));
+ }
+ }
+ })
+ }
+
+ pub fn impl_or_trait_item(&self, id: ast::DefId) -> ImplOrTraitItem<'tcx> {
+ lookup_locally_or_in_crate_store(
+ "impl_or_trait_items", id, &self.impl_or_trait_items,
+ || csearch::get_impl_or_trait_item(self, id))
+ }
+
+ pub fn trait_item_def_ids(&self, id: ast::DefId) -> Rc<Vec<ImplOrTraitItemId>> {
+ lookup_locally_or_in_crate_store(
+ "trait_item_def_ids", id, &self.trait_item_def_ids,
+ || Rc::new(csearch::get_trait_item_def_ids(&self.sess.cstore, id)))
+ }
+
+ /// Returns the trait-ref corresponding to a given impl, or None if it is
+ /// an inherent impl.
+ pub fn impl_trait_ref(&self, id: ast::DefId) -> Option<TraitRef<'tcx>> {
+ lookup_locally_or_in_crate_store(
+ "impl_trait_refs", id, &self.impl_trait_refs,
+ || csearch::get_impl_trait(self, id))
+ }
+
+ /// Returns whether this DefId refers to an impl
+ pub fn is_impl(&self, id: ast::DefId) -> bool {
+ if id.krate == ast::LOCAL_CRATE {
+ if let Some(ast_map::NodeItem(
+ &ast::Item { node: ast::ItemImpl(..), .. })) = self.map.find(id.node) {
+ true
+ } else {
+ false
+ }
+ } else {
+ csearch::is_impl(&self.sess.cstore, id)
}
}
- // This returns a String because (1.) it is only used for
- // rendering an error message and (2.) a string can represent the
- // full range from `i64::MIN` through `u64::MAX`.
- fn disr_string(&self, val: Disr) -> String {
- match *self {
- SignedInt(ast::TyI8) => format!("{}", val as i8 ),
- SignedInt(ast::TyI16) => format!("{}", val as i16),
- SignedInt(ast::TyI32) => format!("{}", val as i32),
- SignedInt(ast::TyI64) => format!("{}", val as i64),
- UnsignedInt(ast::TyU8) => format!("{}", val as u8 ),
- UnsignedInt(ast::TyU16) => format!("{}", val as u16),
- UnsignedInt(ast::TyU32) => format!("{}", val as u32),
- UnsignedInt(ast::TyU64) => format!("{}", val as u64),
+ pub fn trait_ref_to_def_id(&self, tr: &ast::TraitRef) -> ast::DefId {
+ self.def_map.borrow().get(&tr.ref_id).expect("no def-map entry for trait").def_id()
+ }
- UnsignedInt(ast::TyUs) |
- SignedInt(ast::TyIs) => unreachable!(),
+ pub fn try_add_builtin_trait(&self,
+ trait_def_id: ast::DefId,
+ builtin_bounds: &mut EnumSet<BuiltinBound>)
+ -> bool
+ {
+ //! Checks whether `trait_ref` refers to one of the builtin
+ //! traits, like `Send`, and adds the corresponding
+ //! bound to the set `builtin_bounds` if so. Returns true if `trait_ref`
+ //! is a builtin trait.
+
+ match self.lang_items.to_builtin_kind(trait_def_id) {
+ Some(bound) => { builtin_bounds.insert(bound); true }
+ None => false
}
}
- fn disr_wrap_incr(&self, val: Option<Disr>) -> Disr {
- macro_rules! add1 {
- ($e:expr) => { ($e).wrapping_add(1) as Disr }
+ pub fn substd_enum_variants(&self,
+ id: ast::DefId,
+ substs: &Substs<'tcx>)
+ -> Vec<Rc<VariantInfo<'tcx>>> {
+ self.enum_variants(id).iter().map(|variant_info| {
+ let substd_args = variant_info.args.iter()
+ .map(|aty| aty.subst(self, substs)).collect::<Vec<_>>();
+
+ let substd_ctor_ty = variant_info.ctor_ty.subst(self, substs);
+
+ Rc::new(VariantInfo {
+ args: substd_args,
+ ctor_ty: substd_ctor_ty,
+ ..(**variant_info).clone()
+ })
+ }).collect()
+ }
+
+ pub fn item_path_str(&self, id: ast::DefId) -> String {
+ self.with_path(id, |path| ast_map::path_to_string(path))
+ }
+
+ /* If struct_id names a struct with a dtor. */
+ pub fn ty_dtor(&self, struct_id: DefId) -> DtorKind {
+ match self.destructor_for_type.borrow().get(&struct_id) {
+ Some(&method_def_id) => {
+ let flag = !self.has_attr(struct_id, "unsafe_no_drop_flag");
+
+ TraitDtor(method_def_id, flag)
+ }
+ None => NoDtor,
}
- let val = val.unwrap_or(ty::INITIAL_DISCRIMINANT_VALUE);
- match *self {
- SignedInt(ast::TyI8) => add1!(val as i8 ),
- SignedInt(ast::TyI16) => add1!(val as i16),
- SignedInt(ast::TyI32) => add1!(val as i32),
- SignedInt(ast::TyI64) => add1!(val as i64),
- UnsignedInt(ast::TyU8) => add1!(val as u8 ),
- UnsignedInt(ast::TyU16) => add1!(val as u16),
- UnsignedInt(ast::TyU32) => add1!(val as u32),
- UnsignedInt(ast::TyU64) => add1!(val as u64),
+ }
- UnsignedInt(ast::TyUs) |
- SignedInt(ast::TyIs) => unreachable!(),
+ pub fn has_dtor(&self, struct_id: DefId) -> bool {
+ self.destructor_for_type.borrow().contains_key(&struct_id)
+ }
+
+ pub fn with_path<T, F>(&self, id: ast::DefId, f: F) -> T where
+ F: FnOnce(ast_map::PathElems) -> T,
+ {
+ if id.krate == ast::LOCAL_CRATE {
+ self.map.with_path(id.node, f)
+ } else {
+ f(csearch::get_item_path(self, id).iter().cloned().chain(LinkedPath::empty()))
}
}
-}
-/// Returns `(normalized_type, ty)`, where `normalized_type` is the
-/// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
-/// and `ty` is the original type (i.e. may include `isize` or
-/// `usize`).
-pub fn enum_repr_type<'tcx>(cx: &ctxt<'tcx>,
- opt_hint: Option<&attr::ReprAttr>)
- -> (attr::IntType, Ty<'tcx>)
-{
- let repr_type = match opt_hint {
- // Feed in the given type
- Some(&attr::ReprInt(_, int_t)) => int_t,
- // ... but provide sensible default if none provided
- //
- // NB. Historically `fn enum_variants` generate i64 here, while
- // rustc_typeck::check would generate isize.
- _ => SignedInt(ast::TyIs),
- };
-
- let repr_type_ty = repr_type.to_ty(cx);
- let repr_type = match repr_type {
- SignedInt(ast::TyIs) =>
- SignedInt(cx.sess.target.int_type),
- UnsignedInt(ast::TyUs) =>
- UnsignedInt(cx.sess.target.uint_type),
- other => other
- };
-
- (repr_type, repr_type_ty)
-}
-
-fn report_discrim_overflow(cx: &ctxt,
- variant_span: Span,
- variant_name: &str,
- repr_type: attr::IntType,
- prev_val: Disr) {
- let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
- let computed_value = repr_type.disr_string(computed_value);
- let prev_val = repr_type.disr_string(prev_val);
- let repr_type = repr_type.to_ty(cx);
- span_err!(cx.sess, variant_span, E0370,
- "enum discriminant overflowed on value after {}: {}; \
- set explicitly via {} = {} if that is desired outcome",
- prev_val, repr_type, variant_name, computed_value);
-}
-
-// This computes the discriminant values for the sequence of Variants
-// attached to a particular enum, taking into account the #[repr] (if
-// any) provided via the `opt_hint`.
-fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
- vs: &'tcx [P<ast::Variant>],
- opt_hint: Option<&attr::ReprAttr>)
- -> Vec<Rc<ty::VariantInfo<'tcx>>> {
- let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
- let mut prev_disr_val: Option<ty::Disr> = None;
-
- let (repr_type, repr_type_ty) = ty::enum_repr_type(cx, opt_hint);
-
- for v in vs {
- // If the discriminant value is specified explicitly in the
- // enum, check whether the initialization expression is valid,
- // otherwise use the last value plus one.
- let current_disr_val;
-
- // This closure marks cases where, when an error occurs during
- // the computation, attempt to assign a (hopefully) fresh
- // value to avoid spurious error reports downstream.
- let attempt_fresh_value = move || -> Disr {
- repr_type.disr_wrap_incr(prev_disr_val)
+ pub fn enum_is_univariant(&self, id: ast::DefId) -> bool {
+ self.enum_variants(id).len() == 1
+ }
+
+ /// Returns `(normalized_type, ty)`, where `normalized_type` is the
+ /// IntType representation of one of {i64,i32,i16,i8,u64,u32,u16,u8},
+ /// and `ty` is the original type (i.e. may include `isize` or
+ /// `usize`).
+ pub fn enum_repr_type(&self, opt_hint: Option<&attr::ReprAttr>)
+ -> (attr::IntType, Ty<'tcx>) {
+ let repr_type = match opt_hint {
+ // Feed in the given type
+ Some(&attr::ReprInt(_, int_t)) => int_t,
+ // ... but provide sensible default if none provided
+ //
+ // NB. Historically `fn enum_variants` generate i64 here, while
+ // rustc_typeck::check would generate isize.
+ _ => SignedInt(ast::TyIs),
};
- match v.node.disr_expr {
- Some(ref e) => {
- debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
-
- // check_expr (from check_const pass) doesn't guarantee
- // that the expression is in a form that eval_const_expr can
- // handle, so we may still get an internal compiler error
- //
- // pnkfelix: The above comment was transcribed from
- // the version of this code taken from rustc_typeck.
- // Presumably the implication is that we need to deal
- // with such ICE's as they arise.
- //
- // Since this can be called from `ty::enum_variants`
- // anyway, best thing is to make `eval_const_expr`
- // more robust (on case-by-case basis).
-
- match const_eval::eval_const_expr_partial(cx, &**e, Some(repr_type_ty)) {
- Ok(ConstVal::Int(val)) => current_disr_val = val as Disr,
- Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr,
- Ok(_) => {
- let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
- span_err!(cx.sess, e.span, E0079,
- "expected {} integer constant",
- sign_desc);
- current_disr_val = attempt_fresh_value();
- }
- Err(ref err) => {
- span_err!(cx.sess, err.span, E0080,
- "constant evaluation error: {}",
- err.description());
- current_disr_val = attempt_fresh_value();
+ let repr_type_ty = repr_type.to_ty(self);
+ let repr_type = match repr_type {
+ SignedInt(ast::TyIs) =>
+ SignedInt(self.sess.target.int_type),
+ UnsignedInt(ast::TyUs) =>
+ UnsignedInt(self.sess.target.uint_type),
+ other => other
+ };
+
+ (repr_type, repr_type_ty)
+ }
+
+ fn report_discrim_overflow(&self,
+ variant_span: Span,
+ variant_name: &str,
+ repr_type: attr::IntType,
+ prev_val: Disr) {
+ let computed_value = repr_type.disr_wrap_incr(Some(prev_val));
+ let computed_value = repr_type.disr_string(computed_value);
+ let prev_val = repr_type.disr_string(prev_val);
+ let repr_type = repr_type.to_ty(self);
+ span_err!(self.sess, variant_span, E0370,
+ "enum discriminant overflowed on value after {}: {}; \
+ set explicitly via {} = {} if that is desired outcome",
+ prev_val, repr_type, variant_name, computed_value);
+ }
+
+ // This computes the discriminant values for the sequence of Variants
+ // attached to a particular enum, taking into account the #[repr] (if
+ // any) provided via the `opt_hint`.
+ fn compute_enum_variants(&self,
+ vs: &'tcx [P<ast::Variant>],
+ opt_hint: Option<&attr::ReprAttr>)
+ -> Vec<Rc<ty::VariantInfo<'tcx>>> {
+ let mut variants: Vec<Rc<ty::VariantInfo>> = Vec::new();
+ let mut prev_disr_val: Option<ty::Disr> = None;
+
+ let (repr_type, repr_type_ty) = self.enum_repr_type(opt_hint);
+
+ for v in vs {
+ // If the discriminant value is specified explicitly in the
+ // enum, check whether the initialization expression is valid,
+ // otherwise use the last value plus one.
+ let current_disr_val;
+
+ // This closure marks cases where, when an error occurs during
+ // the computation, attempt to assign a (hopefully) fresh
+ // value to avoid spurious error reports downstream.
+ let attempt_fresh_value = move || -> Disr {
+ repr_type.disr_wrap_incr(prev_disr_val)
+ };
+
+ match v.node.disr_expr {
+ Some(ref e) => {
+ debug!("disr expr, checking {}", pprust::expr_to_string(&**e));
+
+ // check_expr (from check_const pass) doesn't guarantee
+ // that the expression is in a form that eval_const_expr can
+ // handle, so we may still get an internal compiler error
+ //
+ // pnkfelix: The above comment was transcribed from
+ // the version of this code taken from rustc_typeck.
+ // Presumably the implication is that we need to deal
+ // with such ICE's as they arise.
+ //
+ // Since this can be called from `ty::enum_variants`
+ // anyway, best thing is to make `eval_const_expr`
+ // more robust (on case-by-case basis).
+
+ match const_eval::eval_const_expr_partial(self, &**e, Some(repr_type_ty)) {
+ Ok(ConstVal::Int(val)) => current_disr_val = val as Disr,
+ Ok(ConstVal::Uint(val)) => current_disr_val = val as Disr,
+ Ok(_) => {
+ let sign_desc = if repr_type.is_signed() {
+ "signed"
+ } else {
+ "unsigned"
+ };
+ span_err!(self.sess, e.span, E0079,
+ "expected {} integer constant",
+ sign_desc);
+ current_disr_val = attempt_fresh_value();
+ }
+ Err(ref err) => {
+ span_err!(self.sess, err.span, E0080,
+ "constant evaluation error: {}",
+ err.description());
+ current_disr_val = attempt_fresh_value();
+ }
}
- }
- },
- None => {
- current_disr_val = match prev_disr_val {
- Some(prev_disr_val) => {
- if let Some(v) = repr_type.disr_incr(prev_disr_val) {
- v
- } else {
- report_discrim_overflow(cx, v.span, v.node.name.as_str(),
- repr_type, prev_disr_val);
- attempt_fresh_value()
+ },
+ None => {
+ current_disr_val = match prev_disr_val {
+ Some(prev_disr_val) => {
+ if let Some(v) = repr_type.disr_incr(prev_disr_val) {
+ v
+ } else {
+ self.report_discrim_overflow(v.span, v.node.name.as_str(),
+ repr_type, prev_disr_val);
+ attempt_fresh_value()
+ }
}
+ None => ty::INITIAL_DISCRIMINANT_VALUE
}
- None => ty::INITIAL_DISCRIMINANT_VALUE
}
}
- }
- let variant_info = Rc::new(VariantInfo::from_ast_variant(cx, &**v, current_disr_val));
- prev_disr_val = Some(current_disr_val);
+ let variant_info = Rc::new(VariantInfo::from_ast_variant(self, &**v, current_disr_val));
+ prev_disr_val = Some(current_disr_val);
- variants.push(variant_info);
- }
+ variants.push(variant_info);
+ }
- return variants;
-}
+ variants
+ }
-pub fn enum_variants<'tcx>(cx: &ctxt<'tcx>, id: ast::DefId)
- -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
- memoized(&cx.enum_var_cache, id, |id: ast::DefId| {
- if ast::LOCAL_CRATE != id.krate {
- Rc::new(csearch::get_enum_variants(cx, id))
- } else {
- match cx.map.get(id.node) {
- ast_map::NodeItem(ref item) => {
- match item.node {
- ast::ItemEnum(ref enum_definition, _) => {
- Rc::new(compute_enum_variants(
- cx,
- &enum_definition.variants,
- lookup_repr_hints(cx, id).get(0)))
- }
- _ => {
- cx.sess.bug("enum_variants: id not bound to an enum")
+ pub fn enum_variants(&self, id: ast::DefId) -> Rc<Vec<Rc<VariantInfo<'tcx>>>> {
+ memoized(&self.enum_var_cache, id, |id: ast::DefId| {
+ if ast::LOCAL_CRATE != id.krate {
+ Rc::new(csearch::get_enum_variants(self, id))
+ } else {
+ match self.map.get(id.node) {
+ ast_map::NodeItem(ref item) => {
+ match item.node {
+ ast::ItemEnum(ref enum_definition, _) => {
+ Rc::new(self.compute_enum_variants(
+ &enum_definition.variants,
+ self.lookup_repr_hints(id).get(0)))
+ }
+ _ => {
+ self.sess.bug("enum_variants: id not bound to an enum")
+ }
}
}
+ _ => self.sess.bug("enum_variants: id not bound to an enum")
}
- _ => cx.sess.bug("enum_variants: id not bound to an enum")
}
- }
- })
-}
+ })
+ }
-// Returns information about the enum variant with the given ID:
-pub fn enum_variant_with_id<'tcx>(cx: &ctxt<'tcx>,
- enum_id: ast::DefId,
- variant_id: ast::DefId)
- -> Rc<VariantInfo<'tcx>> {
- enum_variants(cx, enum_id).iter()
- .find(|variant| variant.id == variant_id)
- .expect("enum_variant_with_id(): no variant exists with that ID")
- .clone()
-}
+ // Returns information about the enum variant with the given ID:
+ pub fn enum_variant_with_id(&self,
+ enum_id: ast::DefId,
+ variant_id: ast::DefId)
+ -> Rc<VariantInfo<'tcx>> {
+ self.enum_variants(enum_id).iter()
+ .find(|variant| variant.id == variant_id)
+ .expect("enum_variant_with_id(): no variant exists with that ID")
+ .clone()
+ }
-// If the given item is in an external crate, looks up its type and adds it to
-// the type cache. Returns the type parameters and type.
-pub fn lookup_item_type<'tcx>(cx: &ctxt<'tcx>,
- did: ast::DefId)
- -> TypeScheme<'tcx> {
- lookup_locally_or_in_crate_store(
- "tcache", did, &cx.tcache,
- || csearch::get_type(cx, did))
-}
+ // If the given item is in an external crate, looks up its type and adds it to
+ // the type cache. Returns the type parameters and type.
+ pub fn lookup_item_type(&self, did: ast::DefId) -> TypeScheme<'tcx> {
+ lookup_locally_or_in_crate_store(
+ "tcache", did, &self.tcache,
+ || csearch::get_type(self, did))
+ }
-/// Given the did of a trait, returns its canonical trait ref.
-pub fn lookup_trait_def<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
- -> &'tcx TraitDef<'tcx> {
- lookup_locally_or_in_crate_store(
- "trait_defs", did, &cx.trait_defs,
- || cx.arenas.trait_defs.alloc(csearch::get_trait_def(cx, did))
- )
-}
+ /// Given the did of a trait, returns its canonical trait ref.
+ pub fn lookup_trait_def(&self, did: ast::DefId) -> &'tcx TraitDef<'tcx> {
+ lookup_locally_or_in_crate_store(
+ "trait_defs", did, &self.trait_defs,
+ || self.arenas.trait_defs.alloc(csearch::get_trait_def(self, did))
+ )
+ }
-/// Given the did of an item, returns its full set of predicates.
-pub fn lookup_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
- -> GenericPredicates<'tcx>
-{
- lookup_locally_or_in_crate_store(
- "predicates", did, &cx.predicates,
- || csearch::get_predicates(cx, did))
-}
+ /// Given the did of an item, returns its full set of predicates.
+ pub fn lookup_predicates(&self, did: ast::DefId) -> GenericPredicates<'tcx> {
+ lookup_locally_or_in_crate_store(
+ "predicates", did, &self.predicates,
+ || csearch::get_predicates(self, did))
+ }
-/// Given the did of a trait, returns its superpredicates.
-pub fn lookup_super_predicates<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId)
- -> GenericPredicates<'tcx>
-{
- lookup_locally_or_in_crate_store(
- "super_predicates", did, &cx.super_predicates,
- || csearch::get_super_predicates(cx, did))
-}
+ /// Given the did of a trait, returns its superpredicates.
+ pub fn lookup_super_predicates(&self, did: ast::DefId) -> GenericPredicates<'tcx> {
+ lookup_locally_or_in_crate_store(
+ "super_predicates", did, &self.super_predicates,
+ || csearch::get_super_predicates(self, did))
+ }
-/// Get the attributes of a definition.
-pub fn get_attrs<'tcx>(tcx: &'tcx ctxt, did: DefId)
- -> Cow<'tcx, [ast::Attribute]> {
- if is_local(did) {
- Cow::Borrowed(tcx.map.attrs(did.node))
- } else {
- Cow::Owned(csearch::get_item_attrs(&tcx.sess.cstore, did))
+ /// Get the attributes of a definition.
+ pub fn get_attrs(&self, did: DefId) -> Cow<'tcx, [ast::Attribute]> {
+ if is_local(did) {
+ Cow::Borrowed(self.map.attrs(did.node))
+ } else {
+ Cow::Owned(csearch::get_item_attrs(&self.sess.cstore, did))
+ }
}
-}
-/// Determine whether an item is annotated with an attribute
-pub fn has_attr(tcx: &ctxt, did: DefId, attr: &str) -> bool {
- get_attrs(tcx, did).iter().any(|item| item.check_name(attr))
-}
+ /// Determine whether an item is annotated with an attribute
+ pub fn has_attr(&self, did: DefId, attr: &str) -> bool {
+ self.get_attrs(did).iter().any(|item| item.check_name(attr))
+ }
-/// Determine whether an item is annotated with `#[repr(packed)]`
-pub fn lookup_packed(tcx: &ctxt, did: DefId) -> bool {
- lookup_repr_hints(tcx, did).contains(&attr::ReprPacked)
-}
+ /// Determine whether an item is annotated with `#[repr(packed)]`
+ pub fn lookup_packed(&self, did: DefId) -> bool {
+ self.lookup_repr_hints(did).contains(&attr::ReprPacked)
+ }
-/// Determine whether an item is annotated with `#[simd]`
-pub fn lookup_simd(tcx: &ctxt, did: DefId) -> bool {
- has_attr(tcx, did, "simd")
-}
+ /// Determine whether an item is annotated with `#[simd]`
+ pub fn lookup_simd(&self, did: DefId) -> bool {
+ self.has_attr(did, "simd")
+ }
-/// Obtain the representation annotation for a struct definition.
-pub fn lookup_repr_hints(tcx: &ctxt, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
- memoized(&tcx.repr_hint_cache, did, |did: DefId| {
- Rc::new(if did.krate == LOCAL_CRATE {
- get_attrs(tcx, did).iter().flat_map(|meta| {
- attr::find_repr_attrs(tcx.sess.diagnostic(), meta).into_iter()
- }).collect()
- } else {
- csearch::get_repr_attrs(&tcx.sess.cstore, did)
+ /// Obtain the representation annotation for a struct definition.
+ pub fn lookup_repr_hints(&self, did: DefId) -> Rc<Vec<attr::ReprAttr>> {
+ memoized(&self.repr_hint_cache, did, |did: DefId| {
+ Rc::new(if did.krate == LOCAL_CRATE {
+ self.get_attrs(did).iter().flat_map(|meta| {
+ attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter()
+ }).collect()
+ } else {
+ csearch::get_repr_attrs(&self.sess.cstore, did)
+ })
})
- })
-}
+ }
-// Look up a field ID, whether or not it's local
-pub fn lookup_field_type_unsubstituted<'tcx>(tcx: &ctxt<'tcx>,
- struct_id: DefId,
- id: DefId)
- -> Ty<'tcx> {
- if id.krate == ast::LOCAL_CRATE {
- node_id_to_type(tcx, id.node)
- } else {
- let mut tcache = tcx.tcache.borrow_mut();
- tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
+ // Look up a field ID, whether or not it's local
+ pub fn lookup_field_type_unsubstituted(&self,
+ struct_id: DefId,
+ id: DefId)
+ -> Ty<'tcx> {
+ if id.krate == ast::LOCAL_CRATE {
+ self.node_id_to_type(id.node)
+ } else {
+ let mut tcache = self.tcache.borrow_mut();
+ tcache.entry(id).or_insert_with(|| csearch::get_field_type(self, struct_id, id)).ty
+ }
}
-}
-// Look up a field ID, whether or not it's local
-// Takes a list of type substs in case the struct is generic
-pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
- struct_id: DefId,
- id: DefId,
- substs: &Substs<'tcx>)
- -> Ty<'tcx> {
- lookup_field_type_unsubstituted(tcx, struct_id, id).subst(tcx, substs)
-}
+ // Look up a field ID, whether or not it's local
+ // Takes a list of type substs in case the struct is generic
+ pub fn lookup_field_type(&self,
+ struct_id: DefId,
+ id: DefId,
+ substs: &Substs<'tcx>)
+ -> Ty<'tcx> {
+ self.lookup_field_type_unsubstituted(struct_id, id).subst(self, substs)
+ }
-// Look up the list of field names and IDs for a given struct.
-// Panics if the id is not bound to a struct.
-pub fn lookup_struct_fields(cx: &ctxt, did: ast::DefId) -> Vec<field_ty> {
- if did.krate == ast::LOCAL_CRATE {
- let struct_fields = cx.struct_fields.borrow();
- match struct_fields.get(&did) {
- Some(fields) => (**fields).clone(),
- _ => {
- cx.sess.bug(
- &format!("ID not mapped to struct fields: {}",
- cx.map.node_to_string(did.node)));
+ // Look up the list of field names and IDs for a given struct.
+ // Panics if the id is not bound to a struct.
+ pub fn lookup_struct_fields(&self, did: ast::DefId) -> Vec<field_ty> {
+ if did.krate == ast::LOCAL_CRATE {
+ let struct_fields = self.struct_fields.borrow();
+ match struct_fields.get(&did) {
+ Some(fields) => (**fields).clone(),
+ _ => {
+ self.sess.bug(
+ &format!("ID not mapped to struct fields: {}",
+ self.map.node_to_string(did.node)));
+ }
}
+ } else {
+ csearch::get_struct_fields(&self.sess.cstore, did)
}
- } else {
- csearch::get_struct_fields(&cx.sess.cstore, did)
}
-}
-pub fn is_tuple_struct(cx: &ctxt, did: ast::DefId) -> bool {
- let fields = lookup_struct_fields(cx, did);
- !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
-}
+ pub fn is_tuple_struct(&self, did: ast::DefId) -> bool {
+ let fields = self.lookup_struct_fields(did);
+ !fields.is_empty() && fields.iter().all(|f| f.name == token::special_names::unnamed_field)
+ }
-// Returns a list of fields corresponding to the struct's items. trans uses
-// this. Takes a list of substs with which to instantiate field types.
-pub fn struct_fields<'tcx>(cx: &ctxt<'tcx>, did: ast::DefId, substs: &Substs<'tcx>)
- -> Vec<field<'tcx>> {
- lookup_struct_fields(cx, did).iter().map(|f| {
- field {
- name: f.name,
- mt: mt {
- ty: lookup_field_type(cx, did, f.id, substs),
- mutbl: MutImmutable
+ // Returns a list of fields corresponding to the struct's items. trans uses
+ // this. Takes a list of substs with which to instantiate field types.
+ pub fn struct_fields(&self, did: ast::DefId, substs: &Substs<'tcx>)
+ -> Vec<field<'tcx>> {
+ self.lookup_struct_fields(did).iter().map(|f| {
+ field {
+ name: f.name,
+ mt: mt {
+ ty: self.lookup_field_type(did, f.id, substs),
+ mutbl: MutImmutable
+ }
}
- }
- }).collect()
-}
+ }).collect()
+ }
-// Returns a list of fields corresponding to the tuple's items. trans uses
-// this.
-pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
- v.iter().enumerate().map(|(i, &f)| {
- field {
- name: token::intern(&i.to_string()),
- mt: mt {
- ty: f,
- mutbl: MutImmutable
+ /// Returns the deeply last field of nested structures, or the same type,
+ /// if not a structure at all. Corresponds to the only possible unsized
+ /// field, and its type can be used to determine unsizing strategy.
+ pub fn struct_tail(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
+ while let TyStruct(def_id, substs) = ty.sty {
+ match self.struct_fields(def_id, substs).last() {
+ Some(f) => ty = f.mt.ty,
+ None => break
}
}
- }).collect()
-}
-
-/// Returns the deeply last field of nested structures, or the same type,
-/// if not a structure at all. Corresponds to the only possible unsized
-/// field, and its type can be used to determine unsizing strategy.
-pub fn struct_tail<'tcx>(cx: &ctxt<'tcx>, mut ty: Ty<'tcx>) -> Ty<'tcx> {
- while let TyStruct(def_id, substs) = ty.sty {
- match struct_fields(cx, def_id, substs).last() {
- Some(f) => ty = f.mt.ty,
- None => break
- }
+ ty
}
- ty
-}
-/// Same as applying struct_tail on `source` and `target`, but only
-/// keeps going as long as the two types are instances of the same
-/// structure definitions.
-/// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
-/// whereas struct_tail produces `T`, and `Trait`, respectively.
-pub fn struct_lockstep_tails<'tcx>(cx: &ctxt<'tcx>,
- source: Ty<'tcx>,
- target: Ty<'tcx>)
- -> (Ty<'tcx>, Ty<'tcx>) {
- let (mut a, mut b) = (source, target);
- while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) {
- if a_did != b_did {
- continue;
- }
- if let Some(a_f) = struct_fields(cx, a_did, a_substs).last() {
- if let Some(b_f) = struct_fields(cx, b_did, b_substs).last() {
- a = a_f.mt.ty;
- b = b_f.mt.ty;
+ /// Same as applying struct_tail on `source` and `target`, but only
+ /// keeps going as long as the two types are instances of the same
+ /// structure definitions.
+ /// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
+ /// whereas struct_tail produces `T`, and `Trait`, respectively.
+ pub fn struct_lockstep_tails(&self,
+ source: Ty<'tcx>,
+ target: Ty<'tcx>)
+ -> (Ty<'tcx>, Ty<'tcx>) {
+ let (mut a, mut b) = (source, target);
+ while let (&TyStruct(a_did, a_substs), &TyStruct(b_did, b_substs)) = (&a.sty, &b.sty) {
+ if a_did != b_did {
+ break;
+ }
+ if let Some(a_f) = self.struct_fields(a_did, a_substs).last() {
+ if let Some(b_f) = self.struct_fields(b_did, b_substs).last() {
+ a = a_f.mt.ty;
+ b = b_f.mt.ty;
+ } else {
+ break;
+ }
} else {
break;
}
- } else {
- break;
}
+ (a, b)
}
- (a, b)
-}
-#[derive(Copy, Clone)]
-pub struct ClosureUpvar<'tcx> {
- pub def: def::Def,
- pub span: Span,
- pub ty: Ty<'tcx>,
-}
+ // Returns a list of `ClosureUpvar`s for each upvar.
+ pub fn closure_upvars(typer: &Typer<'tcx>,
+ closure_id: ast::DefId,
+ substs: &Substs<'tcx>)
+ -> Option<Vec<ClosureUpvar<'tcx>>>
+ {
+ // Presently an unboxed closure type cannot "escape" out of a
+ // function, so we will only encounter ones that originated in the
+ // local crate or were inlined into it along with some function.
+ // This may change if abstract return types of some sort are
+ // implemented.
+ assert!(closure_id.krate == ast::LOCAL_CRATE);
+ let tcx = typer.tcx();
+ match tcx.freevars.borrow().get(&closure_id.node) {
+ None => Some(vec![]),
+ Some(ref freevars) => {
+ freevars.iter()
+ .map(|freevar| {
+ let freevar_def_id = freevar.def.def_id();
+ let freevar_ty = match typer.node_ty(freevar_def_id.node) {
+ Ok(t) => { t }
+ Err(()) => { return None; }
+ };
+ let freevar_ty = freevar_ty.subst(tcx, substs);
-// Returns a list of `ClosureUpvar`s for each upvar.
-pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
- closure_id: ast::DefId,
- substs: &Substs<'tcx>)
- -> Option<Vec<ClosureUpvar<'tcx>>>
-{
- // Presently an unboxed closure type cannot "escape" out of a
- // function, so we will only encounter ones that originated in the
- // local crate or were inlined into it along with some function.
- // This may change if abstract return types of some sort are
- // implemented.
- assert!(closure_id.krate == ast::LOCAL_CRATE);
- let tcx = typer.tcx();
- match tcx.freevars.borrow().get(&closure_id.node) {
- None => Some(vec![]),
- Some(ref freevars) => {
- freevars.iter()
- .map(|freevar| {
- let freevar_def_id = freevar.def.def_id();
- let freevar_ty = match typer.node_ty(freevar_def_id.node) {
- Ok(t) => { t }
- Err(()) => { return None; }
- };
- let freevar_ty = freevar_ty.subst(tcx, substs);
-
- let upvar_id = ty::UpvarId {
- var_id: freevar_def_id.node,
- closure_expr_id: closure_id.node
- };
-
- typer.upvar_capture(upvar_id).map(|capture| {
- let freevar_ref_ty = match capture {
- UpvarCapture::ByValue => {
- freevar_ty
- }
- UpvarCapture::ByRef(borrow) => {
- tcx.mk_ref(tcx.mk_region(borrow.region),
- ty::mt {
- ty: freevar_ty,
- mutbl: borrow.kind.to_mutbl_lossy(),
- })
- }
+ let upvar_id = ty::UpvarId {
+ var_id: freevar_def_id.node,
+ closure_expr_id: closure_id.node
};
- ClosureUpvar {
- def: freevar.def,
- span: freevar.span,
- ty: freevar_ref_ty,
- }
+ typer.upvar_capture(upvar_id).map(|capture| {
+ let freevar_ref_ty = match capture {
+ UpvarCapture::ByValue => {
+ freevar_ty
+ }
+ UpvarCapture::ByRef(borrow) => {
+ tcx.mk_ref(tcx.mk_region(borrow.region),
+ ty::mt {
+ ty: freevar_ty,
+ mutbl: borrow.kind.to_mutbl_lossy(),
+ })
+ }
+ };
+
+ ClosureUpvar {
+ def: freevar.def,
+ span: freevar.span,
+ ty: freevar_ref_ty,
+ }
+ })
})
- })
- .collect()
- }
- }
-}
-
-// Returns the repeat count for a repeating vector expression.
-pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> usize {
- match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.usize)) {
- Ok(val) => {
- let found = match val {
- ConstVal::Uint(count) => return count as usize,
- ConstVal::Int(count) if count >= 0 => return count as usize,
- ConstVal::Int(_) => "negative integer",
- ConstVal::Float(_) => "float",
- ConstVal::Str(_) => "string",
- ConstVal::Bool(_) => "boolean",
- ConstVal::Binary(_) => "binary array",
- ConstVal::Struct(..) => "struct",
- ConstVal::Tuple(_) => "tuple"
- };
- span_err!(tcx.sess, count_expr.span, E0306,
- "expected positive integer for repeat count, found {}",
- found);
- }
- Err(err) => {
- let err_description = err.description();
- let found = match count_expr.node {
- ast::ExprPath(None, ast::Path {
- global: false,
- ref segments,
- ..
- }) if segments.len() == 1 =>
- format!("{}", "found variable"),
- _ =>
- format!("but {}", err_description),
- };
- span_err!(tcx.sess, count_expr.span, E0307,
- "expected constant integer for repeat count, {}",
- found);
+ .collect()
+ }
}
}
- 0
-}
-// Iterate over a type parameter's bounded traits and any supertraits
-// of those traits, ignoring kinds.
-// Here, the supertraits are the transitive closure of the supertrait
-// relation on the supertraits from each bounded trait's constraint
-// list.
-pub fn each_bound_trait_and_supertraits<'tcx, F>(tcx: &ctxt<'tcx>,
- bounds: &[PolyTraitRef<'tcx>],
- mut f: F)
- -> bool where
- F: FnMut(PolyTraitRef<'tcx>) -> bool,
-{
- for bound_trait_ref in traits::transitive_bounds(tcx, bounds) {
- if !f(bound_trait_ref) {
- return false;
+ // Returns the repeat count for a repeating vector expression.
+ pub fn eval_repeat_count(&self, count_expr: &ast::Expr) -> usize {
+ match const_eval::eval_const_expr_partial(self, count_expr, Some(self.types.usize)) {
+ Ok(val) => {
+ let found = match val {
+ ConstVal::Uint(count) => return count as usize,
+ ConstVal::Int(count) if count >= 0 => return count as usize,
+ ConstVal::Int(_) => "negative integer",
+ ConstVal::Float(_) => "float",
+ ConstVal::Str(_) => "string",
+ ConstVal::Bool(_) => "boolean",
+ ConstVal::Binary(_) => "binary array",
+ ConstVal::Struct(..) => "struct",
+ ConstVal::Tuple(_) => "tuple"
+ };
+ span_err!(self.sess, count_expr.span, E0306,
+ "expected positive integer for repeat count, found {}",
+ found);
+ }
+ Err(err) => {
+ let err_description = err.description();
+ let found = match count_expr.node {
+ ast::ExprPath(None, ast::Path {
+ global: false,
+ ref segments,
+ ..
+ }) if segments.len() == 1 =>
+ format!("{}", "found variable"),
+ _ =>
+ format!("but {}", err_description),
+ };
+ span_err!(self.sess, count_expr.span, E0307,
+ "expected constant integer for repeat count, {}",
+ found);
+ }
}
+ 0
}
- return true;
-}
-/// Given a set of predicates that apply to an object type, returns
-/// the region bounds that the (erased) `Self` type must
-/// outlive. Precisely *because* the `Self` type is erased, the
-/// parameter `erased_self_ty` must be supplied to indicate what type
-/// has been used to represent `Self` in the predicates
-/// themselves. This should really be a unique type; `FreshTy(0)` is a
-/// popular choice.
-///
-/// Requires that trait definitions have been processed so that we can
-/// elaborate predicates and walk supertraits.
-pub fn required_region_bounds<'tcx>(tcx: &ctxt<'tcx>,
- erased_self_ty: Ty<'tcx>,
- predicates: Vec<ty::Predicate<'tcx>>)
- -> Vec<ty::Region>
-{
- debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
- erased_self_ty,
- predicates);
-
- assert!(!erased_self_ty.has_escaping_regions());
-
- traits::elaborate_predicates(tcx, predicates)
- .filter_map(|predicate| {
- match predicate {
- ty::Predicate::Projection(..) |
- ty::Predicate::Trait(..) |
- ty::Predicate::Equate(..) |
- ty::Predicate::RegionOutlives(..) => {
- None
- }
- ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
- // Search for a bound of the form `erased_self_ty
- // : 'a`, but be wary of something like `for<'a>
- // erased_self_ty : 'a` (we interpret a
- // higher-ranked bound like that as 'static,
- // though at present the code in `fulfill.rs`
- // considers such bounds to be unsatisfiable, so
- // it's kind of a moot point since you could never
- // construct such an object, but this seems
- // correct even if that code changes).
- if t == erased_self_ty && !r.has_escaping_regions() {
- if r.has_escaping_regions() {
- Some(ty::ReStatic)
+ // Iterate over a type parameter's bounded traits and any supertraits
+ // of those traits, ignoring kinds.
+ // Here, the supertraits are the transitive closure of the supertrait
+ // relation on the supertraits from each bounded trait's constraint
+ // list.
+ pub fn each_bound_trait_and_supertraits<F>(&self,
+ bounds: &[PolyTraitRef<'tcx>],
+ mut f: F)
+ -> bool where
+ F: FnMut(PolyTraitRef<'tcx>) -> bool,
+ {
+ for bound_trait_ref in traits::transitive_bounds(self, bounds) {
+ if !f(bound_trait_ref) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// Given a set of predicates that apply to an object type, returns
+ /// the region bounds that the (erased) `Self` type must
+ /// outlive. Precisely *because* the `Self` type is erased, the
+ /// parameter `erased_self_ty` must be supplied to indicate what type
+ /// has been used to represent `Self` in the predicates
+ /// themselves. This should really be a unique type; `FreshTy(0)` is a
+ /// popular choice.
+ ///
+ /// Requires that trait definitions have been processed so that we can
+ /// elaborate predicates and walk supertraits.
+ pub fn required_region_bounds(&self,
+ erased_self_ty: Ty<'tcx>,
+ predicates: Vec<ty::Predicate<'tcx>>)
+ -> Vec<ty::Region>
+ {
+ debug!("required_region_bounds(erased_self_ty={:?}, predicates={:?})",
+ erased_self_ty,
+ predicates);
+
+ assert!(!erased_self_ty.has_escaping_regions());
+
+ traits::elaborate_predicates(self, predicates)
+ .filter_map(|predicate| {
+ match predicate {
+ ty::Predicate::Projection(..) |
+ ty::Predicate::Trait(..) |
+ ty::Predicate::Equate(..) |
+ ty::Predicate::RegionOutlives(..) => {
+ None
+ }
+ ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t, r))) => {
+ // Search for a bound of the form `erased_self_ty
+ // : 'a`, but be wary of something like `for<'a>
+ // erased_self_ty : 'a` (we interpret a
+ // higher-ranked bound like that as 'static,
+ // though at present the code in `fulfill.rs`
+ // considers such bounds to be unsatisfiable, so
+ // it's kind of a moot point since you could never
+ // construct such an object, but this seems
+ // correct even if that code changes).
+ if t == erased_self_ty && !r.has_escaping_regions() {
+ if r.has_escaping_regions() {
+ Some(ty::ReStatic)
+ } else {
+ Some(r)
+ }
} else {
- Some(r)
+ None
}
- } else {
- None
}
}
- }
- })
- .collect()
-}
-
-pub fn item_variances(tcx: &ctxt, item_id: ast::DefId) -> Rc<ItemVariances> {
- lookup_locally_or_in_crate_store(
- "item_variance_map", item_id, &tcx.item_variance_map,
- || Rc::new(csearch::get_item_variances(&tcx.sess.cstore, item_id)))
-}
-
-pub fn trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) -> bool {
- populate_implementations_for_trait_if_necessary(tcx, trait_def_id);
+ })
+ .collect()
+ }
- let def = lookup_trait_def(tcx, trait_def_id);
- def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
-}
+ pub fn item_variances(&self, item_id: ast::DefId) -> Rc<ItemVariances> {
+ lookup_locally_or_in_crate_store(
+ "item_variance_map", item_id, &self.item_variance_map,
+ || Rc::new(csearch::get_item_variances(&self.sess.cstore, item_id)))
+ }
-/// Records a trait-to-implementation mapping.
-pub fn record_trait_has_default_impl(tcx: &ctxt, trait_def_id: DefId) {
- let def = lookup_trait_def(tcx, trait_def_id);
- def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
-}
+ pub fn trait_has_default_impl(&self, trait_def_id: DefId) -> bool {
+ self.populate_implementations_for_trait_if_necessary(trait_def_id);
-/// Load primitive inherent implementations if necessary
-pub fn populate_implementations_for_primitive_if_necessary(tcx: &ctxt,
- primitive_def_id: ast::DefId) {
- if primitive_def_id.krate == LOCAL_CRATE {
- return
+ let def = self.lookup_trait_def(trait_def_id);
+ def.flags.get().intersects(TraitFlags::HAS_DEFAULT_IMPL)
}
- if tcx.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
- return
+ /// Records a trait-to-implementation mapping.
+ pub fn record_trait_has_default_impl(&self, trait_def_id: DefId) {
+ let def = self.lookup_trait_def(trait_def_id);
+ def.flags.set(def.flags.get() | TraitFlags::HAS_DEFAULT_IMPL)
}
- debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
- primitive_def_id);
+ /// Load primitive inherent implementations if necessary
+ pub fn populate_implementations_for_primitive_if_necessary(&self,
+ primitive_def_id: ast::DefId) {
+ if primitive_def_id.krate == LOCAL_CRATE {
+ return
+ }
- let impl_items = csearch::get_impl_items(&tcx.sess.cstore, primitive_def_id);
+ if self.populated_external_primitive_impls.borrow().contains(&primitive_def_id) {
+ return
+ }
- // Store the implementation info.
- tcx.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
- tcx.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
-}
+ debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}",
+ primitive_def_id);
-/// Populates the type context with all the inherent implementations for
-/// the given type if necessary.
-pub fn populate_inherent_implementations_for_type_if_necessary(tcx: &ctxt,
- type_id: ast::DefId) {
- if type_id.krate == LOCAL_CRATE {
- return
- }
+ let impl_items = csearch::get_impl_items(&self.sess.cstore, primitive_def_id);
- if tcx.populated_external_types.borrow().contains(&type_id) {
- return
+ // Store the implementation info.
+ self.impl_items.borrow_mut().insert(primitive_def_id, impl_items);
+ self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id);
}
- debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}", type_id);
+ /// Populates the type context with all the inherent implementations for
+ /// the given type if necessary.
+ pub fn populate_inherent_implementations_for_type_if_necessary(&self,
+ type_id: ast::DefId) {
+ if type_id.krate == LOCAL_CRATE {
+ return
+ }
+
+ if self.populated_external_types.borrow().contains(&type_id) {
+ return
+ }
- let mut inherent_impls = Vec::new();
- csearch::each_inherent_implementation_for_type(&tcx.sess.cstore, type_id, |impl_def_id| {
- // Record the implementation.
- inherent_impls.push(impl_def_id);
+ debug!("populate_inherent_implementations_for_type_if_necessary: searching for {:?}",
+ type_id);
- // Store the implementation info.
- let impl_items = csearch::get_impl_items(&tcx.sess.cstore, impl_def_id);
- tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
- });
+ let mut inherent_impls = Vec::new();
+ csearch::each_inherent_implementation_for_type(&self.sess.cstore, type_id, |impl_def_id| {
+ // Record the implementation.
+ inherent_impls.push(impl_def_id);
- tcx.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
- tcx.populated_external_types.borrow_mut().insert(type_id);
-}
+ // Store the implementation info.
+ let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
+ self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
+ });
-/// Populates the type context with all the implementations for the given
-/// trait if necessary.
-pub fn populate_implementations_for_trait_if_necessary(tcx: &ctxt, trait_id: ast::DefId) {
- if trait_id.krate == LOCAL_CRATE {
- return
+ self.inherent_impls.borrow_mut().insert(type_id, Rc::new(inherent_impls));
+ self.populated_external_types.borrow_mut().insert(type_id);
}
- let def = lookup_trait_def(tcx, trait_id);
- if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
- return;
- }
+ /// Populates the type context with all the implementations for the given
+ /// trait if necessary.
+ pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: ast::DefId) {
+ if trait_id.krate == LOCAL_CRATE {
+ return
+ }
- debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
+ let def = self.lookup_trait_def(trait_id);
+ if def.flags.get().intersects(TraitFlags::IMPLS_VALID) {
+ return;
+ }
- if csearch::is_defaulted_trait(&tcx.sess.cstore, trait_id) {
- record_trait_has_default_impl(tcx, trait_id);
- }
+ debug!("populate_implementations_for_trait_if_necessary: searching for {:?}", def);
- csearch::each_implementation_for_trait(&tcx.sess.cstore, trait_id, |implementation_def_id| {
- let impl_items = csearch::get_impl_items(&tcx.sess.cstore, implementation_def_id);
- let trait_ref = impl_trait_ref(tcx, implementation_def_id).unwrap();
- // Record the trait->implementation mapping.
- def.record_impl(tcx, implementation_def_id, trait_ref);
+ if csearch::is_defaulted_trait(&self.sess.cstore, trait_id) {
+ self.record_trait_has_default_impl(trait_id);
+ }
+
+ csearch::each_implementation_for_trait(&self.sess.cstore, trait_id, |impl_def_id| {
+ let impl_items = csearch::get_impl_items(&self.sess.cstore, impl_def_id);
+ let trait_ref = self.impl_trait_ref(impl_def_id).unwrap();
+ // Record the trait->implementation mapping.
+ def.record_impl(self, impl_def_id, trait_ref);
- // For any methods that use a default implementation, add them to
- // the map. This is a bit unfortunate.
- for impl_item_def_id in &impl_items {
- let method_def_id = impl_item_def_id.def_id();
- match impl_or_trait_item(tcx, method_def_id) {
- MethodTraitItem(method) => {
- if let Some(source) = method.provided_source {
- tcx.provided_method_sources
- .borrow_mut()
- .insert(method_def_id, source);
+ // For any methods that use a default implementation, add them to
+ // the map. This is a bit unfortunate.
+ for impl_item_def_id in &impl_items {
+ let method_def_id = impl_item_def_id.def_id();
+ match self.impl_or_trait_item(method_def_id) {
+ MethodTraitItem(method) => {
+ if let Some(source) = method.provided_source {
+ self.provided_method_sources
+ .borrow_mut()
+ .insert(method_def_id, source);
+ }
}
+ _ => {}
}
- _ => {}
}
- }
-
- // Store the implementation info.
- tcx.impl_items.borrow_mut().insert(implementation_def_id, impl_items);
- });
- def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
-}
+ // Store the implementation info.
+ self.impl_items.borrow_mut().insert(impl_def_id, impl_items);
+ });
-/// Given the def_id of an impl, return the def_id of the trait it implements.
-/// If it implements no trait, return `None`.
-pub fn trait_id_of_impl(tcx: &ctxt,
- def_id: ast::DefId)
- -> Option<ast::DefId> {
- ty::impl_trait_ref(tcx, def_id).map(|tr| tr.def_id)
-}
+ def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
+ }
-/// If the given def ID describes a method belonging to an impl, return the
-/// ID of the impl that the method belongs to. Otherwise, return `None`.
-pub fn impl_of_method(tcx: &ctxt, def_id: ast::DefId)
- -> Option<ast::DefId> {
- if def_id.krate != LOCAL_CRATE {
- return match csearch::get_impl_or_trait_item(tcx,
- def_id).container() {
- TraitContainer(_) => None,
- ImplContainer(def_id) => Some(def_id),
- };
+ /// Given the def_id of an impl, return the def_id of the trait it implements.
+ /// If it implements no trait, return `None`.
+ pub fn trait_id_of_impl(&self, def_id: ast::DefId) -> Option<ast::DefId> {
+ self.impl_trait_ref(def_id).map(|tr| tr.def_id)
}
- match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
- Some(trait_item) => {
- match trait_item.container() {
+
+ /// If the given def ID describes a method belonging to an impl, return the
+ /// ID of the impl that the method belongs to. Otherwise, return `None`.
+ pub fn impl_of_method(&self, def_id: ast::DefId) -> Option<ast::DefId> {
+ if def_id.krate != LOCAL_CRATE {
+ return match csearch::get_impl_or_trait_item(self,
+ def_id).container() {
TraitContainer(_) => None,
ImplContainer(def_id) => Some(def_id),
- }
+ };
}
- None => None
- }
-}
-
-/// If the given def ID describes an item belonging to a trait (either a
-/// default method or an implementation of a trait method), return the ID of
-/// the trait that the method belongs to. Otherwise, return `None`.
-pub fn trait_of_item(tcx: &ctxt, def_id: ast::DefId) -> Option<ast::DefId> {
- if def_id.krate != LOCAL_CRATE {
- return csearch::get_trait_of_item(&tcx.sess.cstore, def_id, tcx);
- }
- match tcx.impl_or_trait_items.borrow().get(&def_id).cloned() {
- Some(impl_or_trait_item) => {
- match impl_or_trait_item.container() {
- TraitContainer(def_id) => Some(def_id),
- ImplContainer(def_id) => trait_id_of_impl(tcx, def_id),
+ match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
+ Some(trait_item) => {
+ match trait_item.container() {
+ TraitContainer(_) => None,
+ ImplContainer(def_id) => Some(def_id),
+ }
}
+ None => None
}
- None => None
}
-}
-/// If the given def ID describes an item belonging to a trait, (either a
-/// default method or an implementation of a trait method), return the ID of
-/// the method inside trait definition (this means that if the given def ID
-/// is already that of the original trait method, then the return value is
-/// the same).
-/// Otherwise, return `None`.
-pub fn trait_item_of_item(tcx: &ctxt, def_id: ast::DefId)
- -> Option<ImplOrTraitItemId> {
- let impl_item = match tcx.impl_or_trait_items.borrow().get(&def_id) {
- Some(m) => m.clone(),
- None => return None,
- };
- let name = impl_item.name();
- match trait_of_item(tcx, def_id) {
- Some(trait_did) => {
- let trait_items = ty::trait_items(tcx, trait_did);
- trait_items.iter()
- .position(|m| m.name() == name)
- .map(|idx| ty::trait_item(tcx, trait_did, idx).id())
+ /// If the given def ID describes an item belonging to a trait (either a
+ /// default method or an implementation of a trait method), return the ID of
+ /// the trait that the method belongs to. Otherwise, return `None`.
+ pub fn trait_of_item(&self, def_id: ast::DefId) -> Option<ast::DefId> {
+ if def_id.krate != LOCAL_CRATE {
+ return csearch::get_trait_of_item(&self.sess.cstore, def_id, self);
}
- None => None
- }
-}
-
-/// Creates a hash of the type `Ty` which will be the same no matter what crate
-/// context it's calculated within. This is used by the `type_id` intrinsic.
-pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -> u64 {
- let mut state = SipHasher::new();
- helper(tcx, ty, svh, &mut state);
- return state.finish();
-
- fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
- state: &mut SipHasher) {
- macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
- macro_rules! hash { ($e:expr) => { $e.hash(state) } }
-
- let region = |state: &mut SipHasher, r: Region| {
- match r {
- ReStatic => {}
- ReLateBound(db, BrAnon(i)) => {
- db.hash(state);
- i.hash(state);
+ match self.impl_or_trait_items.borrow().get(&def_id).cloned() {
+ Some(impl_or_trait_item) => {
+ match impl_or_trait_item.container() {
+ TraitContainer(def_id) => Some(def_id),
+ ImplContainer(def_id) => self.trait_id_of_impl(def_id),
}
- ReEmpty |
- ReEarlyBound(..) |
- ReLateBound(..) |
- ReFree(..) |
- ReScope(..) |
- ReInfer(..) => {
- tcx.sess.bug("unexpected region found when hashing a type")
- }
- }
- };
- let did = |state: &mut SipHasher, did: DefId| {
- let h = if ast_util::is_local(did) {
- svh.clone()
- } else {
- tcx.sess.cstore.get_crate_hash(did.krate)
- };
- h.as_str().hash(state);
- did.node.hash(state);
- };
- let mt = |state: &mut SipHasher, mt: mt| {
- mt.mutbl.hash(state);
- };
- let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
- let sig = anonymize_late_bound_regions(tcx, sig).0;
- for a in &sig.inputs { helper(tcx, *a, svh, state); }
- if let ty::FnConverging(output) = sig.output {
- helper(tcx, output, svh, state);
}
+ None => None
+ }
+ }
+
+ /// If the given def ID describes an item belonging to a trait, (either a
+ /// default method or an implementation of a trait method), return the ID of
+ /// the method inside trait definition (this means that if the given def ID
+ /// is already that of the original trait method, then the return value is
+ /// the same).
+ /// Otherwise, return `None`.
+ pub fn trait_item_of_item(&self, def_id: ast::DefId) -> Option<ImplOrTraitItemId> {
+ let impl_item = match self.impl_or_trait_items.borrow().get(&def_id) {
+ Some(m) => m.clone(),
+ None => return None,
};
- ty.maybe_walk(|ty| {
- match ty.sty {
- TyBool => byte!(2),
- TyChar => byte!(3),
- TyInt(i) => {
- byte!(4);
- hash!(i);
- }
- TyUint(u) => {
- byte!(5);
- hash!(u);
- }
- TyFloat(f) => {
- byte!(6);
- hash!(f);
- }
- TyStr => {
- byte!(7);
- }
- TyEnum(d, _) => {
- byte!(8);
- did(state, d);
- }
- TyBox(_) => {
- byte!(9);
- }
- TyArray(_, n) => {
- byte!(10);
- n.hash(state);
- }
- TySlice(_) => {
- byte!(11);
- }
- TyRawPtr(m) => {
- byte!(12);
- mt(state, m);
- }
- TyRef(r, m) => {
- byte!(13);
- region(state, *r);
- mt(state, m);
+ let name = impl_item.name();
+ match self.trait_of_item(def_id) {
+ Some(trait_did) => {
+ let trait_items = self.trait_items(trait_did);
+ trait_items.iter()
+ .position(|m| m.name() == name)
+ .map(|idx| self.trait_item(trait_did, idx).id())
+ }
+ None => None
+ }
+ }
+
+ /// Creates a hash of the type `Ty` which will be the same no matter what crate
+ /// context it's calculated within. This is used by the `type_id` intrinsic.
+ pub fn hash_crate_independent(&self, ty: Ty<'tcx>, svh: &Svh) -> u64 {
+ let mut state = SipHasher::new();
+ helper(self, ty, svh, &mut state);
+ return state.finish();
+
+ fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh,
+ state: &mut SipHasher) {
+ macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
+ macro_rules! hash { ($e:expr) => { $e.hash(state) } }
+
+ let region = |state: &mut SipHasher, r: Region| {
+ match r {
+ ReStatic => {}
+ ReLateBound(db, BrAnon(i)) => {
+ db.hash(state);
+ i.hash(state);
+ }
+ ReEmpty |
+ ReEarlyBound(..) |
+ ReLateBound(..) |
+ ReFree(..) |
+ ReScope(..) |
+ ReInfer(..) => {
+ tcx.sess.bug("unexpected region found when hashing a type")
+ }
}
- TyBareFn(opt_def_id, ref b) => {
- byte!(14);
- hash!(opt_def_id);
- hash!(b.unsafety);
- hash!(b.abi);
- fn_sig(state, &b.sig);
- return false;
+ };
+ let did = |state: &mut SipHasher, did: DefId| {
+ let h = if ast_util::is_local(did) {
+ svh.clone()
+ } else {
+ tcx.sess.cstore.get_crate_hash(did.krate)
+ };
+ h.as_str().hash(state);
+ did.node.hash(state);
+ };
+ let mt = |state: &mut SipHasher, mt: mt| {
+ mt.mutbl.hash(state);
+ };
+ let fn_sig = |state: &mut SipHasher, sig: &Binder<FnSig<'tcx>>| {
+ let sig = tcx.anonymize_late_bound_regions(sig).0;
+ for a in &sig.inputs { helper(tcx, *a, svh, state); }
+ if let ty::FnConverging(output) = sig.output {
+ helper(tcx, output, svh, state);
}
- TyTrait(ref data) => {
- byte!(17);
- did(state, data.principal_def_id());
- hash!(data.bounds);
-
- let principal = anonymize_late_bound_regions(tcx, &data.principal).0;
- for subty in &principal.substs.types {
- helper(tcx, subty, svh, state);
+ };
+ ty.maybe_walk(|ty| {
+ match ty.sty {
+ TyBool => byte!(2),
+ TyChar => byte!(3),
+ TyInt(i) => {
+ byte!(4);
+ hash!(i);
+ }
+ TyUint(u) => {
+ byte!(5);
+ hash!(u);
}
+ TyFloat(f) => {
+ byte!(6);
+ hash!(f);
+ }
+ TyStr => {
+ byte!(7);
+ }
+ TyEnum(d, _) => {
+ byte!(8);
+ did(state, d);
+ }
+ TyBox(_) => {
+ byte!(9);
+ }
+ TyArray(_, n) => {
+ byte!(10);
+ n.hash(state);
+ }
+ TySlice(_) => {
+ byte!(11);
+ }
+ TyRawPtr(m) => {
+ byte!(12);
+ mt(state, m);
+ }
+ TyRef(r, m) => {
+ byte!(13);
+ region(state, *r);
+ mt(state, m);
+ }
+ TyBareFn(opt_def_id, ref b) => {
+ byte!(14);
+ hash!(opt_def_id);
+ hash!(b.unsafety);
+ hash!(b.abi);
+ fn_sig(state, &b.sig);
+ return false;
+ }
+ TyTrait(ref data) => {
+ byte!(17);
+ did(state, data.principal_def_id());
+ hash!(data.bounds);
+
+ let principal = tcx.anonymize_late_bound_regions(&data.principal).0;
+ for subty in &principal.substs.types {
+ helper(tcx, subty, svh, state);
+ }
- return false;
- }
- TyStruct(d, _) => {
- byte!(18);
- did(state, d);
- }
- TyTuple(ref inner) => {
- byte!(19);
- hash!(inner.len());
- }
- TyParam(p) => {
- byte!(20);
- hash!(p.space);
- hash!(p.idx);
- hash!(token::get_name(p.name));
- }
- TyInfer(_) => unreachable!(),
- TyError => byte!(21),
- TyClosure(d, _) => {
- byte!(22);
- did(state, d);
- }
- TyProjection(ref data) => {
- byte!(23);
- did(state, data.trait_ref.def_id);
- hash!(token::get_name(data.item_name));
+ return false;
+ }
+ TyStruct(d, _) => {
+ byte!(18);
+ did(state, d);
+ }
+ TyTuple(ref inner) => {
+ byte!(19);
+ hash!(inner.len());
+ }
+ TyParam(p) => {
+ byte!(20);
+ hash!(p.space);
+ hash!(p.idx);
+ hash!(token::get_name(p.name));
+ }
+ TyInfer(_) => unreachable!(),
+ TyError => byte!(21),
+ TyClosure(d, _) => {
+ byte!(22);
+ did(state, d);
+ }
+ TyProjection(ref data) => {
+ byte!(23);
+ did(state, data.trait_ref.def_id);
+ hash!(token::get_name(data.item_name));
+ }
}
- }
- true
- });
- }
-}
-
-impl fmt::Debug for Variance {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str(match *self {
- Covariant => "+",
- Contravariant => "-",
- Invariant => "o",
- Bivariant => "*",
- })
- }
-}
-
-/// Construct a parameter environment suitable for static contexts or other contexts where there
-/// are no free type/lifetime parameters in scope.
-pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvironment<'a,'tcx> {
- ty::ParameterEnvironment { tcx: cx,
- free_substs: Substs::empty(),
- caller_bounds: Vec::new(),
- implicit_region_bound: ty::ReEmpty,
- selection_cache: traits::SelectionCache::new(), }
-}
-
-/// Constructs and returns a substitution that can be applied to move from
-/// the "outer" view of a type or method to the "inner" view.
-/// In general, this means converting from bound parameters to
-/// free parameters. Since we currently represent bound/free type
-/// parameters in the same way, this only has an effect on regions.
-pub fn construct_free_substs<'a,'tcx>(
- tcx: &'a ctxt<'tcx>,
- generics: &Generics<'tcx>,
- free_id: ast::NodeId)
- -> Substs<'tcx>
-{
- // map T => T
- let mut types = VecPerParamSpace::empty();
- push_types_from_defs(tcx, &mut types, generics.types.as_slice());
-
- let free_id_outlive = region::DestructionScopeData::new(free_id);
-
- // map bound 'a => free 'a
- let mut regions = VecPerParamSpace::empty();
- push_region_params(&mut regions, free_id_outlive, generics.regions.as_slice());
+ true
+ });
+ }
+ }
+
+ /// Construct a parameter environment suitable for static contexts or other contexts where there
+ /// are no free type/lifetime parameters in scope.
+ pub fn empty_parameter_environment<'a>(&'a self) -> ParameterEnvironment<'a,'tcx> {
+ ty::ParameterEnvironment { tcx: self,
+ free_substs: Substs::empty(),
+ caller_bounds: Vec::new(),
+ implicit_region_bound: ty::ReEmpty,
+ selection_cache: traits::SelectionCache::new(), }
+ }
+
+ /// Constructs and returns a substitution that can be applied to move from
+ /// the "outer" view of a type or method to the "inner" view.
+ /// In general, this means converting from bound parameters to
+ /// free parameters. Since we currently represent bound/free type
+ /// parameters in the same way, this only has an effect on regions.
+ pub fn construct_free_substs(&self, generics: &Generics<'tcx>,
+ free_id: ast::NodeId) -> Substs<'tcx> {
+ // map T => T
+ let mut types = VecPerParamSpace::empty();
+ for def in generics.types.as_slice() {
+ debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
+ def);
+ types.push(def.space, self.mk_param_from_def(def));
+ }
- return Substs {
- types: types,
- regions: subst::NonerasedRegions(regions)
- };
+ let free_id_outlive = region::DestructionScopeData::new(free_id);
- fn push_region_params(regions: &mut VecPerParamSpace<ty::Region>,
- all_outlive_extent: region::DestructionScopeData,
- region_params: &[RegionParameterDef])
- {
- for def in region_params {
+ // map bound 'a => free 'a
+ let mut regions = VecPerParamSpace::empty();
+ for def in generics.regions.as_slice() {
let region =
- ReFree(FreeRegion { scope: all_outlive_extent,
+ ReFree(FreeRegion { scope: free_id_outlive,
bound_region: BrNamed(def.def_id, def.name) });
debug!("push_region_params {:?}", region);
regions.push(def.space, region);
}
- }
- fn push_types_from_defs<'tcx>(tcx: &ctxt<'tcx>,
- types: &mut VecPerParamSpace<Ty<'tcx>>,
- defs: &[TypeParameterDef<'tcx>]) {
- for def in defs {
- debug!("construct_parameter_environment(): push_types_from_defs: def={:?}",
- def);
- let ty = tcx.mk_param_from_def(def);
- types.push(def.space, ty);
- }
+ Substs {
+ types: types,
+ regions: subst::NonerasedRegions(regions)
+ }
}
-}
-
-/// See `ParameterEnvironment` struct def'n for details
-pub fn construct_parameter_environment<'a,'tcx>(
- tcx: &'a ctxt<'tcx>,
- span: Span,
- generics: &ty::Generics<'tcx>,
- generic_predicates: &ty::GenericPredicates<'tcx>,
- free_id: ast::NodeId)
- -> ParameterEnvironment<'a, 'tcx>
-{
- //
- // Construct the free substs.
- //
-
- let free_substs = construct_free_substs(tcx, generics, free_id);
- let free_id_outlive = region::DestructionScopeData::new(free_id);
-
- //
- // Compute the bounds on Self and the type parameters.
- //
-
- let bounds = generic_predicates.instantiate(tcx, &free_substs);
- let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
- let predicates = bounds.predicates.into_vec();
- debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
- free_id,
- free_substs,
- predicates);
+ /// See `ParameterEnvironment` struct def'n for details
+ pub fn construct_parameter_environment<'a>(&'a self,
+ span: Span,
+ generics: &ty::Generics<'tcx>,
+ generic_predicates: &ty::GenericPredicates<'tcx>,
+ free_id: ast::NodeId)
+ -> ParameterEnvironment<'a, 'tcx>
+ {
+ //
+ // Construct the free substs.
+ //
- //
- // Finally, we have to normalize the bounds in the environment, in
- // case they contain any associated type projections. This process
- // can yield errors if the put in illegal associated types, like
- // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
- // report these errors right here; this doesn't actually feel
- // right to me, because constructing the environment feels like a
- // kind of a "idempotent" action, but I'm not sure where would be
- // a better place. In practice, we construct environments for
- // every fn once during type checking, and we'll abort if there
- // are any errors at that point, so after type checking you can be
- // sure that this will succeed without errors anyway.
- //
+ let free_substs = self.construct_free_substs(generics, free_id);
+ let free_id_outlive = region::DestructionScopeData::new(free_id);
- let unnormalized_env = ty::ParameterEnvironment {
- tcx: tcx,
- free_substs: free_substs,
- implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
- caller_bounds: predicates,
- selection_cache: traits::SelectionCache::new(),
- };
+ //
+ // Compute the bounds on Self and the type parameters.
+ //
- let cause = traits::ObligationCause::misc(span, free_id);
- traits::normalize_param_env_or_error(unnormalized_env, cause)
-}
+ let bounds = generic_predicates.instantiate(self, &free_substs);
+ let bounds = self.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
+ let predicates = bounds.predicates.into_vec();
-impl BorrowKind {
- pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
- match m {
- ast::MutMutable => MutBorrow,
- ast::MutImmutable => ImmBorrow,
- }
- }
+ debug!("construct_parameter_environment: free_id={:?} free_subst={:?} predicates={:?}",
+ free_id,
+ free_substs,
+ predicates);
- /// Returns a mutability `m` such that an `&m T` pointer could be used to obtain this borrow
- /// kind. Because borrow kinds are richer than mutabilities, we sometimes have to pick a
- /// mutability that is stronger than necessary so that it at least *would permit* the borrow in
- /// question.
- pub fn to_mutbl_lossy(self) -> ast::Mutability {
- match self {
- MutBorrow => ast::MutMutable,
- ImmBorrow => ast::MutImmutable,
+ //
+ // Finally, we have to normalize the bounds in the environment, in
+ // case they contain any associated type projections. This process
+ // can yield errors if the put in illegal associated types, like
+ // `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
+ // report these errors right here; this doesn't actually feel
+ // right to me, because constructing the environment feels like a
+ // kind of a "idempotent" action, but I'm not sure where would be
+ // a better place. In practice, we construct environments for
+ // every fn once during type checking, and we'll abort if there
+ // are any errors at that point, so after type checking you can be
+ // sure that this will succeed without errors anyway.
+ //
- // We have no type corresponding to a unique imm borrow, so
- // use `&mut`. It gives all the capabilities of an `&uniq`
- // and hence is a safe "over approximation".
- UniqueImmBorrow => ast::MutMutable,
- }
- }
+ let unnormalized_env = ty::ParameterEnvironment {
+ tcx: self,
+ free_substs: free_substs,
+ implicit_region_bound: ty::ReScope(free_id_outlive.to_code_extent()),
+ caller_bounds: predicates,
+ selection_cache: traits::SelectionCache::new(),
+ };
- pub fn to_user_str(&self) -> &'static str {
- match *self {
- MutBorrow => "mutable",
- ImmBorrow => "immutable",
- UniqueImmBorrow => "uniquely immutable",
- }
+ let cause = traits::ObligationCause::misc(span, free_id);
+ traits::normalize_param_env_or_error(unnormalized_env, cause)
}
-}
-impl<'tcx> ctxt<'tcx> {
pub fn is_method_call(&self, expr_id: ast::NodeId) -> bool {
self.method_map.borrow().contains_key(&MethodCall::expr(expr_id))
}
}
}
-impl<'a,'tcx> mc::Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
+impl<'a,'tcx> Typer<'tcx> for ParameterEnvironment<'a,'tcx> {
fn node_ty(&self, id: ast::NodeId) -> mc::McResult<Ty<'tcx>> {
- Ok(ty::node_id_to_type(self.tcx, id))
+ Ok(self.tcx.node_id_to_type(id))
}
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> mc::McResult<Ty<'tcx>> {
- Ok(ty::expr_ty_adjusted(self.tcx, expr))
+ Ok(self.tcx.expr_ty_adjusted(expr))
}
fn node_method_ty(&self, method_call: ty::MethodCall) -> Option<Ty<'tcx>> {
self.tcx.upvar_capture(upvar_id)
}
- fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
- type_moves_by_default(self, span, ty)
+ fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
+ ty.moves_by_default(self, span)
}
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
- -> Option<Vec<ClosureUpvar<'tcx>>>
- {
- closure_upvars(self, def_id, substs)
+ -> Option<Vec<ClosureUpvar<'tcx>>> {
+ ctxt::closure_upvars(self, def_id, substs)
}
}
ByBoxExplicitSelfCategory,
}
-/// Pushes all the lifetimes in the given type onto the given list. A
-/// "lifetime in a type" is a lifetime specified by a reference or a lifetime
-/// in a list of type substitutions. This does *not* traverse into nominal
-/// types, nor does it resolve fictitious types.
-pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
- ty: Ty) {
- for ty in ty.walk() {
- match ty.sty {
- TyRef(region, _) => {
- accumulator.push(*region)
- }
- TyTrait(ref t) => {
- accumulator.push_all(t.principal.0.substs.regions().as_slice());
- }
- TyEnum(_, substs) |
- TyStruct(_, substs) => {
- accum_substs(accumulator, substs);
- }
- TyClosure(_, substs) => {
- accum_substs(accumulator, substs);
- }
- TyBool |
- TyChar |
- TyInt(_) |
- TyUint(_) |
- TyFloat(_) |
- TyBox(_) |
- TyStr |
- TyArray(_, _) |
- TySlice(_) |
- TyRawPtr(_) |
- TyBareFn(..) |
- TyTuple(_) |
- TyProjection(_) |
- TyParam(_) |
- TyInfer(_) |
- TyError => {
+impl<'tcx> TyS<'tcx> {
+ /// Pushes all the lifetimes in the given type onto the given list. A
+ /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
+ /// in a list of type substitutions. This does *not* traverse into nominal
+ /// types, nor does it resolve fictitious types.
+ pub fn accumulate_lifetimes_in_type(&self, accumulator: &mut Vec<ty::Region>) {
+ for ty in self.walk() {
+ match ty.sty {
+ TyRef(region, _) => {
+ accumulator.push(*region)
+ }
+ TyTrait(ref t) => {
+ accumulator.push_all(t.principal.0.substs.regions().as_slice());
+ }
+ TyEnum(_, substs) |
+ TyStruct(_, substs) => {
+ accum_substs(accumulator, substs);
+ }
+ TyClosure(_, substs) => {
+ accum_substs(accumulator, substs);
+ }
+ TyBool |
+ TyChar |
+ TyInt(_) |
+ TyUint(_) |
+ TyFloat(_) |
+ TyBox(_) |
+ TyStr |
+ TyArray(_, _) |
+ TySlice(_) |
+ TyRawPtr(_) |
+ TyBareFn(..) |
+ TyTuple(_) |
+ TyProjection(_) |
+ TyParam(_) |
+ TyInfer(_) |
+ TyError => {
+ }
}
}
- }
- fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
- match substs.regions {
- subst::ErasedRegions => {}
- subst::NonerasedRegions(ref regions) => {
- for region in regions {
- accumulator.push(*region)
+ fn accum_substs(accumulator: &mut Vec<Region>, substs: &Substs) {
+ match substs.regions {
+ subst::ErasedRegions => {}
+ subst::NonerasedRegions(ref regions) => {
+ for region in regions {
+ accumulator.push(*region)
+ }
}
}
}
// imported.
pub type GlobMap = HashMap<NodeId, HashSet<Name>>;
-pub fn with_freevars<T, F>(tcx: &ctxt, fid: ast::NodeId, f: F) -> T where
- F: FnOnce(&[Freevar]) -> T,
-{
- match tcx.freevars.borrow().get(&fid) {
- None => f(&[]),
- Some(d) => f(&d[..])
- }
-}
-
impl<'tcx> AutoAdjustment<'tcx> {
pub fn is_identity(&self) -> bool {
match *self {
}
}
-/// Replace any late-bound regions bound in `value` with free variants attached to scope-id
-/// `scope_id`.
-pub fn liberate_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- all_outlive_scope: region::DestructionScopeData,
- value: &Binder<T>)
- -> T
- where T : TypeFoldable<'tcx>
-{
- ty_fold::replace_late_bound_regions(
- tcx, value,
- |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
-}
+impl<'tcx> ctxt<'tcx> {
+ pub fn with_freevars<T, F>(&self, fid: ast::NodeId, f: F) -> T where
+ F: FnOnce(&[Freevar]) -> T,
+ {
+ match self.freevars.borrow().get(&fid) {
+ None => f(&[]),
+ Some(d) => f(&d[..])
+ }
+ }
-pub fn count_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- value: &Binder<T>)
- -> usize
- where T : TypeFoldable<'tcx>
-{
- let (_, skol_map) = ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic);
- skol_map.len()
-}
+ /// Replace any late-bound regions bound in `value` with free variants attached to scope-id
+ /// `scope_id`.
+ pub fn liberate_late_bound_regions<T>(&self,
+ all_outlive_scope: region::DestructionScopeData,
+ value: &Binder<T>)
+ -> T
+ where T : TypeFoldable<'tcx>
+ {
+ ty_fold::replace_late_bound_regions(
+ self, value,
+ |br| ty::ReFree(ty::FreeRegion{scope: all_outlive_scope, bound_region: br})).0
+ }
-pub fn binds_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- value: &Binder<T>)
- -> bool
- where T : TypeFoldable<'tcx>
-{
- count_late_bound_regions(tcx, value) > 0
-}
+ pub fn count_late_bound_regions<T>(&self, value: &Binder<T>) -> usize
+ where T : TypeFoldable<'tcx>
+ {
+ let (_, skol_map) = ty_fold::replace_late_bound_regions(self, value, |_| ty::ReStatic);
+ skol_map.len()
+ }
-/// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
-/// becomes `for<'a,'b> Foo`.
-pub fn flatten_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- bound2_value: &Binder<Binder<T>>)
- -> Binder<T>
- where T: TypeFoldable<'tcx>
-{
- let bound0_value = bound2_value.skip_binder().skip_binder();
- let value = ty_fold::fold_regions(tcx, bound0_value, |region, current_depth| {
- match region {
- ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
- // should be true if no escaping regions from bound2_value
- assert!(debruijn.depth - current_depth <= 1);
- ty::ReLateBound(DebruijnIndex::new(current_depth), br)
- }
- _ => {
- region
+ pub fn binds_late_bound_regions<T>(&self, value: &Binder<T>) -> bool
+ where T : TypeFoldable<'tcx>
+ {
+ self.count_late_bound_regions(value) > 0
+ }
+
+ /// Flattens two binding levels into one. So `for<'a> for<'b> Foo`
+ /// becomes `for<'a,'b> Foo`.
+ pub fn flatten_late_bound_regions<T>(&self, bound2_value: &Binder<Binder<T>>)
+ -> Binder<T>
+ where T: TypeFoldable<'tcx>
+ {
+ let bound0_value = bound2_value.skip_binder().skip_binder();
+ let value = ty_fold::fold_regions(self, bound0_value, |region, current_depth| {
+ match region {
+ ty::ReLateBound(debruijn, br) if debruijn.depth >= current_depth => {
+ // should be true if no escaping regions from bound2_value
+ assert!(debruijn.depth - current_depth <= 1);
+ ty::ReLateBound(DebruijnIndex::new(current_depth), br)
+ }
+ _ => {
+ region
+ }
}
+ });
+ Binder(value)
+ }
+
+ pub fn no_late_bound_regions<T>(&self, value: &Binder<T>) -> Option<T>
+ where T : TypeFoldable<'tcx>
+ {
+ if self.binds_late_bound_regions(value) {
+ None
+ } else {
+ Some(value.0.clone())
}
- });
- Binder(value)
-}
+ }
-pub fn no_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- value: &Binder<T>)
- -> Option<T>
- where T : TypeFoldable<'tcx>
-{
- if binds_late_bound_regions(tcx, value) {
- None
- } else {
- Some(value.0.clone())
+ /// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
+ /// method lookup and a few other places where precise region relationships are not required.
+ pub fn erase_late_bound_regions<T>(&self, value: &Binder<T>) -> T
+ where T : TypeFoldable<'tcx>
+ {
+ ty_fold::replace_late_bound_regions(self, value, |_| ty::ReStatic).0
}
-}
-/// Replace any late-bound regions bound in `value` with `'static`. Useful in trans but also
-/// method lookup and a few other places where precise region relationships are not required.
-pub fn erase_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- value: &Binder<T>)
- -> T
- where T : TypeFoldable<'tcx>
-{
- ty_fold::replace_late_bound_regions(tcx, value, |_| ty::ReStatic).0
-}
+ /// Rewrite any late-bound regions so that they are anonymous. Region numbers are
+ /// assigned starting at 1 and increasing monotonically in the order traversed
+ /// by the fold operation.
+ ///
+ /// The chief purpose of this function is to canonicalize regions so that two
+ /// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
+ /// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
+ /// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
+ pub fn anonymize_late_bound_regions<T>(&self, sig: &Binder<T>) -> Binder<T>
+ where T : TypeFoldable<'tcx>,
+ {
+ let mut counter = 0;
+ ty::Binder(ty_fold::replace_late_bound_regions(self, sig, |_| {
+ counter += 1;
+ ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
+ }).0)
+ }
-/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
-/// assigned starting at 1 and increasing monotonically in the order traversed
-/// by the fold operation.
-///
-/// The chief purpose of this function is to canonicalize regions so that two
-/// `FnSig`s or `TraitRef`s which are equivalent up to region naming will become
-/// structurally identical. For example, `for<'a, 'b> fn(&'a isize, &'b isize)` and
-/// `for<'a, 'b> fn(&'b isize, &'a isize)` will become identical after anonymization.
-pub fn anonymize_late_bound_regions<'tcx, T>(
- tcx: &ctxt<'tcx>,
- sig: &Binder<T>)
- -> Binder<T>
- where T : TypeFoldable<'tcx>,
-{
- let mut counter = 0;
- ty::Binder(ty_fold::replace_late_bound_regions(tcx, sig, |_| {
- counter += 1;
- ReLateBound(ty::DebruijnIndex::new(1), BrAnon(counter))
- }).0)
+ pub fn make_substs_for_receiver_types(&self,
+ trait_ref: &ty::TraitRef<'tcx>,
+ method: &ty::Method<'tcx>)
+ -> subst::Substs<'tcx>
+ {
+ /*!
+ * Substitutes the values for the receiver's type parameters
+ * that are found in method, leaving the method's type parameters
+ * intact.
+ */
+
+ let meth_tps: Vec<Ty> =
+ method.generics.types.get_slice(subst::FnSpace)
+ .iter()
+ .map(|def| self.mk_param_from_def(def))
+ .collect();
+ let meth_regions: Vec<ty::Region> =
+ method.generics.regions.get_slice(subst::FnSpace)
+ .iter()
+ .map(|def| def.to_early_bound_region())
+ .collect();
+ trait_ref.substs.clone().with_method(meth_tps, meth_regions)
+ }
}
impl DebruijnIndex {
}
}
-pub fn make_substs_for_receiver_types<'tcx>(tcx: &ctxt<'tcx>,
- trait_ref: &ty::TraitRef<'tcx>,
- method: &ty::Method<'tcx>)
- -> subst::Substs<'tcx>
-{
- /*!
- * Substitutes the values for the receiver's type parameters
- * that are found in method, leaving the method's type parameters
- * intact.
- */
-
- let meth_tps: Vec<Ty> =
- method.generics.types.get_slice(subst::FnSpace)
- .iter()
- .map(|def| tcx.mk_param_from_def(def))
- .collect();
- let meth_regions: Vec<ty::Region> =
- method.generics.regions.get_slice(subst::FnSpace)
- .iter()
- .map(|def| def.to_early_bound_region())
- .collect();
- trait_ref.substs.clone().with_method(meth_tps, meth_regions)
-}
-
-#[derive(Copy, Clone)]
-pub enum CopyImplementationError {
- FieldDoesNotImplementCopy(ast::Name),
- VariantDoesNotImplementCopy(ast::Name),
- TypeIsStructural,
- TypeHasDestructor,
-}
-
-pub fn can_type_implement_copy<'a,'tcx>(param_env: &ParameterEnvironment<'a, 'tcx>,
- span: Span,
- self_type: Ty<'tcx>)
- -> Result<(),CopyImplementationError>
-{
- let tcx = param_env.tcx;
-
- let did = match self_type.sty {
- ty::TyStruct(struct_did, substs) => {
- let fields = ty::struct_fields(tcx, struct_did, substs);
- for field in &fields {
- if type_moves_by_default(param_env, span, field.mt.ty) {
- return Err(FieldDoesNotImplementCopy(field.name))
- }
- }
- struct_did
- }
- ty::TyEnum(enum_did, substs) => {
- let enum_variants = ty::enum_variants(tcx, enum_did);
- for variant in enum_variants.iter() {
- for variant_arg_type in &variant.args {
- let substd_arg_type =
- variant_arg_type.subst(tcx, substs);
- if type_moves_by_default(param_env, span, substd_arg_type) {
- return Err(VariantDoesNotImplementCopy(variant.name))
- }
- }
- }
- enum_did
- }
- _ => return Err(TypeIsStructural),
- };
-
- if ty::has_dtor(tcx, did) {
- return Err(TypeHasDestructor)
- }
-
- Ok(())
-}
-
// FIXME(#20298) -- all of these traits basically walk various
// structures to test whether types/regions are reachable with various
// properties. It should be possible to express them in terms of one
let variances;
let opt_variances = if relation.tcx().variance_computed.get() {
- variances = ty::item_variances(relation.tcx(), item_def_id);
+ variances = relation.tcx().item_variances(item_def_id);
Some(&*variances)
} else {
None
where GG: for<'tcx> FnOnce(&ty::ctxt<'tcx>) -> ty::Generics<'tcx>
{
let (fn_trait_kind, verbose) = try!(ty::tls::with(|tcx| {
- try!(write!(f, "{}", ty::item_path_str(tcx, did)));
+ try!(write!(f, "{}", tcx.item_path_str(did)));
Ok((tcx.lang_items.fn_trait_kind(did), tcx.sess.verbose()))
}));
parameterized(f, trait_ref.substs,
trait_ref.def_id,
projection_bounds,
- |tcx| ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
+ |tcx| tcx.lookup_trait_def(trait_ref.def_id).generics.clone())
}
}
impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
parameterized(f, self.substs, self.def_id, &[],
- |tcx| ty::lookup_trait_def(tcx, self.def_id).generics.clone())
+ |tcx| tcx.lookup_trait_def(self.def_id).generics.clone())
}
}
if let Some(def_id) = opt_def_id {
try!(write!(f, " {{{}}}", ty::tls::with(|tcx| {
- ty::item_path_str(tcx, def_id)
+ tcx.item_path_str(def_id)
})));
}
Ok(())
TyParam(ref param_ty) => write!(f, "{}", param_ty),
TyEnum(did, substs) | TyStruct(did, substs) => {
parameterized(f, substs, did, &[],
- |tcx| ty::lookup_item_type(tcx, did).generics)
+ |tcx| tcx.lookup_item_type(did).generics)
}
TyTrait(ref data) => write!(f, "{}", data),
ty::TyProjection(ref data) => write!(f, "{}", data),
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "UpvarId({};`{}`;{})",
self.var_id,
- ty::tls::with(|tcx| ty::local_var_name_str(tcx, self.var_id)),
+ ty::tls::with(|tcx| tcx.local_var_name_str(self.var_id)),
self.closure_expr_id)
}
}
LpExtend(ref lp_base, _, LpInterior(InteriorField(_))) => {
match lp_base.to_type().sty {
ty::TyStruct(def_id, _) | ty::TyEnum(def_id, _) => {
- if ty::has_dtor(self.tcx(), def_id) {
+ if self.tcx().has_dtor(def_id) {
// In the case where the owner implements drop, then
// the path must be initialized to prevent a case of
// partial reinitialization
}
(&ty::TyStruct(def_id, ref _substs), None) => {
- let fields = ty::lookup_struct_fields(tcx, def_id);
+ let fields = tcx.lookup_struct_fields(def_id);
match *origin_field_name {
mc::NamedField(ast_name) => {
for f in &fields {
(&ty::TyEnum(enum_def_id, substs), ref enum_variant_info) => {
let variant_info = {
- let mut variants = ty::substd_enum_variants(tcx, enum_def_id, substs);
+ let mut variants = tcx.substd_enum_variants(enum_def_id, substs);
match *enum_variant_info {
Some((variant_def_id, ref _lp2)) =>
variants.iter()
let loan_path_elem = LpInterior(InteriorField(new_field_name));
let new_lp_type = match new_field_name {
mc::NamedField(ast_name) =>
- ty::named_element_ty(tcx, parent.to_type(), ast_name, opt_variant_did),
+ tcx.named_element_ty(parent.to_type(), ast_name, opt_variant_did),
mc::PositionalField(idx) =>
- ty::positional_element_ty(tcx, parent.to_type(), idx, opt_variant_did),
+ tcx.positional_element_ty(parent.to_type(), idx, opt_variant_did),
};
let new_lp_variant = LpExtend(parent, mc, loan_path_elem);
let new_lp = LoanPath::new(new_lp_variant, new_lp_type.unwrap());
decl_id: ast::NodeId,
_decl_span: Span,
var_id: ast::NodeId) {
- let ty = ty::node_id_to_type(bccx.tcx, var_id);
+ let ty = bccx.tcx.node_id_to_type(var_id);
let loan_path = Rc::new(LoanPath::new(LpVar(var_id), ty));
move_data.add_move(bccx.tcx, loan_path, decl_id, Declared);
}
mc::cat_interior(ref b, mc::InteriorElement(Kind::Pattern, _)) => {
match b.ty.sty {
ty::TyStruct(did, _) | ty::TyEnum(did, _) => {
- if ty::has_dtor(bccx.tcx, did) {
+ if bccx.tcx.has_dtor(did) {
Some(cmt.clone())
} else {
check_and_get_illegal_move_origin(bccx, b)
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
if let ast::ExprAddrOf(mutbl, ref base) = ex.node {
- let param_env = ty::empty_parameter_environment(self.bccx.tcx);
+ let param_env = self.bccx.tcx.empty_parameter_environment();
let mc = mc::MemCategorizationContext::new(¶m_env);
let base_cmt = mc.cat_expr(&**base).unwrap();
let borrow_kind = ty::BorrowKind::from_mutbl(mutbl);
mc::cat_interior(ref b, mc::InteriorField(_)) => {
match b.ty.sty {
ty::TyStruct(did, _) |
- ty::TyEnum(did, _) if ty::has_dtor(bccx.tcx, did) => {
+ ty::TyEnum(did, _) if bccx.tcx.has_dtor(did) => {
bccx.span_err(
move_from.span,
&format!("cannot move out of type `{}`, \
use rustc::middle::dataflow::KillFrom;
use rustc::middle::expr_use_visitor as euv;
use rustc::middle::free_region::FreeRegionMap;
-use rustc::middle::infer::error_reporting::note_and_explain_region;
use rustc::middle::mem_categorization as mc;
+use rustc::middle::mem_categorization::Typer;
use rustc::middle::region;
use rustc::middle::ty::{self, Ty};
.map
.find(the_move.id) {
Some(ast_map::NodeExpr(expr)) => {
- (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
+ (self.tcx.expr_ty_adjusted(&*expr), expr.span)
}
r => {
self.tcx.sess.bug(&format!("MoveExpr({}) maps to \
}
move_data::MovePat => {
- let pat_ty = ty::node_id_to_type(self.tcx, the_move.id);
+ let pat_ty = self.tcx.node_id_to_type(the_move.id);
let span = self.tcx.map.span(the_move.id);
self.tcx.sess.span_note(span,
&format!("`{}` moved here{} because it has type `{}`, \
.map
.find(the_move.id) {
Some(ast_map::NodeExpr(expr)) => {
- (ty::expr_ty_adjusted(self.tcx, &*expr), expr.span)
+ (self.tcx.expr_ty_adjusted(&*expr), expr.span)
}
r => {
self.tcx.sess.bug(&format!("Captured({}) maps to \
-> (&'static str, &'static str) {
match ty.sty {
_ => {
- if ty::type_moves_by_default(param_env, span, ty) {
+ if param_env.type_moves_by_default(ty, span) {
("non-copyable",
"perhaps you meant to use `clone()`?")
} else {
}
err_out_of_scope(super_scope, sub_scope) => {
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"reference must be valid for ",
sub_scope,
"...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
"...but borrowed value is only valid for ",
super_scope,
"");
}
None => self.cmt_to_string(&*err.cmt),
};
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
&format!("{} would have to be valid for ",
descr),
loan_scope,
"...");
- note_and_explain_region(
- self.tcx,
+ self.tcx.note_and_explain_region(
&format!("...but {} is only valid for ", descr),
ptr_scope,
"");
match loan_path.kind {
LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) |
LpVar(id) => {
- out.push_str(&ty::local_var_name_str(self.tcx, id));
+ out.push_str(&self.tcx.local_var_name_str(id));
}
LpDowncast(ref lp_base, variant_def_id) => {
out.push('(');
self.append_loan_path_to_string(&**lp_base, out);
out.push_str(DOWNCAST_PRINTED_OPERATOR);
- out.push_str(&ty::item_path_str(self.tcx, variant_def_id));
+ out.push_str(&self.tcx.item_path_str(variant_def_id));
out.push(')');
}
out.push('(');
self.append_autoderefd_loan_path_to_string(&**lp_base, out);
out.push(':');
- out.push_str(&ty::item_path_str(self.tcx, variant_def_id));
+ out.push_str(&self.tcx.item_path_str(variant_def_id));
out.push(')');
}
LpDowncast(ref lp, variant_def_id) => {
let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE {
- ty::tls::with(|tcx| ty::item_path_str(tcx, variant_def_id))
+ ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
} else {
format!("{:?}", variant_def_id)
};
LpDowncast(ref lp, variant_def_id) => {
let variant_str = if variant_def_id.krate == ast::LOCAL_CRATE {
- ty::tls::with(|tcx| ty::item_path_str(tcx, variant_def_id))
+ ty::tls::with(|tcx| tcx.item_path_str(variant_def_id))
} else {
format!("{:?}", variant_def_id)
};
time(time_passes, "static item recursion checking", (), |_|
middle::check_static_recursion::check_crate(&sess, krate, &def_map, &ast_map));
- ty::with_ctxt(sess,
- arenas,
- def_map,
- named_region_map,
- ast_map,
- freevars,
- region_map,
- lang_items,
- stability::Index::new(krate),
- |tcx| {
+ ty::ctxt::create_and_enter(sess,
+ arenas,
+ def_map,
+ named_region_map,
+ ast_map,
+ freevars,
+ region_map,
+ lang_items,
+ stability::Index::new(krate),
+ |tcx| {
// passes are timed inside typeck
typeck::check_crate(tcx, trait_map);
try!(pp::word(&mut s.s, "as"));
try!(pp::space(&mut s.s));
try!(pp::word(&mut s.s,
- &ty::expr_ty(self.tcx, expr).to_string()));
+ &self.tcx.expr_ty(expr).to_string()));
s.pclose()
}
_ => Ok(())
resolve::resolve_crate(&sess, &ast_map, resolve::MakeGlobMap::No);
let named_region_map = resolve_lifetime::krate(&sess, krate, &def_map);
let region_map = region::resolve_crate(&sess, krate);
- ty::with_ctxt(sess,
- &arenas,
- def_map,
- named_region_map,
- ast_map,
- freevars,
- region_map,
- lang_items,
- stability::Index::new(krate),
- |tcx| {
+ ty::ctxt::create_and_enter(sess,
+ &arenas,
+ def_map,
+ named_region_map,
+ ast_map,
+ freevars,
+ region_map,
+ lang_items,
+ stability::Index::new(krate),
+ |tcx| {
let infcx = infer::new_infer_ctxt(tcx);
body(Env { infcx: &infcx });
let free_regions = FreeRegionMap::new();
use metadata::{csearch, decoder};
use middle::def::*;
+use middle::mem_categorization::Typer;
use middle::subst::Substs;
use middle::ty::{self, Ty};
use middle::{def, pat_util, stability};
}
},
_ => {
- let t = ty::expr_ty(cx.tcx, &**expr);
+ let t = cx.tcx.expr_ty(&**expr);
match t.sty {
ty::TyUint(_) => {
cx.span_lint(UNSIGNED_NEGATION, e.span,
}
if is_shift_binop(binop.node) {
- let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty {
+ let opt_ty_bits = match cx.tcx.expr_ty(&**l).sty {
ty::TyInt(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
ty::TyUint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
_ => None
}
},
ast::ExprLit(ref lit) => {
- match ty::expr_ty(cx.tcx, e).sty {
+ match cx.tcx.expr_ty(e).sty {
ty::TyInt(t) => {
match lit.node {
ast::LitInt(v, ast::SignedIntLit(_, ast::Plus)) |
} else {
binop
};
- match ty::expr_ty(tcx, expr).sty {
+ match tcx.expr_ty(expr).sty {
ty::TyInt(int_ty) => {
let (min, max) = int_ty_range(int_ty);
let lit_val: i64 = match lit.node {
None => panic!("ast_ty_to_ty_cache was incomplete after typeck!")
};
- if !ty::is_ffi_safe(self.cx.tcx, tty) {
+ if !tty.is_ffi_safe(self.cx.tcx) {
self.cx.span_lint(IMPROPER_CTYPES, sp,
"found type without foreign-function-safe \
representation annotation in foreign module, consider \
impl BoxPointers {
fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
span: Span, ty: Ty<'tcx>) {
- let mut n_uniq: usize = 0;
- ty::fold_ty(cx.tcx, ty, |t| {
- match t.sty {
- ty::TyBox(_) => {
- n_uniq += 1;
- }
- _ => ()
- };
- t
- });
-
- if n_uniq > 0 {
- let m = format!("type uses owned (Box type) pointers: {}", ty);
- cx.span_lint(BOX_POINTERS, span, &m[..]);
+ for leaf_ty in ty.walk() {
+ if let ty::TyBox(_) = leaf_ty.sty {
+ let m = format!("type uses owned (Box type) pointers: {}", ty);
+ cx.span_lint(BOX_POINTERS, span, &m);
+ }
}
}
}
ast::ItemEnum(..) |
ast::ItemStruct(..) =>
self.check_heap_type(cx, it.span,
- ty::node_id_to_type(cx.tcx, it.id)),
+ cx.tcx.node_id_to_type(it.id)),
_ => ()
}
ast::ItemStruct(ref struct_def, _) => {
for struct_field in &struct_def.fields {
self.check_heap_type(cx, struct_field.span,
- ty::node_id_to_type(cx.tcx, struct_field.node.id));
+ cx.tcx.node_id_to_type(struct_field.node.id));
}
}
_ => ()
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
- let ty = ty::expr_ty(cx.tcx, e);
+ let ty = cx.tcx.expr_ty(e);
self.check_heap_type(cx, e.span, ty);
}
}
ast::ItemImpl(_, _, _, ref t_ref_opt, _, _) => {
// Deriving the Copy trait does not cause a warning
if let &Some(ref trait_ref) = t_ref_opt {
- let def_id = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+ let def_id = cx.tcx.trait_ref_to_def_id(trait_ref);
if Some(def_id) == cx.tcx.lang_items.copy_trait() {
return;
}
}
- match ty::node_id_to_type(cx.tcx, item.id).sty {
+ match cx.tcx.node_id_to_type(item.id).sty {
ty::TyEnum(did, _) => did,
ty::TyStruct(did, _) => did,
_ => return,
return;
}
- let t = ty::expr_ty(cx.tcx, expr);
+ let t = cx.tcx.expr_ty(expr);
let warned = match t.sty {
ty::TyTuple(ref tys) if tys.is_empty() => return,
ty::TyBool => return,
Some(item) => match item.container() {
ty::TraitContainer(..) => MethodContext::TraitDefaultImpl,
ty::ImplContainer(cid) => {
- match ty::impl_trait_ref(cx.tcx, cid) {
+ match cx.tcx.impl_trait_ref(cid) {
Some(_) => MethodContext::TraitImpl,
None => MethodContext::PlainImpl
}
ast::ItemImpl(_, _, _, Some(ref trait_ref), _, ref impl_items) => {
// If the trait is private, add the impl items to private_traits so they don't get
// reported for missing docs.
- let real_trait = ty::trait_ref_to_def_id(cx.tcx, trait_ref);
+ let real_trait = cx.tcx.trait_ref_to_def_id(trait_ref);
match cx.tcx.map.find(real_trait.node) {
Some(ast_map::NodeItem(item)) => if item.vis == ast::Visibility::Inherited {
for itm in impl_items {
}
_ => return,
};
- let parameter_environment = ty::empty_parameter_environment(cx.tcx);
- if !ty::type_moves_by_default(¶meter_environment, item.span, ty) {
+ let parameter_environment = cx.tcx.empty_parameter_environment();
+ if !parameter_environment.type_moves_by_default(ty, item.span) {
return;
}
- if ty::can_type_implement_copy(¶meter_environment, item.span, ty).is_ok() {
+ if parameter_environment.can_type_implement_copy(ty, item.span).is_ok() {
cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
item.span,
"type could implement `Copy`; consider adding `impl \
};
if self.impling_types.is_none() {
- let debug_def = ty::lookup_trait_def(cx.tcx, debug);
+ let debug_def = cx.tcx.lookup_trait_def(debug);
let mut impls = NodeSet();
debug_def.for_each_impl(cx.tcx, |d| {
if d.krate == ast::LOCAL_CRATE {
- if let Some(ty_def) = ty::ty_to_def_id(ty::node_id_to_type(cx.tcx, d.node)) {
+ if let Some(ty_def) = cx.tcx.node_id_to_type(d.node).ty_to_def_id() {
impls.insert(ty_def.node);
}
}
visit::FkFnBlock => return
};
- let impl_def_id = ty::impl_of_method(cx.tcx, local_def(id))
+ let impl_def_id = cx.tcx.impl_of_method(local_def(id))
.unwrap_or(local_def(ast::DUMMY_NODE_ID));
assert!(ast_util::is_local(impl_def_id));
let impl_node_id = impl_def_id.node;
// method instead.
ty::MethodTypeParam(
ty::MethodParam { ref trait_ref, method_num, impl_def_id: None, }) => {
- ty::trait_item(tcx, trait_ref.def_id, method_num).def_id()
+ tcx.trait_item(trait_ref.def_id, method_num).def_id()
}
// The `impl` is known, so we check that with a
ast::ExprPath(..) => (),
_ => return None
}
- if let DefFn(did, _) = ty::resolve_expr(cx.tcx, expr) {
+ if let DefFn(did, _) = cx.tcx.resolve_expr(expr) {
if !def_id_is_transmute(cx, did) {
return None;
}
- let typ = ty::node_id_to_type(cx.tcx, expr.id);
+ let typ = cx.tcx.node_id_to_type(expr.id);
match typ.sty {
ty::TyBareFn(_, ref bare_fn) if bare_fn.abi == RustIntrinsic => {
if let ty::FnConverging(to) = bare_fn.sig.0.output {
}
fn def_id_is_transmute(cx: &Context, def_id: DefId) -> bool {
- match ty::lookup_item_type(cx.tcx, def_id).ty.sty {
+ match cx.tcx.lookup_item_type(def_id).ty.sty {
ty::TyBareFn(_, ref bfty) if bfty.abi == RustIntrinsic => (),
_ => return false
}
- ty::with_path(cx.tcx, def_id, |path| match path.last() {
+ cx.tcx.with_path(def_id, |path| match path.last() {
Some(ref last) => last.name().as_str() == "transmute",
_ => false
})
let (drop_impl_did, dtor_self_type) =
if dtor_did.krate == ast::LOCAL_CRATE {
let impl_did = ctx.tcx.map.get_parent_did(dtor_did.node);
- let ty = ty::lookup_item_type(ctx.tcx, impl_did).ty;
+ let ty = ctx.tcx.lookup_item_type(impl_did).ty;
(impl_did, ty)
} else {
continue;
ty::TyEnum(self_type_did, _) |
ty::TyStruct(self_type_did, _) |
ty::TyClosure(self_type_did, _) => {
- let hints = ty::lookup_repr_hints(ctx.tcx, self_type_did);
+ let hints = ctx.tcx.lookup_repr_hints(self_type_did);
if hints.iter().any(|attr| *attr == attr::ReprExtern) &&
- ty::ty_dtor(ctx.tcx, self_type_did).has_drop_flag() {
+ ctx.tcx.ty_dtor(self_type_did).has_drop_flag() {
let drop_impl_span = ctx.tcx.map.def_id_span(drop_impl_did,
codemap::DUMMY_SP);
let self_defn_span = ctx.tcx.map.def_id_span(self_type_did,
}
_ => true,
};
- let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
+ let tr = self.tcx.impl_trait_ref(local_def(item.id));
let public_trait = tr.clone().map_or(false, |tr| {
!is_local(tr.def_id) ||
self.exported_items.contains(&tr.def_id.node)
self.def_privacy(id)
}
ty::ImplContainer(id) => {
- match ty::impl_trait_ref(self.tcx, id) {
+ match self.tcx.impl_trait_ref(id) {
Some(t) => {
debug!("privacy - impl of trait {:?}", id);
self.def_privacy(t.def_id)
self.def_privacy(id)
}
ty::ImplContainer(id) => {
- match ty::impl_trait_ref(self.tcx, id) {
+ match self.tcx.impl_trait_ref(id) {
Some(t) => {
debug!("privacy - impl of trait {:?}", id);
self.def_privacy(t.def_id)
self.def_privacy(id)
}
ty::ImplContainer(id) => {
- match ty::impl_trait_ref(self.tcx, id) {
+ match self.tcx.impl_trait_ref(id) {
Some(t) => {
debug!("privacy - impl of trait {:?}", id);
self.def_privacy(t.def_id)
ast::MethodImplItem(..) => {
let imp = self.tcx.map
.get_parent_did(closest_private_id);
- match ty::impl_trait_ref(self.tcx, imp) {
+ match self.tcx.impl_trait_ref(imp) {
Some(..) => return Allowable,
_ if ii.vis == ast::Public => {
return Allowable
span: Span,
id: ast::DefId,
name: FieldName) {
- let fields = ty::lookup_struct_fields(self.tcx, id);
+ let fields = self.tcx.lookup_struct_fields(id);
let field = match name {
NamedField(f_name) => {
debug!("privacy - check named field {} in struct {:?}", f_name, id);
return
}
- let struct_type = ty::lookup_item_type(self.tcx, id).ty;
+ let struct_type = self.tcx.lookup_item_type(id).ty;
let struct_desc = match struct_type.sty {
ty::TyStruct(_, _) =>
- format!("struct `{}`", ty::item_path_str(self.tcx, id)),
+ format!("struct `{}`", self.tcx.item_path_str(id)),
// struct variant fields have inherited visibility
ty::TyEnum(..) => return,
_ => self.tcx.sess.span_bug(span, "can't find struct for field")
name: ast::Name) {
// If the method is a default method, we need to use the def_id of
// the default implementation.
- let method_id = match ty::impl_or_trait_item(self.tcx, method_id) {
+ let method_id = match self.tcx.impl_or_trait_item(method_id) {
ty::MethodTraitItem(method_type) => {
method_type.provided_source.unwrap_or(method_id)
}
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
ast::ExprField(ref base, ident) => {
- if let ty::TyStruct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty {
+ if let ty::TyStruct(id, _) = self.tcx.expr_ty_adjusted(&**base).sty {
self.check_field(expr.span, id, NamedField(ident.node.name));
}
}
ast::ExprTupField(ref base, idx) => {
- if let ty::TyStruct(id, _) = ty::expr_ty_adjusted(self.tcx, &**base).sty {
+ if let ty::TyStruct(id, _) = self.tcx.expr_ty_adjusted(&**base).sty {
self.check_field(expr.span, id, UnnamedField(idx.node));
}
}
}
}
ast::ExprStruct(_, ref fields, _) => {
- match ty::expr_ty(self.tcx, expr).sty {
+ match self.tcx.expr_ty(expr).sty {
ty::TyStruct(ctor_id, _) => {
// RFC 736: ensure all unmentioned fields are visible.
// Rather than computing the set of unmentioned fields
// (i.e. `all_fields - fields`), just check them all.
- let all_fields = ty::lookup_struct_fields(self.tcx, ctor_id);
+ let all_fields = self.tcx.lookup_struct_fields(ctor_id);
for field in all_fields {
self.check_field(expr.span, ctor_id,
NamedField(field.name));
}
ast::ExprPath(..) => {
let guard = |did: ast::DefId| {
- let fields = ty::lookup_struct_fields(self.tcx, did);
+ let fields = self.tcx.lookup_struct_fields(did);
let any_priv = fields.iter().any(|f| {
f.vis != ast::Public && (
!is_local(f.id) ||
match pattern.node {
ast::PatStruct(_, ref fields, _) => {
- match ty::pat_ty(self.tcx, pattern).sty {
+ match self.tcx.pat_ty(pattern).sty {
ty::TyStruct(id, _) => {
for field in fields {
self.check_field(pattern.span, id,
// Patterns which bind no fields are allowable (the path is check
// elsewhere).
ast::PatEnum(_, Some(ref fields)) => {
- match ty::pat_ty(self.tcx, pattern).sty {
+ match self.tcx.pat_ty(pattern).sty {
ty::TyStruct(id, _) => {
for (i, field) in fields.iter().enumerate() {
if let ast::PatWild(..) = field.node {
let not_private_trait =
trait_ref.as_ref().map_or(true, // no trait counts as public trait
|tr| {
- let did = ty::trait_ref_to_def_id(self.tcx, tr);
+ let did = self.tcx.trait_ref_to_def_id(tr);
!is_local(did) || self.trait_is_public(did.node)
});
let mut scope_id;
// The qualname for a method is the trait name or name of the struct in an impl in
// which the method is declared in, followed by the method's name.
- let qualname = match ty::impl_of_method(self.tcx, ast_util::local_def(id)) {
+ let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) {
Some(impl_id) => match self.tcx.map.get(impl_id.node) {
NodeItem(item) => {
scope_id = item.id;
let mut result = String::from("<");
result.push_str(&ty_to_string(&**ty));
- match ty::trait_of_item(self.tcx, ast_util::local_def(id)) {
+ match self.tcx.trait_of_item(ast_util::local_def(id)) {
Some(def_id) => {
result.push_str(" as ");
result.push_str(
- &ty::item_path_str(self.tcx, def_id));
+ &self.tcx.item_path_str(def_id));
},
None => {}
}
impl_id.node, id, self.tcx.map.get(impl_id.node)));
},
},
- None => match ty::trait_of_item(self.tcx, ast_util::local_def(id)) {
+ None => match self.tcx.trait_of_item(ast_util::local_def(id)) {
Some(def_id) => {
scope_id = def_id.node;
match self.tcx.map.get(def_id.node) {
NodeItem(_) => {
- format!("::{}", ty::item_path_str(self.tcx, def_id))
+ format!("::{}", self.tcx.item_path_str(def_id))
}
_ => {
self.sess.span_bug(span,
let qualname = &format!("{}::{}", qualname, &token::get_name(name));
// record the decl for this def (if it has one)
- let decl_id = ty::trait_item_of_item(self.tcx, ast_util::local_def(id))
+ let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
.and_then(|new_id| {
let def_id = new_id.def_id();
if def_id.node != 0 && def_id != ast_util::local_def(id) {
def::DefMethod(declid, provenence) => {
let sub_span = self.span.sub_span_for_meth_name(span);
let defid = if declid.krate == ast::LOCAL_CRATE {
- let ti = ty::impl_or_trait_item(self.tcx, declid);
+ let ti = self.tcx.impl_or_trait_item(declid);
match provenence {
def::FromTrait(def_id) => {
- Some(ty::trait_items(self.tcx, def_id)
+ Some(self.tcx.trait_items(def_id)
.iter()
.find(|mr| {
mr.name() == ti.name()
.unwrap()
.iter()
.find(|mr| {
- ty::impl_or_trait_item(
- self.tcx,
- mr.def_id()
- ).name() == ti.name()
+ self.tcx.impl_or_trait_item(mr.def_id()).name()
+ == ti.name()
})
.unwrap()
.def_id())
// modules or types in the path prefix
match def {
def::DefMethod(did, _) => {
- let ti = ty::impl_or_trait_item(self.tcx, did);
+ let ti = self.tcx.impl_or_trait_item(did);
if let ty::MethodTraitItem(m) = ti {
if m.explicit_self == ty::StaticExplicitSelfCategory {
self.write_sub_path_trait_truncated(path);
ty::MethodStaticClosure(def_id) => {
// method invoked on an object with a concrete type (not a static method)
let decl_id =
- match ty::trait_item_of_item(self.tcx, def_id) {
+ match self.tcx.trait_item_of_item(def_id) {
None => None,
Some(decl_id) => Some(decl_id.def_id()),
};
// This incantation is required if the method referenced is a
// trait's default implementation.
- let def_id = match ty::impl_or_trait_item(self.tcx, def_id) {
+ let def_id = match self.tcx.impl_or_trait_item(def_id) {
ty::MethodTraitItem(method) => {
method.provided_source.unwrap_or(def_id)
}
}
ty::MethodTypeParam(ref mp) => {
// method invoked on a type parameter
- let trait_item = ty::trait_item(self.tcx,
- mp.trait_ref.def_id,
- mp.method_num);
+ let trait_item = self.tcx.trait_item(mp.trait_ref.def_id,
+ mp.method_num);
(None, Some(trait_item.def_id()))
}
ty::MethodTraitObject(ref mo) => {
// method invoked on a trait instance
- let trait_item = ty::trait_item(self.tcx,
- mo.trait_ref.def_id,
- mo.method_num);
+ let trait_item = self.tcx.trait_item(mo.trait_ref.def_id,
+ mo.method_num);
(None, Some(trait_item.def_id()))
}
};
def::DefConst(..) | def::DefAssociatedConst(..) => None,
def::DefVariant(_, variant_id, _) => Some(variant_id),
_ => {
- match ty::ty_to_def_id(ty::node_id_to_type(self.tcx, p.id)) {
+ match self.tcx.node_id_to_type(p.id).ty_to_def_id() {
None => {
self.sess.span_bug(p.span,
&format!("Could not find struct_def for `{}`",
};
if let Some(struct_def) = struct_def {
- let struct_fields = ty::lookup_struct_fields(self.tcx, struct_def);
+ let struct_fields = self.tcx.lookup_struct_fields(struct_def);
for &Spanned { node: ref field, span } in fields {
let sub_span = self.span.span_for_first_ident(span);
for f in &struct_fields {
self.visit_expr(&**sub_ex);
- let ty = &ty::expr_ty_adjusted(self.tcx, &**sub_ex).sty;
+ let ty = &self.tcx.expr_ty_adjusted(&**sub_ex).sty;
match *ty {
ty::TyStruct(def_id, _) => {
- let fields = ty::lookup_struct_fields(self.tcx, def_id);
+ let fields = self.tcx.lookup_struct_fields(def_id);
for (i, f) in fields.iter().enumerate() {
if i == idx.node {
let sub_span = self.span.sub_span_after_token(ex.span, token::Dot);
pub fn get_expr_data(&self, expr: &ast::Expr) -> Option<Data> {
match expr.node {
ast::ExprField(ref sub_ex, ident) => {
- let ty = &ty::expr_ty_adjusted(self.tcx, &sub_ex).sty;
+ let ty = &self.tcx.expr_ty_adjusted(&sub_ex).sty;
match *ty {
ty::TyStruct(def_id, _) => {
- let fields = ty::lookup_struct_fields(self.tcx, def_id);
+ let fields = self.tcx.lookup_struct_fields(def_id);
for f in &fields {
if f.name == ident.node.name {
let sub_span = self.span_utils.span_for_last_ident(expr.span);
}
}
ast::ExprStruct(ref path, _, _) => {
- let ty = &ty::expr_ty_adjusted(&self.tcx, expr).sty;
+ let ty = &self.tcx.expr_ty_adjusted(expr).sty;
match *ty {
ty::TyStruct(def_id, _) => {
let sub_span = self.span_utils.span_for_last_ident(path.span);
struct_id: DefId,
parent: NodeId)
-> VariableRefData {
- let fields = ty::lookup_struct_fields(&self.tcx, struct_id);
+ let fields = self.tcx.lookup_struct_fields(struct_id);
let field_name = get_ident(field_ref.ident.node).to_string();
for f in &fields {
if f.name == field_ref.ident.node.name {
use middle::expr_use_visitor as euv;
use middle::lang_items::StrEqFnLangItem;
use middle::mem_categorization as mc;
+use middle::mem_categorization::Typer;
use middle::pat_util::*;
use trans::adt;
use trans::base::*;
impl<'a> ConstantExpr<'a> {
fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
match const_eval::compare_lit_exprs(tcx, self.0, other.0, None,
- |id| {ty::node_id_item_substs(tcx, id).substs}) {
+ |id| {tcx.node_id_item_substs(id).substs}) {
Some(result) => result == Ordering::Equal,
None => panic!("compare_list_exprs: type mismatch"),
}
let ccx = bcx.ccx();
match *self {
ConstantValue(ConstantExpr(lit_expr), _) => {
- let lit_ty = ty::node_id_to_type(bcx.tcx(), lit_expr.id);
+ let lit_ty = bcx.tcx().node_id_to_type(lit_expr.id);
let (llval, _) = consts::const_expr(ccx, &*lit_expr, bcx.fcx.param_substs, None);
let lit_datum = immediate_rvalue(llval, lit_ty);
let lit_datum = unpack_datum!(bcx, lit_datum.to_appropriate_datum(bcx));
check_match::Constructor::Variant(def_id)
};
- let param_env = ty::empty_parameter_environment(bcx.tcx());
+ let param_env = bcx.tcx().empty_parameter_environment();
let mcx = check_match::MatchCheckCtxt {
tcx: bcx.tcx(),
param_env: param_env,
let opt_def = tcx.def_map.borrow().get(&cur.id).map(|d| d.full_def());
match opt_def {
Some(def::DefVariant(enum_id, var_id, _)) => {
- let variant = ty::enum_variant_with_id(tcx, enum_id, var_id);
+ let variant = tcx.enum_variant_with_id(enum_id, var_id);
Variant(variant.disr_val,
adt::represent_node(bcx, cur.id),
var_id,
let mcx = check_match::MatchCheckCtxt {
tcx: bcx.tcx(),
- param_env: ty::empty_parameter_environment(bcx.tcx()),
+ param_env: bcx.tcx().empty_parameter_environment(),
};
let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
let repr = adt::represent_type(bcx.ccx(), left_ty);
// The last field is technically unsized but
// since we can only ever match that field behind
// a reference we construct a fat ptr here.
- let fields = ty::lookup_struct_fields(bcx.tcx(), def_id);
+ let fields = bcx.tcx().lookup_struct_fields(def_id);
let unsized_ty = fields.iter().last().map(|field| {
- let fty = ty::lookup_field_type(bcx.tcx(), def_id, field.id, substs);
+ let fty = bcx.tcx().lookup_field_type(def_id, field.id, substs);
monomorphize::normalize_associated_type(bcx.tcx(), &fty)
}).unwrap();
let llty = type_of::type_of(bcx.ccx(), unsized_ty);
let variable_ty = node_id_type(bcx, p_id);
let llvariable_ty = type_of::type_of(ccx, variable_ty);
let tcx = bcx.tcx();
- let param_env = ty::empty_parameter_environment(tcx);
+ let param_env = tcx.empty_parameter_environment();
let llmatch;
let trmode;
match bm {
ast::BindByValue(_)
- if !ty::type_moves_by_default(¶m_env, span, variable_ty) || reassigned =>
+ if !param_env.type_moves_by_default(variable_ty, span) || reassigned =>
{
llmatch = alloca_no_lifetime(bcx,
llvariable_ty.ptr_to(),
}
let t = node_id_type(bcx, discr_expr.id);
- let chk = if ty::type_is_empty(tcx, t) {
+ let chk = if t.is_empty(tcx) {
Unreachable
} else {
Infallible
match opt_def {
Some(def::DefVariant(enum_id, var_id, _)) => {
let repr = adt::represent_node(bcx, pat.id);
- let vinfo = ty::enum_variant_with_id(ccx.tcx(),
- enum_id,
- var_id);
+ let vinfo = ccx.tcx().enum_variant_with_id(enum_id, var_id);
let args = extract_variant_args(bcx,
&*repr,
vinfo.disr_val,
let pat_repr = adt::represent_type(bcx.ccx(), pat_ty);
expr::with_field_tys(tcx, pat_ty, Some(pat.id), |discr, field_tys| {
for f in fields {
- let ix = ty::field_idx_strict(tcx, f.node.ident.name, field_tys);
+ let ix = tcx.field_idx_strict(f.node.ident.name, field_tys);
let fldptr = adt::trans_field_ptr(bcx, &*pat_repr, val,
discr, ix);
bcx = bind_irrefutable_pat(bcx, &*f.node.pat, fldptr, cleanup_scope);
Univariant(mk_struct(cx, &elems[..], false, t), 0)
}
ty::TyStruct(def_id, substs) => {
- let fields = ty::lookup_struct_fields(cx.tcx(), def_id);
+ let fields = cx.tcx().lookup_struct_fields(def_id);
let mut ftys = fields.iter().map(|field| {
- let fty = ty::lookup_field_type(cx.tcx(), def_id, field.id, substs);
+ let fty = cx.tcx().lookup_field_type(def_id, field.id, substs);
monomorphize::normalize_associated_type(cx.tcx(), &fty)
}).collect::<Vec<_>>();
- let packed = ty::lookup_packed(cx.tcx(), def_id);
- let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
+ let packed = cx.tcx().lookup_packed(def_id);
+ let dtor = cx.tcx().ty_dtor(def_id).has_drop_flag();
if dtor {
ftys.push(cx.tcx().dtor_type());
}
}
ty::TyEnum(def_id, substs) => {
let cases = get_cases(cx.tcx(), def_id, substs);
- let hint = *ty::lookup_repr_hints(cx.tcx(), def_id).get(0)
+ let hint = *cx.tcx().lookup_repr_hints(def_id).get(0)
.unwrap_or(&attr::ReprAny);
- let dtor = ty::ty_dtor(cx.tcx(), def_id).has_drop_flag();
+ let dtor = cx.tcx().ty_dtor(def_id).has_drop_flag();
if cases.is_empty() {
// Uninhabitable; represent as unit
// been rejected by a checker before this point.
if !cases.iter().enumerate().all(|(i,c)| c.discr == (i as Disr)) {
cx.sess().bug(&format!("non-C-like enum {} with specified \
- discriminants",
- ty::item_path_str(cx.tcx(),
- def_id)));
+ discriminants",
+ cx.tcx().item_path_str(def_id)));
}
if cases.len() == 1 {
// Is this the NonZero lang item wrapping a pointer or integer type?
ty::TyStruct(did, substs) if Some(did) == tcx.lang_items.non_zero() => {
- let nonzero_fields = ty::lookup_struct_fields(tcx, did);
+ let nonzero_fields = tcx.lookup_struct_fields(did);
assert_eq!(nonzero_fields.len(), 1);
- let nonzero_field = ty::lookup_field_type(tcx, did, nonzero_fields[0].id, substs);
+ let nonzero_field = tcx.lookup_field_type(did, nonzero_fields[0].id, substs);
match nonzero_field.sty {
ty::TyRawPtr(ty::mt { ty, .. }) if !type_is_sized(tcx, ty) => {
path.push_all(&[0, FAT_PTR_ADDR]);
// Perhaps one of the fields of this struct is non-zero
// let's recurse and find out
ty::TyStruct(def_id, substs) => {
- let fields = ty::lookup_struct_fields(tcx, def_id);
+ let fields = tcx.lookup_struct_fields(def_id);
for (j, field) in fields.iter().enumerate() {
- let field_ty = ty::lookup_field_type(tcx, def_id, field.id, substs);
+ let field_ty = tcx.lookup_field_type(def_id, field.id, substs);
if let Some(mut fpath) = find_discr_field_candidate(tcx, field_ty, path.clone()) {
fpath.push(j);
return Some(fpath);
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> Vec<Case<'tcx>> {
- ty::enum_variants(tcx, def_id).iter().map(|vi| {
+ tcx.enum_variants(def_id).iter().map(|vi| {
let arg_tys = vi.args.iter().map(|&raw_ty| {
monomorphize::apply_param_substs(tcx, substs, &raw_ty)
}).collect();
_ => ccx.sess().bug("expected closure or function.")
};
- let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
+ let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
let mut attrs = llvm::AttrBuilder::new();
let ret_ty = fn_sig.output;
// `&T` where `T` contains no `UnsafeCell<U>` is immutable, and can be marked as
// both `readonly` and `noalias`, as LLVM's definition of `noalias` is based solely
// on memory dependencies rather than pointer equality
- let interior_unsafe = ty::type_contents(ccx.tcx(), mt.ty).interior_unsafe();
+ let interior_unsafe = mt.ty.type_contents(ccx.tcx()).interior_unsafe();
if mt.mutbl == ast::MutMutable || !interior_unsafe {
attrs.arg(idx, llvm::Attribute::NoAlias);
// don't do this then linker errors can be generated where the linker
// complains that one object files has a thread local version of the
// symbol and another one doesn't.
- for attr in ty::get_attrs(ccx.tcx(), did).iter() {
+ for attr in ccx.tcx().get_attrs(did).iter() {
if attr.check_name("thread_local") {
llvm::set_thread_local(c, true);
}
let ccx = fcx.ccx;
let repr = adt::represent_type(ccx, t);
- let variants = ty::enum_variants(ccx.tcx(), tid);
+ let variants = ccx.tcx().enum_variants(tid);
let n_variants = (*variants).len();
// NB: we must hit the discriminant first so that structural
llfn: llfndecl,
llenv: None,
llretslotptr: Cell::new(None),
- param_env: ty::empty_parameter_environment(ccx.tcx()),
+ param_env: ccx.tcx().empty_parameter_environment(),
alloca_insert_pt: Cell::new(None),
llreturn: Cell::new(None),
needs_ret_allocas: nested_returns,
let _s = StatRecorder::new(ccx, ccx.tcx().map.path_to_string(id).to_string());
debug!("trans_fn(param_substs={:?})", param_substs);
let _icx = push_ctxt("trans_fn");
- let fn_ty = ty::node_id_to_type(ccx.tcx(), id);
- let output_type = ty::erase_late_bound_regions(ccx.tcx(), &fn_ty.fn_ret());
+ let fn_ty = ccx.tcx().node_id_to_type(id);
+ let output_type = ccx.tcx().erase_late_bound_regions(&fn_ty.fn_ret());
let abi = fn_ty.fn_abi();
trans_closure(ccx, decl, body, llfndecl, param_substs, id, attrs, output_type, abi,
closure::ClosureEnv::NotClosure);
let result_ty = match ctor_ty.sty {
ty::TyBareFn(_, ref bft) => {
- ty::erase_late_bound_regions(bcx.tcx(), &bft.sig.output()).unwrap()
+ bcx.tcx().erase_late_bound_regions(&bft.sig.output()).unwrap()
}
_ => ccx.sess().bug(
&format!("trans_enum_variant_constructor: \
disr: ty::Disr,
param_substs: &'tcx Substs<'tcx>,
llfndecl: ValueRef) {
- let ctor_ty = ty::node_id_to_type(ccx.tcx(), ctor_id);
+ let ctor_ty = ccx.tcx().node_id_to_type(ctor_id);
let ctor_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &ctor_ty);
let result_ty = match ctor_ty.sty {
ty::TyBareFn(_, ref bft) => {
- ty::erase_late_bound_regions(ccx.tcx(), &bft.sig.output())
+ ccx.tcx().erase_late_bound_regions(&bft.sig.output())
}
_ => ccx.sess().bug(
&format!("trans_enum_variant_or_tuple_like_struct: \
assert!(!fcx.needs_ret_allocas);
- let arg_tys =
- ty::erase_late_bound_regions(
- ccx.tcx(), &ctor_ty.fn_args());
+ let arg_tys = ccx.tcx().erase_late_bound_regions(&ctor_ty.fn_args());
let arg_datums = create_datums_for_fn_args(bcx, &arg_tys[..]);
return
}
- let ty = ty::node_id_to_type(ccx.tcx(), id);
+ let ty = ccx.tcx().node_id_to_type(id);
let avar = adt::represent_type(ccx, ty);
match *avar {
adt::General(_, ref variants, _) => {
// error in trans. This is used to write compile-fail tests
// that actually test that compilation succeeds without
// reporting an error.
- if ty::has_attr(ccx.tcx(), local_def(item.id), "rustc_error") {
+ if ccx.tcx().has_attr(local_def(item.id), "rustc_error") {
ccx.tcx().sess.span_fatal(item.span, "compilation successful");
}
}
debug!("get_item_val: id={} item={:?}", id, item);
let val = match item {
ast_map::NodeItem(i) => {
- let ty = ty::node_id_to_type(ccx.tcx(), i.id);
+ let ty = ccx.tcx().node_id_to_type(i.id);
let sym = || exported_name(ccx, id, ty, &i.attrs);
let v = match i.node {
match ni.node {
ast::ForeignItemFn(..) => {
let abi = ccx.tcx().map.get_foreign_abi(id);
- let ty = ty::node_id_to_type(ccx.tcx(), ni.id);
+ let ty = ccx.tcx().node_id_to_type(ni.id);
let name = foreign::link_name(&*ni);
let llfn = foreign::register_foreign_item_fn(ccx, abi, ty, &name);
attributes::from_fn_attrs(ccx, &ni.attrs, llfn);
}
};
assert!(!args.is_empty());
- let ty = ty::node_id_to_type(ccx.tcx(), id);
+ let ty = ccx.tcx().node_id_to_type(id);
let parent = ccx.tcx().map.get_parent(id);
let enm = ccx.tcx().map.expect_item(parent);
let sym = exported_name(ccx,
};
let parent = ccx.tcx().map.get_parent(id);
let struct_item = ccx.tcx().map.expect_item(parent);
- let ty = ty::node_id_to_type(ccx.tcx(), ctor_id);
+ let ty = ccx.tcx().node_id_to_type(ctor_id);
let sym = exported_name(ccx,
id,
ty,
fn register_method(ccx: &CrateContext, id: ast::NodeId,
attrs: &[ast::Attribute], span: Span) -> ValueRef {
- let mty = ty::node_id_to_type(ccx.tcx(), id);
+ let mty = ccx.tcx().node_id_to_type(id);
let sym = exported_name(ccx, id, mty, &attrs);
bcx.fcx.param_substs).val)
}
def::DefVariant(tid, vid, _) => {
- let vinfo = ty::enum_variant_with_id(bcx.tcx(), tid, vid);
+ let vinfo = bcx.tcx().enum_variant_with_id(tid, vid);
let substs = common::node_id_substs(bcx.ccx(),
ExprId(ref_expr.id),
bcx.fcx.param_substs);
bare_fn_ty));
}
};
- let sig = ty::erase_late_bound_regions(tcx, sig);
+ let sig = tcx.erase_late_bound_regions(sig);
let tuple_input_ty = tcx.mk_tup(sig.inputs.to_vec());
let tuple_fn_ty = tcx.mk_fn(opt_def_id,
tcx.mk_bare_fn(ty::BareFnTy {
let substs = substs.erase_regions();
// Load the info for the appropriate trait if necessary.
- match ty::trait_of_item(tcx, def_id) {
+ match tcx.trait_of_item(def_id) {
None => {}
Some(trait_id) => {
- ty::populate_implementations_for_trait_if_necessary(tcx, trait_id)
+ tcx.populate_implementations_for_trait_if_necessary(trait_id)
}
}
// We need to do a bunch of special handling for default methods.
// We need to modify the def_id and our substs in order to monomorphize
// the function.
- let (is_default, def_id, substs) = match ty::provided_source(tcx, def_id) {
+ let (is_default, def_id, substs) = match tcx.provided_source(def_id) {
None => {
(false, def_id, tcx.mk_substs(substs))
}
// So, what we need to do is find this substitution and
// compose it with the one we already have.
- let impl_id = ty::impl_or_trait_item(tcx, def_id).container()
+ let impl_id = tcx.impl_or_trait_item(def_id).container()
.id();
- let impl_or_trait_item = ty::impl_or_trait_item(tcx, source_id);
+ let impl_or_trait_item = tcx.impl_or_trait_item(source_id);
match impl_or_trait_item {
ty::MethodTraitItem(method) => {
- let trait_ref = ty::impl_trait_ref(tcx, impl_id).unwrap();
+ let trait_ref = tcx.impl_trait_ref(impl_id).unwrap();
// Compute the first substitution
let first_subst =
- ty::make_substs_for_receiver_types(tcx, &trait_ref, &*method)
+ tcx.make_substs_for_receiver_types(&trait_ref, &*method)
.erase_regions();
// And compose them
// Monotype of the REFERENCE to the function (type params
// are subst'd)
let ref_ty = match node {
- ExprId(id) => ty::node_id_to_type(tcx, id),
+ ExprId(id) => tcx.node_id_to_type(id),
MethodCallKey(method_call) => {
tcx.method_map.borrow().get(&method_call).unwrap().ty
}
}
// Type scheme of the function item (may have type params)
- let fn_type_scheme = ty::lookup_item_type(tcx, def_id);
+ let fn_type_scheme = tcx.lookup_item_type(def_id);
let fn_type = monomorphize::normalize_associated_type(tcx, &fn_type_scheme.ty);
// Find the actual function pointer.
debug_loc: DebugLoc)
-> Result<'blk, 'tcx> {
let fty = if did.krate == ast::LOCAL_CRATE {
- ty::node_id_to_type(bcx.tcx(), did.node)
+ bcx.tcx().node_id_to_type(did.node)
} else {
csearch::get_type(bcx.tcx(), did).ty
};
let (abi, ret_ty) = match callee_ty.sty {
ty::TyBareFn(_, ref f) => {
- let output = ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output());
+ let output = bcx.tcx().erase_late_bound_regions(&f.sig.output());
(f.abi, output)
}
_ => panic!("expected bare rust fn or closure in trans_call_inner")
ignore_self: bool)
-> Block<'blk, 'tcx>
{
- let args =
- ty::erase_late_bound_regions(
- bcx.tcx(), &fn_ty.fn_args());
+ let args = bcx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
// Translate the `self` argument first.
if !ignore_self {
ignore_self: bool)
-> Block<'blk, 'tcx> {
// Translate the `self` argument first.
- let arg_tys = ty::erase_late_bound_regions(bcx.tcx(), &fn_ty.fn_args());
+ let arg_tys = bcx.tcx().erase_late_bound_regions( &fn_ty.fn_args());
if !ignore_self {
let arg_datum = unpack_datum!(bcx, expr::trans(bcx, arg_exprs[0]));
bcx = trans_arg_datum(bcx,
debug!("trans_args(abi={})", abi);
let _icx = push_ctxt("trans_args");
- let arg_tys = ty::erase_late_bound_regions(cx.tcx(), &fn_ty.fn_args());
+ let arg_tys = cx.tcx().erase_late_bound_regions(&fn_ty.fn_args());
let variadic = fn_ty.fn_sig().0.variadic;
let mut bcx = cx;
return None
}
- let function_type = ty::node_id_to_type(ccx.tcx(), closure_id.node);
+ let function_type = ccx.tcx().node_id_to_type(closure_id.node);
let function_type = monomorphize::apply_param_substs(ccx.tcx(), substs, &function_type);
// Normalize type so differences in regions and typedefs don't cause
let function_type = typer.closure_type(closure_id, param_substs);
let freevars: Vec<ty::Freevar> =
- ty::with_freevars(tcx, id, |fv| fv.iter().cloned().collect());
+ tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
- let sig = ty::erase_late_bound_regions(tcx, &function_type.sig);
+ let sig = tcx.erase_late_bound_regions(&function_type.sig);
trans_closure(ccx,
decl,
ccx.sess().bug(&format!("symbol `{}` already defined", function_name));
});
- let sig = ty::erase_late_bound_regions(tcx, &llonce_bare_fn_ty.sig);
+ let sig = tcx.erase_late_bound_regions(&llonce_bare_fn_ty.sig);
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
block_arena = TypedArena::new();
fcx = new_fn_ctxt(ccx,
use middle::infer;
use middle::lang_items::LangItem;
use middle::mem_categorization as mc;
+use middle::mem_categorization::Typer;
use middle::region;
use middle::subst::{self, Subst, Substs};
use trans::base;
fn fold_binder<T>(&mut self, t: &ty::Binder<T>) -> ty::Binder<T>
where T : TypeFoldable<'tcx>
{
- let u = ty::anonymize_late_bound_regions(self.tcx(), t);
+ let u = self.tcx().anonymize_late_bound_regions(t);
ty_fold::super_fold_binder(self, &u)
}
/// Is the type's representation size known at compile time?
pub fn type_is_sized<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
- ty::type_is_sized(None, tcx, DUMMY_SP, ty)
+ ty.is_sized(&tcx.empty_parameter_environment(), DUMMY_SP)
}
pub fn type_is_fat_ptr<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
ty::TyFloat(_) | ty::TyTuple(_) | ty::TyRawPtr(_) => false,
ty::TyEnum(did, substs) =>
- ty::enum_variants(tcx, did).iter().any(|v|
+ tcx.enum_variants(did).iter().any(|v|
v.args.iter().any(|&aty| {
let t = aty.subst(tcx, substs);
type_needs_unwind_cleanup_(tcx, t, tycache)
/// (Note that this implies that if `ty` has a destructor attached,
/// then `type_needs_drop` will definitely return `true` for `ty`.)
pub fn type_needs_drop<'tcx>(cx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
- type_needs_drop_given_env(cx, ty, &ty::empty_parameter_environment(cx))
+ type_needs_drop_given_env(cx, ty, &cx.empty_parameter_environment())
}
/// Core implementation of type_needs_drop, potentially making use of
// normalized version of the type, and therefore will definitely
// know whether the type implements Copy (and thus needs no
// cleanup/drop/zeroing) ...
- let implements_copy = !ty::type_moves_by_default(¶m_env, DUMMY_SP, ty);
+ let implements_copy = !param_env.type_moves_by_default(ty, DUMMY_SP);
if implements_copy { return false; }
// bound attached (see above), it is sound to treat it as having a
// destructor (e.g. zero its memory on move).
- let contents = ty::type_contents(cx, ty);
+ let contents = ty.type_contents(cx);
debug!("type_needs_drop ty={:?} contents={:?}", ty, contents);
contents.needs_drop(cx)
}
fn type_is_newtype_immediate<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ty: Ty<'tcx>) -> bool {
match ty.sty {
ty::TyStruct(def_id, substs) => {
- let fields = ty::lookup_struct_fields(ccx.tcx(), def_id);
+ let fields = ccx.tcx().lookup_struct_fields(def_id);
fields.len() == 1 && {
- let ty = ty::lookup_field_type(ccx.tcx(), def_id, fields[0].id, substs);
+ let ty = ccx.tcx().lookup_field_type(def_id, fields[0].id, substs);
let ty = monomorphize::normalize_associated_type(ccx.tcx(), &ty);
type_is_immediate(ccx, ty)
}
/// zero-size, but not all zero-size types use a `void` return type (in order to aid with C ABI
/// compatibility).
pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
- ty.is_nil() || ty::type_is_empty(ccx.tcx(), ty)
+ ty.is_nil() || ty.is_empty(ccx.tcx())
}
/// Generates a unique symbol based off the name given. This is used to create
Some(self.tcx().upvar_capture_map.borrow().get(&upvar_id).unwrap().clone())
}
- fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
- self.fcx.param_env.type_moves_by_default(span, ty)
+ fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
+ self.fcx.param_env.type_moves_by_default(ty, span)
}
}
pub fn node_id_type<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, id: ast::NodeId) -> Ty<'tcx> {
let tcx = bcx.tcx();
- let t = ty::node_id_to_type(tcx, id);
+ let t = tcx.node_id_to_type(id);
monomorphize_type(bcx, t)
}
}
pub fn expr_ty_adjusted<'blk, 'tcx>(bcx: &BlockS<'blk, 'tcx>, ex: &ast::Expr) -> Ty<'tcx> {
- monomorphize_type(bcx, ty::expr_ty_adjusted(bcx.tcx(), ex))
+ monomorphize_type(bcx, bcx.tcx().expr_ty_adjusted(ex))
}
/// Attempts to resolve an obligation. The result is a shallow vtable resolution -- meaning that we
debug!("trans fulfill_obligation: trait_ref={:?} def_id={:?}",
trait_ref, trait_ref.def_id());
- ty::populate_implementations_for_trait_if_necessary(tcx, trait_ref.def_id());
+ tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id());
let infcx = infer::new_infer_ctxt(tcx);
// Do the initial selection for the obligation. This yields the
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingClosureTyper<'a,'tcx> {
// Parameter environment is used to give details about type parameters,
// but since we are in trans, everything is fully monomorphized.
- NormalizingClosureTyper { param_env: ty::empty_parameter_environment(tcx) }
+ NormalizingClosureTyper { param_env: tcx.empty_parameter_environment() }
}
}
{
// the substitutions in `substs` are already monomorphized,
// but we still must normalize associated types
- let result = ty::closure_upvars(&self.param_env, def_id, substs);
+ let result = self.param_env.closure_upvars(def_id, substs);
monomorphize::normalize_associated_type(self.param_env.tcx, &result)
}
}
let substs = match node {
ExprId(id) => {
- ty::node_id_item_substs(tcx, id).substs
+ tcx.node_id_item_substs(id).substs
}
MethodCallKey(method_call) => {
tcx.method_map.borrow().get(&method_call).unwrap().substs.clone()
C_integral(Type::uint_from_ty(cx, t), u, false)
}
ast::LitInt(i, ast::UnsuffixedIntLit(_)) => {
- let lit_int_ty = ty::node_id_to_type(cx.tcx(), e.id);
+ let lit_int_ty = cx.tcx().node_id_to_type(e.id);
match lit_int_ty.sty {
ty::TyInt(t) => {
C_integral(Type::int_from_ty(cx, t), i as u64, true)
C_floating(&fs, Type::float_from_ty(cx, t))
}
ast::LitFloatUnsuffixed(ref fs) => {
- let lit_float_ty = ty::node_id_to_type(cx.tcx(), e.id);
+ let lit_float_ty = cx.tcx().node_id_to_type(e.id);
match lit_float_ty.sty {
ty::TyFloat(t) => {
C_floating(&fs, Type::float_from_ty(cx, t))
// Avoid autorefs as they would create global instead of stack
// references, even when only the latter are correct.
let ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs,
- &ty::expr_ty(ccx.tcx(), expr));
+ &ccx.tcx().expr_ty(expr));
const_expr_unadjusted(ccx, expr, ty, param_substs, None)
} else {
const_expr(ccx, expr, param_substs, None).0
fn_args: FnArgMap)
-> (ValueRef, Ty<'tcx>) {
let ety = monomorphize::apply_param_substs(cx.tcx(), param_substs,
- &ty::expr_ty(cx.tcx(), e));
+ &cx.tcx().expr_ty(e));
let llconst = const_expr_unadjusted(cx, e, ety, param_substs, fn_args);
let mut llconst = llconst;
let mut ety_adjusted = monomorphize::apply_param_substs(cx.tcx(), param_substs,
- &ty::expr_ty_adjusted(cx.tcx(), e));
+ &cx.tcx().expr_ty_adjusted(e));
let opt_adj = cx.tcx().adjustments.borrow().get(&e.id).cloned();
match opt_adj {
Some(ty::AdjustReifyFnPointer) => {
let (bv, bt) = const_expr(cx, &**base, param_substs, fn_args);
let brepr = adt::represent_type(cx, bt);
expr::with_field_tys(cx.tcx(), bt, None, |discr, field_tys| {
- let ix = ty::field_idx_strict(cx.tcx(), field.node.name, field_tys);
+ let ix = cx.tcx().field_idx_strict(field.node.name, field_tys);
adt::const_get_field(cx, &*brepr, bv, discr, ix)
})
}
ast::ExprRepeat(ref elem, ref count) => {
let unit_ty = ety.sequence_element_type(cx.tcx());
let llunitty = type_of::type_of(cx, unit_ty);
- let n = ty::eval_repeat_count(cx.tcx(), count);
+ let n = cx.tcx().eval_repeat_count(count);
let unit_val = const_expr(cx, &**elem, param_substs, fn_args).0;
let vs: Vec<_> = repeat(unit_val).take(n).collect();
if val_ty(unit_val) != llunitty {
const_deref_ptr(cx, get_const_val(cx, def_id, e))
}
def::DefVariant(enum_did, variant_did, _) => {
- let vinfo = ty::enum_variant_with_id(cx.tcx(),
- enum_did,
- variant_did);
+ let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
if !vinfo.args.is_empty() {
// N-ary variant.
expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
}
def::DefVariant(enum_did, variant_did, _) => {
let repr = adt::represent_type(cx, ety);
- let vinfo = ty::enum_variant_with_id(cx.tcx(),
- enum_did,
- variant_did);
+ let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
adt::trans_const(cx,
&*repr,
vinfo.disr_val,
// As an optimization, all shared statics which do not have interior
// mutability are placed into read-only memory.
if m != ast::MutMutable {
- let node_ty = ty::node_id_to_type(ccx.tcx(), id);
- let tcontents = ty::type_contents(ccx.tcx(), node_ty);
+ let node_ty = ccx.tcx().node_id_to_type(id);
+ let tcontents = node_ty.type_contents(ccx.tcx());
if !tcontents.interior_unsafe() {
llvm::LLVMSetGlobalConstant(g, True);
}
use trans::expr;
use trans::tvec;
use trans::type_of;
-use middle::ty::{self, Ty};
+use middle::mem_categorization::Typer;
+use middle::ty::Ty;
use std::fmt;
use syntax::ast;
* affine values (since they must never be duplicated).
*/
- assert!(!ty::type_moves_by_default(&ty::empty_parameter_environment(bcx.tcx()),
- DUMMY_SP,
- self.ty));
+ assert!(!bcx.tcx().empty_parameter_environment()
+ .type_moves_by_default(self.ty, DUMMY_SP));
self.shallow_copy_raw(bcx, dst)
}
ty::TyTrait(ref trait_data) => {
unique_type_id.push_str("trait ");
- let principal =
- ty::erase_late_bound_regions(cx.tcx(),
- &trait_data.principal);
+ let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
from_def_id_and_substs(self,
cx,
unique_type_id.push_str(" fn(");
- let sig = ty::erase_late_bound_regions(cx.tcx(), sig);
+ let sig = cx.tcx().erase_late_bound_regions(sig);
for ¶meter_type in &sig.inputs {
let parameter_type_id =
unique_type_id.push_str("|");
- let sig = ty::erase_late_bound_regions(cx.tcx(), sig);
+ let sig = cx.tcx().erase_late_bound_regions(sig);
for ¶meter_type in &sig.inputs {
let parameter_type_id =
span: Span)
-> MetadataCreationResult
{
- let signature = ty::erase_late_bound_regions(cx.tcx(), signature);
+ let signature = cx.tcx().erase_late_bound_regions(signature);
let mut signature_metadata: Vec<DIType> = Vec::with_capacity(signature.inputs.len() + 1);
unique_type_id,
containing_scope);
- let mut fields = ty::struct_fields(cx.tcx(), def_id, substs);
+ let mut fields = cx.tcx().struct_fields(def_id, substs);
// The `Ty` values returned by `ty::struct_fields` can still contain
// `TyProjection` variants, so normalize those away.
let loc = span_start(cx, definition_span);
let file_metadata = file_metadata(cx, &loc.file.name);
- let variants = ty::enum_variants(cx.tcx(), enum_def_id);
+ let variants = cx.tcx().enum_variants(enum_def_id);
let enumerators_metadata: Vec<DIDescriptor> = variants
.iter()
};
let is_local_to_unit = is_node_local_to_unit(cx, node_id);
- let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
+ let variable_type = cx.tcx().node_id_to_type(node_id);
let type_metadata = type_metadata(cx, variable_type, span);
let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
let var_name = token::get_name(name).to_string();
use trans::common::{NodeIdAndSpan, CrateContext, FunctionContext, Block};
use trans;
use trans::monomorphize;
-use middle::ty::{self, Ty, ClosureTyper};
+use middle::ty::{Ty, ClosureTyper};
use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
// Return type -- llvm::DIBuilder wants this at index 0
assert_type_for_node_id(cx, fn_ast_id, error_reporting_span);
- let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
+ let return_type = cx.tcx().node_id_to_type(fn_ast_id);
let return_type = monomorphize::apply_param_substs(cx.tcx(),
param_substs,
&return_type);
// Arguments types
for arg in &fn_decl.inputs {
assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
- let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
+ let arg_type = cx.tcx().node_id_to_type(arg.pat.id);
let arg_type = monomorphize::apply_param_substs(cx.tcx(),
param_substs,
&arg_type);
use llvm::debuginfo::DIScope;
use rustc::ast_map;
use trans::common::CrateContext;
-use middle::ty::{self, ClosureTyper};
+use middle::ty::ClosureTyper;
use std::ffi::CString;
use std::ptr;
}
pub fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
- ty::with_path(cx.tcx(), def_id, |path| {
+ cx.tcx().with_path(def_id, |path| {
// prepend crate name if not already present
let krate = if def_id.krate == ast::LOCAL_CRATE {
let crate_namespace_name = token::intern(crate_root_namespace(cx));
output.push(']');
},
ty::TyTrait(ref trait_data) => {
- let principal = ty::erase_late_bound_regions(cx.tcx(), &trait_data.principal);
+ let principal = cx.tcx().erase_late_bound_regions(&trait_data.principal);
push_item_name(cx, principal.def_id, false, output);
push_type_params(cx, principal.substs, output);
},
output.push_str("fn(");
- let sig = ty::erase_late_bound_regions(cx.tcx(), sig);
+ let sig = cx.tcx().erase_late_bound_regions(sig);
if !sig.inputs.is_empty() {
for ¶meter_type in &sig.inputs {
push_debuginfo_type_name(cx, parameter_type, true, output);
def_id: ast::DefId,
qualified: bool,
output: &mut String) {
- ty::with_path(cx.tcx(), def_id, |path| {
+ cx.tcx().with_path(def_id, |path| {
if qualified {
if def_id.krate == ast::LOCAL_CRATE {
output.push_str(crate_root_namespace(cx));
_ => ccx.sess().bug("expected closure or fn")
};
- let sig = ty::Binder(ty::erase_late_bound_regions(ccx.tcx(), sig));
+ let sig = ty::Binder(ccx.tcx().erase_late_bound_regions(sig));
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
let llfty = type_of::type_of_rust_fn(ccx, env, &sig, abi);
debug!("declare_rust_fn llfty={}", ccx.tn().type_to_string(llfty));
use trans::tvec;
use trans::type_of;
use middle::cast::{CastKind, CastTy};
-use middle::ty::{struct_fields, tup_fields};
use middle::ty::{AdjustDerefRef, AdjustReifyFnPointer, AdjustUnsafeFnPointer};
use middle::ty::{self, Ty};
use middle::ty::MethodCall;
old_info: Option<ValueRef>,
param_substs: &'tcx Substs<'tcx>)
-> ValueRef {
- let (source, target) = ty::struct_lockstep_tails(ccx.tcx(), source, target);
+ let (source, target) = ccx.tcx().struct_lockstep_tails(source, target);
match (&source.sty, &target.sty) {
(&ty::TyArray(_, len), &ty::TySlice(_)) => C_uint(ccx, len),
(&ty::TyTrait(_), &ty::TyTrait(_)) => {
let kind = match fulfill_obligation(bcx.ccx(), span, trait_ref) {
traits::VtableImpl(traits::VtableImplData { impl_def_id, .. }) => {
- ty::custom_coerce_unsized_kind(bcx.tcx(), impl_def_id)
+ bcx.tcx().custom_coerce_unsized_kind(impl_def_id)
}
vtable => {
bcx.sess().span_bug(span, &format!("invalid CoerceUnsized vtable: {:?}",
base: &ast::Expr,
field: ast::Name)
-> DatumBlock<'blk, 'tcx, Expr> {
- trans_field(bcx, base, |tcx, field_tys| ty::field_idx_strict(tcx, field, field_tys))
+ trans_field(bcx, base, |tcx, field_tys| tcx.field_idx_strict(field, field_tys))
}
/// Translates `base.<idx>`.
let ix_datum = unpack_datum!(bcx, trans(bcx, idx));
let ref_ty = // invoked methods have LB regions instantiated:
- ty::no_late_bound_regions(
- bcx.tcx(), &method_ty.fn_ret()).unwrap().unwrap();
+ bcx.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap();
let elt_ty = match ref_ty.builtin_deref(true) {
None => {
bcx.tcx().sess.span_bug(index_expr.span,
match def {
def::DefVariant(tid, vid, _) => {
- let variant_info = ty::enum_variant_with_id(bcx.tcx(), tid, vid);
+ let variant_info = bcx.tcx().enum_variant_with_id(tid, vid);
if !variant_info.args.is_empty() {
// N-ary variant.
let llfn = callee::trans_fn_ref(bcx.ccx(), vid,
def::DefStruct(_) => {
let ty = expr_ty(bcx, ref_expr);
match ty.sty {
- ty::TyStruct(did, _) if ty::has_dtor(bcx.tcx(), did) => {
+ ty::TyStruct(did, _) if bcx.tcx().has_dtor(did) => {
let repr = adt::represent_type(bcx.ccx(), ty);
adt::trans_set_discr(bcx, &*repr, lldest, 0);
}
{
match ty.sty {
ty::TyStruct(did, substs) => {
- let fields = struct_fields(tcx, did, substs);
+ let fields = tcx.struct_fields(did, substs);
let fields = monomorphize::normalize_associated_type(tcx, &fields);
op(0, &fields[..])
}
ty::TyTuple(ref v) => {
- op(0, &tup_fields(&v[..]))
+ let fields: Vec<_> = v.iter().enumerate().map(|(i, &f)| {
+ ty::field {
+ name: token::intern(&i.to_string()),
+ mt: ty::mt {
+ ty: f,
+ mutbl: ast::MutImmutable
+ }
+ }
+ }).collect();
+ op(0, &fields)
}
ty::TyEnum(_, substs) => {
let def = tcx.def_map.borrow().get(&node_id).unwrap().full_def();
match def {
def::DefVariant(enum_id, variant_id, _) => {
- let variant_info = ty::enum_variant_with_id(tcx, enum_id, variant_id);
- let fields = struct_fields(tcx, variant_id, substs);
+ let variant_info = tcx.enum_variant_with_id(enum_id, variant_id);
+ let fields = tcx.struct_fields(variant_id, substs);
let fields = monomorphize::normalize_associated_type(tcx, &fields);
op(variant_info.disr_val, &fields[..])
}
};
let ref_ty = // invoked methods have their LB regions instantiated
- ty::no_late_bound_regions(
- ccx.tcx(), &method_ty.fn_ret()).unwrap().unwrap();
+ ccx.tcx().no_late_bound_regions(&method_ty.fn_ret()).unwrap().unwrap();
let scratch = rvalue_scratch_datum(bcx, ref_ty, "overloaded_deref");
unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
match expr.node {
ast::ExprPath(..) => {
- match ty::resolve_expr(tcx, expr) {
+ match tcx.resolve_expr(expr) {
def::DefStruct(_) | def::DefVariant(..) => {
- if let ty::TyBareFn(..) = ty::node_id_to_type(tcx, expr.id).sty {
+ if let ty::TyBareFn(..) = tcx.node_id_to_type(expr.id).sty {
// ctor function
ExprKind::RvalueDatum
} else {
pub fn register_static(ccx: &CrateContext,
foreign_item: &ast::ForeignItem) -> ValueRef {
- let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
+ let ty = ccx.tcx().node_id_to_type(foreign_item.id);
let llty = type_of::type_of(ccx, ty);
let ident = link_name(foreign_item);
ty::TyBareFn(_, ref fn_ty) => (fn_ty.abi, &fn_ty.sig),
_ => ccx.sess().bug("trans_native_call called on non-function type")
};
- let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
+ let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
let llsig = foreign_signature(ccx, &fn_sig, &passed_arg_tys[..]);
let fn_type = cabi::compute_abi_info(ccx,
&llsig.llarg_tys,
match foreign_mod.abi {
Rust | RustIntrinsic => {}
abi => {
- let ty = ty::node_id_to_type(ccx.tcx(), foreign_item.id);
+ let ty = ccx.tcx().node_id_to_type(foreign_item.id);
match ty.sty {
ty::TyBareFn(_, bft) => gate_simd_ffi(ccx.tcx(), &**decl, bft),
_ => ccx.tcx().sess.span_bug(foreign_item.span,
let tys = foreign_types_for_id(ccx, node_id);
let llfn_ty = lltype_for_fn_from_foreign_types(ccx, &tys);
- let t = ty::node_id_to_type(ccx.tcx(), node_id);
+ let t = ccx.tcx().node_id_to_type(node_id);
let cconv = match t.sty {
ty::TyBareFn(_, ref fn_ty) => {
llvm_calling_convention(ccx, fn_ty.abi)
hash: Option<&str>) {
let _icx = push_ctxt("foreign::build_foreign_fn");
- let fnty = ty::node_id_to_type(ccx.tcx(), id);
+ let fnty = ccx.tcx().node_id_to_type(id);
let mty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fnty);
let tys = foreign_types_for_fn_ty(ccx, mty);
{
let _icx = push_ctxt("foreign::foreign::build_rust_fn");
let tcx = ccx.tcx();
- let t = ty::node_id_to_type(tcx, id);
+ let t = tcx.node_id_to_type(id);
let t = monomorphize::apply_param_substs(tcx, param_substs, &t);
let ps = ccx.tcx().map.with_path(id, |path| {
fn foreign_types_for_id<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
id: ast::NodeId) -> ForeignTypes<'tcx> {
- foreign_types_for_fn_ty(ccx, ty::node_id_to_type(ccx.tcx(), id))
+ foreign_types_for_fn_ty(ccx, ccx.tcx().node_id_to_type(id))
}
fn foreign_types_for_fn_ty<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ty::TyBareFn(_, ref fn_ty) => &fn_ty.sig,
_ => ccx.sess().bug("foreign_types_for_fn_ty called on non-function type")
};
- let fn_sig = ty::erase_late_bound_regions(ccx.tcx(), fn_sig);
+ let fn_sig = ccx.tcx().erase_late_bound_regions(fn_sig);
let llsig = foreign_signature(ccx, &fn_sig, &fn_sig.inputs);
let fn_ty = cabi::compute_abi_info(ccx,
&llsig.llarg_tys,
} else {
let tcx = ccx.tcx();
let name = csearch::get_symbol(&ccx.sess().cstore, did);
- let class_ty = ty::lookup_item_type(tcx, parent_id).ty.subst(tcx, substs);
+ let class_ty = tcx.lookup_item_type(parent_id).ty.subst(tcx, substs);
let llty = type_of_dtor(ccx, class_ty);
let dtor_ty = ccx.tcx().mk_ctor_fn(did,
&[get_drop_glue_type(ccx, t)],
// Recurse to get the size of the dynamically sized field (must be
// the last field).
- let fields = ty::struct_fields(bcx.tcx(), id, substs);
+ let fields = bcx.tcx().struct_fields(id, substs);
let last_field = fields[fields.len()-1];
let field_ty = last_field.mt.ty;
let (unsized_size, unsized_align) = size_and_align_of_dst(bcx, field_ty, info);
}
ty::TyStruct(did, substs) | ty::TyEnum(did, substs) => {
let tcx = bcx.tcx();
- match (ty::ty_dtor(tcx, did), skip_dtor) {
+ match (tcx.ty_dtor(did), skip_dtor) {
(ty::TraitDtor(dtor, true), false) => {
// FIXME(16758) Since the struct is unsized, it is hard to
// find the drop flag (which is at the end of the struct).
use middle::subst::Substs;
use trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
use trans::common::*;
-use middle::ty;
use syntax::ast;
use syntax::ast_util::local_def;
Some(&Some(node_id)) => {
// Already inline
debug!("instantiate_inline({}): already inline as node id {}",
- ty::item_path_str(ccx.tcx(), fn_id), node_id);
+ ccx.tcx().item_path_str(fn_id), node_id);
return Some(local_def(node_id));
}
Some(&None) => {
let mut my_id = 0;
match item.node {
ast::ItemEnum(_, _) => {
- let vs_here = ty::enum_variants(ccx.tcx(), local_def(item.id));
- let vs_there = ty::enum_variants(ccx.tcx(), parent_id);
+ let vs_here = ccx.tcx().enum_variants(local_def(item.id));
+ let vs_there = ccx.tcx().enum_variants(parent_id);
for (here, there) in vs_here.iter().zip(vs_there.iter()) {
if there.id == fn_id { my_id = here.id.node; }
ccx.external().borrow_mut().insert(there.id, Some(here.id.node));
// the logic to do that already exists in `middle`. In order to
// reuse that code, it needs to be able to look up the traits for
// inlined items.
- let ty_trait_item = ty::impl_or_trait_item(ccx.tcx(), fn_id).clone();
+ let ty_trait_item = ccx.tcx().impl_or_trait_item(fn_id).clone();
ccx.tcx().impl_or_trait_items.borrow_mut()
.insert(local_def(trait_item.id), ty_trait_item);
// Translate monomorphic impl methods immediately.
if let ast::MethodImplItem(ref sig, ref body) = impl_item.node {
- let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
+ let impl_tpt = ccx.tcx().lookup_item_type(impl_did);
if impl_tpt.generics.types.is_empty() &&
sig.generics.ty_params.is_empty() {
let empty_substs = ccx.tcx().mk_substs(Substs::trans_empty());
let ret_ty = match callee_ty.sty {
ty::TyBareFn(_, ref f) => {
- ty::erase_late_bound_regions(bcx.tcx(), &f.sig.output())
+ bcx.tcx().erase_late_bound_regions(&f.sig.output())
}
_ => panic!("expected bare_fn in trans_intrinsic_call")
};
C_str_slice(ccx, ty_name)
}
(_, "type_id") => {
- let hash = ty::hash_crate_independent(
- ccx.tcx(),
- *substs.types.get(FnSpace, 0),
- &ccx.link_meta().crate_hash);
+ let hash = ccx.tcx().hash_crate_independent(*substs.types.get(FnSpace, 0),
+ &ccx.link_meta().crate_hash);
C_u64(ccx, hash)
}
(_, "init_dropped") => {
debug!("trans_static_method_callee(method_id={:?}, trait_id={}, \
expr_id={})",
method_id,
- ty::item_path_str(tcx, trait_id),
+ tcx.item_path_str(trait_id),
expr_id);
let mname = if method_id.krate == ast::LOCAL_CRATE {
}
traits::VtableObject(ref data) => {
let trait_item_def_ids =
- ty::trait_item_def_ids(ccx.tcx(), trait_id);
+ ccx.tcx().trait_item_def_ids(trait_id);
let method_offset_in_trait =
trait_item_def_ids.iter()
.position(|item| item.def_id() == method_id)
.expect("could not find impl while translating");
let meth_did = impl_items.iter()
.find(|&did| {
- ty::impl_or_trait_item(ccx.tcx(), did.def_id()).name() == name
+ ccx.tcx().impl_or_trait_item(did.def_id()).name() == name
}).expect("could not find method while \
translating");
traits::VtableImpl(vtable_impl) => {
let ccx = bcx.ccx();
let impl_did = vtable_impl.impl_def_id;
- let mname = match ty::trait_item(ccx.tcx(), trait_id, n_method) {
+ let mname = match ccx.tcx().trait_item(trait_id, n_method) {
ty::MethodTraitItem(method) => method.name,
_ => {
bcx.tcx().sess.bug("can't monomorphize a non-method trait \
};
// Upcast to the trait in question and extract out the substitutions.
- let upcast_trait_ref = ty::erase_late_bound_regions(tcx, &upcast_trait_ref);
+ let upcast_trait_ref = tcx.erase_late_bound_regions(&upcast_trait_ref);
let object_substs = upcast_trait_ref.substs.clone().erase_regions();
debug!("trans_object_shim: object_substs={:?}", object_substs);
// Lookup the type of this method as declared in the trait and apply substitutions.
- let method_ty = match ty::trait_item(tcx, trait_id, method_offset_in_trait) {
+ let method_ty = match tcx.trait_item(trait_id, method_offset_in_trait) {
ty::MethodTraitItem(method) => method,
_ => {
tcx.sess.bug("can't create a method shim for a non-method item")
ccx.sess().bug(&format!("symbol `{}` already defined", function_name));
});
- let sig = ty::erase_late_bound_regions(ccx.tcx(), &fty.sig);
+ let sig = ccx.tcx().erase_late_bound_regions(&fty.sig);
let empty_substs = tcx.mk_substs(Substs::trans_empty());
let (block_arena, fcx): (TypedArena<_>, FunctionContext);
substs,
param_substs);
- let trt_id = match ty::impl_trait_ref(tcx, impl_id) {
+ let trt_id = match tcx.impl_trait_ref(impl_id) {
Some(t_id) => t_id.def_id,
None => ccx.sess().bug("make_impl_vtable: don't know how to \
make a vtable for a type impl!")
};
- ty::populate_implementations_for_trait_if_necessary(tcx, trt_id);
+ tcx.populate_implementations_for_trait_if_necessary(trt_id);
let nullptr = C_null(Type::nil(ccx).ptr_to());
- let trait_item_def_ids = ty::trait_item_def_ids(tcx, trt_id);
+ let trait_item_def_ids = tcx.trait_item_def_ids(trt_id);
trait_item_def_ids
.iter()
debug!("emit_vtable_methods: trait_method_def_id={:?}",
trait_method_def_id);
- let trait_method_type = match ty::impl_or_trait_item(tcx, trait_method_def_id) {
+ let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) {
ty::MethodTraitItem(m) => m,
_ => ccx.sess().bug("should be a method, not other assoc item"),
};
// The substitutions we have are on the impl, so we grab
// the method type from the impl to substitute into.
let impl_method_def_id = method_with_name(ccx, impl_id, name);
- let impl_method_type = match ty::impl_or_trait_item(tcx, impl_method_def_id) {
+ let impl_method_type = match tcx.impl_or_trait_item(impl_method_def_id) {
ty::MethodTraitItem(m) => m,
_ => ccx.sess().bug("should be a method, not other assoc item"),
};
// particular set of type parameters. Note that this
// method could then never be called, so we do not want to
// try and trans it, in that case. Issue #23435.
- if ty::provided_source(tcx, impl_method_def_id).is_some() {
+ if tcx.provided_source(impl_method_def_id).is_some() {
let predicates = impl_method_type.predicates.predicates.subst(tcx, &substs);
if !normalize_and_test_predicates(ccx, predicates.into_vec()) {
debug!("emit_vtable_methods: predicates do not hold");
params: &psubsts.types
};
- let item_ty = ty::lookup_item_type(ccx.tcx(), fn_id).ty;
+ let item_ty = ccx.tcx().lookup_item_type(fn_id).ty;
debug!("monomorphic_fn about to subst into {:?}", item_ty);
let mono_ty = item_ty.subst(ccx.tcx(), psubsts);
match ccx.monomorphized().borrow().get(&hash_id) {
Some(&val) => {
debug!("leaving monomorphic fn {}",
- ty::item_path_str(ccx.tcx(), fn_id));
+ ccx.tcx().item_path_str(fn_id));
return (val, mono_ty, false);
}
None => ()
}
ast_map::NodeVariant(v) => {
let parent = ccx.tcx().map.get_parent(fn_id.node);
- let tvs = ty::enum_variants(ccx.tcx(), local_def(parent));
+ let tvs = ccx.tcx().enum_variants(local_def(parent));
let this_tv = tvs.iter().find(|tv| { tv.id.node == fn_id.node}).unwrap();
let d = mk_lldecl(abi::Rust);
attributes::inline(d, attributes::InlineAttr::Hint);
ccx.monomorphizing().borrow_mut().insert(fn_id, depth);
- debug!("leaving monomorphic fn {}", ty::item_path_str(ccx.tcx(), fn_id));
+ debug!("leaving monomorphic fn {}", ccx.tcx().item_path_str(fn_id));
(lldecl, mono_ty, true)
}
return expr::trans_into(bcx, &**element, Ignore);
}
SaveIn(lldest) => {
- match ty::eval_repeat_count(bcx.tcx(), &**count_expr) {
+ match bcx.tcx().eval_repeat_count(&**count_expr) {
0 => expr::trans_into(bcx, &**element, Ignore),
1 => expr::trans_into(bcx, &**element, SaveIn(lldest)),
count => {
},
ast::ExprVec(ref es) => es.len(),
ast::ExprRepeat(_, ref count_expr) => {
- ty::eval_repeat_count(bcx.tcx(), &**count_expr)
+ bcx.tcx().eval_repeat_count(&**count_expr)
}
_ => bcx.tcx().sess.span_bug(content_expr.span,
"unexpected vec content")
sig,
abi);
- let sig = ty::erase_late_bound_regions(cx.tcx(), sig);
+ let sig = cx.tcx().erase_late_bound_regions(sig);
assert!(!sig.variadic); // rust fns are never variadic
let mut atys: Vec<Type> = Vec::new();
cx.tn().find_type("str_slice").unwrap()
} else {
let ptr_ty = in_memory_type_of(cx, ty).ptr_to();
- let unsized_part = ty::struct_tail(cx.tcx(), ty);
+ let unsized_part = cx.tcx().struct_tail(ty);
let info_ty = match unsized_part.sty {
ty::TyStr | ty::TyArray(..) | ty::TySlice(_) => {
Type::uint_from_ty(cx, ast::TyUs)
did: ast::DefId,
tps: &[Ty<'tcx>])
-> String {
- let base = ty::item_path_str(cx.tcx(), did);
+ let base = cx.tcx().item_path_str(did);
let strings: Vec<String> = tps.iter().map(|t| t.to_string()).collect();
let tstr = if strings.is_empty() {
base
item_name: ast::Name)
-> Ty<'tcx>
{
- if ty::binds_late_bound_regions(self.tcx(), &poly_trait_ref) {
+ if self.tcx().binds_late_bound_regions(&poly_trait_ref) {
span_err!(self.tcx().sess, span, E0212,
"cannot extract an associated type from a higher-ranked trait bound \
in this context");
for (input_type, input_pat) in input_tys.iter().zip(input_pats) {
let mut accumulator = Vec::new();
- ty::accumulate_lifetimes_in_type(&mut accumulator, *input_type);
+ input_type.accumulate_lifetimes_in_type(&mut accumulator);
if accumulator.len() == 1 {
// there's a chance that the unique lifetime of this
let mut associated_types: FnvHashSet<(ast::DefId, ast::Name)> =
traits::supertraits(tcx, object_trait_ref)
.flat_map(|tr| {
- let trait_def = ty::lookup_trait_def(tcx, tr.def_id());
+ let trait_def = tcx.lookup_trait_def(tr.def_id());
trait_def.associated_type_names
.clone()
.into_iter()
span_err!(tcx.sess, span, E0191,
"the value of the associated type `{}` (from the trait `{}`) must be specified",
name,
- ty::item_path_str(tcx, trait_def_id));
+ tcx.item_path_str(trait_def_id));
}
tcx.mk_trait(object.principal, object.bounds)
_ => unreachable!()
}
} else {
- let trait_items = ty::trait_items(tcx, trait_did);
+ let trait_items = tcx.trait_items(trait_did);
let item = trait_items.iter().find(|i| i.name() == assoc_name);
item.expect("missing associated type").def_id()
};
let self_ty = if let Some(ty) = opt_self_ty {
ty
} else {
- let path_str = ty::item_path_str(tcx, trait_def_id);
+ let path_str = tcx.item_path_str(trait_def_id);
report_ambiguous_associated_type(tcx,
span,
"Type",
ast::TraitTyParamBound(ref b, ast::TraitBoundModifier::None) => {
match ::lookup_full_def(tcx, b.trait_ref.path.span, b.trait_ref.ref_id) {
def::DefTrait(trait_did) => {
- if ty::try_add_builtin_trait(tcx,
- trait_did,
+ if tcx.try_add_builtin_trait(trait_did,
&mut builtin_bounds) {
let segments = &b.trait_ref.path.segments;
let parameters = &segments[segments.len() - 1].parameters;
}
ast::PatEnum(..) | ast::PatIdent(..) if pat_is_resolved_const(&tcx.def_map, pat) => {
let const_did = tcx.def_map.borrow().get(&pat.id).unwrap().def_id();
- let const_scheme = ty::lookup_item_type(tcx, const_did);
+ let const_scheme = tcx.lookup_item_type(const_did);
assert!(const_scheme.generics.is_empty());
let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
&Substs::empty(),
resolve_ty_and_def_ufcs(fcx, path_res, Some(self_ty),
path, pat.span, pat.id) {
if check_assoc_item_is_const(pcx, def, pat.span) {
- let scheme = ty::lookup_item_type(tcx, def.def_id());
- let predicates = ty::lookup_predicates(tcx, def.def_id());
+ let scheme = tcx.lookup_item_type(def.def_id());
+ let predicates = tcx.lookup_predicates(def.def_id());
instantiate_path(fcx, segments,
scheme, &predicates,
opt_ty, def, pat.span, pat.id);
return;
},
_ => {
- let def_type = ty::lookup_item_type(tcx, def.def_id());
+ let def_type = tcx.lookup_item_type(def.def_id());
match def_type.ty.sty {
ty::TyStruct(struct_def_id, _) =>
(struct_def_id, struct_def_id),
instantiate_path(pcx.fcx,
&path.segments,
- ty::lookup_item_type(tcx, enum_def_id),
- &ty::lookup_predicates(tcx, enum_def_id),
+ tcx.lookup_item_type(enum_def_id),
+ &tcx.lookup_predicates(enum_def_id),
None,
def,
pat.span,
.map(|substs| substs.substs.clone())
.unwrap_or_else(|| Substs::empty());
- let struct_fields = ty::struct_fields(tcx, variant_def_id, &item_substs);
+ let struct_fields = tcx.struct_fields(variant_def_id, &item_substs);
check_struct_pat_fields(pcx, pat.span, fields, &struct_fields,
variant_def_id, etc);
}
let enum_def = def.variant_def_ids()
.map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
- let ctor_scheme = ty::lookup_item_type(tcx, enum_def);
- let ctor_predicates = ty::lookup_predicates(tcx, enum_def);
+ let ctor_scheme = tcx.lookup_item_type(enum_def);
+ let ctor_predicates = tcx.lookup_predicates(enum_def);
let path_scheme = if ctor_scheme.ty.is_fn() {
- let fn_ret = ty::no_late_bound_regions(tcx, &ctor_scheme.ty.fn_ret()).unwrap();
+ let fn_ret = tcx.no_late_bound_regions(&ctor_scheme.ty.fn_ret()).unwrap();
ty::TypeScheme {
ty: fn_ret.unwrap(),
generics: ctor_scheme.generics,
ty::TyEnum(enum_def_id, expected_substs)
if def == def::DefVariant(enum_def_id, def.def_id(), false) =>
{
- let variant = ty::enum_variant_with_id(tcx, enum_def_id, def.def_id());
+ let variant = tcx.enum_variant_with_id(enum_def_id, def.def_id());
(variant.args.iter()
.map(|t| fcx.instantiate_type_scheme(pat.span, expected_substs, t))
.collect(),
"variant")
}
ty::TyStruct(struct_def_id, expected_substs) => {
- let struct_fields = ty::struct_fields(tcx, struct_def_id, expected_substs);
+ let struct_fields = tcx.struct_fields(struct_def_id, expected_substs);
(struct_fields.iter()
.map(|field| fcx.instantiate_type_scheme(pat.span,
expected_substs,
.unwrap_or_else(|| {
span_err!(tcx.sess, span, E0026,
"struct `{}` does not have a field named `{}`",
- ty::item_path_str(tcx, struct_id),
+ tcx.item_path_str(struct_id),
token::get_ident(field.ident));
tcx.types.err
})
// can't because of the annoying need for a TypeTrace.
// (This always bites me, should find a way to
// refactor it.)
- let method_sig =
- ty::no_late_bound_regions(fcx.tcx(),
- method_callee.ty.fn_sig()).unwrap();
+ let method_sig = fcx.tcx().no_late_bound_regions(method_callee.ty.fn_sig())
+ .unwrap();
debug!("attempt_resolution: method_callee={:?}",
method_callee);
ty::TySlice(_) | ty::TyStr => Some(UnsizeKind::Length),
ty::TyTrait(ref tty) => Some(UnsizeKind::Vtable(tty.principal_def_id())),
ty::TyStruct(did, substs) => {
- match ty::struct_fields(fcx.tcx(), did, substs).pop() {
+ match fcx.tcx().struct_fields(did, substs).pop() {
None => None,
Some(f) => unsize_kind(fcx, f.mt.ty)
}
fcx.write_ty(expr.id, closure_type);
- let fn_sig =
- ty::liberate_late_bound_regions(fcx.tcx(),
- region::DestructionScopeData::new(body.id),
- &fn_ty.sig);
+ let fn_sig = fcx.tcx().liberate_late_bound_regions(
+ region::DestructionScopeData::new(body.id), &fn_ty.sig);
check_fn(fcx.ccx,
ast::Unsafety::Normal,
}
_ => (source, None)
};
- let source = ty::adjust_ty_for_autoref(self.tcx(), source, reborrow);
+ let source = source.adjust_for_autoref(self.tcx(), reborrow);
let mut selcx = traits::SelectionContext::new(self.fcx.infcx(), self.fcx);
token::get_name(trait_m.name),
impl_m.fty.sig.0.inputs.len(),
if impl_m.fty.sig.0.inputs.len() == 1 {""} else {"s"},
- ty::item_path_str(tcx, trait_m.def_id),
+ tcx.item_path_str(trait_m.def_id),
trait_m.fty.sig.0.inputs.len());
return;
}
///
pub fn check_drop_impl(tcx: &ty::ctxt, drop_impl_did: ast::DefId) -> Result<(), ()> {
let ty::TypeScheme { generics: ref dtor_generics,
- ty: dtor_self_type } = ty::lookup_item_type(tcx, drop_impl_did);
- let dtor_predicates = ty::lookup_predicates(tcx, drop_impl_did);
+ ty: dtor_self_type } = tcx.lookup_item_type(drop_impl_did);
+ let dtor_predicates = tcx.lookup_predicates(drop_impl_did);
match dtor_self_type.sty {
ty::TyEnum(self_type_did, self_to_impl_substs) |
ty::TyStruct(self_type_did, self_to_impl_substs) |
let ty::TypeScheme { generics: ref named_type_generics,
ty: named_type } =
- ty::lookup_item_type(tcx, self_type_did);
+ tcx.lookup_item_type(self_type_did);
let infcx = infer::new_infer_ctxt(tcx);
infcx.commit_if_ok(|snapshot| {
// We can assume the predicates attached to struct/enum definition
// hold.
- let generic_assumptions = ty::lookup_predicates(tcx, self_type_did);
+ let generic_assumptions = tcx.lookup_predicates(self_type_did);
let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::SelfSpace));
rcx.tcx().sess,
span,
"overflowed on enum {} variant {} argument {} type: {}",
- ty::item_path_str(tcx, def_id),
+ tcx.item_path_str(def_id),
variant,
arg_index,
detected_on_typ);
rcx.tcx().sess,
span,
"overflowed on struct {} field {} type: {}",
- ty::item_path_str(tcx, def_id),
+ tcx.item_path_str(def_id),
field,
detected_on_typ);
}
let (typ, xref_depth) = match typ.sty {
ty::TyStruct(struct_did, substs) => {
if opt_phantom_data_def_id == Some(struct_did) {
- let item_type = ty::lookup_item_type(rcx.tcx(), struct_did);
+ let item_type = rcx.tcx().lookup_item_type(struct_did);
let tp_def = item_type.generics.types
.opt_get(subst::TypeSpace, 0).unwrap();
let new_typ = substs.type_for_def(tp_def);
walker.skip_current_subtree();
let fields =
- ty::lookup_struct_fields(rcx.tcx(), struct_did);
+ rcx.tcx().lookup_struct_fields(struct_did);
for field in &fields {
- let field_type =
- ty::lookup_field_type(rcx.tcx(),
- struct_did,
- field.id,
- substs);
+ let field_type = rcx.tcx().lookup_field_type(struct_did,
+ field.id,
+ substs);
try!(iterate_over_potentially_unsafe_regions_in_type(
rcx,
breadcrumbs,
walker.skip_current_subtree();
let all_variant_info =
- ty::substd_enum_variants(rcx.tcx(),
- enum_did,
- substs);
+ rcx.tcx().substd_enum_variants(enum_did, substs);
for variant_info in &all_variant_info {
for (i, arg_type) in variant_info.args.iter().enumerate() {
try!(iterate_over_potentially_unsafe_regions_in_type(
}
}
DtorKind::KnownDropMethod(dtor_method_did) => {
- let impl_did = ty::impl_of_method(tcx, dtor_method_did)
+ let impl_did = tcx.impl_of_method(dtor_method_did)
.unwrap_or_else(|| {
tcx.sess.span_bug(
span, "no Drop impl found for drop method")
});
- let dtor_typescheme = ty::lookup_item_type(tcx, impl_did);
+ let dtor_typescheme = tcx.lookup_item_type(impl_did);
let dtor_generics = dtor_typescheme.generics;
let mut has_pred_of_interest = false;
continue;
}
- for pred in ty::lookup_predicates(tcx, item_def_id).predicates {
+ for pred in tcx.lookup_predicates(item_def_id).predicates {
let result = match pred {
ty::Predicate::Equate(..) |
ty::Predicate::RegionOutlives(..) |
ty::Predicate::Trait(ty::Binder(ref t_pred)) => {
let def_id = t_pred.trait_ref.def_id;
- if ty::trait_items(tcx, def_id).len() != 0 {
+ if tcx.trait_items(def_id).len() != 0 {
// If trait has items, assume it adds
// capability to access borrowed data.
true
let region = self.infcx().next_region_var(infer::Autoref(self.span));
let autoref = ty::AutoPtr(self.tcx().mk_region(region), mutbl);
(Some(autoref), pick.unsize.map(|target| {
- ty::adjust_ty_for_autoref(self.tcx(), target, Some(autoref))
+ target.adjust_for_autoref(self.tcx(), Some(autoref))
}))
} else {
// No unsizing should be performed without autoref (at
if let Some(target) = unsize {
target
} else {
- ty::adjust_ty_for_autoref(self.tcx(), autoderefd_ty, autoref)
+ autoderefd_ty.adjust_for_autoref(self.tcx(), autoref)
}
}
{
match pick.kind {
probe::InherentImplPick(impl_def_id) => {
- assert!(ty::impl_trait_ref(self.tcx(), impl_def_id).is_none(),
+ assert!(self.tcx().impl_trait_ref(impl_def_id).is_none(),
"impl {:?} is not an inherent impl", impl_def_id);
let impl_polytype = check::impl_self_ty(self.fcx, self.span, impl_def_id);
self.fcx.instantiate_type_scheme(
self.span,
&impl_polytype.substs,
- &ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap());
+ &self.tcx().impl_trait_ref(impl_def_id).unwrap());
let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(),
method_num: method_num,
impl_def_id: Some(impl_def_id) });
}
probe::TraitPick(trait_def_id, method_num) => {
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_def_id);
// Make a trait reference `$0 : Trait<$1...$n>`
// consisting entirely of type variables. Later on in
m_name,
trait_def_id);
- let trait_def = ty::lookup_trait_def(fcx.tcx(), trait_def_id);
+ let trait_def = fcx.tcx().lookup_trait_def(trait_def_id);
let expected_number_of_input_types = trait_def.generics.types.len(subst::TypeSpace);
let input_types = match opt_input_types {
item_name: ast::Name)
-> Option<(usize, ty::ImplOrTraitItem<'tcx>)>
{
- let trait_items = ty::trait_items(tcx, trait_def_id);
+ let trait_items = tcx.trait_items(trait_def_id);
trait_items
.iter()
.enumerate()
let impl_items = impl_items.get(&impl_def_id).unwrap();
impl_items
.iter()
- .map(|&did| ty::impl_or_trait_item(tcx, did.def_id()))
+ .map(|&did| tcx.impl_or_trait_item(did.def_id()))
.find(|m| m.name() == item_name)
}
fn assemble_inherent_impl_for_primitive(&mut self, lang_def_id: Option<ast::DefId>) {
if let Some(impl_def_id) = lang_def_id {
- ty::populate_implementations_for_primitive_if_necessary(self.tcx(), impl_def_id);
+ self.tcx().populate_implementations_for_primitive_if_necessary(impl_def_id);
self.assemble_inherent_impl_probe(impl_def_id);
}
fn assemble_inherent_impl_candidates_for_type(&mut self, def_id: ast::DefId) {
// Read the inherent implementation candidates for this type from the
// metadata if necessary.
- ty::populate_inherent_implementations_for_type_if_necessary(self.tcx(), def_id);
+ self.tcx().populate_inherent_implementations_for_type_if_necessary(def_id);
if let Some(impl_infos) = self.tcx().inherent_impls.borrow().get(&def_id) {
for &impl_def_id in impl_infos.iter() {
// Check whether `trait_def_id` defines a method with suitable name:
let trait_items =
- ty::trait_items(self.tcx(), trait_def_id);
+ self.tcx().trait_items(trait_def_id);
let matching_index =
trait_items.iter()
.position(|item| item.name() == self.item_name);
item: ty::ImplOrTraitItem<'tcx>,
item_index: usize)
{
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_def_id);
// FIXME(arielb1): can we use for_each_relevant_impl here?
trait_def.for_each_impl(self.tcx(), |impl_def_id| {
debug!("impl_substs={:?}", impl_substs);
let impl_trait_ref =
- ty::impl_trait_ref(self.tcx(), impl_def_id)
+ self.tcx().impl_trait_ref(impl_def_id)
.unwrap() // we know this is a trait impl
.subst(self.tcx(), &impl_substs);
None => { return true; }
};
- let impl_type = ty::lookup_item_type(self.tcx(), impl_def_id);
+ let impl_type = self.tcx().lookup_item_type(impl_def_id);
let impl_simplified_type =
match fast_reject::simplify_type(self.tcx(), impl_type.ty, false) {
Some(simplified_type) => simplified_type,
// for the purposes of our method lookup, we only take
// receiver type into account, so we can just substitute
// fresh types here to use during substitution and subtyping.
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_def_id);
let substs = self.infcx().fresh_substs_for_trait(self.span,
&trait_def.generics,
step.self_ty);
debug!("assemble_projection_candidates: projection_trait_ref={:?}",
projection_trait_ref);
- let trait_predicates = ty::lookup_predicates(self.tcx(),
- projection_trait_ref.def_id);
+ let trait_predicates = self.tcx().lookup_predicates(projection_trait_ref.def_id);
let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
let predicates = bounds.predicates.into_vec();
debug!("assemble_projection_candidates: predicates={:?}",
match source {
TraitSource(id) => id,
ImplSource(impl_id) => {
- match ty::trait_id_of_impl(tcx, impl_id) {
+ match tcx.trait_id_of_impl(impl_id) {
Some(id) => id,
None =>
tcx.sess.span_bug(span,
let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
// Check whether the impl imposes obligations we have to worry about.
- let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
+ let impl_bounds = self.tcx().lookup_predicates(impl_def_id);
let impl_bounds = impl_bounds.instantiate(self.tcx(), substs);
let traits::Normalized { value: impl_bounds,
obligations: norm_obligations } =
impl_def_id: ast::DefId)
-> (Ty<'tcx>, subst::Substs<'tcx>)
{
- let impl_pty = ty::lookup_item_type(self.tcx(), impl_def_id);
+ let impl_pty = self.tcx().lookup_item_type(impl_def_id);
let type_vars =
impl_pty.generics.types.map(
fn erase_late_bound_regions<T>(&self, value: &ty::Binder<T>) -> T
where T : TypeFoldable<'tcx>
{
- ty::erase_late_bound_regions(self.tcx(), value)
+ self.tcx().erase_late_bound_regions(value)
}
}
let impl_items = impl_items.get(&impl_def_id).unwrap();
impl_items
.iter()
- .map(|&did| ty::impl_or_trait_item(tcx, did.def_id()))
+ .map(|&did| tcx.impl_or_trait_item(did.def_id()))
.find(|item| item.name() == item_name)
}
item_name: ast::Name)
-> Option<(usize, ty::ImplOrTraitItem<'tcx>)>
{
- let trait_items = ty::trait_items(tcx, trait_def_id);
+ let trait_items = tcx.trait_items(trait_def_id);
debug!("trait_method; items: {:?}", trait_items);
trait_items
.iter()
// If the item has the name of a field, give a help note
if let (&ty::TyStruct(did, substs), Some(expr)) = (&rcvr_ty.sty, rcvr_expr) {
- let fields = ty::lookup_struct_fields(cx, did);
+ let fields = cx.lookup_struct_fields(did);
if let Some(field) = fields.iter().find(|f| f.name == item_name) {
let expr_string = match cx.sess.codemap().span_to_snippet(expr.span) {
};
// Determine if the field can be used as a function in some way
- let field_ty = ty::lookup_field_type(cx, did, field.id, substs);
+ let field_ty = cx.lookup_field_type(did, field.id, substs);
if let Ok(fn_once_trait_did) = cx.lang_items.require(FnOnceTraitLangItem) {
let infcx = fcx.infcx();
infcx.probe(|_| {
invoked on this closure as we have not yet inferred what \
kind of closure it is",
item_name,
- ty::item_path_str(fcx.tcx(), trait_def_id));
+ fcx.tcx().item_path_str(trait_def_id));
let msg = if let Some(callee) = rcvr_expr {
format!("{}; use overloaded call notation instead (e.g., `{}()`)",
msg, pprust::expr_to_string(callee))
let impl_ty = check::impl_self_ty(fcx, span, impl_did).ty;
- let insertion = match ty::impl_trait_ref(fcx.tcx(), impl_did) {
+ let insertion = match fcx.tcx().impl_trait_ref(impl_did) {
None => format!(""),
- Some(trait_ref) => format!(" of the trait `{}`",
- ty::item_path_str(fcx.tcx(),
- trait_ref.def_id)),
+ Some(trait_ref) => {
+ format!(" of the trait `{}`",
+ fcx.tcx().item_path_str(trait_ref.def_id))
+ }
};
span_note!(fcx.sess(), item_span,
span_note!(fcx.sess(), item_span,
"candidate #{} is defined in the trait `{}`",
idx + 1,
- ty::item_path_str(fcx.tcx(), trait_did));
+ fcx.tcx().item_path_str(trait_did));
}
}
}
fcx.sess().fileline_help(span,
&*format!("candidate #{}: use `{}`",
i + 1,
- ty::item_path_str(fcx.tcx(), *trait_did)))
+ fcx.tcx().item_path_str(*trait_did)))
}
return
fcx.sess().fileline_help(span,
&*format!("candidate #{}: `{}`",
i + 1,
- ty::item_path_str(fcx.tcx(), trait_info.def_id)))
+ fcx.tcx().item_path_str(trait_info.def_id)))
}
}
}
use middle::ty::{FnSig, GenericPredicates, TypeScheme};
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
use middle::ty::{self, HasTypeFlags, RegionEscape, ToPolyTraitRef, Ty};
-use middle::ty::liberate_late_bound_regions;
use middle::ty::{MethodCall, MethodCallee, MethodMap};
use middle::ty_fold::{TypeFolder, TypeFoldable};
use rscope::RegionScope;
let ty = self.adjust_expr_ty(expr, self.inh.adjustments.borrow().get(&expr.id));
self.resolve_type_vars_or_error(&ty)
}
- fn type_moves_by_default(&self, span: Span, ty: Ty<'tcx>) -> bool {
+ fn type_moves_by_default(&self, ty: Ty<'tcx>, span: Span) -> bool {
let ty = self.infcx().resolve_type_vars_if_possible(&ty);
!traits::type_known_to_meet_builtin_bound(self.infcx(), self, ty, ty::BoundCopy, span)
}
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
- -> Option<Vec<ty::ClosureUpvar<'tcx>>>
- {
- ty::closure_upvars(self, def_id, substs)
+ -> Option<Vec<ty::ClosureUpvar<'tcx>>> {
+ ty::ctxt::closure_upvars(self, def_id, substs)
}
}
-> Inherited<'a, 'tcx> {
// It's kind of a kludge to manufacture a fake function context
// and statement context, but we might as well do write the code only once
- let param_env = ty::empty_parameter_environment(ccx.tcx);
+ let param_env = ccx.tcx.empty_parameter_environment();
Inherited::new(ccx.tcx, param_env)
}
let fn_sig =
fn_ty.sig.subst(ccx.tcx, &inh.param_env.free_substs);
let fn_sig =
- liberate_late_bound_regions(ccx.tcx,
- region::DestructionScopeData::new(body.id),
- &fn_sig);
+ ccx.tcx.liberate_late_bound_regions(region::DestructionScopeData::new(body.id),
+ &fn_sig);
let fn_sig =
inh.normalize_associated_types_in(&inh.param_env, body.span, body.id, &fn_sig);
check_representable(tcx, span, id, "struct");
check_instantiable(tcx, span, id);
- if ty::lookup_simd(tcx, local_def(id)) {
+ if tcx.lookup_simd(local_def(id)) {
check_simd(tcx, span, id);
}
}
pub fn check_item_type<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
debug!("check_item_type(it.id={}, it.ident={})",
it.id,
- ty::item_path_str(ccx.tcx, local_def(it.id)));
+ ccx.tcx.item_path_str(local_def(it.id)));
let _indenter = indenter();
match it.node {
// Consts can play a role in type-checking, so they are included here.
ast::ItemFn(..) => {} // entirely within check_item_body
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
- match ty::impl_trait_ref(ccx.tcx, local_def(it.id)) {
+ match ccx.tcx.impl_trait_ref(local_def(it.id)) {
Some(impl_trait_ref) => {
check_impl_items_against_trait(ccx,
it.span,
check_struct(ccx, it.id, it.span);
}
ast::ItemTy(ref t, ref generics) => {
- let pty_ty = ty::node_id_to_type(ccx.tcx, it.id);
+ let pty_ty = ccx.tcx.node_id_to_type(it.id);
check_bounds_are_used(ccx, t.span, &generics.ty_params, pty_ty);
}
ast::ItemForeignMod(ref m) => {
}
} else {
for item in &m.items {
- let pty = ty::lookup_item_type(ccx.tcx, local_def(item.id));
+ let pty = ccx.tcx.lookup_item_type(local_def(item.id));
if !pty.generics.types.is_empty() {
span_err!(ccx.tcx.sess, item.span, E0044,
"foreign items may not have type parameters");
pub fn check_item_body<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>, it: &'tcx ast::Item) {
debug!("check_item_body(it.id={}, it.ident={})",
it.id,
- ty::item_path_str(ccx.tcx, local_def(it.id)));
+ ccx.tcx.item_path_str(local_def(it.id)));
let _indenter = indenter();
match it.node {
ast::ItemFn(ref decl, _, _, _, _, ref body) => {
- let fn_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+ let fn_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
let param_env = ParameterEnvironment::for_item(ccx.tcx, it.id);
check_bare_fn(ccx, &**decl, &**body, it.id, it.span, fn_pty.ty, param_env);
}
ast::ItemImpl(_, _, _, _, _, ref impl_items) => {
debug!("ItemImpl {} with id {}", token::get_ident(it.ident), it.id);
- let impl_pty = ty::lookup_item_type(ccx.tcx, ast_util::local_def(it.id));
+ let impl_pty = ccx.tcx.lookup_item_type(ast_util::local_def(it.id));
for impl_item in impl_items {
match impl_item.node {
}
}
ast::ItemTrait(_, _, _, ref trait_items) => {
- let trait_def = ty::lookup_trait_def(ccx.tcx, local_def(it.id));
+ let trait_def = ccx.tcx.lookup_trait_def(local_def(it.id));
for trait_item in trait_items {
match trait_item.node {
ast::ConstTraitItem(_, Some(ref expr)) => {
item_generics, id);
let param_env = ParameterEnvironment::for_item(ccx.tcx, id);
- let fty = ty::node_id_to_type(ccx.tcx, id);
+ let fty = ccx.tcx.node_id_to_type(id);
debug!("check_method_body: fty={:?}", fty);
check_bare_fn(ccx, &sig.decl, body, id, span, fty, param_env);
impl_items: &[P<ast::ImplItem>]) {
// Locate trait methods
let tcx = ccx.tcx;
- let trait_items = ty::trait_items(tcx, impl_trait_ref.def_id);
+ let trait_items = tcx.trait_items(impl_trait_ref.def_id);
// Check existing impl methods to see if they are both present in trait
// and compatible with trait signature
match impl_item.node {
ast::ConstImplItem(..) => {
let impl_const_def_id = local_def(impl_item.id);
- let impl_const_ty = ty::impl_or_trait_item(ccx.tcx,
- impl_const_def_id);
+ let impl_const_ty = ccx.tcx.impl_or_trait_item(impl_const_def_id);
// Find associated const definition.
let opt_associated_const =
check_trait_fn_not_const(ccx, impl_item.span, sig.constness);
let impl_method_def_id = local_def(impl_item.id);
- let impl_item_ty = ty::impl_or_trait_item(ccx.tcx,
- impl_method_def_id);
+ let impl_item_ty = ccx.tcx.impl_or_trait_item(impl_method_def_id);
// If this is an impl of a trait method, find the
// corresponding method definition in the trait.
}
ast::TypeImplItem(_) => {
let typedef_def_id = local_def(impl_item.id);
- let typedef_ty = ty::impl_or_trait_item(ccx.tcx,
- typedef_def_id);
+ let typedef_ty = ccx.tcx.impl_or_trait_item(typedef_def_id);
// If this is an impl of an associated type, find the
// corresponding type definition in the trait.
}
// Check for missing items from trait
- let provided_methods = ty::provided_trait_methods(tcx, impl_trait_ref.def_id);
- let associated_consts = ty::associated_consts(tcx, impl_trait_ref.def_id);
+ let provided_methods = tcx.provided_trait_methods(impl_trait_ref.def_id);
+ let associated_consts = tcx.associated_consts(impl_trait_ref.def_id);
let mut missing_items = Vec::new();
for trait_item in trait_items.iter() {
match *trait_item {
fn get_item_type_scheme(&self, _: Span, id: ast::DefId)
-> Result<ty::TypeScheme<'tcx>, ErrorReported>
{
- Ok(ty::lookup_item_type(self.tcx(), id))
+ Ok(self.tcx().lookup_item_type(id))
}
fn get_trait_def(&self, _: Span, id: ast::DefId)
-> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
{
- Ok(ty::lookup_trait_def(self.tcx(), id))
+ Ok(self.tcx().lookup_trait_def(id))
}
fn ensure_super_predicates(&self, _: Span, _: ast::DefId) -> Result<(), ErrorReported> {
assoc_name: ast::Name)
-> bool
{
- let trait_def = ty::lookup_trait_def(self.ccx.tcx, trait_def_id);
+ let trait_def = self.ccx.tcx.lookup_trait_def(trait_def_id);
trait_def.associated_type_names.contains(&assoc_name)
}
-> TypeAndSubsts<'tcx>
{
let type_scheme =
- ty::lookup_item_type(self.tcx(), def_id);
+ self.tcx().lookup_item_type(def_id);
let type_predicates =
- ty::lookup_predicates(self.tcx(), def_id);
+ self.tcx().lookup_predicates(def_id);
let substs =
self.infcx().fresh_substs_for_generics(
span,
let tcx = self.tcx();
let ty::TypeScheme { generics, ty: decl_ty } =
- ty::lookup_item_type(tcx, did);
+ tcx.lookup_item_type(did);
let substs = astconv::ast_path_substs_for_ty(self, self,
path.span,
let raw_ty = self.expr_ty(expr);
let raw_ty = self.infcx().shallow_resolve(raw_ty);
let resolve_ty = |ty: Ty<'tcx>| self.infcx().resolve_type_vars_if_possible(&ty);
- ty::adjust_ty(self.tcx(),
- expr.span,
- expr.id,
- raw_ty,
- adjustment,
- |method_call| self.inh.method_map.borrow()
- .get(&method_call)
- .map(|method| resolve_ty(method.ty)))
+ raw_ty.adjust(self.tcx(), expr.span, expr.id, adjustment, |method_call| {
+ self.inh.method_map.borrow().get(&method_call)
+ .map(|method| resolve_ty(method.ty))
+ })
}
pub fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx> {
-> Option<Ty<'tcx>>
{
let o_field = items.iter().find(|f| f.name == fieldname);
- o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs))
+ o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
.map(|t| self.normalize_associated_types_in(span, &t))
}
-> Option<Ty<'tcx>>
{
let o_field = if idx < items.len() { Some(&items[idx]) } else { None };
- o_field.map(|f| ty::lookup_field_type(self.tcx(), class_id, f.id, substs))
+ o_field.map(|f| self.tcx().lookup_field_type(class_id, f.id, substs))
.map(|t| self.normalize_associated_types_in(span, &t))
}
// extract method method return type, which will be &T;
// all LB regions should have been instantiated during method lookup
let ret_ty = method.ty.fn_ret();
- let ret_ty = ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap();
+ let ret_ty = fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap();
if let Some(method_call) = method_call {
fcx.inh.method_map.borrow_mut().insert(method_call, method);
-> TypeAndSubsts<'tcx> {
let tcx = fcx.tcx();
- let ity = ty::lookup_item_type(tcx, did);
+ let ity = tcx.lookup_item_type(did);
let (n_tps, rps, raw_ty) =
(ity.generics.types.len(subst::TypeSpace),
ity.generics.regions.get_slice(subst::TypeSpace),
match base_t.sty {
ty::TyStruct(base_id, substs) => {
debug!("struct named {:?}", base_t);
- let fields = ty::lookup_struct_fields(tcx, base_id);
+ let fields = tcx.lookup_struct_fields(base_id);
fcx.lookup_field_ty(expr.span, base_id, &fields[..],
field.node.name, &(*substs))
}
let name = &ident;
// only find fits with at least one matching letter
let mut best_dist = name.len();
- let fields = ty::lookup_struct_fields(tcx, id);
+ let fields = tcx.lookup_struct_fields(id);
let mut best = None;
for elem in &fields {
let n = elem.name.as_str();
|base_t, _| {
match base_t.sty {
ty::TyStruct(base_id, substs) => {
- tuple_like = ty::is_tuple_struct(tcx, base_id);
+ tuple_like = tcx.is_tuple_struct(base_id);
if tuple_like {
debug!("tuple struct named {:?}", base_t);
- let fields = ty::lookup_struct_fields(tcx, base_id);
+ let fields = tcx.lookup_struct_fields(base_id);
fcx.lookup_tup_field_ty(expr.span, base_id, &fields[..],
idx.node, &(*substs))
} else {
field.ident.span,
|actual| match enum_id_opt {
Some(enum_id) => {
- let variant_type = ty::enum_variant_with_id(tcx,
- enum_id,
+ let variant_type = tcx.enum_variant_with_id(enum_id,
class_id);
format!("struct variant `{}::{}` has no field named `{}`",
actual, variant_type.name.as_str(),
let skip_fields = ast_fields.iter().map(|ref x| x.ident.node.name.as_str());
let actual_id = match enum_id_opt {
Some(_) => class_id,
- None => ty::ty_to_def_id(struct_ty).unwrap()
+ None => struct_ty.ty_to_def_id().unwrap()
};
suggest_field_names(actual_id, &field.ident, tcx, skip_fields.collect());
error_happened = true;
}
Some((field_id, false)) => {
expected_field_type =
- ty::lookup_field_type(
- tcx, class_id, field_id, substitutions);
+ tcx.lookup_field_type(class_id, field_id, substitutions);
expected_field_type =
fcx.normalize_associated_types_in(
field.span, &expected_field_type);
} = fcx.instantiate_type(span, class_id);
// Look up and check the fields.
- let class_fields = ty::lookup_struct_fields(tcx, class_id);
+ let class_fields = tcx.lookup_struct_fields(class_id);
check_struct_or_variant_fields(fcx,
struct_type,
span,
} = fcx.instantiate_type(span, enum_id);
// Look up and check the enum variant fields.
- let variant_fields = ty::lookup_struct_fields(tcx, variant_id);
+ let variant_fields = tcx.lookup_struct_fields(variant_id);
check_struct_or_variant_fields(fcx,
enum_type,
span,
let hint = expected.only_has_type(fcx).map_or(NoExpectation, |ty| {
match ty.sty {
ty::TyRef(_, ref mt) | ty::TyRawPtr(ref mt) => {
- if ty::expr_is_lval(fcx.tcx(), &**oprnd) {
+ if fcx.tcx().expr_is_lval(&**oprnd) {
// Lvalues may legitimately have unsized types.
// For example, dereferences of a fat pointer and
// the last field of a struct can be unsized.
check_expr_with_lvalue_pref(fcx, &**lhs, PreferMutLvalue);
let tcx = fcx.tcx();
- if !ty::expr_is_lval(tcx, &**lhs) {
+ if !tcx.expr_is_lval(&**lhs) {
span_err!(tcx.sess, expr.span, E0070,
"illegal left-hand side expression");
}
}
ast::ExprRepeat(ref element, ref count_expr) => {
check_expr_has_type(fcx, &**count_expr, tcx.types.usize);
- let count = ty::eval_repeat_count(fcx.tcx(), &**count_expr);
+ let count = fcx.tcx().eval_repeat_count(&**count_expr);
let uty = match expected {
ExpectHasType(uty) => {
},
def => {
// Verify that this was actually a struct.
- let typ = ty::lookup_item_type(fcx.ccx.tcx, def.def_id());
+ let typ = fcx.ccx.tcx.lookup_item_type(def.def_id());
match typ.ty.sty {
ty::TyStruct(struct_did, _) => {
check_struct_constructor(fcx,
.ty_to_string(
actual_structure_type),
type_error);
- ty::note_and_explain_type_err(tcx, &type_error, path.span);
+ tcx.note_and_explain_type_err(&type_error, path.span);
}
}
}
};
if let Some(did) = did {
- let predicates = ty::lookup_predicates(tcx, did);
+ let predicates = tcx.lookup_predicates(did);
let substs = Substs::new_type(vec![idx_type], vec![]);
let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
fcx.add_obligations_for_parameters(
e: &'tcx ast::Expr,
id: ast::NodeId) {
let inh = static_inherited_fields(ccx);
- let rty = ty::node_id_to_type(ccx.tcx, id);
+ let rty = ccx.tcx.node_id_to_type(id);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), e.id);
let declty = fcx.ccx.tcx.tcache.borrow().get(&local_def(id)).unwrap().ty;
check_const_with_ty(&fcx, sp, e, declty);
sp: Span,
item_id: ast::NodeId,
designation: &str) -> bool {
- let rty = ty::node_id_to_type(tcx, item_id);
+ let rty = tcx.node_id_to_type(item_id);
// Check that it is possible to represent this type. This call identifies
// (1) types that contain themselves and (2) types that contain a different
// recursive type. It is only necessary to throw an error on those that
// contain themselves. For case 2, there must be an inner type that will be
// caught by case 1.
- match ty::is_type_representable(tcx, sp, rty) {
+ match rty.is_representable(tcx, sp) {
ty::SelfRecursive => {
span_err!(tcx.sess, sp, E0072,
"illegal recursive {} type; \
sp: Span,
item_id: ast::NodeId)
-> bool {
- let item_ty = ty::node_id_to_type(tcx, item_id);
- if !ty::is_instantiable(tcx, item_ty) {
+ let item_ty = tcx.node_id_to_type(item_id);
+ if !item_ty.is_instantiable(tcx) {
span_err!(tcx.sess, sp, E0073,
"this type cannot be instantiated without an \
instance of itself");
}
pub fn check_simd(tcx: &ty::ctxt, sp: Span, id: ast::NodeId) {
- let t = ty::node_id_to_type(tcx, id);
+ let t = tcx.node_id_to_type(id);
if t.needs_subst() {
span_err!(tcx.sess, sp, E0074, "SIMD vector cannot be generic");
return;
}
match t.sty {
ty::TyStruct(did, substs) => {
- let fields = ty::lookup_struct_fields(tcx, did);
+ let fields = tcx.lookup_struct_fields(did);
if fields.is_empty() {
span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty");
return;
}
- let e = ty::lookup_field_type(tcx, did, fields[0].id, substs);
+ let e = tcx.lookup_field_type(did, fields[0].id, substs);
if !fields.iter().all(
- |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
+ |f| tcx.lookup_field_type(did, f.id, substs) == e) {
span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous");
return;
}
hint: attr::ReprAttr) {
#![allow(trivial_numeric_casts)]
- let rty = ty::node_id_to_type(ccx.tcx, id);
+ let rty = ccx.tcx.node_id_to_type(id);
let mut disr_vals: Vec<ty::Disr> = Vec::new();
let inh = static_inherited_fields(ccx);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(rty), id);
- let (_, repr_type_ty) = ty::enum_repr_type(ccx.tcx, Some(&hint));
+ let (_, repr_type_ty) = ccx.tcx.enum_repr_type(Some(&hint));
for v in vs {
if let Some(ref e) = v.node.disr_expr {
check_const_with_ty(&fcx, e.span, e, repr_type_ty);
// ty::enum_variants guards against discriminant overflows, so
// we need not check for that.
- let variants = ty::enum_variants(ccx.tcx, def_id);
+ let variants = ccx.tcx.enum_variants(def_id);
for (v, variant) in vs.iter().zip(variants.iter()) {
let current_disr_val = variant.disr_val;
}
}
- let hint = *ty::lookup_repr_hints(ccx.tcx, ast::DefId { krate: ast::LOCAL_CRATE, node: id })
+ let hint = *ccx.tcx.lookup_repr_hints(ast::DefId { krate: ast::LOCAL_CRATE, node: id })
.get(0).unwrap_or(&attr::ReprAny);
if hint != attr::ReprAny && vs.len() <= 1 {
def::DefFn(id, _) | def::DefMethod(id, _) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
- (ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id))
+ (fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
}
def::DefTrait(_) |
def::DefTy(..) |
// is inherent, there is no `Self` parameter, instead, the impl needs
// type parameters, which we can infer by unifying the provided `Self`
// with the substituted impl type.
- let impl_scheme = ty::lookup_item_type(fcx.tcx(), impl_def_id);
+ 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),
variadic: false,
}),
}));
- let i_ty = ty::lookup_item_type(ccx.tcx, local_def(it.id));
+ let i_ty = ccx.tcx.lookup_item_type(local_def(it.id));
let i_n_tps = i_ty.generics.types.len(subst::FnSpace);
if i_n_tps != n_tps {
span_err!(tcx.sess, it.span, E0094,
}
let tcx = fcx.tcx();
- if !ty::expr_is_lval(tcx, lhs_expr) {
+ if !tcx.expr_is_lval(lhs_expr) {
span_err!(tcx.sess, lhs_expr.span, E0067, "illegal left-hand side expression");
}
// extract return type for method; all late bound regions
// should have been instantiated by now
let ret_ty = method_ty.fn_ret();
- Ok(ty::no_late_bound_regions(fcx.tcx(), &ret_ty).unwrap().unwrap())
+ Ok(fcx.tcx().no_late_bound_regions(&ret_ty).unwrap().unwrap())
}
None => {
Err(())
if ty_unadjusted.references_error() {
ty_unadjusted
} else {
- let tcx = self.fcx.tcx();
- ty::adjust_ty(tcx, expr.span, expr.id, ty_unadjusted,
- self.fcx.inh.adjustments.borrow().get(&expr.id),
- |method_call| self.resolve_method_type(method_call))
+ ty_unadjusted.adjust(
+ self.fcx.tcx(), expr.span, expr.id,
+ self.fcx.inh.adjustments.borrow().get(&expr.id),
+ |method_call| self.resolve_method_type(method_call))
}
}
constrain_call(rcx, expr, Some(&**base),
None::<ast::Expr>.iter(), true);
let fn_ret = // late-bound regions in overloaded method calls are instantiated
- ty::no_late_bound_regions(rcx.tcx(), &method.ty.fn_ret()).unwrap();
+ rcx.tcx().no_late_bound_regions(&method.ty.fn_ret()).unwrap();
fn_ret.unwrap()
}
None => rcx.resolve_node_type(base.id)
// was applied on the base type, as that is always the case.
let fn_sig = method.ty.fn_sig();
let fn_sig = // late-bound regions should have been instantiated
- ty::no_late_bound_regions(rcx.tcx(), fn_sig).unwrap();
+ rcx.tcx().no_late_bound_regions(fn_sig).unwrap();
let self_ty = fn_sig.inputs[0];
let (m, r) = match self_ty.sty {
ty::TyRef(r, ref m) => (m.mutbl, r),
// is going to fail anyway, so just stop here and let typeck
// report errors later on in the writeback phase.
let ty0 = rcx.resolve_node_type(id);
- let ty = ty::adjust_ty(tcx, origin.span(), id, ty0,
- rcx.fcx.inh.adjustments.borrow().get(&id),
- |method_call| rcx.resolve_method_type(method_call));
+ let ty = ty0.adjust(tcx, origin.span(), id,
+ rcx.fcx.inh.adjustments.borrow().get(&id),
+ |method_call| rcx.resolve_method_type(method_call));
debug!("constrain_regions_in_type_of_node(\
ty={}, ty0={}, id={}, minimum_lifetime={:?})",
ty, ty0,
id, mutbl, cmt_borrowed);
let rptr_ty = rcx.resolve_node_type(id);
- if !rptr_ty.references_error() {
- let tcx = rcx.fcx.ccx.tcx;
+ if let ty::TyRef(&r, _) = rptr_ty.sty {
debug!("rptr_ty={}", rptr_ty);
- let r = ty::ty_region(tcx, span, rptr_ty);
link_region(rcx, span, &r, ty::BorrowKind::from_mutbl(mutbl),
cmt_borrowed);
}
generic);
// To start, collect bounds from user:
- let mut param_bounds =
- ty::required_region_bounds(rcx.tcx(),
- generic.to_ty(rcx.tcx()),
- param_env.caller_bounds.clone());
+ let mut param_bounds = rcx.tcx().required_region_bounds(generic.to_ty(rcx.tcx()),
+ param_env.caller_bounds.clone());
// In the case of a projection T::Foo, we may be able to extract bounds from the trait def:
match *generic {
// ```
//
// we can thus deduce that `<T as SomeTrait<'a>>::SomeType : 'a`.
- let trait_predicates = ty::lookup_predicates(tcx, projection_ty.trait_ref.def_id);
+ let trait_predicates = tcx.lookup_predicates(projection_ty.trait_ref.def_id);
let predicates = trait_predicates.predicates.as_slice().to_vec();
traits::elaborate_predicates(tcx, predicates)
.filter_map(|predicate| {
closure_def_id);
}
- ty::with_freevars(self.tcx(), expr.id, |freevars| {
+ self.tcx().with_freevars(expr.id, |freevars| {
for freevar in freevars {
let var_node_id = freevar.def.local_node_id();
let upvar_id = ty::UpvarId { var_id: var_node_id,
use middle::subst::{self, TypeSpace, FnSpace, ParamSpace, SelfSpace};
use middle::traits;
use middle::ty::{self, Ty};
-use middle::ty::liberate_late_bound_regions;
use middle::ty_fold::{TypeFolder, TypeFoldable, super_fold_ty};
use std::collections::HashSet;
let ccx = self.ccx;
debug!("check_item_well_formed(it.id={}, it.ident={})",
item.id,
- ty::item_path_str(ccx.tcx, local_def(item.id)));
+ ccx.tcx.item_path_str(local_def(item.id)));
match item.node {
/// Right now we check that every default trait implementation
self.check_impl(item);
}
ast::ItemImpl(_, ast::ImplPolarity::Negative, _, Some(_), _, _) => {
- let trait_ref = ty::impl_trait_ref(ccx.tcx,
- local_def(item.id)).unwrap();
- ty::populate_implementations_for_trait_if_necessary(ccx.tcx, trait_ref.def_id);
+ let trait_ref = ccx.tcx.impl_trait_ref(local_def(item.id)).unwrap();
+ ccx.tcx.populate_implementations_for_trait_if_necessary(trait_ref.def_id);
match ccx.tcx.lang_items.to_builtin_kind(trait_ref.def_id) {
Some(ty::BoundSend) | Some(ty::BoundSync) => {}
Some(_) | None => {
- if !ty::trait_has_default_impl(ccx.tcx, trait_ref.def_id) {
+ if !ccx.tcx.trait_has_default_impl(trait_ref.def_id) {
span_err!(ccx.tcx.sess, item.span, E0192,
"negative impls are only allowed for traits with \
default impls (e.g., `Send` and `Sync`)")
}
ast::ItemTrait(_, _, _, ref items) => {
let trait_predicates =
- ty::lookup_predicates(ccx.tcx, local_def(item.id));
+ ccx.tcx.lookup_predicates(local_def(item.id));
reject_non_type_param_bounds(ccx.tcx, item.span, &trait_predicates);
- if ty::trait_has_default_impl(ccx.tcx, local_def(item.id)) {
+ if ccx.tcx.trait_has_default_impl(local_def(item.id)) {
if !items.is_empty() {
span_err!(ccx.tcx.sess, item.span, E0380,
"traits with default impls (`e.g. unsafe impl \
{
let ccx = self.ccx;
let item_def_id = local_def(item.id);
- let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
- let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
+ let type_scheme = ccx.tcx.lookup_item_type(item_def_id);
+ let type_predicates = ccx.tcx.lookup_predicates(item_def_id);
reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
- let param_env =
- ty::construct_parameter_environment(ccx.tcx,
- item.span,
- &type_scheme.generics,
- &type_predicates,
- item.id);
+ let param_env = ccx.tcx.construct_parameter_environment(item.span,
+ &type_scheme.generics,
+ &type_predicates,
+ item.id);
let inh = Inherited::new(ccx.tcx, param_env);
let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
f(self, &fcx);
Some(&mut this.cache));
debug!("check_item_type at bounds_checker.scope: {:?}", bounds_checker.scope);
- let type_scheme = ty::lookup_item_type(fcx.tcx(), local_def(item.id));
+ let type_scheme = fcx.tcx().lookup_item_type(local_def(item.id));
let item_ty = fcx.instantiate_type_scheme(item.span,
&fcx.inh.param_env.free_substs,
&type_scheme.ty);
// Find the impl self type as seen from the "inside" --
// that is, with all type parameters converted from bound
// to free.
- let self_ty = ty::node_id_to_type(fcx.tcx(), item.id);
+ let self_ty = fcx.tcx().node_id_to_type(item.id);
let self_ty = fcx.instantiate_type_scheme(item.span,
&fcx.inh.param_env.free_substs,
&self_ty);
// Similarly, obtain an "inside" reference to the trait
// that the impl implements.
- let trait_ref = match ty::impl_trait_ref(fcx.tcx(), local_def(item.id)) {
+ let trait_ref = match fcx.tcx().impl_trait_ref(local_def(item.id)) {
None => { return; }
Some(t) => { t }
};
// Find the supertrait bounds. This will add `int:Bar`.
let poly_trait_ref = ty::Binder(trait_ref);
- let predicates = ty::lookup_super_predicates(fcx.tcx(), poly_trait_ref.def_id());
+ let predicates = fcx.tcx().lookup_super_predicates(poly_trait_ref.def_id());
let predicates = predicates.instantiate_supertrait(fcx.tcx(), &poly_trait_ref);
let predicates = {
let selcx = &mut traits::SelectionContext::new(fcx.infcx(), fcx);
ast_generics: &ast::Generics)
{
let item_def_id = local_def(item.id);
- let ty_predicates = ty::lookup_predicates(self.tcx(), item_def_id);
- let variances = ty::item_variances(self.tcx(), item_def_id);
+ let ty_predicates = self.tcx().lookup_predicates(item_def_id);
+ let variances = self.tcx().item_variances(item_def_id);
let mut constrained_parameters: HashSet<_> =
variances.types
span,
&format!("consider removing `{}` or using a marker such as `{}`",
param_name,
- ty::item_path_str(self.tcx(), def_id)));
+ self.tcx().item_path_str(def_id)));
}
None => {
// no lang items, no help!
match fk {
visit::FkFnBlock | visit::FkItemFn(..) => {}
visit::FkMethod(..) => {
- match ty::impl_or_trait_item(self.tcx(), local_def(id)) {
+ match self.tcx().impl_or_trait_item(local_def(id)) {
ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
reject_shadowing_type_parameters(self.tcx(), span, &ty_method.generics)
}
fn visit_trait_item(&mut self, trait_item: &'v ast::TraitItem) {
if let ast::MethodTraitItem(_, None) = trait_item.node {
- match ty::impl_or_trait_item(self.tcx(), local_def(trait_item.id)) {
+ match self.tcx().impl_or_trait_item(local_def(trait_item.id)) {
ty::ImplOrTraitItem::MethodTraitItem(ty_method) => {
reject_non_type_param_bounds(
self.tcx(),
/// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
/// to the point where impl `A : Trait<B>` is implemented).
pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>, span: Span) {
- let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id);
+ let trait_predicates = self.fcx.tcx().lookup_predicates(trait_ref.def_id);
let bounds = self.fcx.instantiate_bounds(span,
trait_ref.substs,
where T : TypeFoldable<'tcx>
{
self.binding_count += 1;
- let value = liberate_late_bound_regions(
- self.fcx.tcx(),
+ let value = self.fcx.tcx().liberate_late_bound_regions(
region::DestructionScopeData::new(self.scope),
binder);
debug!("BoundsChecker::fold_binder: late-bound regions replaced: {:?} at scope: {:?}",
match t.sty{
ty::TyStruct(type_id, substs) |
ty::TyEnum(type_id, substs) => {
- let type_predicates = ty::lookup_predicates(self.fcx.tcx(), type_id);
+ let type_predicates = self.fcx.tcx().lookup_predicates(type_id);
let bounds = self.fcx.instantiate_bounds(self.span, substs,
&type_predicates);
struct_def.fields
.iter()
.map(|field| {
- let field_ty = ty::node_id_to_type(fcx.tcx(), field.node.id);
+ let field_ty = fcx.tcx().node_id_to_type(field.node.id);
let field_ty = fcx.instantiate_type_scheme(field.span,
&fcx.inh.param_env.free_substs,
&field_ty);
.map(|variant| {
match variant.node.kind {
ast::TupleVariantKind(ref args) if !args.is_empty() => {
- let ctor_ty = ty::node_id_to_type(fcx.tcx(), variant.node.id);
+ let ctor_ty = fcx.tcx().node_id_to_type(variant.node.id);
// the regions in the argument types come from the
// enum def'n, and hence will all be early bound
- let arg_tys =
- ty::no_late_bound_regions(
- fcx.tcx(), &ctor_ty.fn_args()).unwrap();
+ let arg_tys = fcx.tcx().no_late_bound_regions(&ctor_ty.fn_args()).unwrap();
AdtVariant {
fields: args.iter().enumerate().map(|(index, arg)| {
let arg_ty = arg_tys[index];
debug!("Type for pattern binding {} (id {}) resolved to {:?}",
pat_to_string(p),
p.id,
- ty::node_id_to_type(self.tcx(), p.id));
+ self.tcx().node_id_to_type(p.id));
visit::walk_pat(self, p);
}
ResolvingLocal(s) => s,
ResolvingPattern(s) => s,
ResolvingUpvar(upvar_id) => {
- ty::expr_span(tcx, upvar_id.closure_expr_id)
+ tcx.expr_span(upvar_id.closure_expr_id)
}
ResolvingClosure(did) => {
if did.krate == ast::LOCAL_CRATE {
- ty::expr_span(tcx, did.node)
+ tcx.expr_span(did.node)
} else {
DUMMY_SP
}
let span = self.reason.span(self.tcx);
span_err!(self.tcx.sess, span, E0104,
"cannot resolve lifetime for captured variable `{}`: {}",
- ty::local_var_name_str(self.tcx, upvar_id.var_id).to_string(),
+ self.tcx.local_var_name_str(upvar_id.var_id).to_string(),
infer::fixup_err_to_string(e));
}
fn check_implementation(&self, item: &Item) {
let tcx = self.crate_context.tcx;
let impl_did = local_def(item.id);
- let self_type = ty::lookup_item_type(tcx, impl_did);
+ let self_type = tcx.lookup_item_type(impl_did);
// If there are no traits, then this implementation must have a
// base type.
let impl_items = self.create_impl_from_item(item);
- if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx,
- impl_did) {
+ if let Some(trait_ref) = self.crate_context.tcx.impl_trait_ref(impl_did) {
debug!("(checking implementation) adding impl for trait '{:?}', item '{}'",
trait_ref,
item.ident);
debug!("instantiate_default_methods(impl_id={:?}, trait_ref={:?})",
impl_id, trait_ref);
- let impl_type_scheme = ty::lookup_item_type(tcx, impl_id);
+ let impl_type_scheme = tcx.lookup_item_type(impl_id);
- let prov = ty::provided_trait_methods(tcx, trait_ref.def_id);
+ let prov = tcx.provided_trait_methods(trait_ref.def_id);
for trait_method in &prov {
// Synthesize an ID.
let new_id = tcx.sess.next_node_id();
fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'tcx>, impl_def_id: DefId) {
debug!("add_trait_impl: impl_trait_ref={:?} impl_def_id={:?}",
impl_trait_ref, impl_def_id);
- let trait_def = ty::lookup_trait_def(self.crate_context.tcx,
- impl_trait_ref.def_id);
+ let trait_def = self.crate_context.tcx.lookup_trait_def(impl_trait_ref.def_id);
trait_def.record_impl(self.crate_context.tcx, impl_def_id, impl_trait_ref);
}
}
}).collect();
- if let Some(trait_ref) = ty::impl_trait_ref(self.crate_context.tcx,
- local_def(item.id)) {
- self.instantiate_default_methods(local_def(item.id),
- &trait_ref,
- &mut items);
+ let def_id = local_def(item.id);
+ if let Some(trait_ref) = self.crate_context.tcx.impl_trait_ref(def_id) {
+ self.instantiate_default_methods(def_id, &trait_ref, &mut items);
}
items
let drop_trait = match tcx.lang_items.drop_trait() {
Some(id) => id, None => { return }
};
- ty::populate_implementations_for_trait_if_necessary(tcx, drop_trait);
- let drop_trait = ty::lookup_trait_def(tcx, drop_trait);
+ tcx.populate_implementations_for_trait_if_necessary(drop_trait);
+ let drop_trait = tcx.lookup_trait_def(drop_trait);
let impl_items = tcx.impl_items.borrow();
}
let method_def_id = items[0];
- let self_type = ty::lookup_item_type(tcx, impl_did);
+ let self_type = tcx.lookup_item_type(impl_did);
match self_type.ty.sty {
ty::TyEnum(type_def_id, _) |
ty::TyStruct(type_def_id, _) |
Some(id) => id,
None => return,
};
- ty::populate_implementations_for_trait_if_necessary(tcx, copy_trait);
- let copy_trait = ty::lookup_trait_def(tcx, copy_trait);
+ tcx.populate_implementations_for_trait_if_necessary(copy_trait);
+ let copy_trait = tcx.lookup_trait_def(copy_trait);
copy_trait.for_each_impl(tcx, |impl_did| {
debug!("check_implementations_of_copy: impl_did={:?}",
return
}
- let self_type = ty::lookup_item_type(tcx, impl_did);
+ let self_type = tcx.lookup_item_type(impl_did);
debug!("check_implementations_of_copy: self_type={:?} (bound)",
self_type);
debug!("check_implementations_of_copy: self_type={:?} (free)",
self_type);
- match ty::can_type_implement_copy(¶m_env, span, self_type) {
+ match param_env.can_type_implement_copy(self_type, span) {
Ok(()) => {}
Err(ty::FieldDoesNotImplementCopy(name)) => {
span_err!(tcx.sess, span, E0204,
}
};
- let trait_def = ty::lookup_trait_def(tcx, coerce_unsized_trait);
+ let trait_def = tcx.lookup_trait_def(coerce_unsized_trait);
trait_def.for_each_impl(tcx, |impl_did| {
debug!("check_implementations_of_coerce_unsized: impl_did={:?}",
return;
}
- let source = ty::lookup_item_type(tcx, impl_did).ty;
- let trait_ref = ty::impl_trait_ref(self.crate_context.tcx,
- impl_did).unwrap();
+ let source = tcx.lookup_item_type(impl_did).ty;
+ let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
let target = *trait_ref.substs.types.get(subst::TypeSpace, 0);
debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
source, target);
(&ty::TyStruct(def_id_a, substs_a), &ty::TyStruct(def_id_b, substs_b)) => {
if def_id_a != def_id_b {
- let source_path = ty::item_path_str(tcx, def_id_a);
- let target_path = ty::item_path_str(tcx, def_id_b);
+ let source_path = tcx.item_path_str(def_id_a);
+ let target_path = tcx.item_path_str(def_id_b);
span_err!(tcx.sess, span, E0377,
"the trait `CoerceUnsized` may only be implemented \
for a coercion between structures with the same \
}
let origin = infer::Misc(span);
- let fields = ty::lookup_struct_fields(tcx, def_id_a);
+ let fields = tcx.lookup_struct_fields(def_id_a);
let diff_fields = fields.iter().enumerate().filter_map(|(i, f)| {
- let ty = ty::lookup_field_type_unsubstituted(tcx, def_id_a, f.id);
+ let ty = tcx.lookup_field_type_unsubstituted(def_id_a, f.id);
let (a, b) = (ty.subst(tcx, substs_a), ty.subst(tcx, substs_b));
if infcx.sub_types(false, origin, b, a).is_ok() {
None
provided_source: Option<ast::DefId>)
-> ty::Method<'tcx>
{
- let combined_substs = ty::make_substs_for_receiver_types(tcx, trait_ref, method);
+ let combined_substs = tcx.make_substs_for_receiver_types(trait_ref, method);
debug!("subst_receiver_types_in_method_ty: combined_substs={:?}",
combined_substs);
// defined in this crate.
debug!("coherence2::orphan check: inherent impl {}",
self.tcx.map.node_to_string(item.id));
- let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
+ let self_ty = self.tcx.lookup_item_type(def_id).ty;
match self_ty.sty {
ty::TyEnum(def_id, _) |
ty::TyStruct(def_id, _) => {
// "Trait" impl
debug!("coherence2::orphan check: trait impl {}",
self.tcx.map.node_to_string(item.id));
- let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
+ let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
let trait_def_id = trait_ref.def_id;
match traits::orphan_check(self.tcx, def_id) {
Ok(()) => { }
debug!("trait_ref={:?} trait_def_id={:?} trait_has_default_impl={}",
trait_ref,
trait_def_id,
- ty::trait_has_default_impl(self.tcx, trait_def_id));
+ self.tcx.trait_has_default_impl(trait_def_id));
if
- ty::trait_has_default_impl(self.tcx, trait_def_id) &&
+ self.tcx.trait_has_default_impl(trait_def_id) &&
trait_def_id.krate != ast::LOCAL_CRATE
{
let self_ty = trait_ref.self_ty();
"cross-crate traits with a default impl, like `{}`, \
can only be implemented for a struct/enum type \
defined in the current crate",
- ty::item_path_str(self.tcx, trait_def_id)))
+ self.tcx.item_path_str(trait_def_id)))
}
}
_ => {
"cross-crate traits with a default impl, like `{}`, \
can only be implemented for a struct/enum type, \
not `{}`",
- ty::item_path_str(self.tcx, trait_def_id),
+ self.tcx.item_path_str(trait_def_id),
self_ty))
}
};
// "Trait" impl
debug!("coherence2::orphan check: default trait impl {}",
self.tcx.map.node_to_string(item.id));
- let trait_ref = ty::impl_trait_ref(self.tcx, def_id).unwrap();
+ let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
if trait_ref.def_id.krate != ast::LOCAL_CRATE {
span_err!(self.tcx.sess, item.span, E0318,
"cannot create default implementations for traits outside the \
let trait_defs: Vec<_> = self.tcx.trait_defs.borrow().values().cloned().collect();
for trait_def in trait_defs {
- ty::populate_implementations_for_trait_if_necessary(
- self.tcx,
- trait_def.trait_ref.def_id);
+ self.tcx.populate_implementations_for_trait_if_necessary(trait_def.trait_ref.def_id);
self.check_for_overlapping_impls_of_trait(trait_def);
}
}
span_err!(self.tcx.sess, self.span_of_impl(impl1), E0119,
"conflicting implementations for trait `{}`",
- ty::item_path_str(self.tcx, trait_def_id));
+ self.tcx.item_path_str(trait_def_id));
self.report_overlap_note(impl1, impl2);
}
// general orphan/coherence rules, it must always be
// in this crate.
let impl_def_id = ast_util::local_def(item.id);
- let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap();
+ let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id);
match prev_default_impl {
Some(prev_id) => {
}
ast::ItemImpl(_, _, _, Some(_), ref self_ty, _) => {
let impl_def_id = ast_util::local_def(item.id);
- let trait_ref = ty::impl_trait_ref(self.tcx, impl_def_id).unwrap();
+ let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
let trait_def_id = trait_ref.def_id;
match trait_ref.self_ty().sty {
ty::TyTrait(ref data) => {
// giving a misleading message below.
span_err!(self.tcx.sess, self_ty.span, E0372,
"the trait `{}` cannot be made into an object",
- ty::item_path_str(self.tcx, data.principal_def_id()));
+ self.tcx.item_path_str(data.principal_def_id()));
} else {
let mut supertrait_def_ids =
traits::supertrait_def_ids(self.tcx, data.principal_def_id());
"the object type `{}` automatically \
implements the trait `{}`",
trait_ref.self_ty(),
- ty::item_path_str(self.tcx, trait_def_id));
+ self.tcx.item_path_str(trait_def_id));
}
}
}
fn check_unsafety_coherence(&mut self, item: &'v ast::Item,
unsafety: ast::Unsafety,
polarity: ast::ImplPolarity) {
- match ty::impl_trait_ref(self.tcx, ast_util::local_def(item.id)) {
+ match self.tcx.impl_trait_ref(ast_util::local_def(item.id)) {
None => {
// Inherent impl.
match unsafety {
}
Some(trait_ref) => {
- let trait_def = ty::lookup_trait_def(self.tcx, trait_ref.def_id);
+ let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id);
match (trait_def.unsafety, unsafety, polarity) {
(ast::Unsafety::Unsafe,
ast::Unsafety::Unsafe, ast::ImplPolarity::Negative) => {
AstConvRequest::GetTraitDef(def_id) => {
tcx.sess.note(
&format!("the cycle begins when processing `{}`...",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::EnsureSuperPredicates(def_id) => {
tcx.sess.note(
&format!("the cycle begins when computing the supertraits of `{}`...",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
AstConvRequest::GetTraitDef(def_id) => {
tcx.sess.note(
&format!("...which then requires processing `{}`...",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::EnsureSuperPredicates(def_id) => {
tcx.sess.note(
&format!("...which then requires computing the supertraits of `{}`...",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
AstConvRequest::GetTraitDef(def_id) => {
tcx.sess.note(
&format!("...which then again requires processing `{}`, completing the cycle.",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::EnsureSuperPredicates(def_id) => {
tcx.sess.note(
&format!("...which then again requires computing the supertraits of `{}`, \
completing the cycle.",
- ty::item_path_str(tcx, def_id)));
+ tcx.item_path_str(def_id)));
}
AstConvRequest::GetTypeParameterBounds(id) => {
let def = tcx.type_parameter_def(id);
let tcx = self.tcx;
if trait_id.krate != ast::LOCAL_CRATE {
- return ty::lookup_trait_def(tcx, trait_id)
+ return tcx.lookup_trait_def(trait_id)
}
let item = match tcx.map.get(trait_id.node) {
if trait_def_id.krate == ast::LOCAL_CRATE {
trait_defines_associated_type_named(self.ccx, trait_def_id.node, assoc_name)
} else {
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_def_id);
trait_def.associated_type_names.contains(&assoc_name)
}
}
ast_trait_ref,
None);
- ty::record_trait_has_default_impl(tcx, trait_ref.def_id);
+ tcx.record_trait_has_default_impl(trait_ref.def_id);
tcx.impl_trait_refs.borrow_mut().insert(local_def(it.id), Some(trait_ref));
}
let _: Result<(), ErrorReported> = // any error is already reported, can ignore
ccx.ensure_super_predicates(it.span, local_def(it.id));
convert_trait_predicates(ccx, it);
- let trait_predicates = ty::lookup_predicates(tcx, local_def(it.id));
+ let trait_predicates = tcx.lookup_predicates(local_def(it.id));
debug!("convert: trait_bounds={:?}", trait_predicates);
_ => tcx.sess.span_bug(it.span, "trait_def_of_item invoked on non-trait"),
};
- let paren_sugar = ty::has_attr(tcx, def_id, "rustc_paren_sugar");
+ let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
ccx.tcx.sess.span_err(
it.span,
}
};
- let super_predicates = ty::lookup_super_predicates(ccx.tcx, def_id);
+ let super_predicates = ccx.tcx.lookup_super_predicates(def_id);
// `ty_generic_predicates` below will consider the bounds on the type
// parameters (including `Self`) and the explicit where-clauses,
-> ty::TypeScheme<'tcx>
{
if def_id.krate != ast::LOCAL_CRATE {
- return ty::lookup_item_type(ccx.tcx, def_id);
+ return ccx.tcx.lookup_item_type(def_id);
}
match ccx.tcx.map.find(def_id.node) {
assert!(prev_predicates.is_none());
// Debugging aid.
- if ty::has_attr(tcx, local_def(it.id), "rustc_object_lifetime_default") {
+ if tcx.has_attr(local_def(it.id), "rustc_object_lifetime_default") {
let object_lifetime_default_reprs: String =
scheme.generics.types.iter()
.map(|t| match t.object_lifetime_default {
match unbound {
Some(ref tpb) => {
// FIXME(#8559) currently requires the unbound to be built-in.
- let trait_def_id = ty::trait_ref_to_def_id(tcx, tpb);
+ let trait_def_id = tcx.trait_ref_to_def_id(tpb);
match kind_id {
Ok(kind_id) if trait_def_id != kind_id => {
tcx.sess.span_warn(span,
"default bound relaxed for a type parameter, but \
this does nothing because the given bound is not \
a default. Only `?Sized` is supported");
- ty::try_add_builtin_trait(tcx, kind_id, bounds);
+ tcx.try_add_builtin_trait(kind_id, bounds);
}
_ => {}
}
}
_ if kind_id.is_ok() => {
- ty::try_add_builtin_trait(tcx, kind_id.unwrap(), bounds);
+ tcx.try_add_builtin_trait(kind_id.unwrap(), bounds);
}
// No lang item for Sized, so we can't add it as a bound.
None => {}
let required_type_free =
liberate_early_bound_regions(
tcx, body_scope,
- &ty::liberate_late_bound_regions(
- tcx, body_scope, &ty::Binder(required_type)));
+ &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(required_type)));
// The "base type" comes from the impl. It too may have late-bound
// regions from the method.
let base_type_free =
liberate_early_bound_regions(
tcx, body_scope,
- &ty::liberate_late_bound_regions(
- tcx, body_scope, &ty::Binder(base_type)));
+ &tcx.liberate_late_bound_regions(body_scope, &ty::Binder(base_type)));
debug!("required_type={:?} required_type_free={:?} \
base_type={:?} base_type_free={:?}",
impl_def_id: ast::DefId,
impl_items: &[P<ast::ImplItem>])
{
- let impl_scheme = ty::lookup_item_type(tcx, impl_def_id);
- let impl_predicates = ty::lookup_predicates(tcx, impl_def_id);
- let impl_trait_ref = ty::impl_trait_ref(tcx, impl_def_id);
+ let impl_scheme = tcx.lookup_item_type(impl_def_id);
+ let impl_predicates = tcx.lookup_predicates(impl_def_id);
+ let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
// The trait reference is an input, so find all type parameters
// reachable from there, to start (if this is an inherent impl,
let lifetimes_in_associated_types: HashSet<_> =
impl_items.iter()
- .map(|item| ty::impl_or_trait_item(tcx, local_def(item.id)))
+ .map(|item| tcx.impl_or_trait_item(local_def(item.id)))
.filter_map(|item| match item {
ty::TypeTraitItem(ref assoc_ty) => assoc_ty.ty,
ty::ConstTraitItem(..) | ty::MethodTraitItem(..) => None
Ok(_) => true,
Err(ref terr) => {
span_err!(tcx.sess, span, E0211, "{}: {}", msg(), terr);
- ty::note_and_explain_type_err(tcx, terr, span);
+ tcx.note_and_explain_type_err(terr, span);
false
}
}
main_id: ast::NodeId,
main_span: Span) {
let tcx = ccx.tcx;
- let main_t = ty::node_id_to_type(tcx, main_id);
+ let main_t = tcx.node_id_to_type(main_id);
match main_t.sty {
ty::TyBareFn(..) => {
match tcx.map.find(main_id) {
start_id: ast::NodeId,
start_span: Span) {
let tcx = ccx.tcx;
- let start_t = ty::node_id_to_type(tcx, start_id);
+ let start_t = tcx.node_id_to_type(start_id);
match start_t.sty {
ty::TyBareFn(..) => {
match tcx.map.find(start_id) {
param_id={}, \
inf_index={:?}, \
initial_variance={:?})",
- ty::item_path_str(self.tcx, ast_util::local_def(item_id)),
+ self.tcx.item_path_str(ast_util::local_def(item_id)),
item_id, kind, space, index, param_id, inf_index,
initial_variance);
}
match item.node {
ast::ItemEnum(ref enum_definition, _) => {
- let scheme = ty::lookup_item_type(tcx, did);
+ let scheme = tcx.lookup_item_type(did);
// Not entirely obvious: constraints on structs/enums do not
// affect the variance of their type parameters. See discussion
}
ast::ItemStruct(..) => {
- let scheme = ty::lookup_item_type(tcx, did);
+ let scheme = tcx.lookup_item_type(did);
// Not entirely obvious: constraints on structs/enums do not
// affect the variance of their type parameters. See discussion
//
// self.add_constraints_from_generics(&scheme.generics);
- let struct_fields = ty::lookup_struct_fields(tcx, did);
+ let struct_fields = tcx.lookup_struct_fields(did);
for field_info in &struct_fields {
assert_eq!(field_info.id.krate, ast::LOCAL_CRATE);
- let field_ty = ty::node_id_to_type(tcx, field_info.id.node);
+ let field_ty = tcx.node_id_to_type(field_info.id.node);
self.add_constraints_from_ty(&scheme.generics, field_ty, self.covariant);
}
}
ast::ItemTrait(..) => {
- let trait_def = ty::lookup_trait_def(tcx, did);
+ let trait_def = tcx.lookup_trait_def(did);
self.add_constraints_from_trait_ref(&trait_def.generics,
trait_def.trait_ref,
self.invariant);
} else {
// Parameter on an item defined within another crate:
// variance already inferred, just look it up.
- let variances = ty::item_variances(self.tcx(), item_def_id);
+ let variances = self.tcx().item_variances(item_def_id);
let variance = match kind {
TypeParam => *variances.types.get(space, index),
RegionParam => *variances.regions.get(space, index),
trait_ref,
variance);
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
self.add_constraints_from_substs(
generics,
ty::TyEnum(def_id, substs) |
ty::TyStruct(def_id, substs) => {
- let item_type = ty::lookup_item_type(self.tcx(), def_id);
+ let item_type = self.tcx().lookup_item_type(def_id);
// All type parameters on enums and structs should be
// in the TypeSpace.
ty::TyProjection(ref data) => {
let trait_ref = &data.trait_ref;
- let trait_def = ty::lookup_trait_def(self.tcx(), trait_ref.def_id);
+ let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
self.add_constraints_from_substs(
generics,
trait_ref.def_id,
// For unit testing: check for a special "rustc_variance"
// attribute and report an error with various results if found.
- if ty::has_attr(tcx, item_def_id, "rustc_variance") {
+ if tcx.has_attr(item_def_id, "rustc_variance") {
span_err!(tcx.sess, tcx.map.span(item_id), E0208, "{:?}", item_variances);
}
pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
did: ast::DefId) -> clean::Trait {
- let def = ty::lookup_trait_def(tcx, did);
- let trait_items = ty::trait_items(tcx, did).clean(cx);
- let predicates = ty::lookup_predicates(tcx, did);
+ let def = tcx.lookup_trait_def(did);
+ let trait_items = tcx.trait_items(did).clean(cx);
+ let predicates = tcx.lookup_predicates(did);
let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
let generics = filter_non_trait_generics(did, generics);
let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
}
fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Function {
- let t = ty::lookup_item_type(tcx, did);
+ let t = tcx.lookup_item_type(did);
let (decl, style, abi) = match t.ty.sty {
ty::TyBareFn(_, ref f) => ((did, &f.sig).clean(cx), f.unsafety, f.abi),
_ => panic!("bad function"),
};
- let predicates = ty::lookup_predicates(tcx, did);
+ let predicates = tcx.lookup_predicates(did);
clean::Function {
decl: decl,
generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
use syntax::parse::token::special_idents::unnamed_field;
- let t = ty::lookup_item_type(tcx, did);
- let predicates = ty::lookup_predicates(tcx, did);
- let fields = ty::lookup_struct_fields(tcx, did);
+ let t = tcx.lookup_item_type(did);
+ let predicates = tcx.lookup_predicates(did);
+ let fields = tcx.lookup_struct_fields(did);
clean::Struct {
struct_type: match &*fields {
}
fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
- let t = ty::lookup_item_type(tcx, did);
- let predicates = ty::lookup_predicates(tcx, did);
+ let t = tcx.lookup_item_type(did);
+ let predicates = tcx.lookup_predicates(did);
match t.ty.sty {
ty::TyEnum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
return clean::EnumItem(clean::Enum {
generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
variants_stripped: false,
- variants: ty::enum_variants(tcx, edid).clean(cx),
+ variants: tcx.enum_variants(edid).clean(cx),
})
}
_ => {}
pub fn build_impls(cx: &DocContext, tcx: &ty::ctxt,
did: ast::DefId) -> Vec<clean::Item> {
- ty::populate_inherent_implementations_for_type_if_necessary(tcx, did);
+ tcx.populate_inherent_implementations_for_type_if_necessary(did);
let mut impls = Vec::new();
match tcx.inherent_impls.borrow().get(&did) {
});
}
- let predicates = ty::lookup_predicates(tcx, did);
+ let predicates = tcx.lookup_predicates(did);
let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
.iter()
.filter_map(|did| {
let did = did.def_id();
- let impl_item = ty::impl_or_trait_item(tcx, did);
+ let impl_item = tcx.impl_or_trait_item(did);
match impl_item {
ty::ConstTraitItem(ref assoc_const) => {
let did = assoc_const.def_id;
- let type_scheme = ty::lookup_item_type(tcx, did);
+ let type_scheme = tcx.lookup_item_type(did);
let default = match assoc_const.default {
Some(_) => Some(const_eval::lookup_const_by_id(tcx, did, None)
.unwrap().span.to_src(cx)),
}
}).collect::<Vec<_>>();
let polarity = csearch::get_impl_polarity(tcx, did);
- let ty = ty::lookup_item_type(tcx, did);
+ let ty = tcx.lookup_item_type(did);
let trait_ = associated_trait.clean(cx).map(|bound| {
match bound {
clean::TraitBound(polyt, _) => polyt.trait_,
debug!("got snippet {}", sn);
clean::Constant {
- type_: ty::lookup_item_type(tcx, did).ty.clean(cx),
+ type_: tcx.lookup_item_type(did).ty.clean(cx),
expr: sn
}
}
did: ast::DefId,
mutable: bool) -> clean::Static {
clean::Static {
- type_: ty::lookup_item_type(tcx, did).ty.clean(cx),
+ type_: tcx.lookup_item_type(did).ty.clean(cx),
mutability: if mutable {clean::Mutable} else {clean::Immutable},
expr: "\n\n\n".to_string(), // trigger the "[definition]" links
}
let provided = match self.container {
ty::ImplContainer(..) => false,
ty::TraitContainer(did) => {
- ty::provided_trait_methods(cx.tcx(), did).iter().any(|m| {
+ cx.tcx().provided_trait_methods(did).iter().any(|m| {
m.def_id == self.def_id
})
}
(Some(self.name), Some(attr_map.get(&self.id.node).unwrap()))
};
- let ty = ty::lookup_item_type(cx.tcx(), self.id);
+ let ty = cx.tcx().lookup_item_type(self.id);
Item {
name: name.clean(cx),
// are actually located on the trait/impl itself, so we need to load
// all of the generics from there and then look for bounds that are
// applied to this associated type in question.
- let def = ty::lookup_trait_def(cx.tcx(), did);
- let predicates = ty::lookup_predicates(cx.tcx(), did);
+ let def = cx.tcx().lookup_trait_def(did);
+ let predicates = cx.tcx().lookup_predicates(did);
let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred {
use std::collections::HashMap;
use rustc::middle::subst;
-use rustc::middle::ty;
use syntax::ast;
use clean::PathParameters as PP;
if child == trait_ {
return true
}
- let def = ty::lookup_trait_def(cx.tcx(), child);
- let predicates = ty::lookup_predicates(cx.tcx(), child);
+ let def = cx.tcx().lookup_trait_def(child);
+ let predicates = cx.tcx().lookup_predicates(child);
let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
generics.where_predicates.iter().filter_map(|pred| {
match *pred {