Repository: rust-analyzer/rust-analyzer
Pull request #1567 (2019-07-20 14:09:45)

speedup CI


Patch:
diff --git a/.travis.yml b/.travis.yml
index e5960ebca4..8ac01171f6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,9 @@
 cache: cargo
 before_cache:
-    - find ./target/debug -maxdepth 1 -type f -delete
-    - rm -fr ./target/debug/{deps,.fingerprint}/{*ra_*,*test*,*gen_lsp*,*thread_worker*}
+    # ask Cargo to clean up artifacts for workspace crates
+    - cargo clean $(printf -- '--package %s ' $(cd crates; ls))
+    # Cargo doesn't clean up depinfo itself, do it manually
+    - find ./target/debug -maxdepth 2 -iname '*.d' -delete
     - rm -f  ./target/.rustc_info.json
 
 matrix:
@@ -14,6 +16,7 @@ matrix:
           script:
               - rustup component add rustfmt
               - rustup component add rust-src
+              - printf "\n\n[profile.dev]\ndebug = false\nopt-level = 1\n" >> Cargo.toml
               - cargo test --no-run  # let's measure compile time separately
               - cargo test
           env:
diff --git a/crates/ra_assists/src/add_impl.rs b/crates/ra_assists/src/add_impl.rs
index 59ca88468b..9a0cfb4e7f 100644
--- a/crates/ra_assists/src/add_impl.rs
+++ b/crates/ra_assists/src/add_impl.rs
@@ -1,5 +1,3 @@
-use std::fmt::Write;
-
 use hir::db::HirDatabase;
 use join_to_string::join;
 use ra_syntax::{
@@ -19,7 +17,7 @@ pub(crate) fn add_impl(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist> {
         let mut buf = String::new();
         buf.push_str("\n\nimpl");
         if let Some(type_params) = &type_params {
-            write!(buf, "{}", type_params.syntax()).unwrap();
+            type_params.syntax().text().push_to(&mut buf);
         }
         buf.push_str(" ");
         buf.push_str(name.text().as_str());
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs
index ab6c347ad9..36235eb137 100644
--- a/crates/ra_assists/src/ast_editor.rs
+++ b/crates/ra_assists/src/ast_editor.rs
@@ -95,7 +95,7 @@ impl AstEditor<ast::NamedFieldList> {
         position: InsertPosition<&'_ ast::NamedField>,
         field: &ast::NamedField,
     ) {
-        let is_multiline = self.ast().syntax().text().contains_char('\n');
+        let is_multiline = self.ast().syntax().text().contains('\n');
         let ws;
         let space = if is_multiline {
             ws = tokens::WsBuilder::new(&format!(
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs
index 911de2d48c..df6c589899 100644
--- a/crates/ra_assists/src/introduce_variable.rs
+++ b/crates/ra_assists/src/introduce_variable.rs
@@ -1,5 +1,3 @@
-use std::fmt::Write;
-
 use hir::db::HirDatabase;
 use ra_syntax::{
     ast::{self, AstNode},
@@ -37,7 +35,8 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option
             buf.push_str("let var_name = ");
             TextUnit::of_str("let ")
         };
-        write!(buf, "{}", expr.syntax()).unwrap();
+
+        expr.syntax().text().push_to(&mut buf);
         let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone());
         let is_full_stmt = if let Some(expr_stmt) = &full_stmt {
             Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone())
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index b09478d7a3..d6e8957293 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -36,7 +36,7 @@ fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
 
 pub fn extract_trivial_expression(block: &ast::Block) -> Option<ast::Expr> {
     let expr = block.expr()?;
-    if expr.syntax().text().contains_char('\n') {
+    if expr.syntax().text().contains('\n') {
         return None;
     }
     let non_trivial_children = block.syntax().children().filter(|it| match it.kind() {
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 4dcea19a93..6eed67f50c 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -220,9 +220,6 @@ pub enum Expr {
         expr: ExprId,
         name: Name,
     },
-    Await {
-        expr: ExprId,
-    },
     Try {
         expr: ExprId,
     },
@@ -362,7 +359,6 @@ impl Expr {
                 f(*rhs);
             }
             Expr::Field { expr, .. }
-            | Expr::Await { expr }
             | Expr::Try { expr }
             | Expr::Cast { expr, .. }
             | Expr::Ref { expr, .. }
@@ -733,10 +729,6 @@ where
                 };
                 self.alloc_expr(Expr::Field { expr, name }, syntax_ptr)
             }
-            ast::ExprKind::AwaitExpr(e) => {
-                let expr = self.collect_expr_opt(e.expr());
-                self.alloc_expr(Expr::Await { expr }, syntax_ptr)
-            }
             ast::ExprKind::TryExpr(e) => {
                 let expr = self.collect_expr_opt(e.expr());
                 self.alloc_expr(Expr::Try { expr }, syntax_ptr)
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 6d14eea8ec..c589f8aba6 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -118,9 +118,6 @@ pub(crate) const ITEM: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"Item
 pub(crate) const OPS: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"ops"));
 pub(crate) const TRY: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Try"));
 pub(crate) const OK: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"Ok"));
-pub(crate) const FUTURE_MOD: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"future"));
-pub(crate) const FUTURE_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Future"));
-pub(crate) const OUTPUT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output"));
 
 fn resolve_name(text: &SmolStr) -> SmolStr {
     let raw_start = "r#";
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index a82dff711d..0e030576d8 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -1114,25 +1114,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
                 .unwrap_or(Ty::Unknown);
                 self.insert_type_vars(ty)
             }
-            Expr::Await { expr } => {
-                let inner_ty = self.infer_expr(*expr, &Expectation::none());
-                let ty = match self.resolve_future_future_output() {
-                    Some(future_future_output_alias) => {
-                        let ty = self.new_type_var();
-                        let projection = ProjectionPredicate {
-                            ty: ty.clone(),
-                            projection_ty: ProjectionTy {
-                                associated_ty: future_future_output_alias,
-                                parameters: vec![inner_ty].into(),
-                            },
-                        };
-                        self.obligations.push(Obligation::Projection(projection));
-                        self.resolve_ty_as_possible(&mut vec![], ty)
-                    }
-                    None => Ty::Unknown,
-                };
-                ty
-            }
             Expr::Try { expr } => {
                 let inner_ty = self.infer_expr(*expr, &Expectation::none());
                 let ty = match self.resolve_ops_try_ok() {
@@ -1387,28 +1368,6 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
             _ => None,
         }
     }
-
-    fn resolve_future_future_output(&self) -> Option<TypeAlias> {
-        let future_future_path = Path {
-            kind: PathKind::Abs,
-            segments: vec![
-                PathSegment { name: name::STD, args_and_bindings: None },
-                PathSegment { name: name::FUTURE_MOD, args_and_bindings: None },
-                PathSegment { name: name::FUTURE_TYPE, args_and_bindings: None },
-            ],
-        };
-
-        match self
-            .resolver
-            .resolve_path_segments(self.db, &future_future_path)
-            .into_fully_resolved()
-        {
-            PerNs { types: Some(Def(Trait(trait_))), .. } => {
-                Some(trait_.associated_type_by_name(self.db, name::OUTPUT)?)
-            }
-            _ => None,
-        }
-    }
 }
 
 /// The ID of a type variable.
diff --git a/crates/ra_ide_api/src/display/short_label.rs b/crates/ra_ide_api/src/display/short_label.rs
index be499e485b..f926f631fc 100644
--- a/crates/ra_ide_api/src/display/short_label.rs
+++ b/crates/ra_ide_api/src/display/short_label.rs
@@ -1,5 +1,3 @@
-use std::fmt::Write;
-
 use ra_syntax::ast::{self, AstNode, NameOwner, TypeAscriptionOwner, VisibilityOwner};
 
 pub(crate) trait ShortLabel {
@@ -73,7 +71,8 @@ where
     let mut buf = short_label_from_node(node, prefix)?;
 
     if let Some(type_ref) = node.ascribed_type() {
-        write!(buf, ": {}", type_ref.syntax()).unwrap();
+        buf.push_str(": ");
+        type_ref.syntax().text().push_to(&mut buf);
     }
 
     Some(buf)
@@ -83,7 +82,7 @@ fn short_label_from_node<T>(node: &T, label: &str) -> Option<String>
 where
     T: NameOwner + VisibilityOwner,
 {
-    let mut buf = node.visibility().map(|v| format!("{} ", v.syntax())).unwrap_or_default();
+    let mut buf = node.visibility().map(|v| format!("{} ", v.syntax().text())).unwrap_or_default();
     buf.push_str(label);
     buf.push_str(node.name()?.text().as_str());
     Some(buf)
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs
index 571d1c5958..9699000dbb 100644
--- a/crates/ra_ide_api/src/folding_ranges.rs
+++ b/crates/ra_ide_api/src/folding_ranges.rs
@@ -31,7 +31,7 @@ pub(crate) fn folding_ranges(file: &SourceFile) -> Vec<Fold> {
         // Fold items that span multiple lines
         if let Some(kind) = fold_kind(element.kind()) {
             let is_multiline = match &element {
-                SyntaxElement::Node(node) => node.text().contains_char('\n'),
+                SyntaxElement::Node(node) => node.text().contains('\n'),
                 SyntaxElement::Token(token) => token.text().contains('\n'),
             };
             if is_multiline {
diff --git a/crates/ra_ide_api/src/join_lines.rs b/crates/ra_ide_api/src/join_lines.rs
index 7f25f21081..fa998ebe1e 100644
--- a/crates/ra_ide_api/src/join_lines.rs
+++ b/crates/ra_ide_api/src/join_lines.rs
@@ -13,7 +13,7 @@ pub fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit {
     let range = if range.is_empty() {
         let syntax = file.syntax();
         let text = syntax.text().slice(range.start()..);
-        let pos = match text.find_char('\n') {
+        let pos = match text.find('\n') {
             None => return TextEditBuilder::default().finish(),
             Some(pos) => pos,
         };
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs
index 5a1cbcc498..1747a529ec 100644
--- a/crates/ra_ide_api/src/typing.rs
+++ b/crates/ra_ide_api/src/typing.rs
@@ -75,7 +75,7 @@ pub fn on_eq_typed(file: &SourceFile, eq_offset: TextUnit) -> Option<TextEdit> {
         if expr_range.contains(eq_offset) && eq_offset != expr_range.start() {
             return None;
         }
-        if file.syntax().text().slice(eq_offset..expr_range.start()).contains_char('\n') {
+        if file.syntax().text().slice(eq_offset..expr_range.start()).contains('\n') {
             return None;
         }
     } else {
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index da8cf4ae8e..99fcdbd9ac 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -175,32 +175,6 @@ impl Attr {
     }
 }
 
-// AwaitExpr
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct AwaitExpr {
-    pub(crate) syntax: SyntaxNode,
-}
-
-impl AstNode for AwaitExpr {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            AWAIT_EXPR => true,
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(AwaitExpr { syntax }) } else { None }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-
-
-impl AwaitExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
-    }
-}
-
 // BinExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BinExpr {
@@ -592,7 +566,7 @@ pub struct Expr {
 impl AstNode for Expr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => true,
+             | TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => true,
             _ => false,
         }
     }
@@ -625,7 +599,6 @@ pub enum ExprKind {
     IndexExpr(IndexExpr),
     MethodCallExpr(MethodCallExpr),
     FieldExpr(FieldExpr),
-    AwaitExpr(AwaitExpr),
     TryExpr(TryExpr),
     TryBlockExpr(TryBlockExpr),
     CastExpr(CastExpr),
@@ -696,9 +669,6 @@ impl From<MethodCallExpr> for Expr {
 impl From<FieldExpr> for Expr {
     fn from(n: FieldExpr) -> Expr { Expr { syntax: n.syntax } }
 }
-impl From<AwaitExpr> for Expr {
-    fn from(n: AwaitExpr) -> Expr { Expr { syntax: n.syntax } }
-}
 impl From<TryExpr> for Expr {
     fn from(n: TryExpr) -> Expr { Expr { syntax: n.syntax } }
 }
@@ -749,7 +719,6 @@ impl Expr {
             INDEX_EXPR => ExprKind::IndexExpr(IndexExpr::cast(self.syntax.clone()).unwrap()),
             METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(self.syntax.clone()).unwrap()),
             FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(self.syntax.clone()).unwrap()),
-            AWAIT_EXPR => ExprKind::AwaitExpr(AwaitExpr::cast(self.syntax.clone()).unwrap()),
             TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(self.syntax.clone()).unwrap()),
             TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(self.syntax.clone()).unwrap()),
             CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(self.syntax.clone()).unwrap()),
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 817dedfbfa..55494239e4 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -477,7 +477,6 @@ Grammar(
         ),
         "IndexExpr": (),
         "FieldExpr": (options: ["Expr", "NameRef"]),
-        "AwaitExpr": (options: ["Expr"]),
         "TryExpr": (options: ["Expr"]),
         "CastExpr": (options: ["Expr", "TypeRef"]),
         "RefExpr": (options: ["Expr"]),
@@ -509,7 +508,6 @@ Grammar(
                 "IndexExpr",
                 "MethodCallExpr",
                 "FieldExpr",
-                "AwaitExpr",
                 "TryExpr",
                 "TryBlockExpr",
                 "CastExpr",
diff --git a/crates/ra_syntax/src/syntax_text.rs b/crates/ra_syntax/src/syntax_text.rs
index 652cb7a1e0..f8ddff48e9 100644
--- a/crates/ra_syntax/src/syntax_text.rs
+++ b/crates/ra_syntax/src/syntax_text.rs
@@ -57,15 +57,25 @@ impl SyntaxText {
         }
     }
 
+    pub fn push_to(&self, buf: &mut String) {
+        self.for_each_chunk(|chunk| buf.push_str(chunk))
+    }
+
+    pub fn to_string(&self) -> String {
+        let mut buf = String::new();
+        self.push_to(&mut buf);
+        buf
+    }
+
     pub fn to_smol_string(&self) -> SmolStr {
         self.to_string().into()
     }
 
-    pub fn contains_char(&self, c: char) -> bool {
+    pub fn contains(&self, c: char) -> bool {
         self.try_for_each_chunk(|chunk| if chunk.contains(c) { Err(()) } else { Ok(()) }).is_err()
     }
 
-    pub fn find_char(&self, c: char) -> Option<TextUnit> {
+    pub fn find(&self, c: char) -> Option<TextUnit> {
         let mut acc: TextUnit = 0.into();
         let res = self.try_for_each_chunk(|chunk| {
             if let Some(pos) = chunk.find(c) {
@@ -148,7 +158,7 @@ impl fmt::Debug for SyntaxText {
 
 impl fmt::Display for SyntaxText {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.try_for_each_chunk(|chunk| fmt::Display::fmt(chunk, f))
+        fmt::Display::fmt(&self.to_string(), f)
     }
 }
 


Test patch:
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs
index 706500484f..7b2bdeb3f6 100644
--- a/crates/ra_hir/src/ty/tests.rs
+++ b/crates/ra_hir/src/ty/tests.rs
@@ -20,41 +20,6 @@ use crate::{
 // against snapshots of the expected results using insta. Use cargo-insta to
 // update the snapshots.
 
-#[test]
-fn infer_await() {
-    let (mut db, pos) = MockDatabase::with_position(
-        r#"
-//- /main.rs
-
-struct IntFuture;
-
-impl Future for IntFuture {
-    type Output = u64;
-}
-
-fn test() {
-    let r = IntFuture;
-    let v = r.await;
-    v<|>;
-}
-
-//- /std.rs
-#[prelude_import] use future::*;
-mod future {
-    trait Future {
-        type Output;
-    }
-}
-
-"#,
-    );
-    db.set_crate_graph_from_fixture(crate_graph! {
-        "main": ("/main.rs", ["std"]),
-        "std": ("/std.rs", []),
-    });
-    assert_eq!("u64", type_at_pos(&db, pos));
-}
-
 #[test]
 fn infer_try() {
     let (mut db, pos) = MockDatabase::with_position(