Rollup merge of #96167 - CAD97:weak-dlsym-less-ptr-crime, r=thomcc
Replace sys/unix/weak AtomicUsize with AtomicPtr
Should fix #96163. Can't easily test on Windows though...
diff --git a/Cargo.lock b/Cargo.lock
index 73dc7f0..fbc9ca7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2513,9 +2513,9 @@
[[package]]
name = "openssl"
-version = "0.10.35"
+version = "0.10.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "549430950c79ae24e6d02e0b7404534ecf311d94cc9f861e9e4020187d13d885"
+checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
dependencies = [
"bitflags",
"cfg-if 1.0.0",
@@ -2542,9 +2542,9 @@
[[package]]
name = "openssl-sys"
-version = "0.9.65"
+version = "0.9.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d"
+checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb"
dependencies = [
"autocfg",
"cc",
@@ -2894,6 +2894,7 @@
name = "proc_macro"
version = "0.0.0"
dependencies = [
+ "core",
"std",
]
@@ -3934,7 +3935,6 @@
"rustc_infer",
"rustc_middle",
"rustc_parse_format",
- "rustc_serialize",
"rustc_session",
"rustc_span",
"rustc_target",
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs
index 80caf37..9a6d12f 100644
--- a/compiler/rustc_ast/src/attr/mod.rs
+++ b/compiler/rustc_ast/src/attr/mod.rs
@@ -9,6 +9,7 @@
use crate::tokenstream::{AttrAnnotatedTokenStream, AttrAnnotatedTokenTree};
use crate::tokenstream::{DelimSpan, Spacing, TokenTree, TreeAndSpacing};
use crate::tokenstream::{LazyTokenStream, TokenStream};
+use crate::util::comments;
use rustc_index::bit_set::GrowableBitSet;
use rustc_span::source_map::BytePos;
@@ -262,6 +263,10 @@ pub fn doc_str(&self) -> Option<Symbol> {
}
}
+ pub fn may_have_doc_links(&self) -> bool {
+ self.doc_str().map_or(false, |s| comments::may_have_doc_links(s.as_str()))
+ }
+
pub fn get_normal_item(&self) -> &AttrItem {
match self.kind {
AttrKind::Normal(ref item, _) => item,
diff --git a/compiler/rustc_ast/src/util/comments.rs b/compiler/rustc_ast/src/util/comments.rs
index 8730aeb..b4fff00 100644
--- a/compiler/rustc_ast/src/util/comments.rs
+++ b/compiler/rustc_ast/src/util/comments.rs
@@ -24,6 +24,14 @@ pub struct Comment {
pub pos: BytePos,
}
+/// A fast conservative estimate on whether the string can contain documentation links.
+/// A pair of square brackets `[]` must exist in the string, but we only search for the
+/// opening bracket because brackets always go in pairs in practice.
+#[inline]
+pub fn may_have_doc_links(s: &str) -> bool {
+ s.contains('[')
+}
+
/// Makes a doc string more presentable to users.
/// Used by rustdoc and perhaps other tools, but not by rustc.
pub fn beautify_doc_string(data: Symbol, kind: CommentKind) -> Symbol {
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 2af050f..2e8cd93 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -589,6 +589,7 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => unimplemented!(),
+ InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => unimplemented!(),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => unimplemented!(),
InlineAsmRegClass::X86(
X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
@@ -654,6 +655,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg) => unimplemented!(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
+ InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => cx.type_i16(),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
@@ -784,6 +786,7 @@ fn modifier_to_gcc(arch: InlineAsmArch, reg: InlineAsmRegClass, modifier: Option
_ => unreachable!(),
},
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
+ InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg0) => None,
InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
unreachable!("clobber-only")
}
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index dff3200..e994001 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -602,7 +602,9 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
InlineAsmRegClass::X86(
- X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg,
+ X86InlineAsmRegClass::x87_reg
+ | X86InlineAsmRegClass::mmx_reg
+ | X86InlineAsmRegClass::kreg0,
) => unreachable!("clobber-only"),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
@@ -687,7 +689,11 @@ fn modifier_to_llvm(
_ => unreachable!(),
},
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
- InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
+ InlineAsmRegClass::X86(
+ X86InlineAsmRegClass::x87_reg
+ | X86InlineAsmRegClass::mmx_reg
+ | X86InlineAsmRegClass::kreg0,
+ ) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
@@ -757,7 +763,11 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'
| InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
- InlineAsmRegClass::X86(X86InlineAsmRegClass::x87_reg | X86InlineAsmRegClass::mmx_reg) => {
+ InlineAsmRegClass::X86(
+ X86InlineAsmRegClass::x87_reg
+ | X86InlineAsmRegClass::mmx_reg
+ | X86InlineAsmRegClass::kreg0,
+ ) => {
unreachable!("clobber-only")
}
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index 765bd87..7b7c676 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -1,12 +1,10 @@
use std::collections::hash_map::Entry::*;
use rustc_ast::expand::allocator::ALLOCATOR_METHODS;
-use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
use rustc_hir::Node;
-use rustc_index::vec::IndexVec;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::{
metadata_symbol_name, ExportedSymbol, SymbolExportLevel,
@@ -277,17 +275,6 @@ fn upstream_monomorphizations_provider(
let mut instances: DefIdMap<FxHashMap<_, _>> = Default::default();
- let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = {
- let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO, cnums.len() + 1);
-
- for &cnum in cnums.iter() {
- cnum_stable_ids[cnum] =
- tcx.def_path_hash(DefId { krate: cnum, index: CRATE_DEF_INDEX }).0;
- }
-
- cnum_stable_ids
- };
-
let drop_in_place_fn_def_id = tcx.lang_items().drop_in_place_fn();
for &cnum in cnums.iter() {
@@ -316,7 +303,7 @@ fn upstream_monomorphizations_provider(
// If there are multiple monomorphizations available,
// we select one deterministically.
let other_cnum = *e.get();
- if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] {
+ if tcx.stable_crate_id(other_cnum) > tcx.stable_crate_id(cnum) {
e.insert(cnum);
}
}
diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs
index 80270f8..68f9bee 100644
--- a/compiler/rustc_const_eval/src/const_eval/mod.rs
+++ b/compiler/rustc_const_eval/src/const_eval/mod.rs
@@ -38,7 +38,7 @@ pub(crate) fn const_caller_location(
if intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &loc_place).is_err() {
bug!("intern_const_alloc_recursive should not error in this case")
}
- ConstValue::Scalar(Scalar::from_pointer(loc_place.ptr.into_pointer_or_addr().unwrap(), &tcx))
+ ConstValue::Scalar(Scalar::from_maybe_pointer(loc_place.ptr, &tcx))
}
/// Convert an evaluated constant to a type level constant
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index f0fff60..8279591 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -679,7 +679,7 @@ pub fn push_stack_frame(
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> {
- debug!("body: {:#?}", body);
+ trace!("body: {:#?}", body);
// first push a stack frame so we have access to the local substs
let pre_frame = Frame {
body,
@@ -836,7 +836,7 @@ pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx>
return Ok(());
}
- debug!("locals: {:#?}", frame.locals);
+ trace!("locals: {:#?}", frame.locals);
// Cleanup: deallocate all locals that are backed by an allocation.
for local in &frame.locals {
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index ddfbcbd..7721485 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -88,6 +88,10 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Pointers are "tagged" with provenance information; typically the `AllocId` they belong to.
type PointerTag: Provenance + Eq + Hash + 'static;
+ /// When getting the AllocId of a pointer, some extra data is also obtained from the tag
+ /// that is passed to memory access hooks so they can do things with it.
+ type TagExtra: Copy + 'static;
+
/// Machines can define extra (non-instance) things that represent values of function pointers.
/// For example, Miri uses this to return a function pointer from `dlsym`
/// that can later be called to execute the right thing.
@@ -122,6 +126,8 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Whether, when checking alignment, we should `force_int` and thus support
/// custom alignment logic based on whatever the integer address happens to be.
+ ///
+ /// Requires PointerTag::OFFSET_IS_ADDR to be true.
fn force_int_for_alignment_check(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
/// Whether to enforce the validity invariant
@@ -285,11 +291,14 @@ fn ptr_from_addr(
addr: u64,
) -> Pointer<Option<Self::PointerTag>>;
- /// Convert a pointer with provenance into an allocation-offset pair.
+ /// Convert a pointer with provenance into an allocation-offset pair
+ /// and extra provenance info.
+ ///
+ /// The returned `AllocId` must be the same as `ptr.provenance.get_alloc_id()`.
fn ptr_get_alloc(
ecx: &InterpCx<'mir, 'tcx, Self>,
ptr: Pointer<Self::PointerTag>,
- ) -> (AllocId, Size);
+ ) -> (AllocId, Size, Self::TagExtra);
/// Called to initialize the "extra" state of an allocation and make the pointers
/// it contains (in relocations) tagged. The way we construct allocations is
@@ -321,7 +330,7 @@ fn memory_read(
_tcx: TyCtxt<'tcx>,
_machine: &Self,
_alloc_extra: &Self::AllocExtra,
- _tag: Self::PointerTag,
+ _tag: (AllocId, Self::TagExtra),
_range: AllocRange,
) -> InterpResult<'tcx> {
Ok(())
@@ -333,7 +342,7 @@ fn memory_written(
_tcx: TyCtxt<'tcx>,
_machine: &mut Self,
_alloc_extra: &mut Self::AllocExtra,
- _tag: Self::PointerTag,
+ _tag: (AllocId, Self::TagExtra),
_range: AllocRange,
) -> InterpResult<'tcx> {
Ok(())
@@ -345,7 +354,7 @@ fn memory_deallocated(
_tcx: TyCtxt<'tcx>,
_machine: &mut Self,
_alloc_extra: &mut Self::AllocExtra,
- _tag: Self::PointerTag,
+ _tag: (AllocId, Self::TagExtra),
_range: AllocRange,
) -> InterpResult<'tcx> {
Ok(())
@@ -397,6 +406,8 @@ fn after_stack_pop(
// (CTFE and ConstProp) use the same instance. Here, we share that code.
pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
type PointerTag = AllocId;
+ type TagExtra = ();
+
type ExtraFnVal = !;
type MemoryMap =
@@ -474,9 +485,12 @@ fn ptr_from_addr(_ecx: &InterpCx<$mir, $tcx, Self>, addr: u64) -> Pointer<Option
}
#[inline(always)]
- fn ptr_get_alloc(_ecx: &InterpCx<$mir, $tcx, Self>, ptr: Pointer<AllocId>) -> (AllocId, Size) {
+ fn ptr_get_alloc(
+ _ecx: &InterpCx<$mir, $tcx, Self>,
+ ptr: Pointer<AllocId>,
+ ) -> (AllocId, Size, Self::TagExtra) {
// We know `offset` is relative to the allocation, so we can use `into_parts`.
let (alloc_id, offset) = ptr.into_parts();
- (alloc_id, offset)
+ (alloc_id, offset, ())
}
}
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index a165fa2..b1d7ab6 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -158,8 +158,7 @@ pub fn global_base_pointer(
&self,
ptr: Pointer<AllocId>,
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
- // We know `offset` is relative to the allocation, so we can use `into_parts`.
- let (alloc_id, offset) = ptr.into_parts();
+ let alloc_id = ptr.provenance;
// We need to handle `extern static`.
match self.tcx.get_global_alloc(alloc_id) {
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_thread_local_static(def_id) => {
@@ -171,7 +170,7 @@ pub fn global_base_pointer(
_ => {}
}
// And we need to get the tag.
- Ok(M::tag_alloc_base_pointer(self, Pointer::new(alloc_id, offset)))
+ Ok(M::tag_alloc_base_pointer(self, ptr))
}
pub fn create_fn_alloc_ptr(
@@ -238,7 +237,7 @@ pub fn reallocate_ptr(
new_align: Align,
kind: MemoryKind<M::MemoryKind>,
) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
- let (alloc_id, offset, ptr) = self.ptr_get_alloc_id(ptr)?;
+ let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
if offset.bytes() != 0 {
throw_ub_format!(
"reallocating {:?} which does not point to the beginning of an object",
@@ -255,14 +254,14 @@ pub fn reallocate_ptr(
};
// This will also call the access hooks.
self.mem_copy(
- ptr.into(),
+ ptr,
Align::ONE,
new_ptr.into(),
Align::ONE,
old_size.min(new_size),
/*nonoverlapping*/ true,
)?;
- self.deallocate_ptr(ptr.into(), old_size_and_align, kind)?;
+ self.deallocate_ptr(ptr, old_size_and_align, kind)?;
Ok(new_ptr)
}
@@ -274,7 +273,7 @@ pub fn deallocate_ptr(
old_size_and_align: Option<(Size, Align)>,
kind: MemoryKind<M::MemoryKind>,
) -> InterpResult<'tcx> {
- let (alloc_id, offset, ptr) = self.ptr_get_alloc_id(ptr)?;
+ let (alloc_id, offset, tag) = self.ptr_get_alloc_id(ptr)?;
trace!("deallocating: {}", alloc_id);
if offset.bytes() != 0 {
@@ -330,7 +329,7 @@ pub fn deallocate_ptr(
*self.tcx,
&mut self.machine,
&mut alloc.extra,
- ptr.provenance,
+ (alloc_id, tag),
alloc_range(Size::ZERO, size),
)?;
@@ -350,17 +349,17 @@ fn get_ptr_access(
ptr: Pointer<Option<M::PointerTag>>,
size: Size,
align: Align,
- ) -> InterpResult<'tcx, Option<(AllocId, Size, Pointer<M::PointerTag>)>> {
+ ) -> InterpResult<'tcx, Option<(AllocId, Size, M::TagExtra)>> {
let align = M::enforce_alignment(&self).then_some(align);
self.check_and_deref_ptr(
ptr,
size,
align,
CheckInAllocMsg::MemoryAccessTest,
- |alloc_id, offset, ptr| {
+ |alloc_id, offset, tag| {
let (size, align) =
self.get_alloc_size_and_align(alloc_id, AllocCheck::Dereferenceable)?;
- Ok((size, align, (alloc_id, offset, ptr)))
+ Ok((size, align, (alloc_id, offset, tag)))
},
)
}
@@ -401,11 +400,7 @@ fn check_and_deref_ptr<T>(
size: Size,
align: Option<Align>,
msg: CheckInAllocMsg,
- alloc_size: impl FnOnce(
- AllocId,
- Size,
- Pointer<M::PointerTag>,
- ) -> InterpResult<'tcx, (Size, Align, T)>,
+ alloc_size: impl FnOnce(AllocId, Size, M::TagExtra) -> InterpResult<'tcx, (Size, Align, T)>,
) -> InterpResult<'tcx, Option<T>> {
fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
if offset % align.bytes() == 0 {
@@ -433,8 +428,8 @@ fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
}
None
}
- Ok((alloc_id, offset, ptr)) => {
- let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, ptr)?;
+ Ok((alloc_id, offset, tag)) => {
+ let (alloc_size, alloc_align, ret_val) = alloc_size(alloc_id, offset, tag)?;
// Test bounds. This also ensures non-null.
// It is sufficient to check this for the end pointer. Also check for overflow!
if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
@@ -450,10 +445,8 @@ fn check_offset_align(offset: u64, align: Align) -> InterpResult<'static> {
// we want the error to be about the bounds.
if let Some(align) = align {
if M::force_int_for_alignment_check(self) {
- let addr = Scalar::from_pointer(ptr, &self.tcx)
- .to_machine_usize(&self.tcx)
- .expect("ptr-to-int cast for align check should never fail");
- check_offset_align(addr, align)?;
+ // `force_int_for_alignment_check` can only be true if `OFFSET_IS_ADDR` is true.
+ check_offset_align(ptr.addr().bytes(), align)?;
} else {
// Check allocation alignment and offset alignment.
if alloc_align.bytes() < align.bytes() {
@@ -569,14 +562,14 @@ pub fn get_ptr_alloc<'a>(
size,
align,
CheckInAllocMsg::MemoryAccessTest,
- |alloc_id, offset, ptr| {
+ |alloc_id, offset, tag| {
let alloc = self.get_alloc_raw(alloc_id)?;
- Ok((alloc.size(), alloc.align, (alloc_id, offset, ptr, alloc)))
+ Ok((alloc.size(), alloc.align, (alloc_id, offset, tag, alloc)))
},
)?;
- if let Some((alloc_id, offset, ptr, alloc)) = ptr_and_alloc {
+ if let Some((alloc_id, offset, tag, alloc)) = ptr_and_alloc {
let range = alloc_range(offset, size);
- M::memory_read(*self.tcx, &self.machine, &alloc.extra, ptr.provenance, range)?;
+ M::memory_read(*self.tcx, &self.machine, &alloc.extra, (alloc_id, tag), range)?;
Ok(Some(AllocRef { alloc, range, tcx: *self.tcx, alloc_id }))
} else {
// Even in this branch we have to be sure that we actually access the allocation, in
@@ -631,13 +624,13 @@ pub fn get_ptr_alloc_mut<'a>(
align: Align,
) -> InterpResult<'tcx, Option<AllocRefMut<'a, 'tcx, M::PointerTag, M::AllocExtra>>> {
let parts = self.get_ptr_access(ptr, size, align)?;
- if let Some((alloc_id, offset, ptr)) = parts {
+ if let Some((alloc_id, offset, tag)) = parts {
let tcx = *self.tcx;
// FIXME: can we somehow avoid looking up the allocation twice here?
// We cannot call `get_raw_mut` inside `check_and_deref_ptr` as that would duplicate `&mut self`.
let (alloc, machine) = self.get_alloc_raw_mut(alloc_id)?;
let range = alloc_range(offset, size);
- M::memory_written(tcx, machine, &mut alloc.extra, ptr.provenance, range)?;
+ M::memory_written(tcx, machine, &mut alloc.extra, (alloc_id, tag), range)?;
Ok(Some(AllocRefMut { alloc, range, tcx, alloc_id }))
} else {
Ok(None)
@@ -732,7 +725,7 @@ pub fn get_ptr_fn(
ptr: Pointer<Option<M::PointerTag>>,
) -> InterpResult<'tcx, FnVal<'tcx, M::ExtraFnVal>> {
trace!("get_fn({:?})", ptr);
- let (alloc_id, offset, _ptr) = self.ptr_get_alloc_id(ptr)?;
+ let (alloc_id, offset, _tag) = self.ptr_get_alloc_id(ptr)?;
if offset.bytes() != 0 {
throw_ub!(InvalidFunctionPointer(Pointer::new(alloc_id, offset)))
}
@@ -877,9 +870,17 @@ pub fn write_scalar(
range: AllocRange,
val: ScalarMaybeUninit<Tag>,
) -> InterpResult<'tcx> {
+ let range = self.range.subrange(range);
+ debug!(
+ "write_scalar in {} at {:#x}, size {}: {:?}",
+ self.alloc_id,
+ range.start.bytes(),
+ range.size.bytes(),
+ val
+ );
Ok(self
.alloc
- .write_scalar(&self.tcx, self.range.subrange(range), val)
+ .write_scalar(&self.tcx, range, val)
.map_err(|e| e.to_interp_error(self.alloc_id))?)
}
@@ -892,17 +893,29 @@ pub fn write_ptr_sized(
}
/// Mark the entire referenced range as uninitalized
- pub fn write_uninit(&mut self) {
- self.alloc.mark_init(self.range, false);
+ pub fn write_uninit(&mut self) -> InterpResult<'tcx> {
+ Ok(self
+ .alloc
+ .write_uninit(&self.tcx, self.range)
+ .map_err(|e| e.to_interp_error(self.alloc_id))?)
}
}
impl<'tcx, 'a, Tag: Provenance, Extra> AllocRef<'a, 'tcx, Tag, Extra> {
pub fn read_scalar(&self, range: AllocRange) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
- Ok(self
+ let range = self.range.subrange(range);
+ let res = self
.alloc
- .read_scalar(&self.tcx, self.range.subrange(range))
- .map_err(|e| e.to_interp_error(self.alloc_id))?)
+ .read_scalar(&self.tcx, range)
+ .map_err(|e| e.to_interp_error(self.alloc_id))?;
+ debug!(
+ "read_scalar in {} at {:#x}, size {}: {:?}",
+ self.alloc_id,
+ range.start.bytes(),
+ range.size.bytes(),
+ res
+ );
+ Ok(res)
}
pub fn read_ptr_sized(&self, offset: Size) -> InterpResult<'tcx, ScalarMaybeUninit<Tag>> {
@@ -1009,16 +1022,16 @@ pub fn mem_copy_repeatedly(
// and once below to get the underlying `&[mut] Allocation`.
// Source alloc preparations and access hooks.
- let Some((src_alloc_id, src_offset, src)) = src_parts else {
+ let Some((src_alloc_id, src_offset, src_tag)) = src_parts else {
// Zero-sized *source*, that means dst is also zero-sized and we have nothing to do.
return Ok(());
};
let src_alloc = self.get_alloc_raw(src_alloc_id)?;
let src_range = alloc_range(src_offset, size);
- M::memory_read(*tcx, &self.machine, &src_alloc.extra, src.provenance, src_range)?;
+ M::memory_read(*tcx, &self.machine, &src_alloc.extra, (src_alloc_id, src_tag), src_range)?;
// We need the `dest` ptr for the next operation, so we get it now.
// We already did the source checks and called the hooks so we are good to return early.
- let Some((dest_alloc_id, dest_offset, dest)) = dest_parts else {
+ let Some((dest_alloc_id, dest_offset, dest_tag)) = dest_parts else {
// Zero-sized *destination*.
return Ok(());
};
@@ -1040,7 +1053,13 @@ pub fn mem_copy_repeatedly(
// Destination alloc preparations and access hooks.
let (dest_alloc, extra) = self.get_alloc_raw_mut(dest_alloc_id)?;
let dest_range = alloc_range(dest_offset, size * num_copies);
- M::memory_written(*tcx, extra, &mut dest_alloc.extra, dest.provenance, dest_range)?;
+ M::memory_written(
+ *tcx,
+ extra,
+ &mut dest_alloc.extra,
+ (dest_alloc_id, dest_tag),
+ dest_range,
+ )?;
let dest_bytes = dest_alloc
.get_bytes_mut_ptr(&tcx, dest_range)
.map_err(|e| e.to_interp_error(dest_alloc_id))?
@@ -1053,8 +1072,10 @@ pub fn mem_copy_repeatedly(
// This also avoids writing to the target bytes so that the backing allocation is never
// touched if the bytes stay uninitialized for the whole interpreter execution. On contemporary
// operating system this can avoid physically allocating the page.
- dest_alloc.mark_init(dest_range, false); // `Size` multiplication
- dest_alloc.mark_relocation_range(relocations);
+ dest_alloc
+ .write_uninit(&tcx, dest_range)
+ .map_err(|e| e.to_interp_error(dest_alloc_id))?;
+ // We can forget about the relocations, this is all not initialized anyway.
return Ok(());
}
@@ -1159,11 +1180,11 @@ pub fn scalar_may_be_null(&self, scalar: Scalar<M::PointerTag>) -> InterpResult<
pub fn ptr_try_get_alloc_id(
&self,
ptr: Pointer<Option<M::PointerTag>>,
- ) -> Result<(AllocId, Size, Pointer<M::PointerTag>), u64> {
+ ) -> Result<(AllocId, Size, M::TagExtra), u64> {
match ptr.into_pointer_or_addr() {
Ok(ptr) => {
- let (alloc_id, offset) = M::ptr_get_alloc(self, ptr);
- Ok((alloc_id, offset, ptr))
+ let (alloc_id, offset, extra) = M::ptr_get_alloc(self, ptr);
+ Ok((alloc_id, offset, extra))
}
Err(addr) => Err(addr.bytes()),
}
@@ -1174,7 +1195,7 @@ pub fn ptr_try_get_alloc_id(
pub fn ptr_get_alloc_id(
&self,
ptr: Pointer<Option<M::PointerTag>>,
- ) -> InterpResult<'tcx, (AllocId, Size, Pointer<M::PointerTag>)> {
+ ) -> InterpResult<'tcx, (AllocId, Size, M::TagExtra)> {
self.ptr_try_get_alloc_id(ptr).map_err(|offset| {
err_ub!(DanglingIntPointer(offset, CheckInAllocMsg::InboundsTest)).into()
})
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 31da452..e4660fe 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -823,7 +823,7 @@ pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::PointerTag>) -> InterpRes
// Zero-sized access
return Ok(());
};
- alloc.write_uninit();
+ alloc.write_uninit()?;
Ok(())
}
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 4a0aa41..71d29be 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -432,7 +432,7 @@ fn check_safe_pointer(
if let Some(ref mut ref_tracking) = self.ref_tracking {
// Proceed recursively even for ZST, no reason to skip them!
// `!` is a ZST and we want to validate it.
- if let Ok((alloc_id, _offset, _ptr)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {
+ if let Ok((alloc_id, _offset, _tag)) = self.ecx.ptr_try_get_alloc_id(place.ptr) {
// Special handling for pointers to statics (irrespective of their type).
let alloc_kind = self.ecx.tcx.get_global_alloc(alloc_id);
if let Some(GlobalAlloc::Static(did)) = alloc_kind {
diff --git a/compiler/rustc_data_structures/src/stable_hasher.rs b/compiler/rustc_data_structures/src/stable_hasher.rs
index 85ad0f2..2535329 100644
--- a/compiler/rustc_data_structures/src/stable_hasher.rs
+++ b/compiler/rustc_data_structures/src/stable_hasher.rs
@@ -207,9 +207,14 @@ pub trait ToStableHashKey<HCX> {
fn to_stable_hash_key(&self, hcx: &HCX) -> Self::KeyType;
}
-// Implement HashStable by just calling `Hash::hash()`. This works fine for
-// self-contained values that don't depend on the hashing context `CTX`.
-#[macro_export]
+/// Implement HashStable by just calling `Hash::hash()`.
+///
+/// **WARNING** This is only valid for types that *really* don't need any context for fingerprinting.
+/// But it is easy to misuse this macro (see [#96013](https://github.com/rust-lang/rust/issues/96013)
+/// for examples). Therefore this macro is not exported and should only be used in the limited cases
+/// here in this module.
+///
+/// Use `#[derive(HashStable_Generic)]` instead.
macro_rules! impl_stable_hash_via_hash {
($t:ty) => {
impl<CTX> $crate::stable_hasher::HashStable<CTX> for $t {
@@ -246,12 +251,14 @@ fn hash_stable(&self, _ctx: &mut CTX, _hasher: &mut StableHasher) {
}
impl<CTX> HashStable<CTX> for ::std::num::NonZeroU32 {
+ #[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher)
}
}
impl<CTX> HashStable<CTX> for ::std::num::NonZeroUsize {
+ #[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
self.get().hash_stable(ctx, hasher)
}
@@ -272,12 +279,14 @@ fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
}
impl<CTX> HashStable<CTX> for ::std::cmp::Ordering {
+ #[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
(*self as i8).hash_stable(ctx, hasher);
}
}
impl<T1: HashStable<CTX>, CTX> HashStable<CTX> for (T1,) {
+ #[inline]
fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) {
let (ref _0,) = *self;
_0.hash_stable(ctx, hasher);
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index de0dd18..e1e0ed7 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -338,18 +338,12 @@ pub fn primary_spans(&self) -> &[Span] {
/// Returns `true` if any of the primary spans are displayable.
pub fn has_primary_spans(&self) -> bool {
- self.primary_spans.iter().any(|sp| !sp.is_dummy())
+ !self.is_dummy()
}
/// Returns `true` if this contains only a dummy primary span with any hygienic context.
pub fn is_dummy(&self) -> bool {
- let mut is_dummy = true;
- for span in &self.primary_spans {
- if !span.is_dummy() {
- is_dummy = false;
- }
- }
- is_dummy
+ self.primary_spans.iter().all(|sp| sp.is_dummy())
}
/// Replaces all occurrences of one Span with another. Used to move `Span`s in areas that don't
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 9cd072c..cd17726 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,12 +1,11 @@
use crate::snippet::Style;
use crate::{
CodeSuggestion, DiagnosticMessage, Level, MultiSpan, Substitution, SubstitutionPart,
- SuggestionStyle, ToolMetadata,
+ SuggestionStyle,
};
use rustc_data_structures::stable_map::FxHashMap;
use rustc_error_messages::FluentValue;
use rustc_lint_defs::{Applicability, LintExpectationId};
-use rustc_serialize::json::Json;
use rustc_span::edition::LATEST_STABLE_EDITION;
use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{Span, DUMMY_SP};
@@ -554,7 +553,6 @@ pub fn multipart_suggestion_with_style(
msg: msg.into(),
style,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -582,7 +580,6 @@ pub fn tool_only_multipart_suggestion(
msg: msg.into(),
style: SuggestionStyle::CompletelyHidden,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -637,7 +634,6 @@ pub fn span_suggestion_with_style(
msg: msg.into(),
style,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -680,7 +676,6 @@ pub fn span_suggestions(
msg: msg.into(),
style: SuggestionStyle::ShowCode,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -705,7 +700,6 @@ pub fn multipart_suggestions(
msg: msg.into(),
style: SuggestionStyle::ShowCode,
applicability,
- tool_metadata: Default::default(),
});
self
}
@@ -774,23 +768,6 @@ pub fn tool_only_span_suggestion(
self
}
- /// Adds a suggestion intended only for a tool. The intent is that the metadata encodes
- /// the suggestion in a tool-specific way, as it may not even directly involve Rust code.
- pub fn tool_only_suggestion_with_metadata(
- &mut self,
- msg: impl Into<DiagnosticMessage>,
- applicability: Applicability,
- tool_metadata: Json,
- ) {
- self.push_suggestion(CodeSuggestion {
- substitutions: vec![],
- msg: msg.into(),
- style: SuggestionStyle::CompletelyHidden,
- applicability,
- tool_metadata: ToolMetadata::new(tool_metadata),
- })
- }
-
pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
self.span = sp.into();
if let Some(span) = self.span.primary_span() {
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 0139007..d680e7f 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -14,7 +14,6 @@
use crate::emitter::{Emitter, HumanReadableErrorType};
use crate::registry::Registry;
use crate::DiagnosticId;
-use crate::ToolMetadata;
use crate::{
CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, SubDiagnostic,
};
@@ -30,7 +29,6 @@
use std::vec;
use rustc_serialize::json::{as_json, as_pretty_json};
-use rustc_serialize::{Encodable, Encoder};
#[cfg(test)]
mod tests;
@@ -205,8 +203,7 @@ fn should_show_explain(&self) -> bool {
// The following data types are provided just for serialisation.
-// NOTE: this has a manual implementation of Encodable which needs to be updated in
-// parallel.
+#[derive(Encodable)]
struct Diagnostic {
/// The primary error message.
message: String,
@@ -218,65 +215,6 @@ struct Diagnostic {
children: Vec<Diagnostic>,
/// The message as rustc would render it.
rendered: Option<String>,
- /// Extra tool metadata
- tool_metadata: ToolMetadata,
-}
-
-macro_rules! encode_fields {
- (
- $enc:expr, // encoder
- $idx:expr, // starting field index
- $struct:expr, // struct we're serializing
- $struct_name:ident, // struct name
- [ $($name:ident),+$(,)? ], // fields to encode
- [ $($ignore:ident),+$(,)? ] // fields we're skipping
- ) => {
- {
- // Pattern match to make sure all fields are accounted for
- let $struct_name { $($name,)+ $($ignore: _,)+ } = $struct;
- let mut idx = $idx;
- $(
- $enc.emit_struct_field(
- stringify!($name),
- idx == 0,
- |enc| $name.encode(enc),
- )?;
- idx += 1;
- )+
- idx
- }
- };
-}
-
-// Special-case encoder to skip tool_metadata if not set
-impl<E: Encoder> Encodable<E> for Diagnostic {
- fn encode(&self, s: &mut E) -> Result<(), E::Error> {
- s.emit_struct(false, |s| {
- let mut idx = 0;
-
- idx = encode_fields!(
- s,
- idx,
- self,
- Self,
- [message, code, level, spans, children, rendered],
- [tool_metadata]
- );
- if self.tool_metadata.is_set() {
- idx = encode_fields!(
- s,
- idx,
- self,
- Self,
- [tool_metadata],
- [message, code, level, spans, children, rendered]
- );
- }
-
- let _ = idx;
- Ok(())
- })
- }
}
#[derive(Encodable)]
@@ -380,7 +318,6 @@ fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnos
spans: DiagnosticSpan::from_suggestion(sugg, &args, je),
children: vec![],
rendered: None,
- tool_metadata: sugg.tool_metadata.clone(),
}
});
@@ -428,7 +365,6 @@ fn flush(&mut self) -> io::Result<()> {
.chain(sugg)
.collect(),
rendered: Some(output),
- tool_metadata: ToolMetadata::default(),
}
}
@@ -449,7 +385,6 @@ fn from_sub_diagnostic(
.unwrap_or_else(|| DiagnosticSpan::from_multispan(&diag.span, args, je)),
children: vec![],
rendered: None,
- tool_metadata: ToolMetadata::default(),
}
}
}
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index d7c5df7..4e6ab0e 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -36,13 +36,12 @@
LazyFallbackBundle, MultiSpan, SpanLabel, DEFAULT_LOCALE_RESOURCES,
};
pub use rustc_lint_defs::{pluralize, Applicability};
-use rustc_serialize::json::Json;
-use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_span::source_map::SourceMap;
+use rustc_span::HashStableContext;
use rustc_span::{Loc, Span};
use std::borrow::Cow;
-use std::hash::{Hash, Hasher};
+use std::hash::Hash;
use std::num::NonZeroUsize;
use std::panic;
use std::path::Path;
@@ -93,39 +92,6 @@ fn hide_inline(&self) -> bool {
}
}
-#[derive(Clone, Debug, PartialEq, Default)]
-pub struct ToolMetadata(pub Option<Json>);
-
-impl ToolMetadata {
- fn new(json: Json) -> Self {
- ToolMetadata(Some(json))
- }
-
- fn is_set(&self) -> bool {
- self.0.is_some()
- }
-}
-
-impl Hash for ToolMetadata {
- fn hash<H: Hasher>(&self, _state: &mut H) {}
-}
-
-// Doesn't really need to round-trip
-impl<D: Decoder> Decodable<D> for ToolMetadata {
- fn decode(_d: &mut D) -> Self {
- ToolMetadata(None)
- }
-}
-
-impl<S: Encoder> Encodable<S> for ToolMetadata {
- fn encode(&self, e: &mut S) -> Result<(), S::Error> {
- match &self.0 {
- None => e.emit_unit(),
- Some(json) => json.encode(e),
- }
- }
-}
-
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
pub struct CodeSuggestion {
/// Each substitute can have multiple variants due to multiple
@@ -159,8 +125,6 @@ pub struct CodeSuggestion {
/// which are useful for users but not useful for
/// tools like rustfix
pub applicability: Applicability,
- /// Tool-specific metadata
- pub tool_metadata: ToolMetadata,
}
#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
@@ -1531,6 +1495,7 @@ pub fn add_elided_lifetime_in_path_suggestion(
/// Useful type to use with `Result<>` indicate that an error has already
/// been reported to the user, so no need to continue checking.
#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(HashStable_Generic)]
pub struct ErrorGuaranteed(());
impl ErrorGuaranteed {
@@ -1540,5 +1505,3 @@ pub fn unchecked_claim_error_was_emitted() -> Self {
ErrorGuaranteed(())
}
}
-
-rustc_data_structures::impl_stable_hash_via_hash!(ErrorGuaranteed);
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 53d60d2..324e110 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -1,4 +1,4 @@
-use crate::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use crate::def_id::DefId;
use crate::hir;
use rustc_ast as ast;
@@ -124,9 +124,7 @@ impl DefKind {
pub fn descr(self, def_id: DefId) -> &'static str {
match self {
DefKind::Fn => "function",
- DefKind::Mod if def_id.index == CRATE_DEF_INDEX && def_id.krate != LOCAL_CRATE => {
- "crate"
- }
+ DefKind::Mod if def_id.is_crate_root() && !def_id.is_local() => "crate",
DefKind::Mod => "module",
DefKind::Static(..) => "static",
DefKind::Enum => "enum",
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index 4908992..bce9ba1 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -353,11 +353,6 @@ pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
}
}
- /// Retrieves the root definition.
- pub fn get_root_def(&self) -> LocalDefId {
- LocalDefId { local_def_index: CRATE_DEF_INDEX }
- }
-
/// Adds a definition with a parent definition.
pub fn create_def(
&mut self,
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index 3b5e4dc..346ac9e 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -1,4 +1,4 @@
-use crate::def_id::{LocalDefId, CRATE_DEF_INDEX};
+use crate::def_id::{LocalDefId, CRATE_DEF_ID};
use std::fmt;
/// Uniquely identifies a node in the HIR of the current crate. It is
@@ -76,16 +76,14 @@ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
/// integers starting at zero, so a mapping that maps all or most nodes within
/// an "item-like" to something else can be implemented by a `Vec` instead of a
/// tree or hash map.
+ #[derive(HashStable_Generic)]
pub struct ItemLocalId { .. }
}
-rustc_data_structures::impl_stable_hash_via_hash!(ItemLocalId);
+
impl ItemLocalId {
/// Signal local id which should never be used.
pub const INVALID: ItemLocalId = ItemLocalId::MAX;
}
-/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_INDEX`.
-pub const CRATE_HIR_ID: HirId = HirId {
- owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
- local_id: ItemLocalId::from_u32(0),
-};
+/// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
+pub const CRATE_HIR_ID: HirId = HirId { owner: CRATE_DEF_ID, local_id: ItemLocalId::from_u32(0) };
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 86229db..0ca0fe3 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -567,11 +567,17 @@ fn relate_item_substs(
// Avoid fetching the variance if we are in an invariant
// context; no need, and it can induce dependency cycles
// (e.g., #41849).
- relate::relate_substs(self, None, a_subst, b_subst)
+ relate::relate_substs(self, a_subst, b_subst)
} else {
let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id);
- relate::relate_substs(self, Some((item_def_id, &opt_variances)), a_subst, b_subst)
+ relate::relate_substs_with_variances(
+ self,
+ item_def_id,
+ &opt_variances,
+ a_subst,
+ b_subst,
+ )
}
}
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 65c0eba..ef6d464 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -53,7 +53,7 @@ fn relate_item_substs(
// performing trait matching (which then performs equality
// unification).
- relate::relate_substs(self, None, a_subst, b_subst)
+ relate::relate_substs(self, a_subst, b_subst)
}
fn relate_with_variance<T: Relate<'tcx>>(
diff --git a/compiler/rustc_lint/Cargo.toml b/compiler/rustc_lint/Cargo.toml
index 8ea47dd..02f747e 100644
--- a/compiler/rustc_lint/Cargo.toml
+++ b/compiler/rustc_lint/Cargo.toml
@@ -18,7 +18,6 @@
rustc_feature = { path = "../rustc_feature" }
rustc_index = { path = "../rustc_index" }
rustc_session = { path = "../rustc_session" }
-rustc_serialize = { path = "../rustc_serialize" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_parse_format = { path = "../rustc_parse_format" }
rustc_infer = { path = "../rustc_infer" }
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 152c53d..0ffa65b 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -33,8 +33,7 @@
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, print::Printer, subst::GenericArg, RegisteredTools, Ty, TyCtxt};
-use rustc_serialize::json::Json;
-use rustc_session::lint::{BuiltinLintDiagnostics, ExternDepSpec};
+use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::lint::{FutureIncompatibleInfo, Level, Lint, LintBuffer, LintId};
use rustc_session::Session;
use rustc_span::lev_distance::find_best_match_for_name;
@@ -728,30 +727,6 @@ fn lookup_with_diagnostics(
BuiltinLintDiagnostics::LegacyDeriveHelpers(span) => {
db.span_label(span, "the attribute is introduced here");
}
- BuiltinLintDiagnostics::ExternDepSpec(krate, loc) => {
- let json = match loc {
- ExternDepSpec::Json(json) => {
- db.help(&format!("remove unnecessary dependency `{}`", krate));
- json
- }
- ExternDepSpec::Raw(raw) => {
- db.help(&format!("remove unnecessary dependency `{}` at `{}`", krate, raw));
- db.span_suggestion_with_style(
- DUMMY_SP,
- "raw extern location",
- raw.clone(),
- Applicability::Unspecified,
- SuggestionStyle::CompletelyHidden,
- );
- Json::String(raw)
- }
- };
- db.tool_only_suggestion_with_metadata(
- "json extern location",
- Applicability::Unspecified,
- json
- );
- }
BuiltinLintDiagnostics::ProcMacroBackCompat(note) => {
db.note(¬e);
}
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 4debbf2..f590172 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -8,8 +8,8 @@
use rustc_ast::{AttrId, Attribute};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
use rustc_error_messages::MultiSpan;
+use rustc_hir::HashStableContext;
use rustc_hir::HirId;
-use rustc_serialize::json::Json;
use rustc_span::edition::Edition;
use rustc_span::{sym, symbol::Ident, Span, Symbol};
use rustc_target::spec::abi::Abi;
@@ -147,7 +147,7 @@ fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
/// Setting for how to handle a lint.
///
/// See: <https://doc.rust-lang.org/rustc/lints/levels.html>
-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash, HashStable_Generic)]
pub enum Level {
/// The `allow` level will not issue any message.
Allow,
@@ -175,8 +175,6 @@ pub enum Level {
Forbid,
}
-rustc_data_structures::impl_stable_hash_via_hash!(Level);
-
impl Level {
/// Converts a level to a lower-case string.
pub fn as_str(self) -> &'static str {
@@ -403,13 +401,6 @@ fn to_stable_hash_key(&self, _: &HCX) -> &'static str {
}
}
-// Duplicated from rustc_session::config::ExternDepSpec to avoid cyclic dependency
-#[derive(PartialEq, Debug)]
-pub enum ExternDepSpec {
- Json(Json),
- Raw(String),
-}
-
// This could be a closure, but then implementing derive trait
// becomes hacky (and it gets allocated).
#[derive(Debug)]
@@ -428,7 +419,6 @@ pub enum BuiltinLintDiagnostics {
UnusedBuiltinAttribute { attr_name: Symbol, macro_name: String, invoc_span: Span },
PatternsInFnsWithoutBody(Span, Ident),
LegacyDeriveHelpers(Span),
- ExternDepSpec(String, ExternDepSpec),
ProcMacroBackCompat(String),
OrPatternsBackCompat(Span, String),
ReservedPrefix(Span),
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 566d272..e5d0cd2 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -13,11 +13,10 @@
use rustc_hir::definitions::Definitions;
use rustc_index::vec::IndexVec;
use rustc_middle::ty::TyCtxt;
-use rustc_serialize::json::ToJson;
use rustc_session::config::{self, CrateType, ExternLocation};
use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate};
use rustc_session::cstore::{ExternCrateSource, MetadataLoaderDyn};
-use rustc_session::lint::{self, BuiltinLintDiagnostics, ExternDepSpec};
+use rustc_session::lint;
use rustc_session::output::validate_crate_name;
use rustc_session::search_paths::PathKind;
use rustc_session::Session;
@@ -27,7 +26,6 @@
use rustc_target::spec::{PanicStrategy, TargetTriple};
use proc_macro::bridge::client::ProcMacro;
-use std::collections::BTreeMap;
use std::ops::Fn;
use std::path::Path;
use std::{cmp, env};
@@ -920,20 +918,7 @@ fn report_unused_deps(&mut self, krate: &ast::Crate) {
continue;
}
- let diag = match self.sess.opts.extern_dep_specs.get(name) {
- Some(loc) => BuiltinLintDiagnostics::ExternDepSpec(name.clone(), loc.into()),
- None => {
- // If we don't have a specific location, provide a json encoding of the `--extern`
- // option.
- let meta: BTreeMap<String, String> =
- std::iter::once(("name".to_string(), name.to_string())).collect();
- BuiltinLintDiagnostics::ExternDepSpec(
- name.clone(),
- ExternDepSpec::Json(meta.to_json()),
- )
- }
- };
- self.sess.parse_sess.buffer_lint_with_diagnostic(
+ self.sess.parse_sess.buffer_lint(
lint::builtin::UNUSED_CRATE_DEPENDENCIES,
span,
ast::CRATE_NODE_ID,
@@ -942,7 +927,6 @@ fn report_unused_deps(&mut self, krate: &ast::Crate) {
name,
self.local_crate_name,
name),
- diag,
);
}
}
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 611694a..77afa7b 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -28,6 +28,7 @@
use rustc_middle::thir;
use rustc_middle::ty::codec::TyDecoder;
use rustc_middle::ty::fast_reject::SimplifiedType;
+use rustc_middle::ty::GeneratorDiagnosticData;
use rustc_middle::ty::{self, Ty, TyCtxt, Visibility};
use rustc_serialize::{opaque, Decodable, Decoder};
use rustc_session::cstore::{
@@ -1725,6 +1726,28 @@ fn imported_source_files(self, sess: &Session) -> &'a [ImportedSourceFile] {
.collect()
})
}
+
+ fn get_generator_diagnostic_data(
+ self,
+ tcx: TyCtxt<'tcx>,
+ id: DefIndex,
+ ) -> Option<GeneratorDiagnosticData<'tcx>> {
+ self.root
+ .tables
+ .generator_diagnostic_data
+ .get(self, id)
+ .map(|param| param.decode((self, tcx)))
+ .map(|generator_data| GeneratorDiagnosticData {
+ generator_interior_types: generator_data.generator_interior_types,
+ hir_owner: generator_data.hir_owner,
+ nodes_types: generator_data.nodes_types,
+ adjustments: generator_data.adjustments,
+ })
+ }
+
+ fn get_may_have_doc_links(self, index: DefIndex) -> bool {
+ self.root.tables.may_have_doc_links.get(self, index).is_some()
+ }
}
impl CrateMetadata {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 63bf929..6b1f7d5 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -5,7 +5,7 @@
use rustc_ast as ast;
use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
use rustc_middle::metadata::ModChild;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
@@ -246,6 +246,7 @@ fn into_args(self) -> (DefId, SimplifiedType) {
crate_extern_paths => { cdata.source().paths().cloned().collect() }
expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
+ generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) }
}
pub(in crate::rmeta) fn provide(providers: &mut Providers) {
@@ -324,7 +325,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
continue;
}
- bfs_queue.push_back(DefId { krate: cnum, index: CRATE_DEF_INDEX });
+ bfs_queue.push_back(cnum.as_def_id());
}
let mut add_child = |bfs_queue: &mut VecDeque<_>, child: &ModChild, parent: DefId| {
@@ -530,6 +531,10 @@ pub fn incoherent_impls_in_crate_untracked(
) -> impl Iterator<Item = DefId> + '_ {
self.get_crate_data(cnum).get_all_incoherent_impls()
}
+
+ pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool {
+ self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index)
+ }
}
impl CrateStore for CStore {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 6a8d4e0..f485e09 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -977,6 +977,14 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
+ fn encode_attrs(&mut self, def_id: DefId) {
+ let attrs = self.tcx.get_attrs(def_id);
+ record!(self.tables.attributes[def_id] <- attrs);
+ if attrs.iter().any(|attr| attr.may_have_doc_links()) {
+ self.tables.may_have_doc_links.set(def_id.index, ());
+ }
+ }
+
fn encode_def_ids(&mut self) {
if self.is_proc_macro {
return;
@@ -989,7 +997,7 @@ fn encode_def_ids(&mut self) {
let Some(def_kind) = def_kind else { continue };
self.tables.opt_def_kind.set(def_id.index, def_kind);
record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
- record!(self.tables.attributes[def_id] <- tcx.get_attrs(def_id));
+ self.encode_attrs(def_id);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
if should_encode_visibility(def_kind) {
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
@@ -1556,16 +1564,17 @@ fn encode_info_for_generic_param(&mut self, def_id: DefId, kind: EntryKind, enco
fn encode_info_for_closure(&mut self, hir_id: hir::HirId) {
let def_id = self.tcx.hir().local_def_id(hir_id);
debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
-
// NOTE(eddyb) `tcx.type_of(def_id)` isn't used because it's fully generic,
// including on the signature, which is inferred in `typeck.
- let ty = self.tcx.typeck(def_id).node_type(hir_id);
-
+ let typeck_result: &'tcx ty::TypeckResults<'tcx> = self.tcx.typeck(def_id);
+ let ty = typeck_result.node_type(hir_id);
match ty.kind() {
ty::Generator(..) => {
let data = self.tcx.generator_kind(def_id).unwrap();
+ let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
record!(self.tables.kind[def_id.to_def_id()] <- EntryKind::Generator);
record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
+ record!(self.tables.generator_diagnostic_data[def_id.to_def_id()] <- generator_diagnostic_data);
}
ty::Closure(..) => {
@@ -1639,7 +1648,7 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
let hir = tcx.hir();
let proc_macro_decls_static = tcx.proc_macro_decls_static(()).unwrap().local_def_index;
- let stability = tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX));
+ let stability = tcx.lookup_stability(CRATE_DEF_ID);
let macros =
self.lazy(tcx.resolutions(()).proc_macros.iter().map(|p| p.local_def_index));
let spans = self.tcx.sess.parse_sess.proc_macro_quoted_spans();
@@ -1650,7 +1659,7 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
- record!(self.tables.attributes[LOCAL_CRATE.as_def_id()] <- tcx.get_attrs(LOCAL_CRATE.as_def_id()));
+ self.encode_attrs(LOCAL_CRATE.as_def_id());
record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id()));
if let Some(stability) = stability {
record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability);
@@ -1691,7 +1700,7 @@ fn encode_proc_macros(&mut self) -> Option<ProcMacroData> {
let def_id = id.to_def_id();
self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
- record!(self.tables.attributes[def_id] <- attrs);
+ self.encode_attrs(def_id);
record!(self.tables.def_keys[def_id] <- def_key);
record!(self.tables.def_ident_span[def_id] <- span);
record!(self.tables.def_span[def_id] <- span);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 43ccfc6..f149866 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -19,6 +19,7 @@
use rustc_middle::thir;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::Providers;
+use rustc_middle::ty::GeneratorDiagnosticData;
use rustc_middle::ty::{self, ReprOptions, Ty};
use rustc_serialize::opaque::Encoder;
use rustc_session::config::SymbolManglingVersion;
@@ -358,6 +359,8 @@ fn encode(&self, buf: &mut Encoder) -> LazyTables<'tcx> {
def_keys: Table<DefIndex, Lazy<DefKey>>,
def_path_hashes: Table<DefIndex, DefPathHash>,
proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
+ generator_diagnostic_data: Table<DefIndex, Lazy<GeneratorDiagnosticData<'tcx>>>,
+ may_have_doc_links: Table<DefIndex, ()>,
}
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index 7a23cba..53fc2ef 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -186,6 +186,20 @@ impl FixedSizeEncoding for Option<RawDefId> {
}
}
+impl FixedSizeEncoding for Option<()> {
+ type ByteArray = [u8; 1];
+
+ #[inline]
+ fn from_bytes(b: &[u8; 1]) -> Self {
+ (b[0] != 0).then(|| ())
+ }
+
+ #[inline]
+ fn write_to_bytes(self, b: &mut [u8; 1]) {
+ b[0] = self.is_some() as u8
+ }
+}
+
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
// generic `Lazy<T>` impl, but in the general case we might not need / want to
// fit every `usize` in `u32`.
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index d20be0a..8402ca3 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -60,7 +60,7 @@
use crate::ty::TyCtxt;
use rustc_data_structures::fingerprint::Fingerprint;
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_hir::definitions::DefPathHash;
use rustc_hir::HirId;
use rustc_query_system::dep_graph::FingerprintStyle;
@@ -366,7 +366,7 @@ fn fingerprint_style() -> FingerprintStyle {
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
- let def_id = DefId { krate: *self, index: CRATE_DEF_INDEX };
+ let def_id = self.as_def_id();
def_id.to_fingerprint(tcx)
}
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index fd6e241..758658c 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -11,7 +11,7 @@
use rustc_feature::GateIssue;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self, HirId};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
@@ -370,8 +370,7 @@ pub fn eval_stability(
};
}
- let is_staged_api =
- self.lookup_stability(DefId { index: CRATE_DEF_INDEX, ..def_id }).is_some();
+ let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
if !is_staged_api {
return EvalResult::Allow;
}
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 438f356..c628406 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -269,7 +269,7 @@ impl<Tag: Provenance, Extra> Allocation<Tag, Extra> {
/// `get_bytes_with_uninit_and_ptr` instead,
///
/// This function also guarantees that the resulting pointer will remain stable
- /// even when new allocations are pushed to the `HashMap`. `copy_repeatedly` relies
+ /// even when new allocations are pushed to the `HashMap`. `mem_copy_repeatedly` relies
/// on that.
///
/// It is the caller's responsibility to check bounds and alignment beforehand.
@@ -429,8 +429,7 @@ pub fn write_scalar(
let val = match val {
ScalarMaybeUninit::Scalar(scalar) => scalar,
ScalarMaybeUninit::Uninit => {
- self.mark_init(range, false);
- return Ok(());
+ return self.write_uninit(cx, range);
}
};
@@ -455,6 +454,13 @@ pub fn write_scalar(
Ok(())
}
+
+ /// Write "uninit" to the given memory range.
+ pub fn write_uninit(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> AllocResult {
+ self.mark_init(range, false);
+ self.clear_relocations(cx, range)?;
+ return Ok(());
+ }
}
/// Relocations.
@@ -509,6 +515,9 @@ fn clear_relocations(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> A
if Tag::ERR_ON_PARTIAL_PTR_OVERWRITE {
return Err(AllocError::PartialPointerOverwrite(first));
}
+ warn!(
+ "Partial pointer overwrite! De-initializing memory at offsets {first:?}..{start:?}."
+ );
self.init_mask.set_range(first, start, false);
}
if last > end {
@@ -517,10 +526,15 @@ fn clear_relocations(&mut self, cx: &impl HasDataLayout, range: AllocRange) -> A
last - cx.data_layout().pointer_size,
));
}
+ warn!(
+ "Partial pointer overwrite! De-initializing memory at offsets {end:?}..{last:?}."
+ );
self.init_mask.set_range(end, last, false);
}
// Forget all the relocations.
+ // Since relocations do not overlap, we know that removing until `last` (exclusive) is fine,
+ // i.e., this will not remove any other relocations just after the ones we care about.
self.relocations.0.remove_range(first..last);
Ok(())
@@ -561,8 +575,10 @@ fn deref(&self) -> &Self::Target {
}
/// A partial, owned list of relocations to transfer into another allocation.
+///
+/// Offsets are already adjusted to the destination allocation.
pub struct AllocationRelocations<Tag> {
- relative_relocations: Vec<(Size, Tag)>,
+ dest_relocations: Vec<(Size, Tag)>,
}
impl<Tag: Copy, Extra> Allocation<Tag, Extra> {
@@ -575,12 +591,17 @@ pub fn prepare_relocation_copy(
) -> AllocationRelocations<Tag> {
let relocations = self.get_relocations(cx, src);
if relocations.is_empty() {
- return AllocationRelocations { relative_relocations: Vec::new() };
+ return AllocationRelocations { dest_relocations: Vec::new() };
}
let size = src.size;
let mut new_relocations = Vec::with_capacity(relocations.len() * (count as usize));
+ // If `count` is large, this is rather wasteful -- we are allocating a big array here, which
+ // is mostly filled with redundant information since it's just N copies of the same `Tag`s
+ // at slightly adjusted offsets. The reason we do this is so that in `mark_relocation_range`
+ // we can use `insert_presorted`. That wouldn't work with an `Iterator` that just produces
+ // the right sequence of relocations for all N copies.
for i in 0..count {
new_relocations.extend(relocations.iter().map(|&(offset, reloc)| {
// compute offset for current repetition
@@ -593,14 +614,17 @@ pub fn prepare_relocation_copy(
}));
}
- AllocationRelocations { relative_relocations: new_relocations }
+ AllocationRelocations { dest_relocations: new_relocations }
}
/// Applies a relocation copy.
/// The affected range, as defined in the parameters to `prepare_relocation_copy` is expected
/// to be clear of relocations.
+ ///
+ /// This is dangerous to use as it can violate internal `Allocation` invariants!
+ /// It only exists to support an efficient implementation of `mem_copy_repeatedly`.
pub fn mark_relocation_range(&mut self, relocations: AllocationRelocations<Tag>) {
- self.relocations.0.insert_presorted(relocations.relative_relocations);
+ self.relocations.0.insert_presorted(relocations.dest_relocations);
}
}
@@ -1056,7 +1080,7 @@ fn check_init(&self, range: AllocRange) -> AllocResult {
})
}
- pub fn mark_init(&mut self, range: AllocRange, is_init: bool) {
+ fn mark_init(&mut self, range: AllocRange, is_init: bool) {
if range.size.bytes() == 0 {
return;
}
@@ -1118,6 +1142,9 @@ pub fn compress_uninit_range(&self, range: AllocRange) -> InitMaskCompressed {
}
/// Applies multiple instances of the run-length encoding to the initialization mask.
+ ///
+ /// This is dangerous to use as it can violate internal `Allocation` invariants!
+ /// It only exists to support an efficient implementation of `mem_copy_repeatedly`.
pub fn mark_compressed_init_range(
&mut self,
defined: &InitMaskCompressed,
diff --git a/compiler/rustc_middle/src/mir/interpret/pointer.rs b/compiler/rustc_middle/src/mir/interpret/pointer.rs
index 813c091..c71aea4 100644
--- a/compiler/rustc_middle/src/mir/interpret/pointer.rs
+++ b/compiler/rustc_middle/src/mir/interpret/pointer.rs
@@ -163,6 +163,9 @@ pub struct Pointer<Tag = AllocId> {
}
static_assert_size!(Pointer, 16);
+// `Option<Tag>` pointers are also passed around quite a bit
+// (but not stored in permanent machine state).
+static_assert_size!(Pointer<Option<AllocId>>, 16);
// We want the `Debug` output to be readable as it is used by `derive(Debug)` for
// all the Miri types.
@@ -198,12 +201,26 @@ fn from(ptr: Pointer<Tag>) -> Self {
}
impl<Tag> Pointer<Option<Tag>> {
+ /// Convert this pointer that *might* have a tag into a pointer that *definitely* has a tag, or
+ /// an absolute address.
+ ///
+ /// This is rarely what you want; call `ptr_try_get_alloc_id` instead.
pub fn into_pointer_or_addr(self) -> Result<Pointer<Tag>, Size> {
match self.provenance {
Some(tag) => Ok(Pointer::new(tag, self.offset)),
None => Err(self.offset),
}
}
+
+ /// Returns the absolute address the pointer points to.
+ /// Only works if Tag::OFFSET_IS_ADDR is true!
+ pub fn addr(self) -> Size
+ where
+ Tag: Provenance,
+ {
+ assert!(Tag::OFFSET_IS_ADDR);
+ self.offset
+ }
}
impl<Tag> Pointer<Option<Tag>> {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 49769b7..4f4b6cf 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -15,7 +15,7 @@
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{CtorKind, Namespace};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_hir::{self, GeneratorKind};
use rustc_hir::{self as hir, HirId};
use rustc_session::Session;
@@ -385,7 +385,7 @@ pub fn new(
pub fn new_cfg_only(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
let mut body = Body {
phase: MirPhase::Built,
- source: MirSource::item(DefId::local(CRATE_DEF_INDEX)),
+ source: MirSource::item(CRATE_DEF_ID.to_def_id()),
basic_blocks,
source_scopes: IndexVec::new(),
generator: None,
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 69dac03..b7f695d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -851,6 +851,7 @@ fn write_allocation_bytes<'tcx, Tag: Provenance, Extra>(
}
if let Some(&tag) = alloc.relocations().get(&i) {
// Memory with a relocation must be defined
+ assert!(alloc.init_mask().is_range_initialized(i, i + ptr_size).is_ok());
let j = i.bytes_usize();
let offset = alloc
.inspect_with_uninit_and_ptr_outside_interpreter(j..j + ptr_size.bytes_usize());
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 999cb9f..78a3383 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1969,4 +1969,10 @@
eval_always
desc { "computing the backend features for CLI flags" }
}
+
+ query generator_diagnostic_data(key: DefId) -> Option<GeneratorDiagnosticData<'tcx>> {
+ storage(ArenaCacheSelector<'tcx>)
+ desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) }
+ separate_provide_extern
+ }
}
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 4b7c1d4..7af7eb4 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -44,10 +44,12 @@ pub struct ConstS<'tcx> {
static_assert_size!(ConstS<'_>, 48);
impl<'tcx> Const<'tcx> {
+ #[inline]
pub fn ty(self) -> Ty<'tcx> {
self.0.ty
}
+ #[inline]
pub fn val(self) -> ConstKind<'tcx> {
self.0.val
}
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4e6be84..30fe3ff 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -367,6 +367,16 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
pub expr: Option<hir::HirId>,
}
+// This type holds diagnostic information on generators and async functions across crate boundaries
+// and is used to provide better error messages
+#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
+pub struct GeneratorDiagnosticData<'tcx> {
+ pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
+ pub hir_owner: DefId,
+ pub nodes_types: ItemLocalMap<Ty<'tcx>>,
+ pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
+}
+
#[derive(TyEncodable, TyDecodable, Debug, HashStable)]
pub struct TypeckResults<'tcx> {
/// The `HirId::owner` all `ItemLocalId`s in this table are relative to.
@@ -623,6 +633,28 @@ pub fn node_types_mut(&mut self) -> LocalTableInContextMut<'_, Ty<'tcx>> {
LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
}
+ pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
+ let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
+ vec.iter()
+ .map(|item| {
+ GeneratorInteriorTypeCause {
+ ty: item.ty,
+ span: item.span,
+ scope_span: item.scope_span,
+ yield_span: item.yield_span,
+ expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
+ }
+ })
+ .collect::<Vec<_>>()
+ });
+ GeneratorDiagnosticData {
+ generator_interior_types: generator_interior_type,
+ hir_owner: self.hir_owner.to_def_id(),
+ nodes_types: self.node_types.clone(),
+ adjustments: self.adjustments.clone(),
+ }
+ }
+
pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
self.node_type_opt(id).unwrap_or_else(|| {
bug!("node_type: no type for node `{}`", tls::with(|tcx| tcx.hir().node_to_string(id)))
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index c2accea..d59fdf4 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -36,7 +36,7 @@
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, CRATE_DEF_ID};
use rustc_hir::Node;
use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext;
@@ -67,8 +67,9 @@
};
pub use self::context::{
tls, CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
- CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorInteriorTypeCause, GlobalCtxt,
- Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex,
+ CtxtInterners, DelaySpanBugEmitted, FreeRegionInfo, GeneratorDiagnosticData,
+ GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType,
+ UserTypeAnnotationIndex,
};
pub use self::instance::{Instance, InstanceDef};
pub use self::list::List;
@@ -319,7 +320,7 @@ impl Visibility {
pub fn from_hir(visibility: &hir::Visibility<'_>, id: hir::HirId, tcx: TyCtxt<'_>) -> Self {
match visibility.node {
hir::VisibilityKind::Public => Visibility::Public,
- hir::VisibilityKind::Crate(_) => Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)),
+ hir::VisibilityKind::Crate(_) => Visibility::Restricted(CRATE_DEF_ID.to_def_id()),
hir::VisibilityKind::Restricted { ref path, .. } => match path.res {
// If there is no resolution, `resolve` will have already reported an error, so
// assume that the visibility is public to avoid reporting more privacy errors.
@@ -1992,8 +1993,8 @@ pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'
}
fn opt_item_name(self, def_id: DefId) -> Option<Symbol> {
- if def_id.index == CRATE_DEF_INDEX {
- Some(self.crate_name(def_id.krate))
+ if let Some(cnum) = def_id.as_crate_root() {
+ Some(self.crate_name(cnum))
} else {
let def_key = self.def_key(def_id);
match def_key.disambiguated_data.data {
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index cac46ba..38362a4 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -6,7 +6,7 @@
use rustc_data_structures::sso::SsoHashSet;
use rustc_hir as hir;
use rustc_hir::def::{self, CtorKind, DefKind, Namespace};
-use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
use rustc_session::config::TrimmedDefPaths;
use rustc_session::cstore::{ExternCrate, ExternCrateSource};
@@ -335,9 +335,7 @@ fn try_print_visible_def_path_recur(
// If `def_id` is a direct or injected extern crate, return the
// path to the crate followed by the path to the item within the crate.
- if def_id.index == CRATE_DEF_INDEX {
- let cnum = def_id.krate;
-
+ if let Some(cnum) = def_id.as_crate_root() {
if cnum == LOCAL_CRATE {
return Ok((self.path_crate(cnum)?, true));
}
@@ -2227,11 +2225,11 @@ fn name_by_region_index(index: usize) -> Symbol {
ty::BrNamed(_, _) => br.kind,
ty::BrAnon(i) => {
let name = region_map[&(i + 1)];
- ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
+ ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
}
ty::BrEnv => {
let name = region_map[&0];
- ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
+ ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
}
};
self.tcx.mk_region(ty::ReLateBound(
@@ -2257,7 +2255,7 @@ fn name_by_region_index(index: usize) -> Symbol {
}
};
do_continue(&mut self, name);
- ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
+ ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
}
};
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
@@ -2697,7 +2695,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
let mut seen_defs: DefIdSet = Default::default();
for &cnum in tcx.crates(()).iter() {
- let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
+ let def_id = cnum.as_def_id();
// Ignore crates that are not direct dependencies.
match tcx.extern_crate(def_id) {
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 9e48c56..7629d7a 100644
--- a/compiler/rustc_middle/src/ty/query.rs
+++ b/compiler/rustc_middle/src/ty/query.rs
@@ -31,8 +31,11 @@
use crate::ty::fast_reject::SimplifiedType;
use crate::ty::subst::{GenericArg, SubstsRef};
use crate::ty::util::AlwaysRequiresDrop;
+use crate::ty::GeneratorDiagnosticData;
use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
+use rustc_ast as ast;
use rustc_ast::expand::allocator::AllocatorKind;
+use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::svh::Svh;
@@ -49,13 +52,10 @@
use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
use rustc_session::utils::NativeLibKind;
use rustc_session::Limits;
-use rustc_target::abi;
-use rustc_target::spec::PanicStrategy;
-
-use rustc_ast as ast;
-use rustc_attr as attr;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
+use rustc_target::abi;
+use rustc_target::spec::PanicStrategy;
use std::ops::Deref;
use std::path::PathBuf;
use std::sync::Arc;
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index d9b5556..4c1160e 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -61,7 +61,7 @@ fn relate_item_substs(
let tcx = self.tcx();
let opt_variances = tcx.variances_of(item_def_id);
- relate_substs(self, Some((item_def_id, opt_variances)), a_subst, b_subst)
+ relate_substs_with_variances(self, item_def_id, opt_variances, a_subst, b_subst)
}
/// Switch variance for the purpose of relating `a` and `b`.
@@ -135,29 +135,34 @@ pub fn relate_type_and_mut<'tcx, R: TypeRelation<'tcx>>(
}
}
+#[inline]
pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>(
relation: &mut R,
- variances: Option<(DefId, &[ty::Variance])>,
+ a_subst: SubstsRef<'tcx>,
+ b_subst: SubstsRef<'tcx>,
+) -> RelateResult<'tcx, SubstsRef<'tcx>> {
+ relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| {
+ relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b)
+ }))
+}
+
+pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>(
+ relation: &mut R,
+ ty_def_id: DefId,
+ variances: &[ty::Variance],
a_subst: SubstsRef<'tcx>,
b_subst: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
let tcx = relation.tcx();
- let mut cached_ty = None;
+ let mut cached_ty = None;
let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| {
- let (variance, variance_info) = match variances {
- Some((ty_def_id, variances)) => {
- let variance = variances[i];
- let variance_info = if variance == ty::Invariant {
- let ty = *cached_ty
- .get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
- ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
- } else {
- ty::VarianceDiagInfo::default()
- };
- (variance, variance_info)
- }
- None => (ty::Invariant, ty::VarianceDiagInfo::default()),
+ let variance = variances[i];
+ let variance_info = if variance == ty::Invariant {
+ let ty = *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).subst(tcx, a_subst));
+ ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
+ } else {
+ ty::VarianceDiagInfo::default()
};
relation.relate_with_variance(variance, variance_info, a, b)
});
@@ -318,7 +323,7 @@ fn relate<R: TypeRelation<'tcx>>(
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
- let substs = relate_substs(relation, None, a.substs, b.substs)?;
+ let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::TraitRef { def_id: a.def_id, substs })
}
}
@@ -334,7 +339,7 @@ fn relate<R: TypeRelation<'tcx>>(
if a.def_id != b.def_id {
Err(TypeError::Traits(expected_found(relation, a.def_id, b.def_id)))
} else {
- let substs = relate_substs(relation, None, a.substs, b.substs)?;
+ let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::ExistentialTraitRef { def_id: a.def_id, substs })
}
}
@@ -554,7 +559,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>(
(&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs))
if a_def_id == b_def_id =>
{
- let substs = relate_substs(relation, None, a_substs, b_substs)?;
+ let substs = relate_substs(relation, a_substs, b_substs)?;
Ok(tcx.mk_opaque(a_def_id, substs))
}
@@ -742,7 +747,7 @@ fn relate<R: TypeRelation<'tcx>>(
a: ty::ClosureSubsts<'tcx>,
b: ty::ClosureSubsts<'tcx>,
) -> RelateResult<'tcx, ty::ClosureSubsts<'tcx>> {
- let substs = relate_substs(relation, None, a.substs, b.substs)?;
+ let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::ClosureSubsts { substs })
}
}
@@ -753,7 +758,7 @@ fn relate<R: TypeRelation<'tcx>>(
a: ty::GeneratorSubsts<'tcx>,
b: ty::GeneratorSubsts<'tcx>,
) -> RelateResult<'tcx, ty::GeneratorSubsts<'tcx>> {
- let substs = relate_substs(relation, None, a.substs, b.substs)?;
+ let substs = relate_substs(relation, a.substs, b.substs)?;
Ok(ty::GeneratorSubsts { substs })
}
}
@@ -764,7 +769,7 @@ fn relate<R: TypeRelation<'tcx>>(
a: SubstsRef<'tcx>,
b: SubstsRef<'tcx>,
) -> RelateResult<'tcx, SubstsRef<'tcx>> {
- relate_substs(relation, None, a, b)
+ relate_substs(relation, a, b)
}
}
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index 5c7910d..4ef6ff1 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -10,7 +10,6 @@
use rustc_data_structures::functor::IdFunctor;
use rustc_hir as hir;
use rustc_hir::def::Namespace;
-use rustc_hir::def_id::CRATE_DEF_INDEX;
use rustc_index::vec::{Idx, IndexVec};
use std::fmt;
@@ -71,7 +70,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::BrAnon(n) => write!(f, "BrAnon({:?})", n),
ty::BrNamed(did, name) => {
- if did.index == CRATE_DEF_INDEX {
+ if did.is_crate_root() {
write!(f, "BrNamed({})", name)
} else {
write!(f, "BrNamed({:?}, {})", did, name)
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index a04ac33..cee657e 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -255,10 +255,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
func: fun,
args,
cleanup: None,
- // FIXME(varkor): replace this with an uninhabitedness-based check.
- // This requires getting access to the current module to call
- // `tcx.is_ty_uninhabited_from`, which is currently tricky to do.
- destination: if expr.ty.is_never() {
+ // The presence or absence of a return edge affects control-flow sensitive
+ // MIR checks and ultimately whether code is accepted or not. We can only
+ // omit the return edge if a return type is visibly uninhabited to a module
+ // that makes the call.
+ destination: if this.tcx.is_ty_uninhabited_from(
+ this.parent_module,
+ expr.ty,
+ this.param_env,
+ ) {
None
} else {
Some((destination, success))
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 901635d..3c51f79 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -350,6 +350,7 @@ struct Builder<'a, 'tcx> {
def_id: DefId,
hir_id: hir::HirId,
+ parent_module: DefId,
check_overflow: bool,
fn_span: Span,
arg_count: usize,
@@ -807,15 +808,17 @@ fn new(
);
let lint_level = LintLevel::Explicit(hir_id);
+ let param_env = tcx.param_env(def.did);
let mut builder = Builder {
thir,
tcx,
infcx,
typeck_results: tcx.typeck_opt_const_arg(def),
region_scope_tree: tcx.region_scope_tree(def.did),
- param_env: tcx.param_env(def.did),
+ param_env,
def_id: def.did.to_def_id(),
hir_id,
+ parent_module: tcx.parent_module(hir_id).to_def_id(),
check_overflow,
cfg: CFG { basic_blocks: IndexVec::new() },
fn_span: span,
diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs
index c4ffb19..1677419 100644
--- a/compiler/rustc_monomorphize/src/partitioning/default.rs
+++ b/compiler/rustc_monomorphize/src/partitioning/default.rs
@@ -2,7 +2,7 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathDataName;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::exported_symbols::SymbolExportLevel;
@@ -335,10 +335,10 @@ fn compute_codegen_unit_name(
let mut cgu_def_id = None;
// Walk backwards from the item we want to find the module for.
loop {
- if current_def_id.index == CRATE_DEF_INDEX {
+ if current_def_id.is_crate_root() {
if cgu_def_id.is_none() {
// If we have not found a module yet, take the crate root.
- cgu_def_id = Some(DefId { krate: def_id.krate, index: CRATE_DEF_INDEX });
+ cgu_def_id = Some(def_id.krate.as_def_id());
}
break;
} else if tcx.def_kind(current_def_id) == DefKind::Mod {
diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs
index 5a1373a..db083d0 100644
--- a/compiler/rustc_passes/src/entry.rs
+++ b/compiler/rustc_passes/src/entry.rs
@@ -1,21 +1,18 @@
use rustc_ast::entry::EntryPointType;
use rustc_errors::struct_span_err;
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{ForeignItem, ImplItem, Item, ItemKind, Node, TraitItem, CRATE_HIR_ID};
-use rustc_middle::hir::map::Map;
use rustc_middle::ty::query::Providers;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{DefIdTree, TyCtxt};
use rustc_session::config::{CrateType, EntryFnType};
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::symbol::sym;
use rustc_span::{Span, DUMMY_SP};
-struct EntryContext<'a, 'tcx> {
- session: &'a Session,
-
- map: Map<'tcx>,
+struct EntryContext<'tcx> {
+ tcx: TyCtxt<'tcx>,
/// The function that has attribute named `main`.
attr_main_fn: Option<(LocalDefId, Span)>,
@@ -28,10 +25,9 @@ struct EntryContext<'a, 'tcx> {
non_main_fns: Vec<Span>,
}
-impl<'a, 'tcx> ItemLikeVisitor<'tcx> for EntryContext<'a, 'tcx> {
+impl<'tcx> ItemLikeVisitor<'tcx> for EntryContext<'tcx> {
fn visit_item(&mut self, item: &'tcx Item<'tcx>) {
- let def_key = self.map.def_key(item.def_id);
- let at_root = def_key.parent == Some(CRATE_DEF_INDEX);
+ let at_root = self.tcx.local_parent(item.def_id) == Some(CRATE_DEF_ID);
find_item(item, self, at_root);
}
@@ -60,13 +56,8 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
return None;
}
- let mut ctxt = EntryContext {
- session: tcx.sess,
- map: tcx.hir(),
- attr_main_fn: None,
- start_fn: None,
- non_main_fns: Vec::new(),
- };
+ let mut ctxt =
+ EntryContext { tcx, attr_main_fn: None, start_fn: None, non_main_fns: Vec::new() };
tcx.hir().visit_all_item_likes(&mut ctxt);
@@ -75,11 +66,11 @@ fn entry_fn(tcx: TyCtxt<'_>, (): ()) -> Option<(DefId, EntryFnType)> {
// Beware, this is duplicated in `librustc_builtin_macros/test_harness.rs`
// (with `ast::Item`), so make sure to keep them in sync.
-fn entry_point_type(ctxt: &EntryContext<'_, '_>, item: &Item<'_>, at_root: bool) -> EntryPointType {
- let attrs = ctxt.map.attrs(item.hir_id());
- if ctxt.session.contains_name(attrs, sym::start) {
+fn entry_point_type(ctxt: &EntryContext<'_>, item: &Item<'_>, at_root: bool) -> EntryPointType {
+ let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+ if ctxt.tcx.sess.contains_name(attrs, sym::start) {
EntryPointType::Start
- } else if ctxt.session.contains_name(attrs, sym::rustc_main) {
+ } else if ctxt.tcx.sess.contains_name(attrs, sym::rustc_main) {
EntryPointType::MainAttr
} else if item.ident.name == sym::main {
if at_root {
@@ -98,16 +89,16 @@ fn throw_attr_err(sess: &Session, span: Span, attr: &str) {
.emit();
}
-fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
+fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_>, at_root: bool) {
match entry_point_type(ctxt, item, at_root) {
EntryPointType::None => (),
_ if !matches!(item.kind, ItemKind::Fn(..)) => {
- let attrs = ctxt.map.attrs(item.hir_id());
- if let Some(attr) = ctxt.session.find_by_name(attrs, sym::start) {
- throw_attr_err(&ctxt.session, attr.span, "start");
+ let attrs = ctxt.tcx.hir().attrs(item.hir_id());
+ if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::start) {
+ throw_attr_err(&ctxt.tcx.sess, attr.span, "start");
}
- if let Some(attr) = ctxt.session.find_by_name(attrs, sym::rustc_main) {
- throw_attr_err(&ctxt.session, attr.span, "rustc_main");
+ if let Some(attr) = ctxt.tcx.sess.find_by_name(attrs, sym::rustc_main) {
+ throw_attr_err(&ctxt.tcx.sess, attr.span, "rustc_main");
}
}
EntryPointType::MainNamed => (),
@@ -119,7 +110,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
ctxt.attr_main_fn = Some((item.def_id, item.span));
} else {
struct_span_err!(
- ctxt.session,
+ ctxt.tcx.sess,
item.span,
E0137,
"multiple functions with a `#[main]` attribute"
@@ -133,7 +124,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
if ctxt.start_fn.is_none() {
ctxt.start_fn = Some((item.def_id, item.span));
} else {
- struct_span_err!(ctxt.session, item.span, E0138, "multiple `start` functions")
+ struct_span_err!(ctxt.tcx.sess, item.span, E0138, "multiple `start` functions")
.span_label(ctxt.start_fn.unwrap().1, "previous `#[start]` function here")
.span_label(item.span, "multiple `start` functions")
.emit();
@@ -142,7 +133,7 @@ fn find_item(item: &Item<'_>, ctxt: &mut EntryContext<'_, '_>, at_root: bool) {
}
}
-fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(DefId, EntryFnType)> {
+fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) -> Option<(DefId, EntryFnType)> {
if let Some((def_id, _)) = visitor.start_fn {
Some((def_id.to_def_id(), EntryFnType::Start))
} else if let Some((def_id, _)) = visitor.attr_main_fn {
@@ -177,7 +168,7 @@ fn configure_main(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) -> Option<(De
}
}
-fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_, '_>) {
+fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) {
let sp = tcx.def_span(CRATE_DEF_ID);
if *tcx.sess.parse_sess.reached_eof.borrow() {
// There's an unclosed brace that made the parser reach `Eof`, we shouldn't complain about
diff --git a/compiler/rustc_passes/src/hir_id_validator.rs b/compiler/rustc_passes/src/hir_id_validator.rs
index 56755d6..379a682 100644
--- a/compiler/rustc_passes/src/hir_id_validator.rs
+++ b/compiler/rustc_passes/src/hir_id_validator.rs
@@ -1,7 +1,7 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lock;
use rustc_hir as hir;
-use rustc_hir::def_id::{LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_hir::intravisit;
use rustc_hir::itemlikevisit::ItemLikeVisitor;
use rustc_hir::{HirId, ItemLocalId};
@@ -89,7 +89,7 @@ fn check<F: FnOnce(&mut HirIdValidator<'a, 'hir>)>(&mut self, owner: LocalDefId,
self.owner = Some(owner);
walk(self);
- if owner.local_def_index == CRATE_DEF_INDEX {
+ if owner == CRATE_DEF_ID {
return;
}
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 01ba9e3..35a858c 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -6,7 +6,7 @@
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
use rustc_hir::hir_id::CRATE_HIR_ID;
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{FieldDef, Generics, HirId, Item, TraitRef, Ty, TyKind, Variant};
@@ -703,7 +703,7 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
let Some(cnum) = self.tcx.extern_mod_stmt_cnum(item.def_id) else {
return;
};
- let def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
+ let def_id = cnum.as_def_id();
self.tcx.check_stability(def_id, Some(item.hir_id()), item.span, None);
}
diff --git a/compiler/rustc_query_impl/src/profiling_support.rs b/compiler/rustc_query_impl/src/profiling_support.rs
index acccf43..b20aa7b 100644
--- a/compiler/rustc_query_impl/src/profiling_support.rs
+++ b/compiler/rustc_query_impl/src/profiling_support.rs
@@ -1,7 +1,7 @@
use measureme::{StringComponent, StringId};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::profiling::SelfProfiler;
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIndex, LocalDefId, LOCAL_CRATE};
use rustc_hir::definitions::DefPathData;
use rustc_middle::ty::{TyCtxt, WithOptConstParam};
use rustc_query_system::query::QueryCache;
@@ -143,7 +143,7 @@ fn spec_to_self_profile_string(
&self,
builder: &mut QueryKeyStringBuilder<'_, '_, '_>,
) -> StringId {
- builder.def_id_to_string_id(DefId { krate: *self, index: CRATE_DEF_INDEX })
+ builder.def_id_to_string_id(self.as_def_id())
}
}
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 063b15e..d97d919 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -23,7 +23,7 @@
use rustc_expand::base::SyntaxExtension;
use rustc_expand::expand::AstFragment;
use rustc_hir::def::{self, *};
-use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
use rustc_metadata::creader::LoadedMacro;
use rustc_middle::bug;
use rustc_middle::metadata::ModChild;
@@ -140,8 +140,8 @@ pub fn expect_module(&mut self, def_id: DefId) -> Module<'a> {
let parent = def_key.parent.map(|index| {
self.get_nearest_non_block_module(DefId { index, krate: def_id.krate })
});
- let name = if def_id.index == CRATE_DEF_INDEX {
- self.cstore().crate_name(def_id.krate)
+ let name = if let Some(cnum) = def_id.as_crate_root() {
+ self.cstore().crate_name(cnum)
} else {
def_key.disambiguated_data.data.get_opt_name().expect("module without name")
};
@@ -250,7 +250,7 @@ fn try_resolve_visibility<'ast>(
match vis.kind {
ast::VisibilityKind::Public => Ok(ty::Visibility::Public),
ast::VisibilityKind::Crate(..) => {
- Ok(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)))
+ Ok(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()))
}
ast::VisibilityKind::Inherited => {
Ok(match self.parent_scope.module.kind {
@@ -758,7 +758,7 @@ fn build_reduced_graph_for_item(&mut self, item: &'b Item) {
let mut ctor_vis = if vis == ty::Visibility::Public
&& self.r.session.contains_name(&item.attrs, sym::non_exhaustive)
{
- ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
+ ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
} else {
vis
};
@@ -1107,7 +1107,7 @@ fn process_macro_use_imports(&mut self, item: &Item, module: Module<'a>) -> bool
root_span: span,
span,
module_path: Vec::new(),
- vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))),
+ vis: Cell::new(ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())),
used: Cell::new(false),
})
};
@@ -1243,7 +1243,7 @@ fn define_macro(&mut self, item: &ast::Item) -> MacroRulesScopeRef<'a> {
let vis = if is_macro_export {
ty::Visibility::Public
} else {
- ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
+ ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
};
let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas);
self.r.set_binding_parent_module(binding, parent_scope.module);
@@ -1489,7 +1489,7 @@ fn visit_variant(&mut self, variant: &'b ast::Variant) {
let ctor_vis = if vis == ty::Visibility::Public
&& self.r.session.contains_name(&variant.attrs, sym::non_exhaustive)
{
- ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))
+ ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id())
} else {
vis
};
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index f3b8c1e..899980a 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -10,7 +10,7 @@
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS};
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::PrimTy;
use rustc_middle::bug;
use rustc_middle::ty::DefIdTree;
@@ -1167,7 +1167,7 @@ fn early_lookup_typo_candidate(
}
Scope::ExternPrelude => {
suggestions.extend(this.extern_prelude.iter().filter_map(|(ident, _)| {
- let res = Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX));
+ let res = Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id());
filter_fn(res).then_some(TypoSuggestion::typo_from_res(ident.name, res))
}));
}
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 9bc5d63..591bad7 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -19,7 +19,7 @@
use rustc_errors::DiagnosticId;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, DefKind, PartialRes, PerNS};
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::{PrimTy, TraitCandidate};
use rustc_middle::ty::DefIdTree;
use rustc_middle::{bug, span_bug};
@@ -2751,7 +2751,7 @@ fn resolve_qpath(
// trait to resolve. In that case, we leave the `B`
// segment to be resolved by type-check.
return Ok(Some(PartialRes::with_unresolved_segments(
- Res::Def(DefKind::Mod, DefId::local(CRATE_DEF_INDEX)),
+ Res::Def(DefKind::Mod, CRATE_DEF_ID.to_def_id()),
path.len(),
)));
}
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 0bae141..d77cc91 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -20,7 +20,7 @@
use rustc_hir as hir;
use rustc_hir::def::Namespace::{self, *};
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::PrimTy;
use rustc_session::parse::feature_err;
use rustc_span::edition::Edition;
@@ -352,7 +352,7 @@ pub(crate) fn smart_resolve_report_errors(
}
})
.collect::<Vec<_>>();
- let crate_def_id = DefId::local(CRATE_DEF_INDEX);
+ let crate_def_id = CRATE_DEF_ID.to_def_id();
if candidates.is_empty() && is_expected(Res::Def(DefKind::Enum, crate_def_id)) {
let mut enum_candidates: Vec<_> = self
.r
@@ -1332,10 +1332,8 @@ fn lookup_typo_candidate(
names.extend(extern_prelude.iter().flat_map(|(ident, _)| {
self.r.crate_loader.maybe_process_path_extern(ident.name).and_then(
|crate_id| {
- let crate_mod = Res::Def(
- DefKind::Mod,
- DefId { krate: crate_id, index: CRATE_DEF_INDEX },
- );
+ let crate_mod =
+ Res::Def(DefKind::Mod, crate_id.as_def_id());
if filter_fn(crate_mod) {
Some(TypoSuggestion::typo_from_res(
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index eed5437..4dfb7ae 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -38,7 +38,7 @@
use rustc_hir::def::Namespace::*;
use rustc_hir::def::{self, CtorOf, DefKind, PartialRes};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefPathHash, LocalDefId};
-use rustc_hir::def_id::{CRATE_DEF_ID, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPathData, Definitions};
use rustc_hir::TraitCandidate;
use rustc_index::vec::IndexVec;
@@ -796,7 +796,7 @@ fn is_extern_crate(&self) -> bool {
NameBindingKind::Module(&ModuleData {
kind: ModuleKind::Def(DefKind::Mod, def_id, _),
..
- }) => def_id.index == CRATE_DEF_INDEX,
+ }) => def_id.is_crate_root(),
_ => false,
}
}
@@ -1248,18 +1248,17 @@ pub fn new(
);
let definitions = Definitions::new(session.local_stable_crate_id(), krate.spans.inner_span);
- let root = definitions.get_root_def();
let mut visibilities = FxHashMap::default();
visibilities.insert(CRATE_DEF_ID, ty::Visibility::Public);
let mut def_id_to_node_id = IndexVec::default();
- assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), root);
+ assert_eq!(def_id_to_node_id.push(CRATE_NODE_ID), CRATE_DEF_ID);
let mut node_id_to_def_id = FxHashMap::default();
- node_id_to_def_id.insert(CRATE_NODE_ID, root);
+ node_id_to_def_id.insert(CRATE_NODE_ID, CRATE_DEF_ID);
let mut invocation_parents = FxHashMap::default();
- invocation_parents.insert(LocalExpnId::ROOT, (root, ImplTraitContext::Existential));
+ invocation_parents.insert(LocalExpnId::ROOT, (CRATE_DEF_ID, ImplTraitContext::Existential));
let mut extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'_>> = session
.opts
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 5a447aa..12c5c44 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3,20 +3,18 @@
pub use crate::options::*;
-use crate::lint;
use crate::search_paths::SearchPath;
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{early_error, early_warn, Session};
+use crate::{lint, HashStableContext};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_data_structures::impl_stable_hash_via_hash;
+use rustc_data_structures::stable_hasher::ToStableHashKey;
use rustc_target::abi::{Align, TargetDataLayout};
use rustc_target::spec::{LinkerFlavor, SplitDebuginfo, Target, TargetTriple, TargetWarnings};
use rustc_target::spec::{PanicStrategy, SanitizerSet, TARGETS};
-use rustc_serialize::json;
-
use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
@@ -80,7 +78,7 @@ pub enum CFProtection {
Full,
}
-#[derive(Clone, Copy, Debug, PartialEq, Hash)]
+#[derive(Clone, Copy, Debug, PartialEq, Hash, HashStable_Generic)]
pub enum OptLevel {
No, // -O0
Less, // -O1
@@ -90,8 +88,6 @@ pub enum OptLevel {
SizeMin, // -Oz
}
-impl_stable_hash_via_hash!(OptLevel);
-
/// This is what the `LtoCli` values get mapped to after resolving defaults and
/// and taking other command line options into account.
///
@@ -232,15 +228,13 @@ pub fn enabled(&self) -> bool {
}
}
-#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic)]
#[derive(Encodable, Decodable)]
pub enum SymbolManglingVersion {
Legacy,
V0,
}
-impl_stable_hash_via_hash!(SymbolManglingVersion);
-
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum DebugInfo {
None,
@@ -279,7 +273,7 @@ fn from_str(s: &str) -> Result<Self, ()> {
}
}
-#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord)]
+#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
#[derive(Encodable, Decodable)]
pub enum OutputType {
Bitcode,
@@ -292,7 +286,13 @@ pub enum OutputType {
DepInfo,
}
-impl_stable_hash_via_hash!(OutputType);
+impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
+ type KeyType = Self;
+
+ fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
+ *self
+ }
+}
impl OutputType {
fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
@@ -398,7 +398,7 @@ pub enum TrimmedDefPaths {
/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
/// dependency tracking for command-line arguments. Also only hash keys, since tracking
/// should only depend on the output types, not the paths they're written to.
-#[derive(Clone, Debug, Hash)]
+#[derive(Clone, Debug, Hash, HashStable_Generic)]
pub struct OutputTypes(BTreeMap<OutputType, Option<PathBuf>>);
impl OutputTypes {
@@ -460,9 +460,6 @@ pub fn should_link(&self) -> bool {
#[derive(Clone)]
pub struct Externs(BTreeMap<String, ExternEntry>);
-#[derive(Clone)]
-pub struct ExternDepSpecs(BTreeMap<String, ExternDepSpec>);
-
#[derive(Clone, Debug)]
pub struct ExternEntry {
pub location: ExternLocation,
@@ -494,27 +491,6 @@ pub enum ExternLocation {
ExactPaths(BTreeSet<CanonicalizedPath>),
}
-/// Supplied source location of a dependency - for example in a build specification
-/// file like Cargo.toml. We support several syntaxes: if it makes sense to reference
-/// a file and line, then the build system can specify that. On the other hand, it may
-/// make more sense to have an arbitrary raw string.
-#[derive(Clone, PartialEq)]
-pub enum ExternDepSpec {
- /// Raw string
- Raw(String),
- /// Raw data in json format
- Json(json::Json),
-}
-
-impl<'a> From<&'a ExternDepSpec> for rustc_lint_defs::ExternDepSpec {
- fn from(from: &'a ExternDepSpec) -> Self {
- match from {
- ExternDepSpec::Raw(s) => rustc_lint_defs::ExternDepSpec::Raw(s.clone()),
- ExternDepSpec::Json(json) => rustc_lint_defs::ExternDepSpec::Json(json.clone()),
- }
- }
-}
-
impl Externs {
/// Used for testing.
pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
@@ -547,25 +523,6 @@ pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
}
}
-impl ExternDepSpecs {
- pub fn new(data: BTreeMap<String, ExternDepSpec>) -> ExternDepSpecs {
- ExternDepSpecs(data)
- }
-
- pub fn get(&self, key: &str) -> Option<&ExternDepSpec> {
- self.0.get(key)
- }
-}
-
-impl fmt::Display for ExternDepSpec {
- fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
- match self {
- ExternDepSpec::Raw(raw) => fmt.write_str(raw),
- ExternDepSpec::Json(json) => json::as_json(json).fmt(fmt),
- }
- }
-}
-
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PrintRequest {
FileNames,
@@ -630,7 +587,7 @@ pub fn source_name(&self) -> FileName {
}
}
-#[derive(Clone, Hash, Debug)]
+#[derive(Clone, Hash, Debug, HashStable_Generic)]
pub struct OutputFilenames {
pub out_directory: PathBuf,
filestem: String,
@@ -639,8 +596,6 @@ pub struct OutputFilenames {
pub outputs: OutputTypes,
}
-impl_stable_hash_via_hash!(OutputFilenames);
-
pub const RLINK_EXT: &str = "rlink";
pub const RUST_CGU_EXT: &str = "rcgu";
pub const DWARF_OBJECT_EXT: &str = "dwo";
@@ -785,7 +740,6 @@ fn default() -> Options {
cg: Default::default(),
error_format: ErrorOutputType::default(),
externs: Externs(BTreeMap::new()),
- extern_dep_specs: ExternDepSpecs(BTreeMap::new()),
crate_name: None,
libs: Vec::new(),
unstable_features: UnstableFeatures::Disallow,
@@ -854,15 +808,14 @@ pub fn diagnostic_handler_flags(&self, can_emit_warnings: bool) -> HandlerFlags
}
// The type of entry function, so users can have their own entry functions
-#[derive(Copy, Clone, PartialEq, Hash, Debug)]
+#[derive(Copy, Clone, PartialEq, Hash, Debug, HashStable_Generic)]
pub enum EntryFnType {
Main,
Start,
}
-impl_stable_hash_via_hash!(EntryFnType);
-
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
+#[derive(HashStable_Generic)]
pub enum CrateType {
Executable,
Dylib,
@@ -872,8 +825,6 @@ pub enum CrateType {
ProcMacro,
}
-impl_stable_hash_via_hash!(CrateType);
-
impl CrateType {
/// When generated, is this crate type an archive?
pub fn is_archive(&self) -> bool {
@@ -1454,12 +1405,6 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
"Specify where an external rust library is located",
"NAME[=PATH]",
),
- opt::multi_s(
- "",
- "extern-location",
- "Location where an external crate dependency is specified",
- "NAME=LOCATION",
- ),
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
opt::multi("Z", "", "Set internal debugging options", "FLAG"),
opt::opt_s(
@@ -2221,68 +2166,6 @@ pub fn parse_externs(
Externs(externs)
}
-fn parse_extern_dep_specs(
- matches: &getopts::Matches,
- debugging_opts: &DebuggingOptions,
- error_format: ErrorOutputType,
-) -> ExternDepSpecs {
- let is_unstable_enabled = debugging_opts.unstable_options;
- let mut map = BTreeMap::new();
-
- for arg in matches.opt_strs("extern-location") {
- if !is_unstable_enabled {
- early_error(
- error_format,
- "`--extern-location` option is unstable: set `-Z unstable-options`",
- );
- }
-
- let mut parts = arg.splitn(2, '=');
- let name = parts.next().unwrap_or_else(|| {
- early_error(error_format, "`--extern-location` value must not be empty")
- });
- let loc = parts.next().unwrap_or_else(|| {
- early_error(
- error_format,
- &format!("`--extern-location`: specify location for extern crate `{name}`"),
- )
- });
-
- let locparts: Vec<_> = loc.split(':').collect();
- let spec = match &locparts[..] {
- ["raw", ..] => {
- // Don't want `:` split string
- let raw = loc.splitn(2, ':').nth(1).unwrap_or_else(|| {
- early_error(error_format, "`--extern-location`: missing `raw` location")
- });
- ExternDepSpec::Raw(raw.to_string())
- }
- ["json", ..] => {
- // Don't want `:` split string
- let raw = loc.splitn(2, ':').nth(1).unwrap_or_else(|| {
- early_error(error_format, "`--extern-location`: missing `json` location")
- });
- let json = json::from_str(raw).unwrap_or_else(|_| {
- early_error(
- error_format,
- &format!("`--extern-location`: malformed json location `{raw}`"),
- )
- });
- ExternDepSpec::Json(json)
- }
- [bad, ..] => early_error(
- error_format,
- &format!("unknown location type `{bad}`: use `raw` or `json`"),
- ),
- [] => early_error(error_format, "missing location specification"),
- };
-
- map.insert(name.to_string(), spec);
- }
-
- ExternDepSpecs::new(map)
-}
-
fn parse_remap_path_prefix(
matches: &getopts::Matches,
debugging_opts: &DebuggingOptions,
@@ -2525,7 +2408,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
}
let externs = parse_externs(matches, &debugging_opts, error_format);
- let extern_dep_specs = parse_extern_dep_specs(matches, &debugging_opts, error_format);
let crate_name = matches.opt_str("crate-name");
@@ -2601,7 +2483,6 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
error_format,
externs,
unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
- extern_dep_specs,
crate_name,
libs,
debug_assertions,
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 4994f8e..df65409 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -183,7 +183,6 @@ pub struct Options {
borrowck_mode: BorrowckMode [UNTRACKED],
cg: CodegenOptions [SUBSTRUCT],
externs: Externs [UNTRACKED],
- extern_dep_specs: ExternDepSpecs [UNTRACKED],
crate_name: Option<String> [TRACKED],
/// Indicates how the compiler should treat unstable features.
unstable_features: UnstableFeatures [TRACKED],
diff --git a/compiler/rustc_session/src/search_paths.rs b/compiler/rustc_session/src/search_paths.rs
index b6bde28..56a6b6f 100644
--- a/compiler/rustc_session/src/search_paths.rs
+++ b/compiler/rustc_session/src/search_paths.rs
@@ -26,7 +26,7 @@ pub struct SearchPathFile {
pub file_name_str: String,
}
-#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable)]
+#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, Encodable, Decodable, HashStable_Generic)]
pub enum PathKind {
Native,
Crate,
@@ -36,8 +36,6 @@ pub enum PathKind {
All,
}
-rustc_data_structures::impl_stable_hash_via_hash!(PathKind);
-
impl PathKind {
pub fn matches(&self, kind: PathKind) -> bool {
match (self, kind) {
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 9a286d9..8064c21 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -18,6 +18,7 @@ pub fn time<R>(&self, what: &'static str, f: impl FnOnce() -> R) -> R {
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
+#[derive(HashStable_Generic)]
pub enum NativeLibKind {
/// Static library (e.g. `libfoo.a` on Linux or `foo.lib` on Windows/MSVC)
Static {
@@ -57,9 +58,8 @@ pub fn has_modifiers(&self) -> bool {
}
}
-rustc_data_structures::impl_stable_hash_via_hash!(NativeLibKind);
-
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
+#[derive(HashStable_Generic)]
pub struct NativeLib {
pub name: String,
pub new_name: Option<String>,
@@ -73,8 +73,6 @@ pub fn has_modifiers(&self) -> bool {
}
}
-rustc_data_structures::impl_stable_hash_via_hash!(NativeLib);
-
/// A path that has been canonicalized along with its original, non-canonicalized form
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct CanonicalizedPath {
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 6d1b367..d5f8063 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -283,8 +283,19 @@ pub fn expect_local(self) -> LocalDefId {
self.as_local().unwrap_or_else(|| panic!("DefId::expect_local: `{:?}` isn't local", self))
}
+ #[inline]
+ pub fn is_crate_root(self) -> bool {
+ self.index == CRATE_DEF_INDEX
+ }
+
+ #[inline]
+ pub fn as_crate_root(self) -> Option<CrateNum> {
+ if self.is_crate_root() { Some(self.krate) } else { None }
+ }
+
+ #[inline]
pub fn is_top_level_module(self) -> bool {
- self.is_local() && self.index == CRATE_DEF_INDEX
+ self.is_local() && self.is_crate_root()
}
}
@@ -357,7 +368,7 @@ pub fn to_def_id(self) -> DefId {
#[inline]
pub fn is_top_level_module(self) -> bool {
- self.local_def_index == CRATE_DEF_INDEX
+ self == CRATE_DEF_ID
}
}
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index b132c0a..b0307cc 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1130,6 +1130,7 @@ pub fn get_source(&self) -> Option<&Lrc<String>> {
pub struct OffsetOverflowError;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Encodable, Decodable)]
+#[derive(HashStable_Generic)]
pub enum SourceFileHashAlgorithm {
Md5,
Sha1,
@@ -1149,8 +1150,6 @@ fn from_str(s: &str) -> Result<SourceFileHashAlgorithm, ()> {
}
}
-rustc_data_structures::impl_stable_hash_via_hash!(SourceFileHashAlgorithm);
-
/// The hash of the on-disk source file used for debug info.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[derive(HashStable_Generic, Encodable, Decodable)]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index d9bada2..e3ce810 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -803,6 +803,7 @@
keyword,
kind,
kreg,
+ kreg0,
label,
label_break_value,
lang,
diff --git a/compiler/rustc_target/src/asm/mod.rs b/compiler/rustc_target/src/asm/mod.rs
index 5bc4b56..6bc807c 100644
--- a/compiler/rustc_target/src/asm/mod.rs
+++ b/compiler/rustc_target/src/asm/mod.rs
@@ -893,7 +893,7 @@ macro_rules! clobbered_regs {
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
- k1, k2, k3, k4, k5, k6, k7,
+ k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7,
@@ -908,7 +908,7 @@ macro_rules! clobbered_regs {
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
- k1, k2, k3, k4, k5, k6, k7,
+ k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7,
@@ -927,7 +927,7 @@ macro_rules! clobbered_regs {
zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23,
zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31,
- k1, k2, k3, k4, k5, k6, k7,
+ k0, k1, k2, k3, k4, k5, k6, k7,
mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7,
st0, st1, st2, st3, st4, st5, st6, st7,
diff --git a/compiler/rustc_target/src/asm/x86.rs b/compiler/rustc_target/src/asm/x86.rs
index 7c136a4..854674c 100644
--- a/compiler/rustc_target/src/asm/x86.rs
+++ b/compiler/rustc_target/src/asm/x86.rs
@@ -14,6 +14,7 @@
ymm_reg,
zmm_reg,
kreg,
+ kreg0,
mmx_reg,
x87_reg,
}
@@ -38,7 +39,7 @@ pub fn valid_modifiers(self, arch: super::InlineAsmArch) -> &'static [char] {
}
Self::reg_byte => &[],
Self::xmm_reg | Self::ymm_reg | Self::zmm_reg => &['x', 'y', 'z'],
- Self::kreg => &[],
+ Self::kreg | Self::kreg0 => &[],
Self::mmx_reg | Self::x87_reg => &[],
}
}
@@ -77,7 +78,7 @@ pub fn suggest_modifier(
256 => Some(('y', "ymm0")),
_ => Some(('x', "xmm0")),
},
- Self::kreg => None,
+ Self::kreg | Self::kreg0 => None,
Self::mmx_reg | Self::x87_reg => None,
}
}
@@ -95,7 +96,7 @@ pub fn default_modifier(self, arch: InlineAsmArch) -> Option<(char, &'static str
Self::xmm_reg => Some(('x', "xmm0")),
Self::ymm_reg => Some(('y', "ymm0")),
Self::zmm_reg => Some(('z', "zmm0")),
- Self::kreg => None,
+ Self::kreg | Self::kreg0 => None,
Self::mmx_reg | Self::x87_reg => None,
}
}
@@ -132,6 +133,7 @@ pub fn supported_types(
avx512f: I8, I16;
avx512bw: I32, I64;
},
+ Self::kreg0 => &[],
Self::mmx_reg | Self::x87_reg => &[],
}
}
@@ -294,6 +296,7 @@ fn esi_reserved(
zmm29: zmm_reg = ["zmm29", "xmm29", "ymm29"] % x86_64_only,
zmm30: zmm_reg = ["zmm30", "xmm30", "ymm30"] % x86_64_only,
zmm31: zmm_reg = ["zmm31", "xmm31", "ymm31"] % x86_64_only,
+ k0: kreg0 = ["k0"],
k1: kreg = ["k1"],
k2: kreg = ["k2"],
k3: kreg = ["k3"],
@@ -323,8 +326,6 @@ fn esi_reserved(
"the stack pointer cannot be used as an operand for inline asm",
#error = ["ip", "eip", "rip"] =>
"the instruction pointer cannot be used as an operand for inline asm",
- #error = ["k0"] =>
- "the k0 AVX mask register cannot be used as an operand for inline asm",
}
}
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 7485c08..0c1ca65 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -19,9 +19,11 @@
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
+use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
- Infer, InferTy, ToPredicate, Ty, TyCtxt, TypeFoldable,
+ GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, ToPredicate, Ty, TyCtxt,
+ TypeFoldable,
};
use rustc_middle::ty::{TypeAndMut, TypeckResults};
use rustc_session::Limit;
@@ -44,6 +46,123 @@ pub enum GeneratorInteriorOrUpvar {
Upvar(Span),
}
+// This type provides a uniform interface to retrieve data on generators, whether it originated from
+// the local crate being compiled or from a foreign crate.
+#[derive(Debug)]
+pub enum GeneratorData<'tcx, 'a> {
+ Local(&'a TypeckResults<'tcx>),
+ Foreign(&'tcx GeneratorDiagnosticData<'tcx>),
+}
+
+impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
+ // Try to get information about variables captured by the generator that matches a type we are
+ // looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
+ // meet an obligation
+ fn try_get_upvar_span<F>(
+ &self,
+ infer_context: &InferCtxt<'a, 'tcx>,
+ generator_did: DefId,
+ ty_matches: F,
+ ) -> Option<GeneratorInteriorOrUpvar>
+ where
+ F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
+ {
+ match self {
+ GeneratorData::Local(typeck_results) => {
+ infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| {
+ upvars.iter().find_map(|(upvar_id, upvar)| {
+ let upvar_ty = typeck_results.node_type(*upvar_id);
+ let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
+ if ty_matches(ty::Binder::dummy(upvar_ty)) {
+ Some(GeneratorInteriorOrUpvar::Upvar(upvar.span))
+ } else {
+ None
+ }
+ })
+ })
+ }
+ GeneratorData::Foreign(_) => None,
+ }
+ }
+
+ // Try to get the span of a type being awaited on that matches the type we are looking with the
+ // `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
+ // obligation
+ fn get_from_await_ty<F>(
+ &self,
+ visitor: AwaitsVisitor,
+ hir: map::Map<'tcx>,
+ ty_matches: F,
+ ) -> Option<Span>
+ where
+ F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
+ {
+ match self {
+ GeneratorData::Local(typeck_results) => visitor
+ .awaits
+ .into_iter()
+ .map(|id| hir.expect_expr(id))
+ .find(|await_expr| {
+ ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr)))
+ })
+ .map(|expr| expr.span),
+ GeneratorData::Foreign(generator_diagnostic_data) => visitor
+ .awaits
+ .into_iter()
+ .map(|id| hir.expect_expr(id))
+ .find(|await_expr| {
+ ty_matches(ty::Binder::dummy(
+ generator_diagnostic_data
+ .adjustments
+ .get(&await_expr.hir_id.local_id)
+ .map_or::<&[ty::adjustment::Adjustment<'tcx>], _>(&[], |a| &a[..])
+ .last()
+ .map_or_else::<Ty<'tcx>, _, _>(
+ || {
+ generator_diagnostic_data
+ .nodes_types
+ .get(&await_expr.hir_id.local_id)
+ .cloned()
+ .unwrap_or_else(|| {
+ bug!(
+ "node_type: no type for node `{}`",
+ ty::tls::with(|tcx| tcx
+ .hir()
+ .node_to_string(await_expr.hir_id))
+ )
+ })
+ },
+ |adj| adj.target,
+ ),
+ ))
+ })
+ .map(|expr| expr.span),
+ }
+ }
+
+ /// Get the type, expression, span and optional scope span of all types
+ /// that are live across the yield of this generator
+ fn get_generator_interior_types(
+ &self,
+ ) -> ty::Binder<'tcx, &Vec<GeneratorInteriorTypeCause<'tcx>>> {
+ match self {
+ GeneratorData::Local(typeck_result) => typeck_result.generator_interior_types.as_ref(),
+ GeneratorData::Foreign(generator_diagnostic_data) => {
+ generator_diagnostic_data.generator_interior_types.as_ref()
+ }
+ }
+ }
+
+ // Used to get the source of the data, note we don't have as much information for generators
+ // originated from foreign crates
+ fn is_foreign(&self) -> bool {
+ match self {
+ GeneratorData::Local(_) => false,
+ GeneratorData::Foreign(_) => true,
+ }
+ }
+}
+
// This trait is public to expose the diagnostics methods to clippy.
pub trait InferCtxtExt<'tcx> {
fn suggest_restricting_param_bound(
@@ -152,7 +271,7 @@ fn note_obligation_cause_for_async_await(
err: &mut Diagnostic,
interior_or_upvar_span: GeneratorInteriorOrUpvar,
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
- inner_generator_body: Option<&hir::Body<'tcx>>,
+ is_async: bool,
outer_generator: Option<DefId>,
trait_pred: ty::TraitPredicate<'tcx>,
target_ty: Ty<'tcx>,
@@ -1642,6 +1761,17 @@ fn maybe_note_obligation_cause_for_async_await(
.map(|def_id| hir.local_def_id_to_hir_id(def_id))
.and_then(|hir_id| hir.maybe_body_owned_by(hir_id))
.map(|body_id| hir.body(body_id));
+ let is_async = match generator_did.as_local() {
+ Some(_) => generator_body
+ .and_then(|body| body.generator_kind())
+ .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
+ .unwrap_or(false),
+ None => self
+ .tcx
+ .generator_kind(generator_did)
+ .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
+ .unwrap_or(false),
+ };
let mut visitor = AwaitsVisitor::default();
if let Some(body) = generator_body {
visitor.visit_body(body);
@@ -1682,61 +1812,55 @@ fn maybe_note_obligation_cause_for_async_await(
// type-checking; otherwise, get them by performing a query. This is needed to avoid
// cycles. If we can't use resolved types because the generator comes from another crate,
// we still provide a targeted error but without all the relevant spans.
- let query_typeck_results;
- let typeck_results: Option<&TypeckResults<'tcx>> = match &in_progress_typeck_results {
- Some(t) if t.hir_owner.to_def_id() == generator_did_root => Some(&t),
- _ if generator_did.is_local() => {
- query_typeck_results = self.tcx.typeck(generator_did.expect_local());
- Some(&query_typeck_results)
+ let generator_data: Option<GeneratorData<'tcx, '_>> = match &in_progress_typeck_results {
+ Some(t) if t.hir_owner.to_def_id() == generator_did_root => {
+ Some(GeneratorData::Local(&t))
}
- _ => None, // Do not ICE on closure typeck (#66868).
+ _ if generator_did.is_local() => {
+ Some(GeneratorData::Local(self.tcx.typeck(generator_did.expect_local())))
+ }
+ _ => self
+ .tcx
+ .generator_diagnostic_data(generator_did)
+ .as_ref()
+ .map(|generator_diag_data| GeneratorData::Foreign(generator_diag_data)),
};
- if let Some(typeck_results) = typeck_results {
- if let Some(upvars) = self.tcx.upvars_mentioned(generator_did) {
- interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| {
- let upvar_ty = typeck_results.node_type(*upvar_id);
- let upvar_ty = self.resolve_vars_if_possible(upvar_ty);
- if ty_matches(ty::Binder::dummy(upvar_ty)) {
- Some(GeneratorInteriorOrUpvar::Upvar(upvar.span))
- } else {
- None
- }
- });
- };
+
+ if let Some(generator_data) = generator_data.as_ref() {
+ interior_or_upvar_span =
+ generator_data.try_get_upvar_span(&self, generator_did, ty_matches);
// The generator interior types share the same binders
if let Some(cause) =
- typeck_results.generator_interior_types.as_ref().skip_binder().iter().find(
+ generator_data.get_generator_interior_types().skip_binder().iter().find(
|ty::GeneratorInteriorTypeCause { ty, .. }| {
- ty_matches(typeck_results.generator_interior_types.rebind(*ty))
+ ty_matches(generator_data.get_generator_interior_types().rebind(*ty))
},
)
{
- // Check to see if any awaited expressions have the target type.
- let from_awaited_ty = visitor
- .awaits
- .into_iter()
- .map(|id| hir.expect_expr(id))
- .find(|await_expr| {
- ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr)))
- })
- .map(|expr| expr.span);
+ let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches);
let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } =
cause;
interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span));
interior_extra_info = Some((*scope_span, *yield_span, *expr, from_awaited_ty));
- };
- } else {
- interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span));
+ }
+
+ if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
+ interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span));
+ }
}
if let Some(interior_or_upvar_span) = interior_or_upvar_span {
+ let typeck_results = generator_data.and_then(|generator_data| match generator_data {
+ GeneratorData::Local(typeck_results) => Some(typeck_results),
+ GeneratorData::Foreign(_) => None,
+ });
self.note_obligation_cause_for_async_await(
err,
interior_or_upvar_span,
interior_extra_info,
- generator_body,
+ is_async,
outer_generator,
trait_ref,
target_ty,
@@ -1757,7 +1881,7 @@ fn note_obligation_cause_for_async_await(
err: &mut Diagnostic,
interior_or_upvar_span: GeneratorInteriorOrUpvar,
interior_extra_info: Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>,
- inner_generator_body: Option<&hir::Body<'tcx>>,
+ is_async: bool,
outer_generator: Option<DefId>,
trait_pred: ty::TraitPredicate<'tcx>,
target_ty: Ty<'tcx>,
@@ -1767,10 +1891,6 @@ fn note_obligation_cause_for_async_await(
) {
let source_map = self.tcx.sess.source_map();
- let is_async = inner_generator_body
- .and_then(|body| body.generator_kind())
- .map(|generator_kind| matches!(generator_kind, hir::GeneratorKind::Async(..)))
- .unwrap_or(false);
let (await_or_yield, an_await_or_yield) =
if is_async { ("await", "an await") } else { ("yield", "a yield") };
let future_or_generator = if is_async { "future" } else { "generator" };
diff --git a/compiler/rustc_typeck/src/astconv/errors.rs b/compiler/rustc_typeck/src/astconv/errors.rs
index 1a10b07..38cc74a 100644
--- a/compiler/rustc_typeck/src/astconv/errors.rs
+++ b/compiler/rustc_typeck/src/astconv/errors.rs
@@ -10,7 +10,6 @@
use rustc_span::{Span, DUMMY_SP};
use std::collections::BTreeSet;
-use std::iter;
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// On missing type parameters, emit an E0393 error and provide a structured suggestion using
@@ -323,6 +322,7 @@ pub(crate) fn complain_about_missing_associated_types(
let mut suggestions = vec![];
let mut types_count = 0;
let mut where_constraints = vec![];
+ let mut already_has_generics_args_suggestion = false;
for (span, assoc_items) in &associated_types {
let mut names: FxHashMap<_, usize> = FxHashMap::default();
for item in assoc_items {
@@ -343,16 +343,10 @@ pub(crate) fn complain_about_missing_associated_types(
}
}
if potential_assoc_types.len() == assoc_items.len() {
- // Only suggest when the amount of missing associated types equals the number of
- // extra type arguments present, as that gives us a relatively high confidence
- // that the user forgot to give the associated type's name. The canonical
- // example would be trying to use `Iterator<isize>` instead of
- // `Iterator<Item = isize>`.
- for (potential, item) in iter::zip(&potential_assoc_types, assoc_items) {
- if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(*potential) {
- suggestions.push((*potential, format!("{} = {}", item.name, snippet)));
- }
- }
+ // When the amount of missing associated types equals the number of
+ // extra type arguments present. A suggesting to replace the generic args with
+ // associated types is already emitted.
+ already_has_generics_args_suggestion = true;
} else if let (Ok(snippet), false) =
(tcx.sess.source_map().span_to_snippet(*span), dupes)
{
@@ -382,7 +376,7 @@ pub(crate) fn complain_about_missing_associated_types(
// the same associated type name.
err.help(where_msg);
}
- if suggestions.len() != 1 {
+ if suggestions.len() != 1 || already_has_generics_args_suggestion {
// We don't need this label if there's an inline suggestion, show otherwise.
for (span, assoc_items) in &associated_types {
let mut names: FxHashMap<_, usize> = FxHashMap::default();
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index f3dcf5f..cf0c570 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -2042,63 +2042,60 @@ fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: T
self.tcx.sess,
span,
E0529,
- "expected an array or slice, found `{}`",
- expected_ty
+ "expected an array or slice, found `{expected_ty}`"
);
- if let ty::Ref(_, ty, _) = expected_ty.kind() {
- if let ty::Array(..) | ty::Slice(..) = ty.kind() {
- err.help("the semantics of slice patterns changed recently; see issue #62254");
- }
+ if let ty::Ref(_, ty, _) = expected_ty.kind()
+ && let ty::Array(..) | ty::Slice(..) = ty.kind()
+ {
+ err.help("the semantics of slice patterns changed recently; see issue #62254");
} else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
+ && let (Some(span), true) = (ti.span, ti.origin_expr)
+ && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
{
- if let (Some(span), true) = (ti.span, ti.origin_expr) {
- if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
- let applicability = Autoderef::new(
- &self.infcx,
- self.param_env,
- self.body_id,
+ let ty = self.resolve_vars_if_possible(ti.expected);
+ let is_slice_or_array_or_vector = self.is_slice_or_array_or_vector(&mut err, snippet.clone(), ty);
+ match is_slice_or_array_or_vector.1.kind() {
+ ty::Adt(adt_def, _)
+ if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
+ || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
+ {
+ // Slicing won't work here, but `.as_deref()` might (issue #91328).
+ err.span_suggestion(
span,
- self.resolve_vars_if_possible(ti.expected),
- span,
- )
- .find_map(|(ty, _)| {
- match ty.kind() {
- ty::Adt(adt_def, _)
- if self.tcx.is_diagnostic_item(sym::Option, adt_def.did())
- || self.tcx.is_diagnostic_item(sym::Result, adt_def.did()) =>
- {
- // Slicing won't work here, but `.as_deref()` might (issue #91328).
- err.span_suggestion(
- span,
- "consider using `as_deref` here",
- format!("{}.as_deref()", snippet),
- Applicability::MaybeIncorrect,
- );
- Some(None)
- }
-
- ty::Slice(..) | ty::Array(..) => {
- Some(Some(Applicability::MachineApplicable))
- }
-
- _ => None,
- }
- })
- .unwrap_or(Some(Applicability::MaybeIncorrect));
-
- if let Some(applicability) = applicability {
- err.span_suggestion(
- span,
- "consider slicing here",
- format!("{}[..]", snippet),
- applicability,
- );
- }
+ "consider using `as_deref` here",
+ format!("{snippet}.as_deref()"),
+ Applicability::MaybeIncorrect,
+ );
}
+ _ => ()
+ }
+ if is_slice_or_array_or_vector.0 {
+ err.span_suggestion(
+ span,
+ "consider slicing here",
+ format!("{snippet}[..]"),
+ Applicability::MachineApplicable,
+ );
}
}
- err.span_label(span, format!("pattern cannot match with input type `{}`", expected_ty));
+ err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`"));
err.emit();
}
+
+ fn is_slice_or_array_or_vector(
+ &self,
+ err: &mut Diagnostic,
+ snippet: String,
+ ty: Ty<'tcx>,
+ ) -> (bool, Ty<'tcx>) {
+ match ty.kind() {
+ ty::Adt(adt_def, _) if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did()) => {
+ (true, ty)
+ }
+ ty::Ref(_, ty, _) => self.is_slice_or_array_or_vector(err, snippet, *ty),
+ ty::Slice(..) | ty::Array(..) => (true, ty),
+ _ => (false, ty),
+ }
+ }
}
diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
index 1b1a203..5cd7a7d 100644
--- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs
@@ -6,9 +6,10 @@
use rustc_hir as hir;
use rustc_middle::hir::map::fn_sig;
use rustc_middle::middle::resolve_lifetime::LifetimeScopeForPath;
-use rustc_middle::ty::{self as ty, TyCtxt};
+use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
use rustc_session::Session;
use rustc_span::def_id::DefId;
+use std::iter;
use GenericArgsInfo::*;
@@ -334,6 +335,22 @@ fn get_type_or_const_args_suggestions_from_param_names(
.join(", ")
}
+ fn get_unbound_associated_types(&self) -> Vec<String> {
+ if self.tcx.is_trait(self.def_id) {
+ let items: &AssocItems<'_> = self.tcx.associated_items(self.def_id);
+ items
+ .in_definition_order()
+ .filter(|item| item.kind == AssocKind::Type)
+ .filter(|item| {
+ !self.gen_args.bindings.iter().any(|binding| binding.ident.name == item.name)
+ })
+ .map(|item| item.name.to_ident_string())
+ .collect()
+ } else {
+ Vec::default()
+ }
+ }
+
fn create_error_message(&self) -> String {
let def_path = self.tcx.def_path_str(self.def_id);
let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id);
@@ -618,6 +635,7 @@ fn suggest_adding_type_and_const_args(&self, err: &mut Diagnostic) {
fn suggest_removing_args_or_generics(&self, err: &mut Diagnostic) {
let num_provided_lt_args = self.num_provided_lifetime_args();
let num_provided_type_const_args = self.num_provided_type_or_const_args();
+ let unbound_types = self.get_unbound_associated_types();
let num_provided_args = num_provided_lt_args + num_provided_type_const_args;
assert!(num_provided_args > 0);
@@ -629,6 +647,8 @@ fn suggest_removing_args_or_generics(&self, err: &mut Diagnostic) {
let redundant_type_or_const_args = num_redundant_type_or_const_args > 0;
let remove_entire_generics = num_redundant_args >= self.gen_args.args.len();
+ let provided_args_matches_unbound_traits =
+ unbound_types.len() == num_redundant_type_or_const_args;
let remove_lifetime_args = |err: &mut Diagnostic| {
let mut lt_arg_spans = Vec::new();
@@ -713,7 +733,28 @@ fn suggest_removing_args_or_generics(&self, err: &mut Diagnostic) {
);
};
- if remove_entire_generics {
+ // If there is a single unbound associated type and a single excess generic param
+ // suggest replacing the generic param with the associated type bound
+ if provided_args_matches_unbound_traits && !unbound_types.is_empty() {
+ let mut suggestions = vec![];
+ let unused_generics = &self.gen_args.args[self.num_expected_type_or_const_args()..];
+ for (potential, name) in iter::zip(unused_generics, &unbound_types) {
+ if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(potential.span()) {
+ suggestions.push((potential.span(), format!("{} = {}", name, snippet)));
+ }
+ }
+
+ if !suggestions.is_empty() {
+ err.multipart_suggestion(
+ &format!(
+ "replace the generic bound{s} with the associated type{s}",
+ s = pluralize!(unbound_types.len())
+ ),
+ suggestions,
+ Applicability::MaybeIncorrect,
+ );
+ }
+ } else if remove_entire_generics {
let span = self
.path_segment
.args
diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs
index d3e9e65..22c1924 100644
--- a/library/alloc/src/macros.rs
+++ b/library/alloc/src/macros.rs
@@ -34,7 +34,7 @@
/// be mindful of side effects.
///
/// [`Vec`]: crate::vec::Vec
-#[cfg(not(test))]
+#[cfg(all(not(no_global_oom_handling), not(test)))]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_diagnostic_item = "vec_macro"]
@@ -55,7 +55,7 @@ macro_rules! vec {
// required for this macro definition, is not available. Instead use the
// `slice::into_vec` function which is only available with cfg(test)
// NB see the slice::hack module in slice.rs for more information
-#[cfg(test)]
+#[cfg(all(not(no_global_oom_handling), test))]
macro_rules! vec {
() => (
$crate::vec::Vec::new()
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 68f39dc..7ef2e95 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -295,7 +295,7 @@ pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata)
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -358,7 +358,7 @@ pub const fn to_raw_parts(self) -> (*const (), <T as super::Pointee>::Metadata)
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -1188,7 +1188,7 @@ pub const fn as_ptr(self) -> *const T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 4c9b0f7..56f9c84 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -302,7 +302,7 @@ pub const fn to_raw_parts(self) -> (*mut (), <T as super::Pointee>::Metadata) {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -368,7 +368,7 @@ pub const fn to_raw_parts(self) -> (*mut (), <T as super::Pointee>::Metadata) {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -550,7 +550,7 @@ pub const fn wrapping_offset(self, count: isize) -> *mut T
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
@@ -615,7 +615,7 @@ pub const fn wrapping_offset(self, count: isize) -> *mut T
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
@@ -1461,7 +1461,7 @@ pub const fn as_mut_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -1513,7 +1513,7 @@ pub const fn as_mut_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 6f40292..5ebe615 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -114,7 +114,7 @@ pub const fn dangling() -> Self {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -148,7 +148,7 @@ pub const fn dangling() -> Self {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
@@ -350,7 +350,7 @@ pub const fn as_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -400,7 +400,7 @@ pub const fn as_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
@@ -580,7 +580,7 @@ pub const fn as_mut_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get mutated (except inside `UnsafeCell`).
///
/// This applies even if the result of this method is unused!
@@ -626,7 +626,7 @@ pub const fn as_mut_ptr(self) -> *mut T {
///
/// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
/// arbitrarily chosen and does not necessarily reflect the actual lifetime of the data.
- /// In particular, for the duration of this lifetime, the memory the pointer points to must
+ /// In particular, while this reference exists, the memory the pointer points to must
/// not get accessed (read or written) through any other pointer.
///
/// This applies even if the result of this method is unused!
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 22662f7..98dd152 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -358,6 +358,20 @@ impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
pub(super) fn new(slice: &'a [T], pred: P) -> Self {
Self { v: slice, pred, finished: false }
}
+ /// Returns a slice which contains items not yet handled by split.
+ /// # Example
+ ///
+ /// ```
+ /// #![feature(split_as_slice)]
+ /// let slice = [1,2,3,4,5];
+ /// let mut split = slice.split(|v| v % 2 == 0);
+ /// assert!(split.next().is_some());
+ /// assert_eq!(split.as_slice(), &[3,4,5]);
+ /// ```
+ #[unstable(feature = "split_as_slice", issue = "96137")]
+ pub fn as_slice(&self) -> &'a [T] {
+ if self.finished { &[] } else { &self.v }
+ }
}
#[stable(feature = "core_impl_debug", since = "1.9.0")]
diff --git a/library/core/tests/hash/sip.rs b/library/core/tests/hash/sip.rs
index 5c0e114..877d084 100644
--- a/library/core/tests/hash/sip.rs
+++ b/library/core/tests/hash/sip.rs
@@ -15,28 +15,6 @@ fn hash<H: Hasher>(&self, state: &mut H) {
}
}
-macro_rules! u8to64_le {
- ($buf:expr, $i:expr) => {
- $buf[0 + $i] as u64
- | ($buf[1 + $i] as u64) << 8
- | ($buf[2 + $i] as u64) << 16
- | ($buf[3 + $i] as u64) << 24
- | ($buf[4 + $i] as u64) << 32
- | ($buf[5 + $i] as u64) << 40
- | ($buf[6 + $i] as u64) << 48
- | ($buf[7 + $i] as u64) << 56
- };
- ($buf:expr, $i:expr, $len:expr) => {{
- let mut t = 0;
- let mut out = 0;
- while t < $len {
- out |= ($buf[t + $i] as u64) << t * 8;
- t += 1;
- }
- out
- }};
-}
-
fn hash_with<H: Hasher, T: Hash>(mut st: H, x: &T) -> u64 {
x.hash(&mut st);
st.finish()
@@ -123,7 +101,7 @@ fn test_siphash_1_3() {
let mut state_inc = SipHasher13::new_with_keys(k0, k1);
while t < 64 {
- let vec = u8to64_le!(vecs[t], 0);
+ let vec = u64::from_le_bytes(vecs[t]);
let out = hash_with(SipHasher13::new_with_keys(k0, k1), &Bytes(&buf));
assert_eq!(vec, out);
@@ -217,7 +195,7 @@ fn test_siphash_2_4() {
let mut state_inc = SipHasher::new_with_keys(k0, k1);
while t < 64 {
- let vec = u8to64_le!(vecs[t], 0);
+ let vec = u64::from_le_bytes(vecs[t]);
let out = hash_with(SipHasher::new_with_keys(k0, k1), &Bytes(&buf));
assert_eq!(vec, out);
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 447a6fc..485fa30 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -46,6 +46,7 @@
#![feature(sort_internals)]
#![feature(slice_take)]
#![feature(slice_from_ptr_range)]
+#![feature(split_as_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_array_assume_init)]
#![feature(maybe_uninit_write_slice)]
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index ada4791..872786e 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2339,6 +2339,18 @@ fn slice_rsplit_array_mut() {
}
}
+#[test]
+fn split_as_slice() {
+ let arr = [1, 2, 3, 4, 5, 6];
+ let mut split = arr.split(|v| v % 2 == 0);
+ assert_eq!(split.as_slice(), &[1, 2, 3, 4, 5, 6]);
+ assert!(split.next().is_some());
+ assert_eq!(split.as_slice(), &[3, 4, 5, 6]);
+ assert!(split.next().is_some());
+ assert!(split.next().is_some());
+ assert_eq!(split.as_slice(), &[]);
+}
+
#[should_panic]
#[test]
fn slice_split_array_ref_out_of_bounds() {
diff --git a/library/proc_macro/Cargo.toml b/library/proc_macro/Cargo.toml
index db5e2e4..e54a50a 100644
--- a/library/proc_macro/Cargo.toml
+++ b/library/proc_macro/Cargo.toml
@@ -5,3 +5,7 @@
[dependencies]
std = { path = "../std" }
+# Workaround: when documenting this crate rustdoc will try to load crate named
+# `core` when resolving doc links. Without this line a different `core` will be
+# loaded from sysroot causing duplicate lang items and other similar errors.
+core = { path = "../core" }
diff --git a/library/std/src/sys/hermit/mutex.rs b/library/std/src/sys/hermit/mutex.rs
index 415cbba..97b4c49 100644
--- a/library/std/src/sys/hermit/mutex.rs
+++ b/library/std/src/sys/hermit/mutex.rs
@@ -1,6 +1,5 @@
use crate::cell::UnsafeCell;
use crate::collections::VecDeque;
-use crate::ffi::c_void;
use crate::hint;
use crate::ops::{Deref, DerefMut, Drop};
use crate::ptr;
@@ -220,38 +219,3 @@ pub unsafe fn try_lock(&self) -> bool {
#[inline]
pub unsafe fn destroy(&self) {}
}
-
-pub struct ReentrantMutex {
- inner: *const c_void,
-}
-
-impl ReentrantMutex {
- pub const unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { inner: ptr::null() }
- }
-
- #[inline]
- pub unsafe fn init(&self) {
- let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _);
- }
-
- #[inline]
- pub unsafe fn lock(&self) {
- let _ = abi::recmutex_lock(self.inner);
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- true
- }
-
- #[inline]
- pub unsafe fn unlock(&self) {
- let _ = abi::recmutex_unlock(self.inner);
- }
-
- #[inline]
- pub unsafe fn destroy(&self) {
- let _ = abi::recmutex_destroy(self.inner);
- }
-}
diff --git a/library/std/src/sys/itron/mutex.rs b/library/std/src/sys/itron/mutex.rs
index e01f595..5ee2318 100644
--- a/library/std/src/sys/itron/mutex.rs
+++ b/library/std/src/sys/itron/mutex.rs
@@ -5,7 +5,6 @@
error::{expect_success, expect_success_aborting, fail, ItronError},
spin::SpinIdOnceCell,
};
-use crate::cell::UnsafeCell;
pub struct Mutex {
/// The ID of the underlying mutex object
@@ -89,95 +88,3 @@ fn drop(&mut self) {
unsafe { self.0.unlock() };
}
}
-
-// All empty stubs because this platform does not yet support threads, so lock
-// acquisition always succeeds.
-pub struct ReentrantMutex {
- /// The ID of the underlying mutex object
- mtx: abi::ID,
- /// The lock count.
- count: UnsafeCell<usize>,
-}
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- pub const unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { mtx: 0, count: UnsafeCell::new(0) }
- }
-
- pub unsafe fn init(&mut self) {
- self.mtx = expect_success(
- unsafe {
- abi::acre_mtx(&abi::T_CMTX {
- // Priority inheritance mutex
- mtxatr: abi::TA_INHERIT,
- // Unused
- ceilpri: 0,
- })
- },
- &"acre_mtx",
- );
- }
-
- pub unsafe fn lock(&self) {
- match unsafe { abi::loc_mtx(self.mtx) } {
- abi::E_OBJ => {
- // Recursive lock
- unsafe {
- let count = &mut *self.count.get();
- if let Some(new_count) = count.checked_add(1) {
- *count = new_count;
- } else {
- // counter overflow
- rtabort!("lock count overflow");
- }
- }
- }
- er => {
- expect_success(er, &"loc_mtx");
- }
- }
- }
-
- pub unsafe fn unlock(&self) {
- unsafe {
- let count = &mut *self.count.get();
- if *count > 0 {
- *count -= 1;
- return;
- }
- }
-
- expect_success_aborting(unsafe { abi::unl_mtx(self.mtx) }, &"unl_mtx");
- }
-
- pub unsafe fn try_lock(&self) -> bool {
- let er = unsafe { abi::ploc_mtx(self.mtx) };
- if er == abi::E_OBJ {
- // Recursive lock
- unsafe {
- let count = &mut *self.count.get();
- if let Some(new_count) = count.checked_add(1) {
- *count = new_count;
- } else {
- // counter overflow
- rtabort!("lock count overflow");
- }
- }
- true
- } else if er == abi::E_TMOUT {
- // Locked by another thread
- false
- } else {
- expect_success(er, &"ploc_mtx");
- // Top-level lock by the current thread
- true
- }
- }
-
- pub unsafe fn destroy(&self) {
- expect_success_aborting(unsafe { abi::del_mtx(self.mtx) }, &"del_mtx");
- }
-}
diff --git a/library/std/src/sys/sgx/mutex.rs b/library/std/src/sys/sgx/mutex.rs
index 0b2d1f4..98a390c 100644
--- a/library/std/src/sys/sgx/mutex.rs
+++ b/library/std/src/sys/sgx/mutex.rs
@@ -1,8 +1,4 @@
-use fortanix_sgx_abi::Tcs;
-
-use super::abi::thread;
-
-use super::waitqueue::{try_lock_or_false, NotifiedTcs, SpinMutex, WaitQueue, WaitVariable};
+use super::waitqueue::{try_lock_or_false, SpinMutex, WaitQueue, WaitVariable};
pub struct Mutex {
inner: SpinMutex<WaitVariable<bool>>,
@@ -60,84 +56,3 @@ pub unsafe fn try_lock(&self) -> bool {
#[inline]
pub unsafe fn destroy(&self) {}
}
-
-struct ReentrantLock {
- owner: Option<Tcs>,
- count: usize,
-}
-
-pub struct ReentrantMutex {
- inner: SpinMutex<WaitVariable<ReentrantLock>>,
-}
-
-impl ReentrantMutex {
- pub const fn uninitialized() -> ReentrantMutex {
- ReentrantMutex {
- inner: SpinMutex::new(WaitVariable::new(ReentrantLock { owner: None, count: 0 })),
- }
- }
-
- #[inline]
- pub unsafe fn init(&self) {}
-
- #[inline]
- pub unsafe fn lock(&self) {
- let mut guard = self.inner.lock();
- match guard.lock_var().owner {
- Some(tcs) if tcs != thread::current() => {
- // Another thread has the lock, wait
- WaitQueue::wait(guard, || {});
- // Another thread has passed the lock to us
- }
- _ => {
- // We are just now obtaining the lock
- guard.lock_var_mut().owner = Some(thread::current());
- guard.lock_var_mut().count += 1;
- }
- }
- }
-
- #[inline]
- pub unsafe fn unlock(&self) {
- let mut guard = self.inner.lock();
- if guard.lock_var().count > 1 {
- guard.lock_var_mut().count -= 1;
- } else {
- match WaitQueue::notify_one(guard) {
- Err(mut guard) => {
- // No other waiters, unlock
- guard.lock_var_mut().count = 0;
- guard.lock_var_mut().owner = None;
- }
- Ok(mut guard) => {
- // There was a thread waiting, just pass the lock
- if let NotifiedTcs::Single(tcs) = guard.notified_tcs() {
- guard.lock_var_mut().owner = Some(tcs)
- } else {
- unreachable!() // called notify_one
- }
- }
- }
- }
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- let mut guard = try_lock_or_false!(self.inner);
- match guard.lock_var().owner {
- Some(tcs) if tcs != thread::current() => {
- // Another thread has the lock
- false
- }
- _ => {
- // We are just now obtaining the lock
- guard.lock_var_mut().owner = Some(thread::current());
- guard.lock_var_mut().count += 1;
- true
- }
- }
- }
-
- #[inline]
- pub unsafe fn destroy(&self) {}
-}
diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs
index 6276037..c12ee16 100644
--- a/library/std/src/sys/unix/futex.rs
+++ b/library/std/src/sys/unix/futex.rs
@@ -52,25 +52,6 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
}
}
-#[cfg(target_os = "emscripten")]
-pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) {
- extern "C" {
- fn emscripten_futex_wait(
- addr: *const AtomicU32,
- val: libc::c_uint,
- max_wait_ms: libc::c_double,
- ) -> libc::c_int;
- }
-
- unsafe {
- emscripten_futex_wait(
- futex,
- expected,
- timeout.map_or(crate::f64::INFINITY, |d| d.as_secs_f64() * 1000.0),
- );
- }
-}
-
/// Wake up one thread that's blocked on futex_wait on this futex.
///
/// Returns true if this actually woke up such a thread,
@@ -101,10 +82,32 @@ pub fn futex_wake_all(futex: &AtomicU32) {
}
#[cfg(target_os = "emscripten")]
-pub fn futex_wake(futex: &AtomicU32) -> bool {
- extern "C" {
- fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
- }
+extern "C" {
+ fn emscripten_futex_wake(addr: *const AtomicU32, count: libc::c_int) -> libc::c_int;
+ fn emscripten_futex_wait(
+ addr: *const AtomicU32,
+ val: libc::c_uint,
+ max_wait_ms: libc::c_double,
+ ) -> libc::c_int;
+}
+#[cfg(target_os = "emscripten")]
+pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
+ unsafe {
+ emscripten_futex_wait(
+ futex,
+ expected,
+ timeout.map_or(f64::INFINITY, |d| d.as_secs_f64() * 1000.0),
+ ) != -libc::ETIMEDOUT
+ }
+}
+
+#[cfg(target_os = "emscripten")]
+pub fn futex_wake(futex: &AtomicU32) -> bool {
unsafe { emscripten_futex_wake(futex, 1) > 0 }
}
+
+#[cfg(target_os = "emscripten")]
+pub fn futex_wake_all(futex: &AtomicU32) {
+ unsafe { emscripten_futex_wake(futex, i32::MAX) };
+}
diff --git a/library/std/src/sys/unix/locks/futex.rs b/library/std/src/sys/unix/locks/futex.rs
index b166e7c..7a63af1 100644
--- a/library/std/src/sys/unix/locks/futex.rs
+++ b/library/std/src/sys/unix/locks/futex.rs
@@ -1,6 +1,5 @@
-use crate::cell::UnsafeCell;
use crate::sync::atomic::{
- AtomicU32, AtomicUsize,
+ AtomicU32,
Ordering::{Acquire, Relaxed, Release},
};
use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all};
@@ -163,98 +162,3 @@ unsafe fn wait_optional_timeout(&self, mutex: &Mutex, timeout: Option<Duration>)
r
}
}
-
-/// A reentrant mutex. Used by stdout().lock() and friends.
-///
-/// The 'owner' field tracks which thread has locked the mutex.
-///
-/// We use current_thread_unique_ptr() as the thread identifier,
-/// which is just the address of a thread local variable.
-///
-/// If `owner` is set to the identifier of the current thread,
-/// we assume the mutex is already locked and instead of locking it again,
-/// we increment `lock_count`.
-///
-/// When unlocking, we decrement `lock_count`, and only unlock the mutex when
-/// it reaches zero.
-///
-/// `lock_count` is protected by the mutex and only accessed by the thread that has
-/// locked the mutex, so needs no synchronization.
-///
-/// `owner` can be checked by other threads that want to see if they already
-/// hold the lock, so needs to be atomic. If it compares equal, we're on the
-/// same thread that holds the mutex and memory access can use relaxed ordering
-/// since we're not dealing with multiple threads. If it compares unequal,
-/// synchronization is left to the mutex, making relaxed memory ordering for
-/// the `owner` field fine in all cases.
-pub struct ReentrantMutex {
- mutex: Mutex,
- owner: AtomicUsize,
- lock_count: UnsafeCell<u32>,
-}
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- #[inline]
- pub const unsafe fn uninitialized() -> Self {
- Self { mutex: Mutex::new(), owner: AtomicUsize::new(0), lock_count: UnsafeCell::new(0) }
- }
-
- #[inline]
- pub unsafe fn init(&self) {}
-
- #[inline]
- pub unsafe fn destroy(&self) {}
-
- pub unsafe fn try_lock(&self) -> bool {
- let this_thread = current_thread_unique_ptr();
- if self.owner.load(Relaxed) == this_thread {
- self.increment_lock_count();
- true
- } else if self.mutex.try_lock() {
- self.owner.store(this_thread, Relaxed);
- debug_assert_eq!(*self.lock_count.get(), 0);
- *self.lock_count.get() = 1;
- true
- } else {
- false
- }
- }
-
- pub unsafe fn lock(&self) {
- let this_thread = current_thread_unique_ptr();
- if self.owner.load(Relaxed) == this_thread {
- self.increment_lock_count();
- } else {
- self.mutex.lock();
- self.owner.store(this_thread, Relaxed);
- debug_assert_eq!(*self.lock_count.get(), 0);
- *self.lock_count.get() = 1;
- }
- }
-
- unsafe fn increment_lock_count(&self) {
- *self.lock_count.get() = (*self.lock_count.get())
- .checked_add(1)
- .expect("lock count overflow in reentrant mutex");
- }
-
- pub unsafe fn unlock(&self) {
- *self.lock_count.get() -= 1;
- if *self.lock_count.get() == 0 {
- self.owner.store(0, Relaxed);
- self.mutex.unlock();
- }
- }
-}
-
-/// Get an address that is unique per running thread.
-///
-/// This can be used as a non-null usize-sized ID.
-pub fn current_thread_unique_ptr() -> usize {
- // Use a non-drop type to make sure it's still available during thread destruction.
- thread_local! { static X: u8 = const { 0 } }
- X.with(|x| <*const _>::addr(x))
-}
diff --git a/library/std/src/sys/unix/locks/mod.rs b/library/std/src/sys/unix/locks/mod.rs
index e0404f4..3e39c8b9 100644
--- a/library/std/src/sys/unix/locks/mod.rs
+++ b/library/std/src/sys/unix/locks/mod.rs
@@ -2,18 +2,17 @@
if #[cfg(any(
target_os = "linux",
target_os = "android",
+ all(target_os = "emscripten", target_feature = "atomics"),
))] {
mod futex;
mod futex_rwlock;
- pub use futex::{Mutex, MovableMutex, Condvar, MovableCondvar, ReentrantMutex};
+ pub use futex::{Mutex, MovableMutex, Condvar, MovableCondvar};
pub use futex_rwlock::{RwLock, MovableRwLock};
} else {
mod pthread_mutex;
- mod pthread_remutex;
mod pthread_rwlock;
mod pthread_condvar;
pub use pthread_mutex::{Mutex, MovableMutex};
- pub use pthread_remutex::ReentrantMutex;
pub use pthread_rwlock::{RwLock, MovableRwLock};
pub use pthread_condvar::{Condvar, MovableCondvar};
}
diff --git a/library/std/src/sys/unix/locks/pthread_remutex.rs b/library/std/src/sys/unix/locks/pthread_remutex.rs
deleted file mode 100644
index b006181..0000000
--- a/library/std/src/sys/unix/locks/pthread_remutex.rs
+++ /dev/null
@@ -1,46 +0,0 @@
-use super::pthread_mutex::PthreadMutexAttr;
-use crate::cell::UnsafeCell;
-use crate::mem::MaybeUninit;
-use crate::sys::cvt_nz;
-
-pub struct ReentrantMutex {
- inner: UnsafeCell<libc::pthread_mutex_t>,
-}
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- pub const unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
- }
-
- pub unsafe fn init(&self) {
- let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
- cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
- let attr = PthreadMutexAttr(&mut attr);
- cvt_nz(libc::pthread_mutexattr_settype(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_RECURSIVE))
- .unwrap();
- cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap();
- }
-
- pub unsafe fn lock(&self) {
- let result = libc::pthread_mutex_lock(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- libc::pthread_mutex_trylock(self.inner.get()) == 0
- }
-
- pub unsafe fn unlock(&self) {
- let result = libc::pthread_mutex_unlock(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-
- pub unsafe fn destroy(&self) {
- let result = libc::pthread_mutex_destroy(self.inner.get());
- debug_assert_eq!(result, 0);
- }
-}
diff --git a/library/std/src/sys/unsupported/locks/mod.rs b/library/std/src/sys/unsupported/locks/mod.rs
index 35bd591..d412ff1 100644
--- a/library/std/src/sys/unsupported/locks/mod.rs
+++ b/library/std/src/sys/unsupported/locks/mod.rs
@@ -2,5 +2,5 @@
mod mutex;
mod rwlock;
pub use condvar::{Condvar, MovableCondvar};
-pub use mutex::{MovableMutex, Mutex, ReentrantMutex};
+pub use mutex::{MovableMutex, Mutex};
pub use rwlock::{MovableRwLock, RwLock};
diff --git a/library/std/src/sys/unsupported/locks/mutex.rs b/library/std/src/sys/unsupported/locks/mutex.rs
index b3203c1..cad991a 100644
--- a/library/std/src/sys/unsupported/locks/mutex.rs
+++ b/library/std/src/sys/unsupported/locks/mutex.rs
@@ -36,26 +36,3 @@ pub unsafe fn try_lock(&self) -> bool {
#[inline]
pub unsafe fn destroy(&self) {}
}
-
-// All empty stubs because this platform does not yet support threads, so lock
-// acquisition always succeeds.
-pub struct ReentrantMutex {}
-
-impl ReentrantMutex {
- pub const unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex {}
- }
-
- pub unsafe fn init(&self) {}
-
- pub unsafe fn lock(&self) {}
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- true
- }
-
- pub unsafe fn unlock(&self) {}
-
- pub unsafe fn destroy(&self) {}
-}
diff --git a/library/std/src/sys/wasm/atomics/mutex.rs b/library/std/src/sys/wasm/atomics/mutex.rs
index 3a09f0b..1acc839 100644
--- a/library/std/src/sys/wasm/atomics/mutex.rs
+++ b/library/std/src/sys/wasm/atomics/mutex.rs
@@ -1,8 +1,6 @@
use crate::arch::wasm32;
-use crate::cell::UnsafeCell;
use crate::mem;
-use crate::sync::atomic::{AtomicU32, AtomicUsize, Ordering::SeqCst};
-use crate::sys::thread;
+use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
pub struct Mutex {
locked: AtomicUsize,
@@ -64,93 +62,3 @@ fn ptr(&self) -> *mut i32 {
self.locked.as_mut_ptr() as *mut i32
}
}
-
-pub struct ReentrantMutex {
- owner: AtomicU32,
- recursions: UnsafeCell<u32>,
-}
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-// Reentrant mutexes are similarly implemented to mutexes above except that
-// instead of "1" meaning unlocked we use the id of a thread to represent
-// whether it has locked a mutex. That way we have an atomic counter which
-// always holds the id of the thread that currently holds the lock (or 0 if the
-// lock is unlocked).
-//
-// Once a thread acquires a lock recursively, which it detects by looking at
-// the value that's already there, it will update a local `recursions` counter
-// in a nonatomic fashion (as we hold the lock). The lock is then fully
-// released when this recursion counter reaches 0.
-
-impl ReentrantMutex {
- pub const unsafe fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { owner: AtomicU32::new(0), recursions: UnsafeCell::new(0) }
- }
-
- pub unsafe fn init(&self) {
- // nothing to do...
- }
-
- pub unsafe fn lock(&self) {
- let me = thread::my_id();
- while let Err(owner) = self._try_lock(me) {
- // SAFETY: the caller must guarantee that `self.ptr()` and `owner` are valid i32.
- let val = unsafe { wasm32::memory_atomic_wait32(self.ptr(), owner as i32, -1) };
- debug_assert!(val == 0 || val == 1);
- }
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- unsafe { self._try_lock(thread::my_id()).is_ok() }
- }
-
- #[inline]
- unsafe fn _try_lock(&self, id: u32) -> Result<(), u32> {
- let id = id.checked_add(1).unwrap();
- match self.owner.compare_exchange(0, id, SeqCst, SeqCst) {
- // we transitioned from unlocked to locked
- Ok(_) => {
- debug_assert_eq!(*self.recursions.get(), 0);
- Ok(())
- }
-
- // we currently own this lock, so let's update our count and return
- // true.
- Err(n) if n == id => {
- *self.recursions.get() += 1;
- Ok(())
- }
-
- // Someone else owns the lock, let our caller take care of it
- Err(other) => Err(other),
- }
- }
-
- pub unsafe fn unlock(&self) {
- // If we didn't ever recursively lock the lock then we fully unlock the
- // mutex and wake up a waiter, if any. Otherwise we decrement our
- // recursive counter and let some one else take care of the zero.
- match *self.recursions.get() {
- 0 => {
- self.owner.swap(0, SeqCst);
- // SAFETY: the caller must guarantee that `self.ptr()` is valid i32.
- unsafe {
- wasm32::memory_atomic_notify(self.ptr() as *mut i32, 1);
- } // wake up one waiter, if any
- }
- ref mut n => *n -= 1,
- }
- }
-
- pub unsafe fn destroy(&self) {
- // nothing to do...
- }
-
- #[inline]
- fn ptr(&self) -> *mut i32 {
- self.owner.as_mut_ptr() as *mut i32
- }
-}
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 336264d..5f14eda 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -536,15 +536,6 @@ pub struct CONDITION_VARIABLE {
pub struct SRWLOCK {
pub ptr: LPVOID,
}
-#[repr(C)]
-pub struct CRITICAL_SECTION {
- CriticalSectionDebug: LPVOID,
- LockCount: LONG,
- RecursionCount: LONG,
- OwningThread: HANDLE,
- LockSemaphore: HANDLE,
- SpinCount: ULONG_PTR,
-}
#[repr(C)]
pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
@@ -875,11 +866,6 @@ pub struct FILE_STANDARD_INFO {
#[link(name = "kernel32")]
extern "system" {
pub fn GetCurrentProcessId() -> DWORD;
- pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOL;
- pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT;
pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
diff --git a/library/std/src/sys/windows/locks/mod.rs b/library/std/src/sys/windows/locks/mod.rs
index 35bd591..d412ff1 100644
--- a/library/std/src/sys/windows/locks/mod.rs
+++ b/library/std/src/sys/windows/locks/mod.rs
@@ -2,5 +2,5 @@
mod mutex;
mod rwlock;
pub use condvar::{Condvar, MovableCondvar};
-pub use mutex::{MovableMutex, Mutex, ReentrantMutex};
+pub use mutex::{MovableMutex, Mutex};
pub use rwlock::{MovableRwLock, RwLock};
diff --git a/library/std/src/sys/windows/locks/mutex.rs b/library/std/src/sys/windows/locks/mutex.rs
index 56f91eb..9fa280b 100644
--- a/library/std/src/sys/windows/locks/mutex.rs
+++ b/library/std/src/sys/windows/locks/mutex.rs
@@ -15,7 +15,6 @@
//! is that there are no guarantees of fairness.
use crate::cell::UnsafeCell;
-use crate::mem::MaybeUninit;
use crate::sys::c;
pub struct Mutex {
@@ -60,37 +59,3 @@ pub unsafe fn destroy(&self) {
// SRWLock does not need to be destroyed.
}
}
-
-pub struct ReentrantMutex {
- inner: MaybeUninit<UnsafeCell<c::CRITICAL_SECTION>>,
-}
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- pub const fn uninitialized() -> ReentrantMutex {
- ReentrantMutex { inner: MaybeUninit::uninit() }
- }
-
- pub unsafe fn init(&self) {
- c::InitializeCriticalSection(UnsafeCell::raw_get(self.inner.as_ptr()));
- }
-
- pub unsafe fn lock(&self) {
- c::EnterCriticalSection(UnsafeCell::raw_get(self.inner.as_ptr()));
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- c::TryEnterCriticalSection(UnsafeCell::raw_get(self.inner.as_ptr())) != 0
- }
-
- pub unsafe fn unlock(&self) {
- c::LeaveCriticalSection(UnsafeCell::raw_get(self.inner.as_ptr()));
- }
-
- pub unsafe fn destroy(&self) {
- c::DeleteCriticalSection(UnsafeCell::raw_get(self.inner.as_ptr()));
- }
-}
diff --git a/library/std/src/sys_common/remutex.rs b/library/std/src/sys_common/remutex.rs
index 801c9c2..8f25230 100644
--- a/library/std/src/sys_common/remutex.rs
+++ b/library/std/src/sys_common/remutex.rs
@@ -1,10 +1,12 @@
#[cfg(all(test, not(target_os = "emscripten")))]
mod tests;
+use crate::cell::UnsafeCell;
use crate::marker::PhantomPinned;
use crate::ops::Deref;
use crate::panic::{RefUnwindSafe, UnwindSafe};
use crate::pin::Pin;
+use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use crate::sys::locks as sys;
/// A re-entrant mutual exclusion
@@ -12,8 +14,36 @@
/// This mutex will block *other* threads waiting for the lock to become
/// available. The thread which has already locked the mutex can lock it
/// multiple times without blocking, preventing a common source of deadlocks.
+///
+/// This is used by stdout().lock() and friends.
+///
+/// ## Implementation details
+///
+/// The 'owner' field tracks which thread has locked the mutex.
+///
+/// We use current_thread_unique_ptr() as the thread identifier,
+/// which is just the address of a thread local variable.
+///
+/// If `owner` is set to the identifier of the current thread,
+/// we assume the mutex is already locked and instead of locking it again,
+/// we increment `lock_count`.
+///
+/// When unlocking, we decrement `lock_count`, and only unlock the mutex when
+/// it reaches zero.
+///
+/// `lock_count` is protected by the mutex and only accessed by the thread that has
+/// locked the mutex, so needs no synchronization.
+///
+/// `owner` can be checked by other threads that want to see if they already
+/// hold the lock, so needs to be atomic. If it compares equal, we're on the
+/// same thread that holds the mutex and memory access can use relaxed ordering
+/// since we're not dealing with multiple threads. If it compares unequal,
+/// synchronization is left to the mutex, making relaxed memory ordering for
+/// the `owner` field fine in all cases.
pub struct ReentrantMutex<T> {
- inner: sys::ReentrantMutex,
+ mutex: sys::Mutex,
+ owner: AtomicUsize,
+ lock_count: UnsafeCell<u32>,
data: T,
_pinned: PhantomPinned,
}
@@ -53,7 +83,9 @@ impl<T> ReentrantMutex<T> {
/// lock/unlock methods safe.
pub const unsafe fn new(t: T) -> ReentrantMutex<T> {
ReentrantMutex {
- inner: sys::ReentrantMutex::uninitialized(),
+ mutex: sys::Mutex::new(),
+ owner: AtomicUsize::new(0),
+ lock_count: UnsafeCell::new(0),
data: t,
_pinned: PhantomPinned,
}
@@ -66,7 +98,7 @@ impl<T> ReentrantMutex<T> {
/// Unsafe to call more than once, and must be called after this will no
/// longer move in memory.
pub unsafe fn init(self: Pin<&mut Self>) {
- self.get_unchecked_mut().inner.init()
+ self.get_unchecked_mut().mutex.init()
}
/// Acquires a mutex, blocking the current thread until it is able to do so.
@@ -82,7 +114,19 @@ pub unsafe fn init(self: Pin<&mut Self>) {
/// this call will return failure if the mutex would otherwise be
/// acquired.
pub fn lock(self: Pin<&Self>) -> ReentrantMutexGuard<'_, T> {
- unsafe { self.inner.lock() }
+ let this_thread = current_thread_unique_ptr();
+ // Safety: We only touch lock_count when we own the lock,
+ // and since self is pinned we can safely call the lock() on the mutex.
+ unsafe {
+ if self.owner.load(Relaxed) == this_thread {
+ self.increment_lock_count();
+ } else {
+ self.mutex.lock();
+ self.owner.store(this_thread, Relaxed);
+ debug_assert_eq!(*self.lock_count.get(), 0);
+ *self.lock_count.get() = 1;
+ }
+ }
ReentrantMutexGuard { lock: self }
}
@@ -99,20 +143,35 @@ pub fn lock(self: Pin<&Self>) -> ReentrantMutexGuard<'_, T> {
/// this call will return failure if the mutex would otherwise be
/// acquired.
pub fn try_lock(self: Pin<&Self>) -> Option<ReentrantMutexGuard<'_, T>> {
- if unsafe { self.inner.try_lock() } {
- Some(ReentrantMutexGuard { lock: self })
- } else {
- None
+ let this_thread = current_thread_unique_ptr();
+ // Safety: We only touch lock_count when we own the lock,
+ // and since self is pinned we can safely call the try_lock on the mutex.
+ unsafe {
+ if self.owner.load(Relaxed) == this_thread {
+ self.increment_lock_count();
+ Some(ReentrantMutexGuard { lock: self })
+ } else if self.mutex.try_lock() {
+ self.owner.store(this_thread, Relaxed);
+ debug_assert_eq!(*self.lock_count.get(), 0);
+ *self.lock_count.get() = 1;
+ Some(ReentrantMutexGuard { lock: self })
+ } else {
+ None
+ }
}
}
+
+ unsafe fn increment_lock_count(&self) {
+ *self.lock_count.get() = (*self.lock_count.get())
+ .checked_add(1)
+ .expect("lock count overflow in reentrant mutex");
+ }
}
impl<T> Drop for ReentrantMutex<T> {
fn drop(&mut self) {
- // This is actually safe b/c we know that there is no further usage of
- // this mutex (it's up to the user to arrange for a mutex to get
- // dropped, that's not our job)
- unsafe { self.inner.destroy() }
+ // Safety: We're the unique owner of this mutex and not going to use it afterwards.
+ unsafe { self.mutex.destroy() }
}
}
@@ -127,8 +186,22 @@ fn deref(&self) -> &T {
impl<T> Drop for ReentrantMutexGuard<'_, T> {
#[inline]
fn drop(&mut self) {
+ // Safety: We own the lock, and the lock is pinned.
unsafe {
- self.lock.inner.unlock();
+ *self.lock.lock_count.get() -= 1;
+ if *self.lock.lock_count.get() == 0 {
+ self.lock.owner.store(0, Relaxed);
+ self.lock.mutex.unlock();
+ }
}
}
}
+
+/// Get an address that is unique per running thread.
+///
+/// This can be used as a non-null usize-sized ID.
+pub fn current_thread_unique_ptr() -> usize {
+ // Use a non-drop type to make sure it's still available during thread destruction.
+ thread_local! { static X: u8 = const { 0 } }
+ X.with(|x| <*const _>::addr(x))
+}
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index d437397..ac1c475 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -817,7 +817,7 @@
return os.path.join(self.bin_root(True), '.rustfmt-stamp')
def llvm_stamp(self):
- """Return the path for .rustfmt-stamp
+ """Return the path for .llvm-stamp
>>> rb = RustBuild()
>>> rb.build_dir = "build"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 0276d15..d688f79 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -364,6 +364,19 @@ pub fn krate(mut self, name: &str) -> Self {
self
}
+ // single alias, which does not correspond to any on-disk path
+ pub fn alias(mut self, alias: &str) -> Self {
+ assert!(
+ !self.builder.src.join(alias).exists(),
+ "use `builder.path()` for real paths: {}",
+ alias
+ );
+ self.paths.insert(PathSet::Set(
+ std::iter::once(TaskPath { path: alias.into(), kind: Some(self.kind) }).collect(),
+ ));
+ self
+ }
+
// single, non-aliased path
pub fn path(self, path: &str) -> Self {
self.paths(&[path])
@@ -372,7 +385,17 @@ pub fn path(self, path: &str) -> Self {
// multiple aliases for the same job
pub fn paths(mut self, paths: &[&str]) -> Self {
self.paths.insert(PathSet::Set(
- paths.iter().map(|p| TaskPath { path: p.into(), kind: Some(self.kind) }).collect(),
+ paths
+ .iter()
+ .map(|p| {
+ assert!(
+ self.builder.src.join(p).exists(),
+ "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}",
+ p
+ );
+ TaskPath { path: p.into(), kind: Some(self.kind) }
+ })
+ .collect(),
));
self
}
diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs
index 7ce4468..dca782c 100644
--- a/src/bootstrap/cc_detect.rs
+++ b/src/bootstrap/cc_detect.rs
@@ -149,6 +149,10 @@ pub fn find(build: &mut Build) {
build.verbose(&format!("AR_{} = {:?}", &target.triple, ar));
build.ar.insert(target, ar);
}
+
+ if let Some(ranlib) = config.and_then(|c| c.ranlib.clone()) {
+ build.ranlib.insert(target, ranlib);
+ }
}
}
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index fdd1581..e3287e3 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -61,7 +61,7 @@ impl Step for Docs {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = run.builder.config.docs;
- run.path("rust-docs").default_condition(default)
+ run.alias("rust-docs").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -94,7 +94,7 @@ impl Step for RustcDocs {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
- run.path("rustc-docs").default_condition(builder.config.compiler_docs)
+ run.alias("rustc-docs").default_condition(builder.config.compiler_docs)
}
fn make_run(run: RunConfig<'_>) {
@@ -272,7 +272,7 @@ impl Step for Mingw {
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rust-mingw")
+ run.alias("rust-mingw")
}
fn make_run(run: RunConfig<'_>) {
@@ -313,7 +313,7 @@ impl Step for Rustc {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rustc")
+ run.alias("rustc")
}
fn make_run(run: RunConfig<'_>) {
@@ -456,7 +456,7 @@ impl Step for DebuggerScripts {
type Output = ();
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/lldb_batchmode.py")
+ run.path("src/etc/lldb_batchmode.py")
}
fn make_run(run: RunConfig<'_>) {
@@ -547,7 +547,7 @@ impl Step for Std {
const DEFAULT: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rust-std")
+ run.alias("rust-std")
}
fn make_run(run: RunConfig<'_>) {
@@ -594,7 +594,7 @@ impl Step for RustcDev {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rustc-dev")
+ run.alias("rustc-dev")
}
fn make_run(run: RunConfig<'_>) {
@@ -653,7 +653,7 @@ impl Step for Analysis {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "analysis");
- run.path("rust-analysis").default_condition(default)
+ run.alias("rust-analysis").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -790,7 +790,7 @@ impl Step for Src {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rust-src")
+ run.alias("rust-src")
}
fn make_run(run: RunConfig<'_>) {
@@ -848,7 +848,7 @@ impl Step for PlainSourceTarball {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
- run.path("rustc-src").default_condition(builder.config.rust_dist_src)
+ run.alias("rustc-src").default_condition(builder.config.rust_dist_src)
}
fn make_run(run: RunConfig<'_>) {
@@ -942,7 +942,7 @@ impl Step for Cargo {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "cargo");
- run.path("cargo").default_condition(default)
+ run.alias("cargo").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -998,7 +998,7 @@ impl Step for Rls {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "rls");
- run.path("rls").default_condition(default)
+ run.alias("rls").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1045,7 +1045,7 @@ impl Step for RustAnalyzer {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "rust-analyzer");
- run.path("rust-analyzer").default_condition(default)
+ run.alias("rust-analyzer").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1101,7 +1101,7 @@ impl Step for Clippy {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "clippy");
- run.path("clippy").default_condition(default)
+ run.alias("clippy").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1152,7 +1152,7 @@ impl Step for Miri {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "miri");
- run.path("miri").default_condition(default)
+ run.alias("miri").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1212,7 +1212,7 @@ impl Step for Rustfmt {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "rustfmt");
- run.path("rustfmt").default_condition(default)
+ run.alias("rustfmt").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1271,7 +1271,7 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
// we run the step by default when only `extended = true`, and decide whether to actually
// run it or not later.
let default = run.builder.config.extended;
- run.path("rust-demangler").default_condition(default)
+ run.alias("rust-demangler").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -1324,7 +1324,7 @@ impl Step for Extended {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let builder = run.builder;
- run.path("extended").default_condition(builder.config.extended)
+ run.alias("extended").default_condition(builder.config.extended)
}
fn make_run(run: RunConfig<'_>) {
@@ -1968,7 +1968,8 @@ impl Step for LlvmTools {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let default = should_build_extended_tool(&run.builder, "llvm-tools");
- run.path("llvm-tools").default_condition(default)
+ // FIXME: allow using the names of the tools themselves?
+ run.alias("llvm-tools").default_condition(default)
}
fn make_run(run: RunConfig<'_>) {
@@ -2022,7 +2023,7 @@ impl Step for RustDev {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("rust-dev")
+ run.alias("rust-dev")
}
fn make_run(run: RunConfig<'_>) {
@@ -2098,7 +2099,7 @@ impl Step for BuildManifest {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("build-manifest")
+ run.alias("build-manifest")
}
fn make_run(run: RunConfig<'_>) {
@@ -2130,7 +2131,7 @@ impl Step for ReproducibleArtifacts {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("reproducible-artifacts")
+ run.alias("reproducible-artifacts")
}
fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs
index 27b9196..08e37a1 100644
--- a/src/bootstrap/install.rs
+++ b/src/bootstrap/install.rs
@@ -93,7 +93,7 @@ fn prepare_dir(mut path: PathBuf) -> String {
macro_rules! install {
(($sel:ident, $builder:ident, $_config:ident),
$($name:ident,
- $path:expr,
+ $condition_name: ident = $path_or_alias: literal,
$default_cond:expr,
only_hosts: $only_hosts:expr,
$run_item:block $(, $c:ident)*;)+) => {
@@ -108,7 +108,7 @@ impl $name {
#[allow(dead_code)]
fn should_build(config: &Config) -> bool {
config.extended && config.tools.as_ref()
- .map_or(true, |t| t.contains($path))
+ .map_or(true, |t| t.contains($path_or_alias))
}
}
@@ -120,7 +120,7 @@ impl Step for $name {
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let $_config = &run.builder.config;
- run.path($path).default_condition($default_cond)
+ run.$condition_name($path_or_alias).default_condition($default_cond)
}
fn make_run(run: RunConfig<'_>) {
@@ -138,11 +138,11 @@ fn run($sel, $builder: &Builder<'_>) {
}
install!((self, builder, _config),
- Docs, "src/doc", _config.docs, only_hosts: false, {
+ Docs, path = "src/doc", _config.docs, only_hosts: false, {
let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs");
install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball);
};
- Std, "library/std", true, only_hosts: false, {
+ Std, path = "library/std", true, only_hosts: false, {
for target in &builder.targets {
// `expect` should be safe, only None when host != build, but this
// only runs when host == build
@@ -153,13 +153,13 @@ fn run($sel, $builder: &Builder<'_>) {
install_sh(builder, "std", self.compiler.stage, Some(*target), &tarball);
}
};
- Cargo, "cargo", Self::should_build(_config), only_hosts: true, {
+ Cargo, alias = "cargo", Self::should_build(_config), only_hosts: true, {
let tarball = builder
.ensure(dist::Cargo { compiler: self.compiler, target: self.target })
.expect("missing cargo");
install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball);
};
- Rls, "rls", Self::should_build(_config), only_hosts: true, {
+ Rls, alias = "rls", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) {
install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball);
} else {
@@ -168,7 +168,7 @@ fn run($sel, $builder: &Builder<'_>) {
);
}
};
- RustAnalyzer, "rust-analyzer", Self::should_build(_config), only_hosts: true, {
+ RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) =
builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target })
{
@@ -179,13 +179,13 @@ fn run($sel, $builder: &Builder<'_>) {
);
}
};
- Clippy, "clippy", Self::should_build(_config), only_hosts: true, {
+ Clippy, alias = "clippy", Self::should_build(_config), only_hosts: true, {
let tarball = builder
.ensure(dist::Clippy { compiler: self.compiler, target: self.target })
.expect("missing clippy");
install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball);
};
- Miri, "miri", Self::should_build(_config), only_hosts: true, {
+ Miri, alias = "miri", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) {
install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball);
} else {
@@ -194,7 +194,7 @@ fn run($sel, $builder: &Builder<'_>) {
);
}
};
- Rustfmt, "rustfmt", Self::should_build(_config), only_hosts: true, {
+ Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::Rustfmt {
compiler: self.compiler,
target: self.target
@@ -206,7 +206,7 @@ fn run($sel, $builder: &Builder<'_>) {
);
}
};
- RustDemangler, "rust-demangler", Self::should_build(_config), only_hosts: true, {
+ RustDemangler, alias = "rust-demangler", Self::should_build(_config), only_hosts: true, {
// Note: Even though `should_build` may return true for `extended` default tools,
// dist::RustDemangler may still return None, unless the target-dependent `profiler` config
// is also true, or the `tools` array explicitly includes "rust-demangler".
@@ -222,7 +222,7 @@ fn run($sel, $builder: &Builder<'_>) {
);
}
};
- Analysis, "analysis", Self::should_build(_config), only_hosts: false, {
+ Analysis, alias = "analysis", Self::should_build(_config), only_hosts: false, {
// `expect` should be safe, only None with host != build, but this
// only uses the `build` compiler
let tarball = builder.ensure(dist::Analysis {
@@ -234,7 +234,7 @@ fn run($sel, $builder: &Builder<'_>) {
}).expect("missing analysis");
install_sh(builder, "analysis", self.compiler.stage, Some(self.target), &tarball);
};
- Rustc, "src/librustc", true, only_hosts: true, {
+ Rustc, path = "compiler/rustc", true, only_hosts: true, {
let tarball = builder.ensure(dist::Rustc {
compiler: builder.compiler(builder.top_stage, self.target),
});
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 6d7ca9a..73fb2da 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -122,7 +122,7 @@ impl Step for Llvm {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/llvm-project").path("src/llvm-project/llvm").path("src/llvm")
+ run.path("src/llvm-project").path("src/llvm-project/llvm")
}
fn make_run(run: RunConfig<'_>) {
@@ -605,7 +605,7 @@ impl Step for Lld {
const ONLY_HOSTS: bool = true;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/llvm-project/lld").path("src/tools/lld")
+ run.path("src/llvm-project/lld")
}
fn make_run(run: RunConfig<'_>) {
@@ -771,7 +771,7 @@ impl Step for Sanitizers {
type Output = Vec<SanitizerRuntime>;
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("src/llvm-project/compiler-rt").path("src/sanitizers")
+ run.alias("sanitizers")
}
fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index f60766b..da46890 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1892,7 +1892,8 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
fn make_run(run: RunConfig<'_>) {
let builder = run.builder;
- let compiler = builder.compiler(builder.top_stage, run.build_triple());
+ let host = run.build_triple();
+ let compiler = builder.compiler_for(builder.top_stage, host, host);
let krate = builder.crate_paths[&run.path];
let test_kind = builder.kind.into();
@@ -1929,7 +1930,8 @@ fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
fn make_run(run: RunConfig<'_>) {
let builder = run.builder;
- let compiler = builder.compiler(builder.top_stage, run.build_triple());
+ let host = run.build_triple();
+ let compiler = builder.compiler_for(builder.top_stage, host, host);
let test_kind = builder.kind.into();
let krate = builder.crate_paths[&run.path];
@@ -2288,7 +2290,7 @@ impl Step for Distcheck {
type Output = ();
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("distcheck")
+ run.alias("distcheck")
}
fn make_run(run: RunConfig<'_>) {
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index c7ea254..3ee6a42 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -234,7 +234,7 @@ fn run(self, builder: &Builder<'_>) {
}
fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
- run.path("check-tools")
+ run.alias("check-tools")
}
fn make_run(run: RunConfig<'_>) {
diff --git a/src/doc/book b/src/doc/book
index ea90bba..765318b 160000
--- a/src/doc/book
+++ b/src/doc/book
@@ -1 +1 @@
-Subproject commit ea90bbaf53ba64ef4e2da9ac2352b298aec6bec8
+Subproject commit 765318b844569a642ceef7bf1adab9639cbf6af3
diff --git a/src/doc/nomicon b/src/doc/nomicon
index 11f1165..c7d8467 160000
--- a/src/doc/nomicon
+++ b/src/doc/nomicon
@@ -1 +1 @@
-Subproject commit 11f1165e8a2f5840467e748c8108dc53c948ee9a
+Subproject commit c7d8467ca9158da58ef295ae65dbf00a308752d9
diff --git a/src/doc/reference b/src/doc/reference
index c97d14f..b5f6c23 160000
--- a/src/doc/reference
+++ b/src/doc/reference
@@ -1 +1 @@
-Subproject commit c97d14fa6fed0baa9255432b8a93cb70614f80e3
+Subproject commit b5f6c2362baf932db9440fbfcb509b309237ee85
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
index ec954f3..c2a98d9 160000
--- a/src/doc/rust-by-example
+++ b/src/doc/rust-by-example
@@ -1 +1 @@
-Subproject commit ec954f35eedf592cd173b21c05a7f80a65b61d8a
+Subproject commit c2a98d9fc5d29c481d42052fbeccfde15ed03116
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
index 155126b..eeb5a83 160000
--- a/src/doc/rustc-dev-guide
+++ b/src/doc/rustc-dev-guide
@@ -1 +1 @@
-Subproject commit 155126b1d2e2cb01ddb1d7ba9489b90d7cd173ad
+Subproject commit eeb5a83c15b6ae60df3e4f19207376b22c6fbc4c
diff --git a/src/doc/unstable-book/src/compiler-flags/extern-location.md b/src/doc/unstable-book/src/compiler-flags/extern-location.md
deleted file mode 100644
index 1c80d54..0000000
--- a/src/doc/unstable-book/src/compiler-flags/extern-location.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# `extern-location`
-
-MCP for this feature: [#303]
-
-[#303]: https://github.com/rust-lang/compiler-team/issues/303
-
-------------------------
-
-The `unused-extern-crates` lint reports when a crate was specified on the rustc
-command-line with `--extern name=path` but no symbols were referenced in it.
-This is useful to know, but it's hard to map that back to a specific place a user
-or tool could fix (ie, to remove the unused dependency).
-
-The `--extern-location` flag allows the build system to associate a location with
-the `--extern` option, which is then emitted as part of the diagnostics. This location
-is abstract and just round-tripped through rustc; the compiler never attempts to
-interpret it in any way.
-
-There are two supported forms of location: a bare string, or a blob of json:
-- `--extern-location foo=raw:Makefile:123` would associate the raw string `Makefile:123`
-- `--extern-location 'bar=json:{"target":"//my_project:library","dep":"//common:serde"}` would
- associate the json structure with `--extern bar=<path>`, indicating which dependency of
- which rule introduced the unused extern crate.
-
-This primarily intended to be used with tooling - for example a linter which can automatically
-remove unused dependencies - rather than being directly presented to users.
-
-`raw` locations are presented as part of the normal rendered diagnostics and included in
-the json form. `json` locations are only included in the json form of diagnostics,
-as a `tool_metadata` field. For `raw` locations `tool_metadata` is simply a json string,
-whereas `json` allows the rustc invoker to fully control its form and content.
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index df215f3..269b686 100644
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -423,8 +423,12 @@
else:
actual_str = flatten(actual_tree)
+ # Conditions:
+ # 1. Is --bless
+ # 2. Are actual and expected tree different
+ # 3. Are actual and expected text different
if not expected_str \
- or (not normalize_to_text and
+ or (not normalize_to_text and \
not compare_tree(make_xml(actual_str), make_xml(expected_str), stderr)) \
or (normalize_to_text and actual_str != expected_str):
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 21016af..a070cef 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -15,7 +15,7 @@
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData};
use rustc_middle::middle::resolve_lifetime as rl;
use rustc_middle::ty::fold::TypeFolder;
@@ -1975,7 +1975,7 @@ fn clean_extern_crate(
// this is the ID of the `extern crate` statement
let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE);
// this is the ID of the crate itself
- let crate_def_id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
+ let crate_def_id = cnum.as_def_id();
let attrs = cx.tcx.hir().attrs(krate.hir_id());
let ty_vis = cx.tcx.visibility(krate.def_id);
let please_inline = ty_vis.is_public()
@@ -2094,7 +2094,7 @@ fn clean_use_statement(
} else {
if inline_attr.is_none() {
if let Res::Def(DefKind::Mod, did) = path.res {
- if !did.is_local() && did.index == CRATE_DEF_INDEX {
+ if !did.is_local() && did.is_crate_root() {
// if we're `pub use`ing an extern crate root, don't inline it unless we
// were specifically asked for it
denied = true;
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 4b473df1..95ac3ab6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -20,7 +20,7 @@
use rustc_data_structures::thin_vec::ThinVec;
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{BodyId, Mutability};
use rustc_index::vec::IndexVec;
@@ -104,14 +104,6 @@ impl ItemId {
ItemId::Primitive(_, krate) => krate,
}
}
-
- #[inline]
- crate fn index(self) -> Option<DefIndex> {
- match self {
- ItemId::DefId(id) => Some(id.index),
- _ => None,
- }
- }
}
impl From<DefId> for ItemId {
@@ -160,7 +152,7 @@ impl ExternalCrate {
#[inline]
crate fn def_id(&self) -> DefId {
- DefId { krate: self.crate_num, index: CRATE_DEF_INDEX }
+ self.crate_num.as_def_id()
}
crate fn src(&self, tcx: TyCtxt<'_>) -> FileName {
@@ -217,7 +209,7 @@ fn to_remote(url: impl ToString) -> ExternalLocation {
// Failing that, see if there's an attribute specifying where to find this
// external crate
- let did = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX };
+ let did = self.crate_num.as_def_id();
tcx.get_attrs(did)
.lists(sym::doc)
.filter(|a| a.has_name(sym::html_root_url))
@@ -559,7 +551,7 @@ impl Item {
}
crate fn is_crate(&self) -> bool {
- self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.index == CRATE_DEF_INDEX)
+ self.is_mod() && self.item_id.as_def_id().map_or(false, |did| did.is_crate_root())
}
crate fn is_mod(&self) -> bool {
self.type_() == ItemType::Module
@@ -1097,35 +1089,35 @@ impl Attributes {
attrs: &[ast::Attribute],
additional_attrs: Option<(&[ast::Attribute], DefId)>,
) -> Attributes {
- let mut doc_strings: Vec<DocFragment> = vec![];
- let clean_attr = |(attr, parent_module): (&ast::Attribute, Option<DefId>)| {
- if let Some((value, kind)) = attr.doc_str_and_comment_kind() {
- trace!("got doc_str={:?}", value);
- let value = beautify_doc_string(value, kind);
+ // Additional documentation should be shown before the original documentation.
+ let attrs1 = additional_attrs
+ .into_iter()
+ .flat_map(|(attrs, def_id)| attrs.iter().map(move |attr| (attr, Some(def_id))));
+ let attrs2 = attrs.iter().map(|attr| (attr, None));
+ Attributes::from_ast_iter(attrs1.chain(attrs2), false)
+ }
+
+ crate fn from_ast_iter<'a>(
+ attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>,
+ doc_only: bool,
+ ) -> Attributes {
+ let mut doc_strings = Vec::new();
+ let mut other_attrs = Vec::new();
+ for (attr, parent_module) in attrs {
+ if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() {
+ trace!("got doc_str={doc_str:?}");
+ let doc = beautify_doc_string(doc_str, comment_kind);
let kind = if attr.is_doc_comment() {
DocFragmentKind::SugaredDoc
} else {
DocFragmentKind::RawDoc
};
-
- let frag =
- DocFragment { span: attr.span, doc: value, kind, parent_module, indent: 0 };
-
- doc_strings.push(frag);
-
- None
- } else {
- Some(attr.clone())
+ let fragment = DocFragment { span: attr.span, doc, kind, parent_module, indent: 0 };
+ doc_strings.push(fragment);
+ } else if !doc_only {
+ other_attrs.push(attr.clone());
}
- };
-
- // Additional documentation should be shown before the original documentation
- let other_attrs = additional_attrs
- .into_iter()
- .flat_map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
- .chain(attrs.iter().map(|attr| (attr, None)))
- .filter_map(clean_attr)
- .collect();
+ }
Attributes { doc_strings, other_attrs }
}
@@ -1146,23 +1138,17 @@ impl Attributes {
}
/// Return the doc-comments on this item, grouped by the module they came from.
- ///
/// The module can be different if this is a re-export with added documentation.
- crate fn collapsed_doc_value_by_module_level(&self) -> FxHashMap<Option<DefId>, String> {
- let mut ret = FxHashMap::default();
- if self.doc_strings.len() == 0 {
- return ret;
+ ///
+ /// The last newline is not trimmed so the produced strings are reusable between
+ /// early and late doc link resolution regardless of their position.
+ crate fn prepare_to_doc_link_resolution(&self) -> FxHashMap<Option<DefId>, String> {
+ let mut res = FxHashMap::default();
+ for fragment in &self.doc_strings {
+ let out_str = res.entry(fragment.parent_module).or_default();
+ add_doc_fragment(out_str, fragment);
}
- let last_index = self.doc_strings.len() - 1;
-
- for (i, new_frag) in self.doc_strings.iter().enumerate() {
- let out = ret.entry(new_frag.parent_module).or_default();
- add_doc_fragment(out, new_frag);
- if i == last_index {
- out.pop();
- }
- }
- ret
+ res
}
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index b9e20c4..1db6064 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -4,7 +4,7 @@
use rustc_errors::emitter::{Emitter, EmitterWriter};
use rustc_errors::json::JsonEmitter;
use rustc_feature::UnstableFeatures;
-use rustc_hir::def::Res;
+use rustc_hir::def::{Namespace, Res};
use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{HirId, Path, TraitCandidate};
@@ -29,11 +29,14 @@
use crate::clean::{self, ItemId, TraitWithExtraInfo};
use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions};
use crate::formats::cache::Cache;
+use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink;
use crate::passes::{self, Condition::*};
crate use rustc_session::config::{DebuggingOptions, Input, Options};
crate struct ResolverCaches {
+ crate markdown_links: Option<FxHashMap<String, Vec<PreprocessedMarkdownLink>>>,
+ crate doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<NodeId>>>,
/// Traits in scope for a given module.
/// See `collect_intra_doc_links::traits_implemented_by` for more details.
crate traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 06e7c9e..b4d2772 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -1,7 +1,7 @@
use std::mem;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId};
use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::ty::TyCtxt;
use rustc_span::{sym, Symbol};
@@ -302,7 +302,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
// A crate has a module at its root, containing all items,
// which should not be indexed. The crate-item itself is
// inserted later on when serializing the search-index.
- if item.item_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) {
+ if item.item_id.as_def_id().map_or(false, |idx| !idx.is_crate_root()) {
let desc = item.doc_value().map_or_else(String::new, |x| {
short_markdown_summary(x.as_str(), &item.link_names(self.cache))
});
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 55b0028..fd6d675 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -18,7 +18,6 @@
use rustc_middle::ty;
use rustc_middle::ty::DefIdTree;
use rustc_middle::ty::TyCtxt;
-use rustc_span::def_id::CRATE_DEF_INDEX;
use rustc_span::{sym, Symbol};
use rustc_target::spec::abi::Abi;
@@ -371,7 +370,8 @@ impl clean::Generics {
clause = clause.replace("<br>", &format!("<br>{}", padding));
clause.insert_str(0, &" ".repeat(indent.saturating_sub(1)));
if !end_newline {
- clause.insert_str(0, "<br>");
+ // we insert the <br> after a single space but before multiple spaces at the start
+ clause.insert_str(if indent == 0 { 1 } else { 0 }, "<br>");
}
}
write!(f, "{}", clause)
@@ -1312,7 +1312,7 @@ impl clean::Visibility {
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
- if vis_did.index == CRATE_DEF_INDEX {
+ if vis_did.is_crate_root() {
"pub(crate) ".to_owned()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
@@ -1360,7 +1360,7 @@ impl clean::Visibility {
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(tcx, item_did);
- if vis_did.index == CRATE_DEF_INDEX {
+ if vis_did.is_crate_root() {
"pub(crate) ".to_owned()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 1ebb41b..eafe6f1 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1255,7 +1255,7 @@ fn markdown_summary_with_limit(
pub range: Range<usize>,
}
-crate fn markdown_links(md: &str) -> Vec<MarkdownLink> {
+crate fn markdown_links<R>(md: &str, filter_map: impl Fn(MarkdownLink) -> Option<R>) -> Vec<R> {
if md.is_empty() {
return vec![];
}
@@ -1295,11 +1295,12 @@ fn markdown_summary_with_limit(
let mut push = |link: BrokenLink<'_>| {
let span = span_for_link(&link.reference, link.span);
- links.borrow_mut().push(MarkdownLink {
+ filter_map(MarkdownLink {
kind: LinkType::ShortcutUnknown,
link: link.reference.to_string(),
range: span,
- });
+ })
+ .map(|link| links.borrow_mut().push(link));
None
};
let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push))
@@ -1314,7 +1315,8 @@ fn markdown_summary_with_limit(
if let Event::Start(Tag::Link(kind, dest, _)) = ev.0 {
debug!("found link: {dest}");
let span = span_for_link(&dest, ev.1);
- links.borrow_mut().push(MarkdownLink { kind, link: dest.into_string(), range: span });
+ filter_map(MarkdownLink { kind, link: dest.into_string(), range: span })
+ .map(|link| links.borrow_mut().push(link));
}
}
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 0b5fb48..56b02cd 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -10,7 +10,6 @@
use rustc_ast::ast;
use rustc_hir::{def::CtorKind, def_id::DefId};
use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::def_id::CRATE_DEF_INDEX;
use rustc_span::Pos;
use rustc_target::spec::abi::Abi as RustcAbi;
@@ -83,7 +82,7 @@ fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
match v {
Public => Visibility::Public,
Inherited => Visibility::Default,
- Restricted(did) if did.index == CRATE_DEF_INDEX => Visibility::Crate,
+ Restricted(did) if did.is_crate_root() => Visibility::Crate,
Restricted(did) => Visibility::Restricted {
parent: from_item_id(did.into()),
path: self.tcx.def_path(did).to_string_no_crate_verbose(),
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c48f8bd..42e87f3 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -3,6 +3,7 @@
//! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md
use pulldown_cmark::LinkType;
+use rustc_ast::util::comments::may_have_doc_links;
use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir::def::Namespace::*;
@@ -159,7 +160,7 @@ fn try_from(res: ResolveRes) -> Result<Self, ()> {
}
/// A link failed to resolve.
-#[derive(Debug)]
+#[derive(Clone, Debug)]
enum ResolutionFailure<'a> {
/// This resolved, but with the wrong namespace.
WrongNamespace {
@@ -199,7 +200,7 @@ enum ResolutionFailure<'a> {
Dummy,
}
-#[derive(Debug)]
+#[derive(Clone, Debug)]
enum MalformedGenerics {
/// This link has unbalanced angle brackets.
///
@@ -252,6 +253,7 @@ fn full_res(&self) -> Option<Res> {
}
}
+#[derive(Clone, Copy)]
enum AnchorFailure {
/// User error: `[std#x#y]` is not valid
MultipleAnchors,
@@ -556,7 +558,15 @@ fn resolve_path(
// Resolver doesn't know about true, false, and types that aren't paths (e.g. `()`).
let result = self
.cx
- .enter_resolver(|resolver| resolver.resolve_rustdoc_path(path_str, ns, module_id))
+ .resolver_caches
+ .doc_link_resolutions
+ .get(&(Symbol::intern(path_str), ns, module_id))
+ .copied()
+ .unwrap_or_else(|| {
+ self.cx.enter_resolver(|resolver| {
+ resolver.resolve_rustdoc_path(path_str, ns, module_id)
+ })
+ })
.and_then(|res| res.try_into().ok())
.or_else(|| resolve_primitive(path_str, ns))
.or_else(|| self.resolve_macro_rules(path_str, ns));
@@ -1040,17 +1050,30 @@ fn visit_item(&mut self, item: &Item) {
// In the presence of re-exports, this is not the same as the module of the item.
// Rather than merging all documentation into one, resolve it one attribute at a time
// so we know which module it came from.
- for (parent_module, doc) in item.attrs.collapsed_doc_value_by_module_level() {
+ for (parent_module, doc) in item.attrs.prepare_to_doc_link_resolution() {
+ if !may_have_doc_links(&doc) {
+ continue;
+ }
debug!("combined_docs={}", doc);
// NOTE: if there are links that start in one crate and end in another, this will not resolve them.
// This is a degenerate case and it's not supported by rustdoc.
let parent_node = parent_module.or(parent_node);
- for md_link in markdown_links(&doc) {
+ let mut tmp_links = self
+ .cx
+ .resolver_caches
+ .markdown_links
+ .take()
+ .expect("`markdown_links` are already borrowed");
+ if !tmp_links.contains_key(&doc) {
+ tmp_links.insert(doc.clone(), preprocessed_markdown_links(&doc));
+ }
+ for md_link in &tmp_links[&doc] {
let link = self.resolve_link(&item, &doc, parent_node, md_link);
if let Some(link) = link {
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link);
}
}
+ self.cx.resolver_caches.markdown_links = Some(tmp_links);
}
if item.is_mod() {
@@ -1066,18 +1089,19 @@ fn visit_item(&mut self, item: &Item) {
}
}
-enum PreprocessingError<'a> {
+enum PreprocessingError {
Anchor(AnchorFailure),
Disambiguator(Range<usize>, String),
- Resolution(ResolutionFailure<'a>, String, Option<Disambiguator>),
+ Resolution(ResolutionFailure<'static>, String, Option<Disambiguator>),
}
-impl From<AnchorFailure> for PreprocessingError<'_> {
+impl From<AnchorFailure> for PreprocessingError {
fn from(err: AnchorFailure) -> Self {
Self::Anchor(err)
}
}
+#[derive(Clone)]
struct PreprocessingInfo {
path_str: String,
disambiguator: Option<Disambiguator>,
@@ -1085,15 +1109,18 @@ struct PreprocessingInfo {
link_text: String,
}
+// Not a typedef to avoid leaking several private structures from this module.
+crate struct PreprocessedMarkdownLink(Result<PreprocessingInfo, PreprocessingError>, MarkdownLink);
+
/// Returns:
/// - `None` if the link should be ignored.
/// - `Some(Err)` if the link should emit an error
/// - `Some(Ok)` if the link is valid
///
/// `link_buffer` is needed for lifetime reasons; it will always be overwritten and the contents ignored.
-fn preprocess_link<'a>(
- ori_link: &'a MarkdownLink,
-) -> Option<Result<PreprocessingInfo, PreprocessingError<'a>>> {
+fn preprocess_link(
+ ori_link: &MarkdownLink,
+) -> Option<Result<PreprocessingInfo, PreprocessingError>> {
// [] is mostly likely not supposed to be a link
if ori_link.link.is_empty() {
return None;
@@ -1172,6 +1199,12 @@ fn preprocess_link<'a>(
}))
}
+fn preprocessed_markdown_links(s: &str) -> Vec<PreprocessedMarkdownLink> {
+ markdown_links(s, |link| {
+ preprocess_link(&link).map(|pp_link| PreprocessedMarkdownLink(pp_link, link))
+ })
+}
+
impl LinkCollector<'_, '_> {
/// This is the entry point for resolving an intra-doc link.
///
@@ -1181,8 +1214,9 @@ fn resolve_link(
item: &Item,
dox: &str,
parent_node: Option<DefId>,
- ori_link: MarkdownLink,
+ link: &PreprocessedMarkdownLink,
) -> Option<ItemLink> {
+ let PreprocessedMarkdownLink(pp_link, ori_link) = link;
trace!("considering link '{}'", ori_link.link);
let diag_info = DiagnosticInfo {
@@ -1192,28 +1226,29 @@ fn resolve_link(
link_range: ori_link.range.clone(),
};
- let PreprocessingInfo { ref path_str, disambiguator, extra_fragment, link_text } =
- match preprocess_link(&ori_link)? {
- Ok(x) => x,
- Err(err) => {
- match err {
- PreprocessingError::Anchor(err) => anchor_failure(self.cx, diag_info, err),
- PreprocessingError::Disambiguator(range, msg) => {
- disambiguator_error(self.cx, diag_info, range, &msg)
- }
- PreprocessingError::Resolution(err, path_str, disambiguator) => {
- resolution_failure(
- self,
- diag_info,
- &path_str,
- disambiguator,
- smallvec![err],
- );
- }
+ let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } = match pp_link
+ {
+ Ok(x) => x,
+ Err(err) => {
+ match err {
+ PreprocessingError::Anchor(err) => anchor_failure(self.cx, diag_info, *err),
+ PreprocessingError::Disambiguator(range, msg) => {
+ disambiguator_error(self.cx, diag_info, range.clone(), msg)
}
- return None;
+ PreprocessingError::Resolution(err, path_str, disambiguator) => {
+ resolution_failure(
+ self,
+ diag_info,
+ path_str,
+ *disambiguator,
+ smallvec![err.clone()],
+ );
+ }
}
- };
+ return None;
+ }
+ };
+ let disambiguator = *disambiguator;
let inner_docs = item.inner_docs(self.cx.tcx);
@@ -1250,7 +1285,7 @@ fn resolve_link(
module_id,
dis: disambiguator,
path_str: path_str.to_owned(),
- extra_fragment,
+ extra_fragment: extra_fragment.clone(),
},
diag_info.clone(), // this struct should really be Copy, but Range is not :(
matches!(ori_link.kind, LinkType::Reference | LinkType::Shortcut),
@@ -1320,8 +1355,8 @@ fn resolve_link(
}
Some(ItemLink {
- link: ori_link.link,
- link_text,
+ link: ori_link.link.clone(),
+ link_text: link_text.clone(),
did: res.def_id(self.cx.tcx),
fragment,
})
@@ -1343,7 +1378,12 @@ fn resolve_link(
&diag_info,
)?;
let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
- Some(ItemLink { link: ori_link.link, link_text, did: id, fragment })
+ Some(ItemLink {
+ link: ori_link.link.clone(),
+ link_text: link_text.clone(),
+ did: id,
+ fragment,
+ })
}
}
}
diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs
index dffceff..e2359da 100644
--- a/src/librustdoc/passes/collect_intra_doc_links/early.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs
@@ -1,19 +1,20 @@
use crate::clean::Attributes;
use crate::core::ResolverCaches;
-use crate::html::markdown::markdown_links;
-use crate::passes::collect_intra_doc_links::preprocess_link;
+use crate::passes::collect_intra_doc_links::preprocessed_markdown_links;
+use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink;
use rustc_ast::visit::{self, AssocCtxt, Visitor};
use rustc_ast::{self as ast, ItemKind};
use rustc_ast_lowering::ResolverAstLowering;
-use rustc_hir::def::Namespace::TypeNS;
-use rustc_hir::def::{DefKind, Res};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def::Namespace::*;
+use rustc_hir::def::{DefKind, Namespace, Res};
use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, CRATE_DEF_ID};
use rustc_hir::TraitCandidate;
use rustc_middle::ty::{DefIdTree, Visibility};
use rustc_resolve::{ParentScope, Resolver};
use rustc_session::config::Externs;
-use rustc_span::SyntaxContext;
+use rustc_span::{Symbol, SyntaxContext};
use std::collections::hash_map::Entry;
use std::mem;
@@ -28,6 +29,8 @@
resolver,
current_mod: CRATE_DEF_ID,
visited_mods: Default::default(),
+ markdown_links: Default::default(),
+ doc_link_resolutions: Default::default(),
traits_in_scope: Default::default(),
all_traits: Default::default(),
all_trait_impls: Default::default(),
@@ -36,7 +39,7 @@
// Overridden `visit_item` below doesn't apply to the crate root,
// so we have to visit its attributes and reexports separately.
- link_resolver.load_links_in_attrs(&krate.attrs);
+ link_resolver.resolve_doc_links_local(&krate.attrs);
link_resolver.process_module_children_or_reexports(CRATE_DEF_ID.to_def_id());
visit::walk_crate(&mut link_resolver, krate);
link_resolver.process_extern_impls();
@@ -50,6 +53,8 @@
}
ResolverCaches {
+ markdown_links: Some(link_resolver.markdown_links),
+ doc_link_resolutions: link_resolver.doc_link_resolutions,
traits_in_scope: link_resolver.traits_in_scope,
all_traits: Some(link_resolver.all_traits),
all_trait_impls: Some(link_resolver.all_trait_impls),
@@ -57,10 +62,18 @@
}
}
+fn doc_attrs<'a>(attrs: impl Iterator<Item = &'a ast::Attribute>) -> Attributes {
+ let mut attrs = Attributes::from_ast_iter(attrs.map(|attr| (attr, None)), true);
+ attrs.unindent_doc_comments();
+ attrs
+}
+
struct EarlyDocLinkResolver<'r, 'ra> {
resolver: &'r mut Resolver<'ra>,
current_mod: LocalDefId,
visited_mods: DefIdSet,
+ markdown_links: FxHashMap<String, Vec<PreprocessedMarkdownLink>>,
+ doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<ast::NodeId>>>,
traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
all_traits: Vec<DefId>,
all_trait_impls: Vec<DefId>,
@@ -92,18 +105,11 @@ fn add_traits_in_scope(&mut self, def_id: DefId) {
}
}
- fn add_traits_in_parent_scope(&mut self, def_id: DefId) {
- if let Some(module_id) = self.resolver.parent(def_id) {
- self.add_traits_in_scope(module_id);
- }
- }
-
/// Add traits in scope for links in impls collected by the `collect-intra-doc-links` pass.
/// That pass filters impls using type-based information, but we don't yet have such
/// information here, so we just conservatively calculate traits in scope for *all* modules
/// having impls in them.
fn process_extern_impls(&mut self) {
- // FIXME: Need to resolve doc links on all these impl and trait items below.
// Resolving links in already existing crates may trigger loading of new crates.
let mut start_cnum = 0;
loop {
@@ -124,7 +130,7 @@ fn process_extern_impls(&mut self) {
// the current crate, and links in their doc comments are not resolved.
for &def_id in &all_traits {
if self.resolver.cstore().visibility_untracked(def_id) == Visibility::Public {
- self.add_traits_in_parent_scope(def_id);
+ self.resolve_doc_links_extern_impl(def_id, false);
}
}
for &(trait_def_id, impl_def_id, simplified_self_ty) in &all_trait_impls {
@@ -135,17 +141,17 @@ fn process_extern_impls(&mut self) {
== Visibility::Public
})
{
- self.add_traits_in_parent_scope(impl_def_id);
+ self.resolve_doc_links_extern_impl(impl_def_id, false);
}
}
for (ty_def_id, impl_def_id) in all_inherent_impls {
if self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public
{
- self.add_traits_in_parent_scope(impl_def_id);
+ self.resolve_doc_links_extern_impl(impl_def_id, true);
}
}
- for def_id in all_incoherent_impls {
- self.add_traits_in_parent_scope(def_id);
+ for impl_def_id in all_incoherent_impls {
+ self.resolve_doc_links_extern_impl(impl_def_id, true);
}
self.all_traits.extend(all_traits);
@@ -161,16 +167,55 @@ fn process_extern_impls(&mut self) {
}
}
- fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute]) {
+ fn resolve_doc_links_extern_impl(&mut self, def_id: DefId, _is_inherent: bool) {
+ // FIXME: Resolve links in associated items in addition to traits themselves,
+ // `force` is used to provide traits in scope for the associated items.
+ self.resolve_doc_links_extern_outer(def_id, def_id, true);
+ }
+
+ fn resolve_doc_links_extern_outer(&mut self, def_id: DefId, scope_id: DefId, force: bool) {
+ if !force && !self.resolver.cstore().may_have_doc_links_untracked(def_id) {
+ return;
+ }
+ // FIXME: actually resolve links, not just add traits in scope.
+ if let Some(parent_id) = self.resolver.parent(scope_id) {
+ self.add_traits_in_scope(parent_id);
+ }
+ }
+
+ fn resolve_doc_links_extern_inner(&mut self, def_id: DefId) {
+ if !self.resolver.cstore().may_have_doc_links_untracked(def_id) {
+ return;
+ }
+ // FIXME: actually resolve links, not just add traits in scope.
+ self.add_traits_in_scope(def_id);
+ }
+
+ fn resolve_doc_links_local(&mut self, attrs: &[ast::Attribute]) {
+ if !attrs.iter().any(|attr| attr.may_have_doc_links()) {
+ return;
+ }
let module_id = self.current_mod.to_def_id();
+ self.resolve_doc_links(doc_attrs(attrs.iter()), module_id);
+ }
+
+ fn resolve_doc_links(&mut self, attrs: Attributes, module_id: DefId) {
let mut need_traits_in_scope = false;
- for (doc_module, doc) in
- Attributes::from_ast(attrs, None).collapsed_doc_value_by_module_level()
- {
+ for (doc_module, doc) in attrs.prepare_to_doc_link_resolution() {
assert_eq!(doc_module, None);
- for link in markdown_links(&doc.as_str()) {
- if let Some(Ok(pinfo)) = preprocess_link(&link) {
- self.resolver.resolve_rustdoc_path(&pinfo.path_str, TypeNS, module_id);
+ let links = self
+ .markdown_links
+ .entry(doc)
+ .or_insert_with_key(|doc| preprocessed_markdown_links(doc));
+ for PreprocessedMarkdownLink(pp_link, _) in links {
+ if let Ok(pinfo) = pp_link {
+ // FIXME: Resolve the path in all namespaces and resolve its prefixes too.
+ let ns = TypeNS;
+ self.doc_link_resolutions
+ .entry((Symbol::intern(&pinfo.path_str), ns, module_id))
+ .or_insert_with_key(|(path, ns, module_id)| {
+ self.resolver.resolve_rustdoc_path(path.as_str(), *ns, *module_id)
+ });
need_traits_in_scope = true;
}
}
@@ -197,15 +242,13 @@ fn process_module_children_or_reexports(&mut self, module_id: DefId) {
&& module_id.is_local()
{
if let Some(def_id) = child.res.opt_def_id() && !def_id.is_local() {
- // FIXME: Need to resolve doc links on all these extern items
- // reached through reexports.
let scope_id = match child.res {
Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id).unwrap(),
_ => def_id,
};
- self.add_traits_in_parent_scope(scope_id); // Outer attribute scope
+ self.resolve_doc_links_extern_outer(def_id, scope_id, false); // Outer attribute scope
if let Res::Def(DefKind::Mod, ..) = child.res {
- self.add_traits_in_scope(def_id); // Inner attribute scope
+ self.resolve_doc_links_extern_inner(def_id); // Inner attribute scope
}
// Traits are processed in `add_extern_traits_in_scope`.
if let Res::Def(DefKind::Mod | DefKind::Enum, ..) = child.res {
@@ -219,10 +262,10 @@ fn process_module_children_or_reexports(&mut self, module_id: DefId) {
impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> {
fn visit_item(&mut self, item: &ast::Item) {
- self.load_links_in_attrs(&item.attrs); // Outer attribute scope
+ self.resolve_doc_links_local(&item.attrs); // Outer attribute scope
if let ItemKind::Mod(..) = item.kind {
let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id));
- self.load_links_in_attrs(&item.attrs); // Inner attribute scope
+ self.resolve_doc_links_local(&item.attrs); // Inner attribute scope
self.process_module_children_or_reexports(self.current_mod.to_def_id());
visit::walk_item(self, item);
self.current_mod = old_mod;
@@ -241,22 +284,22 @@ fn visit_item(&mut self, item: &ast::Item) {
}
fn visit_assoc_item(&mut self, item: &ast::AssocItem, ctxt: AssocCtxt) {
- self.load_links_in_attrs(&item.attrs);
+ self.resolve_doc_links_local(&item.attrs);
visit::walk_assoc_item(self, item, ctxt)
}
fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
- self.load_links_in_attrs(&item.attrs);
+ self.resolve_doc_links_local(&item.attrs);
visit::walk_foreign_item(self, item)
}
fn visit_variant(&mut self, v: &ast::Variant) {
- self.load_links_in_attrs(&v.attrs);
+ self.resolve_doc_links_local(&v.attrs);
visit::walk_variant(self, v)
}
fn visit_field_def(&mut self, field: &ast::FieldDef) {
- self.load_links_in_attrs(&field.attrs);
+ self.resolve_doc_links_local(&field.attrs);
visit::walk_field_def(self, field)
}
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 5bcec77..9723cdb 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -1,6 +1,6 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir::def::{DefKind, Res};
-use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
+use rustc_hir::def_id::{CrateNum, DefId};
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
use rustc_middle::ty::TyCtxt;
@@ -29,7 +29,7 @@ impl<'a, 'tcx> LibEmbargoVisitor<'a, 'tcx> {
}
crate fn visit_lib(&mut self, cnum: CrateNum) {
- let did = DefId { krate: cnum, index: CRATE_DEF_INDEX };
+ let did = cnum.as_def_id();
self.update(did, Some(AccessLevel::Public));
self.visit_mod(did);
}
diff --git a/src/llvm-project b/src/llvm-project
index 9168e23..fd33681 160000
--- a/src/llvm-project
+++ b/src/llvm-project
@@ -1 +1 @@
-Subproject commit 9168e236c548d1d0e9938ee6dd4cdbd308fdfd72
+Subproject commit fd336816c3a6d228dcef22171c43140f6fa7656f
diff --git a/src/test/codegen/asm-clobber_abi.rs b/src/test/codegen/asm-clobber_abi.rs
index 69e3527..a87152e 100644
--- a/src/test/codegen/asm-clobber_abi.rs
+++ b/src/test/codegen/asm-clobber_abi.rs
@@ -6,21 +6,21 @@
use std::arch::asm;
// CHECK-LABEL: @clobber_sysv64
-// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
+// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle]
pub unsafe fn clobber_sysv64() {
asm!("", clobber_abi("sysv64"));
}
// CHECK-LABEL: @clobber_win64
-// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
+// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle]
pub unsafe fn clobber_win64() {
asm!("", clobber_abi("win64"));
}
// CHECK-LABEL: @clobber_sysv64
-// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
+// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle]
pub unsafe fn clobber_sysv64_edx() {
let foo: i32;
@@ -28,7 +28,7 @@ pub unsafe fn clobber_sysv64_edx() {
}
// CHECK-LABEL: @clobber_win64
-// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
+// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory}
#[no_mangle]
pub unsafe fn clobber_win64_edx() {
let foo: i32;
diff --git a/src/test/codegen/set-discriminant-invalid.rs b/src/test/codegen/set-discriminant-invalid.rs
index d9614f0..bccb9e4 100644
--- a/src/test/codegen/set-discriminant-invalid.rs
+++ b/src/test/codegen/set-discriminant-invalid.rs
@@ -28,7 +28,7 @@ impl IntoError<Error> for Api
#[no_mangle]
fn into_error(self, error: Self::Source) -> Error {
Error::Api {
- source: (|v| v)(error),
+ source: error,
}
}
}
diff --git a/src/test/codegen/vec-in-place.rs b/src/test/codegen/vec-in-place.rs
index a656c9e..13c41f7 100644
--- a/src/test/codegen/vec-in-place.rs
+++ b/src/test/codegen/vec-in-place.rs
@@ -1,13 +1,72 @@
+// min-llvm-version: 14.0
// ignore-debug: the debug assertions get in the way
-// compile-flags: -O
+// compile-flags: -O -Z merge-functions=disabled
#![crate_type = "lib"]
// Ensure that trivial casts of vec elements are O(1)
-// CHECK-LABEL: @vec_iterator_cast
+pub struct Wrapper<T>(T);
+
+#[repr(C)]
+pub struct Foo {
+ a: u64,
+ b: u64,
+ c: u64,
+ d: u64,
+}
+
+// Going from an aggregate struct to another type currently requires Copy to
+// enable the TrustedRandomAccess specialization. Without it optimizations do not yet
+// reliably recognize the loops as noop for for repr(C) or non-Copy structs.
+#[derive(Copy, Clone)]
+pub struct Bar {
+ a: u64,
+ b: u64,
+ c: u64,
+ d: u64,
+}
+
+// CHECK-LABEL: @vec_iterator_cast_primitive
#[no_mangle]
-pub fn vec_iterator_cast(vec: Vec<isize>) -> Vec<usize> {
+pub fn vec_iterator_cast_primitive(vec: Vec<i8>) -> Vec<u8> {
// CHECK-NOT: loop
// CHECK-NOT: call
- vec.into_iter().map(|e| e as usize).collect()
+ vec.into_iter().map(|e| e as u8).collect()
+}
+
+// CHECK-LABEL: @vec_iterator_cast_wrapper
+#[no_mangle]
+pub fn vec_iterator_cast_wrapper(vec: Vec<u8>) -> Vec<Wrapper<u8>> {
+ // CHECK-NOT: loop
+ // CHECK-NOT: call
+ vec.into_iter().map(|e| Wrapper(e)).collect()
+}
+
+// CHECK-LABEL: @vec_iterator_cast_unwrap
+#[no_mangle]
+pub fn vec_iterator_cast_unwrap(vec: Vec<Wrapper<u8>>) -> Vec<u8> {
+ // CHECK-NOT: loop
+ // CHECK-NOT: call
+ vec.into_iter().map(|e| e.0).collect()
+}
+
+// CHECK-LABEL: @vec_iterator_cast_aggregate
+#[no_mangle]
+pub fn vec_iterator_cast_aggregate(vec: Vec<[u64; 4]>) -> Vec<Foo> {
+ // CHECK-NOT: loop
+ // CHECK-NOT: call
+ vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect()
+}
+
+// CHECK-LABEL: @vec_iterator_cast_deaggregate
+#[no_mangle]
+pub fn vec_iterator_cast_deaggregate(vec: Vec<Bar>) -> Vec<[u64; 4]> {
+ // CHECK-NOT: loop
+ // CHECK-NOT: call
+
+ // Safety: For the purpose of this test we assume that Bar layout matches [u64; 4].
+ // This currently is not guaranteed for repr(Rust) types, but it happens to work here and
+ // the UCG may add additional guarantees for homogenous types in the future that would make this
+ // correct.
+ vec.into_iter().map(|e| unsafe { std::mem::transmute(e) }).collect()
}
diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
index bea3307..3b890e4 100644
--- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
+++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff
@@ -4,21 +4,22 @@
fn h() -> () {
let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12
let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
-+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
-+ let mut _9: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16
-+ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16
++ let mut _2: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
++ let mut _3: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
++ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16
++ let mut _11: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22
-+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37
-+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
-+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14
-+ let mut _7: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7
-+ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10
++ debug f => _3; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37
++ let _4: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
++ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14
++ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7
++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10
+ scope 2 {
-+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10
-+ let _5: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10
++ debug a => _4; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10
++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10
+ scope 3 {
-+ debug b => _5; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10
++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10
+ }
+ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16
+ scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL
@@ -33,27 +34,25 @@
bb0: {
StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
-- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep) -> bb1; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+- call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
+ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
-+ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
++ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
++ _3 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22
// mir::Constant
- // + span: $DIR/inline-diverging.rs:22:5: 22:15
- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(Scalar(<ZST>)) }
- // mir::Constant
// + span: $DIR/inline-diverging.rs:22:16: 22:21
// + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) }
-+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
-+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
-+ StorageLive(_9); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
-+ _9 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10
++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ _5 = &_3; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14
++ StorageLive(_10); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
++ _10 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
- }
-
- bb1: {
-- StorageDead(_1); // scope 0 at $DIR/inline-diverging.rs:22:22: 22:23
-- _0 = const (); // scope 0 at $DIR/inline-diverging.rs:21:12: 23:2
-- return; // scope 0 at $DIR/inline-diverging.rs:23:2: 23:2
++ }
++
++ bb1: {
+ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12
}
}
diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
index 5fb57c2..4aff444 100644
--- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
+++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir
@@ -21,7 +21,7 @@
StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10
StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43
_3 = (); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43
- _2 = transmute::<(), Void>(move _3) -> [return: bb1, unwind: bb4]; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44
+ transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44
// mir::Constant
// + span: $DIR/issue-72181-1.rs:17:9: 17:40
// + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(Scalar(<ZST>)) }
diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs
index 9465e8e7..7a5156e 100644
--- a/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs
+++ b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs
@@ -1,7 +1,7 @@
// normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL"
+// check-pass
#![deny(warnings)]
//! Email me at <hello@localhost>.
-//~^ ERROR unknown disambiguator `hello`
//! This should *not* warn: <hello@example.com>.
diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr b/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr
deleted file mode 100644
index 1b07828..0000000
--- a/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error: unknown disambiguator `hello`
- --> $DIR/email-address-localhost.rs:4:18
- |
-LL | //! Email me at <hello@localhost>.
- | ^^^^^
- |
-note: the lint level is defined here
- --> $DIR/email-address-localhost.rs:2:9
- |
-LL | #![deny(warnings)]
- | ^^^^^^^^
- = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]`
- = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
-
-error: aborting due to previous error
-
diff --git a/src/test/rustdoc/early-unindent.rs b/src/test/rustdoc/early-unindent.rs
new file mode 100644
index 0000000..791a452
--- /dev/null
+++ b/src/test/rustdoc/early-unindent.rs
@@ -0,0 +1,26 @@
+// This is a regression for https://github.com/rust-lang/rust/issues/96079.
+
+#![crate_name = "foo"]
+
+pub mod app {
+ pub struct S;
+
+ impl S {
+ // @has 'foo/app/struct.S.html'
+ // @has - '//a[@href="../enums/enum.Foo.html#method.by_name"]' 'Foo::by_name'
+ /**
+ Doc comment hello! [`Foo::by_name`](`crate::enums::Foo::by_name`).
+ */
+ pub fn whatever(&self) {}
+ }
+}
+
+pub mod enums {
+ pub enum Foo {
+ Bar,
+ }
+
+ impl Foo {
+ pub fn by_name(&self) {}
+ }
+}
diff --git a/src/test/rustdoc/where.SWhere_Simd_item-decl.html b/src/test/rustdoc/where.SWhere_Simd_item-decl.html
new file mode 100644
index 0000000..0133bca
--- /dev/null
+++ b/src/test/rustdoc/where.SWhere_Simd_item-decl.html
@@ -0,0 +1 @@
+<div class="docblock item-decl"><pre class="rust struct"><code>pub struct Simd<T>(_) <br /><span class="where">where<br />    T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre></div>
\ No newline at end of file
diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
new file mode 100644
index 0000000..54026ff
--- /dev/null
+++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html
@@ -0,0 +1,3 @@
+<div class="docblock item-decl"><pre class="rust trait"><code>pub trait TraitWhere {
+ type <a href="#associatedtype.Item" class="associatedtype">Item</a><'a><br />    <span class="where">where<br />        Self: 'a</span>;
+}</code></pre></div>
\ No newline at end of file
diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs
index 549cfff..50a5722 100644
--- a/src/test/rustdoc/where.rs
+++ b/src/test/rustdoc/where.rs
@@ -1,3 +1,4 @@
+#![feature(generic_associated_types)]
#![crate_name = "foo"]
pub trait MyTrait { fn dummy(&self) { } }
@@ -19,6 +20,18 @@ pub fn delta() {}
pub struct Echo<E>(E);
+// @has 'foo/struct.Simd.html'
+// @snapshot SWhere_Simd_item-decl - '//div[@class="docblock item-decl"]'
+pub struct Simd<T>([T; 1])
+where
+ T: MyTrait;
+
+// @has 'foo/trait.TraitWhere.html'
+// @snapshot SWhere_TraitWhere_item-decl - '//div[@class="docblock item-decl"]'
+pub trait TraitWhere {
+ type Item<'a> where Self: 'a;
+}
+
// @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \
// "impl<E> MyTrait for Echo<E> where E: MyTrait"
// @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \
diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs
index 4c4ce8b..272372e 100644
--- a/src/test/ui/asm/x86_64/bad-reg.rs
+++ b/src/test/ui/asm/x86_64/bad-reg.rs
@@ -29,13 +29,13 @@ fn main() {
//~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand
asm!("", in("ip") foo);
//~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand
- asm!("", in("k0") foo);
- //~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand
asm!("", in("st(2)") foo);
//~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output
asm!("", in("mm0") foo);
//~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output
+ asm!("", in("k0") foo);
+ //~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output
asm!("", out("st(2)") _);
asm!("", out("mm0") _);
asm!("{}", in(x87_reg) foo);
diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr
index f8b024e..84b8b5e 100644
--- a/src/test/ui/asm/x86_64/bad-reg.stderr
+++ b/src/test/ui/asm/x86_64/bad-reg.stderr
@@ -64,24 +64,24 @@
LL | asm!("", in("ip") foo);
| ^^^^^^^^^^^^
-error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm
- --> $DIR/bad-reg.rs:32:18
- |
-LL | asm!("", in("k0") foo);
- | ^^^^^^^^^^^^
-
error: register class `x87_reg` can only be used as a clobber, not as an input or output
- --> $DIR/bad-reg.rs:35:18
+ --> $DIR/bad-reg.rs:33:18
|
LL | asm!("", in("st(2)") foo);
| ^^^^^^^^^^^^^^^
error: register class `mmx_reg` can only be used as a clobber, not as an input or output
- --> $DIR/bad-reg.rs:37:18
+ --> $DIR/bad-reg.rs:35:18
|
LL | asm!("", in("mm0") foo);
| ^^^^^^^^^^^^^
+error: register class `kreg0` can only be used as a clobber, not as an input or output
+ --> $DIR/bad-reg.rs:37:18
+ |
+LL | asm!("", in("k0") foo);
+ | ^^^^^^^^^^^^
+
error: register class `x87_reg` can only be used as a clobber, not as an input or output
--> $DIR/bad-reg.rs:41:20
|
diff --git a/src/test/ui/async-await/issues/issue-67893.rs b/src/test/ui/async-await/issues/issue-67893.rs
index 8b53408..d73772e 100644
--- a/src/test/ui/async-await/issues/issue-67893.rs
+++ b/src/test/ui/async-await/issues/issue-67893.rs
@@ -7,5 +7,5 @@ fn g(_: impl Send) {}
fn main() {
g(issue_67893::run())
- //~^ ERROR generator cannot be sent between threads safely
+ //~^ ERROR future cannot be sent between threads safely
}
diff --git a/src/test/ui/async-await/issues/issue-67893.stderr b/src/test/ui/async-await/issues/issue-67893.stderr
index 0aa0d5d..316b6d0 100644
--- a/src/test/ui/async-await/issues/issue-67893.stderr
+++ b/src/test/ui/async-await/issues/issue-67893.stderr
@@ -1,10 +1,22 @@
-error: generator cannot be sent between threads safely
+error: future cannot be sent between threads safely
--> $DIR/issue-67893.rs:9:7
|
LL | g(issue_67893::run())
- | ^^^^^^^^^^^^^^^^^^ generator is not `Send`
+ | ^^^^^^^^^^^^^^^^^^ future is not `Send`
|
= help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
+note: future is not `Send` as this value is used across an await
+ --> $DIR/auxiliary/issue_67893.rs:9:26
+ |
+LL | f(*x.lock().unwrap()).await;
+ | ----------------- ^^^^^^ await occurs here, with `x.lock().unwrap()` maybe used later
+ | |
+ | has type `MutexGuard<'_, ()>` which is not `Send`
+note: `x.lock().unwrap()` is later dropped here
+ --> $DIR/auxiliary/issue_67893.rs:9:32
+ |
+LL | f(*x.lock().unwrap()).await;
+ | ^
note: required by a bound in `g`
--> $DIR/issue-67893.rs:6:14
|
diff --git a/src/test/ui/const-generics/issues/issue-87493.stderr b/src/test/ui/const-generics/issues/issue-87493.stderr
index 8f92eea..f998c11 100644
--- a/src/test/ui/const-generics/issues/issue-87493.stderr
+++ b/src/test/ui/const-generics/issues/issue-87493.stderr
@@ -13,7 +13,7 @@
--> $DIR/issue-87493.rs:8:8
|
LL | T: MyTrait<Assoc == S::Assoc>,
- | ^^^^^^^------------------- help: remove these generics
+ | ^^^^^^^ ----------------- help: replace the generic bound with the associated type: `Assoc = Assoc == S::Assoc`
| |
| expected 0 generic arguments
|
diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
index 111d243..b60bac5 100644
--- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr
@@ -119,27 +119,17 @@
78 00 00 00 ff ff ff ff │ x.......
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:92:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:92:77
|
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of uninhabited type Never
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 00 00 00 00 00 00 00 00 │ ........
- }
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:94:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:94:77
|
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of the never type `!`
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 00 00 00 00 00 00 00 00 │ ........
- }
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error: aborting due to 13 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
index eee132b..1d81e2b 100644
--- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
+++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr
@@ -119,27 +119,17 @@
78 00 00 00 ff ff ff ff │ x.......
}
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:92:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:92:77
|
LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of uninhabited type Never
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 00 00 00 00 00 00 00 00 │ ........
- }
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/ub-enum.rs:94:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:94:77
|
LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of the never type `!`
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 8, align: 4) {
- 00 00 00 00 00 00 00 00 │ ........
- }
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
error: aborting due to 13 previous errors
diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs
index e408d8e..8628868 100644
--- a/src/test/ui/consts/const-eval/ub-enum.rs
+++ b/src/test/ui/consts/const-eval/ub-enum.rs
@@ -90,9 +90,9 @@ enum UninhDiscriminant {
// All variants are uninhabited but also have data.
// Use `0` as constant to make behavior endianess-independent.
const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
-//~^ ERROR is undefined behavior
+//~^ ERROR evaluation of constant value failed
const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
-//~^ ERROR is undefined behavior
+//~^ ERROR evaluation of constant value failed
fn main() {
}
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
index 7dc1ec8..bbb8511 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -10,14 +10,11 @@
LL | const FOO: [Empty; 3] = [foo(); 3];
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/validate_uninhabited_zsts.rs:16:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/validate_uninhabited_zsts.rs:16:35
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 0, align: 1) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
warning: the type `!` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:4:14
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
index 7dc1ec8..bbb8511 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -10,14 +10,11 @@
LL | const FOO: [Empty; 3] = [foo(); 3];
| ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/validate_uninhabited_zsts.rs:16:1
+error[E0080]: evaluation of constant value failed
+ --> $DIR/validate_uninhabited_zsts.rs:16:35
|
LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 0, align: 1) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
warning: the type `!` does not permit zero-initialization
--> $DIR/validate_uninhabited_zsts.rs:4:14
diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs
index 3465048..990d5a3 100644
--- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs
+++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs
@@ -14,7 +14,7 @@ enum Empty { }
#[warn(const_err)]
const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
-//~^ ERROR it is undefined behavior to use this value
+//~^ ERROR evaluation of constant value failed
//~| WARN the type `Empty` does not permit zero-initialization
fn main() {
diff --git a/src/test/ui/error-codes/E0107.rs b/src/test/ui/error-codes/E0107.rs
index 840700c..d369fc2 100644
--- a/src/test/ui/error-codes/E0107.rs
+++ b/src/test/ui/error-codes/E0107.rs
@@ -47,4 +47,14 @@ struct Baz<'a, 'b, 'c> {
//~| HELP remove this lifetime argument
}
+pub trait T {
+ type A;
+ type B;
+}
+
+fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
+ //~^ ERROR this trait takes 0 generic arguments
+ //~| HELP replace the generic bounds with the associated types
+}
+
fn main() {}
diff --git a/src/test/ui/error-codes/E0107.stderr b/src/test/ui/error-codes/E0107.stderr
index c90f85d..5ca03b4 100644
--- a/src/test/ui/error-codes/E0107.stderr
+++ b/src/test/ui/error-codes/E0107.stderr
@@ -128,6 +128,22 @@
LL | struct Quux<T>(T);
| ^^^^
-error: aborting due to 9 previous errors
+error[E0107]: this trait takes 0 generic arguments but 2 generic arguments were supplied
+ --> $DIR/E0107.rs:55:27
+ |
+LL | fn trait_bound_generic<I: T<u8, u16>>(_i: I) {
+ | ^ expected 0 generic arguments
+ |
+note: trait defined here, with 0 generic parameters
+ --> $DIR/E0107.rs:50:11
+ |
+LL | pub trait T {
+ | ^
+help: replace the generic bounds with the associated types
+ |
+LL | fn trait_bound_generic<I: T<A = u8, B = u16>>(_i: I) {
+ | ~~~~~~ ~~~~~~~
+
+error: aborting due to 10 previous errors
For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/generator/issue-93161.rs b/src/test/ui/generator/issue-93161.rs
index 9988acb..9230560 100644
--- a/src/test/ui/generator/issue-93161.rs
+++ b/src/test/ui/generator/issue-93161.rs
@@ -1,5 +1,6 @@
// edition:2021
// run-pass
+// compile-flags: -Zdrop-tracking
#![feature(never_type)]
@@ -32,7 +33,7 @@ fn never() -> Never {
}
async fn includes_never(crash: bool, x: u32) -> u32 {
- let mut result = async { x * x }.await;
+ let result = async { x * x }.await;
if !crash {
return result;
}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr
similarity index 94%
rename from src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
rename to src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr
index 299a2d2..7985bf2 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:52
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ---- ---- ^ ...but data from `f` is returned here
@@ -7,7 +7,7 @@
| this parameter and the return type are declared with different lifetimes...
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:82
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:82
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ---- ----------------- ^ ...but data from `f` is returned here
@@ -15,7 +15,7 @@
| this parameter and the return type are declared with different lifetimes...
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:22:64
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| ------ --- ^^^ ...but data from `arg` is returned here
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
index 57374b7..8a55a7c 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:52
|
LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| - - ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
@@ -8,7 +8,7 @@
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:15:75
|
LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| - - ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
@@ -17,7 +17,7 @@
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:22:64
|
LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| -- - ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
index f42337d..c54f796 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
use std::pin::Pin;
@@ -6,15 +9,19 @@
impl Foo {
async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
- //~^ ERROR lifetime mismatch
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ lifetime may not live long enough
async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
- //~^ ERROR lifetime mismatch
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ lifetime may not live long enough
}
type Alias<T> = Pin<T>;
impl Foo {
- async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
+ async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+ //[base]~^ ERROR E0623
+ //[nll]~^^ lifetime may not live long enough
}
fn main() {}
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.base.stderr
similarity index 90%
rename from src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
rename to src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.base.stderr
index 64a5746..c0e2f0b 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:46
|
LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| ---- ---- ^ ...but data from `f` is returned here
@@ -13,7 +13,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:76
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:14:76
|
LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| ---- ----------------- ^ ...but data from `f` is returned here
@@ -27,7 +27,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:21:58
|
LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| ------ --- ^^^ ...but data from `arg` is returned here
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
index 92241b2..b06ebf7 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:10:46
|
LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
| - - ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
@@ -8,7 +8,7 @@
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:69
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:14:69
|
LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
| - - ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
@@ -17,7 +17,7 @@
| let's call the lifetime of this reference `'2`
error: lifetime may not live long enough
- --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58
+ --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:21:58
|
LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
| -- ---- has type `Pin<&'1 Foo>` ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a`
diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
index 8291e44..34b08b3 100644
--- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
+++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.rs
@@ -1,16 +1,26 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
use std::pin::Pin;
struct Foo;
impl Foo {
- fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } //~ ERROR E0623
+ fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
+ //[base]~^ ERROR E0623
+ //[nll]~^^ lifetime may not live long enough
- fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } //~ ERROR E0623
+ fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
+ //[base]~^ ERROR E0623
+ //[nll]~^^ lifetime may not live long enough
}
type Alias<T> = Pin<T>;
impl Foo {
- fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } //~ ERROR E0623
+ fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg }
+ //[base]~^ ERROR E0623
+ //[nll]~^^ lifetime may not live long enough
}
fn main() {}
diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.base.stderr
similarity index 91%
rename from src/test/ui/self/elision/lt-ref-self-async.stderr
rename to src/test/ui/self/elision/lt-ref-self-async.base.stderr
index 7448e84..b438549 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:13:9
+ --> $DIR/lt-ref-self-async.rs:16:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ---- ----
@@ -9,7 +9,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:19:9
+ --> $DIR/lt-ref-self-async.rs:24:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ---- ----
@@ -19,7 +19,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:23:9
+ --> $DIR/lt-ref-self-async.rs:30:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -29,7 +29,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:27:9
+ --> $DIR/lt-ref-self-async.rs:36:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -39,7 +39,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:31:9
+ --> $DIR/lt-ref-self-async.rs:42:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -49,7 +49,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self-async.rs:35:9
+ --> $DIR/lt-ref-self-async.rs:48:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
index c10b882..2ba9a65 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:13:9
+ --> $DIR/lt-ref-self-async.rs:16:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:19:9
+ --> $DIR/lt-ref-self-async.rs:24:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:23:9
+ --> $DIR/lt-ref-self-async.rs:30:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:27:9
+ --> $DIR/lt-ref-self-async.rs:36:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:31:9
+ --> $DIR/lt-ref-self-async.rs:42:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self-async.rs:35:9
+ --> $DIR/lt-ref-self-async.rs:48:9
|
LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs
index ef6cbe7..24482b3 100644
--- a/src/test/ui/self/elision/lt-ref-self-async.rs
+++ b/src/test/ui/self/elision/lt-ref-self-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
#![allow(non_snake_case)]
@@ -10,29 +13,41 @@ impl<'a> Struct<'a> {
// Test using `&self` sugar:
async fn ref_self(&self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&Self` explicitly:
async fn ref_Self(self: &Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/lt-ref-self.stderr b/src/test/ui/self/elision/lt-ref-self.base.stderr
similarity index 96%
rename from src/test/ui/self/elision/lt-ref-self.stderr
rename to src/test/ui/self/elision/lt-ref-self.base.stderr
index 5764ab0..0f5cd6f 100644
--- a/src/test/ui/self/elision/lt-ref-self.stderr
+++ b/src/test/ui/self/elision/lt-ref-self.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:11:9
+ --> $DIR/lt-ref-self.rs:15:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| ---- ----
@@ -15,7 +15,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:17:9
+ --> $DIR/lt-ref-self.rs:23:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ---- ----
@@ -31,7 +31,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:21:9
+ --> $DIR/lt-ref-self.rs:29:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -47,7 +47,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:25:9
+ --> $DIR/lt-ref-self.rs:35:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -63,7 +63,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:29:9
+ --> $DIR/lt-ref-self.rs:41:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -79,7 +79,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/lt-ref-self.rs:33:9
+ --> $DIR/lt-ref-self.rs:47:9
|
LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr
index e2de743..1934207 100644
--- a/src/test/ui/self/elision/lt-ref-self.nll.stderr
+++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:11:9
+ --> $DIR/lt-ref-self.rs:15:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:17:9
+ --> $DIR/lt-ref-self.rs:23:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:21:9
+ --> $DIR/lt-ref-self.rs:29:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:25:9
+ --> $DIR/lt-ref-self.rs:35:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:29:9
+ --> $DIR/lt-ref-self.rs:41:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/lt-ref-self.rs:33:9
+ --> $DIR/lt-ref-self.rs:47:9
|
LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/lt-ref-self.rs b/src/test/ui/self/elision/lt-ref-self.rs
index 423c7d5..62bdb13 100644
--- a/src/test/ui/self/elision/lt-ref-self.rs
+++ b/src/test/ui/self/elision/lt-ref-self.rs
@@ -1,3 +1,7 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
#![allow(non_snake_case)]
use std::pin::Pin;
@@ -8,29 +12,41 @@ impl<'a> Struct<'a> {
// Test using `&self` sugar:
fn ref_self(&self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&Self` explicitly:
fn ref_Self(self: &Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.base.stderr
similarity index 91%
rename from src/test/ui/self/elision/ref-mut-self-async.stderr
rename to src/test/ui/self/elision/ref-mut-self-async.base.stderr
index 6056cc4..8513375 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:13:9
+ --> $DIR/ref-mut-self-async.rs:16:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| ---- ----
@@ -9,7 +9,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:19:9
+ --> $DIR/ref-mut-self-async.rs:24:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| ---- ----
@@ -19,7 +19,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:23:9
+ --> $DIR/ref-mut-self-async.rs:30:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| ---- ----
@@ -29,7 +29,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:27:9
+ --> $DIR/ref-mut-self-async.rs:36:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| ---- ----
@@ -39,7 +39,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:31:9
+ --> $DIR/ref-mut-self-async.rs:42:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -49,7 +49,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self-async.rs:35:9
+ --> $DIR/ref-mut-self-async.rs:48:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
index 19496a5..cdd4640 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:13:9
+ --> $DIR/ref-mut-self-async.rs:16:9
|
LL | async fn ref_self(&mut self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:19:9
+ --> $DIR/ref-mut-self-async.rs:24:9
|
LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:23:9
+ --> $DIR/ref-mut-self-async.rs:30:9
|
LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:27:9
+ --> $DIR/ref-mut-self-async.rs:36:9
|
LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:31:9
+ --> $DIR/ref-mut-self-async.rs:42:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self-async.rs:35:9
+ --> $DIR/ref-mut-self-async.rs:48:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs
index 1e65605..59b41f3 100644
--- a/src/test/ui/self/elision/ref-mut-self-async.rs
+++ b/src/test/ui/self/elision/ref-mut-self-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
#![allow(non_snake_case)]
@@ -10,29 +13,41 @@ impl Struct {
// Test using `&mut self` sugar:
async fn ref_self(&mut self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&mut Self` explicitly:
async fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-mut-self.stderr b/src/test/ui/self/elision/ref-mut-self.base.stderr
similarity index 96%
rename from src/test/ui/self/elision/ref-mut-self.stderr
rename to src/test/ui/self/elision/ref-mut-self.base.stderr
index 416719a..fcedddd 100644
--- a/src/test/ui/self/elision/ref-mut-self.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:11:9
+ --> $DIR/ref-mut-self.rs:15:9
|
LL | fn ref_self(&mut self, f: &u32) -> &u32 {
| ---- ----
@@ -15,7 +15,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:17:9
+ --> $DIR/ref-mut-self.rs:23:9
|
LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| ---- ----
@@ -31,7 +31,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:21:9
+ --> $DIR/ref-mut-self.rs:29:9
|
LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| ---- ----
@@ -47,7 +47,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:25:9
+ --> $DIR/ref-mut-self.rs:35:9
|
LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| ---- ----
@@ -63,7 +63,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:29:9
+ --> $DIR/ref-mut-self.rs:41:9
|
LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -79,7 +79,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-self.rs:33:9
+ --> $DIR/ref-mut-self.rs:47:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr
index 94bfc5f..f1f4d34 100644
--- a/src/test/ui/self/elision/ref-mut-self.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:11:9
+ --> $DIR/ref-mut-self.rs:15:9
|
LL | fn ref_self(&mut self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:17:9
+ --> $DIR/ref-mut-self.rs:23:9
|
LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:21:9
+ --> $DIR/ref-mut-self.rs:29:9
|
LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:25:9
+ --> $DIR/ref-mut-self.rs:35:9
|
LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:29:9
+ --> $DIR/ref-mut-self.rs:41:9
|
LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-self.rs:33:9
+ --> $DIR/ref-mut-self.rs:47:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-self.rs b/src/test/ui/self/elision/ref-mut-self.rs
index 8d9359d..81bd279 100644
--- a/src/test/ui/self/elision/ref-mut-self.rs
+++ b/src/test/ui/self/elision/ref-mut-self.rs
@@ -1,3 +1,7 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
#![allow(non_snake_case)]
use std::pin::Pin;
@@ -8,29 +12,41 @@ impl Struct {
// Test using `&mut self` sugar:
fn ref_self(&mut self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&mut Self` explicitly:
fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.base.stderr
similarity index 92%
rename from src/test/ui/self/elision/ref-mut-struct-async.stderr
rename to src/test/ui/self/elision/ref-mut-struct-async.base.stderr
index 61034ae..0de11c2 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:13:9
+ --> $DIR/ref-mut-struct-async.rs:16:9
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| ---- ----
@@ -9,7 +9,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:17:9
+ --> $DIR/ref-mut-struct-async.rs:22:9
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -19,7 +19,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:21:9
+ --> $DIR/ref-mut-struct-async.rs:28:9
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -29,7 +29,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:25:9
+ --> $DIR/ref-mut-struct-async.rs:34:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
@@ -39,7 +39,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct-async.rs:29:9
+ --> $DIR/ref-mut-struct-async.rs:40:9
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
index 94671c7..0ef410c 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:13:9
+ --> $DIR/ref-mut-struct-async.rs:16:9
|
LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:17:9
+ --> $DIR/ref-mut-struct-async.rs:22:9
|
LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:21:9
+ --> $DIR/ref-mut-struct-async.rs:28:9
|
LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:25:9
+ --> $DIR/ref-mut-struct-async.rs:34:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct-async.rs:29:9
+ --> $DIR/ref-mut-struct-async.rs:40:9
|
LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs
index 990f485..7448988 100644
--- a/src/test/ui/self/elision/ref-mut-struct-async.rs
+++ b/src/test/ui/self/elision/ref-mut-struct-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
#![allow(non_snake_case)]
@@ -10,23 +13,33 @@ impl Struct {
// Test using `&mut Struct` explicitly:
async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-mut-struct.stderr b/src/test/ui/self/elision/ref-mut-struct.base.stderr
similarity index 97%
rename from src/test/ui/self/elision/ref-mut-struct.stderr
rename to src/test/ui/self/elision/ref-mut-struct.base.stderr
index 6ca9ab1..a01492f 100644
--- a/src/test/ui/self/elision/ref-mut-struct.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:11:9
+ --> $DIR/ref-mut-struct.rs:15:9
|
LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| ---- ----
@@ -15,7 +15,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:15:9
+ --> $DIR/ref-mut-struct.rs:21:9
|
LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -31,7 +31,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:19:9
+ --> $DIR/ref-mut-struct.rs:27:9
|
LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -47,7 +47,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:23:9
+ --> $DIR/ref-mut-struct.rs:33:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
@@ -63,7 +63,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-mut-struct.rs:27:9
+ --> $DIR/ref-mut-struct.rs:39:9
|
LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
index c9e7479..de7eb02 100644
--- a/src/test/ui/self/elision/ref-mut-struct.nll.stderr
+++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:11:9
+ --> $DIR/ref-mut-struct.rs:15:9
|
LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:15:9
+ --> $DIR/ref-mut-struct.rs:21:9
|
LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:19:9
+ --> $DIR/ref-mut-struct.rs:27:9
|
LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:23:9
+ --> $DIR/ref-mut-struct.rs:33:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-mut-struct.rs:27:9
+ --> $DIR/ref-mut-struct.rs:39:9
|
LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-mut-struct.rs b/src/test/ui/self/elision/ref-mut-struct.rs
index 05e275b..72674bd 100644
--- a/src/test/ui/self/elision/ref-mut-struct.rs
+++ b/src/test/ui/self/elision/ref-mut-struct.rs
@@ -1,3 +1,7 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
#![allow(non_snake_case)]
use std::pin::Pin;
@@ -8,23 +12,33 @@ impl Struct {
// Test using `&mut Struct` explicitly:
fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.base.stderr
similarity index 92%
rename from src/test/ui/self/elision/ref-self-async.stderr
rename to src/test/ui/self/elision/ref-self-async.base.stderr
index 0eab16e..fa13b69 100644
--- a/src/test/ui/self/elision/ref-self-async.stderr
+++ b/src/test/ui/self/elision/ref-self-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:23:9
+ --> $DIR/ref-self-async.rs:26:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| ---- ----
@@ -9,7 +9,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:29:9
+ --> $DIR/ref-self-async.rs:34:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ---- ----
@@ -19,7 +19,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:33:9
+ --> $DIR/ref-self-async.rs:40:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -29,7 +29,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:37:9
+ --> $DIR/ref-self-async.rs:46:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -39,7 +39,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:41:9
+ --> $DIR/ref-self-async.rs:52:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -49,7 +49,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:45:9
+ --> $DIR/ref-self-async.rs:58:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -59,7 +59,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-self-async.rs:49:9
+ --> $DIR/ref-self-async.rs:64:9
|
LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
| --- ---
diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr
index bd1f808..77faaa8 100644
--- a/src/test/ui/self/elision/ref-self-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-self-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:23:9
+ --> $DIR/ref-self-async.rs:26:9
|
LL | async fn ref_self(&self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:29:9
+ --> $DIR/ref-self-async.rs:34:9
|
LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:33:9
+ --> $DIR/ref-self-async.rs:40:9
|
LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:37:9
+ --> $DIR/ref-self-async.rs:46:9
|
LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:41:9
+ --> $DIR/ref-self-async.rs:52:9
|
LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:45:9
+ --> $DIR/ref-self-async.rs:58:9
|
LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -59,7 +59,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self-async.rs:49:9
+ --> $DIR/ref-self-async.rs:64:9
|
LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs
index 0fbbd95..afe5fe1 100644
--- a/src/test/ui/self/elision/ref-self-async.rs
+++ b/src/test/ui/self/elision/ref-self-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
#![allow(non_snake_case)]
#![feature(arbitrary_self_types)]
@@ -20,33 +23,47 @@ impl Struct {
// Test using `&self` sugar:
async fn ref_self(&self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&Self` explicitly:
async fn ref_Self(self: &Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-self.stderr b/src/test/ui/self/elision/ref-self.base.stderr
similarity index 96%
rename from src/test/ui/self/elision/ref-self.stderr
rename to src/test/ui/self/elision/ref-self.base.stderr
index 955222f..8bd194d 100644
--- a/src/test/ui/self/elision/ref-self.stderr
+++ b/src/test/ui/self/elision/ref-self.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:21:9
+ --> $DIR/ref-self.rs:25:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| ---- ----
@@ -15,7 +15,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:27:9
+ --> $DIR/ref-self.rs:33:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| ---- ----
@@ -31,7 +31,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:31:9
+ --> $DIR/ref-self.rs:39:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -47,7 +47,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:35:9
+ --> $DIR/ref-self.rs:45:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| ---- ----
@@ -63,7 +63,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:39:9
+ --> $DIR/ref-self.rs:51:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -79,7 +79,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:43:9
+ --> $DIR/ref-self.rs:57:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| ---- ----
@@ -95,7 +95,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-self.rs:47:9
+ --> $DIR/ref-self.rs:63:9
|
LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
| --- ---
diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr
index d1fd209..f2b7b0a 100644
--- a/src/test/ui/self/elision/ref-self.nll.stderr
+++ b/src/test/ui/self/elision/ref-self.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:21:9
+ --> $DIR/ref-self.rs:25:9
|
LL | fn ref_self(&self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:27:9
+ --> $DIR/ref-self.rs:33:9
|
LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:31:9
+ --> $DIR/ref-self.rs:39:9
|
LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:35:9
+ --> $DIR/ref-self.rs:45:9
|
LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:39:9
+ --> $DIR/ref-self.rs:51:9
|
LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -49,7 +49,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:43:9
+ --> $DIR/ref-self.rs:57:9
|
LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -59,7 +59,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-self.rs:47:9
+ --> $DIR/ref-self.rs:63:9
|
LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-self.rs b/src/test/ui/self/elision/ref-self.rs
index e389d85..34df3da 100644
--- a/src/test/ui/self/elision/ref-self.rs
+++ b/src/test/ui/self/elision/ref-self.rs
@@ -1,3 +1,7 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
#![feature(arbitrary_self_types)]
#![allow(non_snake_case)]
@@ -18,33 +22,47 @@ impl Struct {
// Test using `&self` sugar:
fn ref_self(&self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
// Test using `&Self` explicitly:
fn ref_Self(self: &Self, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.base.stderr
similarity index 92%
rename from src/test/ui/self/elision/ref-struct-async.stderr
rename to src/test/ui/self/elision/ref-struct-async.base.stderr
index aa1d745..8da673d 100644
--- a/src/test/ui/self/elision/ref-struct-async.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:13:9
+ --> $DIR/ref-struct-async.rs:16:9
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ---- ----
@@ -9,7 +9,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:17:9
+ --> $DIR/ref-struct-async.rs:22:9
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -19,7 +19,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:21:9
+ --> $DIR/ref-struct-async.rs:28:9
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -29,7 +29,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:25:9
+ --> $DIR/ref-struct-async.rs:34:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| ---- ----
@@ -39,7 +39,7 @@
| ^ ...but data from `f` is returned here
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct-async.rs:29:9
+ --> $DIR/ref-struct-async.rs:40:9
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr
index 9361b6f..ad07c70 100644
--- a/src/test/ui/self/elision/ref-struct-async.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:13:9
+ --> $DIR/ref-struct-async.rs:16:9
|
LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:17:9
+ --> $DIR/ref-struct-async.rs:22:9
|
LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:21:9
+ --> $DIR/ref-struct-async.rs:28:9
|
LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:25:9
+ --> $DIR/ref-struct-async.rs:34:9
|
LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct-async.rs:29:9
+ --> $DIR/ref-struct-async.rs:40:9
|
LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs
index e6bd541..12f8f6f 100644
--- a/src/test/ui/self/elision/ref-struct-async.rs
+++ b/src/test/ui/self/elision/ref-struct-async.rs
@@ -1,4 +1,7 @@
// edition:2018
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
#![allow(non_snake_case)]
@@ -10,23 +13,33 @@ impl Struct {
// Test using `&Struct` explicitly:
async fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/self/elision/ref-struct.stderr b/src/test/ui/self/elision/ref-struct.base.stderr
similarity index 97%
rename from src/test/ui/self/elision/ref-struct.stderr
rename to src/test/ui/self/elision/ref-struct.base.stderr
index c80993f..5650b37 100644
--- a/src/test/ui/self/elision/ref-struct.stderr
+++ b/src/test/ui/self/elision/ref-struct.base.stderr
@@ -1,5 +1,5 @@
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:11:9
+ --> $DIR/ref-struct.rs:15:9
|
LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| ---- ----
@@ -15,7 +15,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:15:9
+ --> $DIR/ref-struct.rs:21:9
|
LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -31,7 +31,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:19:9
+ --> $DIR/ref-struct.rs:27:9
|
LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| ---- ----
@@ -47,7 +47,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:23:9
+ --> $DIR/ref-struct.rs:33:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| ---- ----
@@ -63,7 +63,7 @@
| ++++ ++ ++
error[E0623]: lifetime mismatch
- --> $DIR/ref-struct.rs:27:9
+ --> $DIR/ref-struct.rs:39:9
|
LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| ---- ----
diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr
index e1cc38b..70453b0 100644
--- a/src/test/ui/self/elision/ref-struct.nll.stderr
+++ b/src/test/ui/self/elision/ref-struct.nll.stderr
@@ -1,5 +1,5 @@
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:11:9
+ --> $DIR/ref-struct.rs:15:9
|
LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -9,7 +9,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:15:9
+ --> $DIR/ref-struct.rs:21:9
|
LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -19,7 +19,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:19:9
+ --> $DIR/ref-struct.rs:27:9
|
LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -29,7 +29,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:23:9
+ --> $DIR/ref-struct.rs:33:9
|
LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
@@ -39,7 +39,7 @@
| ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
error: lifetime may not live long enough
- --> $DIR/ref-struct.rs:27:9
+ --> $DIR/ref-struct.rs:39:9
|
LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
| - - let's call the lifetime of this reference `'1`
diff --git a/src/test/ui/self/elision/ref-struct.rs b/src/test/ui/self/elision/ref-struct.rs
index 73711a7..0ffe727 100644
--- a/src/test/ui/self/elision/ref-struct.rs
+++ b/src/test/ui/self/elision/ref-struct.rs
@@ -1,3 +1,7 @@
+// revisions: base nll
+// ignore-compare-mode-nll
+//[nll] compile-flags: -Z borrowck=mir
+
#![allow(non_snake_case)]
use std::pin::Pin;
@@ -8,23 +12,33 @@ impl Struct {
// Test using `&Struct` explicitly:
fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
- f //~ ERROR lifetime mismatch
+ f
+ //[base]~^ ERROR lifetime mismatch
+ //[nll]~^^ ERROR lifetime may not live long enough
}
}
diff --git a/src/test/ui/statics/uninhabited-static.rs b/src/test/ui/statics/uninhabited-static.rs
index d564547..f5c6f44 100644
--- a/src/test/ui/statics/uninhabited-static.rs
+++ b/src/test/ui/statics/uninhabited-static.rs
@@ -11,11 +11,11 @@ enum Void {}
static VOID2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type
//~| WARN: previously accepted
-//~| ERROR undefined behavior to use this value
+//~| ERROR could not evaluate static initializer
//~| WARN: type `Void` does not permit zero-initialization
static NEVER2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type
//~| WARN: previously accepted
-//~| ERROR undefined behavior to use this value
+//~| ERROR could not evaluate static initializer
//~| WARN: type `Void` does not permit zero-initialization
fn main() {}
diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr
index c38cf10..1e0becb 100644
--- a/src/test/ui/statics/uninhabited-static.stderr
+++ b/src/test/ui/statics/uninhabited-static.stderr
@@ -43,23 +43,17 @@
= note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840>
= note: uninhabited statics cannot be initialized, and any access would be an immediate error
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/uninhabited-static.rs:12:1
+error[E0080]: could not evaluate static initializer
+ --> $DIR/uninhabited-static.rs:12:31
|
LL | static VOID2: Void = unsafe { std::mem::transmute(()) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 0, align: 1) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
-error[E0080]: it is undefined behavior to use this value
- --> $DIR/uninhabited-static.rs:16:1
+error[E0080]: could not evaluate static initializer
+ --> $DIR/uninhabited-static.rs:16:32
|
LL | static NEVER2: Void = unsafe { std::mem::transmute(()) };
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void
- |
- = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
- = note: the raw bytes of the constant (size: 0, align: 1) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
warning: the type `Void` does not permit zero-initialization
--> $DIR/uninhabited-static.rs:12:31
diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs
new file mode 100644
index 0000000..5b223a9
--- /dev/null
+++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.rs
@@ -0,0 +1,35 @@
+use std::ops::Deref;
+
+struct Foo {
+ v: Vec<u32>,
+}
+
+struct Bar {
+ v: Vec<u32>,
+}
+
+impl Deref for Bar {
+ type Target = Vec<u32>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.v
+ }
+}
+
+fn f(foo: &Foo) {
+ match foo {
+ Foo { v: [1, 2] } => {}
+ //~^ ERROR expected an array or slice, found `Vec<u32>
+ _ => {}
+ }
+}
+
+fn bar(bar: &Bar) {
+ match bar {
+ Bar { v: [1, 2] } => {}
+ //~^ ERROR expected an array or slice, found `Vec<u32>
+ _ => {}
+ }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr
new file mode 100644
index 0000000..5b48a8b
--- /dev/null
+++ b/src/test/ui/suggestions/pattern-struct-with-slice-vec-field.stderr
@@ -0,0 +1,15 @@
+error[E0529]: expected an array or slice, found `Vec<u32>`
+ --> $DIR/pattern-struct-with-slice-vec-field.rs:21:18
+ |
+LL | Foo { v: [1, 2] } => {}
+ | ^^^^^^ pattern cannot match with input type `Vec<u32>`
+
+error[E0529]: expected an array or slice, found `Vec<u32>`
+ --> $DIR/pattern-struct-with-slice-vec-field.rs:29:18
+ |
+LL | Bar { v: [1, 2] } => {}
+ | ^^^^^^ pattern cannot match with input type `Vec<u32>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0529`.
diff --git a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
index 5a158e5..5409e32 100644
--- a/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
+++ b/src/test/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr
@@ -2,15 +2,17 @@
--> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
|
LL | i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
- | ^ ------------ help: remove these generic arguments
- | |
- | expected 2 generic arguments
+ | ^ expected 2 generic arguments
|
note: trait defined here, with 2 generic parameters: `X`, `Y`
--> $DIR/use-type-argument-instead-of-assoc-type.rs:1:11
|
LL | pub trait T<X, Y> {
| ^ - -
+help: replace the generic bounds with the associated types
+ |
+LL | i: Box<dyn T<usize, usize, A = usize, C = usize, B=usize>>,
+ | ~~~~~~~~~ ~~~~~~~~~
error[E0191]: the value of the associated types `A` (from trait `T`), `C` (from trait `T`) must be specified
--> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16
@@ -23,11 +25,6 @@
...
LL | i: Box<dyn T<usize, usize, usize, usize, B=usize>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated types `A`, `C` must be specified
- |
-help: specify the associated types
- |
-LL | i: Box<dyn T<usize, usize, A = usize, C = usize, B=usize>>,
- | ~~~~~~~~~ ~~~~~~~~~
error: aborting due to 2 previous errors
diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs
new file mode 100644
index 0000000..b37ec26
--- /dev/null
+++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs
@@ -0,0 +1,29 @@
+// Verifies that MIR building for a call expression respects
+// privacy when checking if a call return type is uninhabited.
+
+pub mod widget {
+ enum Unimplemented {}
+ pub struct Widget(Unimplemented);
+
+ impl Widget {
+ pub fn new() -> Widget {
+ todo!();
+ }
+ }
+
+ pub fn f() {
+ let x: &mut u32;
+ Widget::new();
+ // Ok. Widget type returned from new is known to be uninhabited
+ // and the following code is considered unreachable.
+ *x = 1;
+ }
+}
+
+fn main() {
+ let y: &mut u32;
+ widget::Widget::new();
+ // Error. Widget type is not known to be uninhabited here,
+ // so the following code is considered reachable.
+ *y = 2; //~ ERROR use of possibly-uninitialized variable
+}
diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr
new file mode 100644
index 0000000..fb19534
--- /dev/null
+++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr
@@ -0,0 +1,9 @@
+error[E0381]: use of possibly-uninitialized variable: `y`
+ --> $DIR/privately-uninhabited-mir-call.rs:28:5
+ |
+LL | *y = 2;
+ | ^^^^^^ use of possibly-uninitialized `y`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0381`.
diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr
index 33f762c..e796096 100644
--- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr
+++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr
@@ -1,11 +1,27 @@
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
- --> $DIR/issue-45087-unreachable-unsafe.rs:6:5
+ --> $DIR/issue-45087-unreachable-unsafe.rs:7:5
|
LL | *(1 as *mut u32) = 42;
| ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer
|
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-error: aborting due to previous error
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+ --> $DIR/issue-45087-unreachable-unsafe.rs:17:5
+ |
+LL | *a = 1;
+ | ^^^^^^ dereference of raw pointer
+ |
+ = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+ --> $DIR/issue-45087-unreachable-unsafe.rs:29:5
+ |
+LL | *b = 1;
+ | ^^^^^^ dereference of raw pointer
+ |
+ = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs
index 071cea8..3e3da66 100644
--- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs
+++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs
@@ -1,3 +1,4 @@
+// Verify that unreachable code undergoes unsafety checks.
// revisions: mir thir
// [thir]compile-flags: -Z thir-unsafeck
@@ -6,3 +7,25 @@ fn main() {
*(1 as *mut u32) = 42;
//~^ ERROR dereference of raw pointer is unsafe
}
+
+fn panic() -> ! {
+ panic!();
+}
+
+fn f(a: *mut u32) {
+ panic();
+ *a = 1;
+ //~^ ERROR dereference of raw pointer is unsafe
+}
+
+enum Void {}
+
+fn uninhabited() -> Void {
+ panic!();
+}
+
+fn g(b: *mut u32) {
+ uninhabited();
+ *b = 1;
+ //~^ ERROR dereference of raw pointer is unsafe
+}
diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr
index 73a1136..e81adad 100644
--- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr
+++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr
@@ -1,11 +1,27 @@
error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
- --> $DIR/issue-45087-unreachable-unsafe.rs:6:5
+ --> $DIR/issue-45087-unreachable-unsafe.rs:7:5
|
LL | *(1 as *mut u32) = 42;
| ^^^^^^^^^^^^^^^^ dereference of raw pointer
|
= note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
-error: aborting due to previous error
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+ --> $DIR/issue-45087-unreachable-unsafe.rs:17:5
+ |
+LL | *a = 1;
+ | ^^ dereference of raw pointer
+ |
+ = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
+ --> $DIR/issue-45087-unreachable-unsafe.rs:29:5
+ |
+LL | *b = 1;
+ | ^^ dereference of raw pointer
+ |
+ = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
+
+error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0133`.
diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
deleted file mode 100644
index e69df03..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// --extern-location with bad location type
-
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=badloc:in-the-test-file -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr b/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr
deleted file mode 100644
index 12378f1..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-bad-loctype.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown location type `badloc`: use `raw` or `json`
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs b/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs
deleted file mode 100644
index a023f53..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-defl-json.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// Default extern location from name and path if one isn't specified
-
-// check-pass
-// aux-crate:bar=bar.rs
-// compile-flags:--error-format json
-
-#![warn(unused_crate_dependencies)]
-//~^ WARNING external crate `bar` unused in
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr
deleted file mode 100644
index cee3f6c..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-defl-json.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-{"message":"external crate `bar` unused in `extern_loc_defl_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-defl-json.rs","byte_start":146,"byte_end":146,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-defl-json.rs","byte_start":154,"byte_end":179,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"name":"bar"}}],"rendered":"warning: external crate `bar` unused in `extern_loc_defl_json`: remove the dependency or add `use bar as _;`
- --> $DIR/extern-loc-defl-json.rs:7:1
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^
- |
-note: the lint level is defined here
- --> $DIR/extern-loc-defl-json.rs:7:9
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar`
-
-"}
-{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted
-
-"}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
deleted file mode 100644
index aee6233..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// --extern-location with a raw reference
-
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:[{"malformed -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr
deleted file mode 100644
index 20d6063..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json-bad-json.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: `--extern-location`: malformed json location `[{"malformed`
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
deleted file mode 100644
index c7988cd..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// --extern-location with a raw reference
-
-// check-pass
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}} --error-format json -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-//~^ WARNING external crate `bar` unused in
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
deleted file mode 100644
index 001ec6a..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json-json.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-{"message":"external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":189,"byte_end":189,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-json-json.rs","byte_start":197,"byte_end":222,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":{"key":123,"value":{}}}],"rendered":"warning: external crate `bar` unused in `extern_loc_json_json`: remove the dependency or add `use bar as _;`
- --> $DIR/extern-loc-json-json.rs:7:1
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^
- |
-note: the lint level is defined here
- --> $DIR/extern-loc-json-json.rs:7:9
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar`
-
-"}
-{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted
-
-"}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.rs b/src/test/ui/unused-crate-deps/extern-loc-json.rs
deleted file mode 100644
index c0d76c8..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// --extern-location with a raw reference
-
-// check-pass
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=json:{"key":123,"value":{}} -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-//~^ WARNING external crate `bar` unused in
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-json.stderr
deleted file mode 100644
index a6bbc0d..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-json.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-warning: external crate `bar` unused in `extern_loc_json`: remove the dependency or add `use bar as _;`
- --> $DIR/extern-loc-json.rs:7:1
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^
- |
-note: the lint level is defined here
- --> $DIR/extern-loc-json.rs:7:9
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar`
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs
deleted file mode 100644
index 6ac5589..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// --extern-location with a raw reference
-
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar -Zunstable-options
-
-#![warn(unused_crate_dependencies)]
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr b/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr
deleted file mode 100644
index 4584fbf..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loc.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: `--extern-location`: specify location for extern crate `bar`
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
deleted file mode 100644
index 3590b9c..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// --extern-location with no type
-
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=missing-loc-type -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr b/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr
deleted file mode 100644
index d0c36eb..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-missing-loctype.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: unknown location type `missing-loc-type`: use `raw` or `json`
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
deleted file mode 100644
index 64c3d77..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// --extern-location with a raw reference
-
-// check-pass
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file --error-format json -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-//~^ WARNING external crate `bar` unused in
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
deleted file mode 100644
index 4083bd5..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-json.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-{"message":"external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`","code":{"code":"unused_crate_dependencies","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":182,"byte_end":182,"line_start":7,"line_end":7,"column_start":1,"column_end":1,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":1,"highlight_end":1}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"the lint level is defined here","code":null,"level":"note","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":190,"byte_end":215,"line_start":7,"line_end":7,"column_start":9,"column_end":34,"is_primary":true,"text":[{"text":"#![warn(unused_crate_dependencies)]","highlight_start":9,"highlight_end":34}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[],"rendered":null},{"message":"remove unnecessary dependency `bar` at `in-the-test-file`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"raw extern location","code":null,"level":"help","spans":[{"file_name":"$DIR/extern-loc-raw-json.rs","byte_start":0,"byte_end":0,"line_start":1,"line_end":1,"column_start":1,"column_end":1,"is_primary":true,"text":[],"label":null,"suggested_replacement":"in-the-test-file","suggestion_applicability":"Unspecified","expansion":null}],"children":[],"rendered":null},{"message":"json extern location","code":null,"level":"help","spans":[],"children":[],"rendered":null,"tool_metadata":"in-the-test-file"}],"rendered":"warning: external crate `bar` unused in `extern_loc_raw_json`: remove the dependency or add `use bar as _;`
- --> $DIR/extern-loc-raw-json.rs:7:1
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^
- |
-note: the lint level is defined here
- --> $DIR/extern-loc-raw-json.rs:7:9
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar` at `in-the-test-file`
-
-"}
-{"message":"1 warning emitted","code":null,"level":"warning","spans":[],"children":[],"rendered":"warning: 1 warning emitted
-
-"}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
deleted file mode 100644
index a9e7afb..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// --extern-location with a raw reference
-
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr
deleted file mode 100644
index 4b51266..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw-missing-loc.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: `--extern-location`: missing `raw` location
-
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.rs b/src/test/ui/unused-crate-deps/extern-loc-raw.rs
deleted file mode 100644
index 27d0975..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-// --extern-location with a raw reference
-
-// check-pass
-// aux-crate:bar=bar.rs
-// compile-flags:--extern-location bar=raw:in-the-test-file -Z unstable-options
-
-#![warn(unused_crate_dependencies)]
-//~^ WARNING external crate `bar` unused in
-
-fn main() {}
diff --git a/src/test/ui/unused-crate-deps/extern-loc-raw.stderr b/src/test/ui/unused-crate-deps/extern-loc-raw.stderr
deleted file mode 100644
index 2cdd005..0000000
--- a/src/test/ui/unused-crate-deps/extern-loc-raw.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-warning: external crate `bar` unused in `extern_loc_raw`: remove the dependency or add `use bar as _;`
- --> $DIR/extern-loc-raw.rs:7:1
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^
- |
-note: the lint level is defined here
- --> $DIR/extern-loc-raw.rs:7:9
- |
-LL | #![warn(unused_crate_dependencies)]
- | ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar` at `in-the-test-file`
-
-warning: 1 warning emitted
-
diff --git a/src/test/ui/unused-crate-deps/libfib.stderr b/src/test/ui/unused-crate-deps/libfib.stderr
index 479f51b..1583312 100644
--- a/src/test/ui/unused-crate-deps/libfib.stderr
+++ b/src/test/ui/unused-crate-deps/libfib.stderr
@@ -5,7 +5,6 @@
| ^
|
= note: requested on the command line with `-W unused-crate-dependencies`
- = help: remove unnecessary dependency `bar`
warning: 1 warning emitted
diff --git a/src/test/ui/unused-crate-deps/unused-aliases.stderr b/src/test/ui/unused-crate-deps/unused-aliases.stderr
index 1142d15..c8c6c45 100644
--- a/src/test/ui/unused-crate-deps/unused-aliases.stderr
+++ b/src/test/ui/unused-crate-deps/unused-aliases.stderr
@@ -9,7 +9,6 @@
|
LL | #![warn(unused_crate_dependencies)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `barbar`
warning: 1 warning emitted
diff --git a/src/test/ui/unused-crate-deps/warn-attr.stderr b/src/test/ui/unused-crate-deps/warn-attr.stderr
index 29667d9..0d38315 100644
--- a/src/test/ui/unused-crate-deps/warn-attr.stderr
+++ b/src/test/ui/unused-crate-deps/warn-attr.stderr
@@ -9,7 +9,6 @@
|
LL | #![warn(unused_crate_dependencies)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^
- = help: remove unnecessary dependency `bar`
warning: 1 warning emitted
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
index 2c0c921..6595646 100644
--- a/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
+++ b/src/test/ui/unused-crate-deps/warn-cmdline-static.stderr
@@ -5,7 +5,6 @@
| ^
|
= note: requested on the command line with `-W unused-crate-dependencies`
- = help: remove unnecessary dependency `bar`
warning: 1 warning emitted
diff --git a/src/test/ui/unused-crate-deps/warn-cmdline.stderr b/src/test/ui/unused-crate-deps/warn-cmdline.stderr
index 2cd4921..ea675ba 100644
--- a/src/test/ui/unused-crate-deps/warn-cmdline.stderr
+++ b/src/test/ui/unused-crate-deps/warn-cmdline.stderr
@@ -5,7 +5,6 @@
| ^
|
= note: requested on the command line with `-W unused-crate-dependencies`
- = help: remove unnecessary dependency `bar`
warning: 1 warning emitted
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index fc0483a..5816a95 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -10,7 +10,7 @@
use rustc_ast::ast;
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty;
+use rustc_middle::ty::{self, DefIdTree};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::source_map::Span;
@@ -114,8 +114,8 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx hir::Item<'_>) {
hir::ItemKind::Fn(..) => {
// ignore main()
if it.ident.name == sym::main {
- let def_key = cx.tcx.hir().def_key(it.def_id);
- if def_key.parent == Some(hir::def_id::CRATE_DEF_INDEX) {
+ let at_root = cx.tcx.local_parent(it.def_id) == Some(CRATE_DEF_ID);
+ if at_root {
return;
}
}