Skip to content

Commit 2f21ead

Browse files
Rollup merge of rust-lang#103579 - lnicola:rust-analyzer-2022-10-26, r=lnicola
⬆️ rust-analyzer r? `@ghost`
2 parents f619f01 + 22a6bc4 commit 2f21ead

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2221
-1584
lines changed

Diff for: src/tools/rust-analyzer/.github/workflows/publish.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ name: publish
22
on:
33
workflow_dispatch: # We can add version input when 1.0 is released and scheduled releases are removed
44

5-
# schedule:
6-
# - cron: "0 0 * * *" # midnight UTC
5+
# schedule:
6+
# - cron: "0 0 * * *" # midnight UTC
77

88
push:
99
branches:
@@ -50,5 +50,7 @@ jobs:
5050
cargo workspaces rename --from test-utils test_utils
5151
cargo workspaces rename --from text-edit text_edit
5252
cargo workspaces rename ra_ap_%n
53+
# Remove library crates from the workspaces so we don't auto-publish them as well
54+
sed -i 's/ "lib\/\*",//' ./Cargo.toml
5355
find crates/rust-analyzer -type f -name '*.rs' -exec sed -i 's/rust_analyzer/ra_ap_rust_analyzer/g' {} +
5456
cargo workspaces publish --yes --force '*' --exact --no-git-commit --allow-dirty --skip-published custom 0.0.$PATCH

Diff for: src/tools/rust-analyzer/crates/flycheck/src/lib.rs

+63-19
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,20 @@ pub use cargo_metadata::diagnostic::{
2121
DiagnosticSpanMacroExpansion,
2222
};
2323

24+
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
25+
pub enum InvocationStrategy {
26+
Once,
27+
#[default]
28+
PerWorkspace,
29+
}
30+
31+
#[derive(Clone, Debug, Default, PartialEq, Eq)]
32+
pub enum InvocationLocation {
33+
Root(AbsPathBuf),
34+
#[default]
35+
Workspace,
36+
}
37+
2438
#[derive(Clone, Debug, PartialEq, Eq)]
2539
pub enum FlycheckConfig {
2640
CargoCommand {
@@ -37,6 +51,8 @@ pub enum FlycheckConfig {
3751
command: String,
3852
args: Vec<String>,
3953
extra_env: FxHashMap<String, String>,
54+
invocation_strategy: InvocationStrategy,
55+
invocation_location: InvocationLocation,
4056
},
4157
}
4258

@@ -136,11 +152,15 @@ enum Restart {
136152
No,
137153
}
138154

155+
/// A [`FlycheckActor`] is a single check instance of a workspace.
139156
struct FlycheckActor {
157+
/// The workspace id of this flycheck instance.
140158
id: usize,
141159
sender: Box<dyn Fn(Message) + Send>,
142160
config: FlycheckConfig,
143-
workspace_root: AbsPathBuf,
161+
/// Either the workspace root of the workspace we are flychecking,
162+
/// or the project root of the project.
163+
root: AbsPathBuf,
144164
/// CargoHandle exists to wrap around the communication needed to be able to
145165
/// run `cargo check` without blocking. Currently the Rust standard library
146166
/// doesn't provide a way to read sub-process output without blocking, so we
@@ -162,11 +182,13 @@ impl FlycheckActor {
162182
workspace_root: AbsPathBuf,
163183
) -> FlycheckActor {
164184
tracing::info!(%id, ?workspace_root, "Spawning flycheck");
165-
FlycheckActor { id, sender, config, workspace_root, cargo_handle: None }
185+
FlycheckActor { id, sender, config, root: workspace_root, cargo_handle: None }
166186
}
167-
fn progress(&self, progress: Progress) {
187+
188+
fn report_progress(&self, progress: Progress) {
168189
self.send(Message::Progress { id: self.id, progress });
169190
}
191+
170192
fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
171193
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
172194
if let Ok(msg) = inbox.try_recv() {
@@ -178,6 +200,7 @@ impl FlycheckActor {
178200
recv(check_chan.unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())),
179201
}
180202
}
203+
181204
fn run(mut self, inbox: Receiver<Restart>) {
182205
'event: while let Some(event) = self.next_event(&inbox) {
183206
match event {
@@ -203,10 +226,10 @@ impl FlycheckActor {
203226
"did restart flycheck"
204227
);
205228
self.cargo_handle = Some(cargo_handle);
206-
self.progress(Progress::DidStart);
229+
self.report_progress(Progress::DidStart);
207230
}
208231
Err(error) => {
209-
self.progress(Progress::DidFailToRestart(format!(
232+
self.report_progress(Progress::DidFailToRestart(format!(
210233
"Failed to run the following command: {:?} error={}",
211234
self.check_command(),
212235
error
@@ -226,17 +249,17 @@ impl FlycheckActor {
226249
self.check_command()
227250
);
228251
}
229-
self.progress(Progress::DidFinish(res));
252+
self.report_progress(Progress::DidFinish(res));
230253
}
231254
Event::CheckEvent(Some(message)) => match message {
232255
CargoMessage::CompilerArtifact(msg) => {
233-
self.progress(Progress::DidCheckCrate(msg.target.name));
256+
self.report_progress(Progress::DidCheckCrate(msg.target.name));
234257
}
235258

236259
CargoMessage::Diagnostic(msg) => {
237260
self.send(Message::AddDiagnostic {
238261
id: self.id,
239-
workspace_root: self.workspace_root.clone(),
262+
workspace_root: self.root.clone(),
240263
diagnostic: msg,
241264
});
242265
}
@@ -254,12 +277,12 @@ impl FlycheckActor {
254277
"did cancel flycheck"
255278
);
256279
cargo_handle.cancel();
257-
self.progress(Progress::DidCancel);
280+
self.report_progress(Progress::DidCancel);
258281
}
259282
}
260283

261284
fn check_command(&self) -> Command {
262-
let mut cmd = match &self.config {
285+
let (mut cmd, args) = match &self.config {
263286
FlycheckConfig::CargoCommand {
264287
command,
265288
target_triple,
@@ -272,9 +295,7 @@ impl FlycheckActor {
272295
} => {
273296
let mut cmd = Command::new(toolchain::cargo());
274297
cmd.arg(command);
275-
cmd.current_dir(&self.workspace_root);
276-
cmd.args(&["--workspace", "--message-format=json", "--manifest-path"])
277-
.arg(self.workspace_root.join("Cargo.toml").as_os_str());
298+
cmd.args(&["--workspace", "--message-format=json"]);
278299

279300
if let Some(target) = target_triple {
280301
cmd.args(&["--target", target.as_str()]);
@@ -293,18 +314,41 @@ impl FlycheckActor {
293314
cmd.arg(features.join(" "));
294315
}
295316
}
296-
cmd.args(extra_args);
297317
cmd.envs(extra_env);
298-
cmd
318+
(cmd, extra_args)
299319
}
300-
FlycheckConfig::CustomCommand { command, args, extra_env } => {
320+
FlycheckConfig::CustomCommand {
321+
command,
322+
args,
323+
extra_env,
324+
invocation_strategy,
325+
invocation_location,
326+
} => {
301327
let mut cmd = Command::new(command);
302-
cmd.args(args);
303328
cmd.envs(extra_env);
304-
cmd
329+
330+
match invocation_location {
331+
InvocationLocation::Workspace => {
332+
match invocation_strategy {
333+
InvocationStrategy::Once => {
334+
cmd.current_dir(&self.root);
335+
}
336+
InvocationStrategy::PerWorkspace => {
337+
// FIXME: cmd.current_dir(&affected_workspace);
338+
cmd.current_dir(&self.root);
339+
}
340+
}
341+
}
342+
InvocationLocation::Root(root) => {
343+
cmd.current_dir(root);
344+
}
345+
}
346+
347+
(cmd, args)
305348
}
306349
};
307-
cmd.current_dir(&self.workspace_root);
350+
351+
cmd.args(args);
308352
cmd
309353
}
310354

Diff for: src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs

+26-10
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ fn test_copy_expand_simple() {
1212
#[derive(Copy)]
1313
struct Foo;
1414
"#,
15-
expect![[r##"
15+
expect![[r#"
1616
#[derive(Copy)]
1717
struct Foo;
1818
19-
impl < > core::marker::Copy for Foo< > {}"##]],
19+
impl < > core::marker::Copy for Foo< > {}"#]],
2020
);
2121
}
2222

@@ -33,15 +33,15 @@ macro Copy {}
3333
#[derive(Copy)]
3434
struct Foo;
3535
"#,
36-
expect![[r##"
36+
expect![[r#"
3737
#[rustc_builtin_macro]
3838
macro derive {}
3939
#[rustc_builtin_macro]
4040
macro Copy {}
4141
#[derive(Copy)]
4242
struct Foo;
4343
44-
impl < > crate ::marker::Copy for Foo< > {}"##]],
44+
impl < > crate ::marker::Copy for Foo< > {}"#]],
4545
);
4646
}
4747

@@ -53,11 +53,11 @@ fn test_copy_expand_with_type_params() {
5353
#[derive(Copy)]
5454
struct Foo<A, B>;
5555
"#,
56-
expect![[r##"
56+
expect![[r#"
5757
#[derive(Copy)]
5858
struct Foo<A, B>;
5959
60-
impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
60+
impl <T0: core::marker::Copy, T1: core::marker::Copy, > core::marker::Copy for Foo<T0, T1, > {}"#]],
6161
);
6262
}
6363

@@ -70,11 +70,11 @@ fn test_copy_expand_with_lifetimes() {
7070
#[derive(Copy)]
7171
struct Foo<A, B, 'a, 'b>;
7272
"#,
73-
expect![[r##"
73+
expect![[r#"
7474
#[derive(Copy)]
7575
struct Foo<A, B, 'a, 'b>;
7676
77-
impl <T0: core::marker::Copy, T1: core::marker::Copy> core::marker::Copy for Foo<T0, T1> {}"##]],
77+
impl <T0: core::marker::Copy, T1: core::marker::Copy, > core::marker::Copy for Foo<T0, T1, > {}"#]],
7878
);
7979
}
8080

@@ -86,10 +86,26 @@ fn test_clone_expand() {
8686
#[derive(Clone)]
8787
struct Foo<A, B>;
8888
"#,
89-
expect![[r##"
89+
expect![[r#"
9090
#[derive(Clone)]
9191
struct Foo<A, B>;
9292
93-
impl <T0: core::clone::Clone, T1: core::clone::Clone> core::clone::Clone for Foo<T0, T1> {}"##]],
93+
impl <T0: core::clone::Clone, T1: core::clone::Clone, > core::clone::Clone for Foo<T0, T1, > {}"#]],
94+
);
95+
}
96+
97+
#[test]
98+
fn test_clone_expand_with_const_generics() {
99+
check(
100+
r#"
101+
//- minicore: derive, clone
102+
#[derive(Clone)]
103+
struct Foo<const X: usize, T>(u32);
104+
"#,
105+
expect![[r#"
106+
#[derive(Clone)]
107+
struct Foo<const X: usize, T>(u32);
108+
109+
impl <const T0: usize, T1: core::clone::Clone, > core::clone::Clone for Foo<T0, T1, > {}"#]],
94110
);
95111
}

Diff for: src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs

+36-50
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander>
6060

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

6667
fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
@@ -92,65 +93,50 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
9293
let name_token_id =
9394
token_map.token_by_range(name.syntax().text_range()).unwrap_or_else(TokenId::unspecified);
9495
let name_token = tt::Ident { id: name_token_id, text: name.text().into() };
95-
let type_or_const_params =
96-
params.map_or(0, |type_param_list| type_param_list.type_or_const_params().count());
97-
Ok(BasicAdtInfo { name: name_token, type_or_const_params })
98-
}
99-
100-
fn make_type_args(n: usize, bound: Vec<tt::TokenTree>) -> Vec<tt::TokenTree> {
101-
let mut result = Vec::<tt::TokenTree>::with_capacity(n * 2);
102-
result.push(
103-
tt::Leaf::Punct(tt::Punct {
104-
char: '<',
105-
spacing: tt::Spacing::Alone,
106-
id: tt::TokenId::unspecified(),
107-
})
108-
.into(),
109-
);
110-
for i in 0..n {
111-
if i > 0 {
112-
result.push(
113-
tt::Leaf::Punct(tt::Punct {
114-
char: ',',
115-
spacing: tt::Spacing::Alone,
116-
id: tt::TokenId::unspecified(),
117-
})
118-
.into(),
119-
);
120-
}
121-
result.push(
122-
tt::Leaf::Ident(tt::Ident {
123-
id: tt::TokenId::unspecified(),
124-
text: format!("T{}", i).into(),
125-
})
126-
.into(),
127-
);
128-
result.extend(bound.iter().cloned());
129-
}
130-
result.push(
131-
tt::Leaf::Punct(tt::Punct {
132-
char: '>',
133-
spacing: tt::Spacing::Alone,
134-
id: tt::TokenId::unspecified(),
96+
let param_types = params
97+
.into_iter()
98+
.flat_map(|param_list| param_list.type_or_const_params())
99+
.map(|param| {
100+
if let ast::TypeOrConstParam::Const(param) = param {
101+
let ty = param
102+
.ty()
103+
.map(|ty| mbe::syntax_node_to_token_tree(ty.syntax()).0)
104+
.unwrap_or_default();
105+
Some(ty)
106+
} else {
107+
None
108+
}
135109
})
136-
.into(),
137-
);
138-
result
110+
.collect();
111+
Ok(BasicAdtInfo { name: name_token, param_types })
139112
}
140113

141114
fn expand_simple_derive(tt: &tt::Subtree, trait_path: tt::Subtree) -> ExpandResult<tt::Subtree> {
142115
let info = match parse_adt(tt) {
143116
Ok(info) => info,
144117
Err(e) => return ExpandResult::only_err(e),
145118
};
119+
let (params, args): (Vec<_>, Vec<_>) = info
120+
.param_types
121+
.into_iter()
122+
.enumerate()
123+
.map(|(idx, param_ty)| {
124+
let ident = tt::Leaf::Ident(tt::Ident {
125+
id: tt::TokenId::unspecified(),
126+
text: format!("T{idx}").into(),
127+
});
128+
let ident_ = ident.clone();
129+
if let Some(ty) = param_ty {
130+
(quote! { const #ident : #ty , }, quote! { #ident_ , })
131+
} else {
132+
let bound = trait_path.clone();
133+
(quote! { #ident : #bound , }, quote! { #ident_ , })
134+
}
135+
})
136+
.unzip();
146137
let name = info.name;
147-
let trait_path_clone = trait_path.token_trees.clone();
148-
let bound = (quote! { : ##trait_path_clone }).token_trees;
149-
let type_params = make_type_args(info.type_or_const_params, bound);
150-
let type_args = make_type_args(info.type_or_const_params, Vec::new());
151-
let trait_path = trait_path.token_trees;
152138
let expanded = quote! {
153-
impl ##type_params ##trait_path for #name ##type_args {}
139+
impl < ##params > #trait_path for #name < ##args > {}
154140
};
155141
ExpandResult::ok(expanded)
156142
}

0 commit comments

Comments
 (0)