Resolve lifetime parameters for foreign functions.
Pretty straightforward; just need to make sure to explicitly handle the generic parameters of each ast::ForeignItemFn. Fixes #26587.
This commit is contained in:
parent
5542830665
commit
b2213498c4
@ -109,7 +109,7 @@ pub fn krate(sess: &Session, krate: &ast::Crate, def_map: &DefMap) -> NamedRegio
|
||||
|
||||
impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
// Items save/restore the set of labels. This way innner items
|
||||
// Items save/restore the set of labels. This way inner items
|
||||
// can freely reuse names, be they loop labels or lifetimes.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
||||
@ -151,6 +151,29 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||
replace(&mut self.labels_in_fn, saved);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
|
||||
// Items save/restore the set of labels. This way inner items
|
||||
// can freely reuse names, be they loop labels or lifetimes.
|
||||
let saved = replace(&mut self.labels_in_fn, vec![]);
|
||||
|
||||
// Items always introduce a new root scope
|
||||
self.with(RootScope, |_, this| {
|
||||
match item.node {
|
||||
ast::ForeignItemFn(_, ref generics) => {
|
||||
this.visit_early_late(subst::FnSpace, generics, |this| {
|
||||
visit::walk_foreign_item(this, item);
|
||||
})
|
||||
}
|
||||
ast::ForeignItemStatic(..) => {
|
||||
visit::walk_foreign_item(this, item);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Done traversing the item; restore saved set of labels.
|
||||
replace(&mut self.labels_in_fn, saved);
|
||||
}
|
||||
|
||||
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
|
||||
b: &'v ast::Block, s: Span, _: ast::NodeId) {
|
||||
match fk {
|
||||
|
25
src/test/compile-fail/generic-extern-lifetime.rs
Normal file
25
src/test/compile-fail/generic-extern-lifetime.rs
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test to make sure the names of the lifetimes are correctly resolved
|
||||
// in extern blocks.
|
||||
|
||||
extern {
|
||||
pub fn life<'a>(x:&'a i32);
|
||||
pub fn life2<'b>(x:&'a i32, y:&'b i32); //~ ERROR use of undeclared lifetime name `'a`
|
||||
pub fn life3<'a>(x:&'a i32, y:&i32) -> &'a i32;
|
||||
pub fn life4<'b>(x: for<'c> fn(&'a i32)); //~ ERROR use of undeclared lifetime name `'a`
|
||||
pub fn life5<'b>(x: for<'c> fn(&'b i32));
|
||||
pub fn life6<'b>(x: for<'c> fn(&'c i32));
|
||||
pub fn life7<'b>() -> for<'c> fn(&'a i32); //~ ERROR use of undeclared lifetime name `'a`
|
||||
pub fn life8<'b>() -> for<'c> fn(&'b i32);
|
||||
pub fn life9<'b>() -> for<'c> fn(&'c i32);
|
||||
}
|
||||
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user