Repository: rust-analyzer/rust-analyzer
Pull request #4671 (2020-05-31 13:15:57)

docs


bors r+
🤖

bors[bot]: Canceled.
matklad: bors r+
bors[bot]: Canceled.

Patch:
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index f159f80af0..905c0cf5da 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -134,7 +134,7 @@ impl ExprCollector<'_> {
         self.make_expr(expr, Err(SyntheticSyntax))
     }
     fn empty_block(&mut self) -> ExprId {
-        self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None, label: None })
+        self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None })
     }
     fn missing_expr(&mut self) -> ExprId {
         self.alloc_expr_desugared(Expr::Missing)
@@ -215,16 +215,7 @@ impl ExprCollector<'_> {
             ast::Expr::BlockExpr(e) => self.collect_block(e),
             ast::Expr::LoopExpr(e) => {
                 let body = self.collect_block_opt(e.loop_body());
-                self.alloc_expr(
-                    Expr::Loop {
-                        body,
-                        label: e
-                            .label()
-                            .and_then(|l| l.lifetime_token())
-                            .map(|l| Name::new_lifetime(&l)),
-                    },
-                    syntax_ptr,
-                )
+                self.alloc_expr(Expr::Loop { body }, syntax_ptr)
             }
             ast::Expr::WhileExpr(e) => {
                 let body = self.collect_block_opt(e.loop_body());
@@ -239,56 +230,25 @@ impl ExprCollector<'_> {
                             let pat = self.collect_pat(pat);
                             let match_expr = self.collect_expr_opt(condition.expr());
                             let placeholder_pat = self.missing_pat();
-                            let break_ =
-                                self.alloc_expr_desugared(Expr::Break { expr: None, label: None });
+                            let break_ = self.alloc_expr_desugared(Expr::Break { expr: None });
                             let arms = vec![
                                 MatchArm { pat, expr: body, guard: None },
                                 MatchArm { pat: placeholder_pat, expr: break_, guard: None },
                             ];
                             let match_expr =
                                 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
-                            return self.alloc_expr(
-                                Expr::Loop {
-                                    body: match_expr,
-                                    label: e
-                                        .label()
-                                        .and_then(|l| l.lifetime_token())
-                                        .map(|l| Name::new_lifetime(&l)),
-                                },
-                                syntax_ptr,
-                            );
+                            return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr);
                         }
                     },
                 };
 
-                self.alloc_expr(
-                    Expr::While {
-                        condition,
-                        body,
-                        label: e
-                            .label()
-                            .and_then(|l| l.lifetime_token())
-                            .map(|l| Name::new_lifetime(&l)),
-                    },
-                    syntax_ptr,
-                )
+                self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
             }
             ast::Expr::ForExpr(e) => {
                 let iterable = self.collect_expr_opt(e.iterable());
                 let pat = self.collect_pat_opt(e.pat());
                 let body = self.collect_block_opt(e.loop_body());
-                self.alloc_expr(
-                    Expr::For {
-                        iterable,
-                        pat,
-                        body,
-                        label: e
-                            .label()
-                            .and_then(|l| l.lifetime_token())
-                            .map(|l| Name::new_lifetime(&l)),
-                    },
-                    syntax_ptr,
-                )
+                self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr)
             }
             ast::Expr::CallExpr(e) => {
                 let callee = self.collect_expr_opt(e.expr());
@@ -341,16 +301,13 @@ impl ExprCollector<'_> {
                     .unwrap_or(Expr::Missing);
                 self.alloc_expr(path, syntax_ptr)
             }
-            ast::Expr::ContinueExpr(e) => self.alloc_expr(
-                Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
-                syntax_ptr,
-            ),
+            ast::Expr::ContinueExpr(_e) => {
+                // FIXME: labels
+                self.alloc_expr(Expr::Continue, syntax_ptr)
+            }
             ast::Expr::BreakExpr(e) => {
                 let expr = e.expr().map(|e| self.collect_expr(e));
-                self.alloc_expr(
-                    Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
-                    syntax_ptr,
-                )
+                self.alloc_expr(Expr::Break { expr }, syntax_ptr)
             }
             ast::Expr::ParenExpr(e) => {
                 let inner = self.collect_expr_opt(e.expr());
@@ -572,8 +529,7 @@ impl ExprCollector<'_> {
             })
             .collect();
         let tail = block.expr().map(|e| self.collect_expr(e));
-        let label = block.label().and_then(|l| l.lifetime_token()).map(|t| Name::new_lifetime(&t));
-        self.alloc_expr(Expr::Block { statements, tail, label }, syntax_node_ptr)
+        self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
     }
 
     fn collect_block_items(&mut self, block: &ast::BlockExpr) {
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index e48ff38f96..09e92b74e1 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -138,10 +138,10 @@ fn compute_block_scopes(
 fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
     scopes.set_scope(expr, scope);
     match &body[expr] {
-        Expr::Block { statements, tail, .. } => {
+        Expr::Block { statements, tail } => {
             compute_block_scopes(&statements, *tail, body, scopes, scope);
         }
-        Expr::For { iterable, pat, body: body_expr, .. } => {
+        Expr::For { iterable, pat, body: body_expr } => {
             compute_expr_scopes(*iterable, body, scopes, scope);
             let scope = scopes.new_scope(scope);
             scopes.add_bindings(body, scope, *pat);
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index ca49b26d15..f25c6f9580 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -52,22 +52,18 @@ pub enum Expr {
     Block {
         statements: Vec<Statement>,
         tail: Option<ExprId>,
-        label: Option<Name>,
     },
     Loop {
         body: ExprId,
-        label: Option<Name>,
     },
     While {
         condition: ExprId,
         body: ExprId,
-        label: Option<Name>,
     },
     For {
         iterable: ExprId,
         pat: PatId,
         body: ExprId,
-        label: Option<Name>,
     },
     Call {
         callee: ExprId,
@@ -83,12 +79,9 @@ pub enum Expr {
         expr: ExprId,
         arms: Vec<MatchArm>,
     },
-    Continue {
-        label: Option<Name>,
-    },
+    Continue,
     Break {
         expr: Option<ExprId>,
-        label: Option<Name>,
     },
     Return {
         expr: Option<ExprId>,
@@ -232,7 +225,7 @@ impl Expr {
                     f(*else_branch);
                 }
             }
-            Expr::Block { statements, tail, .. } => {
+            Expr::Block { statements, tail } => {
                 for stmt in statements {
                     match stmt {
                         Statement::Let { initializer, .. } => {
@@ -248,8 +241,8 @@ impl Expr {
                 }
             }
             Expr::TryBlock { body } => f(*body),
-            Expr::Loop { body, .. } => f(*body),
-            Expr::While { condition, body, .. } => {
+            Expr::Loop { body } => f(*body),
+            Expr::While { condition, body } => {
                 f(*condition);
                 f(*body);
             }
@@ -275,8 +268,8 @@ impl Expr {
                     f(arm.expr);
                 }
             }
-            Expr::Continue { .. } => {}
-            Expr::Break { expr, .. } | Expr::Return { expr } => {
+            Expr::Continue => {}
+            Expr::Break { expr } | Expr::Return { expr } => {
                 if let Some(expr) = expr {
                     f(*expr);
                 }
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index ea495cb11a..fecce224ee 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -37,11 +37,6 @@ impl Name {
         Name(Repr::TupleField(idx))
     }
 
-    pub fn new_lifetime(lt: &ra_syntax::SyntaxToken) -> Name {
-        assert!(lt.kind() == ra_syntax::SyntaxKind::LIFETIME);
-        Name(Repr::Text(lt.text().clone()))
-    }
-
     /// Shortcut to create inline plain text name
     const fn new_inline_ascii(text: &[u8]) -> Name {
         Name::new_text(SmolStr::new_inline_from_ascii(text.len(), text))
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index dc77e88e50..957d6e0b57 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -219,17 +219,6 @@ struct InferenceContext<'a> {
 struct BreakableContext {
     pub may_break: bool,
     pub break_ty: Ty,
-    pub label: Option<name::Name>,
-}
-
-fn find_breakable<'c>(
-    ctxs: &'c mut [BreakableContext],
-    label: Option<&name::Name>,
-) -> Option<&'c mut BreakableContext> {
-    match label {
-        Some(_) => ctxs.iter_mut().rev().find(|ctx| ctx.label.as_ref() == label),
-        None => ctxs.last_mut(),
-    }
 }
 
 impl<'a> InferenceContext<'a> {
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 4a98e2debf..78084cb573 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -22,8 +22,8 @@ use crate::{
 };
 
 use super::{
-    find_breakable, BindingMode, BreakableContext, Diverges, Expectation, InferenceContext,
-    InferenceDiagnostic, TypeMismatch,
+    BindingMode, BreakableContext, Diverges, Expectation, InferenceContext, InferenceDiagnostic,
+    TypeMismatch,
 };
 
 impl<'a> InferenceContext<'a> {
@@ -86,20 +86,16 @@ impl<'a> InferenceContext<'a> {
 
                 self.coerce_merge_branch(&then_ty, &else_ty)
             }
-            Expr::Block { statements, tail, .. } => {
-                // FIXME: Breakable block inference
-                self.infer_block(statements, *tail, expected)
-            }
+            Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
             Expr::TryBlock { body } => {
                 let _inner = self.infer_expr(*body, expected);
                 // FIXME should be std::result::Result<{inner}, _>
                 Ty::Unknown
             }
-            Expr::Loop { body, label } => {
+            Expr::Loop { body } => {
                 self.breakables.push(BreakableContext {
                     may_break: false,
                     break_ty: self.table.new_type_var(),
-                    label: label.clone(),
                 });
                 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
 
@@ -114,12 +110,8 @@ impl<'a> InferenceContext<'a> {
                     Ty::simple(TypeCtor::Never)
                 }
             }
-            Expr::While { condition, body, label } => {
-                self.breakables.push(BreakableContext {
-                    may_break: false,
-                    break_ty: Ty::Unknown,
-                    label: label.clone(),
-                });
+            Expr::While { condition, body } => {
+                self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown });
                 // while let is desugared to a match loop, so this is always simple while
                 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool)));
                 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
@@ -128,14 +120,10 @@ impl<'a> InferenceContext<'a> {
                 self.diverges = Diverges::Maybe;
                 Ty::unit()
             }
-            Expr::For { iterable, body, pat, label } => {
+            Expr::For { iterable, body, pat } => {
                 let iterable_ty = self.infer_expr(*iterable, &Expectation::none());
 
-                self.breakables.push(BreakableContext {
-                    may_break: false,
-                    break_ty: Ty::Unknown,
-                    label: label.clone(),
-                });
+                self.breakables.push(BreakableContext { may_break: false, break_ty: Ty::Unknown });
                 let pat_ty =
                     self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
 
@@ -248,24 +236,23 @@ impl<'a> InferenceContext<'a> {
                 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
                 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
             }
-            Expr::Continue { .. } => Ty::simple(TypeCtor::Never),
-            Expr::Break { expr, label } => {
+            Expr::Continue => Ty::simple(TypeCtor::Never),
+            Expr::Break { expr } => {
                 let val_ty = if let Some(expr) = expr {
                     self.infer_expr(*expr, &Expectation::none())
                 } else {
                     Ty::unit()
                 };
 
-                let last_ty =
-                    if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
-                        ctxt.break_ty.clone()
-                    } else {
-                        Ty::Unknown
-                    };
+                let last_ty = if let Some(ctxt) = self.breakables.last() {
+                    ctxt.break_ty.clone()
+                } else {
+                    Ty::Unknown
+                };
 
                 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty);
 
-                if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
+                if let Some(ctxt) = self.breakables.last_mut() {
                     ctxt.break_ty = merged_type;
                     ctxt.may_break = true;
                 } else {
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index cb430ca013..255402fbce 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -1081,7 +1081,6 @@ pub struct BlockExpr {
 impl ast::AttrsOwner for BlockExpr {}
 impl ast::ModuleItemOwner for BlockExpr {}
 impl BlockExpr {
-    pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 27b3792135..202783fd95 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -2,12 +2,7 @@
 :toc: preamble
 :sectanchors:
 :page-layout: post
-// https://gist.github.com/dcode/0cfbf2699a1fe9b46ff04c41721dda74#admonitions
-:tip-caption: :bulb:
-:note-caption: :information_source:
-:important-caption: :heavy_exclamation_mark:
-:caution-caption: :fire:
-:warning-caption: :warning:
+:icons: font
 :source-highlighter: rouge
 :experimental:
 
@@ -67,16 +62,6 @@ The server binary is stored in:
 
 Note that we only support two most recent versions of VS Code.
 
-==== Special `when` clause context for keybindings.
-You may use `inRustProject` context to configure keybindings for rust projects only. For example:
-[source,json]
-----
-{ "key": "ctrl+shift+f5", "command": "workbench.action.debug.restart", "when": "inDebugMode && !inRustProject"},
-{ "key": "ctrl+shift+f5", "command": "rust-analyzer.debug", "when": "inRustProject"},
-{ "key": "ctrl+i", "command": "rust-analyzer.toggleInlayHints", "when": "inRustProject" }
-----
-More about `when` clause contexts https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts[here].
-
 ==== Updates
 
 The extension will be updated automatically as new versions become available. It will ask your permission to download the matching language server version binary if needed.
@@ -124,10 +109,23 @@ Here are some useful self-diagnostic commands:
 * To log all LSP requests, add `"rust-analyzer.trace.server": "verbose"` to the settings and look for `Server Trace` in the panel.
 * To enable client-side logging, add `"rust-analyzer.trace.extension": true` to the settings and open the `Console` tab of VS Code developer tools.
 
+==== Special `when` clause context for keybindings.
+You may use `inRustProject` context to configure keybindings for rust projects only. For example:
+[source,json]
+----
+{
+  "key": "ctrl+i",
+  "command": "rust-analyzer.toggleInlayHints",
+  "when": "inRustProject"
+}
+----
+More about `when` clause contexts https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts[here].
+
 === rust-analyzer Language Server Binary
 
 Other editors generally require the `rust-analyzer` binary to be in `$PATH`.
-You can download the pre-built binary from the https://github.com/rust-analyzer/rust-analyzer/releases[releases] page. Typically, you then need to rename the binary for your platform, e.g. `rust-analyzer-mac` if you're on Mac OS, to `rust-analyzer` and make it executable in addition to moving it into a directory in your `$PATH`.
+You can download the pre-built binary from the https://github.com/rust-analyzer/rust-analyzer/releases[releases] page.
+Typically, you then need to rename the binary for your platform, e.g. `rust-analyzer-mac` if you're on Mac OS, to `rust-analyzer` and make it executable in addition to moving it into a directory in your `$PATH`.
 
 On Linux to install the `rust-analyzer` binary into `~/.local/bin`, this commands could be used
 
@@ -147,7 +145,8 @@ $ git clone https://github.com/rust-analyzer/rust-analyzer.git && cd rust-analyz
 $ cargo xtask install --server
 ----
 
-If your editor can't find the binary even though the binary is on your `$PATH`, the likely explanation is that it doesn't see the same `$PATH` as the shell, see https://github.com/rust-analyzer/rust-analyzer/issues/1811[this issue]. On Unix, running the editor from a shell or changing the `.desktop` file to set the environment should help.
+If your editor can't find the binary even though the binary is on your `$PATH`, the likely explanation is that it doesn't see the same `$PATH` as the shell, see https://github.com/rust-analyzer/rust-analyzer/issues/1811[this issue].
+On Unix, running the editor from a shell or changing the `.desktop` file to set the environment should help.
 
 ==== Arch Linux
 
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index f60f0fb16c..d4621930ed 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -1058,7 +1058,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
         /// [Reference](https://doc.rust-lang.org/reference/expressions/block-expr.html)
         /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
         struct BlockExpr: AttrsOwner, ModuleItemOwner {
-            Label, T!['{'], statements: [Stmt], Expr, T!['}'],
+            T!['{'], statements: [Stmt], Expr, T!['}'],
         }
 
         /// Return expression.


Test patch:
diff --git a/crates/ra_hir_ty/src/tests/simple.rs b/crates/ra_hir_ty/src/tests/simple.rs
index 88309157b7..839491b9e2 100644
--- a/crates/ra_hir_ty/src/tests/simple.rs
+++ b/crates/ra_hir_ty/src/tests/simple.rs
@@ -1943,57 +1943,3 @@ fn test() {
     "###
     );
 }
-
-#[test]
-fn infer_labelled_break_with_val() {
-    assert_snapshot!(
-        infer(r#"
-fn foo() {
-    let _x = || 'outer: loop {
-        let inner = 'inner: loop {
-            let i = Default::default();
-            if (break 'outer i) {
-                loop { break 'inner 5i8; };
-            } else if true {
-                break 'inner 6;
-            }
-            break 7;
-        };
-        break inner < 8;
-    };
-}
-"#),
-        @r###"
-    10..336 '{     ...  }; }': ()
-    20..22 '_x': || -> bool
-    25..333 '|| 'ou...     }': || -> bool
-    28..333 ''outer...     }': bool
-    41..333 '{     ...     }': ()
-    55..60 'inner': i8
-    63..301 ''inner...     }': i8
-    76..301 '{     ...     }': ()
-    94..95 'i': bool
-    98..114 'Defaul...efault': {unknown}
-    98..116 'Defaul...ault()': bool
-    130..270 'if (br...     }': ()
-    134..148 'break 'outer i': !
-    147..148 'i': bool
-    150..209 '{     ...     }': ()
-    168..194 'loop {...5i8; }': !
-    173..194 '{ brea...5i8; }': ()
-    175..191 'break ...er 5i8': !
-    188..191 '5i8': i8
-    215..270 'if tru...     }': ()
-    218..222 'true': bool
-    223..270 '{     ...     }': ()
-    241..255 'break 'inner 6': !
-    254..255 '6': i8
-    283..290 'break 7': !
-    289..290 '7': i8
-    311..326 'break inner < 8': !
-    317..322 'inner': i8
-    317..326 'inner < 8': bool
-    325..326 '8': i8
-    "###
-    );
-}