File tree Expand file tree Collapse file tree 4 files changed +62
-1
lines changed Expand file tree Collapse file tree 4 files changed +62
-1
lines changed Original file line number Diff line number Diff line change @@ -131,3 +131,31 @@ impl AstDiagnostic for MissingOkInTailExpr {
131131 ast:: Expr :: cast ( node) . unwrap ( )
132132 }
133133}
134+
135+ #[ derive( Debug ) ]
136+ pub struct BreakOutsideOfLoop {
137+ pub file : HirFileId ,
138+ pub expr : AstPtr < ast:: Expr > ,
139+ }
140+
141+ impl Diagnostic for BreakOutsideOfLoop {
142+ fn message ( & self ) -> String {
143+ "break outside of loop" . to_string ( )
144+ }
145+ fn source ( & self ) -> InFile < SyntaxNodePtr > {
146+ InFile { file_id : self . file , value : self . expr . clone ( ) . into ( ) }
147+ }
148+ fn as_any ( & self ) -> & ( dyn Any + Send + ' static ) {
149+ self
150+ }
151+ }
152+
153+ impl AstDiagnostic for BreakOutsideOfLoop {
154+ type AST = ast:: Expr ;
155+
156+ fn ast ( & self , db : & impl AstDatabase ) -> Self :: AST {
157+ let root = db. parse_or_expand ( self . file ) . unwrap ( ) ;
158+ let node = self . source ( ) . value . to_node ( & root) ;
159+ ast:: Expr :: cast ( node) . unwrap ( )
160+ }
161+ }
Original file line number Diff line number Diff line change @@ -717,11 +717,15 @@ mod diagnostics {
717717 use hir_def:: { expr:: ExprId , FunctionId } ;
718718 use hir_expand:: diagnostics:: DiagnosticSink ;
719719
720- use crate :: { db:: HirDatabase , diagnostics:: NoSuchField } ;
720+ use crate :: {
721+ db:: HirDatabase ,
722+ diagnostics:: { BreakOutsideOfLoop , NoSuchField } ,
723+ } ;
721724
722725 #[ derive( Debug , PartialEq , Eq , Clone ) ]
723726 pub ( super ) enum InferenceDiagnostic {
724727 NoSuchField { expr : ExprId , field : usize } ,
728+ BreakOutsideOfLoop { expr : ExprId } ,
725729 }
726730
727731 impl InferenceDiagnostic {
@@ -737,6 +741,13 @@ mod diagnostics {
737741 let field = source_map. field_syntax ( * expr, * field) ;
738742 sink. push ( NoSuchField { file : field. file_id , field : field. value } )
739743 }
744+ InferenceDiagnostic :: BreakOutsideOfLoop { expr } => {
745+ let ( _, source_map) = db. body_with_source_map ( owner. into ( ) ) ;
746+ let ptr = source_map
747+ . expr_syntax ( * expr)
748+ . expect ( "break outside of loop in synthetic syntax" ) ;
749+ sink. push ( BreakOutsideOfLoop { file : ptr. file_id , expr : ptr. value } )
750+ }
740751 }
741752 }
742753 }
Original file line number Diff line number Diff line change @@ -235,6 +235,10 @@ impl<'a> InferenceContext<'a> {
235235 }
236236 if let Some ( ctxt) = self . breakables . last_mut ( ) {
237237 ctxt. may_break = true ;
238+ } else {
239+ self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
240+ expr : tgt_expr,
241+ } ) ;
238242 }
239243 Ty :: simple ( TypeCtor :: Never )
240244 }
Original file line number Diff line number Diff line change @@ -518,3 +518,21 @@ fn missing_record_pat_field_no_diagnostic_if_not_exhaustive() {
518518
519519 assert_snapshot ! ( diagnostics, @"" ) ;
520520}
521+
522+ #[ test]
523+ fn break_outside_of_loop ( ) {
524+ let diagnostics = TestDB :: with_files (
525+ r"
526+ //- /lib.rs
527+ fn foo() {
528+ break;
529+ }
530+ " ,
531+ )
532+ . diagnostics ( )
533+ . 0 ;
534+
535+ assert_snapshot ! ( diagnostics, @r###""break": break outside of loop
536+ "###
537+ ) ;
538+ }
You can’t perform that action at this time.
0 commit comments