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 {
131
131
ast:: Expr :: cast ( node) . unwrap ( )
132
132
}
133
133
}
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 {
717
717
use hir_def:: { expr:: ExprId , FunctionId } ;
718
718
use hir_expand:: diagnostics:: DiagnosticSink ;
719
719
720
- use crate :: { db:: HirDatabase , diagnostics:: NoSuchField } ;
720
+ use crate :: {
721
+ db:: HirDatabase ,
722
+ diagnostics:: { BreakOutsideOfLoop , NoSuchField } ,
723
+ } ;
721
724
722
725
#[ derive( Debug , PartialEq , Eq , Clone ) ]
723
726
pub ( super ) enum InferenceDiagnostic {
724
727
NoSuchField { expr : ExprId , field : usize } ,
728
+ BreakOutsideOfLoop { expr : ExprId } ,
725
729
}
726
730
727
731
impl InferenceDiagnostic {
@@ -737,6 +741,13 @@ mod diagnostics {
737
741
let field = source_map. field_syntax ( * expr, * field) ;
738
742
sink. push ( NoSuchField { file : field. file_id , field : field. value } )
739
743
}
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
+ }
740
751
}
741
752
}
742
753
}
Original file line number Diff line number Diff line change @@ -235,6 +235,10 @@ impl<'a> InferenceContext<'a> {
235
235
}
236
236
if let Some ( ctxt) = self . breakables . last_mut ( ) {
237
237
ctxt. may_break = true ;
238
+ } else {
239
+ self . push_diagnostic ( InferenceDiagnostic :: BreakOutsideOfLoop {
240
+ expr : tgt_expr,
241
+ } ) ;
238
242
}
239
243
Ty :: simple ( TypeCtor :: Never )
240
244
}
Original file line number Diff line number Diff line change @@ -518,3 +518,21 @@ fn missing_record_pat_field_no_diagnostic_if_not_exhaustive() {
518
518
519
519
assert_snapshot ! ( diagnostics, @"" ) ;
520
520
}
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