use metadata::tydecode::{DefIdSource, NominalType, TypeWithId, TypeParameter,
RegionParameter};
use metadata::tyencode;
-use middle::typeck::{method_origin, method_map_entry};
+use middle::typeck::method_origin;
use middle::{ty, typeck, moves};
use middle;
use util::ppaux::ty_to_str;
}
// ______________________________________________________________________
-// Encoding and decoding of method_map_entry
-
-trait read_method_map_entry_helper {
- fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
- -> method_map_entry;
-}
-
-fn encode_method_map_entry(ebml_w: &mut writer::Encoder, mme: method_map_entry) {
- ebml_w.emit_struct("method_map_entry", 3, |ebml_w| {
- ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
- mme.origin.encode(ebml_w);
- });
- })
-}
-
-impl<'a> read_method_map_entry_helper for reader::Decoder<'a> {
- fn read_method_map_entry(&mut self, xcx: @ExtendedDecodeContext)
- -> method_map_entry {
- self.read_struct("method_map_entry", 3, |this| {
- method_map_entry {
- origin: this.read_struct_field("origin", 1, |this| {
- let method_origin: method_origin =
- Decodable::decode(this);
- method_origin.tr(xcx)
- })
- }
- })
- }
-}
+// Encoding and decoding of method_origin
impl tr for method_origin {
fn tr(&self, xcx: @ExtendedDecodeContext) -> method_origin {
{
let method_map = maps.method_map.borrow();
let r = method_map.get().find(&id);
- for &mme in r.iter() {
+ for &origin in r.iter() {
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
ebml_w.id(id);
ebml_w.tag(c::tag_table_val, |ebml_w| {
- encode_method_map_entry(ebml_w, *mme)
+ origin.encode(ebml_w);
})
})
}
ty_param_defs.get().insert(id, bounds);
}
c::tag_table_method_map => {
- let entry = val_dsr.read_method_map_entry(xcx);
+ let origin: method_origin = Decodable::decode(val_dsr);
let mut method_map = dcx.maps.method_map.borrow_mut();
- method_map.get().insert(id, entry);
+ method_map.get().insert(id, origin.tr(xcx));
}
c::tag_table_vtable_map => {
let vtable_res =
span: codemap::Span) {
let method_map = self.method_map.borrow();
match method_map.get().find(id) {
- Some(&typeck::method_map_entry { origin, .. }) => {
+ Some(&origin) => {
match origin {
typeck::method_static(def_id) => {
match ty::provided_source(self.tcx, def_id) {
// Even though the callee_id may have been the id with
// node_type_substs, e.id is correct here.
- ty::method_call_type_param_defs(cx.tcx, cx.method_map, e.id).expect(
- "non path/method call expr has type substs??")
+ match cx.method_map.borrow().get().find(&e.id) {
+ Some(origin) => {
+ ty::method_call_type_param_defs(cx.tcx, *origin)
+ }
+ None => {
+ cx.tcx.sess.span_bug(e.span,
+ "non path/method call expr has type substs??");
+ }
+ }
}
};
let type_param_defs = type_param_defs.borrow();
ast::ExprMethodCall(..) => {
let method_map = cx.method_map.borrow();
match method_map.get().find(&e.id) {
- Some(&typeck::method_map_entry { origin, .. }) => {
+ Some(&origin) => {
match origin {
typeck::method_static(def_id) => {
// If this implements a trait method, get def_id
let t = ty::type_autoderef(ty::expr_ty(self.tcx, args[0]));
match ty::get(t).sty {
ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
- let method_map = self.method_map.borrow();
- let entry = match method_map.get().find(&expr.id) {
+ match self.method_map.borrow().get().find(&expr.id) {
None => {
self.tcx.sess.span_bug(expr.span,
"method call not in \
method map");
}
- Some(entry) => entry
- };
- debug!("(privacy checking) checking impl method");
- self.check_method(expr.span, &entry.origin, ident);
+ Some(origin) => {
+ debug!("(privacy checking) checking impl method");
+ self.check_method(expr.span, origin, ident);
+ }
+ }
}
_ => {}
}
ast::ExprMethodCall(..) => {
let method_map = self.method_map.borrow();
match method_map.get().find(&expr.id) {
- Some(&typeck::method_map_entry {
- origin: typeck::method_static(def_id),
- ..
- }) => {
+ Some(&typeck::method_static(def_id)) => {
if is_local(def_id) {
if ReachableContext::
def_id_represents_local_inlined_item(
Some(_) => {}
None => {
self.tcx.sess.span_bug(expr.span,
- "method call expression \
- not in method map?!")
+ "method call expression not in method map?!")
}
}
}
bcx: &'a Block<'a>,
callee_id: ast::NodeId,
this: &ast::Expr,
- mentry: typeck::method_map_entry,
+ origin: typeck::method_origin,
arg_cleanup_scope: cleanup::ScopeId)
-> Callee<'a> {
let _icx = push_ctxt("meth::trans_method_callee");
- debug!("trans_method_callee(callee_id={:?}, mentry={})",
- callee_id,
- mentry.repr(bcx.tcx()));
+ debug!("trans_method_callee(callee_id={:?}, origin={})",
+ callee_id, origin.repr(bcx.tcx()));
- match mentry.origin {
+ match origin {
typeck::method_static(did) => {
Callee {
bcx: bcx,
return node_id_has_type_params(cx, expr.id);
}
-pub fn method_call_type_param_defs(tcx: ctxt,
- method_map: typeck::method_map,
- id: ast::NodeId)
- -> Option<Rc<~[TypeParameterDef]>> {
- let method_map = method_map.borrow();
- method_map.get().find(&id).map(|method| {
- match method.origin {
- typeck::method_static(did) => {
+pub fn method_call_type_param_defs(tcx: ctxt, origin: typeck::method_origin)
+ -> Rc<~[TypeParameterDef]> {
+ match origin {
+ typeck::method_static(did) => {
// n.b.: When we encode impl methods, the bounds
// that we encode include both the impl bounds
// and then the method bounds themselves...
ty::lookup_item_type(tcx, did).generics.type_param_defs
- }
- typeck::method_param(typeck::method_param {
- trait_id: trt_id,
- method_num: n_mth, ..}) |
- typeck::method_object(typeck::method_object {
- trait_id: trt_id,
- method_num: n_mth, ..}) => {
+ }
+ typeck::method_param(typeck::method_param {
+ trait_id: trt_id,
+ method_num: n_mth, ..}) |
+ typeck::method_object(typeck::method_object {
+ trait_id: trt_id,
+ method_num: n_mth, ..}) => {
// ...trait methods bounds, in contrast, include only the
// method bounds, so we must preprend the tps from the
// trait itself. This ought to be harmonized.
ty::trait_method(tcx,
trt_id,
n_mth).generics.type_param_defs()))
- }
}
- })
+ }
}
pub fn resolve_expr(tcx: ctxt, expr: &ast::Expr) -> ast::Def {
// Requires that the two types unify, and prints an error message if they
// don't.
-pub fn suptype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
+pub fn suptype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
suptype_with_fn(fcx, sp, false, expected, actual,
|sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
}
-pub fn subtype(fcx: @FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
+pub fn subtype(fcx: &FnCtxt, sp: Span, expected: ty::t, actual: ty::t) {
suptype_with_fn(fcx, sp, true, actual, expected,
|sp, a, e, s| { fcx.report_mismatched_types(sp, e, a, s) })
}
-pub fn suptype_with_fn(fcx: @FnCtxt,
+pub fn suptype_with_fn(fcx: &FnCtxt,
sp: Span,
b_is_expected: bool,
ty_a: ty::t,
use middle::typeck::check::vtable;
use middle::typeck::check;
use middle::typeck::infer;
-use middle::typeck::{method_map_entry, method_origin, method_param};
+use middle::typeck::{method_origin, method_param};
use middle::typeck::{method_static, method_object};
use middle::typeck::{param_numbered, param_self, param_index};
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
deref_args: check::DerefArgs, // Whether we autopointer first.
check_traits: CheckTraitsFlag, // Whether we check traits only.
autoderef_receiver: AutoderefReceiverFlag)
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
let impl_dups = @RefCell::new(HashSet::new());
let lcx = LookupContext {
fcx: fcx,
}
impl<'a> LookupContext<'a> {
- fn search(&self, self_ty: ty::t) -> Option<method_map_entry> {
+ fn search(&self, self_ty: ty::t) -> Option<method_origin> {
let mut self_ty = self_ty;
let mut autoderefs = 0;
loop {
fn search_for_autoderefd_method(&self,
self_ty: ty::t,
autoderefs: uint)
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
let (self_ty, autoadjust) =
self.consider_reborrow(self_ty, autoderefs);
match self.search_for_method(self_ty) {
}
fn search_for_autosliced_method(&self,
- self_ty: ty::t,
- autoderefs: uint)
- -> Option<method_map_entry> {
+ self_ty: ty::t,
+ autoderefs: uint)
+ -> Option<method_origin> {
/*!
*
* Searches for a candidate by converting things like
}
fn search_for_autoptrd_method(&self, self_ty: ty::t, autoderefs: uint)
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
/*!
*
* Converts any type `T` to `&M T` where `M` is an
autoderefs: uint,
mutbls: &[ast::Mutability],
mk_autoref_ty: |ast::Mutability, ty::Region| -> ty::t)
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
// This is hokey. We should have mutability inference as a
// variable. But for now, try &const, then &, then &mut:
let region =
}
fn search_for_method(&self, rcvr_ty: ty::t)
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
debug!("search_for_method(rcvr_ty={})", self.ty_to_str(rcvr_ty));
let _indenter = indenter();
fn consider_candidates(&self,
rcvr_ty: ty::t,
candidates: &mut ~[Candidate])
- -> Option<method_map_entry> {
+ -> Option<method_origin> {
// FIXME(pcwalton): Do we need to clone here?
let relevant_candidates: ~[Candidate] =
candidates.iter().map(|c| (*c).clone()).
}
fn confirm_candidate(&self, rcvr_ty: ty::t, candidate: &Candidate)
- -> method_map_entry {
+ -> method_origin {
// This method performs two sets of substitutions, one after the other:
// 1. Substitute values for any type/lifetime parameters from the impl and
// method declaration into the method type. This is the function type
self.fcx.write_ty(self.callee_id, fty);
self.fcx.write_substs(self.callee_id, all_substs);
- method_map_entry {
- origin: candidate.origin
- }
+ candidate.origin
}
fn construct_transformed_self_ty_for_object(
ast_trait_ref,
impl_trait_ref,
*ms);
- vtable::resolve_impl(ccx, it, &impl_tpt.generics,
- impl_trait_ref);
+ vtable::resolve_impl(ccx.tcx, it, &impl_tpt.generics, impl_trait_ref);
}
None => { }
}
// Resolves `typ` by a single level if `typ` is a type variable. If no
// resolution is possible, then an error is reported.
-pub fn structurally_resolved_type(fcx: @FnCtxt, sp: Span, tp: ty::t)
- -> ty::t {
+pub fn structurally_resolved_type(fcx: &FnCtxt, sp: Span, tp: ty::t) -> ty::t {
match infer::resolve_type(fcx.infcx(), tp, force_tvar) {
Ok(t_s) if !ty::type_is_ty_var(t_s) => t_s,
_ => {
use middle::typeck::infer::fixup_err_to_str;
use middle::typeck::infer::{resolve_and_force_all_but_regions, resolve_type};
use middle::typeck::infer;
-use middle::typeck::{CrateCtxt, vtable_origin, vtable_res, vtable_param_res};
+use middle::typeck::{vtable_origin, vtable_res, vtable_param_res};
use middle::typeck::{vtable_static, vtable_param, impl_res};
use middle::typeck::{param_numbered, param_self, param_index};
use middle::subst::Subst;
relate_trait_refs(vcx, location_info, impl_trait_ref, trait_ref);
}
-fn insert_vtables(fcx: @FnCtxt,
- callee_id: ast::NodeId,
- vtables: vtable_res) {
+fn insert_vtables(fcx: &FnCtxt, callee_id: ast::NodeId, vtables: vtable_res) {
debug!("insert_vtables(callee_id={}, vtables={:?})",
callee_id, vtables.repr(fcx.tcx()));
let mut vtable_map = fcx.inh.vtable_map.borrow_mut();
}
}
-pub fn early_resolve_expr(ex: &ast::Expr, fcx: @FnCtxt, is_early: bool) {
+pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
debug!("vtable: early_resolve_expr() ex with id {:?} (early: {}): {}",
ex.id, is_early, expr_to_str(ex));
let _indent = indenter();
ast::ExprAssignOp(callee_id, _, _, _) |
ast::ExprIndex(callee_id, _, _) |
ast::ExprMethodCall(callee_id, _, _, _) => {
- match ty::method_call_type_param_defs(cx.tcx, fcx.inh.method_map, ex.id) {
- Some(type_param_defs) => {
+ match fcx.inh.method_map.borrow().get().find(&ex.id) {
+ Some(origin) => {
debug!("vtable resolution on parameter bounds for method call {}",
ex.repr(fcx.tcx()));
+ let type_param_defs = ty::method_call_type_param_defs(cx.tcx, *origin);
if has_trait_bounds(*type_param_defs.borrow()) {
let substs = fcx.node_ty_substs(callee_id);
let vcx = fcx.vtable_context();
}
}
}
- None => ()
+ None => {}
}
}
ast::ExprCast(src, _) => {
}
}
-fn resolve_expr(fcx: @FnCtxt, ex: &ast::Expr) {
- let mut fcx = fcx;
- early_resolve_expr(ex, fcx, false);
- visit::walk_expr(&mut fcx, ex, ());
-}
-
-pub fn resolve_impl(ccx: @CrateCtxt,
+pub fn resolve_impl(tcx: ty::ctxt,
impl_item: &ast::Item,
impl_generics: &ty::Generics,
impl_trait_ref: &ty::TraitRef) {
let param_env = ty::construct_parameter_environment(
- ccx.tcx,
+ tcx,
None,
impl_generics.type_param_defs(),
[],
impl_generics.region_param_defs(),
impl_item.id);
- let impl_trait_ref = @impl_trait_ref.subst(ccx.tcx, ¶m_env.free_substs);
+ let impl_trait_ref = @impl_trait_ref.subst(tcx, ¶m_env.free_substs);
- let infcx = &infer::new_infer_ctxt(ccx.tcx);
+ let infcx = &infer::new_infer_ctxt(tcx);
let vcx = VtableContext { infcx: infcx, param_env: ¶m_env };
let loc_info = location_info_for_item(impl_item);
// First, check that the impl implements any trait bounds
// on the trait.
- let trait_def = ty::lookup_trait_def(ccx.tcx, impl_trait_ref.def_id);
+ let trait_def = ty::lookup_trait_def(tcx, impl_trait_ref.def_id);
let vtbls = lookup_vtables(&vcx,
&loc_info,
trait_def.generics.type_param_defs(),
builtin_bounds: ty::EmptyBuiltinBounds(),
trait_bounds: ~[impl_trait_ref]
};
- let t = ty::node_id_to_type(ccx.tcx, impl_item.id);
- let t = t.subst(ccx.tcx, ¶m_env.free_substs);
+ let t = ty::node_id_to_type(tcx, impl_item.id);
+ let t = t.subst(tcx, ¶m_env.free_substs);
debug!("=== Doing a self lookup now.");
// Right now, we don't have any place to store this.
};
let impl_def_id = ast_util::local_def(impl_item.id);
- let mut impl_vtables = ccx.tcx.impl_vtables.borrow_mut();
+ let mut impl_vtables = tcx.impl_vtables.borrow_mut();
impl_vtables.get().insert(impl_def_id, res);
}
-impl visit::Visitor<()> for @FnCtxt {
+impl<'a> visit::Visitor<()> for &'a FnCtxt {
fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
- resolve_expr(*self, ex);
+ early_resolve_expr(ex, *self, false);
+ visit::walk_expr(self, ex, ());
}
fn visit_item(&mut self, _: &ast::Item, _: ()) {
// no-op
// Detect points where a trait-bounded type parameter is
// instantiated, resolve the impls for the parameters.
-pub fn resolve_in_block(mut fcx: @FnCtxt, bl: &ast::Block) {
+pub fn resolve_in_block(mut fcx: &FnCtxt, bl: &ast::Block) {
visit::walk_block(&mut fcx, bl, ());
}
real_index: uint,
}
-
-#[deriving(Clone)]
-pub struct method_map_entry {
- // method details being invoked
- origin: method_origin,
-}
-
// maps from an expression id that corresponds to a method call to the details
// of the method to be invoked
-pub type method_map = @RefCell<HashMap<ast::NodeId, method_map_entry>>;
+pub type method_map = @RefCell<HashMap<ast::NodeId, method_origin>>;
pub type vtable_param_res = @~[vtable_origin];
// Resolutions for bounds of all parameters, left to right, for a given path.
}
}
-impl Repr for typeck::method_map_entry {
- fn repr(&self, tcx: ctxt) -> ~str {
- format!("method_map_entry \\{origin: {}\\}", self.origin.repr(tcx))
- }
-}
-
impl Repr for typeck::method_origin {
fn repr(&self, tcx: ctxt) -> ~str {
match self {