@@ -65,13 +65,19 @@ type ctxt = {
65
65
parent : parent ,
66
66
67
67
/* True if we're within the pattern part of an alt, false otherwise. */
68
- in_alt : bool
68
+ in_alt : bool ,
69
+
70
+ /*
71
+ * Points to the site of the current typeclass implementation, or none if
72
+ * we're outside one.
73
+ */
74
+ self_binding : option < ast:: def_id >
69
75
} ;
70
76
71
77
fn region_to_scope ( region_map : @region_map , region : ty:: region )
72
78
-> ast:: node_id {
73
79
ret alt region {
74
- ty : : re_caller ( def_id) { def_id. node }
80
+ ty : : re_caller ( def_id) | ty :: re_self ( def_id ) { def_id. node }
75
81
ty:: re_named ( def_id) { region_map. region_name_to_fn . get ( def_id) }
76
82
ty:: re_block ( node_id) { node_id }
77
83
ty:: re_inferred { fail "unresolved region in region_to_scope" }
@@ -115,7 +121,21 @@ fn resolve_ty(ty: @ast::ty, cx: ctxt, visitor: visit::vt<ctxt>) {
115
121
alt ty. node {
116
122
ast:: ty_rptr ( { id: region_id, node: node} , _) {
117
123
alt node {
118
- ast : : re_inferred | ast:: re_self { /* no-op */ }
124
+ ast : : re_inferred { /* no-op */ }
125
+ ast:: re_self {
126
+ alt cx. self_binding {
127
+ some( def_id) {
128
+ let region = ty:: re_self ( def_id) ;
129
+ let rm = cx. region_map ;
130
+ rm. ast_type_to_region . insert ( region_id, region) ;
131
+ }
132
+ none {
133
+ cx. sess . span_err ( ty. span ,
134
+ "the `self` region is not \
135
+ allowed here") ;
136
+ }
137
+ }
138
+ }
119
139
ast:: re_named ( ident) {
120
140
// If at item scope, introduce or reuse a binding. If at
121
141
// block scope, require that the binding be introduced.
@@ -281,13 +301,22 @@ fn resolve_local(local: @ast::local, cx: ctxt, visitor: visit::vt<ctxt>) {
281
301
282
302
fn resolve_item ( item : @ast:: item , cx : ctxt , visitor : visit:: vt < ctxt > ) {
283
303
// Items create a new outer block scope as far as we're concerned.
284
- let parent = alt item. node {
285
- ast:: item_fn ( _, _, _) | ast:: item_enum ( _, _) { pa_fn_item ( item. id ) }
286
- _ { pa_item( item. id ) }
304
+ let parent;
305
+ let mut self_binding = cx. self_binding ;
306
+ alt item. node {
307
+ ast:: item_fn ( _, _, _) | ast:: item_enum ( _, _) {
308
+ parent = pa_fn_item ( item. id ) ;
309
+ }
310
+ ast:: item_impl ( _, _, _, _) {
311
+ self_binding = some ( { crate : ast:: local_crate, node: item. id } ) ;
312
+ parent = pa_item ( item. id ) ;
313
+ }
314
+ _ { parent = pa_item ( item. id ) ; }
287
315
} ;
288
316
let new_cx: ctxt = { bindings: @list:: nil,
289
317
parent: parent,
290
- in_alt: false
318
+ in_alt: false ,
319
+ self_binding: self_binding
291
320
with cx} ;
292
321
visit:: visit_item ( item, new_cx, visitor) ;
293
322
}
@@ -307,7 +336,8 @@ fn resolve_crate(sess: session, def_map: resolve::def_map, crate: @ast::crate)
307
336
mut bindings: @list:: nil,
308
337
mut queued_locals: [ ] ,
309
338
parent: pa_crate,
310
- in_alt: false } ;
339
+ in_alt: false ,
340
+ self_binding: none} ;
311
341
let visitor = visit:: mk_vt ( @{
312
342
visit_block: resolve_block,
313
343
visit_item: resolve_item,
0 commit comments