Skip to content

Commit dbbd80f

Browse files
author
Paolo Tranquilli
committed
Rust: pick correct edition for the files
Previously we would unconditionally set the edition to the latest stable according to rust-analyzer (2021 at the moment). Now we ask rust-analyzer itself to pick the correct edition for the file.
1 parent 4ae49cf commit dbbd80f

File tree

1 file changed

+59
-58
lines changed

1 file changed

+59
-58
lines changed

rust/extractor/src/rust_analyzer.rs

Lines changed: 59 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use itertools::Itertools;
2-
use ra_ap_base_db::{EditionedFileId, RootQueryDb, SourceDatabase};
2+
use ra_ap_base_db::{EditionedFileId, FileText, RootQueryDb, SourceDatabase};
33
use ra_ap_hir::Semantics;
44
use ra_ap_ide_db::RootDatabase;
55
use ra_ap_load_cargo::{LoadCargoConfig, load_workspace_at};
66
use ra_ap_paths::{AbsPath, Utf8PathBuf};
77
use ra_ap_project_model::ProjectManifest;
88
use ra_ap_project_model::{CargoConfig, ManifestPath};
99
use ra_ap_span::Edition;
10-
use ra_ap_span::EditionedFileId as SpanEditionedFileId;
1110
use ra_ap_span::TextRange;
1211
use ra_ap_span::TextSize;
1312
use ra_ap_syntax::SourceFile;
@@ -54,7 +53,6 @@ impl<'a> RustAnalyzer<'a> {
5453
) -> Option<(RootDatabase, Vfs)> {
5554
let progress = |t| (trace!("progress: {}", t));
5655
let manifest = project.manifest_path();
57-
5856
match load_workspace_at(manifest.as_ref(), config, load_config, &progress) {
5957
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
6058
Err(err) => {
@@ -66,67 +64,70 @@ impl<'a> RustAnalyzer<'a> {
6664
pub fn new(vfs: &'a Vfs, semantics: &'a Semantics<'a, RootDatabase>) -> Self {
6765
RustAnalyzer::WithSemantics { vfs, semantics }
6866
}
69-
pub fn parse(&self, path: &Path) -> ParseResult {
70-
let no_semantics_reason;
67+
fn get_file_data(
68+
&self,
69+
path: &Path,
70+
) -> Result<(&Semantics<RootDatabase>, EditionedFileId, FileText), &str> {
7171
match self {
72+
RustAnalyzer::WithoutSemantics { reason } => Err(reason),
7273
RustAnalyzer::WithSemantics { vfs, semantics } => {
73-
if let Some(file_id) = path_to_file_id(path, vfs) {
74-
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
75-
{
76-
let file_id = EditionedFileId::new(
77-
semantics.db,
78-
SpanEditionedFileId::current_edition(file_id),
79-
);
80-
let source_file = semantics.parse(file_id);
81-
let errors = semantics
82-
.db
83-
.parse_errors(file_id)
84-
.into_iter()
85-
.flat_map(|x| x.to_vec())
86-
.collect();
87-
88-
return ParseResult {
89-
ast: source_file,
90-
text: input.text(semantics.db),
91-
errors,
92-
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
93-
};
94-
}
95-
debug!(
96-
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
97-
file_id,
98-
path.to_string_lossy()
99-
);
100-
no_semantics_reason = "no text available for the file in the project";
101-
} else {
102-
no_semantics_reason = "file not found in project";
103-
}
104-
}
105-
RustAnalyzer::WithoutSemantics { reason } => {
106-
no_semantics_reason = reason;
74+
let file_id = path_to_file_id(path, vfs).ok_or("file not found in project")?;
75+
let input = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
76+
.or(Err("no text available for the file in the project"))?;
77+
let editioned_file_id = semantics
78+
.attach_first_edition(file_id)
79+
.ok_or("failed to determine rust edition")?;
80+
Ok((
81+
semantics,
82+
EditionedFileId::new(semantics.db, editioned_file_id),
83+
input,
84+
))
10785
}
10886
}
109-
let mut errors = Vec::new();
110-
let input = match std::fs::read(path) {
111-
Ok(data) => data,
112-
Err(e) => {
113-
errors.push(SyntaxError::new(
114-
format!("Could not read {}: {}", path.to_string_lossy(), e),
115-
TextRange::empty(TextSize::default()),
116-
));
117-
vec![]
87+
}
88+
89+
pub fn parse(&self, path: &Path) -> ParseResult {
90+
match self.get_file_data(path) {
91+
Ok((semantics, file_id, input)) => {
92+
let source_file = semantics.parse(file_id);
93+
let errors = semantics
94+
.db
95+
.parse_errors(file_id)
96+
.into_iter()
97+
.flat_map(|x| x.to_vec())
98+
.collect();
99+
100+
ParseResult {
101+
ast: source_file,
102+
text: input.text(semantics.db),
103+
errors,
104+
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
105+
}
118106
}
119-
};
120-
let (input, err) = from_utf8_lossy(&input);
107+
Err(reason) => {
108+
let mut errors = Vec::new();
109+
let input = match std::fs::read(path) {
110+
Ok(data) => data,
111+
Err(e) => {
112+
errors.push(SyntaxError::new(
113+
format!("Could not read {}: {}", path.to_string_lossy(), e),
114+
TextRange::empty(TextSize::default()),
115+
));
116+
vec![]
117+
}
118+
};
119+
let (input, err) = from_utf8_lossy(&input);
121120

122-
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
123-
errors.extend(parse.errors());
124-
errors.extend(err);
125-
ParseResult {
126-
ast: parse.tree(),
127-
text: input.as_ref().into(),
128-
errors,
129-
semantics_info: Err(no_semantics_reason),
121+
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
122+
errors.extend(parse.errors());
123+
errors.extend(err);
124+
ParseResult {
125+
ast: parse.tree(),
126+
text: input.as_ref().into(),
127+
errors,
128+
semantics_info: Err(reason),
129+
}
130+
}
130131
}
131132
}
132133
}

0 commit comments

Comments
 (0)