around the whole document, but we don't have that. */
+ position: relative;
+}
+
+a.doc-anchor {
+ color: black;
+ display: none;
+ position: absolute;
+ left: -20px;
+ /* We add this padding so that when the cursor moves from the heading's text to the anchor,
+ the anchor doesn't disappear. */
+ padding-right: 5px;
+ /* And this padding is used to make the anchor larger and easier to click on. */
+ padding-left: 3px;
+}
+*:hover > .doc-anchor {
+ display: block;
+}
+
+
/* Code */
pre, code {
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 12a421f3c45..83acce80f96 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -52,7 +52,7 @@
- [powerpc64-ibm-aix](platform-support/aix.md)
- [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md)
- [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md)
- - [riscv32*-unknown-none-elf](platform-support/riscv32imac-unknown-none-elf.md)
+ - [riscv32*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md)
- [sparc-unknown-none-elf](./platform-support/sparc-unknown-none-elf.md)
- [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md)
- [\*-nto-qnx-\*](platform-support/nto-qnx.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 2ebbf5e15e6..274745b9082 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -118,6 +118,7 @@ The `std` column in the table below has the following meanings:
* ✓ indicates the full standard library is available.
* \* indicates the target only supports [`no_std`] development.
+* ? indicates the standard library support is unknown or a work-in-progress.
[`no_std`]: https://rust-embedded.github.io/book/intro/no-std.html
@@ -140,7 +141,7 @@ target | std | notes
[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony
`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat
`aarch64-unknown-none` | * | Bare ARM64, hardfloat
-[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | * | ARM64 UEFI
+[`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI
[`arm-linux-androideabi`](platform-support/android.md) | ✓ | ARMv6 Android
`arm-unknown-linux-musleabi` | ✓ | ARMv6 Linux with musl 1.2.3
`arm-unknown-linux-musleabihf` | ✓ | ARMv6 Linux with musl 1.2.3, hardfloat
@@ -162,15 +163,15 @@ target | std | notes
[`i686-linux-android`](platform-support/android.md) | ✓ | 32-bit x86 Android [^x86_32-floats-return-ABI]
`i686-unknown-freebsd` | ✓ | 32-bit FreeBSD [^x86_32-floats-return-ABI]
`i686-unknown-linux-musl` | ✓ | 32-bit Linux with musl 1.2.3 [^x86_32-floats-return-ABI]
-[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI
+[`i686-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 32-bit UEFI
[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64D ABI)
[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | | LoongArch64 Bare-metal (LP64S ABI)
[`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs]
-[`riscv32imac-unknown-none-elf`](platform-support/riscv32imac-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA)
-[`riscv32i-unknown-none-elf`](platform-support/riscv32imac-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA)
-[`riscv32im-unknown-none-elf`](platform-support/riscv32imac-unknown-none-elf.md) | * | | Bare RISC-V (RV32IM ISA)
-[`riscv32imc-unknown-none-elf`](platform-support/riscv32imac-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA)
-[`riscv32imafc-unknown-none-elf`](platform-support/riscv32imac-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA)
+[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA)
+[`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA)
+[`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IM ISA)
+[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA)
+[`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA)
`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA)
`riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA)
`sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23)
@@ -199,7 +200,7 @@ target | std | notes
[`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony
[`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat
`x86_64-unknown-redox` | ✓ | Redox OS
-[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | * | 64-bit UEFI
+[`x86_64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | 64-bit UEFI
[^x86_32-floats-x87]: Floating-point support on `i586` targets is non-compliant: the `x87` registers and instructions used for these targets do not provide IEEE-754-compliant behavior, in particular when it comes to rounding and NaN payload bits. See [issue #114479][x86-32-float-issue].
[wasi-rename]: https://github.com/rust-lang/compiler-team/issues/607
diff --git a/src/doc/rustc/src/platform-support/riscv32imac-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md
similarity index 100%
rename from src/doc/rustc/src/platform-support/riscv32imac-unknown-none-elf.md
rename to src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md
diff --git a/src/doc/rustc/src/platform-support/riscv32i-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32i-unknown-none-elf.md
deleted file mode 100644
index edfe07fc053..00000000000
--- a/src/doc/rustc/src/platform-support/riscv32i-unknown-none-elf.md
+++ /dev/null
@@ -1 +0,0 @@
-riscv32imac-unknown-none-elf.md
diff --git a/src/doc/rustc/src/platform-support/riscv32im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32im-unknown-none-elf.md
deleted file mode 100644
index edfe07fc053..00000000000
--- a/src/doc/rustc/src/platform-support/riscv32im-unknown-none-elf.md
+++ /dev/null
@@ -1 +0,0 @@
-riscv32imac-unknown-none-elf.md
diff --git a/src/doc/rustc/src/platform-support/riscv32imafc-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32imafc-unknown-none-elf.md
deleted file mode 100644
index edfe07fc053..00000000000
--- a/src/doc/rustc/src/platform-support/riscv32imafc-unknown-none-elf.md
+++ /dev/null
@@ -1 +0,0 @@
-riscv32imac-unknown-none-elf.md
diff --git a/src/doc/rustc/src/platform-support/riscv32imc-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv32imc-unknown-none-elf.md
deleted file mode 100644
index edfe07fc053..00000000000
--- a/src/doc/rustc/src/platform-support/riscv32imc-unknown-none-elf.md
+++ /dev/null
@@ -1 +0,0 @@
-riscv32imac-unknown-none-elf.md
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index dfc026fe50b..855fb132fc8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1572,7 +1572,7 @@ fn first_non_private<'tcx>(
path: &hir::Path<'tcx>,
) -> Option
{
let target_def_id = path.res.opt_def_id()?;
- let (parent_def_id, ident) = match &path.segments[..] {
+ let (parent_def_id, ident) = match &path.segments {
[] => return None,
// Relative paths are available in the same scope as the owner.
[leaf] => (cx.tcx.local_parent(hir_id.owner.def_id), leaf.ident),
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 0b20cca3bca..365d63d9657 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -598,7 +598,7 @@ pub(crate) fn has_doc_flag(tcx: TyCtxt<'_>, did: DefId, flag: Symbol) -> bool {
/// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable.
pub(crate) const DOC_RUST_LANG_ORG_CHANNEL: &str = env!("DOC_RUST_LANG_ORG_CHANNEL");
pub(crate) static DOC_CHANNEL: Lazy<&'static str> =
- Lazy::new(|| DOC_RUST_LANG_ORG_CHANNEL.rsplit('/').filter(|c| !c.is_empty()).next().unwrap());
+ Lazy::new(|| DOC_RUST_LANG_ORG_CHANNEL.rsplit('/').find(|c| !c.is_empty()).unwrap());
/// Render a sequence of macro arms in a format suitable for displaying to the user
/// as part of an item declaration.
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 6c5040414bc..f1887684797 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -150,13 +150,13 @@ impl RenderType {
string.push('{');
write_optional_id(self.id, string);
string.push('{');
- for generic in &self.generics.as_ref().map(Vec::as_slice).unwrap_or_default()[..] {
+ for generic in &self.generics.as_deref().unwrap_or_default()[..] {
generic.write_to_string(string);
}
string.push('}');
if self.bindings.is_some() {
string.push('{');
- for binding in &self.bindings.as_ref().map(Vec::as_slice).unwrap_or_default()[..] {
+ for binding in &self.bindings.as_deref().unwrap_or_default()[..] {
string.push('{');
binding.0.write_to_string(string);
string.push('{');
diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs
index 451a44cd53a..524795ed77c 100644
--- a/src/librustdoc/passes/check_custom_code_classes.rs
+++ b/src/librustdoc/passes/check_custom_code_classes.rs
@@ -75,6 +75,7 @@ pub(crate) fn look_for_custom_classes<'tcx>(cx: &DocContext<'tcx>, item: &Item)
sym::custom_code_classes_in_docs,
GateIssue::Language,
false,
+ None,
);
err.note(
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index ea73d9afa2e..cebd2385656 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -290,14 +290,14 @@ impl NonCopyConst {
promoted: None,
};
let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx);
- let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None);
+ let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, rustc_span::DUMMY_SP);
self.is_value_unfrozen_raw(cx, result, ty)
}
fn is_value_unfrozen_expr<'tcx>(&self, cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool {
let args = cx.typeck_results().node_args(hir_id);
- let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), None);
+ let result = Self::const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), rustc_span::DUMMY_SP);
self.is_value_unfrozen_raw(cx, result, ty)
}
@@ -305,7 +305,7 @@ impl NonCopyConst {
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ct: ty::UnevaluatedConst<'tcx>,
- span: Option,
+ span: Span,
) -> EvalToValTreeResult<'tcx> {
match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) {
Ok(Some(instance)) => {
@@ -315,8 +315,8 @@ impl NonCopyConst {
};
tcx.const_eval_global_id_for_typeck(param_env, cid, span)
},
- Ok(None) => Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP))),
- Err(err) => Err(ErrorHandled::Reported(err.into(), span.unwrap_or(rustc_span::DUMMY_SP))),
+ Ok(None) => Err(ErrorHandled::TooGeneric(span)),
+ Err(err) => Err(ErrorHandled::Reported(err.into(), span)),
}
}
}
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 07ed4fbbf8e..e75d5953fae 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -550,7 +550,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
let result = self
.lcx
.tcx
- .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None)
+ .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
.ok()
.map(|val| rustc_middle::mir::Const::from_value(val, ty))?;
let result = mir_to_const(self.lcx, result)?;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index f427055728f..83c595ce241 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3734,36 +3734,42 @@ impl<'test> TestCx<'test> {
debug!(?support_lib_deps);
debug!(?support_lib_deps_deps);
- let res = self.cmd2procres(
- Command::new(&self.config.rustc_path)
- .arg("-o")
- .arg(&recipe_bin)
- .arg(format!(
- "-Ldependency={}",
- &support_lib_path.parent().unwrap().to_string_lossy()
- ))
- .arg(format!("-Ldependency={}", &support_lib_deps.to_string_lossy()))
- .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
- .arg("--extern")
- .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
- .arg(&self.testpaths.file.join("rmake.rs"))
- .env("TARGET", &self.config.target)
- .env("PYTHON", &self.config.python)
- .env("S", &src_root)
- .env("RUST_BUILD_STAGE", &self.config.stage_id)
- .env("RUSTC", cwd.join(&self.config.rustc_path))
- .env("TMPDIR", &tmpdir)
- .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
- .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
- .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
- .env("LLVM_COMPONENTS", &self.config.llvm_components)
- // We for sure don't want these tests to run in parallel, so make
- // sure they don't have access to these vars if we run via `make`
- // at the top level
- .env_remove("MAKEFLAGS")
- .env_remove("MFLAGS")
- .env_remove("CARGO_MAKEFLAGS"),
- );
+ let mut cmd = Command::new(&self.config.rustc_path);
+ cmd.arg("-o")
+ .arg(&recipe_bin)
+ .arg(format!("-Ldependency={}", &support_lib_path.parent().unwrap().to_string_lossy()))
+ .arg(format!("-Ldependency={}", &support_lib_deps.to_string_lossy()))
+ .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
+ .arg("--extern")
+ .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
+ .arg(&self.testpaths.file.join("rmake.rs"))
+ .env("TARGET", &self.config.target)
+ .env("PYTHON", &self.config.python)
+ .env("S", &src_root)
+ .env("RUST_BUILD_STAGE", &self.config.stage_id)
+ .env("RUSTC", cwd.join(&self.config.rustc_path))
+ .env("TMPDIR", &tmpdir)
+ .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
+ .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
+ .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
+ .env("LLVM_COMPONENTS", &self.config.llvm_components)
+ // We for sure don't want these tests to run in parallel, so make
+ // sure they don't have access to these vars if we run via `make`
+ // at the top level
+ .env_remove("MAKEFLAGS")
+ .env_remove("MFLAGS")
+ .env_remove("CARGO_MAKEFLAGS");
+
+ if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
+ let mut stage0_sysroot = build_root.clone();
+ stage0_sysroot.push("stage0-sysroot");
+ debug!(?stage0_sysroot);
+ debug!(exists = stage0_sysroot.exists());
+
+ cmd.arg("--sysroot").arg(&stage0_sysroot);
+ }
+
+ let res = self.cmd2procres(&mut cmd);
if !res.status.success() {
self.fatal_proc_rec("run-make test failed: could not build `rmake.rs` recipe", &res);
}
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 0f7200fb407..8d76a488269 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -5,7 +5,7 @@ use std::num::NonZero;
use smallvec::SmallVec;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_middle::{mir::RetagKind, ty::Ty};
+use rustc_middle::mir::RetagKind;
use rustc_target::abi::Size;
use crate::*;
@@ -291,19 +291,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}
- fn retag_box_to_raw(
- &mut self,
- val: &ImmTy<'tcx, Provenance>,
- alloc_ty: Ty<'tcx>,
- ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
- let this = self.eval_context_mut();
- let method = this.machine.borrow_tracker.as_ref().unwrap().borrow().borrow_tracker_method;
- match method {
- BorrowTrackerMethod::StackedBorrows => this.sb_retag_box_to_raw(val, alloc_ty),
- BorrowTrackerMethod::TreeBorrows => this.tb_retag_box_to_raw(val, alloc_ty),
- }
- }
-
fn retag_place_contents(
&mut self,
kind: RetagKind,
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 9130601bbdd..7a6a85a2f79 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -865,24 +865,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.sb_retag_reference(val, new_perm, RetagInfo { cause, in_field: false })
}
- fn sb_retag_box_to_raw(
- &mut self,
- val: &ImmTy<'tcx, Provenance>,
- alloc_ty: Ty<'tcx>,
- ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
- let this = self.eval_context_mut();
- let is_global_alloc = alloc_ty.ty_adt_def().is_some_and(|adt| {
- let global_alloc = this.tcx.require_lang_item(rustc_hir::LangItem::GlobalAlloc, None);
- adt.did() == global_alloc
- });
- if is_global_alloc {
- // Retag this as-if it was a mutable reference.
- this.sb_retag_ptr_value(RetagKind::Raw, val)
- } else {
- Ok(val.clone())
- }
- }
-
fn sb_retag_place_contents(
&mut self,
kind: RetagKind,
@@ -891,9 +873,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let this = self.eval_context_mut();
let retag_fields = this.machine.borrow_tracker.as_mut().unwrap().get_mut().retag_fields;
let retag_cause = match kind {
- RetagKind::Raw | RetagKind::TwoPhase { .. } => unreachable!(), // these can only happen in `retag_ptr_value`
+ RetagKind::TwoPhase { .. } => unreachable!(), // can only happen in `retag_ptr_value`
RetagKind::FnEntry => RetagCause::FnEntry,
- RetagKind::Default => RetagCause::Normal,
+ RetagKind::Default | RetagKind::Raw => RetagCause::Normal,
};
let mut visitor =
RetagVisitor { ecx: this, kind, retag_cause, retag_fields, in_field: false };
@@ -959,14 +941,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// Check the type of this value to see what to do with it (retag, or recurse).
match place.layout.ty.kind() {
- ty::Ref(..) => {
- let new_perm =
- NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx);
- self.retag_ptr_inplace(place, new_perm)?;
- }
- ty::RawPtr(..) => {
- // We do *not* want to recurse into raw pointers -- wide raw pointers have
- // fields, and for dyn Trait pointees those can have reference type!
+ ty::Ref(..) | ty::RawPtr(..) => {
+ if matches!(place.layout.ty.kind(), ty::Ref(..))
+ || self.kind == RetagKind::Raw
+ {
+ let new_perm =
+ NewPermission::from_ref_ty(place.layout.ty, self.kind, self.ecx);
+ self.retag_ptr_inplace(place, new_perm)?;
+ }
}
ty::Adt(adt, _) if adt.is_box() => {
// Recurse for boxes, they require some tricky handling and will end up in `visit_box` above.
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 9eb78b08ef7..80bdcbb7559 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -392,15 +392,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
}
- fn tb_retag_box_to_raw(
- &mut self,
- val: &ImmTy<'tcx, Provenance>,
- _alloc_ty: Ty<'tcx>,
- ) -> InterpResult<'tcx, ImmTy<'tcx, Provenance>> {
- // Casts to raw pointers are NOPs in Tree Borrows.
- Ok(val.clone())
- }
-
/// Retag all pointers that are stored in this place.
fn tb_retag_place_contents(
&mut self,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 7e5518392d8..3a4ab32e4ab 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1503,7 +1503,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
fn eval_mir_constant(
ecx: &InterpCx<'mir, 'tcx, Self>,
val: mir::Const<'tcx>,
- span: Option,
+ span: Span,
layout: Option>,
eval: F,
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>
@@ -1511,7 +1511,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
F: Fn(
&InterpCx<'mir, 'tcx, Self>,
mir::Const<'tcx>,
- Option,
+ Span,
Option>,
) -> InterpResult<'tcx, OpTy<'tcx, Self::Provenance>>,
{
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index 976d4b4de55..d16d5d99e9c 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -140,18 +140,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
}
- "retag_box_to_raw" => {
- let [ptr] = check_arg_count(args)?;
- let alloc_ty = generic_args[1].expect_ty();
-
- let val = this.read_immediate(ptr)?;
- let new_val = if this.machine.borrow_tracker.is_some() {
- this.retag_box_to_raw(&val, alloc_ty)?
- } else {
- val
- };
- this.write_immediate(*new_val, dest)?;
- }
// We want to return either `true` or `false` at random, or else something like
// ```
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index ddddcdcebd2..c97a052f517 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -549,7 +549,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let index = generic_args[2]
.expect_const()
- .eval(*this.tcx, this.param_env(), Some(this.tcx.span))
+ .eval(*this.tcx, this.param_env(), this.tcx.span)
.unwrap()
.unwrap_branch();
let index_len = index.len();
diff --git a/src/tools/miri/test-cargo-miri/tests/main.rs b/src/tools/miri/test-cargo-miri/tests/main.rs
index bb94c8f3787..72224e29619 100644
--- a/src/tools/miri/test-cargo-miri/tests/main.rs
+++ b/src/tools/miri/test-cargo-miri/tests/main.rs
@@ -1,3 +1 @@
-#![feature(imported_main)]
-
use cargo_miri_test::main;
diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
index c26c7f397b0..867907e98e6 100644
--- a/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/newtype_pair_retagging.stack.stderr
@@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: was created by a SharedReadWrite retag at offsets [0x0..0x4]
+help: was created by a Unique retag at offsets [0x0..0x4]
--> $DIR/newtype_pair_retagging.rs:LL:CC
|
LL | let ptr = Box::into_raw(Box::new(0i32));
diff --git a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
index ae54da70fe2..56715938e97 100644
--- a/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
+++ b/src/tools/miri/tests/fail/both_borrows/newtype_retagging.stack.stderr
@@ -6,7 +6,7 @@ LL | Box(unsafe { Unique::new_unchecked(raw) }, alloc)
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: was created by a SharedReadWrite retag at offsets [0x0..0x4]
+help: was created by a Unique retag at offsets [0x0..0x4]
--> $DIR/newtype_retagging.rs:LL:CC
|
LL | let ptr = Box::into_raw(Box::new(0i32));
diff --git a/src/tools/miri/tests/pass/imported_main.rs b/src/tools/miri/tests/pass/imported_main.rs
index 32b39152f78..eb93cd11d38 100644
--- a/src/tools/miri/tests/pass/imported_main.rs
+++ b/src/tools/miri/tests/pass/imported_main.rs
@@ -1,5 +1,3 @@
-#![feature(imported_main)]
-
pub mod foo {
pub fn mymain() {
println!("Hello, world!");
diff --git a/src/tools/miri/tests/pass/main_fn.rs b/src/tools/miri/tests/pass/main_fn.rs
index 3b84d1abe6f..4cdd034f30e 100644
--- a/src/tools/miri/tests/pass/main_fn.rs
+++ b/src/tools/miri/tests/pass/main_fn.rs
@@ -1,5 +1,3 @@
-#![feature(imported_main)]
-
mod foo {
pub(crate) fn bar() {}
}
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
index ac536d0fdde..dc0a6c2d91f 100644
--- a/src/tools/rust-analyzer/.github/workflows/release.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -36,7 +36,6 @@ jobs:
- os: ubuntu-20.04
target: x86_64-unknown-linux-gnu
code-target: linux-x64
- container: ubuntu:18.04
- os: ubuntu-20.04
target: aarch64-unknown-linux-gnu
code-target: linux-arm64
@@ -63,14 +62,6 @@ jobs:
with:
fetch-depth: ${{ env.FETCH_DEPTH }}
- - name: Install toolchain dependencies
- if: matrix.container == 'ubuntu:18.04'
- shell: bash
- run: |
- apt-get update && apt-get install -y build-essential curl
- curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y
- echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
-
- name: Install Rust toolchain
run: |
rustup update --no-self-update stable
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 903141eee9a..68ed32391b7 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -71,6 +71,7 @@ version = "0.0.0"
dependencies = [
"cfg",
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lz4_flex",
"rustc-hash",
"salsa",
"semver",
@@ -134,9 +135,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.89"
+version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0ba8f7aaa012f30d5b2861462f6708eccd49c3c39863fe083a308035f63d723"
+checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
[[package]]
name = "cfg"
@@ -874,9 +875,9 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libloading"
-version = "0.8.2"
+version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2caa5afb8bf9f3a2652760ce7d4f62d21c4d5a423e68466fca30df82f2330164"
+checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
dependencies = [
"cfg-if",
"windows-targets 0.52.4",
@@ -992,6 +993,12 @@ dependencies = [
"url",
]
+[[package]]
+name = "lz4_flex"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15"
+
[[package]]
name = "mbe"
version = "0.0.0"
@@ -1597,6 +1604,7 @@ dependencies = [
"rayon",
"rustc-hash",
"scip",
+ "semver",
"serde",
"serde_json",
"sourcegen",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 440f46a938b..0679522efd6 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -105,6 +105,10 @@ anyhow = "1.0.75"
arrayvec = "0.7.4"
bitflags = "2.4.1"
cargo_metadata = "0.18.1"
+chalk-solve = { version = "0.96.0", default-features = false }
+chalk-ir = "0.96.0"
+chalk-recursive = { version = "0.96.0", default-features = false }
+chalk-derive = "0.96.0"
command-group = "2.0.1"
crossbeam-channel = "0.5.8"
dissimilar = "1.0.7"
diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
index 118abf5d6eb..4ab99fc33c4 100644
--- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
@@ -12,6 +12,8 @@ rust-version.workspace = true
doctest = false
[dependencies]
+lz4_flex = { version = "0.11", default-features = false }
+
la-arena.workspace = true
salsa.workspace = true
rustc-hash.workspace = true
diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs
index 003ffb24d9d..f202a885e27 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/change.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs
@@ -7,13 +7,13 @@ use salsa::Durability;
use triomphe::Arc;
use vfs::FileId;
-use crate::{CrateGraph, SourceDatabaseExt, SourceRoot, SourceRootId};
+use crate::{CrateGraph, SourceDatabaseExt, SourceDatabaseExt2, SourceRoot, SourceRootId};
/// Encapsulate a bunch of raw `.set` calls on the database.
#[derive(Default)]
pub struct FileChange {
pub roots: Option>,
- pub files_changed: Vec<(FileId, Option>)>,
+ pub files_changed: Vec<(FileId, Option)>,
pub crate_graph: Option,
}
@@ -42,7 +42,7 @@ impl FileChange {
self.roots = Some(roots);
}
- pub fn change_file(&mut self, file_id: FileId, new_text: Option>) {
+ pub fn change_file(&mut self, file_id: FileId, new_text: Option) {
self.files_changed.push((file_id, new_text))
}
@@ -68,8 +68,8 @@ impl FileChange {
let source_root = db.source_root(source_root_id);
let durability = durability(&source_root);
// XXX: can't actually remove the file, just reset the text
- let text = text.unwrap_or_else(|| Arc::from(""));
- db.set_file_text_with_durability(file_id, text, durability)
+ let text = text.unwrap_or_default();
+ db.set_file_text_with_durability(file_id, &text, durability)
}
if let Some(crate_graph) = self.crate_graph {
db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH);
diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
index 758d2a45c8f..5dcb580723f 100644
--- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs
@@ -7,6 +7,7 @@ mod input;
use std::panic;
+use salsa::Durability;
use syntax::{ast, Parse, SourceFile};
use triomphe::Arc;
@@ -42,6 +43,7 @@ pub trait Upcast {
fn upcast(&self) -> &T;
}
+pub const DEFAULT_FILE_TEXT_LRU_CAP: usize = 16;
pub const DEFAULT_PARSE_LRU_CAP: usize = 128;
pub const DEFAULT_BORROWCK_LRU_CAP: usize = 1024;
@@ -89,7 +91,10 @@ fn parse(db: &dyn SourceDatabase, file_id: FileId) -> Parse {
#[salsa::query_group(SourceDatabaseExtStorage)]
pub trait SourceDatabaseExt: SourceDatabase {
#[salsa::input]
+ fn compressed_file_text(&self, file_id: FileId) -> Arc<[u8]>;
+
fn file_text(&self, file_id: FileId) -> Arc;
+
/// Path to a file, relative to the root of its source root.
/// Source root of the file.
#[salsa::input]
@@ -101,6 +106,44 @@ pub trait SourceDatabaseExt: SourceDatabase {
fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>;
}
+fn file_text(db: &dyn SourceDatabaseExt, file_id: FileId) -> Arc {
+ let bytes = db.compressed_file_text(file_id);
+ let bytes =
+ lz4_flex::decompress_size_prepended(&bytes).expect("lz4 decompression should not fail");
+ let text = std::str::from_utf8(&bytes).expect("file contents should be valid UTF-8");
+ Arc::from(text)
+}
+
+pub trait SourceDatabaseExt2 {
+ fn set_file_text(&mut self, file_id: FileId, text: &str) {
+ self.set_file_text_with_durability(file_id, text, Durability::LOW);
+ }
+
+ fn set_file_text_with_durability(
+ &mut self,
+ file_id: FileId,
+ text: &str,
+ durability: Durability,
+ );
+}
+
+impl SourceDatabaseExt2 for Db {
+ fn set_file_text_with_durability(
+ &mut self,
+ file_id: FileId,
+ text: &str,
+ durability: Durability,
+ ) {
+ let bytes = text.as_bytes();
+ let compressed = lz4_flex::compress_prepend_size(bytes);
+ self.set_compressed_file_text_with_durability(
+ file_id,
+ Arc::from(compressed.as_slice()),
+ durability,
+ )
+ }
+}
+
fn source_root_crates(db: &dyn SourceDatabaseExt, id: SourceRootId) -> Arc<[CrateId]> {
let graph = db.crate_graph();
let mut crates = graph
diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
index fbda065b10f..9b3a5026ac8 100644
--- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
@@ -31,4 +31,4 @@ mbe.workspace = true
syntax.workspace = true
[lints]
-workspace = true
\ No newline at end of file
+workspace = true
diff --git a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
index 4be6ae7481d..b7dbb7b5fdd 100644
--- a/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
+++ b/src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs
@@ -47,6 +47,7 @@ impl CfgExpr {
pub fn parse(tt: &tt::Subtree) -> CfgExpr {
next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
}
+
/// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option {
match self {
@@ -62,7 +63,6 @@ impl CfgExpr {
}
}
}
-
fn next_cfg_expr(it: &mut SliceIter<'_, tt::TokenTree>) -> Option {
let name = match it.next() {
None => return None,
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs b/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs
index 6dac5899ee3..31378716b3e 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs
+++ b/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs
@@ -28,19 +28,20 @@ pub enum CargoTestMessage {
},
Suite,
Finished,
+ Custom {
+ text: String,
+ },
}
impl ParseFromLine for CargoTestMessage {
- fn from_line(line: &str, error: &mut String) -> Option {
+ fn from_line(line: &str, _: &mut String) -> Option {
let mut deserializer = serde_json::Deserializer::from_str(line);
deserializer.disable_recursion_limit();
if let Ok(message) = CargoTestMessage::deserialize(&mut deserializer) {
return Some(message);
}
- error.push_str(line);
- error.push('\n');
- None
+ Some(CargoTestMessage::Custom { text: line.to_owned() })
}
fn from_eof() -> Option {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body.rs b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
index 37d37fd3311..c9f1add2751 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body.rs
@@ -10,7 +10,6 @@ use std::ops::Index;
use base_db::CrateId;
use cfg::{CfgExpr, CfgOptions};
-use either::Either;
use hir_expand::{name::Name, HirFileId, InFile};
use la_arena::{Arena, ArenaMap};
use rustc_hash::FxHashMap;
@@ -45,7 +44,8 @@ pub struct Body {
///
/// If this `Body` is for the body of a constant, this will just be
/// empty.
- pub params: Vec,
+ pub params: Box<[PatId]>,
+ pub self_param: Option,
/// The `ExprId` of the actual body expression.
pub body_expr: ExprId,
/// Block expressions in this body that may contain inner items.
@@ -55,7 +55,7 @@ pub struct Body {
pub type ExprPtr = AstPtr;
pub type ExprSource = InFile;
-pub type PatPtr = AstPtr>;
+pub type PatPtr = AstPtr;
pub type PatSource = InFile;
pub type LabelPtr = AstPtr;
@@ -63,6 +63,7 @@ pub type LabelSource = InFile;
pub type FieldPtr = AstPtr;
pub type FieldSource = InFile;
+
pub type PatFieldPtr = AstPtr;
pub type PatFieldSource = InFile;
@@ -88,6 +89,8 @@ pub struct BodySourceMap {
label_map: FxHashMap,
label_map_back: ArenaMap,
+ self_param: Option>>,
+
/// We don't create explicit nodes for record fields (`S { record_field: 92 }`).
/// Instead, we use id of expression (`92`) to identify the field.
field_map_back: FxHashMap,
@@ -215,10 +218,11 @@ impl Body {
fn shrink_to_fit(&mut self) {
let Self {
body_expr: _,
+ params: _,
+ self_param: _,
block_scopes,
exprs,
labels,
- params,
pats,
bindings,
binding_owners,
@@ -226,7 +230,6 @@ impl Body {
block_scopes.shrink_to_fit();
exprs.shrink_to_fit();
labels.shrink_to_fit();
- params.shrink_to_fit();
pats.shrink_to_fit();
bindings.shrink_to_fit();
binding_owners.shrink_to_fit();
@@ -297,6 +300,7 @@ impl Default for Body {
params: Default::default(),
block_scopes: Default::default(),
binding_owners: Default::default(),
+ self_param: Default::default(),
}
}
}
@@ -354,14 +358,12 @@ impl BodySourceMap {
self.pat_map_back.get(pat).cloned().ok_or(SyntheticSyntax)
}
- pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option {
- let src = node.map(|it| AstPtr::new(it).wrap_left());
- self.pat_map.get(&src).cloned()
+ pub fn self_param_syntax(&self) -> Option>> {
+ self.self_param
}
- pub fn node_self_param(&self, node: InFile<&ast::SelfParam>) -> Option {
- let src = node.map(|it| AstPtr::new(it).wrap_right());
- self.pat_map.get(&src).cloned()
+ pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option {
+ self.pat_map.get(&node.map(AstPtr::new)).cloned()
}
pub fn label_syntax(&self, label: LabelId) -> LabelSource {
@@ -401,6 +403,7 @@ impl BodySourceMap {
fn shrink_to_fit(&mut self) {
let Self {
+ self_param: _,
expr_map,
expr_map_back,
pat_map,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
index 66691277894..340e95dbc2f 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/lower.rs
@@ -4,7 +4,6 @@
use std::mem;
use base_db::CrateId;
-use either::Either;
use hir_expand::{
name::{name, AsName, Name},
ExpandError, InFile,
@@ -29,7 +28,6 @@ use crate::{
db::DefDatabase,
expander::Expander,
hir::{
- dummy_expr_id,
format_args::{
self, FormatAlignment, FormatArgs, FormatArgsPiece, FormatArgument, FormatArgumentKind,
FormatArgumentsCollector, FormatCount, FormatDebugHex, FormatOptions,
@@ -66,16 +64,7 @@ pub(super) fn lower(
def_map: expander.module.def_map(db),
source_map: BodySourceMap::default(),
ast_id_map: db.ast_id_map(expander.current_file_id()),
- body: Body {
- exprs: Default::default(),
- pats: Default::default(),
- bindings: Default::default(),
- binding_owners: Default::default(),
- labels: Default::default(),
- params: Vec::new(),
- body_expr: dummy_expr_id(),
- block_scopes: Vec::new(),
- },
+ body: Body::default(),
expander,
current_try_block_label: None,
is_lowering_assignee_expr: false,
@@ -191,35 +180,35 @@ impl ExprCollector<'_> {
is_async_fn: bool,
) -> (Body, BodySourceMap) {
if let Some((param_list, mut attr_enabled)) = param_list {
+ let mut params = vec![];
if let Some(self_param) =
param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
{
let is_mutable =
self_param.mut_token().is_some() && self_param.amp_token().is_none();
- let ptr = AstPtr::new(&Either::Right(self_param));
let binding_id: la_arena::Idx =
self.alloc_binding(name![self], BindingAnnotation::new(is_mutable, false));
- let param_pat = self.alloc_pat(Pat::Bind { id: binding_id, subpat: None }, ptr);
- self.add_definition_to_binding(binding_id, param_pat);
- self.body.params.push(param_pat);
+ self.body.self_param = Some(binding_id);
+ self.source_map.self_param = Some(self.expander.in_file(AstPtr::new(&self_param)));
}
for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled)
{
let param_pat = self.collect_pat_top(param.pat());
- self.body.params.push(param_pat);
+ params.push(param_pat);
}
+ self.body.params = params.into_boxed_slice();
};
self.body.body_expr = self.with_label_rib(RibKind::Closure, |this| {
if is_async_fn {
match body {
Some(e) => {
+ let syntax_ptr = AstPtr::new(&e);
let expr = this.collect_expr(e);
- this.alloc_expr_desugared(Expr::Async {
- id: None,
- statements: Box::new([]),
- tail: Some(expr),
- })
+ this.alloc_expr_desugared_with_ptr(
+ Expr::Async { id: None, statements: Box::new([]), tail: Some(expr) },
+ syntax_ptr,
+ )
}
None => this.missing_expr(),
}
@@ -405,7 +394,7 @@ impl ExprCollector<'_> {
}
ast::Expr::ParenExpr(e) => {
let inner = self.collect_expr_opt(e.expr());
- // make the paren expr point to the inner expression as well
+ // make the paren expr point to the inner expression as well for IDE resolution
let src = self.expander.in_file(syntax_ptr);
self.source_map.expr_map.insert(src, inner);
inner
@@ -707,6 +696,7 @@ impl ExprCollector<'_> {
.alloc_label_desugared(Label { name: Name::generate_new_name(self.body.labels.len()) });
let old_label = self.current_try_block_label.replace(label);
+ let ptr = AstPtr::new(&e).upcast();
let (btail, expr_id) = self.with_labeled_rib(label, |this| {
let mut btail = None;
let block = this.collect_block_(e, |id, statements, tail| {
@@ -716,23 +706,21 @@ impl ExprCollector<'_> {
(btail, block)
});
- let callee = self.alloc_expr_desugared(Expr::Path(try_from_output));
+ let callee = self.alloc_expr_desugared_with_ptr(Expr::Path(try_from_output), ptr);
let next_tail = match btail {
- Some(tail) => self.alloc_expr_desugared(Expr::Call {
- callee,
- args: Box::new([tail]),
- is_assignee_expr: false,
- }),
+ Some(tail) => self.alloc_expr_desugared_with_ptr(
+ Expr::Call { callee, args: Box::new([tail]), is_assignee_expr: false },
+ ptr,
+ ),
None => {
- let unit = self.alloc_expr_desugared(Expr::Tuple {
- exprs: Box::new([]),
- is_assignee_expr: false,
- });
- self.alloc_expr_desugared(Expr::Call {
- callee,
- args: Box::new([unit]),
- is_assignee_expr: false,
- })
+ let unit = self.alloc_expr_desugared_with_ptr(
+ Expr::Tuple { exprs: Box::new([]), is_assignee_expr: false },
+ ptr,
+ );
+ self.alloc_expr_desugared_with_ptr(
+ Expr::Call { callee, args: Box::new([unit]), is_assignee_expr: false },
+ ptr,
+ )
}
};
let Expr::Block { tail, .. } = &mut self.body.exprs[expr_id] else {
@@ -1067,16 +1055,12 @@ impl ExprCollector<'_> {
None => None,
},
);
- match expansion {
- Some(tail) => {
- // Make the macro-call point to its expanded expression so we can query
- // semantics on syntax pointers to the macro
- let src = self.expander.in_file(syntax_ptr);
- self.source_map.expr_map.insert(src, tail);
- Some(tail)
- }
- None => None,
- }
+ expansion.inspect(|&tail| {
+ // Make the macro-call point to its expanded expression so we can query
+ // semantics on syntax pointers to the macro
+ let src = self.expander.in_file(syntax_ptr);
+ self.source_map.expr_map.insert(src, tail);
+ })
}
fn collect_stmt(&mut self, statements: &mut Vec, s: ast::Stmt) {
@@ -1261,7 +1245,7 @@ impl ExprCollector<'_> {
(Some(id), Pat::Bind { id, subpat })
};
- let ptr = AstPtr::new(&Either::Left(pat));
+ let ptr = AstPtr::new(&pat);
let pat = self.alloc_pat(pattern, ptr);
if let Some(binding_id) = binding {
self.add_definition_to_binding(binding_id, pat);
@@ -1359,9 +1343,10 @@ impl ExprCollector<'_> {
suffix: suffix.into_iter().map(|p| self.collect_pat(p, binding_list)).collect(),
}
}
- #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5676
ast::Pat::LiteralPat(lit) => 'b: {
- let Some((hir_lit, ast_lit)) = pat_literal_to_hir(lit) else { break 'b Pat::Missing };
+ let Some((hir_lit, ast_lit)) = pat_literal_to_hir(lit) else {
+ break 'b Pat::Missing;
+ };
let expr = Expr::Literal(hir_lit);
let expr_ptr = AstPtr::new(&ast::Expr::Literal(ast_lit));
let expr_id = self.alloc_expr(expr, expr_ptr);
@@ -1397,7 +1382,7 @@ impl ExprCollector<'_> {
ast::Pat::MacroPat(mac) => match mac.macro_call() {
Some(call) => {
let macro_ptr = AstPtr::new(&call);
- let src = self.expander.in_file(AstPtr::new(&Either::Left(pat)));
+ let src = self.expander.in_file(AstPtr::new(&pat));
let pat =
self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
this.collect_pat_opt(expanded_pat, binding_list)
@@ -1426,7 +1411,7 @@ impl ExprCollector<'_> {
Pat::Range { start, end }
}
};
- let ptr = AstPtr::new(&Either::Left(pat));
+ let ptr = AstPtr::new(&pat);
self.alloc_pat(pattern, ptr)
}
@@ -1987,10 +1972,19 @@ impl ExprCollector<'_> {
self.source_map.expr_map.insert(src, id);
id
}
- // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed somehow.
+ // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed.
+ // Migrate to alloc_expr_desugared_with_ptr and then rename back
fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId {
self.body.exprs.alloc(expr)
}
+ fn alloc_expr_desugared_with_ptr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId {
+ let src = self.expander.in_file(ptr);
+ let id = self.body.exprs.alloc(expr);
+ self.source_map.expr_map_back.insert(id, src);
+ // We intentionally don't fill this as it could overwrite a non-desugared entry
+ // self.source_map.expr_map.insert(src, id);
+ id
+ }
fn missing_expr(&mut self) -> ExprId {
self.alloc_expr_desugared(Expr::Missing)
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
index b2aab55a6a8..cbb5ca887f4 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/pretty.rs
@@ -48,7 +48,16 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false };
if let DefWithBodyId::FunctionId(it) = owner {
p.buf.push('(');
- body.params.iter().zip(db.function_data(it).params.iter()).for_each(|(¶m, ty)| {
+ let params = &db.function_data(it).params;
+ let mut params = params.iter();
+ if let Some(self_param) = body.self_param {
+ p.print_binding(self_param);
+ p.buf.push(':');
+ if let Some(ty) = params.next() {
+ p.print_type_ref(ty);
+ }
+ }
+ body.params.iter().zip(params).for_each(|(¶m, ty)| {
p.print_pat(param);
p.buf.push(':');
p.print_type_ref(ty);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
index 69b82ae871a..0020e4eac30 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/body/scope.rs
@@ -96,6 +96,9 @@ impl ExprScopes {
scope_by_expr: ArenaMap::with_capacity(body.exprs.len()),
};
let mut root = scopes.root_scope();
+ if let Some(self_param) = body.self_param {
+ scopes.add_bindings(body, root, self_param);
+ }
scopes.add_params_bindings(body, root, &body.params);
compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
scopes
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs b/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
index f1c6b3b89fc..0b41984bdd8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/child_by_source.rs
@@ -76,7 +76,7 @@ impl ChildBySource for ItemScope {
self.extern_crate_decls()
.for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::EXTERN_CRATE));
self.use_decls().for_each(|ext| insert_item_loc(db, res, file_id, ext, keys::USE));
- self.unnamed_consts(db)
+ self.unnamed_consts()
.for_each(|konst| insert_item_loc(db, res, file_id, konst, keys::CONST));
self.attr_macro_invocs().filter(|(id, _)| id.file_id == file_id).for_each(
|(ast_id, call_id)| {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
index d4c1db8b95b..b815c9b73ef 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data.rs
@@ -715,7 +715,7 @@ impl<'a> AssocItemCollector<'a> {
}
AssocItem::MacroCall(call) => {
let file_id = self.expander.current_file_id();
- let MacroCall { ast_id, expand_to, call_site, ref path } = item_tree[call];
+ let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call];
let module = self.expander.module.local_id;
let resolver = |path| {
@@ -734,7 +734,7 @@ impl<'a> AssocItemCollector<'a> {
match macro_call_as_call_id(
self.db.upcast(),
&AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
- call_site,
+ ctxt,
expand_to,
self.expander.module.krate(),
resolver,
@@ -745,6 +745,7 @@ impl<'a> AssocItemCollector<'a> {
self.collect_macro_items(res, &|| hir_expand::MacroCallKind::FnLike {
ast_id: InFile::new(file_id, ast_id),
expand_to: hir_expand::ExpandTo::Items,
+ eager: None,
});
}
Ok(None) => (),
@@ -754,6 +755,7 @@ impl<'a> AssocItemCollector<'a> {
MacroCallKind::FnLike {
ast_id: InFile::new(file_id, ast_id),
expand_to,
+ eager: None,
},
Clone::clone(path),
));
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
index 5790e600f63..a7461b78af1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs
@@ -191,9 +191,9 @@ impl StructData {
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
- let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
+ let cfg_options = db.crate_graph()[krate].cfg_options.clone();
- let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
+ let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
let mut flags = StructFlags::NO_FLAGS;
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
@@ -248,9 +248,9 @@ impl StructData {
let krate = loc.container.krate;
let item_tree = loc.id.item_tree(db);
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
- let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
+ let cfg_options = db.crate_graph()[krate].cfg_options.clone();
- let attrs = item_tree.attrs(db, loc.container.krate, ModItem::from(loc.id.value).into());
+ let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into());
let mut flags = StructFlags::NO_FLAGS;
if attrs.by_key("rustc_has_incoherent_inherent_impls").exists() {
flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL;
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
index 544ed6bc347..30d52d87f19 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs
@@ -309,13 +309,9 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
local_inner: false,
allow_internal_unsafe: loc.allow_internal_unsafe,
- span: db
- .span_map(loc.id.file_id())
- .span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
edition: loc.edition,
}
}
-
MacroId::MacroRulesId(it) => {
let loc: MacroRulesLoc = it.lookup(db);
@@ -328,9 +324,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
allow_internal_unsafe: loc
.flags
.contains(MacroRulesLocFlags::ALLOW_INTERNAL_UNSAFE),
- span: db
- .span_map(loc.id.file_id())
- .span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
edition: loc.edition,
}
}
@@ -348,9 +341,6 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
),
local_inner: false,
allow_internal_unsafe: false,
- span: db
- .span_map(loc.id.file_id())
- .span_for_range(db.ast_id_map(loc.id.file_id()).get(makro.ast_id).text_range()),
edition: loc.edition,
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
index 0e6826a75a6..2b059d1f8dc 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_scope.rs
@@ -241,30 +241,8 @@ impl ItemScope {
})
}
- pub fn unnamed_consts<'a>(
- &'a self,
- db: &'a dyn DefDatabase,
- ) -> impl Iterator- + 'a {
- // FIXME: Also treat consts named `_DERIVE_*` as unnamed, since synstructure generates those.
- // Should be removed once synstructure stops doing that.
- let synstructure_hack_consts = self.values.values().filter_map(|(item, _, _)| match item {
- &ModuleDefId::ConstId(id) => {
- let loc = id.lookup(db);
- let item_tree = loc.id.item_tree(db);
- if item_tree[loc.id.value]
- .name
- .as_ref()
- .map_or(false, |n| n.to_smol_str().starts_with("_DERIVE_"))
- {
- Some(id)
- } else {
- None
- }
- }
- _ => None,
- });
-
- self.unnamed_consts.iter().copied().chain(synstructure_hack_consts)
+ pub fn unnamed_consts(&self) -> impl Iterator
- + '_ {
+ self.unnamed_consts.iter().copied()
}
/// Iterate over all module scoped macros
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
index bd3d377ec08..585e93ce21e 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs
@@ -49,7 +49,7 @@ use intern::Interned;
use la_arena::{Arena, Idx, IdxRange, RawIdx};
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
-use span::{AstIdNode, FileAstId, Span};
+use span::{AstIdNode, FileAstId, SyntaxContextId};
use stdx::never;
use syntax::{ast, match_ast, SyntaxKind};
use triomphe::Arc;
@@ -790,8 +790,7 @@ pub struct MacroCall {
pub path: Interned,
pub ast_id: FileAstId,
pub expand_to: ExpandTo,
- // FIXME: We need to move this out. It invalidates the item tree when typing inside the macro call.
- pub call_site: Span,
+ pub ctxt: SyntaxContextId,
}
#[derive(Debug, Clone, Eq, PartialEq)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
index bf3d54f4caf..f02163cbe44 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs
@@ -560,35 +560,32 @@ impl<'a> Ctx<'a> {
fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option> {
let span_map = self.span_map();
- let path = Interned::new(ModPath::from_src(self.db.upcast(), m.path()?, &mut |range| {
+ let path = m.path()?;
+ let range = path.syntax().text_range();
+ let path = Interned::new(ModPath::from_src(self.db.upcast(), path, &mut |range| {
span_map.span_for_range(range).ctx
})?);
let ast_id = self.source_ast_id_map.ast_id(m);
let expand_to = hir_expand::ExpandTo::from_call_site(m);
- let res = MacroCall {
- path,
- ast_id,
- expand_to,
- call_site: span_map.span_for_range(m.syntax().text_range()),
- };
+ let res = MacroCall { path, ast_id, expand_to, ctxt: span_map.span_for_range(range).ctx };
Some(id(self.data().macro_calls.alloc(res)))
}
fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option> {
- let name = m.name().map(|it| it.as_name())?;
+ let name = m.name()?;
let ast_id = self.source_ast_id_map.ast_id(m);
- let res = MacroRules { name, ast_id };
+ let res = MacroRules { name: name.as_name(), ast_id };
Some(id(self.data().macro_rules.alloc(res)))
}
fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option> {
- let name = m.name().map(|it| it.as_name())?;
+ let name = m.name()?;
let ast_id = self.source_ast_id_map.ast_id(m);
let visibility = self.lower_visibility(m);
- let res = Macro2 { name, ast_id, visibility };
+ let res = Macro2 { name: name.as_name(), ast_id, visibility };
Some(id(self.data().macro_defs.alloc(res)))
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
index 87c90a4c6ab..953bf6b85d6 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/pretty.rs
@@ -487,12 +487,12 @@ impl Printer<'_> {
}
}
ModItem::MacroCall(it) => {
- let MacroCall { path, ast_id, expand_to, call_site } = &self.tree[it];
+ let MacroCall { path, ast_id, expand_to, ctxt } = &self.tree[it];
let _ = writeln!(
self,
- "// AstId: {:?}, Span: {}, ExpandTo: {:?}",
+ "// AstId: {:?}, SyntaxContext: {}, ExpandTo: {:?}",
ast_id.erase().into_raw(),
- call_site,
+ ctxt,
expand_to
);
wln!(self, "{}!(...);", path.display(self.db.upcast()));
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
index 26f7b41c77a..48da876ac15 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree/tests.rs
@@ -278,7 +278,7 @@ m!();
// AstId: 2
pub macro m2 { ... }
- // AstId: 3, Span: 0:3@0..5#0, ExpandTo: Items
+ // AstId: 3, SyntaxContext: 0, ExpandTo: Items
m!(...);
"#]],
);
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
index d63f2268aa4..828842de7e8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs
@@ -90,7 +90,7 @@ use hir_expand::{
use item_tree::ExternBlock;
use la_arena::Idx;
use nameres::DefMap;
-use span::{AstIdNode, FileAstId, FileId, Span};
+use span::{AstIdNode, FileAstId, FileId, SyntaxContextId};
use stdx::impl_from;
use syntax::{ast, AstNode};
@@ -1342,21 +1342,22 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
let ast_id = AstId::new(self.file_id, db.ast_id_map(self.file_id).ast_id(self.value));
let span_map = db.span_map(self.file_id);
let path = self.value.path().and_then(|path| {
- path::ModPath::from_src(db, path, &mut |range| {
+ let range = path.syntax().text_range();
+ let mod_path = path::ModPath::from_src(db, path, &mut |range| {
span_map.as_ref().span_for_range(range).ctx
- })
+ })?;
+ let call_site = span_map.span_for_range(range);
+ Some((call_site, mod_path))
});
- let Some(path) = path else {
+ let Some((call_site, path)) = path else {
return Ok(ExpandResult::only_err(ExpandError::other("malformed macro invocation")));
};
- let call_site = span_map.span_for_range(self.value.syntax().text_range());
-
macro_call_as_call_id_with_eager(
db,
&AstIdWithPath::new(ast_id.file_id, ast_id.value, path),
- call_site,
+ call_site.ctx,
expands_to,
krate,
resolver,
@@ -1381,7 +1382,7 @@ impl AstIdWithPath {
fn macro_call_as_call_id(
db: &dyn ExpandDatabase,
call: &AstIdWithPath,
- call_site: Span,
+ call_site: SyntaxContextId,
expand_to: ExpandTo,
krate: CrateId,
resolver: impl Fn(path::ModPath) -> Option + Copy,
@@ -1393,7 +1394,7 @@ fn macro_call_as_call_id(
fn macro_call_as_call_id_with_eager(
db: &dyn ExpandDatabase,
call: &AstIdWithPath,
- call_site: Span,
+ call_site: SyntaxContextId,
expand_to: ExpandTo,
krate: CrateId,
resolver: impl FnOnce(path::ModPath) -> Option,
@@ -1403,17 +1404,20 @@ fn macro_call_as_call_id_with_eager(
resolver(call.path.clone()).ok_or_else(|| UnresolvedMacro { path: call.path.clone() })?;
let res = match def.kind {
- MacroDefKind::BuiltInEager(..) => {
- let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db));
- expand_eager_macro_input(db, krate, macro_call, def, call_site, &|path| {
- eager_resolver(path).filter(MacroDefId::is_fn_like)
- })
- }
+ MacroDefKind::BuiltInEager(..) => expand_eager_macro_input(
+ db,
+ krate,
+ &call.ast_id.to_node(db),
+ call.ast_id,
+ def,
+ call_site,
+ &|path| eager_resolver(path).filter(MacroDefId::is_fn_like),
+ ),
_ if def.is_fn_like() => ExpandResult {
- value: Some(def.as_lazy_macro(
+ value: Some(def.make_call(
db,
krate,
- MacroCallKind::FnLike { ast_id: call.ast_id, expand_to },
+ MacroCallKind::FnLike { ast_id: call.ast_id, expand_to, eager: None },
call_site,
)),
err: None,
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
index 86b4466153a..89c1b446081 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
@@ -528,3 +528,121 @@ impl < > $crate::fmt::Debug for Command< > where {
}"#]],
);
}
+#[test]
+fn test_debug_expand_with_cfg() {
+ check(
+ r#"
+ //- minicore: derive, fmt
+ use core::fmt::Debug;
+
+ #[derive(Debug)]
+ struct HideAndShow {
+ #[cfg(never)]
+ always_hide: u32,
+ #[cfg(not(never))]
+ always_show: u32,
+ }
+ #[derive(Debug)]
+ enum HideAndShowEnum {
+ #[cfg(never)]
+ AlwaysHide,
+ #[cfg(not(never))]
+ AlwaysShow{
+ #[cfg(never)]
+ always_hide: u32,
+ #[cfg(not(never))]
+ always_show: u32,
+ }
+ }
+ "#,
+ expect![[r#"
+use core::fmt::Debug;
+
+#[derive(Debug)]
+struct HideAndShow {
+ #[cfg(never)]
+ always_hide: u32,
+ #[cfg(not(never))]
+ always_show: u32,
+}
+#[derive(Debug)]
+enum HideAndShowEnum {
+ #[cfg(never)]
+ AlwaysHide,
+ #[cfg(not(never))]
+ AlwaysShow{
+ #[cfg(never)]
+ always_hide: u32,
+ #[cfg(not(never))]
+ always_show: u32,
+ }
+}
+
+impl < > $crate::fmt::Debug for HideAndShow< > where {
+ fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
+ match self {
+ HideAndShow {
+ always_show: always_show,
+ }
+ =>f.debug_struct("HideAndShow").field("always_show", &always_show).finish()
+ }
+ }
+}
+impl < > $crate::fmt::Debug for HideAndShowEnum< > where {
+ fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
+ match self {
+ HideAndShowEnum::AlwaysShow {
+ always_show: always_show,
+ }
+ =>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(),
+ }
+ }
+}"#]],
+ );
+}
+#[test]
+fn test_default_expand_with_cfg() {
+ check(
+ r#"
+//- minicore: derive, default
+#[derive(Default)]
+struct Foo {
+ field1: i32,
+ #[cfg(never)]
+ field2: (),
+}
+#[derive(Default)]
+enum Bar {
+ Foo,
+ #[cfg_attr(not(never), default)]
+ Bar,
+}
+"#,
+ expect![[r#"
+#[derive(Default)]
+struct Foo {
+ field1: i32,
+ #[cfg(never)]
+ field2: (),
+}
+#[derive(Default)]
+enum Bar {
+ Foo,
+ #[cfg_attr(not(never), default)]
+ Bar,
+}
+
+impl < > $crate::default::Default for Foo< > where {
+ fn default() -> Self {
+ Foo {
+ field1: $crate::default::Default::default(),
+ }
+ }
+}
+impl < > $crate::default::Default for Bar< > where {
+ fn default() -> Self {
+ Bar::Bar
+ }
+}"#]],
+ );
+}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
index edc8247f166..965f329acb9 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -171,7 +171,7 @@ fn main(foo: ()) {
}
fn main(foo: ()) {
- /* error: unresolved macro unresolved */"helloworld!"#0:3@207..323#2#;
+ /* error: unresolved macro unresolved */"helloworld!"#0:3@236..321#0#;
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
index 63f211022c9..23d8b023b8b 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/matching.rs
@@ -33,7 +33,7 @@ m!(&k");
"#,
expect![[r#"
macro_rules! m { ($i:literal) => {}; }
-/* error: mismatched delimiters */"#]],
+/* error: expected literal */"#]],
);
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 362c189f6a7..fb5797d6e53 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -98,7 +98,7 @@ macro_rules! m1 { ($x:ident) => { ($x } }
macro_rules! m2 { ($x:ident) => {} }
/* error: macro definition has parse errors */
-/* error: mismatched delimiters */
+/* error: expected ident */
"#]],
)
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
index 764617eafb7..b56dee3efb5 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs
@@ -61,15 +61,16 @@ use std::ops::Deref;
use base_db::{CrateId, Edition, FileId};
use hir_expand::{
- name::Name, proc_macro::ProcMacroKind, HirFileId, InFile, MacroCallId, MacroDefId,
+ name::Name, proc_macro::ProcMacroKind, ErasedAstId, HirFileId, InFile, MacroCallId, MacroDefId,
};
use itertools::Itertools;
use la_arena::Arena;
use rustc_hash::{FxHashMap, FxHashSet};
-use span::FileAstId;
+use span::{FileAstId, ROOT_ERASED_FILE_AST_ID};
use stdx::format_to;
use syntax::{ast, SmolStr};
use triomphe::Arc;
+use tt::TextRange;
use crate::{
db::DefDatabase,
@@ -677,6 +678,25 @@ impl ModuleData {
}
}
+ pub fn definition_source_range(&self, db: &dyn DefDatabase) -> InFile {
+ match &self.origin {
+ &ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => {
+ InFile::new(
+ definition.into(),
+ ErasedAstId::new(definition.into(), ROOT_ERASED_FILE_AST_ID)
+ .to_range(db.upcast()),
+ )
+ }
+ &ModuleOrigin::Inline { definition, definition_tree_id } => InFile::new(
+ definition_tree_id.file_id(),
+ AstId::new(definition_tree_id.file_id(), definition).to_range(db.upcast()),
+ ),
+ ModuleOrigin::BlockExpr { block, .. } => {
+ InFile::new(block.file_id, block.to_range(db.upcast()))
+ }
+ }
+ }
+
/// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
/// `None` for the crate root or block.
pub fn declaration_source(&self, db: &dyn DefDatabase) -> Option> {
@@ -684,6 +704,13 @@ impl ModuleData {
let value = decl.to_node(db.upcast());
Some(InFile { file_id: decl.file_id, value })
}
+
+ /// Returns the range which declares this module, either a `mod foo;` or a `mod foo {}`.
+ /// `None` for the crate root or block.
+ pub fn declaration_source_range(&self, db: &dyn DefDatabase) -> Option> {
+ let decl = self.origin.declaration()?;
+ Some(InFile { file_id: decl.file_id, value: decl.to_range(db.upcast()) })
+ }
}
#[derive(Debug, Clone, PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs
index 1cadae8c87c..662c80edf32 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/attr_resolution.rs
@@ -5,7 +5,7 @@ use hir_expand::{
attrs::{Attr, AttrId, AttrInput},
MacroCallId, MacroCallKind, MacroDefId,
};
-use span::Span;
+use span::SyntaxContextId;
use syntax::{ast, SmolStr};
use triomphe::Arc;
@@ -109,14 +109,14 @@ pub(super) fn attr_macro_as_call_id(
let arg = match macro_attr.input.as_deref() {
Some(AttrInput::TokenTree(tt)) => {
let mut tt = tt.as_ref().clone();
- tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
+ tt.delimiter.kind = tt::DelimiterKind::Invisible;
Some(tt)
}
_ => None,
};
- def.as_lazy_macro(
+ def.make_call(
db.upcast(),
krate,
MacroCallKind::Attr {
@@ -124,7 +124,7 @@ pub(super) fn attr_macro_as_call_id(
attr_args: arg.map(Arc::new),
invoc_attr_index: macro_attr.id,
},
- macro_attr.span,
+ macro_attr.ctxt,
)
}
@@ -133,14 +133,14 @@ pub(super) fn derive_macro_as_call_id(
item_attr: &AstIdWithPath,
derive_attr_index: AttrId,
derive_pos: u32,
- call_site: Span,
+ call_site: SyntaxContextId,
krate: CrateId,
resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
let (macro_id, def_id) = resolver(item_attr.path.clone())
.filter(|(_, def_id)| def_id.is_derive())
.ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
- let call_id = def_id.as_lazy_macro(
+ let call_id = def_id.make_call(
db.upcast(),
krate,
MacroCallKind::Derive {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
index f9fe6d3b903..3d026447fb7 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/collector.rs
@@ -230,13 +230,13 @@ enum MacroDirectiveKind {
FnLike {
ast_id: AstIdWithPath,
expand_to: ExpandTo,
- call_site: Span,
+ ctxt: SyntaxContextId,
},
Derive {
ast_id: AstIdWithPath,
derive_attr: AttrId,
derive_pos: usize,
- call_site: Span,
+ ctxt: SyntaxContextId,
},
Attr {
ast_id: AstIdWithPath,
@@ -1126,7 +1126,7 @@ impl DefCollector<'_> {
let resolver_def_id = |path| resolver(path).map(|(_, it)| it);
match &directive.kind {
- MacroDirectiveKind::FnLike { ast_id, expand_to, call_site } => {
+ MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => {
let call_id = macro_call_as_call_id(
self.db.upcast(),
ast_id,
@@ -1146,7 +1146,7 @@ impl DefCollector<'_> {
return Resolved::Yes;
}
}
- MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos, call_site } => {
+ MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos, ctxt: call_site } => {
let id = derive_macro_as_call_id(
self.db,
ast_id,
@@ -1266,7 +1266,7 @@ impl DefCollector<'_> {
ast_id,
derive_attr: attr.id,
derive_pos: idx,
- call_site,
+ ctxt: call_site.ctx,
},
container: directive.container,
});
@@ -1428,7 +1428,7 @@ impl DefCollector<'_> {
for directive in &self.unresolved_macros {
match &directive.kind {
- MacroDirectiveKind::FnLike { ast_id, expand_to, call_site } => {
+ MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt: call_site } => {
// FIXME: we shouldn't need to re-resolve the macro here just to get the unresolved error!
let macro_call_as_call_id = macro_call_as_call_id(
self.db.upcast(),
@@ -1451,12 +1451,16 @@ impl DefCollector<'_> {
if let Err(UnresolvedMacro { path }) = macro_call_as_call_id {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
directive.module_id,
- MacroCallKind::FnLike { ast_id: ast_id.ast_id, expand_to: *expand_to },
+ MacroCallKind::FnLike {
+ ast_id: ast_id.ast_id,
+ expand_to: *expand_to,
+ eager: None,
+ },
path,
));
}
}
- MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos, call_site: _ } => {
+ MacroDirectiveKind::Derive { ast_id, derive_attr, derive_pos, ctxt: _ } => {
self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
directive.module_id,
MacroCallKind::Derive {
@@ -2285,7 +2289,7 @@ impl ModCollector<'_, '_> {
fn collect_macro_call(
&mut self,
- &MacroCall { ref path, ast_id, expand_to, call_site }: &MacroCall,
+ &MacroCall { ref path, ast_id, expand_to, ctxt }: &MacroCall,
container: ItemContainerId,
) {
let ast_id = AstIdWithPath::new(self.file_id(), ast_id, ModPath::clone(path));
@@ -2299,7 +2303,7 @@ impl ModCollector<'_, '_> {
if let Ok(res) = macro_call_as_call_id_with_eager(
db.upcast(),
&ast_id,
- call_site,
+ ctxt,
expand_to,
self.def_collector.def_map.krate,
|path| {
@@ -2357,7 +2361,7 @@ impl ModCollector<'_, '_> {
self.def_collector.unresolved_macros.push(MacroDirective {
module_id: self.module_id,
depth: self.macro_depth + 1,
- kind: MacroDirectiveKind::FnLike { ast_id, expand_to, call_site },
+ kind: MacroDirectiveKind::FnLike { ast_id, expand_to, ctxt },
container,
});
}
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
index 6efced02718..be41634eb57 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/tests/incremental.rs
@@ -1,6 +1,5 @@
-use base_db::{SourceDatabase, SourceDatabaseExt};
+use base_db::{SourceDatabase, SourceDatabaseExt2 as _};
use test_fixture::WithFixture;
-use triomphe::Arc;
use crate::{db::DefDatabase, nameres::tests::TestDB, AdtId, ModuleDefId};
@@ -17,7 +16,7 @@ fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change:
});
assert!(format!("{events:?}").contains("crate_def_map"), "{events:#?}")
}
- db.set_file_text(pos.file_id, Arc::from(ra_fixture_change));
+ db.set_file_text(pos.file_id, ra_fixture_change);
{
let events = db.log_executed(|| {
@@ -267,7 +266,7 @@ fn quux() { 92 }
m!(Y);
m!(Z);
"#;
- db.set_file_text(pos.file_id, Arc::from(new_text));
+ db.set_file_text(pos.file_id, new_text);
{
let events = db.log_executed(|| {
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/src.rs b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
index 4283f003f89..2b1da8c34e1 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/src.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/src.rs
@@ -3,7 +3,7 @@
use either::Either;
use hir_expand::InFile;
use la_arena::ArenaMap;
-use syntax::ast;
+use syntax::{ast, AstNode, AstPtr};
use crate::{
data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
@@ -12,8 +12,12 @@ use crate::{
};
pub trait HasSource {
- type Value;
- fn source(&self, db: &dyn DefDatabase) -> InFile;
+ type Value: AstNode;
+ fn source(&self, db: &dyn DefDatabase) -> InFile {
+ let InFile { file_id, value } = self.ast_ptr(db);
+ InFile::new(file_id, value.to_node(&db.parse_or_expand(file_id)))
+ }
+ fn ast_ptr(&self, db: &dyn DefDatabase) -> InFile>;
}
impl HasSource for T
@@ -22,16 +26,14 @@ where
T::Id: ItemTreeNode,
{
type Value = ::Source;
-
- fn source(&self, db: &dyn DefDatabase) -> InFile {
+ fn ast_ptr(&self, db: &dyn DefDatabase) -> InFile> {
let id = self.item_tree_id();
let file_id = id.file_id();
let tree = id.item_tree(db);
let ast_id_map = db.ast_id_map(file_id);
- let root = db.parse_or_expand(file_id);
let node = &tree[id.value];
- InFile::new(file_id, ast_id_map.get(node.ast_id()).to_node(&root))
+ InFile::new(file_id, ast_id_map.get(node.ast_id()))
}
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
index 7793e995323..af3ecdcd5e3 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/attrs.rs
@@ -7,7 +7,7 @@ use either::Either;
use intern::Interned;
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
use smallvec::{smallvec, SmallVec};
-use span::Span;
+use span::{Span, SyntaxContextId};
use syntax::{ast, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
use triomphe::Arc;
@@ -53,7 +53,7 @@ impl RawAttrs {
id,
input: Some(Interned::new(AttrInput::Literal(SmolStr::new(doc)))),
path: Interned::new(ModPath::from(crate::name!(doc))),
- span: span_map.span_for_range(comment.syntax().text_range()),
+ ctxt: span_map.span_for_range(comment.syntax().text_range()).ctx,
}),
});
let entries: Arc<[Attr]> = Arc::from_iter(entries);
@@ -173,7 +173,7 @@ pub struct Attr {
pub id: AttrId,
pub path: Interned,
pub input: Option>,
- pub span: Span,
+ pub ctxt: SyntaxContextId,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -201,10 +201,12 @@ impl Attr {
span_map: SpanMapRef<'_>,
id: AttrId,
) -> Option {
- let path = Interned::new(ModPath::from_src(db, ast.path()?, &mut |range| {
+ let path = ast.path()?;
+ let range = path.syntax().text_range();
+ let path = Interned::new(ModPath::from_src(db, path, &mut |range| {
span_map.span_for_range(range).ctx
})?);
- let span = span_map.span_for_range(ast.syntax().text_range());
+ let span = span_map.span_for_range(range);
let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() {
let value = match lit.kind() {
ast::LiteralKind::String(string) => string.value()?.into(),
@@ -217,11 +219,11 @@ impl Attr {
} else {
None
};
- Some(Attr { id, path, input, span })
+ Some(Attr { id, path, input, ctxt: span.ctx })
}
fn from_tt(db: &dyn ExpandDatabase, tt: &[tt::TokenTree], id: AttrId) -> Option {
- let span = tt.first()?.first_span();
+ let ctxt = tt.first()?.first_span().ctx;
let path_end = tt
.iter()
.position(|tt| {
@@ -253,7 +255,7 @@ impl Attr {
}
_ => None,
};
- Some(Attr { id, path, input, span })
+ Some(Attr { id, path, input, ctxt })
}
pub fn path(&self) -> &ModPath {
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs
index a0102f36aff..9ff29b484d3 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_attr_macro.rs
@@ -11,7 +11,7 @@ macro_rules! register_builtin {
}
impl BuiltinAttrExpander {
- pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree) -> ExpandResult {
+ pub fn expander(&self) -> fn (&dyn ExpandDatabase, MacroCallId, &tt::Subtree, Span) -> ExpandResult {
match *self {
$( BuiltinAttrExpander::$variant => $expand, )*
}
@@ -34,8 +34,9 @@ impl BuiltinAttrExpander {
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
+ span: Span,
) -> ExpandResult {
- self.expander()(db, id, tt)
+ self.expander()(db, id, tt, span)
}
pub fn is_derive(self) -> bool {
@@ -71,6 +72,7 @@ fn dummy_attr_expand(
_db: &dyn ExpandDatabase,
_id: MacroCallId,
tt: &tt::Subtree,
+ _span: Span,
) -> ExpandResult {
ExpandResult::ok(tt.clone())
}
@@ -100,6 +102,7 @@ fn derive_expand(
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
+ span: Span,
) -> ExpandResult {
let loc = db.lookup_intern_macro_call(id);
let derives = match &loc.kind {
@@ -107,17 +110,14 @@ fn derive_expand(
attr_args
}
_ => {
- return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan {
- open: loc.call_site,
- close: loc.call_site,
- }))
+ return ExpandResult::ok(tt::Subtree::empty(tt::DelimSpan { open: span, close: span }))
}
};
- pseudo_derive_attr_expansion(tt, derives, loc.call_site)
+ pseudo_derive_attr_expansion(tt, derives, span)
}
pub fn pseudo_derive_attr_expansion(
- tt: &tt::Subtree,
+ _: &tt::Subtree,
args: &tt::Subtree,
call_site: Span,
) -> ExpandResult {
@@ -141,7 +141,7 @@ pub fn pseudo_derive_attr_expansion(
token_trees.push(mk_leaf(']'));
}
ExpandResult::ok(tt::Subtree {
- delimiter: tt.delimiter,
+ delimiter: args.delimiter,
token_trees: token_trees.into_boxed_slice(),
})
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs
index 66dec7d89e5..528038a9ccf 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_derive_macro.rs
@@ -50,8 +50,8 @@ impl BuiltinDeriveExpander {
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
+ span: Span,
) -> ExpandResult {
- let span = db.lookup_intern_macro_call(id).call_site;
let span = span_with_def_site_ctxt(db, span, id);
self.expander()(span, tt)
}
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
index 0fd0c25dcce..9fb6a0b2346 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs
@@ -19,14 +19,14 @@ use crate::{
};
macro_rules! register_builtin {
- ( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => {
+ ( $LAZY:ident: $(($name:ident, $kind: ident) => $expand:ident),* , $EAGER:ident: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
- pub enum BuiltinFnLikeExpander {
+ pub enum $LAZY {
$($kind),*
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
- pub enum EagerExpander {
+ pub enum $EAGER {
$($e_kind),*
}
@@ -62,8 +62,8 @@ impl BuiltinFnLikeExpander {
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
+ span: Span,
) -> ExpandResult {
- let span = db.lookup_intern_macro_call(id).call_site;
let span = span_with_def_site_ctxt(db, span, id);
self.expander()(db, id, tt, span)
}
@@ -75,8 +75,8 @@ impl EagerExpander {
db: &dyn ExpandDatabase,
id: MacroCallId,
tt: &tt::Subtree,
+ span: Span,
) -> ExpandResult {
- let span = db.lookup_intern_macro_call(id).call_site;
let span = span_with_def_site_ctxt(db, span, id);
self.expander()(db, id, tt, span)
}
@@ -84,6 +84,17 @@ impl EagerExpander {
pub fn is_include(&self) -> bool {
matches!(self, EagerExpander::Include)
}
+
+ pub fn is_include_like(&self) -> bool {
+ matches!(
+ self,
+ EagerExpander::Include | EagerExpander::IncludeStr | EagerExpander::IncludeBytes
+ )
+ }
+
+ pub fn is_env_or_option_env(&self) -> bool {
+ matches!(self, EagerExpander::Env | EagerExpander::OptionEnv)
+ }
}
pub fn find_builtin_macro(
@@ -93,7 +104,7 @@ pub fn find_builtin_macro(
}
register_builtin! {
- LAZY:
+ BuiltinFnLikeExpander:
(column, Column) => line_expand,
(file, File) => file_expand,
(line, Line) => line_expand,
@@ -114,7 +125,7 @@ register_builtin! {
(format_args_nl, FormatArgsNl) => format_args_nl_expand,
(quote, Quote) => quote_expand,
- EAGER:
+ EagerExpander:
(compile_error, CompileError) => compile_error_expand,
(concat, Concat) => concat_expand,
(concat_idents, ConcatIdents) => concat_idents_expand,
@@ -426,22 +437,25 @@ fn use_panic_2021(db: &dyn ExpandDatabase, span: Span) -> bool {
}
}
-fn unquote_str(lit: &tt::Literal) -> Option {
+fn unquote_str(lit: &tt::Literal) -> Option<(String, Span)> {
+ let span = lit.span;
let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::String::cast(lit)?;
- token.value().map(|it| it.into_owned())
+ token.value().map(|it| (it.into_owned(), span))
}
-fn unquote_char(lit: &tt::Literal) -> Option {
+fn unquote_char(lit: &tt::Literal) -> Option<(char, Span)> {
+ let span = lit.span;
let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::Char::cast(lit)?;
- token.value()
+ token.value().zip(Some(span))
}
-fn unquote_byte_string(lit: &tt::Literal) -> Option> {
+fn unquote_byte_string(lit: &tt::Literal) -> Option<(Vec, Span)> {
+ let span = lit.span;
let lit = ast::make::tokens::literal(&lit.to_string());
let token = ast::ByteString::cast(lit)?;
- token.value().map(|it| it.into_owned())
+ token.value().map(|it| (it.into_owned(), span))
}
fn compile_error_expand(
@@ -452,7 +466,7 @@ fn compile_error_expand(
) -> ExpandResult {
let err = match &*tt.token_trees {
[tt::TokenTree::Leaf(tt::Leaf::Literal(it))] => match unquote_str(it) {
- Some(unquoted) => ExpandError::other(unquoted.into_boxed_str()),
+ Some((unquoted, _)) => ExpandError::other(unquoted.into_boxed_str()),
None => ExpandError::other("`compile_error!` argument must be a string"),
},
_ => ExpandError::other("`compile_error!` argument must be a string"),
@@ -465,10 +479,16 @@ fn concat_expand(
_db: &dyn ExpandDatabase,
_arg_id: MacroCallId,
tt: &tt::Subtree,
- span: Span,
+ _: Span,
) -> ExpandResult {
let mut err = None;
let mut text = String::new();
+ let mut span: Option = None;
+ let mut record_span = |s: Span| match &mut span {
+ Some(span) if span.anchor == s.anchor => span.range = span.range.cover(s.range),
+ Some(_) => (),
+ None => span = Some(s),
+ };
for (i, mut t) in tt.token_trees.iter().enumerate() {
// FIXME: hack on top of a hack: `$e:expr` captures get surrounded in parentheses
// to ensure the right parsing order, so skip the parentheses here. Ideally we'd
@@ -486,11 +506,14 @@ fn concat_expand(
// concat works with string and char literals, so remove any quotes.
// It also works with integer, float and boolean literals, so just use the rest
// as-is.
- if let Some(c) = unquote_char(it) {
+ if let Some((c, span)) = unquote_char(it) {
text.push(c);
+ record_span(span);
} else {
- let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
+ let (component, span) =
+ unquote_str(it).unwrap_or_else(|| (it.text.to_string(), it.span));
text.push_str(&component);
+ record_span(span);
}
}
// handle boolean literals
@@ -498,6 +521,7 @@ fn concat_expand(
if i % 2 == 0 && (id.text == "true" || id.text == "false") =>
{
text.push_str(id.text.as_str());
+ record_span(id.span);
}
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
_ => {
@@ -505,6 +529,7 @@ fn concat_expand(
}
}
}
+ let span = span.unwrap_or(tt.delimiter.open);
ExpandResult { value: quote!(span =>#text), err }
}
@@ -512,18 +537,25 @@ fn concat_bytes_expand(
_db: &dyn ExpandDatabase,
_arg_id: MacroCallId,
tt: &tt::Subtree,
- span: Span,
+ call_site: Span,
) -> ExpandResult {
let mut bytes = Vec::new();
let mut err = None;
+ let mut span: Option = None;
+ let mut record_span = |s: Span| match &mut span {
+ Some(span) if span.anchor == s.anchor => span.range = span.range.cover(s.range),
+ Some(_) => (),
+ None => span = Some(s),
+ };
for (i, t) in tt.token_trees.iter().enumerate() {
match t {
tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
let token = ast::make::tokens::literal(&lit.to_string());
+ record_span(lit.span);
match token.kind() {
syntax::SyntaxKind::BYTE => bytes.push(token.text().to_owned()),
syntax::SyntaxKind::BYTE_STRING => {
- let components = unquote_byte_string(lit).unwrap_or_default();
+ let components = unquote_byte_string(lit).map_or(vec![], |(it, _)| it);
components.into_iter().for_each(|it| bytes.push(it.to_string()));
}
_ => {
@@ -534,7 +566,7 @@ fn concat_bytes_expand(
}
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if i % 2 == 1 && punct.char == ',' => (),
tt::TokenTree::Subtree(tree) if tree.delimiter.kind == tt::DelimiterKind::Bracket => {
- if let Err(e) = concat_bytes_expand_subtree(tree, &mut bytes) {
+ if let Err(e) = concat_bytes_expand_subtree(tree, &mut bytes, &mut record_span) {
err.get_or_insert(e);
break;
}
@@ -546,17 +578,24 @@ fn concat_bytes_expand(
}
}
let value = tt::Subtree {
- delimiter: tt::Delimiter { open: span, close: span, kind: tt::DelimiterKind::Bracket },
+ delimiter: tt::Delimiter {
+ open: call_site,
+ close: call_site,
+ kind: tt::DelimiterKind::Bracket,
+ },
token_trees: {
Itertools::intersperse_with(
bytes.into_iter().map(|it| {
- tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { text: it.into(), span }))
+ tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal {
+ text: it.into(),
+ span: span.unwrap_or(call_site),
+ }))
}),
|| {
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct {
char: ',',
spacing: tt::Spacing::Alone,
- span,
+ span: call_site,
}))
},
)
@@ -569,13 +608,15 @@ fn concat_bytes_expand(
fn concat_bytes_expand_subtree(
tree: &tt::Subtree,
bytes: &mut Vec,
+ mut record_span: impl FnMut(Span),
) -> Result<(), ExpandError> {
for (ti, tt) in tree.token_trees.iter().enumerate() {
match tt {
- tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
- let lit = ast::make::tokens::literal(&lit.to_string());
+ tt::TokenTree::Leaf(tt::Leaf::Literal(it)) => {
+ let lit = ast::make::tokens::literal(&it.to_string());
match lit.kind() {
syntax::SyntaxKind::BYTE | syntax::SyntaxKind::INT_NUMBER => {
+ record_span(it.span);
bytes.push(lit.text().to_owned())
}
_ => {
@@ -635,7 +676,7 @@ fn relative_file(
}
}
-fn parse_string(tt: &tt::Subtree) -> Result {
+fn parse_string(tt: &tt::Subtree) -> Result<(String, Span), ExpandError> {
tt.token_trees
.first()
.and_then(|tt| match tt {
@@ -675,7 +716,7 @@ pub fn include_input_to_file_id(
arg_id: MacroCallId,
arg: &tt::Subtree,
) -> Result {
- relative_file(db, arg_id, &parse_string(arg)?, false)
+ relative_file(db, arg_id, &parse_string(arg)?.0, false)
}
fn include_bytes_expand(
@@ -701,7 +742,7 @@ fn include_str_expand(
tt: &tt::Subtree,
span: Span,
) -> ExpandResult