Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

librustc: Fix explicit self for objects in more cases #4155

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/librustc/middle/trans/deriving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use middle::trans::common::{fn_ctxt};
use middle::trans::expr::SaveIn;
use middle::trans::type_of::type_of;
use middle::ty::{DerivedFieldInfo, re_static};
use middle::typeck::check::method::TransformTypeNormally;
use middle::typeck::check::method;
use middle::typeck::method_static;
use syntax::ast;
Expand Down Expand Up @@ -99,7 +100,8 @@ pub fn trans_deriving_impl(ccx: @crate_ctxt,
ccx.tcx,
Some(re_static),
self_ty.ty,
derived_method_info.method_info.self_type);
derived_method_info.method_info.self_type,
TransformTypeNormally);

match ty::get(self_ty.ty).sty {
ty::ty_class(*) => {
Expand Down
10 changes: 9 additions & 1 deletion src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,16 @@ fn trans_trait_callee(bcx: block,

let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
let mut bcx = bcx;
let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr));
let self_datum = unpack_datum!(bcx,
expr::trans_to_datum(bcx, self_expr));
let llpair = self_datum.to_ref_llval(bcx);

let llpair = match explicit_self {
ast::sty_region(_) => Load(bcx, llpair),
ast::sty_static | ast::sty_by_ref | ast::sty_value |
ast::sty_box(_) | ast::sty_uniq(_) => llpair
};

let callee_ty = node_id_type(bcx, callee_id);
trans_trait_callee_from_llval(bcx,
callee_ty,
Expand Down
87 changes: 41 additions & 46 deletions src/librustc/middle/typeck/check/method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ struct Candidate {
}

/**
* Whether the self type should be transformed according to the form of
* explicit self provided by the method.
* How the self type should be transformed according to the form of explicit
* self provided by the method.
*/
enum TransformTypeFlag {
DontTransformType,
TransformType
TransformTypeNormally,
TransformTypeForObject,
}

impl LookupContext {
Expand Down Expand Up @@ -325,7 +325,8 @@ impl LookupContext {
}
}

fn push_inherent_candidates_from_param(&self, rcvr_ty: ty::t,
fn push_inherent_candidates_from_param(&self,
rcvr_ty: ty::t,
param_ty: param_ty) {
debug!("push_inherent_candidates_from_param(param_ty=%?)",
param_ty);
Expand Down Expand Up @@ -424,7 +425,7 @@ impl LookupContext {
method.self_ty,
rcvr_ty,
move init_substs,
TransformType);
TransformTypeNormally);

let cand = Candidate {
rcvr_ty: rcvr_ty,
Expand Down Expand Up @@ -486,7 +487,7 @@ impl LookupContext {
self.create_rcvr_ty_and_substs_for_method(method.self_ty,
self_ty,
move rcvr_substs,
DontTransformType);
TransformTypeForObject);

self.inherent_candidates.push(Candidate {
rcvr_ty: rcvr_ty,
Expand Down Expand Up @@ -517,7 +518,7 @@ impl LookupContext {
method.self_ty,
self_ty,
move rcvr_substs,
TransformType);
TransformTypeNormally);

self.inherent_candidates.push(Candidate {
rcvr_ty: rcvr_ty,
Expand Down Expand Up @@ -572,7 +573,7 @@ impl LookupContext {
method.self_type,
impl_ty,
move impl_substs,
TransformType);
TransformTypeNormally);

candidates.push(Candidate {
rcvr_ty: impl_ty,
Expand Down Expand Up @@ -608,7 +609,7 @@ impl LookupContext {
provided_method_info.method_info.self_type,
self_ty,
dummy_substs,
TransformType);
TransformTypeNormally);

candidates.push(Candidate {
rcvr_ty: impl_ty,
Expand Down Expand Up @@ -656,18 +657,11 @@ impl LookupContext {
}
};

let rcvr_ty;
match transform_type {
TransformType => {
rcvr_ty = transform_self_type_for_method(self.tcx(),
rcvr_substs.self_r,
self_ty,
self_decl);
}
DontTransformType => {
rcvr_ty = self_ty;
}
}
let rcvr_ty = transform_self_type_for_method(self.tcx(),
rcvr_substs.self_r,
self_ty,
self_decl,
transform_type);

(rcvr_ty, rcvr_substs)
}
Expand All @@ -684,6 +678,10 @@ impl LookupContext {
match self.search_for_method(self_ty) {
None => None,
Some(move mme) => {
debug!("(searching for autoderef'd method) writing \
adjustment (%u) to %d",
autoderefs,
self.self_expr.id);
self.fcx.write_autoderef_adjustment(
self.self_expr.id, autoderefs);
Some(mme)
Expand Down Expand Up @@ -812,25 +810,12 @@ impl LookupContext {
match self.search_for_method(autoref_ty) {
None => {}
Some(move mme) => {
match mme.origin {
method_trait(*) => {
// Do not write adjustments; they make no sense
// here since the adjustments are to be performed
// on the self element of the object pair/triple,
// not the object itself.
//
// FIXME (#4088): This is wrong in the presence
// of autoderef.
}
_ => {
self.fcx.write_adjustment(
self.self_expr.id,
@{autoderefs: autoderefs,
autoref: Some({kind: kind,
region: region,
mutbl: *mutbl})});
}
}
self.fcx.write_adjustment(
self.self_expr.id,
@{autoderefs: autoderefs,
autoref: Some({kind: kind,
region: region,
mutbl: *mutbl})});
return Some(mme);
}
}
Expand Down Expand Up @@ -1160,9 +1145,9 @@ impl LookupContext {
fn transform_self_type_for_method(tcx: ty::ctxt,
self_region: Option<ty::Region>,
impl_ty: ty::t,
self_type: ast::self_ty_)
-> ty::t
{
self_type: ast::self_ty_,
flag: TransformTypeFlag)
-> ty::t {
match self_type {
sty_static => {
tcx.sess.bug(~"calling transform_self_type_for_method on \
Expand All @@ -1177,10 +1162,20 @@ fn transform_self_type_for_method(tcx: ty::ctxt,
{ ty: impl_ty, mutbl: mutability })
}
sty_box(mutability) => {
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
match flag {
TransformTypeNormally => {
mk_box(tcx, { ty: impl_ty, mutbl: mutability })
}
TransformTypeForObject => impl_ty
}
}
sty_uniq(mutability) => {
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
match flag {
TransformTypeNormally => {
mk_uniq(tcx, { ty: impl_ty, mutbl: mutability })
}
TransformTypeForObject => impl_ty
}
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ type parameter).

use astconv::{ast_conv, ast_path_to_ty, ast_ty_to_ty};
use astconv::{ast_region_to_region};
use method::TransformTypeNormally;
use middle::ty::{TyVid, vid, FnTyBase, FnMeta, FnSig, VariantInfo_};
use regionmanip::{replace_bound_regions_in_fn_ty};
use rscope::{anon_rscope, binding_rscope, empty_rscope, in_anon_rscope};
Expand Down Expand Up @@ -302,8 +303,11 @@ fn check_fn(ccx: @crate_ctxt,
} else {
let self_region = fcx.in_scope_regions.find(ty::br_self);
let ty = method::transform_self_type_for_method(
fcx.tcx(), self_region,
self_info.self_ty, self_info.explicit_self.node);
fcx.tcx(),
self_region,
self_info.self_ty,
self_info.explicit_self.node,
TransformTypeNormally);
Some({self_ty: ty,.. *self_info})
}
};
Expand Down
7 changes: 6 additions & 1 deletion src/librustc/middle/typeck/deriving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use middle::ty::{ty_class, ty_enum, ty_param_bounds_and_ty};
use /*middle::typeck::*/check::method;
use /*middle::typeck::*/check::vtable;
use /*middle::typeck::*/infer::infer_ctxt;
use /*middle::typeck::*/method::TransformTypeNormally;
use /*middle::typeck::*/vtable::{LocationInfo, VtableContext};
use util::ppaux;

Expand Down Expand Up @@ -70,7 +71,11 @@ impl DerivingChecker {
let inference_context = infer::new_infer_ctxt(self.crate_context.tcx);
let region = inference_context.next_region_var_nb(span);
let transformed_type = method::transform_self_type_for_method(
tcx, Some(region), impl_self_tpbt.ty, method_info.self_type);
tcx,
Some(region),
impl_self_tpbt.ty,
method_info.self_type,
TransformTypeNormally);

let substs = {
self_r: None,
Expand Down
39 changes: 39 additions & 0 deletions src/test/run-pass/explicit-self-objects-ext-1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.

/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}

pub trait ReaderUtil {

/// Read len bytes into a new vec.
fn read_bytes(&self, len: uint);
}

impl<T: Reader> T : ReaderUtil {

fn read_bytes(&self, len: uint) {
let count = self.read(&[mut 0], len);
}

}

struct S {
x: int,
y: int
}

impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}

fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}
39 changes: 39 additions & 0 deletions src/test/run-pass/explicit-self-objects-ext-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.

/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}

pub trait ReaderUtil {

/// Read len bytes into a new vec.
fn read_bytes(&self, len: uint);
}

impl<T: Reader> T : ReaderUtil {

fn read_bytes(&self, len: uint) {
let count = self.read(&[mut 0], len);
}

}

struct S {
x: int,
y: int
}

impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}

fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}
39 changes: 39 additions & 0 deletions src/test/run-pass/explicit-self-objects-ext-3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub trait Reader {
// FIXME (#2004): Seekable really should be orthogonal.

/// Read up to len bytes (or EOF) and put them into bytes (which
/// must be at least len bytes long). Return number of bytes read.
// FIXME (#2982): This should probably return an error.
fn read(&self, bytes: &[mut u8], len: uint) -> uint;
}

pub trait ReaderUtil {

/// Read len bytes into a new vec.
fn read_bytes(len: uint);
}

impl<T: Reader> T : ReaderUtil {

fn read_bytes(len: uint) {
let count = self.read(&[mut 0], len);
}

}

struct S {
x: int,
y: int
}

impl S: Reader {
fn read(&self, bytes: &[mut u8], len: uint) -> uint {
0
}
}

fn main() {
let x = S { x: 1, y: 2 };
let x = x as @Reader;
x.read_bytes(0);
}
Loading