mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 14:13:58 +00:00
Try to support pre and post-change metavars
This commit is contained in:
parent
8753ca5360
commit
f48ecb6e09
21 changed files with 255 additions and 110 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -74,6 +74,7 @@ dependencies = [
|
||||||
"profile",
|
"profile",
|
||||||
"rust-analyzer-salsa",
|
"rust-analyzer-salsa",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
"semver",
|
||||||
"span",
|
"span",
|
||||||
"stdx",
|
"stdx",
|
||||||
"syntax",
|
"syntax",
|
||||||
|
|
|
@ -110,6 +110,7 @@ nohash-hasher = "0.2.0"
|
||||||
rayon = "1.8.0"
|
rayon = "1.8.0"
|
||||||
rust-analyzer-salsa = "0.17.0-pre.4"
|
rust-analyzer-salsa = "0.17.0-pre.4"
|
||||||
rustc-hash = "1.1.0"
|
rustc-hash = "1.1.0"
|
||||||
|
semver = "1.0.14"
|
||||||
serde = { version = "1.0.192", features = ["derive"] }
|
serde = { version = "1.0.192", features = ["derive"] }
|
||||||
serde_json = "1.0.108"
|
serde_json = "1.0.108"
|
||||||
smallvec = { version = "1.10.0", features = [
|
smallvec = { version = "1.10.0", features = [
|
||||||
|
|
|
@ -16,6 +16,7 @@ la-arena.workspace = true
|
||||||
rust-analyzer-salsa.workspace = true
|
rust-analyzer-salsa.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
triomphe.workspace = true
|
triomphe.workspace = true
|
||||||
|
semver.workspace = true
|
||||||
|
|
||||||
# local deps
|
# local deps
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::{fmt, mem, ops, str::FromStr};
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use la_arena::{Arena, Idx};
|
use la_arena::{Arena, Idx};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use semver::Version;
|
||||||
use syntax::SmolStr;
|
use syntax::SmolStr;
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
|
use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath};
|
||||||
|
@ -258,7 +259,7 @@ impl ReleaseChannel {
|
||||||
|
|
||||||
pub fn from_str(str: &str) -> Option<Self> {
|
pub fn from_str(str: &str) -> Option<Self> {
|
||||||
Some(match str {
|
Some(match str {
|
||||||
"" => ReleaseChannel::Stable,
|
"" | "stable" => ReleaseChannel::Stable,
|
||||||
"nightly" => ReleaseChannel::Nightly,
|
"nightly" => ReleaseChannel::Nightly,
|
||||||
_ if str.starts_with("beta") => ReleaseChannel::Beta,
|
_ if str.starts_with("beta") => ReleaseChannel::Beta,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
|
@ -289,7 +290,7 @@ pub struct CrateData {
|
||||||
// things. This info does need to be somewhat present though as to prevent deduplication from
|
// things. This info does need to be somewhat present though as to prevent deduplication from
|
||||||
// happening across different workspaces with different layouts.
|
// happening across different workspaces with different layouts.
|
||||||
pub target_layout: TargetLayoutLoadResult,
|
pub target_layout: TargetLayoutLoadResult,
|
||||||
pub channel: Option<ReleaseChannel>,
|
pub toolchain: Option<Version>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CrateData {
|
impl CrateData {
|
||||||
|
@ -346,6 +347,10 @@ impl CrateData {
|
||||||
|
|
||||||
slf_deps.eq(other_deps)
|
slf_deps.eq(other_deps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn channel(&self) -> Option<ReleaseChannel> {
|
||||||
|
self.toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -427,7 +432,7 @@ impl CrateGraph {
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
origin: CrateOrigin,
|
origin: CrateOrigin,
|
||||||
target_layout: Result<Arc<str>, Arc<str>>,
|
target_layout: Result<Arc<str>, Arc<str>>,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<Version>,
|
||||||
) -> CrateId {
|
) -> CrateId {
|
||||||
let data = CrateData {
|
let data = CrateData {
|
||||||
root_file_id,
|
root_file_id,
|
||||||
|
@ -441,7 +446,7 @@ impl CrateGraph {
|
||||||
origin,
|
origin,
|
||||||
target_layout,
|
target_layout,
|
||||||
is_proc_macro,
|
is_proc_macro,
|
||||||
channel,
|
toolchain,
|
||||||
};
|
};
|
||||||
self.arena.alloc(data)
|
self.arena.alloc(data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ pub use salsa::{self, Cancelled};
|
||||||
pub use span::{FilePosition, FileRange};
|
pub use span::{FilePosition, FileRange};
|
||||||
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
|
pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath};
|
||||||
|
|
||||||
|
pub use semver::{BuildMetadata, Prerelease, Version, VersionReq};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_intern_key {
|
macro_rules! impl_intern_key {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
//! Defines database & queries for macro expansion.
|
//! Defines database & queries for macro expansion.
|
||||||
|
|
||||||
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
salsa::{self, debug::DebugQueryTable},
|
salsa::{self, debug::DebugQueryTable},
|
||||||
CrateId, Edition, FileId, SourceDatabase,
|
CrateId, Edition, FileId, SourceDatabase, VersionReq,
|
||||||
};
|
};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use limit::Limit;
|
use limit::Limit;
|
||||||
|
@ -45,6 +47,9 @@ pub struct DeclarativeMacroExpander {
|
||||||
pub transparency: Transparency,
|
pub transparency: Transparency,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Remove this once we drop support for 1.76
|
||||||
|
static REQUIREMENT: OnceLock<VersionReq> = OnceLock::new();
|
||||||
|
|
||||||
impl DeclarativeMacroExpander {
|
impl DeclarativeMacroExpander {
|
||||||
pub fn expand(
|
pub fn expand(
|
||||||
&self,
|
&self,
|
||||||
|
@ -52,6 +57,18 @@ impl DeclarativeMacroExpander {
|
||||||
tt: tt::Subtree,
|
tt: tt::Subtree,
|
||||||
call_id: MacroCallId,
|
call_id: MacroCallId,
|
||||||
) -> ExpandResult<tt::Subtree> {
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
let toolchain = &db.crate_graph()[db.lookup_intern_macro_call(call_id).def.krate].toolchain;
|
||||||
|
let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
|
||||||
|
REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches(
|
||||||
|
&base_db::Version {
|
||||||
|
pre: base_db::Prerelease::EMPTY,
|
||||||
|
build: base_db::BuildMetadata::EMPTY,
|
||||||
|
major: version.major,
|
||||||
|
minor: version.minor,
|
||||||
|
patch: version.patch,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
match self.mac.err() {
|
match self.mac.err() {
|
||||||
Some(e) => ExpandResult::new(
|
Some(e) => ExpandResult::new(
|
||||||
tt::Subtree::empty(tt::DelimSpan::DUMMY),
|
tt::Subtree::empty(tt::DelimSpan::DUMMY),
|
||||||
|
@ -59,18 +76,39 @@ impl DeclarativeMacroExpander {
|
||||||
),
|
),
|
||||||
None => self
|
None => self
|
||||||
.mac
|
.mac
|
||||||
.expand(&tt, |s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency))
|
.expand(
|
||||||
|
&tt,
|
||||||
|
|s| s.ctx = apply_mark(db, s.ctx, call_id, self.transparency),
|
||||||
|
new_meta_vars,
|
||||||
|
)
|
||||||
.map_err(Into::into),
|
.map_err(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expand_unhygienic(&self, tt: tt::Subtree) -> ExpandResult<tt::Subtree> {
|
pub fn expand_unhygienic(
|
||||||
|
&self,
|
||||||
|
db: &dyn ExpandDatabase,
|
||||||
|
tt: tt::Subtree,
|
||||||
|
krate: CrateId,
|
||||||
|
) -> ExpandResult<tt::Subtree> {
|
||||||
|
let toolchain = &db.crate_graph()[krate].toolchain;
|
||||||
|
let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
|
||||||
|
REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches(
|
||||||
|
&base_db::Version {
|
||||||
|
pre: base_db::Prerelease::EMPTY,
|
||||||
|
build: base_db::BuildMetadata::EMPTY,
|
||||||
|
major: version.major,
|
||||||
|
minor: version.minor,
|
||||||
|
patch: version.patch,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
match self.mac.err() {
|
match self.mac.err() {
|
||||||
Some(e) => ExpandResult::new(
|
Some(e) => ExpandResult::new(
|
||||||
tt::Subtree::empty(tt::DelimSpan::DUMMY),
|
tt::Subtree::empty(tt::DelimSpan::DUMMY),
|
||||||
ExpandError::other(format!("invalid macro definition: {e}")),
|
ExpandError::other(format!("invalid macro definition: {e}")),
|
||||||
),
|
),
|
||||||
None => self.mac.expand(&tt, |_| ()).map_err(Into::into),
|
None => self.mac.expand(&tt, |_| (), new_meta_vars).map_err(Into::into),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -278,7 +316,7 @@ pub fn expand_speculative(
|
||||||
expander.expand(db, actual_macro_call, &adt, span_map)
|
expander.expand(db, actual_macro_call, &adt, span_map)
|
||||||
}
|
}
|
||||||
MacroDefKind::Declarative(it) => {
|
MacroDefKind::Declarative(it) => {
|
||||||
db.decl_macro_expander(loc.krate, it).expand_unhygienic(tt)
|
db.decl_macro_expander(loc.krate, it).expand_unhygienic(db, tt, loc.def.krate)
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltIn(it, _) => it.expand(db, actual_macro_call, &tt).map_err(Into::into),
|
MacroDefKind::BuiltIn(it, _) => it.expand(db, actual_macro_call, &tt).map_err(Into::into),
|
||||||
MacroDefKind::BuiltInEager(it, _) => {
|
MacroDefKind::BuiltInEager(it, _) => {
|
||||||
|
@ -525,7 +563,8 @@ fn decl_macro_expander(
|
||||||
def_crate: CrateId,
|
def_crate: CrateId,
|
||||||
id: AstId<ast::Macro>,
|
id: AstId<ast::Macro>,
|
||||||
) -> Arc<DeclarativeMacroExpander> {
|
) -> Arc<DeclarativeMacroExpander> {
|
||||||
let is_2021 = db.crate_graph()[def_crate].edition >= Edition::Edition2021;
|
let crate_data = &db.crate_graph()[def_crate];
|
||||||
|
let is_2021 = crate_data.edition >= Edition::Edition2021;
|
||||||
let (root, map) = parse_with_map(db, id.file_id);
|
let (root, map) = parse_with_map(db, id.file_id);
|
||||||
let root = root.syntax_node();
|
let root = root.syntax_node();
|
||||||
|
|
||||||
|
@ -549,13 +588,25 @@ fn decl_macro_expander(
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let toolchain = crate_data.toolchain.as_ref();
|
||||||
|
let new_meta_vars = toolchain.as_ref().map_or(false, |version| {
|
||||||
|
REQUIREMENT.get_or_init(|| VersionReq::parse(">=1.76").unwrap()).matches(
|
||||||
|
&base_db::Version {
|
||||||
|
pre: base_db::Prerelease::EMPTY,
|
||||||
|
build: base_db::BuildMetadata::EMPTY,
|
||||||
|
major: version.major,
|
||||||
|
minor: version.minor,
|
||||||
|
patch: version.patch,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let (mac, transparency) = match id.to_ptr(db).to_node(&root) {
|
let (mac, transparency) = match id.to_ptr(db).to_node(&root) {
|
||||||
ast::Macro::MacroRules(macro_rules) => (
|
ast::Macro::MacroRules(macro_rules) => (
|
||||||
match macro_rules.token_tree() {
|
match macro_rules.token_tree() {
|
||||||
Some(arg) => {
|
Some(arg) => {
|
||||||
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
|
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
|
||||||
let mac = mbe::DeclarativeMacro::parse_macro_rules(&tt, is_2021);
|
let mac = mbe::DeclarativeMacro::parse_macro_rules(&tt, is_2021, new_meta_vars);
|
||||||
mac
|
mac
|
||||||
}
|
}
|
||||||
None => mbe::DeclarativeMacro::from_err(
|
None => mbe::DeclarativeMacro::from_err(
|
||||||
|
@ -569,7 +620,7 @@ fn decl_macro_expander(
|
||||||
match macro_def.body() {
|
match macro_def.body() {
|
||||||
Some(arg) => {
|
Some(arg) => {
|
||||||
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
|
let tt = mbe::syntax_node_to_token_tree(arg.syntax(), map.as_ref());
|
||||||
let mac = mbe::DeclarativeMacro::parse_macro2(&tt, is_2021);
|
let mac = mbe::DeclarativeMacro::parse_macro2(&tt, is_2021, new_meta_vars);
|
||||||
mac
|
mac
|
||||||
}
|
}
|
||||||
None => mbe::DeclarativeMacro::from_err(
|
None => mbe::DeclarativeMacro::from_err(
|
||||||
|
|
|
@ -693,7 +693,7 @@ impl<'a> CompletionContext<'a> {
|
||||||
let krate = scope.krate();
|
let krate = scope.krate();
|
||||||
let module = scope.module();
|
let module = scope.module();
|
||||||
|
|
||||||
let toolchain = db.crate_graph()[krate.into()].channel;
|
let toolchain = db.crate_graph()[krate.into()].channel();
|
||||||
// `toolchain == None` means we're in some detached files. Since we have no information on
|
// `toolchain == None` means we're in some detached files. Since we have no information on
|
||||||
// the toolchain being used, let's just allow unstable items to be listed.
|
// the toolchain being used, let's just allow unstable items to be listed.
|
||||||
let is_nightly = matches!(toolchain, Some(base_db::ReleaseChannel::Nightly) | None);
|
let is_nightly = matches!(toolchain, Some(base_db::ReleaseChannel::Nightly) | None);
|
||||||
|
|
|
@ -492,7 +492,7 @@ fn get_doc_base_urls(
|
||||||
let Some(krate) = def.krate(db) else { return Default::default() };
|
let Some(krate) = def.krate(db) else { return Default::default() };
|
||||||
let Some(display_name) = krate.display_name(db) else { return Default::default() };
|
let Some(display_name) = krate.display_name(db) else { return Default::default() };
|
||||||
let crate_data = &db.crate_graph()[krate.into()];
|
let crate_data = &db.crate_graph()[krate.into()];
|
||||||
let channel = crate_data.channel.map_or("nightly", ReleaseChannel::as_str);
|
let channel = crate_data.channel().unwrap_or(ReleaseChannel::Nightly).as_str();
|
||||||
|
|
||||||
let (web_base, local_base) = match &crate_data.origin {
|
let (web_base, local_base) = match &crate_data.origin {
|
||||||
// std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself.
|
// std and co do not specify `html_root_url` any longer so we gotta handwrite this ourself.
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub(crate) fn shuffle_crate_graph(db: &mut RootDatabase) {
|
||||||
data.is_proc_macro,
|
data.is_proc_macro,
|
||||||
data.origin.clone(),
|
data.origin.clone(),
|
||||||
data.target_layout.clone(),
|
data.target_layout.clone(),
|
||||||
data.channel,
|
data.toolchain.clone(),
|
||||||
);
|
);
|
||||||
new_proc_macros.insert(new_id, proc_macros[&old_id].clone());
|
new_proc_macros.insert(new_id, proc_macros[&old_id].clone());
|
||||||
map.insert(old_id, new_id);
|
map.insert(old_id, new_id);
|
||||||
|
|
|
@ -20,7 +20,10 @@ fn benchmark_parse_macro_rules() {
|
||||||
let rules = macro_rules_fixtures_tt();
|
let rules = macro_rules_fixtures_tt();
|
||||||
let hash: usize = {
|
let hash: usize = {
|
||||||
let _pt = bench("mbe parse macro rules");
|
let _pt = bench("mbe parse macro rules");
|
||||||
rules.values().map(|it| DeclarativeMacro::parse_macro_rules(it, true).rules.len()).sum()
|
rules
|
||||||
|
.values()
|
||||||
|
.map(|it| DeclarativeMacro::parse_macro_rules(it, true, true).rules.len())
|
||||||
|
.sum()
|
||||||
};
|
};
|
||||||
assert_eq!(hash, 1144);
|
assert_eq!(hash, 1144);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +41,7 @@ fn benchmark_expand_macro_rules() {
|
||||||
invocations
|
invocations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(id, tt)| {
|
.map(|(id, tt)| {
|
||||||
let res = rules[&id].expand(&tt, |_| ());
|
let res = rules[&id].expand(&tt, |_| (), true);
|
||||||
assert!(res.err.is_none());
|
assert!(res.err.is_none());
|
||||||
res.value.token_trees.len()
|
res.value.token_trees.len()
|
||||||
})
|
})
|
||||||
|
@ -50,7 +53,7 @@ fn benchmark_expand_macro_rules() {
|
||||||
fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro<DummyTestSpanData>> {
|
fn macro_rules_fixtures() -> FxHashMap<String, DeclarativeMacro<DummyTestSpanData>> {
|
||||||
macro_rules_fixtures_tt()
|
macro_rules_fixtures_tt()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(id, tt)| (id, DeclarativeMacro::parse_macro_rules(&tt, true)))
|
.map(|(id, tt)| (id, DeclarativeMacro::parse_macro_rules(&tt, true, true)))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +108,7 @@ fn invocation_fixtures(
|
||||||
for op in rule.lhs.iter() {
|
for op in rule.lhs.iter() {
|
||||||
collect_from_op(op, &mut subtree, &mut seed);
|
collect_from_op(op, &mut subtree, &mut seed);
|
||||||
}
|
}
|
||||||
if it.expand(&subtree, |_| ()).err.is_none() {
|
if it.expand(&subtree, |_| (), true).err.is_none() {
|
||||||
res.push((name.clone(), subtree));
|
res.push((name.clone(), subtree));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub(crate) fn expand_rules<S: Span>(
|
||||||
input: &tt::Subtree<S>,
|
input: &tt::Subtree<S>,
|
||||||
marker: impl Fn(&mut S) + Copy,
|
marker: impl Fn(&mut S) + Copy,
|
||||||
is_2021: bool,
|
is_2021: bool,
|
||||||
|
new_meta_vars: bool,
|
||||||
) -> ExpandResult<tt::Subtree<S>> {
|
) -> ExpandResult<tt::Subtree<S>> {
|
||||||
let mut match_: Option<(matcher::Match<S>, &crate::Rule<S>)> = None;
|
let mut match_: Option<(matcher::Match<S>, &crate::Rule<S>)> = None;
|
||||||
for rule in rules {
|
for rule in rules {
|
||||||
|
@ -26,7 +27,7 @@ pub(crate) fn expand_rules<S: Span>(
|
||||||
// Unconditionally returning the transcription here makes the
|
// Unconditionally returning the transcription here makes the
|
||||||
// `test_repeat_bad_var` test fail.
|
// `test_repeat_bad_var` test fail.
|
||||||
let ExpandResult { value, err: transcribe_err } =
|
let ExpandResult { value, err: transcribe_err } =
|
||||||
transcriber::transcribe(&rule.rhs, &new_match.bindings, marker);
|
transcriber::transcribe(&rule.rhs, &new_match.bindings, marker, new_meta_vars);
|
||||||
if transcribe_err.is_none() {
|
if transcribe_err.is_none() {
|
||||||
return ExpandResult::ok(value);
|
return ExpandResult::ok(value);
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ pub(crate) fn expand_rules<S: Span>(
|
||||||
if let Some((match_, rule)) = match_ {
|
if let Some((match_, rule)) = match_ {
|
||||||
// if we got here, there was no match without errors
|
// if we got here, there was no match without errors
|
||||||
let ExpandResult { value, err: transcribe_err } =
|
let ExpandResult { value, err: transcribe_err } =
|
||||||
transcriber::transcribe(&rule.rhs, &match_.bindings, marker);
|
transcriber::transcribe(&rule.rhs, &match_.bindings, marker, new_meta_vars);
|
||||||
ExpandResult { value, err: match_.err.or(transcribe_err) }
|
ExpandResult { value, err: match_.err.or(transcribe_err) }
|
||||||
} else {
|
} else {
|
||||||
ExpandResult::new(
|
ExpandResult::new(
|
||||||
|
|
|
@ -131,8 +131,9 @@ pub(super) fn transcribe<S: Span>(
|
||||||
template: &MetaTemplate<S>,
|
template: &MetaTemplate<S>,
|
||||||
bindings: &Bindings<S>,
|
bindings: &Bindings<S>,
|
||||||
marker: impl Fn(&mut S) + Copy,
|
marker: impl Fn(&mut S) + Copy,
|
||||||
|
new_meta_vars: bool,
|
||||||
) -> ExpandResult<tt::Subtree<S>> {
|
) -> ExpandResult<tt::Subtree<S>> {
|
||||||
let mut ctx = ExpandCtx { bindings, nesting: Vec::new() };
|
let mut ctx = ExpandCtx { bindings, nesting: Vec::new(), new_meta_vars };
|
||||||
let mut arena: Vec<tt::TokenTree<S>> = Vec::new();
|
let mut arena: Vec<tt::TokenTree<S>> = Vec::new();
|
||||||
expand_subtree(&mut ctx, template, None, &mut arena, marker)
|
expand_subtree(&mut ctx, template, None, &mut arena, marker)
|
||||||
}
|
}
|
||||||
|
@ -152,6 +153,7 @@ struct NestingState {
|
||||||
struct ExpandCtx<'a, S> {
|
struct ExpandCtx<'a, S> {
|
||||||
bindings: &'a Bindings<S>,
|
bindings: &'a Bindings<S>,
|
||||||
nesting: Vec<NestingState>,
|
nesting: Vec<NestingState>,
|
||||||
|
new_meta_vars: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expand_subtree<S: Span>(
|
fn expand_subtree<S: Span>(
|
||||||
|
@ -284,7 +286,13 @@ fn expand_subtree<S: Span>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let c = match count(ctx, binding, 0, *depth) {
|
let res = if ctx.new_meta_vars {
|
||||||
|
count(ctx, binding, 0, depth.unwrap_or(0))
|
||||||
|
} else {
|
||||||
|
count_old(ctx, binding, 0, *depth)
|
||||||
|
};
|
||||||
|
|
||||||
|
let c = match res {
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// XXX: It *might* make sense to emit a dummy integer value like `0` here.
|
// XXX: It *might* make sense to emit a dummy integer value like `0` here.
|
||||||
|
@ -548,3 +556,32 @@ fn count<S>(
|
||||||
Binding::Fragment(_) | Binding::Missing(_) => Ok(1),
|
Binding::Fragment(_) | Binding::Missing(_) => Ok(1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn count_old<S>(
|
||||||
|
ctx: &ExpandCtx<'_, S>,
|
||||||
|
binding: &Binding<S>,
|
||||||
|
our_depth: usize,
|
||||||
|
count_depth: Option<usize>,
|
||||||
|
) -> Result<usize, CountError> {
|
||||||
|
match binding {
|
||||||
|
Binding::Nested(bs) => match count_depth {
|
||||||
|
None => bs.iter().map(|b| count_old(ctx, b, our_depth + 1, None)).sum(),
|
||||||
|
Some(0) => Ok(bs.len()),
|
||||||
|
Some(d) => bs.iter().map(|b| count_old(ctx, b, our_depth + 1, Some(d - 1))).sum(),
|
||||||
|
},
|
||||||
|
Binding::Empty => Ok(0),
|
||||||
|
Binding::Fragment(_) | Binding::Missing(_) => {
|
||||||
|
if our_depth == 0 {
|
||||||
|
// `${count(t)}` is placed inside the innermost repetition. This includes cases
|
||||||
|
// where `t` is not a repeated fragment.
|
||||||
|
Err(CountError::Misplaced)
|
||||||
|
} else if count_depth.is_none() {
|
||||||
|
Ok(1)
|
||||||
|
} else {
|
||||||
|
// We've reached at the innermost repeated fragment, but the user wants us to go
|
||||||
|
// further!
|
||||||
|
Err(CountError::OutOfBounds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -147,7 +147,12 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The old, `macro_rules! m {}` flavor.
|
/// The old, `macro_rules! m {}` flavor.
|
||||||
pub fn parse_macro_rules(tt: &tt::Subtree<S>, is_2021: bool) -> DeclarativeMacro<S> {
|
pub fn parse_macro_rules(
|
||||||
|
tt: &tt::Subtree<S>,
|
||||||
|
is_2021: bool,
|
||||||
|
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
|
||||||
|
new_meta_vars: bool,
|
||||||
|
) -> DeclarativeMacro<S> {
|
||||||
// Note: this parsing can be implemented using mbe machinery itself, by
|
// Note: this parsing can be implemented using mbe machinery itself, by
|
||||||
// matching against `$($lhs:tt => $rhs:tt);*` pattern, but implementing
|
// matching against `$($lhs:tt => $rhs:tt);*` pattern, but implementing
|
||||||
// manually seems easier.
|
// manually seems easier.
|
||||||
|
@ -156,7 +161,7 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
|
|
||||||
while src.len() > 0 {
|
while src.len() > 0 {
|
||||||
let rule = match Rule::parse(&mut src, true) {
|
let rule = match Rule::parse(&mut src, true, new_meta_vars) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err = Some(Box::new(e));
|
err = Some(Box::new(e));
|
||||||
|
@ -183,7 +188,12 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The new, unstable `macro m {}` flavor.
|
/// The new, unstable `macro m {}` flavor.
|
||||||
pub fn parse_macro2(tt: &tt::Subtree<S>, is_2021: bool) -> DeclarativeMacro<S> {
|
pub fn parse_macro2(
|
||||||
|
tt: &tt::Subtree<S>,
|
||||||
|
is_2021: bool,
|
||||||
|
// FIXME: Remove this once we drop support for rust 1.76 (defaults to true then)
|
||||||
|
new_meta_vars: bool,
|
||||||
|
) -> DeclarativeMacro<S> {
|
||||||
let mut src = TtIter::new(tt);
|
let mut src = TtIter::new(tt);
|
||||||
let mut rules = Vec::new();
|
let mut rules = Vec::new();
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
|
@ -191,7 +201,7 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
if tt::DelimiterKind::Brace == tt.delimiter.kind {
|
if tt::DelimiterKind::Brace == tt.delimiter.kind {
|
||||||
cov_mark::hit!(parse_macro_def_rules);
|
cov_mark::hit!(parse_macro_def_rules);
|
||||||
while src.len() > 0 {
|
while src.len() > 0 {
|
||||||
let rule = match Rule::parse(&mut src, true) {
|
let rule = match Rule::parse(&mut src, true, new_meta_vars) {
|
||||||
Ok(it) => it,
|
Ok(it) => it,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
err = Some(Box::new(e));
|
err = Some(Box::new(e));
|
||||||
|
@ -210,7 +220,7 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cov_mark::hit!(parse_macro_def_simple);
|
cov_mark::hit!(parse_macro_def_simple);
|
||||||
match Rule::parse(&mut src, false) {
|
match Rule::parse(&mut src, false, new_meta_vars) {
|
||||||
Ok(rule) => {
|
Ok(rule) => {
|
||||||
if src.len() != 0 {
|
if src.len() != 0 {
|
||||||
err = Some(Box::new(ParseError::expected("remaining tokens in macro def")));
|
err = Some(Box::new(ParseError::expected("remaining tokens in macro def")));
|
||||||
|
@ -241,13 +251,18 @@ impl<S: Span> DeclarativeMacro<S> {
|
||||||
&self,
|
&self,
|
||||||
tt: &tt::Subtree<S>,
|
tt: &tt::Subtree<S>,
|
||||||
marker: impl Fn(&mut S) + Copy,
|
marker: impl Fn(&mut S) + Copy,
|
||||||
|
new_meta_vars: bool,
|
||||||
) -> ExpandResult<tt::Subtree<S>> {
|
) -> ExpandResult<tt::Subtree<S>> {
|
||||||
expander::expand_rules(&self.rules, &tt, marker, self.is_2021)
|
expander::expand_rules(&self.rules, &tt, marker, self.is_2021, new_meta_vars)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Span> Rule<S> {
|
impl<S: Span> Rule<S> {
|
||||||
fn parse(src: &mut TtIter<'_, S>, expect_arrow: bool) -> Result<Self, ParseError> {
|
fn parse(
|
||||||
|
src: &mut TtIter<'_, S>,
|
||||||
|
expect_arrow: bool,
|
||||||
|
new_meta_vars: bool,
|
||||||
|
) -> Result<Self, ParseError> {
|
||||||
let lhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
|
let lhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
|
||||||
if expect_arrow {
|
if expect_arrow {
|
||||||
src.expect_char('=').map_err(|()| ParseError::expected("expected `=`"))?;
|
src.expect_char('=').map_err(|()| ParseError::expected("expected `=`"))?;
|
||||||
|
@ -256,7 +271,7 @@ impl<S: Span> Rule<S> {
|
||||||
let rhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
|
let rhs = src.expect_subtree().map_err(|()| ParseError::expected("expected subtree"))?;
|
||||||
|
|
||||||
let lhs = MetaTemplate::parse_pattern(lhs)?;
|
let lhs = MetaTemplate::parse_pattern(lhs)?;
|
||||||
let rhs = MetaTemplate::parse_template(rhs)?;
|
let rhs = MetaTemplate::parse_template(rhs, new_meta_vars)?;
|
||||||
|
|
||||||
Ok(crate::Rule { lhs, rhs })
|
Ok(crate::Rule { lhs, rhs })
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,23 +25,26 @@ pub(crate) struct MetaTemplate<S>(pub(crate) Box<[Op<S>]>);
|
||||||
|
|
||||||
impl<S: Span> MetaTemplate<S> {
|
impl<S: Span> MetaTemplate<S> {
|
||||||
pub(crate) fn parse_pattern(pattern: &tt::Subtree<S>) -> Result<Self, ParseError> {
|
pub(crate) fn parse_pattern(pattern: &tt::Subtree<S>) -> Result<Self, ParseError> {
|
||||||
MetaTemplate::parse(pattern, Mode::Pattern)
|
MetaTemplate::parse(pattern, Mode::Pattern, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse_template(template: &tt::Subtree<S>) -> Result<Self, ParseError> {
|
pub(crate) fn parse_template(
|
||||||
MetaTemplate::parse(template, Mode::Template)
|
template: &tt::Subtree<S>,
|
||||||
|
new_meta_vars: bool,
|
||||||
|
) -> Result<Self, ParseError> {
|
||||||
|
MetaTemplate::parse(template, Mode::Template, new_meta_vars)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn iter(&self) -> impl Iterator<Item = &Op<S>> {
|
pub(crate) fn iter(&self) -> impl Iterator<Item = &Op<S>> {
|
||||||
self.0.iter()
|
self.0.iter()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse(tt: &tt::Subtree<S>, mode: Mode) -> Result<Self, ParseError> {
|
fn parse(tt: &tt::Subtree<S>, mode: Mode, new_meta_vars: bool) -> Result<Self, ParseError> {
|
||||||
let mut src = TtIter::new(tt);
|
let mut src = TtIter::new(tt);
|
||||||
|
|
||||||
let mut res = Vec::new();
|
let mut res = Vec::new();
|
||||||
while let Some(first) = src.peek_n(0) {
|
while let Some(first) = src.peek_n(0) {
|
||||||
let op = next_op(first, &mut src, mode)?;
|
let op = next_op(first, &mut src, mode, new_meta_vars)?;
|
||||||
res.push(op);
|
res.push(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +54,35 @@ impl<S: Span> MetaTemplate<S> {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub(crate) enum Op<S> {
|
pub(crate) enum Op<S> {
|
||||||
Var { name: SmolStr, kind: Option<MetaVarKind>, id: S },
|
Var {
|
||||||
Ignore { name: SmolStr, id: S },
|
name: SmolStr,
|
||||||
Index { depth: usize },
|
kind: Option<MetaVarKind>,
|
||||||
Length { depth: usize },
|
id: S,
|
||||||
Count { name: SmolStr, depth: usize },
|
},
|
||||||
Repeat { tokens: MetaTemplate<S>, kind: RepeatKind, separator: Option<Separator<S>> },
|
Ignore {
|
||||||
Subtree { tokens: MetaTemplate<S>, delimiter: tt::Delimiter<S> },
|
name: SmolStr,
|
||||||
|
id: S,
|
||||||
|
},
|
||||||
|
Index {
|
||||||
|
depth: usize,
|
||||||
|
},
|
||||||
|
Length {
|
||||||
|
depth: usize,
|
||||||
|
},
|
||||||
|
Count {
|
||||||
|
name: SmolStr,
|
||||||
|
// FIXME: `usize`` once we drop support for 1.76
|
||||||
|
depth: Option<usize>,
|
||||||
|
},
|
||||||
|
Repeat {
|
||||||
|
tokens: MetaTemplate<S>,
|
||||||
|
kind: RepeatKind,
|
||||||
|
separator: Option<Separator<S>>,
|
||||||
|
},
|
||||||
|
Subtree {
|
||||||
|
tokens: MetaTemplate<S>,
|
||||||
|
delimiter: tt::Delimiter<S>,
|
||||||
|
},
|
||||||
Literal(tt::Literal<S>),
|
Literal(tt::Literal<S>),
|
||||||
Punct(SmallVec<[tt::Punct<S>; 3]>),
|
Punct(SmallVec<[tt::Punct<S>; 3]>),
|
||||||
Ident(tt::Ident<S>),
|
Ident(tt::Ident<S>),
|
||||||
|
@ -123,6 +148,7 @@ fn next_op<S: Span>(
|
||||||
first_peeked: &tt::TokenTree<S>,
|
first_peeked: &tt::TokenTree<S>,
|
||||||
src: &mut TtIter<'_, S>,
|
src: &mut TtIter<'_, S>,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
|
new_meta_vars: bool,
|
||||||
) -> Result<Op<S>, ParseError> {
|
) -> Result<Op<S>, ParseError> {
|
||||||
let res = match first_peeked {
|
let res = match first_peeked {
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Punct(p @ tt::Punct { char: '$', .. })) => {
|
tt::TokenTree::Leaf(tt::Leaf::Punct(p @ tt::Punct { char: '$', .. })) => {
|
||||||
|
@ -136,14 +162,14 @@ fn next_op<S: Span>(
|
||||||
tt::TokenTree::Subtree(subtree) => match subtree.delimiter.kind {
|
tt::TokenTree::Subtree(subtree) => match subtree.delimiter.kind {
|
||||||
tt::DelimiterKind::Parenthesis => {
|
tt::DelimiterKind::Parenthesis => {
|
||||||
let (separator, kind) = parse_repeat(src)?;
|
let (separator, kind) = parse_repeat(src)?;
|
||||||
let tokens = MetaTemplate::parse(subtree, mode)?;
|
let tokens = MetaTemplate::parse(subtree, mode, new_meta_vars)?;
|
||||||
Op::Repeat { tokens, separator, kind }
|
Op::Repeat { tokens, separator, kind }
|
||||||
}
|
}
|
||||||
tt::DelimiterKind::Brace => match mode {
|
tt::DelimiterKind::Brace => match mode {
|
||||||
Mode::Template => {
|
Mode::Template => {
|
||||||
parse_metavar_expr(&mut TtIter::new(subtree)).map_err(|()| {
|
parse_metavar_expr(new_meta_vars, &mut TtIter::new(subtree)).map_err(
|
||||||
ParseError::unexpected("invalid metavariable expression")
|
|()| ParseError::unexpected("invalid metavariable expression"),
|
||||||
})?
|
)?
|
||||||
}
|
}
|
||||||
Mode::Pattern => {
|
Mode::Pattern => {
|
||||||
return Err(ParseError::unexpected(
|
return Err(ParseError::unexpected(
|
||||||
|
@ -207,7 +233,7 @@ fn next_op<S: Span>(
|
||||||
|
|
||||||
tt::TokenTree::Subtree(subtree) => {
|
tt::TokenTree::Subtree(subtree) => {
|
||||||
src.next().expect("first token already peeked");
|
src.next().expect("first token already peeked");
|
||||||
let tokens = MetaTemplate::parse(subtree, mode)?;
|
let tokens = MetaTemplate::parse(subtree, mode, new_meta_vars)?;
|
||||||
Op::Subtree { tokens, delimiter: subtree.delimiter }
|
Op::Subtree { tokens, delimiter: subtree.delimiter }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -288,7 +314,7 @@ fn parse_repeat<S: Span>(
|
||||||
Err(ParseError::InvalidRepeat)
|
Err(ParseError::InvalidRepeat)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_metavar_expr<S: Span>(src: &mut TtIter<'_, S>) -> Result<Op<S>, ()> {
|
fn parse_metavar_expr<S: Span>(new_meta_vars: bool, src: &mut TtIter<'_, S>) -> Result<Op<S>, ()> {
|
||||||
let func = src.expect_ident()?;
|
let func = src.expect_ident()?;
|
||||||
let args = src.expect_subtree()?;
|
let args = src.expect_subtree()?;
|
||||||
|
|
||||||
|
@ -300,16 +326,20 @@ fn parse_metavar_expr<S: Span>(src: &mut TtIter<'_, S>) -> Result<Op<S>, ()> {
|
||||||
|
|
||||||
let op = match &*func.text {
|
let op = match &*func.text {
|
||||||
"ignore" => {
|
"ignore" => {
|
||||||
|
if new_meta_vars {
|
||||||
args.expect_dollar()?;
|
args.expect_dollar()?;
|
||||||
|
}
|
||||||
let ident = args.expect_ident()?;
|
let ident = args.expect_ident()?;
|
||||||
Op::Ignore { name: ident.text.clone(), id: ident.span }
|
Op::Ignore { name: ident.text.clone(), id: ident.span }
|
||||||
}
|
}
|
||||||
"index" => Op::Index { depth: parse_depth(&mut args)? },
|
"index" => Op::Index { depth: parse_depth(&mut args)? },
|
||||||
"length" => Op::Length { depth: parse_depth(&mut args)? },
|
"length" => Op::Length { depth: parse_depth(&mut args)? },
|
||||||
"count" => {
|
"count" => {
|
||||||
|
if new_meta_vars {
|
||||||
args.expect_dollar()?;
|
args.expect_dollar()?;
|
||||||
|
}
|
||||||
let ident = args.expect_ident()?;
|
let ident = args.expect_ident()?;
|
||||||
let depth = if try_eat_comma(&mut args) { parse_depth(&mut args)? } else { 0 };
|
let depth = if try_eat_comma(&mut args) { Some(parse_depth(&mut args)?) } else { None };
|
||||||
Op::Count { name: ident.text.clone(), depth }
|
Op::Count { name: ident.text.clone(), depth }
|
||||||
}
|
}
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
|
|
|
@ -15,7 +15,7 @@ doctest = false
|
||||||
anyhow.workspace = true
|
anyhow.workspace = true
|
||||||
cargo_metadata.workspace = true
|
cargo_metadata.workspace = true
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
semver = "1.0.14"
|
semver.workspace = true
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
|
|
@ -7,7 +7,7 @@ use std::{collections::VecDeque, fmt, fs, iter, process::Command, str::FromStr,
|
||||||
use anyhow::{format_err, Context};
|
use anyhow::{format_err, Context};
|
||||||
use base_db::{
|
use base_db::{
|
||||||
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, DependencyKind,
|
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, DependencyKind,
|
||||||
Edition, Env, FileId, LangCrateOrigin, ProcMacroPaths, ReleaseChannel, TargetLayoutLoadResult,
|
Edition, Env, FileId, LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
|
||||||
};
|
};
|
||||||
use cfg::{CfgDiff, CfgOptions};
|
use cfg::{CfgDiff, CfgOptions};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
|
@ -619,7 +619,7 @@ impl ProjectWorkspace {
|
||||||
sysroot.as_ref().ok(),
|
sysroot.as_ref().ok(),
|
||||||
extra_env,
|
extra_env,
|
||||||
Err("rust-project.json projects have no target layout set".into()),
|
Err("rust-project.json projects have no target layout set".into()),
|
||||||
toolchain.as_ref().and_then(|it| ReleaseChannel::from_str(it.pre.as_str())),
|
toolchain.clone(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ProjectWorkspace::Cargo {
|
ProjectWorkspace::Cargo {
|
||||||
|
@ -644,7 +644,7 @@ impl ProjectWorkspace {
|
||||||
Ok(it) => Ok(Arc::from(it.as_str())),
|
Ok(it) => Ok(Arc::from(it.as_str())),
|
||||||
Err(it) => Err(Arc::from(it.as_str())),
|
Err(it) => Err(Arc::from(it.as_str())),
|
||||||
},
|
},
|
||||||
toolchain.as_ref().and_then(|it| ReleaseChannel::from_str(it.pre.as_str())),
|
toolchain.as_ref(),
|
||||||
),
|
),
|
||||||
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
|
ProjectWorkspace::DetachedFiles { files, sysroot, rustc_cfg } => {
|
||||||
detached_files_to_crate_graph(
|
detached_files_to_crate_graph(
|
||||||
|
@ -733,7 +733,7 @@ fn project_json_to_crate_graph(
|
||||||
sysroot: Option<&Sysroot>,
|
sysroot: Option<&Sysroot>,
|
||||||
extra_env: &FxHashMap<String, String>,
|
extra_env: &FxHashMap<String, String>,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<Version>,
|
||||||
) -> (CrateGraph, ProcMacroPaths) {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||||
let (crate_graph, proc_macros) = &mut res;
|
let (crate_graph, proc_macros) = &mut res;
|
||||||
|
@ -744,7 +744,7 @@ fn project_json_to_crate_graph(
|
||||||
rustc_cfg.clone(),
|
rustc_cfg.clone(),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
load,
|
load,
|
||||||
channel,
|
toolchain.as_ref(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -807,7 +807,7 @@ fn project_json_to_crate_graph(
|
||||||
CrateOrigin::Local { repo: None, name: None }
|
CrateOrigin::Local { repo: None, name: None }
|
||||||
},
|
},
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
channel,
|
toolchain.clone(),
|
||||||
);
|
);
|
||||||
if *is_proc_macro {
|
if *is_proc_macro {
|
||||||
if let Some(path) = proc_macro_dylib_path.clone() {
|
if let Some(path) = proc_macro_dylib_path.clone() {
|
||||||
|
@ -853,7 +853,7 @@ fn cargo_to_crate_graph(
|
||||||
forced_cfg: Option<CfgOptions>,
|
forced_cfg: Option<CfgOptions>,
|
||||||
build_scripts: &WorkspaceBuildScripts,
|
build_scripts: &WorkspaceBuildScripts,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<&Version>,
|
||||||
) -> (CrateGraph, ProcMacroPaths) {
|
) -> (CrateGraph, ProcMacroPaths) {
|
||||||
let _p = profile::span("cargo_to_crate_graph");
|
let _p = profile::span("cargo_to_crate_graph");
|
||||||
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
let mut res = (CrateGraph::default(), ProcMacroPaths::default());
|
||||||
|
@ -866,7 +866,7 @@ fn cargo_to_crate_graph(
|
||||||
rustc_cfg.clone(),
|
rustc_cfg.clone(),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
load,
|
load,
|
||||||
channel,
|
toolchain,
|
||||||
),
|
),
|
||||||
None => (SysrootPublicDeps::default(), None),
|
None => (SysrootPublicDeps::default(), None),
|
||||||
};
|
};
|
||||||
|
@ -950,7 +950,7 @@ fn cargo_to_crate_graph(
|
||||||
is_proc_macro,
|
is_proc_macro,
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
false,
|
false,
|
||||||
channel,
|
toolchain.cloned(),
|
||||||
);
|
);
|
||||||
if kind == TargetKind::Lib {
|
if kind == TargetKind::Lib {
|
||||||
lib_tgt = Some((crate_id, name.clone()));
|
lib_tgt = Some((crate_id, name.clone()));
|
||||||
|
@ -1038,7 +1038,7 @@ fn cargo_to_crate_graph(
|
||||||
rustc_build_scripts
|
rustc_build_scripts
|
||||||
},
|
},
|
||||||
target_layout,
|
target_layout,
|
||||||
channel,
|
toolchain,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1117,7 +1117,7 @@ fn handle_rustc_crates(
|
||||||
override_cfg: &CfgOverrides,
|
override_cfg: &CfgOverrides,
|
||||||
build_scripts: &WorkspaceBuildScripts,
|
build_scripts: &WorkspaceBuildScripts,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<&Version>,
|
||||||
) {
|
) {
|
||||||
let mut rustc_pkg_crates = FxHashMap::default();
|
let mut rustc_pkg_crates = FxHashMap::default();
|
||||||
// The root package of the rustc-dev component is rustc_driver, so we match that
|
// The root package of the rustc-dev component is rustc_driver, so we match that
|
||||||
|
@ -1172,7 +1172,7 @@ fn handle_rustc_crates(
|
||||||
rustc_workspace[tgt].is_proc_macro,
|
rustc_workspace[tgt].is_proc_macro,
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
true,
|
true,
|
||||||
channel,
|
toolchain.cloned(),
|
||||||
);
|
);
|
||||||
pkg_to_lib_crate.insert(pkg, crate_id);
|
pkg_to_lib_crate.insert(pkg, crate_id);
|
||||||
// Add dependencies on core / std / alloc for this crate
|
// Add dependencies on core / std / alloc for this crate
|
||||||
|
@ -1248,7 +1248,7 @@ fn add_target_crate_root(
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
rustc_crate: bool,
|
rustc_crate: bool,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<Version>,
|
||||||
) -> CrateId {
|
) -> CrateId {
|
||||||
let edition = pkg.edition;
|
let edition = pkg.edition;
|
||||||
let potential_cfg_options = if pkg.features.is_empty() {
|
let potential_cfg_options = if pkg.features.is_empty() {
|
||||||
|
@ -1304,7 +1304,7 @@ fn add_target_crate_root(
|
||||||
CrateOrigin::Library { repo: pkg.repository.clone(), name: pkg.name.clone() }
|
CrateOrigin::Library { repo: pkg.repository.clone(), name: pkg.name.clone() }
|
||||||
},
|
},
|
||||||
target_layout,
|
target_layout,
|
||||||
channel,
|
toolchain,
|
||||||
);
|
);
|
||||||
if is_proc_macro {
|
if is_proc_macro {
|
||||||
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
|
let proc_macro = match build_data.as_ref().map(|it| it.proc_macro_dylib_path.as_ref()) {
|
||||||
|
@ -1346,7 +1346,7 @@ fn sysroot_to_crate_graph(
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
target_layout: TargetLayoutLoadResult,
|
target_layout: TargetLayoutLoadResult,
|
||||||
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<&Version>,
|
||||||
) -> (SysrootPublicDeps, Option<CrateId>) {
|
) -> (SysrootPublicDeps, Option<CrateId>) {
|
||||||
let _p = profile::span("sysroot_to_crate_graph");
|
let _p = profile::span("sysroot_to_crate_graph");
|
||||||
let cfg_options = create_cfg_options(rustc_cfg.clone());
|
let cfg_options = create_cfg_options(rustc_cfg.clone());
|
||||||
|
@ -1357,7 +1357,7 @@ fn sysroot_to_crate_graph(
|
||||||
rustc_cfg,
|
rustc_cfg,
|
||||||
cfg_options,
|
cfg_options,
|
||||||
target_layout,
|
target_layout,
|
||||||
channel,
|
toolchain,
|
||||||
crate_graph,
|
crate_graph,
|
||||||
sysroot,
|
sysroot,
|
||||||
),
|
),
|
||||||
|
@ -1380,7 +1380,7 @@ fn sysroot_to_crate_graph(
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
|
CrateOrigin::Lang(LangCrateOrigin::from(&*sysroot[krate].name)),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
channel,
|
toolchain.cloned(),
|
||||||
);
|
);
|
||||||
Some((krate, crate_id))
|
Some((krate, crate_id))
|
||||||
})
|
})
|
||||||
|
@ -1412,7 +1412,7 @@ fn handle_hack_cargo_workspace(
|
||||||
rustc_cfg: Vec<CfgFlag>,
|
rustc_cfg: Vec<CfgFlag>,
|
||||||
cfg_options: CfgOptions,
|
cfg_options: CfgOptions,
|
||||||
target_layout: Result<Arc<str>, Arc<str>>,
|
target_layout: Result<Arc<str>, Arc<str>>,
|
||||||
channel: Option<ReleaseChannel>,
|
toolchain: Option<&Version>,
|
||||||
crate_graph: &mut CrateGraph,
|
crate_graph: &mut CrateGraph,
|
||||||
sysroot: &Sysroot,
|
sysroot: &Sysroot,
|
||||||
) -> FxHashMap<SysrootCrate, CrateId> {
|
) -> FxHashMap<SysrootCrate, CrateId> {
|
||||||
|
@ -1426,7 +1426,7 @@ fn handle_hack_cargo_workspace(
|
||||||
Some(cfg_options),
|
Some(cfg_options),
|
||||||
&WorkspaceBuildScripts::default(),
|
&WorkspaceBuildScripts::default(),
|
||||||
target_layout,
|
target_layout,
|
||||||
channel,
|
toolchain,
|
||||||
);
|
);
|
||||||
crate_graph.extend(cg, &mut pm);
|
crate_graph.extend(cg, &mut pm);
|
||||||
for crate_name in ["std", "alloc", "core"] {
|
for crate_name in ["std", "alloc", "core"] {
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
1: CrateData {
|
1: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
2: CrateData {
|
2: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -208,7 +208,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
3: CrateData {
|
3: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
4: CrateData {
|
4: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -350,6 +350,6 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -62,7 +62,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
1: CrateData {
|
1: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
2: CrateData {
|
2: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -208,7 +208,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
3: CrateData {
|
3: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -281,7 +281,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
4: CrateData {
|
4: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -350,6 +350,6 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -61,7 +61,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
1: CrateData {
|
1: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
2: CrateData {
|
2: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
3: CrateData {
|
3: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -277,7 +277,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
4: CrateData {
|
4: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -346,6 +346,6 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"target_data_layout not loaded",
|
"target_data_layout not loaded",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -39,7 +39,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
1: CrateData {
|
1: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
2: CrateData {
|
2: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -105,7 +105,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
3: CrateData {
|
3: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -138,7 +138,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
4: CrateData {
|
4: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -188,7 +188,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
5: CrateData {
|
5: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -221,7 +221,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
6: CrateData {
|
6: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -319,7 +319,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
7: CrateData {
|
7: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -352,7 +352,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
8: CrateData {
|
8: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -385,7 +385,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
9: CrateData {
|
9: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -418,7 +418,7 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
10: CrateData {
|
10: CrateData {
|
||||||
root_file_id: FileId(
|
root_file_id: FileId(
|
||||||
|
@ -495,6 +495,6 @@
|
||||||
target_layout: Err(
|
target_layout: Err(
|
||||||
"rust-project.json projects have no target layout set",
|
"rust-project.json projects have no target layout set",
|
||||||
),
|
),
|
||||||
channel: None,
|
toolchain: None,
|
||||||
},
|
},
|
||||||
}
|
}
|
|
@ -3,8 +3,8 @@ use std::{mem, ops::Not, str::FromStr, sync};
|
||||||
|
|
||||||
use base_db::{
|
use base_db::{
|
||||||
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, DependencyKind,
|
CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, DependencyKind,
|
||||||
Edition, Env, FileChange, FileSet, LangCrateOrigin, ReleaseChannel, SourceDatabaseExt,
|
Edition, Env, FileChange, FileSet, LangCrateOrigin, SourceDatabaseExt, SourceRoot, Version,
|
||||||
SourceRoot, VfsPath,
|
VfsPath,
|
||||||
};
|
};
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
|
@ -120,12 +120,10 @@ impl ChangeFixture {
|
||||||
) -> ChangeFixture {
|
) -> ChangeFixture {
|
||||||
let FixtureWithProjectMeta { fixture, mini_core, proc_macro_names, toolchain } =
|
let FixtureWithProjectMeta { fixture, mini_core, proc_macro_names, toolchain } =
|
||||||
FixtureWithProjectMeta::parse(ra_fixture);
|
FixtureWithProjectMeta::parse(ra_fixture);
|
||||||
let toolchain = toolchain
|
let toolchain = Some({
|
||||||
.map(|it| {
|
let channel = toolchain.as_deref().unwrap_or("stable");
|
||||||
ReleaseChannel::from_str(&it)
|
Version::parse(&format!("1.76.0-{channel}")).unwrap()
|
||||||
.unwrap_or_else(|| panic!("unknown release channel found: {it}"))
|
});
|
||||||
})
|
|
||||||
.unwrap_or(ReleaseChannel::Stable);
|
|
||||||
let mut source_change = FileChange::new();
|
let mut source_change = FileChange::new();
|
||||||
|
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
@ -193,7 +191,7 @@ impl ChangeFixture {
|
||||||
.as_deref()
|
.as_deref()
|
||||||
.map(From::from)
|
.map(From::from)
|
||||||
.ok_or_else(|| "target_data_layout unset".into()),
|
.ok_or_else(|| "target_data_layout unset".into()),
|
||||||
Some(toolchain),
|
toolchain.clone(),
|
||||||
);
|
);
|
||||||
let prev = crates.insert(crate_name.clone(), crate_id);
|
let prev = crates.insert(crate_name.clone(), crate_id);
|
||||||
assert!(prev.is_none(), "multiple crates with same name: {}", crate_name);
|
assert!(prev.is_none(), "multiple crates with same name: {}", crate_name);
|
||||||
|
@ -233,7 +231,7 @@ impl ChangeFixture {
|
||||||
default_target_data_layout
|
default_target_data_layout
|
||||||
.map(|it| it.into())
|
.map(|it| it.into())
|
||||||
.ok_or_else(|| "target_data_layout unset".into()),
|
.ok_or_else(|| "target_data_layout unset".into()),
|
||||||
Some(toolchain),
|
toolchain.clone(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
for (from, to, prelude) in crate_deps {
|
for (from, to, prelude) in crate_deps {
|
||||||
|
@ -280,7 +278,7 @@ impl ChangeFixture {
|
||||||
false,
|
false,
|
||||||
CrateOrigin::Lang(LangCrateOrigin::Core),
|
CrateOrigin::Lang(LangCrateOrigin::Core),
|
||||||
target_layout.clone(),
|
target_layout.clone(),
|
||||||
Some(toolchain),
|
toolchain.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
for krate in all_crates {
|
for krate in all_crates {
|
||||||
|
@ -325,7 +323,7 @@ impl ChangeFixture {
|
||||||
true,
|
true,
|
||||||
CrateOrigin::Local { repo: None, name: None },
|
CrateOrigin::Local { repo: None, name: None },
|
||||||
target_layout,
|
target_layout,
|
||||||
Some(toolchain),
|
toolchain,
|
||||||
);
|
);
|
||||||
proc_macros.insert(proc_macros_crate, Ok(proc_macro));
|
proc_macros.insert(proc_macros_crate, Ok(proc_macro));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue