Skip to content

Commit d6a6178

Browse files
committed
Auto merge of #26588 - eefriedman:foreign-lifetime, r=nrc
Pretty straightforward; just need to make sure to explicitly handle the generic parameters of each ast::ForeignItemFn. Fixes #26587.
2 parents 8d91bbd + b221349 commit d6a6178

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

src/librustc/middle/resolve_lifetime.rs

+24-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
109109

110110
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
111111
fn visit_item(&mut self, item: &ast::Item) {
112-
// Items save/restore the set of labels. This way innner items
112+
// Items save/restore the set of labels. This way inner items
113113
// can freely reuse names, be they loop labels or lifetimes.
114114
let saved = replace(&mut self.labels_in_fn, vec![]);
115115

@@ -151,6 +151,29 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
151151
replace(&mut self.labels_in_fn, saved);
152152
}
153153

154+
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
155+
// Items save/restore the set of labels. This way inner items
156+
// can freely reuse names, be they loop labels or lifetimes.
157+
let saved = replace(&mut self.labels_in_fn, vec![]);
158+
159+
// Items always introduce a new root scope
160+
self.with(RootScope, |_, this| {
161+
match item.node {
162+
ast::ForeignItemFn(_, ref generics) => {
163+
this.visit_early_late(subst::FnSpace, generics, |this| {
164+
visit::walk_foreign_item(this, item);
165+
})
166+
}
167+
ast::ForeignItemStatic(..) => {
168+
visit::walk_foreign_item(this, item);
169+
}
170+
}
171+
});
172+
173+
// Done traversing the item; restore saved set of labels.
174+
replace(&mut self.labels_in_fn, saved);
175+
}
176+
154177
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
155178
b: &'v ast::Block, s: Span, _: ast::NodeId) {
156179
match fk {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Test to make sure the names of the lifetimes are correctly resolved
12+
// in extern blocks.
13+
14+
extern {
15+
pub fn life<'a>(x:&'a i32);
16+
pub fn life2<'b>(x:&'a i32, y:&'b i32); //~ ERROR use of undeclared lifetime name `'a`
17+
pub fn life3<'a>(x:&'a i32, y:&i32) -> &'a i32;
18+
pub fn life4<'b>(x: for<'c> fn(&'a i32)); //~ ERROR use of undeclared lifetime name `'a`
19+
pub fn life5<'b>(x: for<'c> fn(&'b i32));
20+
pub fn life6<'b>(x: for<'c> fn(&'c i32));
21+
pub fn life7<'b>() -> for<'c> fn(&'a i32); //~ ERROR use of undeclared lifetime name `'a`
22+
pub fn life8<'b>() -> for<'c> fn(&'b i32);
23+
pub fn life9<'b>() -> for<'c> fn(&'c i32);
24+
}
25+
fn main() {}

0 commit comments

Comments
 (0)