diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-05-08 19:09:25 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-05-08 19:09:25 +0100 |
commit | f9ec7cebef732fbc9d4849d87d325efef5faadea (patch) | |
tree | 4a40dbed04c432dee54f8a8d016c89c7411b1e6d /crates/ra_hir_ty/src/diagnostics.rs | |
parent | f1fa9aa4c4d4fcfe7d6e90ba9cefca90bc7c4998 (diff) | |
parent | d0129c4ddba3b72e7b26e94e9c25546d37dbf166 (diff) |
Merge #4377
4377: Implement better handling of divergence r=matklad a=flodiebold
Divergence here means that for some reason, the end of a block will not be reached. We tried to model this just using the never type, but that doesn't work fully (e.g. in `let x = { loop {}; "foo" };` x should still have type `&str`); so this introduces a `diverges` flag that the type checker keeps track of, like rustc does. We also add some checking for `break`, but no support for break-with-value or labeled breaks yet.
Co-authored-by: Florian Diebold <[email protected]>
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/diagnostics.rs')
-rw-r--r-- | crates/ra_hir_ty/src/diagnostics.rs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs index c8fd54861..41ac70272 100644 --- a/crates/ra_hir_ty/src/diagnostics.rs +++ b/crates/ra_hir_ty/src/diagnostics.rs | |||
@@ -131,3 +131,31 @@ impl AstDiagnostic for MissingOkInTailExpr { | |||
131 | ast::Expr::cast(node).unwrap() | 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 | } | ||