Repository: rust-analyzer/rust-analyzer
Pull request #5361 (2020-07-14 09:01:46)

Check power on CI


bors r+
🤖


Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 3adf9e6ca0..a5a4b3ccd6 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -95,6 +95,40 @@ jobs:
       if: matrix.os == 'windows-latest'
       run: Remove-Item ./target/debug/xtask.exe, ./target/debug/deps/xtask.exe
 
+  # Weird target to catch non-portable code
+  rust-power:
+    name: Rust Power
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v2
+
+    - name: Install Rust toolchain
+      uses: actions-rs/toolchain@v1
+      with:
+        toolchain: stable
+        profile: minimal
+        override: true
+        target: 'powerpc-unknown-linux-gnu'
+
+    - run: sudo chown -R $(whoami):$(id -ng) ~/.cargo/
+
+    - name: Cache cargo registry
+      uses: actions/cache@v1
+      with:
+        path: ~/.cargo/registry
+        key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
+
+    - name: Cache cargo index
+      uses: actions/cache@v1
+      with:
+        path: ~/.cargo/git
+        key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
+
+    - name: Check
+      run: cargo check --target=powerpc-unknown-linux-gnu --all-targets
+
   typescript:
     name: TypeScript
     strategy:
@@ -103,7 +137,7 @@ jobs:
         os: [ubuntu-latest, windows-latest, macos-latest]
 
     runs-on: ${{ matrix.os }}
-    
+
     steps:
     - name: Checkout repository
       uses: actions/checkout@v2
diff --git a/Cargo.lock b/Cargo.lock
index c16cf4bc80..2c19b3cde3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -992,6 +992,16 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "quanta"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f4f7a1905379198075914bc93d32a5465c40474f90a078bb13439cb00c547bcc"
+dependencies = [
+ "libc",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "quote"
 version = "1.0.7"
@@ -1908,13 +1918,14 @@ dependencies = [
 
 [[package]]
 name = "tracing-tree"
-version = "0.1.4"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37ee7f0f53ed2093971a698db799ef56a2dfd89b32e3aeb5165f0e637a02be04"
+checksum = "e0a389731c9e6c56fef11e438e5b6afae861d5bc301c8b4bdca8d19f0e830d82"
 dependencies = [
  "ansi_term 0.12.1",
  "atty",
  "chrono",
+ "quanta",
  "termcolor",
  "tracing",
  "tracing-subscriber",
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 42c9ca189f..9222009fec 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -25,8 +25,11 @@ use hir_expand::{
 use hir_ty::{
     autoderef,
     display::{HirDisplayError, HirFormatter},
-    method_resolution, ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs,
-    TraitEnvironment, Ty, TyDefId, TypeCtor,
+    expr::ExprValidator,
+    method_resolution,
+    unsafe_validation::UnsafeValidator,
+    ApplicationTy, Canonical, GenericPredicate, InEnvironment, Substs, TraitEnvironment, Ty,
+    TyDefId, TypeCtor,
 };
 use ra_db::{CrateId, Edition, FileId};
 use ra_prof::profile;
@@ -677,7 +680,13 @@ impl Function {
     }
 
     pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) {
-        hir_ty::diagnostics::validate_body(db, self.id.into(), sink)
+        let _p = profile("Function::diagnostics");
+        let infer = db.infer(self.id.into());
+        infer.add_diagnostics(db, self.id, sink);
+        let mut validator = ExprValidator::new(self.id, infer.clone(), sink);
+        validator.validate_body(db);
+        let mut validator = UnsafeValidator::new(self.id, infer, sink);
+        validator.validate_body(db);
     }
 }
 
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index d76345525f..f74b78b237 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -18,7 +18,7 @@ use hir_def::{
 };
 use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
 use hir_ty::{
-    diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
+    expr::{record_literal_missing_fields, record_pattern_missing_fields},
     InferenceResult, Substs, Ty,
 };
 use ra_syntax::{
diff --git a/crates/ra_hir_ty/src/diagnostics.rs b/crates/ra_hir_ty/src/diagnostics.rs
index 3623b8569e..5b0dda634f 100644
--- a/crates/ra_hir_ty/src/diagnostics.rs
+++ b/crates/ra_hir_ty/src/diagnostics.rs
@@ -1,30 +1,13 @@
 //! FIXME: write short doc here
-mod expr;
-mod match_check;
-mod unsafe_check;
 
 use std::any::Any;
 
-use hir_def::DefWithBodyId;
-use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
 use hir_expand::{db::AstDatabase, name::Name, HirFileId, InFile};
-use ra_prof::profile;
 use ra_syntax::{ast, AstNode, AstPtr, SyntaxNodePtr};
 use stdx::format_to;
 
-use crate::db::HirDatabase;
-
-pub use crate::diagnostics::expr::{record_literal_missing_fields, record_pattern_missing_fields};
-
-pub fn validate_body(db: &dyn HirDatabase, owner: DefWithBodyId, sink: &mut DiagnosticSink<'_>) {
-    let _p = profile("validate_body");
-    let infer = db.infer(owner);
-    infer.add_diagnostics(db, owner, sink);
-    let mut validator = expr::ExprValidator::new(owner, infer.clone(), sink);
-    validator.validate_body(db);
-    let mut validator = unsafe_check::UnsafeValidator::new(owner, infer, sink);
-    validator.validate_body(db);
-}
+pub use hir_def::{diagnostics::UnresolvedModule, expr::MatchArm, path::Path};
+pub use hir_expand::diagnostics::{AstDiagnostic, Diagnostic, DiagnosticSink};
 
 #[derive(Debug)]
 pub struct NoSuchField {
diff --git a/crates/ra_hir_ty/src/diagnostics/expr.rs b/crates/ra_hir_ty/src/expr.rs
similarity index 94%
rename from crates/ra_hir_ty/src/diagnostics/expr.rs
rename to crates/ra_hir_ty/src/expr.rs
index 239be779fa..d44562b227 100644
--- a/crates/ra_hir_ty/src/diagnostics/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -2,7 +2,7 @@
 
 use std::sync::Arc;
 
-use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId};
+use hir_def::{path::path, resolver::HasResolver, AdtId, FunctionId};
 use hir_expand::diagnostics::DiagnosticSink;
 use ra_syntax::{ast, AstPtr};
 use rustc_hash::FxHashSet;
@@ -10,9 +10,9 @@ use rustc_hash::FxHashSet;
 use crate::{
     db::HirDatabase,
     diagnostics::{
-        match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
         MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields,
     },
+    match_checking::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness},
     utils::variant_data,
     ApplicationTy, InferenceResult, Ty, TypeCtor,
 };
@@ -30,23 +30,23 @@ pub use hir_def::{
     LocalFieldId, Lookup, VariantId,
 };
 
-pub(super) struct ExprValidator<'a, 'b: 'a> {
-    owner: DefWithBodyId,
+pub struct ExprValidator<'a, 'b: 'a> {
+    func: FunctionId,
     infer: Arc<InferenceResult>,
     sink: &'a mut DiagnosticSink<'b>,
 }
 
 impl<'a, 'b> ExprValidator<'a, 'b> {
-    pub(super) fn new(
-        owner: DefWithBodyId,
+    pub fn new(
+        func: FunctionId,
         infer: Arc<InferenceResult>,
         sink: &'a mut DiagnosticSink<'b>,
     ) -> ExprValidator<'a, 'b> {
-        ExprValidator { owner, infer, sink }
+        ExprValidator { func, infer, sink }
     }
 
-    pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
-        let body = db.body(self.owner.into());
+    pub fn validate_body(&mut self, db: &dyn HirDatabase) {
+        let body = db.body(self.func.into());
 
         for (id, expr) in body.exprs.iter() {
             if let Some((variant_def, missed_fields, true)) =
@@ -96,7 +96,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
         missed_fields: Vec<LocalFieldId>,
     ) {
         // XXX: only look at source_map if we do have missing fields
-        let (_, source_map) = db.body_with_source_map(self.owner.into());
+        let (_, source_map) = db.body_with_source_map(self.func.into());
 
         if let Ok(source_ptr) = source_map.expr_syntax(id) {
             let root = source_ptr.file_syntax(db.upcast());
@@ -125,7 +125,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
         missed_fields: Vec<LocalFieldId>,
     ) {
         // XXX: only look at source_map if we do have missing fields
-        let (_, source_map) = db.body_with_source_map(self.owner.into());
+        let (_, source_map) = db.body_with_source_map(self.func.into());
 
         if let Ok(source_ptr) = source_map.pat_syntax(id) {
             if let Some(expr) = source_ptr.value.as_ref().left() {
@@ -181,7 +181,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
         let mut arg_count = args.len();
 
         if arg_count != param_count {
-            let (_, source_map) = db.body_with_source_map(self.owner.into());
+            let (_, source_map) = db.body_with_source_map(self.func.into());
             if let Ok(source_ptr) = source_map.expr_syntax(call_id) {
                 if is_method_call {
                     param_count -= 1;
@@ -208,7 +208,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
         infer: Arc<InferenceResult>,
     ) {
         let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
-            db.body_with_source_map(self.owner.into());
+            db.body_with_source_map(self.func.into());
 
         let match_expr_ty = match infer.type_of_expr.get(match_expr) {
             Some(ty) => ty,
@@ -289,7 +289,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
 
         let core_result_path = path![core::result::Result];
 
-        let resolver = self.owner.resolver(db.upcast());
+        let resolver = self.func.resolver(db.upcast());
         let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) {
             Some(it) => it,
             _ => return,
@@ -304,7 +304,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
         };
 
         if params.len() == 2 && params[0] == mismatch.actual {
-            let (_, source_map) = db.body_with_source_map(self.owner.into());
+            let (_, source_map) = db.body_with_source_map(self.func.into());
 
             if let Ok(source_ptr) = source_map.expr_syntax(id) {
                 self.sink
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 28f32a0a4d..2ce4f65ccc 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -168,7 +168,7 @@ impl InferenceResult {
     pub fn add_diagnostics(
         &self,
         db: &dyn HirDatabase,
-        owner: DefWithBodyId,
+        owner: FunctionId,
         sink: &mut DiagnosticSink,
     ) {
         self.diagnostics.iter().for_each(|it| it.add_to(db, owner, sink))
@@ -760,7 +760,7 @@ impl std::ops::BitOrAssign for Diverges {
 }
 
 mod diagnostics {
-    use hir_def::{expr::ExprId, DefWithBodyId};
+    use hir_def::{expr::ExprId, FunctionId};
     use hir_expand::diagnostics::DiagnosticSink;
 
     use crate::{
@@ -778,17 +778,17 @@ mod diagnostics {
         pub(super) fn add_to(
             &self,
             db: &dyn HirDatabase,
-            owner: DefWithBodyId,
+            owner: FunctionId,
             sink: &mut DiagnosticSink,
         ) {
             match self {
                 InferenceDiagnostic::NoSuchField { expr, field } => {
-                    let (_, source_map) = db.body_with_source_map(owner);
+                    let (_, source_map) = db.body_with_source_map(owner.into());
                     let field = source_map.field_syntax(*expr, *field);
                     sink.push(NoSuchField { file: field.file_id, field: field.value })
                 }
                 InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
-                    let (_, source_map) = db.body_with_source_map(owner);
+                    let (_, source_map) = db.body_with_source_map(owner.into());
                     let ptr = source_map
                         .expr_syntax(*expr)
                         .expect("break outside of loop in synthetic syntax");
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index d54568e67a..2652d200f5 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -12,12 +12,15 @@ pub mod traits;
 pub mod method_resolution;
 mod op;
 mod lower;
+mod match_checking;
 pub(crate) mod infer;
 pub(crate) mod utils;
 
 pub mod display;
 pub mod db;
 pub mod diagnostics;
+pub mod expr;
+pub mod unsafe_validation;
 
 #[cfg(test)]
 mod tests;
diff --git a/crates/ra_hir_ty/src/diagnostics/match_check.rs b/crates/ra_hir_ty/src/match_checking.rs
similarity index 99%
rename from crates/ra_hir_ty/src/diagnostics/match_check.rs
rename to crates/ra_hir_ty/src/match_checking.rs
index 722c0e9eea..5495ce284f 100644
--- a/crates/ra_hir_ty/src/diagnostics/match_check.rs
+++ b/crates/ra_hir_ty/src/match_checking.rs
@@ -218,16 +218,15 @@
 //!   ```
 use std::sync::Arc;
 
-use hir_def::{
-    adt::VariantData,
-    body::Body,
-    expr::{Expr, Literal, Pat, PatId},
-    AdtId, EnumVariantId, VariantId,
-};
-use ra_arena::Idx;
 use smallvec::{smallvec, SmallVec};
 
-use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor};
+use crate::{
+    db::HirDatabase,
+    expr::{Body, Expr, Literal, Pat, PatId},
+    ApplicationTy, InferenceResult, Ty, TypeCtor,
+};
+use hir_def::{adt::VariantData, AdtId, EnumVariantId, VariantId};
+use ra_arena::Idx;
 
 #[derive(Debug, Clone, Copy)]
 /// Either a pattern from the source code being analyzed, represented as
diff --git a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs b/crates/ra_hir_ty/src/unsafe_validation.rs
similarity index 85%
rename from crates/ra_hir_ty/src/diagnostics/unsafe_check.rs
rename to crates/ra_hir_ty/src/unsafe_validation.rs
index b8ff95ee1e..c512c4f8e9 100644
--- a/crates/ra_hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/ra_hir_ty/src/unsafe_validation.rs
@@ -6,7 +6,7 @@ use std::sync::Arc;
 use hir_def::{
     body::Body,
     expr::{Expr, ExprId, UnaryOp},
-    DefWithBodyId,
+    DefWithBodyId, FunctionId,
 };
 use hir_expand::diagnostics::DiagnosticSink;
 
@@ -15,29 +15,26 @@ use crate::{
     InferenceResult, Ty, TypeCtor,
 };
 
-pub(super) struct UnsafeValidator<'a, 'b: 'a> {
-    owner: DefWithBodyId,
+pub struct UnsafeValidator<'a, 'b: 'a> {
+    func: FunctionId,
     infer: Arc<InferenceResult>,
     sink: &'a mut DiagnosticSink<'b>,
 }
 
 impl<'a, 'b> UnsafeValidator<'a, 'b> {
-    pub(super) fn new(
-        owner: DefWithBodyId,
+    pub fn new(
+        func: FunctionId,
         infer: Arc<InferenceResult>,
         sink: &'a mut DiagnosticSink<'b>,
     ) -> UnsafeValidator<'a, 'b> {
-        UnsafeValidator { owner, infer, sink }
+        UnsafeValidator { func, infer, sink }
     }
 
-    pub(super) fn validate_body(&mut self, db: &dyn HirDatabase) {
-        let def = self.owner.into();
+    pub fn validate_body(&mut self, db: &dyn HirDatabase) {
+        let def = self.func.into();
         let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
-        let is_unsafe = match self.owner {
-            DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe,
-            DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
-        };
-        if is_unsafe
+        let func_data = db.function_data(self.func);
+        if func_data.is_unsafe
             || unsafe_expressions
                 .iter()
                 .filter(|unsafe_expr| !unsafe_expr.inside_unsafe_block)


Test patch:
diff --git a/crates/ra_hir_ty/src/test_db.rs b/crates/ra_hir_ty/src/test_db.rs
index ddafd0ea13..dc447955f7 100644
--- a/crates/ra_hir_ty/src/test_db.rs
+++ b/crates/ra_hir_ty/src/test_db.rs
@@ -6,17 +6,17 @@ use std::{
 };
 
 use hir_def::{db::DefDatabase, AssocItemId, ModuleDefId, ModuleId};
-use hir_expand::{
-    db::AstDatabase,
-    diagnostics::{Diagnostic, DiagnosticSink},
-};
+use hir_expand::{db::AstDatabase, diagnostics::DiagnosticSink};
 use ra_db::{salsa, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast};
 use ra_syntax::TextRange;
 use rustc_hash::{FxHashMap, FxHashSet};
 use stdx::format_to;
 use test_utils::extract_annotations;
 
-use crate::diagnostics::validate_body;
+use crate::{
+    db::HirDatabase, diagnostics::Diagnostic, expr::ExprValidator,
+    unsafe_validation::UnsafeValidator,
+};
 
 #[salsa::database(
     ra_db::SourceDatabaseExtStorage,
@@ -118,8 +118,13 @@ impl TestDB {
             }
 
             for f in fns {
+                let infer = self.infer(f.into());
                 let mut sink = DiagnosticSink::new(&mut cb);
-                validate_body(self, f.into(), &mut sink);
+                infer.add_diagnostics(self, f, &mut sink);
+                let mut validator = ExprValidator::new(f, infer.clone(), &mut sink);
+                validator.validate_body(self);
+                let mut validator = UnsafeValidator::new(f, infer, &mut sink);
+                validator.validate_body(self);
             }
         }
     }
diff --git a/crates/test_utils/src/mark.rs b/crates/test_utils/src/mark.rs
index 97f5a93ad9..7c309a8945 100644
--- a/crates/test_utils/src/mark.rs
+++ b/crates/test_utils/src/mark.rs
@@ -62,7 +62,7 @@ pub struct MarkChecker {
 
 impl MarkChecker {
     pub fn new(mark: &'static AtomicUsize) -> MarkChecker {
-        let value_on_entry = mark.load(Ordering::Relaxed);
+        let value_on_entry = mark.load(Ordering::SeqCst);
         MarkChecker { mark, value_on_entry }
     }
 }
@@ -72,7 +72,7 @@ impl Drop for MarkChecker {
         if std::thread::panicking() {
             return;
         }
-        let value_on_exit = self.mark.load(Ordering::Relaxed);
+        let value_on_exit = self.mark.load(Ordering::SeqCst);
         assert!(value_on_exit > self.value_on_entry, "mark was not hit")
     }
 }