librustc: Remove overloaded operator autoderef.

This commit is contained in:
Patrick Walton 2013-03-12 15:06:57 -07:00
parent b1c699815d
commit b85158e23a
4 changed files with 63 additions and 29 deletions

View file

@ -312,7 +312,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
let lname = link_name(ccx, foreign_item); let lname = link_name(ccx, foreign_item);
let llbasefn = base_fn(ccx, *lname, tys, cc); let llbasefn = base_fn(ccx, *lname, tys, cc);
// Name the shim function // Name the shim function
let shim_name = lname + ~"__c_stack_shim"; let shim_name = *lname + ~"__c_stack_shim";
return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc, return build_shim_fn_(ccx, shim_name, llbasefn, tys, cc,
build_args, build_ret); build_args, build_ret);
} }

View file

@ -111,20 +111,26 @@ pub enum CheckTraitsFlag {
CheckTraitsAndInherentMethods, CheckTraitsAndInherentMethods,
} }
#[deriving_eq]
pub enum AutoderefReceiverFlag {
AutoderefReceiver,
DontAutoderefReceiver,
}
pub fn lookup( pub fn lookup(
fcx: @mut FnCtxt, fcx: @mut FnCtxt,
// In a call `a.b::<X, Y, ...>(...)`: // In a call `a.b::<X, Y, ...>(...)`:
expr: @ast::expr, // The expression `a.b`. expr: @ast::expr, // The expression `a.b`.
self_expr: @ast::expr, // The expression `a`. self_expr: @ast::expr, // The expression `a`.
callee_id: node_id, // Where to store the type of `a.b` callee_id: node_id, // Where to store `a.b`'s type
m_name: ast::ident, // The ident `b`. m_name: ast::ident, // The ident `b`.
self_ty: ty::t, // The type of `a`. self_ty: ty::t, // The type of `a`.
supplied_tps: &[ty::t], // The list of types X, Y, ... . supplied_tps: &[ty::t], // The list of types X, Y, ... .
deref_args: check::DerefArgs, // Whether we autopointer first. deref_args: check::DerefArgs, // Whether we autopointer first.
check_traits: CheckTraitsFlag) // Whether we check traits only. check_traits: CheckTraitsFlag, // Whether we check traits only.
-> Option<method_map_entry> autoderef_receiver: AutoderefReceiverFlag)
{ -> Option<method_map_entry> {
let lcx = LookupContext { let lcx = LookupContext {
fcx: fcx, fcx: fcx,
expr: expr, expr: expr,
@ -137,6 +143,7 @@ pub fn lookup(
extension_candidates: @mut ~[], extension_candidates: @mut ~[],
deref_args: deref_args, deref_args: deref_args,
check_traits: check_traits, check_traits: check_traits,
autoderef_receiver: autoderef_receiver,
}; };
let mme = lcx.do_lookup(self_ty); let mme = lcx.do_lookup(self_ty);
debug!("method lookup for %s yielded %?", debug!("method lookup for %s yielded %?",
@ -156,6 +163,7 @@ pub struct LookupContext {
extension_candidates: @mut ~[Candidate], extension_candidates: @mut ~[Candidate],
deref_args: check::DerefArgs, deref_args: check::DerefArgs,
check_traits: CheckTraitsFlag, check_traits: CheckTraitsFlag,
autoderef_receiver: AutoderefReceiverFlag,
} }
/** /**
@ -232,6 +240,12 @@ pub impl LookupContext/&self {
} }
} }
// Don't autoderef if we aren't supposed to.
if self.autoderef_receiver == DontAutoderefReceiver {
break;
}
// Otherwise, perform autoderef.
match self.deref(self_ty, &mut enum_dids) { match self.deref(self_ty, &mut enum_dids) {
None => { break; } None => { break; }
Some(ty) => { Some(ty) => {

View file

@ -89,8 +89,11 @@ use middle::typeck::astconv::{AstConv, ast_path_to_ty};
use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty};
use middle::typeck::astconv; use middle::typeck::astconv;
use middle::typeck::check::_match::pat_ctxt; use middle::typeck::check::_match::pat_ctxt;
use middle::typeck::check::method::{AutoderefReceiver};
use middle::typeck::check::method::{AutoderefReceiverFlag};
use middle::typeck::check::method::{CheckTraitsAndInherentMethods}; use middle::typeck::check::method::{CheckTraitsAndInherentMethods};
use middle::typeck::check::method::{CheckTraitsOnly, TransformTypeNormally}; use middle::typeck::check::method::{CheckTraitsOnly, DontAutoderefReceiver};
use middle::typeck::check::method::{TransformTypeNormally};
use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig; use middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig;
use middle::typeck::check::vtable::{LocationInfo, VtableContext}; use middle::typeck::check::vtable::{LocationInfo, VtableContext};
use middle::typeck::CrateCtxt; use middle::typeck::CrateCtxt;
@ -1373,7 +1376,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
expr_t, expr_t,
tps, tps,
DontDerefArgs, DontDerefArgs,
CheckTraitsAndInherentMethods) { CheckTraitsAndInherentMethods,
AutoderefReceiver) {
Some(ref entry) => { Some(ref entry) => {
let method_map = fcx.ccx.method_map; let method_map = fcx.ccx.method_map;
method_map.insert(expr.id, (*entry)); method_map.insert(expr.id, (*entry));
@ -1453,7 +1457,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
self_t: ty::t, self_t: ty::t,
opname: ast::ident, opname: ast::ident,
+args: ~[@ast::expr], +args: ~[@ast::expr],
+deref_args: DerefArgs) +deref_args: DerefArgs,
+autoderef_receiver: AutoderefReceiverFlag)
-> Option<(ty::t, bool)> { -> Option<(ty::t, bool)> {
match method::lookup(fcx, match method::lookup(fcx,
op_ex, op_ex,
@ -1463,7 +1468,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
self_t, self_t,
~[], ~[],
deref_args, deref_args,
CheckTraitsOnly) { CheckTraitsOnly,
autoderef_receiver) {
Some(ref origin) => { Some(ref origin) => {
let method_ty = fcx.node_ty(op_ex.callee_id); let method_ty = fcx.node_ty(op_ex.callee_id);
let method_map = fcx.ccx.method_map; let method_map = fcx.ccx.method_map;
@ -1548,9 +1554,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
let tcx = fcx.ccx.tcx; let tcx = fcx.ccx.tcx;
match ast_util::binop_to_method_name(op) { match ast_util::binop_to_method_name(op) {
Some(ref name) => { Some(ref name) => {
match lookup_op_method(fcx, ex, lhs_expr, lhs_resolved_t, match lookup_op_method(fcx,
ex,
lhs_expr,
lhs_resolved_t,
fcx.tcx().sess.ident_of(copy *name), fcx.tcx().sess.ident_of(copy *name),
~[rhs], DoDerefArgs) { ~[rhs],
DoDerefArgs,
DontAutoderefReceiver) {
Some(pair) => return pair, Some(pair) => return pair,
_ => () _ => ()
} }
@ -1588,11 +1599,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
rhs_expr: @ast::expr, rhs_expr: @ast::expr,
rhs_t: ty::t) rhs_t: ty::t)
-> ty::t { -> ty::t {
match lookup_op_method( match lookup_op_method(fcx,
fcx, ex, rhs_expr, rhs_t, ex,
fcx.tcx().sess.ident_of(/*bad*/ copy mname), ~[], rhs_expr,
DontDerefArgs) rhs_t,
{ fcx.tcx().sess.ident_of(/*bad*/ copy mname),
~[],
DontDerefArgs,
DontAutoderefReceiver) {
Some((ret_ty, _)) => ret_ty, Some((ret_ty, _)) => ret_ty,
_ => { _ => {
fcx.type_error_message(ex.span, |actual| { fcx.type_error_message(ex.span, |actual| {
@ -1740,7 +1754,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
expr_t, expr_t,
tps, tps,
DontDerefArgs, DontDerefArgs,
CheckTraitsAndInherentMethods) { CheckTraitsAndInherentMethods,
AutoderefReceiver) {
Some(ref entry) => { Some(ref entry) => {
let method_map = fcx.ccx.method_map; let method_map = fcx.ccx.method_map;
method_map.insert(expr.id, (*entry)); method_map.insert(expr.id, (*entry));
@ -2569,9 +2584,14 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
None => { None => {
let resolved = structurally_resolved_type(fcx, expr.span, let resolved = structurally_resolved_type(fcx, expr.span,
raw_base_t); raw_base_t);
match lookup_op_method(fcx, expr, base, resolved, match lookup_op_method(fcx,
expr,
base,
resolved,
tcx.sess.ident_of(~"index"), tcx.sess.ident_of(~"index"),
~[idx], DontDerefArgs) { ~[idx],
DontDerefArgs,
AutoderefReceiver) {
Some((ret_ty, _)) => fcx.write_ty(id, ret_ty), Some((ret_ty, _)) => fcx.write_ty(id, ret_ty),
_ => { _ => {
fcx.type_error_message(expr.span, |actual| fcx.type_error_message(expr.span, |actual|

View file

@ -3407,7 +3407,7 @@ pub impl Parser {
let prefix = Path(self.sess.cm.span_to_filename(*self.span)); let prefix = Path(self.sess.cm.span_to_filename(*self.span));
let prefix = prefix.dir_path(); let prefix = prefix.dir_path();
let mod_path = Path(".").push_many(*self.mod_path_stack); let mod_path = Path(".").push_many(*self.mod_path_stack);
let default_path = self.sess.interner.get(id) + ~".rs"; let default_path = *self.sess.interner.get(id) + ~".rs";
let file_path = match ::attr::first_attr_value_str_by_name( let file_path = match ::attr::first_attr_value_str_by_name(
outer_attrs, ~"path") { outer_attrs, ~"path") {
Some(d) => { Some(d) => {