diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index e59e50ae9e698..2365bdda932fb 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -103,6 +103,7 @@ 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 @@ -230,6 +231,7 @@ 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(), @@ -968,31 +970,30 @@ impl<'a> LoweringContext<'a> { } fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination { - match destination { - Some((id, label)) => { - let target_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) - }; - hir::Destination { - label: self.lower_label(Some(label)), - target_id, + 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 => { - let target_id = 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: None, - target_id, + 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)), + target_id, } } @@ -3440,13 +3441,22 @@ impl<'a> LoweringContext<'a> { } fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst { - let LoweredNodeId { node_id, hir_id } = self.lower_node_id(c.id); + 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; - hir::AnonConst { + 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 } fn lower_expr(&mut self, e: &Expr) -> hir::Expr { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 6ccf09f4dfc4f..a83aa47fd4f13 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -840,6 +840,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) { debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat); + let tcx = self.tcx(); let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self; return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| { if let PatKind::Binding(_, canonical_id, ..) = pat.node { @@ -849,34 +850,36 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { pat, match_mode, ); - let bm = *mc.tables.pat_binding_modes().get(pat.hir_id) - .expect("missing binding mode"); - debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); - - // pat_ty: the type of the binding being produced. - let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); - debug!("walk_pat: pat_ty={:?}", pat_ty); - - // Each match binding is effectively an assignment to the - // binding being produced. - let def = Def::Local(canonical_id); - if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) { - delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init); - } + if let Some(&bm) = mc.tables.pat_binding_modes().get(pat.hir_id) { + debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm); + + // pat_ty: the type of the binding being produced. + let pat_ty = return_if_err!(mc.node_ty(pat.hir_id)); + debug!("walk_pat: pat_ty={:?}", pat_ty); + + // Each match binding is effectively an assignment to the + // binding being produced. + let def = Def::Local(canonical_id); + if let Ok(ref binding_cmt) = mc.cat_def(pat.hir_id, pat.span, pat_ty, def) { + delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init); + } - // It is also a borrow or copy/move of the value being matched. - match bm { - ty::BindByReference(m) => { - if let ty::TyRef(r, _, _) = pat_ty.sty { - let bk = ty::BorrowKind::from_mutbl(m); - delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding); + // It is also a borrow or copy/move of the value being matched. + match bm { + ty::BindByReference(m) => { + if let ty::TyRef(r, _, _) = pat_ty.sty { + let bk = ty::BorrowKind::from_mutbl(m); + delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding); + } + } + ty::BindByValue(..) => { + let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove); + debug!("walk_pat binding consuming pat"); + delegate.consume_pat(pat, &cmt_pat, mode); } } - ty::BindByValue(..) => { - let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove); - debug!("walk_pat binding consuming pat"); - delegate.consume_pat(pat, &cmt_pat, mode); - } + } else { + tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } } })); diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index f5c2a0c3f9f05..a32fdbb285d12 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1115,12 +1115,12 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { } tcx.layout_raw(param_env.and(normalized))? } - ty::TyParam(_) => { - return Err(LayoutError::Unknown(ty)); - } - ty::TyGeneratorWitness(..) | ty::TyInfer(_) | ty::TyError => { + ty::TyGeneratorWitness(..) | ty::TyInfer(_) => { bug!("LayoutDetails::compute: unexpected type `{}`", ty) } + ty::TyParam(_) | ty::TyError => { + return Err(LayoutError::Unknown(ty)); + } }) } diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs index 294ae1e63a9ee..475ff0b744349 100644 --- a/src/librustc_borrowck/borrowck/unused.rs +++ b/src/librustc_borrowck/borrowck/unused.rs @@ -54,16 +54,16 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> { // Skip anything that looks like `&foo` or `&mut foo`, only look // for by-value bindings - let bm = match self.bccx.tables.pat_binding_modes().get(hir_id) { - Some(&bm) => bm, - None => span_bug!(span, "missing binding mode"), - }; - match bm { - ty::BindByValue(hir::MutMutable) => {} - _ => return, + if let Some(&bm) = self.bccx.tables.pat_binding_modes().get(hir_id) { + match bm { + ty::BindByValue(hir::MutMutable) => {} + _ => return, + } + + mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span)); + } else { + tcx.sess.delay_span_bug(span, "missing binding mode"); } - - mutables.entry(ident.name).or_insert(Vec::new()).push((hir_id, span)); }); } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 4db5c8e9278e5..cdf0079e2ae83 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -541,13 +541,14 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>, if let hir::PatKind::Binding(_, _, ident, _) = pat.node { decl.debug_name = ident.name; - let bm = *hir.tables.pat_binding_modes() - .get(pat.hir_id) - .expect("missing binding mode"); - if bm == ty::BindByValue(hir::MutMutable) { - decl.mutability = Mutability::Mut; + if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) { + if bm == ty::BindByValue(hir::MutMutable) { + decl.mutability = Mutability::Mut; + } else { + decl.mutability = Mutability::Not; + } } else { - decl.mutability = Mutability::Not; + tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } } } diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs index b9d6486d9174a..502091e519201 100644 --- a/src/librustc_mir/build/scope.rs +++ b/src/librustc_mir/build/scope.rs @@ -541,9 +541,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { /// Finds the breakable scope for a given label. This is used for /// resolving `break` and `continue`. pub fn find_breakable_scope(&self, - span: Span, - label: region::Scope) - -> &BreakableScope<'tcx> { + span: Span, + label: region::Scope) + -> &BreakableScope<'tcx> { // find the loop-scope with the correct id self.breakable_scopes.iter() .rev() diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index e04cdcfa02773..18ae7c7745915 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -309,33 +309,32 @@ impl<'a, 'tcx> MatchVisitor<'a, 'tcx> { fn check_for_bindings_named_the_same_as_variants(cx: &MatchVisitor, pat: &Pat) { pat.walk(|p| { if let PatKind::Binding(_, _, ident, None) = p.node { - let bm = *cx.tables - .pat_binding_modes() - .get(p.hir_id) - .expect("missing binding mode"); - - if bm != ty::BindByValue(hir::MutImmutable) { - // Nothing to check. - return true; - } - let pat_ty = cx.tables.pat_ty(p); - if let ty::TyAdt(edef, _) = pat_ty.sty { - if edef.is_enum() && edef.variants.iter().any(|variant| { - variant.name == ident.name && variant.ctor_kind == CtorKind::Const - }) { - let ty_path = cx.tcx.item_path_str(edef.did); - let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, - "pattern binding `{}` is named the same as one \ - of the variants of the type `{}`", - ident, ty_path); - err.span_suggestion_with_applicability( - p.span, - "to match on the variant, qualify the path", - format!("{}::{}", ty_path, ident), - Applicability::MachineApplicable - ); - err.emit(); + if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { + if bm != ty::BindByValue(hir::MutImmutable) { + // Nothing to check. + return true; } + let pat_ty = cx.tables.pat_ty(p); + if let ty::TyAdt(edef, _) = pat_ty.sty { + if edef.is_enum() && edef.variants.iter().any(|variant| { + variant.name == ident.name && variant.ctor_kind == CtorKind::Const + }) { + let ty_path = cx.tcx.item_path_str(edef.did); + let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, + "pattern binding `{}` is named the same as one \ + of the variants of the type `{}`", + ident, ty_path); + err.span_suggestion_with_applicability( + p.span, + "to match on the variant, qualify the path", + format!("{}::{}", ty_path, ident), + Applicability::MachineApplicable + ); + err.emit(); + } + } + } else { + cx.tcx.sess.delay_span_bug(p.span, "missing binding mode"); } } true @@ -517,12 +516,12 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, let mut by_ref_span = None; for pat in pats { pat.each_binding(|_, hir_id, span, _path| { - let bm = *cx.tables - .pat_binding_modes() - .get(hir_id) - .expect("missing binding mode"); - if let ty::BindByReference(..) = bm { - by_ref_span = Some(span); + if let Some(&bm) = cx.tables.pat_binding_modes().get(hir_id) { + if let ty::BindByReference(..) = bm { + by_ref_span = Some(span); + } + } else { + cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } }) } @@ -553,18 +552,18 @@ fn check_legality_of_move_bindings(cx: &MatchVisitor, for pat in pats { pat.walk(|p| { if let PatKind::Binding(_, _, _, ref sub) = p.node { - let bm = *cx.tables - .pat_binding_modes() - .get(p.hir_id) - .expect("missing binding mode"); - match bm { - ty::BindByValue(..) => { - let pat_ty = cx.tables.node_id_to_type(p.hir_id); - if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { - check_move(p, sub.as_ref().map(|p| &**p)); + if let Some(&bm) = cx.tables.pat_binding_modes().get(p.hir_id) { + match bm { + ty::BindByValue(..) => { + let pat_ty = cx.tables.node_id_to_type(p.hir_id); + if pat_ty.moves_by_default(cx.tcx, cx.param_env, pat.span) { + check_move(p, sub.as_ref().map(|p| &**p)); + } } + _ => {} } - _ => {} + } else { + cx.tcx.sess.delay_span_bug(pat.span, "missing binding mode"); } } true diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 4d0e3e826e878..636969e263222 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -743,8 +743,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ); *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind }, - Err(()) => { - self.errors.push(PatternError::FloatBug); + Err(e) => { + if e == LitToConstError::UnparseableFloat { + self.errors.push(PatternError::FloatBug); + } PatternKind::Wild }, } @@ -764,8 +766,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { ); *self.const_to_pat(instance, val, expr.hir_id, lit.span).kind }, - Err(()) => { - self.errors.push(PatternError::FloatBug); + Err(e) => { + if e == LitToConstError::UnparseableFloat { + self.errors.push(PatternError::FloatBug); + } PatternKind::Wild }, } @@ -1118,12 +1122,18 @@ pub fn compare_const_vals<'a, 'tcx>( fallback() } +#[derive(PartialEq)] +enum LitToConstError { + UnparseableFloat, + Propagated, +} + // FIXME: Combine with rustc_mir::hair::cx::const_eval_literal fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>, neg: bool) - -> Result<&'tcx ty::Const<'tcx>, ()> { + -> Result<&'tcx ty::Const<'tcx>, LitToConstError> { use syntax::ast::*; use rustc::mir::interpret::*; @@ -1152,7 +1162,10 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, ty::TyInt(other) => Int::Signed(other), ty::TyUint(UintTy::Usize) => Int::Unsigned(tcx.sess.target.usize_ty), ty::TyUint(other) => Int::Unsigned(other), - _ => bug!(), + ty::TyError => { // Avoid ICE (#51963) + return Err(LitToConstError::Propagated); + } + _ => bug!("literal integer type with bad type ({:?})", ty.sty), }; // This converts from LitKind::Int (which is sign extended) to // Scalar::Bytes (which is zero extended) @@ -1182,14 +1195,14 @@ fn lit_to_const<'a, 'tcx>(lit: &'tcx ast::LitKind, }) }, LitKind::Float(n, fty) => { - parse_float(n, fty, neg)? + parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)? } LitKind::FloatUnsuffixed(n) => { let fty = match ty.sty { ty::TyFloat(fty) => fty, _ => bug!() }; - parse_float(n, fty, neg)? + parse_float(n, fty, neg).map_err(|_| LitToConstError::UnparseableFloat)? } LitKind::Bool(b) => ConstValue::Scalar(Scalar::Bits { bits: b as u128, diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index c99f1e9da439f..eff0dbe1235ff 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -17,7 +17,7 @@ use rustc::hir::{self, Destination}; use syntax::ast; use syntax_pos::Span; -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] enum LoopKind { Loop(hir::LoopSource), WhileLoop, @@ -34,12 +34,13 @@ impl LoopKind { } } -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] enum Context { Normal, Loop(LoopKind), Closure, LabeledBlock, + AnonConst, } #[derive(Copy, Clone)] @@ -71,6 +72,10 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { self.with_context(Normal, |v| intravisit::walk_impl_item(v, i)); } + fn visit_anon_const(&mut self, c: &'hir hir::AnonConst) { + self.with_context(AnonConst, |v| intravisit::walk_anon_const(v, c)); + } + fn visit_expr(&mut self, e: &'hir hir::Expr) { match e.node { hir::ExprWhile(ref e, ref b, _) => { @@ -194,7 +199,7 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { .span_label(span, "cannot break inside of a closure") .emit(); } - Normal => { + Normal | AnonConst => { struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name) .span_label(span, "cannot break outside of a loop") .emit(); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fa78b38dbb7a8..646c4f17568f0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3827,7 +3827,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // this can only happen if the `break` was not // inside a loop at all, which is caught by the // loop-checking pass. - assert!(self.tcx.sess.err_count() > 0); + if self.tcx.sess.err_count() == 0 { + self.tcx.sess.delay_span_bug(expr.span, + "break was outside loop, but no error was emitted"); + } // We still need to assign a type to the inner expression to // prevent the ICE in #43162. @@ -3960,7 +3963,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // is nil. This makes sense because infinite loops // (which would have type !) are only possible iff we // permit break with a value [1]. - assert!(ctxt.coerce.is_some() || ctxt.may_break); // [1] + if ctxt.coerce.is_none() && !ctxt.may_break { + // [1] + self.tcx.sess.delay_span_bug(body.span, "no coercion, but loop may not break"); + } ctxt.coerce.map(|c| c.complete(self)).unwrap_or(self.tcx.mk_nil()) } hir::ExprMatch(ref discrim, ref arms, match_src) => { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index e489c4d4a46be..68fcde0b1657a 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1039,11 +1039,13 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { match sub_pat.node { // `ref x` pattern PatKind::Binding(..) => { - let bm = *mc.tables.pat_binding_modes().get(sub_pat.hir_id) - .expect("missing binding mode"); - if let ty::BindByReference(mutbl) = bm { - self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id, - mutbl, &sub_cmt); + if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) { + if let ty::BindByReference(mutbl) = bm { + self.link_region_from_node_type(sub_pat.span, sub_pat.hir_id, + mutbl, &sub_cmt); + } + } else { + self.tcx.sess.delay_span_bug(sub_pat.span, "missing binding mode"); } } _ => {} diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index f7d1e40794580..2445cae98607a 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -257,13 +257,11 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> { fn visit_pat(&mut self, p: &'gcx hir::Pat) { match p.node { hir::PatKind::Binding(..) => { - let bm = *self.fcx - .tables - .borrow() - .pat_binding_modes() - .get(p.hir_id) - .expect("missing binding mode"); - self.tables.pat_binding_modes_mut().insert(p.hir_id, bm); + if let Some(&bm) = self.fcx.tables.borrow().pat_binding_modes().get(p.hir_id) { + self.tables.pat_binding_modes_mut().insert(p.hir_id, bm); + } else { + self.tcx().sess.delay_span_bug(p.span, "missing binding mode"); + } } hir::PatKind::Struct(_, ref fields, _) => { for field in fields { diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs new file mode 100644 index 0000000000000..c3cfff0e1f642 --- /dev/null +++ b/src/test/ui/array-break-length.rs @@ -0,0 +1,19 @@ +// 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]| {} //~ ERROR: `break` outside of loop + } + + loop { + |_: [_; continue]| {} //~ ERROR: `continue` outside of loop + } +} diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr new file mode 100644 index 0000000000000..114245b9cc77b --- /dev/null +++ b/src/test/ui/array-break-length.stderr @@ -0,0 +1,15 @@ +error[E0268]: `break` outside of loop + --> $DIR/array-break-length.rs:13:17 + | +LL | |_: [_; break]| {} //~ ERROR: `break` outside of loop + | ^^^^^ cannot break outside of a loop + +error[E0268]: `continue` outside of loop + --> $DIR/array-break-length.rs:17:17 + | +LL | |_: [_; continue]| {} //~ ERROR: `continue` outside of loop + | ^^^^^^^^ cannot break outside of a loop + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0268`. diff --git a/src/test/ui/closure-array-break-length.rs b/src/test/ui/closure-array-break-length.rs index 2e99921956ab2..8be5b925a399e 100644 --- a/src/test/ui/closure-array-break-length.rs +++ b/src/test/ui/closure-array-break-length.rs @@ -11,7 +11,7 @@ fn main() { |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop - while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label + while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop - while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label + while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop } diff --git a/src/test/ui/closure-array-break-length.stderr b/src/test/ui/closure-array-break-length.stderr index 139153992e274..f62b135437092 100644 --- a/src/test/ui/closure-array-break-length.stderr +++ b/src/test/ui/closure-array-break-length.stderr @@ -4,19 +4,18 @@ error[E0268]: `continue` outside of loop LL | |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop | ^^^^^^^^ cannot break outside of a loop -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop +error[E0268]: `continue` outside of loop --> $DIR/closure-array-break-length.rs:14:19 | -LL | while |_: [_; continue]| {} {} //~ ERROR: `break` or `continue` with no label - | ^^^^^^^^ unlabeled `continue` in the condition of a `while` loop +LL | while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop + | ^^^^^^^^ cannot break outside of a loop -error[E0590]: `break` or `continue` with no label in the condition of a `while` loop +error[E0268]: `break` outside of loop --> $DIR/closure-array-break-length.rs:16:19 | -LL | while |_: [_; break]| {} {} //~ ERROR: `break` or `continue` with no label - | ^^^^^ unlabeled `break` in the condition of a `while` loop +LL | while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop + | ^^^^^ cannot break outside of a loop error: aborting due to 3 previous errors -Some errors occurred: E0268, E0590. -For more information about an error, try `rustc --explain E0268`. +For more information about this error, try `rustc --explain E0268`. diff --git a/src/test/ui/issue-51714.rs b/src/test/ui/issue-51714.rs index 96c5b92ddfdcc..2b9d51f81b988 100644 --- a/src/test/ui/issue-51714.rs +++ b/src/test/ui/issue-51714.rs @@ -9,11 +9,16 @@ // except according to those terms. fn main() { - |_: [_; return || {}] | {} + |_: [_; return || {}] | {}; //~^ ERROR return statement outside of function body -} -fn foo() { [(); return || {}]; //~^ ERROR return statement outside of function body + + [(); return |ice| {}]; + //~^ ERROR return statement outside of function body + + [(); return while let Some(n) = Some(0) {}]; + //~^ ERROR return statement outside of function body + //~^^ ERROR irrefutable while-let pattern } diff --git a/src/test/ui/issue-51714.stderr b/src/test/ui/issue-51714.stderr index 746adea6b7ed7..ddc70bfb38e01 100644 --- a/src/test/ui/issue-51714.stderr +++ b/src/test/ui/issue-51714.stderr @@ -1,15 +1,34 @@ error[E0572]: return statement outside of function body --> $DIR/issue-51714.rs:12:14 | -LL | |_: [_; return || {}] | {} +LL | |_: [_; return || {}] | {}; | ^^^^^^^^^^^^ error[E0572]: return statement outside of function body - --> $DIR/issue-51714.rs:17:10 + --> $DIR/issue-51714.rs:15:10 | LL | [(); return || {}]; | ^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0572]: return statement outside of function body + --> $DIR/issue-51714.rs:18:10 + | +LL | [(); return |ice| {}]; + | ^^^^^^^^^^^^^^^ + +error[E0572]: return statement outside of function body + --> $DIR/issue-51714.rs:21:10 + | +LL | [(); return while let Some(n) = Some(0) {}]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0165]: irrefutable while-let pattern + --> $DIR/issue-51714.rs:21:27 + | +LL | [(); return while let Some(n) = Some(0) {}]; + | ^^^^^^^ irrefutable pattern + +error: aborting due to 5 previous errors -For more information about this error, try `rustc --explain E0572`. +Some errors occurred: E0165, E0572. +For more information about an error, try `rustc --explain E0165`. diff --git a/src/test/ui/return-match-array-const.rs b/src/test/ui/return-match-array-const.rs new file mode 100644 index 0000000000000..45fc571d79d56 --- /dev/null +++ b/src/test/ui/return-match-array-const.rs @@ -0,0 +1,17 @@ +// 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() { + [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body + + [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body + + [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body +} diff --git a/src/test/ui/return-match-array-const.stderr b/src/test/ui/return-match-array-const.stderr new file mode 100644 index 0000000000000..044dc8f51455f --- /dev/null +++ b/src/test/ui/return-match-array-const.stderr @@ -0,0 +1,21 @@ +error[E0572]: return statement outside of function body + --> $DIR/return-match-array-const.rs:12:10 + | +LL | [(); return match 0 { n => n }]; //~ ERROR: return statement outside of function body + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0572]: return statement outside of function body + --> $DIR/return-match-array-const.rs:14:10 + | +LL | [(); return match 0 { 0 => 0 }]; //~ ERROR: return statement outside of function body + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0572]: return statement outside of function body + --> $DIR/return-match-array-const.rs:16:10 + | +LL | [(); return match () { 'a' => 0, _ => 0 }]; //~ ERROR: return statement outside of function body + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0572`.