diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 93fb282546bb..313f4af762f4 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -103,7 +103,6 @@ pub struct LoweringContext<'a> { loop_scopes: Vec, is_in_loop_condition: bool, is_in_trait_impl: bool, - is_in_anon_const: bool, /// What to do when we encounter either an "anonymous lifetime /// reference". The term "anonymous" is meant to encompass both @@ -231,7 +230,6 @@ pub fn lower_crate( node_id_to_hir_id: IndexVec::new(), is_generator: false, is_in_trait_impl: false, - is_in_anon_const: false, lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, in_scope_lifetimes: Vec::new(), @@ -970,26 +968,22 @@ impl<'a> LoweringContext<'a> { } fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination { - let target_id = if self.is_in_anon_const { - Err(hir::LoopIdError::OutsideLoopScope) - } else { - match destination { - Some((id, _)) => { - if let Def::Label(loop_id) = self.expect_full_def(id) { - Ok(self.lower_node_id(loop_id).node_id) - } else { - Err(hir::LoopIdError::UnresolvedLabel) - } - } - None => { - self.loop_scopes - .last() - .map(|innermost_loop_id| *innermost_loop_id) - .map(|id| Ok(self.lower_node_id(id).node_id)) - .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope)) - .into() + let target_id = match destination { + Some((id, _)) => { + if let Def::Label(loop_id) = self.expect_full_def(id) { + Ok(self.lower_node_id(loop_id).node_id) + } else { + Err(hir::LoopIdError::UnresolvedLabel) } } + None => { + self.loop_scopes + .last() + .map(|innermost_loop_id| *innermost_loop_id) + .map(|id| Ok(self.lower_node_id(id).node_id)) + .unwrap_or(Err(hir::LoopIdError::OutsideLoopScope)) + .into() + } }; hir::Destination { label: self.lower_label(destination.map(|(_, label)| label)), @@ -3448,22 +3442,14 @@ impl<'a> LoweringContext<'a> { } fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { - let was_in_loop_condition = self.is_in_loop_condition; - self.is_in_loop_condition = false; - let was_in_anon_const = self.is_in_anon_const; - self.is_in_anon_const = true; - - let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id); - let anon_const = hir::AnonConst { - id: node_id, - hir_id, - body: self.lower_body(None, |this| this.lower_expr(&c.value)), - }; - - self.is_in_anon_const = was_in_anon_const; - self.is_in_loop_condition = was_in_loop_condition; - - anon_const + self.with_new_scopes(|this| { + let LoweredNodeId { node_id, hir_id } = this.lower_node_id(c.id); + hir::AnonConst { + id: node_id, + hir_id, + body: this.lower_body(None, |this| this.lower_expr(&c.value)), + } + }) } fn lower_expr(&mut self, e: &Expr) -> hir::Expr { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 177e4ed8cf37..f3e8a04e2ee3 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2358,7 +2358,9 @@ impl<'a> Resolver<'a> { where F: FnOnce(&mut Resolver) { self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); + self.label_ribs.push(Rib::new(ConstantItemRibKind)); f(self); + self.label_ribs.pop(); self.ribs[ValueNS].pop(); } diff --git a/src/test/ui/const-eval/issue-52442.rs b/src/test/ui/const-eval/issue-52442.rs new file mode 100644 index 000000000000..755dc153d405 --- /dev/null +++ b/src/test/ui/const-eval/issue-52442.rs @@ -0,0 +1,13 @@ +// Copyright 2018 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 main() { + [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type +} diff --git a/src/test/ui/const-eval/issue-52442.stderr b/src/test/ui/const-eval/issue-52442.stderr new file mode 100644 index 000000000000..586c9fa22cec --- /dev/null +++ b/src/test/ui/const-eval/issue-52442.stderr @@ -0,0 +1,9 @@ +error[E0019]: constant contains unimplemented expression type + --> $DIR/issue-52442.rs:12:14 + | +LL | [(); { &loop { break } as *const _ as usize } ]; //~ ERROR unimplemented expression type + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0019`. diff --git a/src/test/ui/const-eval/issue-52443.rs b/src/test/ui/const-eval/issue-52443.rs new file mode 100644 index 000000000000..2ae94f6d6420 --- /dev/null +++ b/src/test/ui/const-eval/issue-52443.rs @@ -0,0 +1,18 @@ +// Copyright 2018 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 main() { + [(); & { loop { continue } } ]; //~ ERROR mismatched types + [(); loop { break }]; //~ ERROR mismatched types + [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type + [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions + //~^ ERROR constant contains unimplemented expression type + //~| ERROR could not evaluate repeat length +} diff --git a/src/test/ui/const-eval/issue-52443.stderr b/src/test/ui/const-eval/issue-52443.stderr new file mode 100644 index 000000000000..3a145ba78d9b --- /dev/null +++ b/src/test/ui/const-eval/issue-52443.stderr @@ -0,0 +1,51 @@ +error[E0308]: mismatched types + --> $DIR/issue-52443.rs:12:10 + | +LL | [(); & { loop { continue } } ]; //~ ERROR mismatched types + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | expected usize, found reference + | help: consider removing the borrow: `{ loop { continue } }` + | + = note: expected type `usize` + found type `&_` + +error[E0308]: mismatched types + --> $DIR/issue-52443.rs:13:17 + | +LL | [(); loop { break }]; //~ ERROR mismatched types + | ^^^^^ expected (), found usize + | + = note: expected type `()` + found type `usize` + +error[E0019]: constant contains unimplemented expression type + --> $DIR/issue-52443.rs:14:11 + | +LL | [(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type + | ^^^^^^^^^^^^^^^^^^ + +error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants + --> $DIR/issue-52443.rs:15:21 + | +LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions + | ^^^^^^^^ + +error[E0019]: constant contains unimplemented expression type + --> $DIR/issue-52443.rs:15:21 + | +LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions + | ^^^^^^^^ + +error[E0080]: could not evaluate repeat length + --> $DIR/issue-52443.rs:15:10 + | +LL | [(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions + | ^^^^^^^^^^^--------^^^^^^^ + | | + | calling non-const fn `>::into_iter` + +error: aborting due to 6 previous errors + +Some errors occurred: E0015, E0019, E0080, E0308. +For more information about an error, try `rustc --explain E0015`.