diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 1594d4f0ff99..0516a05b4154 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -207,8 +207,8 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { self.imp.resolve_record_field(field) } - pub fn resolve_record_field_pat(&self, field: &ast::RecordPatField) -> Option { - self.imp.resolve_record_field_pat(field) + pub fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option { + self.imp.resolve_record_pat_field(field) } pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { @@ -433,8 +433,8 @@ impl<'db> SemanticsImpl<'db> { self.analyze(field.syntax()).resolve_record_field(self.db, field) } - fn resolve_record_field_pat(&self, field: &ast::RecordPatField) -> Option { - self.analyze(field.syntax()).resolve_record_field_pat(self.db, field) + fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option { + self.analyze(field.syntax()).resolve_record_pat_field(self.db, field) } fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 1d13c4f1d3b7..1aef0f33f5f8 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -179,13 +179,13 @@ impl SourceAnalyzer { Some((struct_field.into(), local)) } - pub(crate) fn resolve_record_field_pat( + pub(crate) fn resolve_record_pat_field( &self, _db: &dyn HirDatabase, field: &ast::RecordPatField, ) -> Option { let pat_id = self.pat_id(&field.pat()?)?; - let struct_field = self.infer.as_ref()?.record_field_pat_resolution(pat_id)?; + let struct_field = self.infer.as_ref()?.record_pat_field_resolution(pat_id)?; Some(struct_field.into()) } diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 03b00b101c23..2b53b8297314 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -125,7 +125,7 @@ pub struct InferenceResult { field_resolutions: FxHashMap, /// For each field in record literal, records the field it resolves to. record_field_resolutions: FxHashMap, - record_field_pat_resolutions: FxHashMap, + record_pat_field_resolutions: FxHashMap, /// For each struct literal, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to @@ -146,8 +146,8 @@ impl InferenceResult { pub fn record_field_resolution(&self, expr: ExprId) -> Option { self.record_field_resolutions.get(&expr).copied() } - pub fn record_field_pat_resolution(&self, pat: PatId) -> Option { - self.record_field_pat_resolutions.get(&pat).copied() + pub fn record_pat_field_resolution(&self, pat: PatId) -> Option { + self.record_pat_field_resolutions.get(&pat).copied() } pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option { self.variant_resolutions.get(&id.into()).copied() diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 4dd4f9802d6e..dde38bc397b6 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs @@ -70,7 +70,7 @@ impl<'a> InferenceContext<'a> { let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); if let Some(local_id) = matching_field { let field_def = FieldId { parent: def.unwrap(), local_id }; - self.result.record_field_pat_resolutions.insert(subpat.pat, field_def); + self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); } let expected_ty = diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 0d0affc27357..f8c7aa491ea5 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -157,9 +157,9 @@ pub fn classify_name(sema: &Semantics, name: &ast::Name) -> Option ast::IdentPat(it) => { let local = sema.to_def(&it)?; - if let Some(record_field_pat) = it.syntax().parent().and_then(ast::RecordPatField::cast) { - if record_field_pat.name_ref().is_none() { - if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { + if let Some(record_pat_field) = it.syntax().parent().and_then(ast::RecordPatField::cast) { + if record_pat_field.name_ref().is_none() { + if let Some(field) = sema.resolve_record_pat_field(&record_pat_field) { let field = Definition::Field(field); return Some(NameClass::FieldShorthand { local, field }); } @@ -275,8 +275,8 @@ pub fn classify_name_ref( } } - if let Some(record_field_pat) = ast::RecordPatField::cast(parent.clone()) { - if let Some(field) = sema.resolve_record_field_pat(&record_field_pat) { + if let Some(record_pat_field) = ast::RecordPatField::cast(parent.clone()) { + if let Some(field) = sema.resolve_record_pat_field(&record_pat_field) { let field = Definition::Field(field); return Some(NameRefClass::Definition(field)); } diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index 796f206e1284..7e7f73deeac9 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs @@ -188,7 +188,7 @@ fn tuple_pat_fields(p: &mut Parser) { p.expect(T![')']); } -// test record_field_pat_list +// test record_pat_field_list // fn foo() { // let S {} = (); // let S { f, ref mut g } = (); @@ -208,7 +208,7 @@ fn record_pat_field_list(p: &mut Parser) { c => { let m = p.start(); match c { - // test record_field_pat + // test record_pat_field // fn foo() { // let S { 0: 1 } = (); // let S { x: 1 } = (); diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index 2d91939ce0c6..288c39e49478 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs @@ -33,7 +33,7 @@ pub enum ProjectWorkspace { /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`. Cargo { cargo: CargoWorkspace, sysroot: Sysroot }, /// Project workspace was manually specified using a `rust-project.json` file. - Json { project: ProjectJson }, + Json { project: ProjectJson, sysroot: Option }, } impl fmt::Debug for ProjectWorkspace { @@ -44,10 +44,10 @@ impl fmt::Debug for ProjectWorkspace { .field("n_packages", &cargo.packages().len()) .field("n_sysroot_crates", &sysroot.crates().len()) .finish(), - ProjectWorkspace::Json { project } => { + ProjectWorkspace::Json { project, sysroot } => { let mut debug_struct = f.debug_struct("Json"); debug_struct.field("n_crates", &project.n_crates()); - if let Some(sysroot) = &project.sysroot { + if let Some(sysroot) = sysroot { debug_struct.field("n_sysroot_crates", &sysroot.crates().len()); } debug_struct.finish() @@ -169,7 +169,11 @@ impl ProjectWorkspace { })?; let project_location = project_json.parent().unwrap().to_path_buf(); let project = ProjectJson::new(&project_location, data); - ProjectWorkspace::Json { project } + let sysroot = match &project.sysroot_src { + Some(path) => Some(Sysroot::load(path)?), + None => None, + }; + ProjectWorkspace::Json { project, sysroot } } ProjectManifest::CargoToml(cargo_toml) => { let cargo_version = utf8_stdout({ @@ -203,12 +207,21 @@ impl ProjectWorkspace { Ok(res) } + pub fn load_inline(project_json: ProjectJson) -> Result { + let sysroot = match &project_json.sysroot_src { + Some(path) => Some(Sysroot::load(path)?), + None => None, + }; + + Ok(ProjectWorkspace::Json { project: project_json, sysroot }) + } + /// Returns the roots for the current `ProjectWorkspace` /// The return type contains the path and whether or not /// the root is a member of the current workspace pub fn to_roots(&self) -> Vec { match self { - ProjectWorkspace::Json { project } => project + ProjectWorkspace::Json { project, sysroot } => project .crates() .map(|(_, krate)| PackageRoot { is_member: krate.is_workspace_member, @@ -217,7 +230,7 @@ impl ProjectWorkspace { }) .collect::>() .into_iter() - .chain(project.sysroot.as_ref().into_iter().flat_map(|sysroot| { + .chain(sysroot.as_ref().into_iter().flat_map(|sysroot| { sysroot.crates().map(move |krate| PackageRoot { is_member: false, include: vec![sysroot[krate].root_dir().to_path_buf()], @@ -255,7 +268,7 @@ impl ProjectWorkspace { pub fn proc_macro_dylib_paths(&self) -> Vec { match self { - ProjectWorkspace::Json { project } => project + ProjectWorkspace::Json { project, sysroot: _ } => project .crates() .filter_map(|(_, krate)| krate.proc_macro_dylib_path.as_ref()) .cloned() @@ -285,9 +298,8 @@ impl ProjectWorkspace { ) -> CrateGraph { let mut crate_graph = CrateGraph::default(); match self { - ProjectWorkspace::Json { project } => { - let sysroot_dps = project - .sysroot + ProjectWorkspace::Json { project, sysroot } => { + let sysroot_dps = sysroot .as_ref() .map(|sysroot| sysroot_to_crate_graph(&mut crate_graph, sysroot, target, load)); diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs index 5a0fe749a597..979e90058390 100644 --- a/crates/project_model/src/project_json.rs +++ b/crates/project_model/src/project_json.rs @@ -7,12 +7,12 @@ use paths::{AbsPath, AbsPathBuf}; use rustc_hash::FxHashMap; use serde::{de, Deserialize}; -use crate::{cfg_flag::CfgFlag, Sysroot}; +use crate::cfg_flag::CfgFlag; /// Roots and crates that compose this Rust project. #[derive(Clone, Debug, Eq, PartialEq)] pub struct ProjectJson { - pub(crate) sysroot: Option, + pub(crate) sysroot_src: Option, crates: Vec, } @@ -35,7 +35,7 @@ pub struct Crate { impl ProjectJson { pub fn new(base: &AbsPath, data: ProjectJsonData) -> ProjectJson { ProjectJson { - sysroot: data.sysroot_src.map(|it| base.join(it)).map(|it| Sysroot::load(&it)), + sysroot_src: data.sysroot_src.map(|it| base.join(it)), crates: data .crates .into_iter() diff --git a/crates/project_model/src/sysroot.rs b/crates/project_model/src/sysroot.rs index 74c0eda9a522..871808d89e5d 100644 --- a/crates/project_model/src/sysroot.rs +++ b/crates/project_model/src/sysroot.rs @@ -51,11 +51,11 @@ impl Sysroot { pub fn discover(cargo_toml: &AbsPath) -> Result { let current_dir = cargo_toml.parent().unwrap(); let sysroot_src_dir = discover_sysroot_src_dir(current_dir)?; - let res = Sysroot::load(&sysroot_src_dir); + let res = Sysroot::load(&sysroot_src_dir)?; Ok(res) } - pub fn load(sysroot_src_dir: &AbsPath) -> Sysroot { + pub fn load(sysroot_src_dir: &AbsPath) -> Result { let mut sysroot = Sysroot { crates: Arena::default() }; for name in SYSROOT_CRATES.trim().lines() { @@ -89,7 +89,14 @@ impl Sysroot { } } - sysroot + if sysroot.by_name("core").is_none() { + anyhow::bail!( + "could not find libcore in sysroot path `{}`", + sysroot_src_dir.as_ref().display() + ); + } + + Ok(sysroot) } fn by_name(&self, name: &str) -> Option { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 20019b944586..bab6f8a71bbb 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -109,7 +109,7 @@ impl GlobalState { ) } LinkedProject::InlineJsonProject(it) => { - Ok(project_model::ProjectWorkspace::Json { project: it.clone() }) + project_model::ProjectWorkspace::load_inline(it.clone()) } }) .collect::>(); diff --git a/crates/syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast similarity index 100% rename from crates/syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rast rename to crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rast diff --git a/crates/syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rs b/crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs similarity index 100% rename from crates/syntax/test_data/parser/inline/ok/0102_record_field_pat_list.rs rename to crates/syntax/test_data/parser/inline/ok/0102_record_pat_field_list.rs diff --git a/crates/syntax/test_data/parser/inline/ok/0145_record_field_pat.rast b/crates/syntax/test_data/parser/inline/ok/0145_record_pat_field.rast similarity index 100% rename from crates/syntax/test_data/parser/inline/ok/0145_record_field_pat.rast rename to crates/syntax/test_data/parser/inline/ok/0145_record_pat_field.rast diff --git a/crates/syntax/test_data/parser/inline/ok/0145_record_field_pat.rs b/crates/syntax/test_data/parser/inline/ok/0145_record_pat_field.rs similarity index 100% rename from crates/syntax/test_data/parser/inline/ok/0145_record_field_pat.rs rename to crates/syntax/test_data/parser/inline/ok/0145_record_pat_field.rs