Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⬆️ rust-analyzer #103579

Merged
merged 53 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f310d4c
Don't auto-publish lib crates
Veykril Sep 27, 2022
d7fb8d5
Migrate assists to format args captures, part 2
DropDemBits Oct 10, 2022
d5f467a
Substitute some VSCode variables in the VSCode client
Veykril Oct 16, 2022
a2e4f78
Auto merge of #13399 - DropDemBits:assists-format-args-capture-pt2, r…
bors Oct 17, 2022
40cbeb5
Auto merge of #13423 - Veykril:vscode-vars, r=Veykril
bors Oct 17, 2022
f079792
Auto merge of #13302 - Veykril:auto-publish, r=Veykril
bors Oct 17, 2022
6f43597
Refactor language client handling
Veykril Oct 17, 2022
8aaafdd
Properly reload changed configs for server start
Veykril Oct 17, 2022
d68616a
Make more things private
Veykril Oct 17, 2022
0421756
Implement stop and start server commands
Veykril Oct 17, 2022
7b5c943
Downgrade vscode types dependency
Veykril Oct 17, 2022
d63c44e
Cleanup output channels
Veykril Oct 17, 2022
067c410
Auto merge of #13426 - Veykril:client-refactor, r=Veykril
bors Oct 17, 2022
e41023c
Make flycheck workdone progress reports cancellable
Veykril Oct 17, 2022
106285b
Auto merge of #13427 - Veykril:cancel-check, r=Veykril
bors Oct 17, 2022
a762bac
fix: Fix formatting requests hanging when r-a is still starting
Veykril Oct 17, 2022
4d4c05d
Auto merge of #13428 - Veykril:fmt-stuck, r=Veykril
bors Oct 17, 2022
8047512
Revert "feat: Diagnose some incorrect usages of the question mark ope…
Veykril Oct 18, 2022
97b357e
Auto merge of #13433 - rust-lang:revert-13354-try-stuff, r=Veykril
bors Oct 18, 2022
9d3e616
Simplify
Veykril Oct 19, 2022
3392573
Auto merge of #13439 - Veykril:simplify, r=Veykril
bors Oct 19, 2022
653dafa
Add some sysroot logging
Veykril Oct 19, 2022
82ac6f7
Auto merge of #13441 - Veykril:sysroot-logging, r=Veykril
bors Oct 19, 2022
7e2c41d
Implement invocation strategy config for build scripts
Veykril Aug 27, 2022
4a287d2
Implement invocation strategy config for checkOnSave
Veykril Sep 15, 2022
5174b65
Use correct invocation strategy config for checkOnSave
Veykril Sep 15, 2022
7db5029
{manifest-path} interpolation
Veykril Sep 26, 2022
4673236
Remove simplistic interpolation for manifest-path
Veykril Oct 19, 2022
a77ac93
Auto merge of #13128 - Veykril:invocation-strategy, r=Veykril
bors Oct 19, 2022
69b8456
Don't catch the server activation error
Veykril Oct 20, 2022
32614e2
Auto merge of #13444 - Veykril:rethrow-err, r=Veykril
bors Oct 20, 2022
5bff6c5
feat: add multiple getters mode in `generate_getter`
feniljain Oct 7, 2022
f3cce5f
Auto merge of #13365 - feniljain:master, r=Veykril
bors Oct 20, 2022
de195ff
fix: Fix DidSaveDocument requests blocking the server on startup
Veykril Oct 20, 2022
e05df93
Workaround the python vscode extension's polyfill
yotamofek Oct 20, 2022
7741e3d
Auto merge of #13448 - yotamofek:python-ext-polyfill-workaround, r=Ve…
bors Oct 20, 2022
2481721
Auto merge of #13447 - Veykril:didsavedoc-block, r=Veykril
bors Oct 20, 2022
a8e0a20
internal: Properly handle language configuration config changes
Veykril Oct 20, 2022
69f01fd
Auto merge of #13451 - Veykril:lang-config, r=Veykril
bors Oct 20, 2022
1cb4607
internal: Properly handle commands in the VSCode client when the serv…
Veykril Oct 21, 2022
8ee23f4
Auto merge of #13453 - Veykril:disabled-commands, r=Veykril
bors Oct 21, 2022
7ee7225
scip: minor clean-ups
emilio Oct 22, 2022
bd49d01
ide: Remove unnecessary continue.
emilio Oct 22, 2022
ec6d72b
scip: Rewrite tests to be closer to what we actually do.
emilio Oct 21, 2022
b643dd6
Auto merge of #13461 - emilio:ide-cleanup-continue, r=Veykril
bors Oct 22, 2022
d3b7e94
Auto merge of #13460 - emilio:scip-cleanups, r=Veykril
bors Oct 22, 2022
6459d7f
Support const generics for builtin derive macro
lowr Oct 22, 2022
19efa0b
Auto merge of #13463 - lowr:fix/builtin-derive-with-const-generics, r…
bors Oct 22, 2022
0f8904e
Implement invocation location config
Veykril Oct 22, 2022
b25f657
Auto merge of #13466 - Veykril:invocation-location, r=Veykril
bors Oct 22, 2022
859f559
Handle multiple projects sharing dependency correctly in `once` strategy
Veykril Oct 23, 2022
43fb956
Auto merge of #13471 - Veykril:invoc-strategy-once, r=Veykril
bors Oct 23, 2022
22a6bc4
:arrow_up: rust-analyzer
lnicola Oct 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/tools/rust-analyzer/.github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ name: publish
on:
workflow_dispatch: # We can add version input when 1.0 is released and scheduled releases are removed

# schedule:
# - cron: "0 0 * * *" # midnight UTC
# schedule:
# - cron: "0 0 * * *" # midnight UTC

push:
branches:
Expand Down Expand Up @@ -50,5 +50,7 @@ jobs:
cargo workspaces rename --from test-utils test_utils
cargo workspaces rename --from text-edit text_edit
cargo workspaces rename ra_ap_%n
# Remove library crates from the workspaces so we don't auto-publish them as well
sed -i 's/ "lib\/\*",//' ./Cargo.toml
find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} +
cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$PATCH
82 changes: 63 additions & 19 deletions src/tools/rust-analyzer/crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@ pub use cargo_metadata::diagnostic::{
DiagnosticSpanMacroExpansion,
};

#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
pub enum InvocationStrategy {
Once,
#[default]
PerWorkspace,
}

#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub enum InvocationLocation {
Root(AbsPathBuf),
#[default]
Workspace,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FlycheckConfig {
CargoCommand {
Expand All @@ -37,6 +51,8 @@ pub enum FlycheckConfig {
command: String,
args: Vec<String>,
extra_env: FxHashMap<String, String>,
invocation_strategy: InvocationStrategy,
invocation_location: InvocationLocation,
},
}

Expand Down Expand Up @@ -136,11 +152,15 @@ enum Restart {
No,
}

/// A [`FlycheckActor`] is a single check instance of a workspace.
struct FlycheckActor {
/// The workspace id of this flycheck instance.
id: usize,
sender: Box<dyn Fn(Message) + Send>,
config: FlycheckConfig,
workspace_root: AbsPathBuf,
/// Either the workspace root of the workspace we are flychecking,
/// or the project root of the project.
root: AbsPathBuf,
/// CargoHandle exists to wrap around the communication needed to be able to
/// run `cargo check` without blocking. Currently the Rust standard library
/// doesn't provide a way to read sub-process output without blocking, so we
Expand All @@ -162,11 +182,13 @@ impl FlycheckActor {
workspace_root: AbsPathBuf,
) -> FlycheckActor {
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
FlycheckActor { id, sender, config, root: workspace_root, cargo_handle: None }
}
fn progress(&self, progress: Progress) {

fn report_progress(&self, progress: Progress) {
self.send(Message::Progress { id: self.id, progress });
}

fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
if let Ok(msg) = inbox.try_recv() {
Expand All @@ -178,6 +200,7 @@ impl FlycheckActor {
recv(check_chan.unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())),
}
}

fn run(mut self, inbox: Receiver<Restart>) {
'event: while let Some(event) = self.next_event(&inbox) {
match event {
Expand All @@ -203,10 +226,10 @@ impl FlycheckActor {
"did restart flycheck"
);
self.cargo_handle = Some(cargo_handle);
self.progress(Progress::DidStart);
self.report_progress(Progress::DidStart);
}
Err(error) => {
self.progress(Progress::DidFailToRestart(format!(
self.report_progress(Progress::DidFailToRestart(format!(
"Failed to run the following command: {:?} error={}",
self.check_command(),
error
Expand All @@ -226,17 +249,17 @@ impl FlycheckActor {
self.check_command()
);
}
self.progress(Progress::DidFinish(res));
self.report_progress(Progress::DidFinish(res));
}
Event::CheckEvent(Some(message)) => match message {
CargoMessage::CompilerArtifact(msg) => {
self.progress(Progress::DidCheckCrate(msg.target.name));
self.report_progress(Progress::DidCheckCrate(msg.target.name));
}

CargoMessage::Diagnostic(msg) => {
self.send(Message::AddDiagnostic {
id: self.id,
workspace_root: self.workspace_root.clone(),
workspace_root: self.root.clone(),
diagnostic: msg,
});
}
Expand All @@ -254,12 +277,12 @@ impl FlycheckActor {
"did cancel flycheck"
);
cargo_handle.cancel();
self.progress(Progress::DidCancel);
self.report_progress(Progress::DidCancel);
}
}

fn check_command(&self) -> Command {
let mut cmd = match &self.config {
let (mut cmd, args) = match &self.config {
FlycheckConfig::CargoCommand {
command,
target_triple,
Expand All @@ -272,9 +295,7 @@ impl FlycheckActor {
} => {
let mut cmd = Command::new(toolchain::cargo());
cmd.arg(command);
cmd.current_dir(&self.workspace_root);
cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
.arg(self.workspace_root.join("Cargo.toml").as_os_str());
cmd.args(&["--workspace", "--message-format=json"]);

if let Some(target) = target_triple {
cmd.args(&["--target", target.as_str()]);
Expand All @@ -293,18 +314,41 @@ impl FlycheckActor {
cmd.arg(features.join(" "));
}
}
cmd.args(extra_args);
cmd.envs(extra_env);
cmd
(cmd, extra_args)
}
FlycheckConfig::CustomCommand { command, args, extra_env } => {
FlycheckConfig::CustomCommand {
command,
args,
extra_env,
invocation_strategy,
invocation_location,
} => {
let mut cmd = Command::new(command);
cmd.args(args);
cmd.envs(extra_env);
cmd

match invocation_location {
InvocationLocation::Workspace => {
match invocation_strategy {
InvocationStrategy::Once => {
cmd.current_dir(&self.root);
}
InvocationStrategy::PerWorkspace => {
// FIXME: cmd.current_dir(&affected_workspace);
cmd.current_dir(&self.root);
}
}
}
InvocationLocation::Root(root) => {
cmd.current_dir(root);
}
}

(cmd, args)
}
};
cmd.current_dir(&self.workspace_root);

cmd.args(args);
cmd
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ fn test_copy_expand_simple() {
#[derive(Copy)]
struct Foo;
"#,
expect![[r##"
expect![[r#"
#[derive(Copy)]
struct Foo;

impl < > core::marker::Copy for Foo< > {}"##]],
impl < > core::marker::Copy for Foo< > {}"#]],
);
}

Expand All @@ -33,15 +33,15 @@ macro Copy {}
#[derive(Copy)]
struct Foo;
"#,
expect![[r##"
expect![[r#"
#[rustc_builtin_macro]
macro derive {}
#[rustc_builtin_macro]
macro Copy {}
#[derive(Copy)]
struct Foo;

impl < > crate ::marker::Copy for Foo< > {}"##]],
impl < > crate ::marker::Copy for Foo< > {}"#]],
);
}

Expand All @@ -53,11 +53,11 @@ fn test_copy_expand_with_type_params() {
#[derive(Copy)]
struct Foo<A, B>;
"#,
expect![[r##"
expect![[r#"
#[derive(Copy)]
struct Foo<A, B>;

impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
impl <T0: core::marker::Copy, T1: core::marker::Copy, > core::marker::Copy for Foo<T0, T1, > {}"#]],
);
}

Expand All @@ -70,11 +70,11 @@ fn test_copy_expand_with_lifetimes() {
#[derive(Copy)]
struct Foo<A, B, 'a, 'b>;
"#,
expect![[r##"
expect![[r#"
#[derive(Copy)]
struct Foo<A, B, 'a, 'b>;

impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
impl <T0: core::marker::Copy, T1: core::marker::Copy, > core::marker::Copy for Foo<T0, T1, > {}"#]],
);
}

Expand All @@ -86,10 +86,26 @@ fn test_clone_expand() {
#[derive(Clone)]
struct Foo<A, B>;
"#,
expect![[r##"
expect![[r#"
#[derive(Clone)]
struct Foo<A, B>;

impl <T0: core::clone::Clone, T1: core::clone::Clone> core::clone::Clone for Foo<T0, T1> {}"##]],
impl <T0: core::clone::Clone, T1: core::clone::Clone, > core::clone::Clone for Foo<T0, T1, > {}"#]],
);
}

#[test]
fn test_clone_expand_with_const_generics() {
check(
r#"
//- minicore: derive, clone
#[derive(Clone)]
struct Foo<const X: usize, T>(u32);
"#,
expect![[r#"
#[derive(Clone)]
struct Foo<const X: usize, T>(u32);

impl <const T0: usize, T1: core::clone::Clone, > core::clone::Clone for Foo<T0, T1, > {}"#]],
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander>

struct BasicAdtInfo {
name: tt::Ident,
type_or_const_params: usize,
/// `Some(ty)` if it's a const param of type `ty`, `None` if it's a type param.
param_types: Vec<Option<tt::Subtree>>,
}

fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
Expand Down Expand Up @@ -92,65 +93,50 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
let name_token_id =
token_map.token_by_range(name.syntax().text_range()).unwrap_or_else(TokenId::unspecified);
let name_token = tt::Ident { id: name_token_id, text: name.text().into() };
let type_or_const_params =
params.map_or(0, |type_param_list| type_param_list.type_or_const_params().count());
Ok(BasicAdtInfo { name: name_token, type_or_const_params })
}

fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> {
let mut result = Vec::<tt::TokenTree>::with_capacity(n * 2);
result.push(
tt::Leaf::Punct(tt::Punct {
char: '<',
spacing: tt::Spacing::Alone,
id: tt::TokenId::unspecified(),
})
.into(),
);
for i in 0..n {
if i > 0 {
result.push(
tt::Leaf::Punct(tt::Punct {
char: ',',
spacing: tt::Spacing::Alone,
id: tt::TokenId::unspecified(),
})
.into(),
);
}
result.push(
tt::Leaf::Ident(tt::Ident {
id: tt::TokenId::unspecified(),
text: format!("T{}", i).into(),
})
.into(),
);
result.extend(bound.iter().cloned());
}
result.push(
tt::Leaf::Punct(tt::Punct {
char: '>',
spacing: tt::Spacing::Alone,
id: tt::TokenId::unspecified(),
let param_types = params
.into_iter()
.flat_map(|param_list| param_list.type_or_const_params())
.map(|param| {
if let ast::TypeOrConstParam::Const(param) = param {
let ty = param
.ty()
.map(|ty| mbe::syntax_node_to_token_tree(ty.syntax()).0)
.unwrap_or_default();
Some(ty)
} else {
None
}
})
.into(),
);
result
.collect();
Ok(BasicAdtInfo { name: name_token, param_types })
}

fn expand_simple_derive(tt: &tt::Subtree, trait_path: tt::Subtree) -> ExpandResult<tt::Subtree> {
let info = match parse_adt(tt) {
Ok(info) => info,
Err(e) => return ExpandResult::only_err(e),
};
let (params, args): (Vec<_>, Vec<_>) = info
.param_types
.into_iter()
.enumerate()
.map(|(idx, param_ty)| {
let ident = tt::Leaf::Ident(tt::Ident {
id: tt::TokenId::unspecified(),
text: format!("T{idx}").into(),
});
let ident_ = ident.clone();
if let Some(ty) = param_ty {
(quote! { const #ident : #ty , }, quote! { #ident_ , })
} else {
let bound = trait_path.clone();
(quote! { #ident : #bound , }, quote! { #ident_ , })
}
})
.unzip();
let name = info.name;
let trait_path_clone = trait_path.token_trees.clone();
let bound = (quote! { : ##trait_path_clone }).token_trees;
let type_params = make_type_args(info.type_or_const_params, bound);
let type_args = make_type_args(info.type_or_const_params, Vec::new());
let trait_path = trait_path.token_trees;
let expanded = quote! {
impl ##type_params ##trait_path for #name ##type_args {}
impl < ##params > #trait_path for #name < ##args > {}
};
ExpandResult::ok(expanded)
}
Expand Down
Loading