Skip to content

Commit

Permalink
⬆️ rust-analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
lnicola committed Mar 13, 2023
2 parents d610b0c + 9549753 commit e862901
Show file tree
Hide file tree
Showing 217 changed files with 12,635 additions and 3,055 deletions.
2 changes: 2 additions & 0 deletions src/tools/rust-analyzer/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,7 @@ dependencies = [
"chalk-recursive",
"chalk-solve",
"cov-mark",
"either",
"ena",
"expect-test",
"hir-def",
Expand Down Expand Up @@ -1714,6 +1715,7 @@ name = "syntax"
version = "0.0.0"
dependencies = [
"cov-mark",
"either",
"expect-test",
"indexmap",
"itertools",
Expand Down
109 changes: 67 additions & 42 deletions src/tools/rust-analyzer/crates/flycheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl fmt::Display for FlycheckConfig {
#[derive(Debug)]
pub struct FlycheckHandle {
// XXX: drop order is significant
sender: Sender<Restart>,
sender: Sender<StateChange>,
_thread: jod_thread::JoinHandle,
id: usize,
}
Expand All @@ -89,7 +89,7 @@ impl FlycheckHandle {
workspace_root: AbsPathBuf,
) -> FlycheckHandle {
let actor = FlycheckActor::new(id, sender, config, workspace_root);
let (sender, receiver) = unbounded::<Restart>();
let (sender, receiver) = unbounded::<StateChange>();
let thread = jod_thread::Builder::new()
.name("Flycheck".to_owned())
.spawn(move || actor.run(receiver))
Expand All @@ -99,12 +99,12 @@ impl FlycheckHandle {

/// Schedule a re-start of the cargo check worker.
pub fn restart(&self) {
self.sender.send(Restart::Yes).unwrap();
self.sender.send(StateChange::Restart).unwrap();
}

/// Stop this cargo check worker.
pub fn cancel(&self) {
self.sender.send(Restart::No).unwrap();
self.sender.send(StateChange::Cancel).unwrap();
}

pub fn id(&self) -> usize {
Expand Down Expand Up @@ -149,9 +149,9 @@ pub enum Progress {
DidFailToRestart(String),
}

enum Restart {
Yes,
No,
enum StateChange {
Restart,
Cancel,
}

/// A [`FlycheckActor`] is a single check instance of a workspace.
Expand All @@ -172,7 +172,7 @@ struct FlycheckActor {
}

enum Event {
Restart(Restart),
RequestStateChange(StateChange),
CheckEvent(Option<CargoMessage>),
}

Expand All @@ -191,30 +191,31 @@ impl FlycheckActor {
self.send(Message::Progress { id: self.id, progress });
}

fn next_event(&self, inbox: &Receiver<Restart>) -> Option<Event> {
fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
let check_chan = self.cargo_handle.as_ref().map(|cargo| &cargo.receiver);
if let Ok(msg) = inbox.try_recv() {
// give restarts a preference so check outputs don't block a restart or stop
return Some(Event::Restart(msg));
return Some(Event::RequestStateChange(msg));
}
select! {
recv(inbox) -> msg => msg.ok().map(Event::Restart),
recv(inbox) -> msg => msg.ok().map(Event::RequestStateChange),
recv(check_chan.unwrap_or(&never())) -> msg => Some(Event::CheckEvent(msg.ok())),
}
}

fn run(mut self, inbox: Receiver<Restart>) {
fn run(mut self, inbox: Receiver<StateChange>) {
'event: while let Some(event) = self.next_event(&inbox) {
match event {
Event::Restart(Restart::No) => {
Event::RequestStateChange(StateChange::Cancel) => {
tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
self.cancel_check_process();
}
Event::Restart(Restart::Yes) => {
Event::RequestStateChange(StateChange::Restart) => {
// Cancel the previously spawned process
self.cancel_check_process();
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
// restart chained with a stop, so just cancel
if let Restart::No = restart {
if let StateChange::Cancel = restart {
continue 'event;
}
}
Expand Down Expand Up @@ -255,10 +256,20 @@ impl FlycheckActor {
}
Event::CheckEvent(Some(message)) => match message {
CargoMessage::CompilerArtifact(msg) => {
tracing::trace!(
flycheck_id = self.id,
artifact = msg.target.name,
"artifact received"
);
self.report_progress(Progress::DidCheckCrate(msg.target.name));
}

CargoMessage::Diagnostic(msg) => {
tracing::trace!(
flycheck_id = self.id,
message = msg.message,
"diagnostic received"
);
self.send(Message::AddDiagnostic {
id: self.id,
workspace_root: self.root.clone(),
Expand Down Expand Up @@ -445,42 +456,56 @@ impl CargoActor {
// simply skip a line if it doesn't parse, which just ignores any
// erroneous output.

let mut error = String::new();
let mut read_at_least_one_message = false;
let mut stdout_errors = String::new();
let mut stderr_errors = String::new();
let mut read_at_least_one_stdout_message = false;
let mut read_at_least_one_stderr_message = false;
let process_line = |line: &str, error: &mut String| {
// Try to deserialize a message from Cargo or Rustc.
let mut deserializer = serde_json::Deserializer::from_str(line);
deserializer.disable_recursion_limit();
if let Ok(message) = JsonMessage::deserialize(&mut deserializer) {
match message {
// Skip certain kinds of messages to only spend time on what's useful
JsonMessage::Cargo(message) => match message {
cargo_metadata::Message::CompilerArtifact(artifact) if !artifact.fresh => {
self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap();
}
cargo_metadata::Message::CompilerMessage(msg) => {
self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap();
}
_ => (),
},
JsonMessage::Rustc(message) => {
self.sender.send(CargoMessage::Diagnostic(message)).unwrap();
}
}
return true;
}

error.push_str(line);
error.push('\n');
return false;
};
let output = streaming_output(
self.stdout,
self.stderr,
&mut |line| {
read_at_least_one_message = true;

// Try to deserialize a message from Cargo or Rustc.
let mut deserializer = serde_json::Deserializer::from_str(line);
deserializer.disable_recursion_limit();
if let Ok(message) = JsonMessage::deserialize(&mut deserializer) {
match message {
// Skip certain kinds of messages to only spend time on what's useful
JsonMessage::Cargo(message) => match message {
cargo_metadata::Message::CompilerArtifact(artifact)
if !artifact.fresh =>
{
self.sender.send(CargoMessage::CompilerArtifact(artifact)).unwrap();
}
cargo_metadata::Message::CompilerMessage(msg) => {
self.sender.send(CargoMessage::Diagnostic(msg.message)).unwrap();
}
_ => (),
},
JsonMessage::Rustc(message) => {
self.sender.send(CargoMessage::Diagnostic(message)).unwrap();
}
}
if process_line(line, &mut stdout_errors) {
read_at_least_one_stdout_message = true;
}
},
&mut |line| {
error.push_str(line);
error.push('\n');
if process_line(line, &mut stderr_errors) {
read_at_least_one_stderr_message = true;
}
},
);

let read_at_least_one_message =
read_at_least_one_stdout_message || read_at_least_one_stderr_message;
let mut error = stdout_errors;
error.push_str(&stderr_errors);
match output {
Ok(_) => Ok((read_at_least_one_message, error)),
Err(e) => Err(io::Error::new(e.kind(), format!("{e:?}: {error}"))),
Expand Down
48 changes: 12 additions & 36 deletions src/tools/rust-analyzer/crates/hir-def/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ impl AttrsWithOwner {
AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
},
AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
AttrDefId::TraitAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
AttrDefId::MacroId(it) => match it {
MacroId::Macro2Id(it) => attrs_from_item_tree(it.lookup(db).id, db),
MacroId::MacroRulesId(it) => attrs_from_item_tree(it.lookup(db).id, db),
Expand All @@ -315,26 +316,14 @@ impl AttrsWithOwner {
let src = it.parent().child_source(db);
RawAttrs::from_attrs_owner(
db.upcast(),
src.with_value(src.value[it.local_id()].as_ref().either(
|it| match it {
ast::TypeOrConstParam::Type(it) => it as _,
ast::TypeOrConstParam::Const(it) => it as _,
},
|it| it as _,
)),
src.with_value(&src.value[it.local_id()]),
)
}
GenericParamId::TypeParamId(it) => {
let src = it.parent().child_source(db);
RawAttrs::from_attrs_owner(
db.upcast(),
src.with_value(src.value[it.local_id()].as_ref().either(
|it| match it {
ast::TypeOrConstParam::Type(it) => it as _,
ast::TypeOrConstParam::Const(it) => it as _,
},
|it| it as _,
)),
src.with_value(&src.value[it.local_id()]),
)
}
GenericParamId::LifetimeParamId(it) => {
Expand Down Expand Up @@ -404,6 +393,7 @@ impl AttrsWithOwner {
AttrDefId::StaticId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::ConstId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::TraitId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::TraitAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::TypeAliasId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::MacroId(id) => match id {
MacroId::Macro2Id(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
Expand All @@ -412,28 +402,14 @@ impl AttrsWithOwner {
},
AttrDefId::ImplId(id) => id.lookup(db).source(db).map(ast::AnyHasAttrs::new),
AttrDefId::GenericParamId(id) => match id {
GenericParamId::ConstParamId(id) => {
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
Either::Left(ast::TypeOrConstParam::Type(id)) => {
ast::AnyHasAttrs::new(id.clone())
}
Either::Left(ast::TypeOrConstParam::Const(id)) => {
ast::AnyHasAttrs::new(id.clone())
}
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
})
}
GenericParamId::TypeParamId(id) => {
id.parent().child_source(db).map(|source| match &source[id.local_id()] {
Either::Left(ast::TypeOrConstParam::Type(id)) => {
ast::AnyHasAttrs::new(id.clone())
}
Either::Left(ast::TypeOrConstParam::Const(id)) => {
ast::AnyHasAttrs::new(id.clone())
}
Either::Right(id) => ast::AnyHasAttrs::new(id.clone()),
})
}
GenericParamId::ConstParamId(id) => id
.parent()
.child_source(db)
.map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())),
GenericParamId::TypeParamId(id) => id
.parent()
.child_source(db)
.map(|source| ast::AnyHasAttrs::new(source[id.local_id()].clone())),
GenericParamId::LifetimeParamId(id) => id
.parent
.child_source(db)
Expand Down
31 changes: 14 additions & 17 deletions src/tools/rust-analyzer/crates/hir-def/src/body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use syntax::{ast, AstPtr, SyntaxNode, SyntaxNodePtr};
use crate::{
attr::Attrs,
db::DefDatabase,
expr::{dummy_expr_id, Expr, ExprId, Label, LabelId, Pat, PatId},
expr::{dummy_expr_id, Binding, BindingId, Expr, ExprId, Label, LabelId, Pat, PatId},
item_scope::BuiltinShadowMode,
macro_id_to_def_id,
nameres::DefMap,
Expand Down Expand Up @@ -270,7 +270,7 @@ pub struct Mark {
pub struct Body {
pub exprs: Arena<Expr>,
pub pats: Arena<Pat>,
pub or_pats: FxHashMap<PatId, Arc<[PatId]>>,
pub bindings: Arena<Binding>,
pub labels: Arena<Label>,
/// The patterns for the function's parameters. While the parameter types are
/// part of the function signature, the patterns are not (they don't change
Expand Down Expand Up @@ -409,18 +409,6 @@ impl Body {
.map(move |&block| (block, db.block_def_map(block).expect("block ID without DefMap")))
}

pub fn pattern_representative(&self, pat: PatId) -> PatId {
self.or_pats.get(&pat).and_then(|pats| pats.first().copied()).unwrap_or(pat)
}

/// Retrieves all ident patterns this pattern shares the ident with.
pub fn ident_patterns_for<'slf>(&'slf self, pat: &'slf PatId) -> &'slf [PatId] {
match self.or_pats.get(pat) {
Some(pats) => pats,
None => std::slice::from_ref(pat),
}
}

pub fn pretty_print(&self, db: &dyn DefDatabase, owner: DefWithBodyId) -> String {
pretty::print_body_hir(db, self, owner)
}
Expand All @@ -435,13 +423,14 @@ impl Body {
}

fn shrink_to_fit(&mut self) {
let Self { _c: _, body_expr: _, block_scopes, or_pats, exprs, labels, params, pats } = self;
let Self { _c: _, body_expr: _, block_scopes, exprs, labels, params, pats, bindings } =
self;
block_scopes.shrink_to_fit();
or_pats.shrink_to_fit();
exprs.shrink_to_fit();
labels.shrink_to_fit();
params.shrink_to_fit();
pats.shrink_to_fit();
bindings.shrink_to_fit();
}
}

Expand All @@ -451,7 +440,7 @@ impl Default for Body {
body_expr: dummy_expr_id(),
exprs: Default::default(),
pats: Default::default(),
or_pats: Default::default(),
bindings: Default::default(),
labels: Default::default(),
params: Default::default(),
block_scopes: Default::default(),
Expand Down Expand Up @@ -484,6 +473,14 @@ impl Index<LabelId> for Body {
}
}

impl Index<BindingId> for Body {
type Output = Binding;

fn index(&self, b: BindingId) -> &Binding {
&self.bindings[b]
}
}

// FIXME: Change `node_` prefix to something more reasonable.
// Perhaps `expr_syntax` and `expr_id`?
impl BodySourceMap {
Expand Down
Loading

0 comments on commit e862901

Please sign in to comment.