Skip to content

Commit cbfd88a

Browse files
committedMar 5, 2013
Update region inference for traits so that a method with
explicit self doesn't incorrectly cause the entire trait to be tagged as being region-parameterized. Fixes #5224.
1 parent 65986ba commit cbfd88a

File tree

13 files changed

+263
-189
lines changed

13 files changed

+263
-189
lines changed
 

‎src/librustc/middle/check_const.rs

-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use middle::ty;
1616
use middle::typeck;
1717
use util::ppaux;
1818

19-
use core::option;
2019
use syntax::ast::*;
2120
use syntax::codemap;
2221
use syntax::{visit, ast_util, ast_map};

‎src/librustc/middle/check_match.rs

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use middle::typeck::method_map;
1919
use middle::moves;
2020
use util::ppaux::ty_to_str;
2121

22-
use core::option;
2322
use core::uint;
2423
use core::vec;
2524
use std::sort;

‎src/librustc/middle/kind.rs

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use middle::ty;
1818
use middle::typeck;
1919
use util::ppaux::{ty_to_str, tys_to_str};
2020

21-
use core::option;
2221
use core::str;
2322
use core::vec;
2423
use std::oldmap::HashMap;

‎src/librustc/middle/region.rs

+50-29
Original file line numberDiff line numberDiff line change
@@ -416,9 +416,13 @@ pub struct DetermineRpCtxt {
416416
item_id: ast::node_id,
417417

418418
// true when we are within an item but not within a method.
419-
// see long discussion on region_is_relevant()
419+
// see long discussion on region_is_relevant().
420420
anon_implies_rp: bool,
421421

422+
// true when we are not within an &self method.
423+
// see long discussion on region_is_relevant().
424+
self_implies_rp: bool,
425+
422426
// encodes the context of the current type; invariant if
423427
// mutable, covariant otherwise
424428
ambient_variance: region_variance,
@@ -458,14 +462,14 @@ pub fn add_variance(+ambient_variance: region_variance,
458462
}
459463

460464
pub impl DetermineRpCtxt {
461-
fn add_variance(@mut self, variance: region_variance) -> region_variance {
465+
fn add_variance(&self, variance: region_variance) -> region_variance {
462466
add_variance(self.ambient_variance, variance)
463467
}
464468

465469
/// Records that item `id` is region-parameterized with the
466470
/// variance `variance`. If `id` was already parameterized, then
467471
/// the new variance is joined with the old variance.
468-
fn add_rp(@mut self, id: ast::node_id, variance: region_variance) {
472+
fn add_rp(&mut self, id: ast::node_id, variance: region_variance) {
469473
assert id != 0;
470474
let old_variance = self.region_paramd_items.find(&id);
471475
let joined_variance = match old_variance {
@@ -490,7 +494,7 @@ pub impl DetermineRpCtxt {
490494
/// `from`. Put another way, it indicates that the current item
491495
/// contains a value of type `from`, so if `from` is
492496
/// region-parameterized, so is the current item.
493-
fn add_dep(@mut self, from: ast::node_id) {
497+
fn add_dep(&mut self, from: ast::node_id) {
494498
debug!("add dependency from %d -> %d (%s -> %s) with variance %?",
495499
from, self.item_id,
496500
ast_map::node_id_to_str(self.ast_map, from,
@@ -515,42 +519,46 @@ pub impl DetermineRpCtxt {
515519
}
516520

517521
// Determines whether a reference to a region that appears in the
518-
// AST implies that the enclosing type is region-parameterized.
519-
//
520-
// This point is subtle. Here are four examples to make it more
522+
// AST implies that the enclosing type is region-parameterized (RP).
523+
// This point is subtle. Here are some examples to make it more
521524
// concrete.
522525
//
523526
// 1. impl foo for &int { ... }
524527
// 2. impl foo for &self/int { ... }
525-
// 3. impl foo for bar { fn m() -> &self/int { ... } }
526-
// 4. impl foo for bar { fn m() -> &int { ... } }
528+
// 3. impl foo for bar { fn m(@self) -> &self/int { ... } }
529+
// 4. impl foo for bar { fn m(&self) -> &self/int { ... } }
530+
// 5. impl foo for bar { fn m(&self) -> &int { ... } }
527531
//
528532
// In case 1, the anonymous region is being referenced,
529533
// but it appears in a context where the anonymous region
530-
// resolves to self, so the impl foo is region-parameterized.
534+
// resolves to self, so the impl foo is RP.
531535
//
532536
// In case 2, the self parameter is written explicitly.
533537
//
534-
// In case 3, the method refers to self, so that implies that the
535-
// impl must be region parameterized. (If the type bar is not
536-
// region parameterized, that is an error, because the self region
537-
// is effectively unconstrained, but that is detected elsewhere).
538+
// In case 3, the method refers to the region `self`, so that
539+
// implies that the impl must be region parameterized. (If the
540+
// type bar is not region parameterized, that is an error, because
541+
// the self region is effectively unconstrained, but that is
542+
// detected elsewhere).
543+
//
544+
// In case 4, the method refers to the region `self`, but the
545+
// `self` region is bound by the `&self` receiver, and so this
546+
// does not require that `bar` be RP.
538547
//
539-
// In case 4, the anonymous region is referenced, but it
548+
// In case 5, the anonymous region is referenced, but it
540549
// bound by the method, so it does not refer to self. This impl
541550
// need not be region parameterized.
542551
//
543-
// So the rules basically are: the `self` region always implies
544-
// that the enclosing type is region parameterized. The anonymous
545-
// region also does, unless it appears within a method, in which
546-
// case it is bound. We handle this by setting a flag
547-
// (anon_implies_rp) to true when we enter an item and setting
548-
// that flag to false when we enter a method.
549-
fn region_is_relevant(@mut self, r: @ast::region) -> bool {
552+
// Normally, & or &self implies that the enclosing item is RP.
553+
// However, within a function, & is always bound. Within a method
554+
// with &self type, &self is also bound. We detect those last two
555+
// cases via flags (anon_implies_rp and self_implies_rp) that are
556+
// true when the anon or self region implies RP.
557+
fn region_is_relevant(&self, r: @ast::region) -> bool {
550558
match r.node {
551559
ast::re_static => false,
552560
ast::re_anon => self.anon_implies_rp,
553-
ast::re_self => true,
561+
ast::re_self => self.self_implies_rp,
554562
ast::re_named(_) => false
555563
}
556564
}
@@ -561,7 +569,7 @@ pub impl DetermineRpCtxt {
561569
//
562570
// If the region is explicitly specified, then we follows the
563571
// normal rules.
564-
fn opt_region_is_relevant(@mut self,
572+
fn opt_region_is_relevant(&self,
565573
opt_r: Option<@ast::region>)
566574
-> bool {
567575
debug!("opt_region_is_relevant: %? (anon_implies_rp=%b)",
@@ -575,16 +583,23 @@ pub impl DetermineRpCtxt {
575583
fn with(@mut self,
576584
item_id: ast::node_id,
577585
anon_implies_rp: bool,
586+
self_implies_rp: bool,
578587
f: &fn()) {
579588
let old_item_id = self.item_id;
580589
let old_anon_implies_rp = self.anon_implies_rp;
590+
let old_self_implies_rp = self.self_implies_rp;
581591
self.item_id = item_id;
582592
self.anon_implies_rp = anon_implies_rp;
583-
debug!("with_item_id(%d, %b)", item_id, anon_implies_rp);
593+
self.self_implies_rp = self_implies_rp;
594+
debug!("with_item_id(%d, %b, %b)",
595+
item_id,
596+
anon_implies_rp,
597+
self_implies_rp);
584598
let _i = ::util::common::indenter();
585599
f();
586600
self.item_id = old_item_id;
587601
self.anon_implies_rp = old_anon_implies_rp;
602+
self.self_implies_rp = old_self_implies_rp;
588603
}
589604

590605
fn with_ambient_variance(@mut self, variance: region_variance, f: &fn()) {
@@ -598,7 +613,7 @@ pub impl DetermineRpCtxt {
598613
pub fn determine_rp_in_item(item: @ast::item,
599614
&&cx: @mut DetermineRpCtxt,
600615
visitor: visit::vt<@mut DetermineRpCtxt>) {
601-
do cx.with(item.id, true) {
616+
do cx.with(item.id, true, true) {
602617
visit::visit_item(item, cx, visitor);
603618
}
604619
}
@@ -610,7 +625,12 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind,
610625
_: ast::node_id,
611626
&&cx: @mut DetermineRpCtxt,
612627
visitor: visit::vt<@mut DetermineRpCtxt>) {
613-
do cx.with(cx.item_id, false) {
628+
let self_implies_rp = match fk {
629+
&visit::fk_method(_, _, m) => !m.self_ty.node.is_borrowed(),
630+
_ => true
631+
};
632+
633+
do cx.with(cx.item_id, false, self_implies_rp) {
614634
do cx.with_ambient_variance(rv_contravariant) {
615635
for decl.inputs.each |a| {
616636
(visitor.visit_ty)(a.ty, cx, visitor);
@@ -626,7 +646,7 @@ pub fn determine_rp_in_fn(fk: &visit::fn_kind,
626646
pub fn determine_rp_in_ty_method(ty_m: &ast::ty_method,
627647
&&cx: @mut DetermineRpCtxt,
628648
visitor: visit::vt<@mut DetermineRpCtxt>) {
629-
do cx.with(cx.item_id, false) {
649+
do cx.with(cx.item_id, false, !ty_m.self_ty.node.is_borrowed()) {
630650
visit::visit_ty_method(ty_m, cx, visitor);
631651
}
632652
}
@@ -735,7 +755,7 @@ pub fn determine_rp_in_ty(ty: @ast::Ty,
735755
ast::ty_bare_fn(@ast::TyBareFn {decl: ref decl, _}) => {
736756
// fn() binds the & region, so do not consider &T types that
737757
// appear *inside* a fn() type to affect the enclosing item:
738-
do cx.with(cx.item_id, false) {
758+
do cx.with(cx.item_id, false, true) {
739759
// parameters are contravariant
740760
do cx.with_ambient_variance(rv_contravariant) {
741761
for decl.inputs.each |a| {
@@ -796,6 +816,7 @@ pub fn determine_rp_in_crate(sess: Session,
796816
worklist: ~[],
797817
item_id: 0,
798818
anon_implies_rp: false,
819+
self_implies_rp: true,
799820
ambient_variance: rv_covariant
800821
};
801822

‎src/librustc/middle/trans/base.rs

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ use core::hash;
6969
use core::int;
7070
use core::io;
7171
use core::libc::{c_uint, c_ulonglong};
72-
use core::option;
7372
use core::uint;
7473
use std::oldmap::HashMap;
7574
use std::{oldmap, time, list};

‎src/librustc/middle/typeck/astconv.rs

+27-27
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,11 @@ use syntax::print::pprust::path_to_str;
6969
use util::common::indenter;
7070

7171
pub trait AstConv {
72-
fn tcx(@mut self) -> ty::ctxt;
73-
fn ccx(@mut self) -> @mut CrateCtxt;
74-
fn get_item_ty(@mut self, id: ast::def_id) -> ty::ty_param_bounds_and_ty;
72+
fn tcx(&self) -> ty::ctxt;
73+
fn get_item_ty(&self, id: ast::def_id) -> ty::ty_param_bounds_and_ty;
7574

7675
// what type should we use when a type is omitted?
77-
fn ty_infer(@mut self, span: span) -> ty::t;
76+
fn ty_infer(&self, span: span) -> ty::t;
7877
}
7978

8079
pub fn get_region_reporting_err(tcx: ty::ctxt,
@@ -92,8 +91,8 @@ pub fn get_region_reporting_err(tcx: ty::ctxt,
9291
}
9392

9493
pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + Durable>(
95-
self: @mut AC,
96-
rscope: RS,
94+
self: &AC,
95+
rscope: &RS,
9796
span: span,
9897
a_r: @ast::region)
9998
-> ty::Region {
@@ -108,8 +107,8 @@ pub fn ast_region_to_region<AC:AstConv,RS:region_scope + Copy + Durable>(
108107
}
109108

110109
pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
111-
self: @mut AC,
112-
rscope: RS,
110+
self: &AC,
111+
rscope: &RS,
113112
did: ast::def_id,
114113
path: @ast::path)
115114
-> ty_param_substs_and_ty {
@@ -164,8 +163,8 @@ pub fn ast_path_to_substs_and_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
164163
}
165164

166165
pub fn ast_path_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
167-
self: @mut AC,
168-
rscope: RS,
166+
self: &AC,
167+
rscope: &RS,
169168
did: ast::def_id,
170169
path: @ast::path,
171170
path_id: ast::node_id)
@@ -189,11 +188,11 @@ pub const NO_TPS: uint = 2;
189188
// Parses the programmer's textual representation of a type into our
190189
// internal notion of a type. `getter` is a function that returns the type
191190
// corresponding to a definition ID:
192-
pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
193-
self: @mut AC, rscope: RS, &&ast_ty: @ast::Ty) -> ty::t {
191+
pub fn ast_ty_to_ty<AC:AstConv, RS:region_scope + Copy + Durable>(
192+
self: &AC, rscope: &RS, &&ast_ty: @ast::Ty) -> ty::t {
194193

195-
fn ast_mt_to_mt<AC:AstConv,RS:region_scope + Copy + Durable>(
196-
self: @mut AC, rscope: RS, mt: ast::mt) -> ty::mt {
194+
fn ast_mt_to_mt<AC:AstConv, RS:region_scope + Copy + Durable>(
195+
self: &AC, rscope: &RS, mt: ast::mt) -> ty::mt {
197196

198197
ty::mt {ty: ast_ty_to_ty(self, rscope, mt.ty), mutbl: mt.mutbl}
199198
}
@@ -202,8 +201,8 @@ pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
202201
// If a_seq_ty is a str or a vec, make it an estr/evec.
203202
// Also handle function sigils and first-class trait types.
204203
fn mk_pointer<AC:AstConv,RS:region_scope + Copy + Durable>(
205-
self: @mut AC,
206-
rscope: RS,
204+
self: &AC,
205+
rscope: &RS,
207206
a_seq_ty: ast::mt,
208207
vst: ty::vstore,
209208
constr: fn(ty::mt) -> ty::t) -> ty::t
@@ -316,7 +315,8 @@ pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
316315
}
317316
ast::ty_rptr(region, mt) => {
318317
let r = ast_region_to_region(self, rscope, ast_ty.span, region);
319-
mk_pointer(self, in_anon_rscope(rscope, r), mt, ty::vstore_slice(r),
318+
let anon_rscope = in_anon_rscope(rscope, r);
319+
mk_pointer(self, &anon_rscope, mt, ty::vstore_slice(r),
320320
|tmt| ty::mk_rptr(tcx, r, tmt))
321321
}
322322
ast::ty_tup(fields) => {
@@ -419,8 +419,8 @@ pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
419419
}
420420

421421
pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
422-
self: @mut AC,
423-
rscope: RS,
422+
self: &AC,
423+
rscope: &RS,
424424
a: ast::arg,
425425
expected_ty: Option<ty::arg>)
426426
-> ty::arg {
@@ -467,8 +467,8 @@ pub fn ty_of_arg<AC:AstConv,RS:region_scope + Copy + Durable>(
467467
}
468468

469469
pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
470-
self: @mut AC,
471-
rscope: RS,
470+
self: &AC,
471+
rscope: &RS,
472472
purity: ast::purity,
473473
abi: ast::Abi,
474474
decl: &ast::fn_decl)
@@ -479,10 +479,10 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
479479
// that function type
480480
let rb = in_binding_rscope(rscope);
481481

482-
let input_tys = decl.inputs.map(|a| ty_of_arg(self, rb, *a, None));
482+
let input_tys = decl.inputs.map(|a| ty_of_arg(self, &rb, *a, None));
483483
let output_ty = match decl.output.node {
484484
ast::ty_infer => self.ty_infer(decl.output.span),
485-
_ => ast_ty_to_ty(self, rb, decl.output)
485+
_ => ast_ty_to_ty(self, &rb, decl.output)
486486
};
487487

488488
ty::BareFnTy {
@@ -493,8 +493,8 @@ pub fn ty_of_bare_fn<AC:AstConv,RS:region_scope + Copy + Durable>(
493493
}
494494

495495
pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
496-
self: @mut AC,
497-
rscope: RS,
496+
self: &AC,
497+
rscope: &RS,
498498
sigil: ast::Sigil,
499499
purity: ast::purity,
500500
onceness: ast::Onceness,
@@ -538,14 +538,14 @@ pub fn ty_of_closure<AC:AstConv,RS:region_scope + Copy + Durable>(
538538
// were supplied
539539
if i < e.inputs.len() {Some(e.inputs[i])} else {None}
540540
};
541-
ty_of_arg(self, rb, *a, expected_arg_ty)
541+
ty_of_arg(self, &rb, *a, expected_arg_ty)
542542
};
543543

544544
let expected_ret_ty = expected_tys.map(|e| e.output);
545545
let output_ty = match decl.output.node {
546546
ast::ty_infer if expected_ret_ty.is_some() => expected_ret_ty.get(),
547547
ast::ty_infer => self.ty_infer(decl.output.span),
548-
_ => ast_ty_to_ty(self, rb, decl.output)
548+
_ => ast_ty_to_ty(self, &rb, decl.output)
549549
};
550550

551551
ty::ClosureTy {

‎src/librustc/middle/typeck/check/mod.rs

+17-26
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
581581
let rp = ccx.tcx.region_paramd_items.find(&it.id);
582582
debug!("item_impl %s with id %d rp %?",
583583
*ccx.tcx.sess.str_of(it.ident), it.id, rp);
584-
let self_ty = ccx.to_ty(rscope::type_rscope(rp), ty);
584+
let self_ty = ccx.to_ty(&rscope::type_rscope(rp), ty);
585585
for ms.each |m| {
586586
check_method(ccx, *m, self_ty, local_def(it.id));
587587
}
@@ -636,21 +636,20 @@ pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
636636
}
637637

638638
impl AstConv for FnCtxt {
639-
fn tcx(@mut self) -> ty::ctxt { self.ccx.tcx }
640-
fn ccx(@mut self) -> @mut CrateCtxt { self.ccx }
639+
fn tcx(&self) -> ty::ctxt { self.ccx.tcx }
641640

642-
fn get_item_ty(@mut self, id: ast::def_id) -> ty::ty_param_bounds_and_ty {
641+
fn get_item_ty(&self, id: ast::def_id) -> ty::ty_param_bounds_and_ty {
643642
ty::lookup_item_type(self.tcx(), id)
644643
}
645644

646-
fn ty_infer(@mut self, _span: span) -> ty::t {
645+
fn ty_infer(&self, _span: span) -> ty::t {
647646
self.infcx().next_ty_var()
648647
}
649648
}
650649

651650
pub impl FnCtxt {
652-
fn infcx(@mut self) -> @mut infer::InferCtxt { self.inh.infcx }
653-
fn search_in_scope_regions(@mut self,
651+
fn infcx(&self) -> @mut infer::InferCtxt { self.inh.infcx }
652+
fn search_in_scope_regions(&self,
654653
br: ty::bound_region)
655654
-> Result<ty::Region, ~str> {
656655
let in_scope_regions = self.in_scope_regions;
@@ -669,25 +668,17 @@ pub impl FnCtxt {
669668
}
670669
}
671670

672-
impl region_scope for @mut FnCtxt {
673-
pure fn anon_region(&self, span: span) -> Result<ty::Region, ~str> {
674-
// XXX: Unsafe to work around purity
675-
unsafe {
676-
result::Ok(self.infcx().next_region_var_nb(span))
677-
}
671+
impl region_scope for FnCtxt {
672+
fn anon_region(&self, span: span) -> Result<ty::Region, ~str> {
673+
result::Ok(self.infcx().next_region_var_nb(span))
678674
}
679-
pure fn self_region(&self, _span: span) -> Result<ty::Region, ~str> {
680-
// XXX: Unsafe to work around purity
681-
unsafe {
682-
self.search_in_scope_regions(ty::br_self)
683-
}
675+
fn self_region(&self, _span: span) -> Result<ty::Region, ~str> {
676+
self.search_in_scope_regions(ty::br_self)
684677
}
685-
pure fn named_region(&self, _span: span, id: ast::ident)
686-
-> Result<ty::Region, ~str> {
687-
// XXX: Unsafe to work around purity
688-
unsafe {
689-
self.search_in_scope_regions(ty::br_named(id))
690-
}
678+
fn named_region(&self,
679+
_span: span,
680+
id: ast::ident) -> Result<ty::Region, ~str> {
681+
self.search_in_scope_regions(ty::br_named(id))
691682
}
692683
}
693684

@@ -710,7 +701,7 @@ pub impl FnCtxt {
710701
pprust::expr_to_str(expr, self.tcx().sess.intr()))
711702
}
712703

713-
fn block_region(@mut self) -> ty::Region {
704+
fn block_region(&self) -> ty::Region {
714705
ty::re_scope(self.region_lb)
715706
}
716707

@@ -1076,7 +1067,7 @@ pub fn impl_self_ty(vcx: &VtableContext,
10761067
}, _)) => {
10771068
(ts.ty_params.len(),
10781069
region_param,
1079-
vcx.ccx.to_ty(rscope::type_rscope(region_param), st))
1070+
vcx.ccx.to_ty(&rscope::type_rscope(region_param), st))
10801071
}
10811072
Some(ast_map::node_item(@ast::item {
10821073
node: ast::item_struct(_, ref ts),

‎src/librustc/middle/typeck/collect.rs

+63-56
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ use util::common::{indenter, pluralize};
4747
use util::ppaux;
4848

4949
use core::dvec;
50-
use core::option;
5150
use core::vec;
5251
use syntax::ast::{RegionTyParamBound, TraitTyParamBound};
5352
use syntax::ast;
@@ -108,24 +107,24 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: @ast::crate) {
108107
visit::visit_crate(
109108
*crate, (),
110109
visit::mk_simple_visitor(@visit::SimpleVisitor {
111-
visit_item: |a|convert(ccx, a),
110+
visit_item: |a| convert(ccx, a),
112111
visit_foreign_item: |a|convert_foreign(ccx, a),
113112
.. *visit::default_simple_visitor()
114113
}));
115114
}
116115

117-
pub impl @mut CrateCtxt {
118-
fn to_ty<RS:region_scope + Copy + Durable>(rs: RS, ast_ty: @ast::Ty)
119-
-> ty::t {
116+
impl CrateCtxt {
117+
fn to_ty<RS:region_scope + Copy + Durable>(
118+
&self, rs: &RS, ast_ty: @ast::Ty) -> ty::t
119+
{
120120
ast_ty_to_ty(self, rs, ast_ty)
121121
}
122122
}
123123

124124
impl AstConv for CrateCtxt {
125-
fn tcx(@mut self) -> ty::ctxt { self.tcx }
126-
fn ccx(@mut self) -> @mut CrateCtxt { self }
125+
fn tcx(&self) -> ty::ctxt { self.tcx }
127126

128-
fn get_item_ty(@mut self, id: ast::def_id) -> ty::ty_param_bounds_and_ty {
127+
fn get_item_ty(&self, id: ast::def_id) -> ty::ty_param_bounds_and_ty {
129128
if id.crate != ast::local_crate {
130129
csearch::get_type(self.tcx, id)
131130
} else {
@@ -144,13 +143,13 @@ impl AstConv for CrateCtxt {
144143
}
145144
}
146145

147-
fn ty_infer(@mut self, span: span) -> ty::t {
146+
fn ty_infer(&self, span: span) -> ty::t {
148147
self.tcx.sess.span_bug(span,
149148
~"found `ty_infer` in unexpected place");
150149
}
151150
}
152151

153-
pub fn get_enum_variant_types(ccx: @mut CrateCtxt,
152+
pub fn get_enum_variant_types(ccx: &CrateCtxt,
154153
enum_ty: ty::t,
155154
variants: &[ast::variant],
156155
generics: &ast::Generics,
@@ -165,7 +164,7 @@ pub fn get_enum_variant_types(ccx: @mut CrateCtxt,
165164
match variant.node.kind {
166165
ast::tuple_variant_kind(ref args) if args.len() > 0 => {
167166
let rs = type_rscope(rp);
168-
let input_tys = args.map(|va| ccx.to_ty(rs, va.ty));
167+
let input_tys = args.map(|va| ccx.to_ty(&rs, va.ty));
169168
result_ty = Some(ty::mk_ctor_fn(tcx, input_tys, enum_ty));
170169
}
171170

@@ -217,17 +216,17 @@ pub fn get_enum_variant_types(ccx: @mut CrateCtxt,
217216
}
218217
}
219218

220-
pub fn ensure_trait_methods(ccx: @mut CrateCtxt,
219+
pub fn ensure_trait_methods(ccx: &CrateCtxt,
221220
id: ast::node_id,
222221
trait_ty: ty::t) {
223-
fn store_methods<T>(ccx: @mut CrateCtxt,
222+
fn store_methods<T>(ccx: &CrateCtxt,
224223
id: ast::node_id,
225224
stuff: ~[T],
226225
f: &fn(v: &T) -> ty::method) {
227226
ty::store_trait_methods(ccx.tcx, id, @vec::map(stuff, f));
228227
}
229228

230-
fn make_static_method_ty(ccx: @mut CrateCtxt,
229+
fn make_static_method_ty(ccx: &CrateCtxt,
231230
am: &ast::ty_method,
232231
rp: Option<ty::region_variance>,
233232
m: ty::method,
@@ -308,7 +307,7 @@ pub fn ensure_trait_methods(ccx: @mut CrateCtxt,
308307
}
309308
}
310309

311-
pub fn ensure_supertraits(ccx: @mut CrateCtxt,
310+
pub fn ensure_supertraits(ccx: &CrateCtxt,
312311
id: ast::node_id,
313312
sp: codemap::span,
314313
rp: Option<ty::region_variance>,
@@ -492,7 +491,7 @@ pub fn compare_impl_method(tcx: ty::ctxt,
492491
}
493492
}
494493
495-
pub fn check_methods_against_trait(ccx: @mut CrateCtxt,
494+
pub fn check_methods_against_trait(ccx: &CrateCtxt,
496495
generics: &ast::Generics,
497496
rp: Option<ty::region_variance>,
498497
selfty: ty::t,
@@ -544,11 +543,11 @@ pub fn check_methods_against_trait(ccx: @mut CrateCtxt,
544543
}
545544
} // fn
546545

547-
pub fn convert_field(ccx: @mut CrateCtxt,
546+
pub fn convert_field(ccx: &CrateCtxt,
548547
rp: Option<ty::region_variance>,
549548
bounds: @~[ty::param_bounds],
550549
v: @ast::struct_field) {
551-
let tt = ccx.to_ty(type_rscope(rp), v.node.ty);
550+
let tt = ccx.to_ty(&type_rscope(rp), v.node.ty);
552551
write_ty_to_tcx(ccx.tcx, v.node.id, tt);
553552
/* add the field to the tcache */
554553
ccx.tcx.tcache.insert(local_def(v.node.id),
@@ -566,8 +565,8 @@ pub struct ConvertedMethod {
566565
body_id: ast::node_id
567566
}
568567

569-
pub fn convert_methods(ccx: @mut CrateCtxt,
570-
ms: ~[@ast::method],
568+
pub fn convert_methods(ccx: &CrateCtxt,
569+
ms: &[@ast::method],
571570
rp: Option<ty::region_variance>,
572571
rcvr_bounds: @~[ty::param_bounds])
573572
-> ~[ConvertedMethod] {
@@ -593,7 +592,7 @@ pub fn convert_methods(ccx: @mut CrateCtxt,
593592
}
594593
}
595594

596-
pub fn ensure_no_ty_param_bounds(ccx: @mut CrateCtxt,
595+
pub fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
597596
span: span,
598597
generics: &ast::Generics,
599598
thing: &static/str) {
@@ -607,7 +606,7 @@ pub fn ensure_no_ty_param_bounds(ccx: @mut CrateCtxt,
607606
}
608607
}
609608

610-
pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) {
609+
pub fn convert(ccx: &CrateCtxt, it: @ast::item) {
611610
let tcx = ccx.tcx;
612611
let rp = tcx.region_paramd_items.find(&it.id);
613612
debug!("convert: item %s with id %d rp %?",
@@ -627,7 +626,7 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) {
627626
}
628627
ast::item_impl(ref generics, trait_ref, selfty, ref ms) => {
629628
let i_bounds = ty_param_bounds(ccx, generics);
630-
let selfty = ccx.to_ty(type_rscope(rp), selfty);
629+
let selfty = ccx.to_ty(&type_rscope(rp), selfty);
631630
write_ty_to_tcx(tcx, it.id, selfty);
632631
tcx.tcache.insert(local_def(it.id),
633632
ty_param_bounds_and_ty {
@@ -636,7 +635,7 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) {
636635
ty: selfty});
637636

638637
// XXX: Bad copy of `ms` below.
639-
let cms = convert_methods(ccx, /*bad*/copy *ms, rp, i_bounds);
638+
let cms = convert_methods(ccx, *ms, rp, i_bounds);
640639
for trait_ref.each |t| {
641640
check_methods_against_trait(ccx, generics, rp, selfty,
642641
*t, /*bad*/copy cms);
@@ -680,7 +679,7 @@ pub fn convert(ccx: @mut CrateCtxt, it: @ast::item) {
680679
}
681680
}
682681

683-
pub fn convert_struct(ccx: @mut CrateCtxt,
682+
pub fn convert_struct(ccx: &CrateCtxt,
684683
rp: Option<ty::region_variance>,
685684
struct_def: @ast::struct_def,
686685
generics: &ast::Generics,
@@ -693,7 +692,7 @@ pub fn convert_struct(ccx: @mut CrateCtxt,
693692
let t_dtor = ty::mk_bare_fn(
694693
tcx,
695694
astconv::ty_of_bare_fn(
696-
ccx, type_rscope(rp),
695+
ccx, &type_rscope(rp),
697696
ast::impure_fn, ast::RustAbi,
698697
&ast_util::dtor_dec()));
699698
write_ty_to_tcx(tcx, dtor.node.id, t_dtor);
@@ -738,7 +737,7 @@ pub fn convert_struct(ccx: @mut CrateCtxt,
738737
}
739738
}
740739

741-
pub fn convert_foreign(ccx: @mut CrateCtxt, i: @ast::foreign_item) {
740+
pub fn convert_foreign(ccx: &CrateCtxt, i: @ast::foreign_item) {
742741
// As above, this call populates the type table with the converted
743742
// type of the foreign item. We simply write it into the node type
744743
// table.
@@ -747,28 +746,38 @@ pub fn convert_foreign(ccx: @mut CrateCtxt, i: @ast::foreign_item) {
747746
ccx.tcx.tcache.insert(local_def(i.id), tpt);
748747
}
749748

750-
pub fn ty_of_method(ccx: @mut CrateCtxt,
749+
pub fn ty_of_method(ccx: &CrateCtxt,
751750
m: @ast::method,
752751
rp: Option<ty::region_variance>) -> ty::method {
752+
let rscope = MethodRscope {
753+
self_ty: m.self_ty.node,
754+
region_parameterization: rp
755+
};
756+
753757
ty::method {
754758
ident: m.ident,
755759
tps: ty_param_bounds(ccx, &m.generics),
756-
fty: astconv::ty_of_bare_fn(ccx, type_rscope(rp), m.purity,
760+
fty: astconv::ty_of_bare_fn(ccx, &rscope, m.purity,
757761
ast::RustAbi, &m.decl),
758762
self_ty: m.self_ty.node,
759763
vis: m.vis,
760764
def_id: local_def(m.id)
761765
}
762766
}
763767

764-
pub fn ty_of_ty_method(self: @mut CrateCtxt,
768+
pub fn ty_of_ty_method(self: &CrateCtxt,
765769
m: &ast::ty_method,
766770
rp: Option<ty::region_variance>,
767771
id: ast::def_id) -> ty::method {
772+
let rscope = MethodRscope {
773+
self_ty: m.self_ty.node,
774+
region_parameterization: rp
775+
};
776+
768777
ty::method {
769778
ident: m.ident,
770779
tps: ty_param_bounds(self, &m.generics),
771-
fty: astconv::ty_of_bare_fn(self, type_rscope(rp), m.purity,
780+
fty: astconv::ty_of_bare_fn(self, &rscope, m.purity,
772781
ast::RustAbi, &m.decl),
773782
// assume public, because this is only invoked on trait methods
774783
self_ty: m.self_ty.node,
@@ -782,7 +791,7 @@ pub fn ty_of_ty_method(self: @mut CrateCtxt,
782791
it's bound to a valid trait type. Returns the def_id for the defining
783792
trait. Fails if the type is a type other than an trait type.
784793
*/
785-
pub fn instantiate_trait_ref(ccx: @mut CrateCtxt, t: @ast::trait_ref,
794+
pub fn instantiate_trait_ref(ccx: &CrateCtxt, t: @ast::trait_ref,
786795
rp: Option<ty::region_variance>)
787796
-> (ast::def_id, ty_param_substs_and_ty) {
788797

@@ -793,7 +802,7 @@ pub fn instantiate_trait_ref(ccx: @mut CrateCtxt, t: @ast::trait_ref,
793802

794803
match lookup_def_tcx(ccx.tcx, t.path.span, t.ref_id) {
795804
ast::def_ty(t_id) => {
796-
let tpt = astconv::ast_path_to_ty(ccx, rscope, t_id, t.path,
805+
let tpt = astconv::ast_path_to_ty(ccx, &rscope, t_id, t.path,
797806
t.ref_id);
798807
match ty::get(tpt.ty).sty {
799808
ty::ty_trait(*) => {
@@ -806,7 +815,7 @@ pub fn instantiate_trait_ref(ccx: @mut CrateCtxt, t: @ast::trait_ref,
806815
}
807816
}
808817

809-
pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item)
818+
pub fn ty_of_item(ccx: &CrateCtxt, it: @ast::item)
810819
-> ty::ty_param_bounds_and_ty {
811820
let def_id = local_def(it.id);
812821
let tcx = ccx.tcx;
@@ -817,14 +826,14 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item)
817826
let rp = tcx.region_paramd_items.find(&it.id);
818827
match it.node {
819828
ast::item_const(t, _) => {
820-
let typ = ccx.to_ty(empty_rscope, t);
829+
let typ = ccx.to_ty(&empty_rscope, t);
821830
let tpt = no_params(typ);
822831
tcx.tcache.insert(local_def(it.id), tpt);
823832
return tpt;
824833
}
825834
ast::item_fn(ref decl, purity, ref generics, _) => {
826835
let bounds = ty_param_bounds(ccx, generics);
827-
let tofd = astconv::ty_of_bare_fn(ccx, empty_rscope, purity,
836+
let tofd = astconv::ty_of_bare_fn(ccx, &empty_rscope, purity,
828837
ast::RustAbi, decl);
829838
let tpt = ty_param_bounds_and_ty {
830839
bounds: bounds,
@@ -847,7 +856,7 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item)
847856
let rp = tcx.region_paramd_items.find(&it.id);
848857
let tpt = {
849858
let ty = {
850-
let t0 = ccx.to_ty(type_rscope(rp), t);
859+
let t0 = ccx.to_ty(&type_rscope(rp), t);
851860
// Do not associate a def id with a named, parameterized type
852861
// like "foo<X>". This is because otherwise ty_to_str will
853862
// print the name as merely "foo", as it has no way to
@@ -906,23 +915,21 @@ pub fn ty_of_item(ccx: @mut CrateCtxt, it: @ast::item)
906915
}
907916
}
908917
909-
pub fn ty_of_foreign_item(ccx: @mut CrateCtxt, it: @ast::foreign_item)
918+
pub fn ty_of_foreign_item(ccx: &CrateCtxt, it: @ast::foreign_item)
910919
-> ty::ty_param_bounds_and_ty {
911-
match /*bad*/copy it.node {
920+
match it.node {
912921
ast::foreign_item_fn(ref fn_decl, _, ref generics) => {
913-
ty_of_foreign_fn_decl(
914-
ccx,
915-
fn_decl,
916-
local_def(it.id),
917-
generics
918-
)
922+
ty_of_foreign_fn_decl(ccx,
923+
fn_decl,
924+
local_def(it.id),
925+
generics)
919926
}
920927
ast::foreign_item_const(t) => {
921-
let rb = in_binding_rscope(empty_rscope);
928+
let rb = in_binding_rscope(&empty_rscope);
922929
ty::ty_param_bounds_and_ty {
923930
bounds: @~[],
924931
region_param: None,
925-
ty: ast_ty_to_ty(ccx, rb, t)
932+
ty: ast_ty_to_ty(ccx, &rb, t)
926933
}
927934
}
928935
}
@@ -932,14 +939,14 @@ pub fn ty_of_foreign_item(ccx: @mut CrateCtxt, it: @ast::foreign_item)
932939
// of a newtyped Ty or a region) to ty's notion of ty param bounds, which can
933940
// either be user-defined traits, or one of the four built-in traits (formerly
934941
// known as kinds): Const, Copy, Durable, and Send.
935-
pub fn compute_bounds(ccx: @mut CrateCtxt,
942+
pub fn compute_bounds(ccx: &CrateCtxt,
936943
ast_bounds: @OptVec<ast::TyParamBound>)
937944
-> ty::param_bounds {
938945
@ast_bounds.flat_map_to_vec(|b| {
939946
match b {
940947
&TraitTyParamBound(b) => {
941948
let li = &ccx.tcx.lang_items;
942-
let ity = ast_ty_to_ty(ccx, empty_rscope, b);
949+
let ity = ast_ty_to_ty(ccx, &empty_rscope, b);
943950
match ty::get(ity).sty {
944951
ty::ty_trait(did, _, _) => {
945952
if did == li.owned_trait() {
@@ -968,7 +975,7 @@ pub fn compute_bounds(ccx: @mut CrateCtxt,
968975
})
969976
}
970977

971-
pub fn ty_param_bounds(ccx: @mut CrateCtxt,
978+
pub fn ty_param_bounds(ccx: &CrateCtxt,
972979
generics: &ast::Generics)
973980
-> @~[ty::param_bounds] {
974981
@do generics.ty_params.map_to_vec |param| {
@@ -983,15 +990,15 @@ pub fn ty_param_bounds(ccx: @mut CrateCtxt,
983990
}
984991
}
985992

986-
pub fn ty_of_foreign_fn_decl(ccx: @mut CrateCtxt,
993+
pub fn ty_of_foreign_fn_decl(ccx: &CrateCtxt,
987994
decl: &ast::fn_decl,
988995
def_id: ast::def_id,
989996
generics: &ast::Generics)
990997
-> ty::ty_param_bounds_and_ty {
991998
let bounds = ty_param_bounds(ccx, generics);
992-
let rb = in_binding_rscope(empty_rscope);
993-
let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, rb, *a, None) );
994-
let output_ty = ast_ty_to_ty(ccx, rb, decl.output);
999+
let rb = in_binding_rscope(&empty_rscope);
1000+
let input_tys = decl.inputs.map(|a| ty_of_arg(ccx, &rb, *a, None) );
1001+
let output_ty = ast_ty_to_ty(ccx, &rb, decl.output);
9951002

9961003
let t_fn = ty::mk_bare_fn(
9971004
ccx.tcx,
@@ -1009,7 +1016,7 @@ pub fn ty_of_foreign_fn_decl(ccx: @mut CrateCtxt,
10091016
return tpt;
10101017
}
10111018

1012-
pub fn mk_generics(ccx: @mut CrateCtxt, generics: &ast::Generics)
1019+
pub fn mk_generics(ccx: &CrateCtxt, generics: &ast::Generics)
10131020
-> (@~[ty::param_bounds], ~[ty::t])
10141021
{
10151022
let mut i = 0u;
@@ -1022,7 +1029,7 @@ pub fn mk_generics(ccx: @mut CrateCtxt, generics: &ast::Generics)
10221029
}))
10231030
}
10241031

1025-
pub fn mk_substs(ccx: @mut CrateCtxt,
1032+
pub fn mk_substs(ccx: &CrateCtxt,
10261033
generics: &ast::Generics,
10271034
rp: Option<ty::region_variance>)
10281035
-> (@~[ty::param_bounds], ty::substs)

‎src/librustc/middle/typeck/rscope.rs

+68-45
Original file line numberDiff line numberDiff line change
@@ -18,41 +18,59 @@ use syntax::ast;
1818
use syntax::codemap::span;
1919

2020
pub trait region_scope {
21-
pure fn anon_region(&self, span: span) -> Result<ty::Region, ~str>;
22-
pure fn self_region(&self, span: span) -> Result<ty::Region, ~str>;
23-
pure fn named_region(&self, span: span, id: ast::ident)
21+
fn anon_region(&self, span: span) -> Result<ty::Region, ~str>;
22+
fn self_region(&self, span: span) -> Result<ty::Region, ~str>;
23+
fn named_region(&self, span: span, id: ast::ident)
2424
-> Result<ty::Region, ~str>;
2525
}
2626

2727
pub enum empty_rscope { empty_rscope }
28-
2928
impl region_scope for empty_rscope {
30-
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
31-
result::Ok(ty::re_static)
29+
fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
30+
Ok(ty::re_static)
3231
}
33-
pure fn self_region(&self, _span: span) -> Result<ty::Region, ~str> {
32+
fn self_region(&self, _span: span) -> Result<ty::Region, ~str> {
3433
result::Err(~"only the static region is allowed here")
3534
}
36-
pure fn named_region(&self, _span: span, _id: ast::ident)
35+
fn named_region(&self, _span: span, _id: ast::ident)
3736
-> Result<ty::Region, ~str> {
3837
result::Err(~"only the static region is allowed here")
3938
}
4039
}
4140

42-
pub enum type_rscope = Option<ty::region_variance>;
41+
pub struct MethodRscope {
42+
self_ty: ast::self_ty_,
43+
region_parameterization: Option<ty::region_variance>
44+
}
45+
impl region_scope for MethodRscope {
46+
fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
47+
result::Err(~"anonymous region types are not permitted here")
48+
}
49+
fn self_region(&self, _span: span) -> Result<ty::Region, ~str> {
50+
assert self.region_parameterization.is_some() ||
51+
self.self_ty.is_borrowed();
52+
result::Ok(ty::re_bound(ty::br_self))
53+
}
54+
fn named_region(&self, span: span, id: ast::ident)
55+
-> Result<ty::Region, ~str> {
56+
do empty_rscope.named_region(span, id).chain_err |_e| {
57+
result::Err(~"region is not in scope here")
58+
}
59+
}
60+
}
4361

62+
pub enum type_rscope = Option<ty::region_variance>;
4463
impl region_scope for type_rscope {
45-
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
46-
match **self {
47-
Some(_) => result::Ok(ty::re_bound(ty::br_self)),
48-
None => result::Err(~"to use region types here, the containing \
49-
type must be declared with a region bound")
50-
}
64+
fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
65+
// if the anon or self region is used, region parameterization should
66+
// have inferred that this type is RP
67+
assert self.is_some();
68+
result::Ok(ty::re_bound(ty::br_self))
5169
}
52-
pure fn self_region(&self, span: span) -> Result<ty::Region, ~str> {
70+
fn self_region(&self, span: span) -> Result<ty::Region, ~str> {
5371
self.anon_region(span)
5472
}
55-
pure fn named_region(&self, span: span, id: ast::ident)
73+
fn named_region(&self, span: span, id: ast::ident)
5674
-> Result<ty::Region, ~str> {
5775
do empty_rscope.named_region(span, id).chain_err |_e| {
5876
result::Err(~"named regions other than `self` are not \
@@ -70,50 +88,55 @@ pub fn bound_self_region(rp: Option<ty::region_variance>)
7088
}
7189

7290
pub struct anon_rscope { anon: ty::Region, base: @region_scope }
73-
pub fn in_anon_rscope<RS:region_scope + Copy + Durable>(self: RS,
74-
r: ty::Region)
75-
-> @anon_rscope {
76-
@anon_rscope {anon: r, base: @self as @region_scope}
91+
pub fn in_anon_rscope<RS:region_scope + Copy + Durable>(
92+
self: &RS,
93+
r: ty::Region) -> anon_rscope
94+
{
95+
let base = @(copy *self) as @region_scope;
96+
anon_rscope {anon: r, base: base}
7797
}
78-
79-
impl region_scope for @anon_rscope {
80-
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
98+
impl region_scope for anon_rscope {
99+
fn anon_region(&self,
100+
_span: span) -> Result<ty::Region, ~str>
101+
{
81102
result::Ok(self.anon)
82103
}
83-
pure fn self_region(&self, span: span) -> Result<ty::Region, ~str> {
104+
fn self_region(&self,
105+
span: span) -> Result<ty::Region, ~str>
106+
{
84107
self.base.self_region(span)
85108
}
86-
pure fn named_region(&self, span: span, id: ast::ident)
87-
-> Result<ty::Region, ~str> {
109+
fn named_region(&self,
110+
span: span,
111+
id: ast::ident) -> Result<ty::Region, ~str>
112+
{
88113
self.base.named_region(span, id)
89114
}
90115
}
91116

92117
pub struct binding_rscope {
93-
base: region_scope,
94-
anon_bindings: uint,
118+
base: @region_scope,
119+
anon_bindings: @mut uint,
95120
}
96121

97-
pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(self: RS)
98-
-> @mut binding_rscope {
99-
let base = @self as @region_scope;
100-
@mut binding_rscope { base: base, anon_bindings: 0 }
122+
pub fn in_binding_rscope<RS:region_scope + Copy + Durable>(self: &RS)
123+
-> binding_rscope {
124+
let base = @(copy *self) as @region_scope;
125+
binding_rscope { base: base, anon_bindings: @mut 0 }
101126
}
102-
103-
impl region_scope for @mut binding_rscope {
104-
pure fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
105-
// XXX: Unsafe to work around purity
106-
unsafe {
107-
let idx = self.anon_bindings;
108-
self.anon_bindings += 1;
109-
result::Ok(ty::re_bound(ty::br_anon(idx)))
110-
}
127+
impl region_scope for binding_rscope {
128+
fn anon_region(&self, _span: span) -> Result<ty::Region, ~str> {
129+
let idx = *self.anon_bindings;
130+
*self.anon_bindings += 1;
131+
result::Ok(ty::re_bound(ty::br_anon(idx)))
111132
}
112-
pure fn self_region(&self, span: span) -> Result<ty::Region, ~str> {
133+
fn self_region(&self, span: span) -> Result<ty::Region, ~str> {
113134
self.base.self_region(span)
114135
}
115-
pure fn named_region(&self, span: span, id: ast::ident)
116-
-> Result<ty::Region, ~str> {
136+
fn named_region(&self,
137+
span: span,
138+
id: ast::ident) -> Result<ty::Region, ~str>
139+
{
117140
do self.base.named_region(span, id).chain_err |_e| {
118141
result::Ok(ty::re_bound(ty::br_named(id)))
119142
}

‎src/libsyntax/ast.rs

+9
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,15 @@ pub enum self_ty_ {
10171017
sty_uniq(mutability) // by-unique-pointer self: `~self`
10181018
}
10191019
1020+
impl self_ty_ {
1021+
fn is_borrowed(&self) -> bool {
1022+
match *self {
1023+
sty_region(_) => true,
1024+
_ => false
1025+
}
1026+
}
1027+
}
1028+
10201029
pub type self_ty = spanned<self_ty_>;
10211030
10221031
#[auto_encode]

‎src/libsyntax/print/pprust.rs

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use print::pprust;
3030
use core::char;
3131
use core::dvec::DVec;
3232
use core::io;
33-
use core::option;
3433
use core::str;
3534
use core::u64;
3635
use core::vec;

‎src/test/compile-fail/map-types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ fn main() {
1717
let x: @Map<~str, ~str> = @LinearMap::new::<~str, ~str>() as
1818
Map::<~str, ~str>;
1919
let y: @Map<uint, ~str> = @x;
20-
//~^ ERROR mismatched types: expected `@core::container::Map/&<uint,~str>`
20+
//~^ ERROR mismatched types: expected `@core::container::Map<uint,~str>`
2121
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Test how region-parameterization inference
2+
// interacts with explicit self types.
3+
//
4+
// Issue #5224.
5+
6+
trait Getter {
7+
// This trait does not need to be
8+
// region-parameterized, because 'self
9+
// is bound in the self type:
10+
fn get(&self) -> &'self int;
11+
}
12+
13+
struct Foo {
14+
field: int
15+
}
16+
17+
impl Getter for Foo {
18+
fn get(&self) -> &'self int { &self.field }
19+
}
20+
21+
fn get_int<G: Getter>(g: &G) -> int {
22+
*g.get()
23+
}
24+
25+
fn main() {
26+
let foo = Foo { field: 22 };
27+
assert get_int(&foo) == 22;
28+
}

5 commit comments

Comments
 (5)

bors commented on Mar 5, 2013

@bors
Contributor

saw approval from nikomatsakis
at nikomatsakis@cbfd88a

bors commented on Mar 5, 2013

@bors
Contributor

merging nikomatsakis/rust/issue-5224 = cbfd88a into auto

bors commented on Mar 5, 2013

@bors
Contributor

nikomatsakis/rust/issue-5224 = cbfd88a merged ok, testing candidate = 9ec7f3f

bors commented on Mar 5, 2013

@bors
Contributor

fast-forwarding incoming to auto = 9ec7f3f

Please sign in to comment.