From 9449161aea9f05b9f680ed6538b1c4ac95b4186b Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Fri, 26 Dec 2014 20:08:00 +0900 Subject: [PATCH] Do not resolve labels across function boundary --- src/librustc_resolve/lib.rs | 27 ++++++++++++++++++++++++-- src/test/compile-fail/resolve-label.rs | 21 ++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/test/compile-fail/resolve-label.rs diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index bf9e9294307ef..23de857bdfeb1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3934,6 +3934,30 @@ impl<'a> Resolver<'a> { None } + fn search_label(&self, name: Name) -> Option { + for rib in self.label_ribs.iter().rev() { + match rib.kind { + NormalRibKind => { + // Continue + } + _ => { + // Do not resolve labels across function boundary + return None + } + } + let result = rib.bindings.get(&name).cloned(); + match result { + Some(_) => { + return result + } + None => { + // Continue + } + } + } + None + } + fn resolve_crate(&mut self, krate: &ast::Crate) { debug!("(resolving crate) starting"); @@ -5752,8 +5776,7 @@ impl<'a> Resolver<'a> { ExprBreak(Some(label)) | ExprAgain(Some(label)) => { let renamed = mtwt::resolve(label); - match self.search_ribs(self.label_ribs[], - renamed, expr.span) { + match self.search_label(renamed) { None => { self.resolve_error( expr.span, diff --git a/src/test/compile-fail/resolve-label.rs b/src/test/compile-fail/resolve-label.rs new file mode 100644 index 0000000000000..398b4f5859e65 --- /dev/null +++ b/src/test/compile-fail/resolve-label.rs @@ -0,0 +1,21 @@ +// Copyright 2014 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn f() { + 'l: loop { + fn g() { + loop { + break 'l; //~ ERROR use of undeclared label + } + } + } +} + +fn main() {}