use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; // Diagnostic: break-outside-of-loop // // This diagnostic is triggered if the `break` keyword is used outside of a loop. pub(crate) fn break_outside_of_loop( ctx: &DiagnosticsContext<'_>, d: &hir::BreakOutsideOfLoop, ) -> Diagnostic { let message = if d.bad_value_break { "can't break with a value in this position".to_owned() } else { let construct = if d.is_break { "break" } else { "continue" }; format!("{construct} outside of loop") }; Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0268"), message, d.expr.map(|it| it.into()), ) } #[cfg(test)] mod tests { use crate::tests::check_diagnostics; #[test] fn outside_of_loop() { check_diagnostics( r#" fn foo() { break; //^^^^^ error: break outside of loop continue; //^^^^^^^^ error: continue outside of loop } "#, ); } #[test] fn async_blocks_are_borders() { check_diagnostics( r#" fn foo() { 'a: loop { async { break; //^^^^^ error: break outside of loop continue; //^^^^^^^^ error: continue outside of loop }; } } "#, ); } #[test] fn closures_are_borders() { check_diagnostics( r#" fn foo() { 'a: loop { || { break; //^^^^^ error: break outside of loop continue; //^^^^^^^^ error: continue outside of loop }; } } "#, ); } #[test] fn blocks_pass_through() { check_diagnostics( r#" fn foo() { 'a: loop { { break; continue; } } } "#, ); } #[test] fn try_blocks_pass_through() { check_diagnostics( r#" fn foo() { 'a: loop { try { break; continue; }; } } "#, ); } #[test] fn label_blocks() { check_diagnostics( r#" fn foo() { 'a: { break; //^^^^^ error: break outside of loop continue; //^^^^^^^^ error: continue outside of loop } } "#, ); } #[test] fn value_break_in_for_loop() { // FIXME: the error is correct, but the message is terrible check_diagnostics( r#" //- minicore: iterator fn test() { for _ in [()] { break 3; // ^ error: expected (), found i32 } } "#, ); } #[test] fn try_block_desugaring_inside_closure() { // regression test for #14701 check_diagnostics( r#" //- minicore: option, try fn test() { try { || { let x = Some(2); Some(x?) }; }; } "#, ); } }