Skip to content

Commit c611e44

Browse files
committed
Auto merge of rust-lang#17483 - alibektas:ratoml/fixes, r=alibektas
minor : fixes for ratoml module This is a follow-up PR to rust-lang#17058. - Parse errors are reflected as such by defining a new variant called `ConfigError::ParseError` - New error collection has been added to store config level agnostic errors. EDIT : Some things that this PR promised to solve are removed and will be addressed by other PRs
2 parents b8e83b7 + abdad6f commit c611e44

File tree

3 files changed

+92
-115
lines changed

3 files changed

+92
-115
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs

+72-47
Original file line numberDiff line numberDiff line change
@@ -779,7 +779,6 @@ pub struct Config {
779779
/// | Windows | `{FOLDERID_RoamingAppData}` | C:\Users\Alice\AppData\Roaming |
780780
user_config_path: VfsPath,
781781

782-
/// FIXME @alibektas : Change this to sth better.
783782
/// Config node whose values apply to **every** Rust project.
784783
user_config: Option<(GlobalLocalConfigInput, ConfigErrors)>,
785784

@@ -795,6 +794,12 @@ pub struct Config {
795794
/// Clone of the value that is stored inside a `GlobalState`.
796795
source_root_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>,
797796

797+
/// Use case : It is an error to have an empty value for `check_command`.
798+
/// Since it is a `global` command at the moment, its final value can only be determined by
799+
/// traversing through `global` configs and the `client` config. However the non-null value constraint
800+
/// is config level agnostic, so this requires an independent error storage
801+
validation_errors: ConfigErrors,
802+
798803
detached_files: Vec<AbsPathBuf>,
799804
}
800805

@@ -824,6 +829,7 @@ impl Config {
824829
/// The return tuple's bool component signals whether the `GlobalState` should call its `update_configuration()` method.
825830
fn apply_change_with_sink(&self, change: ConfigChange) -> (Config, bool) {
826831
let mut config = self.clone();
832+
config.validation_errors = ConfigErrors::default();
827833

828834
let mut should_update = false;
829835

@@ -852,6 +858,7 @@ impl Config {
852858

853859
if let Some(mut json) = change.client_config_change {
854860
tracing::info!("updating config from JSON: {:#}", json);
861+
855862
if !(json.is_null() || json.as_object().map_or(false, |it| it.is_empty())) {
856863
let mut json_errors = vec![];
857864
let detached_files = get_field_json::<Vec<Utf8PathBuf>>(
@@ -867,6 +874,37 @@ impl Config {
867874

868875
patch_old_style::patch_json_for_outdated_configs(&mut json);
869876

877+
// IMPORTANT : This holds as long as ` completion_snippets_custom` is declared `client`.
878+
config.snippets.clear();
879+
880+
let snips = self.completion_snippets_custom().to_owned();
881+
882+
for (name, def) in snips.iter() {
883+
if def.prefix.is_empty() && def.postfix.is_empty() {
884+
continue;
885+
}
886+
let scope = match def.scope {
887+
SnippetScopeDef::Expr => SnippetScope::Expr,
888+
SnippetScopeDef::Type => SnippetScope::Type,
889+
SnippetScopeDef::Item => SnippetScope::Item,
890+
};
891+
match Snippet::new(
892+
&def.prefix,
893+
&def.postfix,
894+
&def.body,
895+
def.description.as_ref().unwrap_or(name),
896+
&def.requires,
897+
scope,
898+
) {
899+
Some(snippet) => config.snippets.push(snippet),
900+
None => json_errors.push((
901+
name.to_owned(),
902+
<serde_json::Error as serde::de::Error>::custom(format!(
903+
"snippet {name} is invalid or triggers are missing",
904+
)),
905+
)),
906+
}
907+
}
870908
config.client_config = (
871909
FullConfigInput::from_json(json, &mut json_errors),
872910
ConfigErrors(
@@ -906,8 +944,15 @@ impl Config {
906944
));
907945
should_update = true;
908946
}
909-
// FIXME
910-
Err(_) => (),
947+
Err(e) => {
948+
config.root_ratoml = Some((
949+
GlobalLocalConfigInput::from_toml(toml::map::Map::default(), &mut vec![]),
950+
ConfigErrors(vec![ConfigErrorInner::ParseError {
951+
reason: e.message().to_owned(),
952+
}
953+
.into()]),
954+
));
955+
}
911956
}
912957
}
913958

@@ -942,8 +987,18 @@ impl Config {
942987
),
943988
);
944989
}
945-
// FIXME
946-
Err(_) => (),
990+
Err(e) => {
991+
config.root_ratoml = Some((
992+
GlobalLocalConfigInput::from_toml(
993+
toml::map::Map::default(),
994+
&mut vec![],
995+
),
996+
ConfigErrors(vec![ConfigErrorInner::ParseError {
997+
reason: e.message().to_owned(),
998+
}
999+
.into()]),
1000+
));
1001+
}
9471002
}
9481003
}
9491004
}
@@ -953,48 +1008,13 @@ impl Config {
9531008
config.source_root_parent_map = source_root_map;
9541009
}
9551010

956-
// IMPORTANT : This holds as long as ` completion_snippets_custom` is declared `client`.
957-
config.snippets.clear();
958-
959-
let snips = self.completion_snippets_custom().to_owned();
960-
961-
for (name, def) in snips.iter() {
962-
if def.prefix.is_empty() && def.postfix.is_empty() {
963-
continue;
964-
}
965-
let scope = match def.scope {
966-
SnippetScopeDef::Expr => SnippetScope::Expr,
967-
SnippetScopeDef::Type => SnippetScope::Type,
968-
SnippetScopeDef::Item => SnippetScope::Item,
969-
};
970-
#[allow(clippy::single_match)]
971-
match Snippet::new(
972-
&def.prefix,
973-
&def.postfix,
974-
&def.body,
975-
def.description.as_ref().unwrap_or(name),
976-
&def.requires,
977-
scope,
978-
) {
979-
Some(snippet) => config.snippets.push(snippet),
980-
// FIXME
981-
// None => error_sink.0.push(ConfigErrorInner::Json {
982-
// config_key: "".to_owned(),
983-
// error: <serde_json::Error as serde::de::Error>::custom(format!(
984-
// "snippet {name} is invalid or triggers are missing",
985-
// )),
986-
// }),
987-
None => (),
988-
}
1011+
if config.check_command().is_empty() {
1012+
config.validation_errors.0.push(Arc::new(ConfigErrorInner::Json {
1013+
config_key: "/check/command".to_owned(),
1014+
error: serde_json::Error::custom("expected a non-empty string"),
1015+
}));
9891016
}
9901017

991-
// FIXME: bring this back
992-
// if config.check_command().is_empty() {
993-
// error_sink.0.push(ConfigErrorInner::Json {
994-
// config_key: "/check/command".to_owned(),
995-
// error: serde_json::Error::custom("expected a non-empty string"),
996-
// });
997-
// }
9981018
(config, should_update)
9991019
}
10001020

@@ -1012,6 +1032,7 @@ impl Config {
10121032
.chain(config.root_ratoml.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
10131033
.chain(config.user_config.as_ref().into_iter().flat_map(|it| it.1 .0.iter()))
10141034
.chain(config.ratoml_files.values().flat_map(|it| it.1 .0.iter()))
1035+
.chain(config.validation_errors.0.iter())
10151036
.cloned()
10161037
.collect(),
10171038
);
@@ -1259,9 +1280,10 @@ pub struct ClientCommandsConfig {
12591280
pub enum ConfigErrorInner {
12601281
Json { config_key: String, error: serde_json::Error },
12611282
Toml { config_key: String, error: toml::de::Error },
1283+
ParseError { reason: String },
12621284
}
12631285

1264-
#[derive(Clone, Debug)]
1286+
#[derive(Clone, Debug, Default)]
12651287
pub struct ConfigErrors(Vec<Arc<ConfigErrorInner>>);
12661288

12671289
impl ConfigErrors {
@@ -1283,6 +1305,7 @@ impl fmt::Display for ConfigErrors {
12831305
f(&": ")?;
12841306
f(e)
12851307
}
1308+
ConfigErrorInner::ParseError { reason } => f(reason),
12861309
});
12871310
write!(f, "invalid config value{}:\n{}", if self.0.len() == 1 { "" } else { "s" }, errors)
12881311
}
@@ -1336,6 +1359,7 @@ impl Config {
13361359
root_ratoml: None,
13371360
root_ratoml_path,
13381361
detached_files: Default::default(),
1362+
validation_errors: Default::default(),
13391363
}
13401364
}
13411365

@@ -2575,6 +2599,7 @@ macro_rules! _impl_for_config_data {
25752599
}
25762600
}
25772601

2602+
25782603
&self.default_config.global.$field
25792604
}
25802605
)*
@@ -3304,7 +3329,7 @@ fn validate_toml_table(
33043329
ptr.push_str(k);
33053330

33063331
match v {
3307-
// This is a table config, any entry in it is therefor valid
3332+
// This is a table config, any entry in it is therefore valid
33083333
toml::Value::Table(_) if verify(ptr) => (),
33093334
toml::Value::Table(table) => validate_toml_table(known_ptrs, table, ptr, error_sink),
33103335
_ if !verify(ptr) => error_sink

src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use ide_db::base_db::{SourceDatabase, SourceDatabaseExt, VfsPath};
1414
use lsp_server::{Connection, Notification, Request};
1515
use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
1616
use stdx::thread::ThreadIntent;
17-
use tracing::{span, Level};
17+
use tracing::{error, span, Level};
1818
use vfs::{AbsPathBuf, FileId};
1919

2020
use crate::{
@@ -674,7 +674,7 @@ impl GlobalState {
674674
self.fetch_workspaces_queue
675675
.op_completed(Some((workspaces, force_reload_crate_graph)));
676676
if let Err(e) = self.fetch_workspace_error() {
677-
tracing::error!("FetchWorkspaceError:\n{e}");
677+
error!("FetchWorkspaceError:\n{e}");
678678
}
679679
self.switch_workspaces("fetched workspace".to_owned());
680680
(Progress::End, None)
@@ -719,7 +719,7 @@ impl GlobalState {
719719
BuildDataProgress::End(build_data_result) => {
720720
self.fetch_build_data_queue.op_completed(build_data_result);
721721
if let Err(e) = self.fetch_build_data_error() {
722-
tracing::error!("FetchBuildDataError:\n{e}");
722+
error!("FetchBuildDataError:\n{e}");
723723
}
724724

725725
self.switch_workspaces("fetched build data".to_owned());
@@ -937,7 +937,7 @@ impl GlobalState {
937937
diag.fix,
938938
),
939939
Err(err) => {
940-
tracing::error!(
940+
error!(
941941
"flycheck {id}: File with cargo diagnostic not found in VFS: {}",
942942
err
943943
);

0 commit comments

Comments
 (0)