Skip to content

Commit

Permalink
Issue #5656: Make &self not mean "&'self self"
Browse files Browse the repository at this point in the history
Fixes #5656.
Fixes #5541.
  • Loading branch information
nikomatsakis committed Apr 11, 2013
1 parent 3322595 commit 49de82c
Show file tree
Hide file tree
Showing 16 changed files with 336 additions and 295 deletions.
2 changes: 1 addition & 1 deletion src/librustc/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use middle::liveness;
use middle::pat_util;
use middle::ty;
use middle::typeck;
use util::ppaux::{Repr, ty_to_str, tys_to_str};
use util::ppaux::{Repr, ty_to_str};

use syntax::ast::*;
use syntax::attr::attrs_contains_name;
Expand Down
29 changes: 7 additions & 22 deletions src/librustc/middle/region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,10 +544,6 @@ pub struct DetermineRpCtxt {
// see long discussion on region_is_relevant().
anon_implies_rp: bool,

// true when we are not within an &self method.
// see long discussion on region_is_relevant().
self_implies_rp: bool,

// encodes the context of the current type; invariant if
// mutable, covariant otherwise
ambient_variance: region_variance,
Expand Down Expand Up @@ -689,7 +685,7 @@ pub impl DetermineRpCtxt {
false
}
Some(ref l) if l.ident == special_idents::self_ => {
self.self_implies_rp
true
}
Some(_) => {
false
Expand All @@ -700,23 +696,18 @@ pub impl DetermineRpCtxt {
fn with(@mut self,
item_id: ast::node_id,
anon_implies_rp: bool,
self_implies_rp: bool,
f: &fn()) {
let old_item_id = self.item_id;
let old_anon_implies_rp = self.anon_implies_rp;
let old_self_implies_rp = self.self_implies_rp;
self.item_id = item_id;
self.anon_implies_rp = anon_implies_rp;
self.self_implies_rp = self_implies_rp;
debug!("with_item_id(%d, %b, %b)",
debug!("with_item_id(%d, %b)",
item_id,
anon_implies_rp,
self_implies_rp);
anon_implies_rp);
let _i = ::util::common::indenter();
f();
self.item_id = old_item_id;
self.anon_implies_rp = old_anon_implies_rp;
self.self_implies_rp = old_self_implies_rp;
}

fn with_ambient_variance(@mut self, variance: region_variance, f: &fn()) {
Expand All @@ -730,7 +721,7 @@ pub impl DetermineRpCtxt {
pub fn determine_rp_in_item(item: @ast::item,
&&cx: @mut DetermineRpCtxt,
visitor: visit::vt<@mut DetermineRpCtxt>) {
do cx.with(item.id, true, true) {
do cx.with(item.id, true) {
visit::visit_item(item, cx, visitor);
}
}
Expand All @@ -742,12 +733,7 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind,
_: ast::node_id,
&&cx: @mut DetermineRpCtxt,
visitor: visit::vt<@mut DetermineRpCtxt>) {
let self_implies_rp = match fk {
&visit::fk_method(_, _, m) => !m.self_ty.node.is_borrowed(),
_ => true
};

do cx.with(cx.item_id, false, self_implies_rp) {
do cx.with(cx.item_id, false) {
do cx.with_ambient_variance(rv_contravariant) {
for decl.inputs.each |a| {
(visitor.visit_ty)(a.ty, cx, visitor);
Expand All @@ -763,7 +749,7 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind,
pub fn determine_rp_in_ty_method(ty_m: &ast::ty_method,
&&cx: @mut DetermineRpCtxt,
visitor: visit::vt<@mut DetermineRpCtxt>) {
do cx.with(cx.item_id, false, !ty_m.self_ty.node.is_borrowed()) {
do cx.with(cx.item_id, false) {
visit::visit_ty_method(ty_m, cx, visitor);
}
}
Expand Down Expand Up @@ -868,7 +854,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => {
// fn() binds the & region, so do not consider &T types that
// appear *inside* a fn() type to affect the enclosing item:
do cx.with(cx.item_id, false, true) {
do cx.with(cx.item_id, false) {
// parameters are contravariant
do cx.with_ambient_variance(rv_contravariant) {
for decl.inputs.each |a| {
Expand Down Expand Up @@ -929,7 +915,6 @@ pub fn determine_rp_in_crate(sess: Session,
worklist: ~[],
item_id: 0,
anon_implies_rp: false,
self_implies_rp: true,
ambient_variance: rv_covariant
};

Expand Down
47 changes: 30 additions & 17 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,7 @@ impl EffectfulSubst for ty::t {
_ => {
ty::fold_regions_and_ty(
tcx, *self,
|r| match r {
ty::re_bound(ty::br_self) => {
match substs.self_r {
None => {
tcx.sess.bug(
fmt!("ty::subst: \
Reference to self region when \
given substs with no self region, \
ty = %s",
self.repr(tcx)));
}
Some(self_r) => self_r
}
}
_ => r
},
|r| r.subst(tcx, substs),
|t| t.effectfulSubst(tcx, substs),
|t| t.effectfulSubst(tcx, substs))
}
Expand Down Expand Up @@ -118,7 +103,7 @@ impl Subst for ty::TraitRef {
impl Subst for ty::substs {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::substs {
ty::substs {
self_r: self.self_r,
self_r: self.self_r.subst(tcx, substs),
self_ty: self.self_ty.map(|typ| typ.subst(tcx, substs)),
tps: self.tps.map(|typ| typ.subst(tcx, substs))
}
Expand Down Expand Up @@ -166,6 +151,34 @@ impl Subst for ty::Generics {
}
}

impl Subst for ty::Region {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::Region {
// Note: This routine only handles the self region, because it
// is only concerned with substitutions of regions that appear
// in types. Region substitution of the bound regions that
// appear in a function signature is done using the
// specialized routine
// `middle::typeck::check::regionmanip::replace_bound_regions_in_fn_sig()`.
// As we transition to the new region syntax this distinction
// will most likely disappear.
match self {
&ty::re_bound(ty::br_self) => {
match substs.self_r {
None => {
tcx.sess.bug(
fmt!("ty::Region#subst(): \
Reference to self region when \
given substs with no self region: %s",
substs.repr(tcx)));
}
Some(self_r) => self_r
}
}
_ => *self
}
}
}

impl Subst for ty::ty_param_bounds_and_ty {
fn subst(&self, tcx: ty::ctxt, substs: &ty::substs) -> ty::ty_param_bounds_and_ty {
ty::ty_param_bounds_and_ty {
Expand Down
3 changes: 1 addition & 2 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ use middle::subst::Subst;
use middle::typeck;
use middle;
use util::ppaux::{note_and_explain_region, bound_region_to_str};
use util::ppaux::{region_to_str, vstore_to_str};
use util::ppaux::{trait_store_to_str, ty_to_str, tys_to_str};
use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str};
use util::ppaux::Repr;
use util::common::{indenter};

Expand Down
Loading

0 comments on commit 49de82c

Please sign in to comment.