Skip to content

Commit e936353

Browse files
committed
Properly scope label resolution
1 parent 3e832b8 commit e936353

File tree

6 files changed

+115
-36
lines changed

6 files changed

+115
-36
lines changed

src/librustc/hir/lowering.rs

+22-36
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ pub struct LoweringContext<'a> {
103103
loop_scopes: Vec<NodeId>,
104104
is_in_loop_condition: bool,
105105
is_in_trait_impl: bool,
106-
is_in_anon_const: bool,
107106

108107
/// What to do when we encounter either an "anonymous lifetime
109108
/// reference". The term "anonymous" is meant to encompass both
@@ -231,7 +230,6 @@ pub fn lower_crate(
231230
node_id_to_hir_id: IndexVec::new(),
232231
is_generator: false,
233232
is_in_trait_impl: false,
234-
is_in_anon_const: false,
235233
lifetimes_to_define: Vec::new(),
236234
is_collecting_in_band_lifetimes: false,
237235
in_scope_lifetimes: Vec::new(),
@@ -970,26 +968,22 @@ impl<'a> LoweringContext<'a> {
970968
}
971969

972970
fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination {
973-
let target_id = if self.is_in_anon_const {
974-
Err(hir::LoopIdError::OutsideLoopScope)
975-
} else {
976-
match destination {
977-
Some((id, _)) => {
978-
if let Def::Label(loop_id) = self.expect_full_def(id) {
979-
Ok(self.lower_node_id(loop_id).node_id)
980-
} else {
981-
Err(hir::LoopIdError::UnresolvedLabel)
982-
}
983-
}
984-
None => {
985-
self.loop_scopes
986-
.last()
987-
.map(|innermost_loop_id| *innermost_loop_id)
988-
.map(|id| Ok(self.lower_node_id(id).node_id))
989-
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
990-
.into()
971+
let target_id = match destination {
972+
Some((id, _)) => {
973+
if let Def::Label(loop_id) = self.expect_full_def(id) {
974+
Ok(self.lower_node_id(loop_id).node_id)
975+
} else {
976+
Err(hir::LoopIdError::UnresolvedLabel)
991977
}
992978
}
979+
None => {
980+
self.loop_scopes
981+
.last()
982+
.map(|innermost_loop_id| *innermost_loop_id)
983+
.map(|id| Ok(self.lower_node_id(id).node_id))
984+
.unwrap_or(Err(hir::LoopIdError::OutsideLoopScope))
985+
.into()
986+
}
993987
};
994988
hir::Destination {
995989
label: self.lower_label(destination.map(|(_, label)| label)),
@@ -3448,22 +3442,14 @@ impl<'a> LoweringContext<'a> {
34483442
}
34493443

34503444
fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
3451-
let was_in_loop_condition = self.is_in_loop_condition;
3452-
self.is_in_loop_condition = false;
3453-
let was_in_anon_const = self.is_in_anon_const;
3454-
self.is_in_anon_const = true;
3455-
3456-
let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id);
3457-
let anon_const = hir::AnonConst {
3458-
id: node_id,
3459-
hir_id,
3460-
body: self.lower_body(None, |this| this.lower_expr(&c.value)),
3461-
};
3462-
3463-
self.is_in_anon_const = was_in_anon_const;
3464-
self.is_in_loop_condition = was_in_loop_condition;
3465-
3466-
anon_const
3445+
self.with_new_scopes(|this| {
3446+
let LoweredNodeId { node_id, hir_id } = this.lower_node_id(c.id);
3447+
hir::AnonConst {
3448+
id: node_id,
3449+
hir_id,
3450+
body: this.lower_body(None, |this| this.lower_expr(&c.value)),
3451+
}
3452+
})
34673453
}
34683454

34693455
fn lower_expr(&mut self, e: &Expr) -> hir::Expr {

src/librustc_resolve/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2358,7 +2358,9 @@ impl<'a> Resolver<'a> {
23582358
where F: FnOnce(&mut Resolver)
23592359
{
23602360
self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind));
2361+
self.label_ribs.push(Rib::new(ConstantItemRibKind));
23612362
f(self);
2363+
self.label_ribs.pop();
23622364
self.ribs[ValueNS].pop();
23632365
}
23642366

src/test/ui/const-eval/issue-52442.rs

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018 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+
fn main() {
12+
[(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0019]: constant contains unimplemented expression type
2+
--> $DIR/issue-52442.rs:12:14
3+
|
4+
LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type
5+
| ^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0019`.

src/test/ui/const-eval/issue-52443.rs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2018 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+
fn main() {
12+
[(); & { loop { continue } } ]; //~ ERROR mismatched types
13+
[(); loop { break }]; //~ ERROR mismatched types
14+
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
15+
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
16+
//~^ ERROR constant contains unimplemented expression type
17+
//~| ERROR could not evaluate repeat length
18+
}
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/issue-52443.rs:12:10
3+
|
4+
LL | [(); & { loop { continue } } ]; //~ ERROR mismatched types
5+
| ^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| expected usize, found reference
8+
| help: consider removing the borrow: `{ loop { continue } }`
9+
|
10+
= note: expected type `usize`
11+
found type `&_`
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/issue-52443.rs:13:17
15+
|
16+
LL | [(); loop { break }]; //~ ERROR mismatched types
17+
| ^^^^^ expected (), found usize
18+
|
19+
= note: expected type `()`
20+
found type `usize`
21+
22+
error[E0019]: constant contains unimplemented expression type
23+
--> $DIR/issue-52443.rs:14:11
24+
|
25+
LL | [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
26+
| ^^^^^^^^^^^^^^^^^^
27+
28+
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
29+
--> $DIR/issue-52443.rs:15:21
30+
|
31+
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
32+
| ^^^^^^^^
33+
34+
error[E0019]: constant contains unimplemented expression type
35+
--> $DIR/issue-52443.rs:15:21
36+
|
37+
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
38+
| ^^^^^^^^
39+
40+
error[E0080]: could not evaluate repeat length
41+
--> $DIR/issue-52443.rs:15:10
42+
|
43+
LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
44+
| ^^^^^^^^^^^--------^^^^^^^
45+
| |
46+
| calling non-const fn `<I as std::iter::IntoIterator><std::ops::RangeFrom<usize>>::into_iter`
47+
48+
error: aborting due to 6 previous errors
49+
50+
Some errors occurred: E0015, E0019, E0080, E0308.
51+
For more information about an error, try `rustc --explain E0015`.

0 commit comments

Comments
 (0)