diff --git a/Cargo.lock b/Cargo.lock index 9eba61f8d293b..73dc7f03236d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -606,12 +606,22 @@ dependencies = [ "atty", "bitflags", "indexmap", + "lazy_static", "os_str_bytes", "strsim 0.10.0", "termcolor", "textwrap 0.14.2", ] +[[package]] +name = "clap_complete" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df6f3613c0a3cddfd78b41b10203eb322cb29b600cbdf808a7d3db95691b8e25" +dependencies = [ + "clap 3.1.1", +] + [[package]] name = "clippy" version = "0.1.62" @@ -2240,14 +2250,15 @@ dependencies = [ [[package]] name = "mdbook" -version = "0.4.15" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241f10687eb3b4e0634b3b4e423f97c5f1efbd69dc9522e24a8b94583eeec3c6" +checksum = "74612ae81a3e5ee509854049dfa4c7975ae033c06f5fc4735c7dfbe60ee2a39d" dependencies = [ "ammonia", "anyhow", "chrono", - "clap 2.34.0", + "clap 3.1.1", + "clap_complete", "elasticlunr-rs", "env_logger 0.7.1", "handlebars", @@ -2911,7 +2922,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6" dependencies = [ "bitflags", - "getopts", "memchr", "unicase", ] @@ -3129,9 +3139,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.4" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" dependencies = [ "aho-corasick", "memchr", diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index c2247150d09c2..3c9bb81bedb1c 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -959,7 +959,7 @@ impl<'a> State<'a> { self.word_space("="); match term { Term::Ty(ty) => self.print_type(ty), - Term::Const(c) => self.print_expr_anon_const(c), + Term::Const(c) => self.print_expr_anon_const(c, &[]), } } ast::AssocConstraintKind::Bound { bounds } => self.print_type_bounds(":", &*bounds), diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 6435f1b6141e3..9de4cbbee13f0 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -88,10 +88,21 @@ impl<'a> State<'a> { self.end(); } - pub(super) fn print_expr_anon_const(&mut self, expr: &ast::AnonConst) { + pub(super) fn print_expr_anon_const( + &mut self, + expr: &ast::AnonConst, + attrs: &[ast::Attribute], + ) { self.ibox(INDENT_UNIT); self.word("const"); - self.print_expr(&expr.value); + self.nbsp(); + if let ast::ExprKind::Block(block, None) = &expr.value.kind { + self.cbox(0); + self.ibox(0); + self.print_block_with_attrs(block, attrs); + } else { + self.print_expr(&expr.value); + } self.end(); } @@ -275,7 +286,7 @@ impl<'a> State<'a> { self.print_expr_vec(exprs); } ast::ExprKind::ConstBlock(ref anon_const) => { - self.print_expr_anon_const(anon_const); + self.print_expr_anon_const(anon_const, attrs); } ast::ExprKind::Repeat(ref element, ref count) => { self.print_expr_repeat(element, count); diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 498b2f1b081b3..7cca6178ab257 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -188,6 +188,7 @@ pub(super) fn op_to_const<'tcx>( } } +#[instrument(skip(tcx), level = "debug")] fn turn_into_const_value<'tcx>( tcx: TyCtxt<'tcx>, constant: ConstAlloc<'tcx>, @@ -206,6 +207,7 @@ fn turn_into_const_value<'tcx>( !is_static || cid.promoted.is_some(), "the `eval_to_const_value_raw` query should not be used for statics, use `eval_to_allocation` instead" ); + // Turn this into a proper constant. op_to_const(&ecx, &mplace.into()) } diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 6fd7f707e7e5d..80270f825630f 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -3,12 +3,14 @@ use std::convert::TryFrom; use rustc_hir::Mutability; +use rustc_middle::ty::layout::HasTyCtxt; use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::{ mir::{self, interpret::ConstAlloc}, ty::ScalarInt, }; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; +use rustc_target::abi::VariantIdx; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MPlaceTy, @@ -55,28 +57,48 @@ pub(crate) fn const_to_valtree<'tcx>( const_to_valtree_inner(&ecx, &place) } -fn const_to_valtree_inner<'tcx>( +#[instrument(skip(ecx), level = "debug")] +fn branches<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, + n: usize, + variant: Option, ) -> Option> { - let branches = |n, variant| { - let place = match variant { - Some(variant) => ecx.mplace_downcast(&place, variant).unwrap(), - None => *place, - }; - let variant = - variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32())))); - let fields = (0..n).map(|i| { - let field = ecx.mplace_field(&place, i).unwrap(); - const_to_valtree_inner(ecx, &field) - }); - // For enums, we preped their variant index before the variant's fields so we can figure out - // the variant again when just seeing a valtree. - let branches = variant.into_iter().chain(fields); - Some(ty::ValTree::Branch( - ecx.tcx.arena.alloc_from_iter(branches.collect::>>()?), - )) + let place = match variant { + Some(variant) => ecx.mplace_downcast(&place, variant).unwrap(), + None => *place, }; + let variant = variant.map(|variant| Some(ty::ValTree::Leaf(ScalarInt::from(variant.as_u32())))); + debug!(?place, ?variant); + + let fields = (0..n).map(|i| { + let field = ecx.mplace_field(&place, i).unwrap(); + const_to_valtree_inner(ecx, &field) + }); + // For enums, we prepend their variant index before the variant's fields so we can figure out + // the variant again when just seeing a valtree. + let branches = variant.into_iter().chain(fields); + Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::>>()?))) +} + +fn slice_branches<'tcx>( + ecx: &CompileTimeEvalContext<'tcx, 'tcx>, + place: &MPlaceTy<'tcx>, +) -> Option> { + let n = place.len(&ecx.tcx()).expect(&format!("expected to use len of place {:?}", place)); + let branches = (0..n).map(|i| { + let place_elem = ecx.mplace_index(place, i).unwrap(); + const_to_valtree_inner(ecx, &place_elem) + }); + + Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::>>()?))) +} + +#[instrument(skip(ecx), level = "debug")] +fn const_to_valtree_inner<'tcx>( + ecx: &CompileTimeEvalContext<'tcx, 'tcx>, + place: &MPlaceTy<'tcx>, +) -> Option> { match place.layout.ty.kind() { ty::FnDef(..) => Some(ty::ValTree::zst()), ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => { @@ -90,19 +112,27 @@ fn const_to_valtree_inner<'tcx>( // Technically we could allow function pointers (represented as `ty::Instance`), but this is not guaranteed to // agree with runtime equality tests. ty::FnPtr(_) | ty::RawPtr(_) => None, - ty::Ref(..) => unimplemented!("need to use deref_const"), + ty::Ref(_, _, _) => { + let derefd_place = ecx.deref_operand(&place.into()).unwrap_or_else(|e| bug!("couldn't deref {:?}, error: {:?}", place, e)); + debug!(?derefd_place); + + const_to_valtree_inner(ecx, &derefd_place) + } + + ty::Str | ty::Slice(_) | ty::Array(_, _) => { + let valtree = slice_branches(ecx, place); + debug!(?valtree); + + valtree + } // Trait objects are not allowed in type level constants, as we have no concept for // resolving their backing type, even if we can do that at const eval time. We may // hypothetically be able to allow `dyn StructuralEq` trait objects in the future, // but it is unclear if this is useful. ty::Dynamic(..) => None, - ty::Slice(_) | ty::Str => { - unimplemented!("need to find the backing data of the slice/str and recurse on that") - } - ty::Tuple(substs) => branches(substs.len(), None), - ty::Array(_, len) => branches(usize::try_from(len.eval_usize(ecx.tcx.tcx, ecx.param_env)).unwrap(), None), + ty::Tuple(substs) => branches(ecx, place, substs.len(), None), ty::Adt(def, _) => { if def.variants().is_empty() { @@ -111,7 +141,7 @@ fn const_to_valtree_inner<'tcx>( let variant = ecx.read_discriminant(&place.into()).unwrap().1; - branches(def.variant(variant).fields.len(), def.is_enum().then_some(variant)) + branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant)) } ty::Never diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 8dc74035d61d0..31da4522a1fda 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -191,7 +191,7 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> { } #[inline] - pub(super) fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { + pub(crate) fn len(&self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { if self.layout.is_unsized() { // We need to consult `meta` metadata match self.layout.ty.kind() { diff --git a/compiler/rustc_data_structures/src/flock.rs b/compiler/rustc_data_structures/src/flock.rs index 293ef4caac400..e395d8dbbbf8b 100644 --- a/compiler/rustc_data_structures/src/flock.rs +++ b/compiler/rustc_data_structures/src/flock.rs @@ -7,225 +7,20 @@ #![allow(non_camel_case_types)] #![allow(nonstandard_style)] -use std::fs::{File, OpenOptions}; -use std::io; -use std::path::Path; - cfg_if! { - // We use `flock` rather than `fcntl` on Linux, because WSL1 does not support - // `fcntl`-style advisory locks properly (rust-lang/rust#72157). - // - // For other Unix targets we still use `fcntl` because it's more portable than - // `flock`. if #[cfg(target_os = "linux")] { - use std::os::unix::prelude::*; - - #[derive(Debug)] - pub struct Lock { - _file: File, - } - - impl Lock { - pub fn new(p: &Path, - wait: bool, - create: bool, - exclusive: bool) - -> io::Result { - let file = OpenOptions::new() - .read(true) - .write(true) - .create(create) - .mode(libc::S_IRWXU as u32) - .open(p)?; - - let mut operation = if exclusive { - libc::LOCK_EX - } else { - libc::LOCK_SH - }; - if !wait { - operation |= libc::LOCK_NB - } - - let ret = unsafe { libc::flock(file.as_raw_fd(), operation) }; - if ret == -1 { - Err(io::Error::last_os_error()) - } else { - Ok(Lock { _file: file }) - } - } - - pub fn error_unsupported(err: &io::Error) -> bool { - matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS)) - } - } - - // Note that we don't need a Drop impl to execute `flock(fd, LOCK_UN)`. Lock acquired by - // `flock` is associated with the file descriptor and closing the file release it - // automatically. + mod linux; + use linux as imp; } else if #[cfg(unix)] { - use std::mem; - use std::os::unix::prelude::*; - - #[derive(Debug)] - pub struct Lock { - file: File, - } - - impl Lock { - pub fn new(p: &Path, - wait: bool, - create: bool, - exclusive: bool) - -> io::Result { - let file = OpenOptions::new() - .read(true) - .write(true) - .create(create) - .mode(libc::S_IRWXU as u32) - .open(p)?; - - let lock_type = if exclusive { - libc::F_WRLCK - } else { - libc::F_RDLCK - }; - - let mut flock: libc::flock = unsafe { mem::zeroed() }; - flock.l_type = lock_type as libc::c_short; - flock.l_whence = libc::SEEK_SET as libc::c_short; - flock.l_start = 0; - flock.l_len = 0; - - let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK }; - let ret = unsafe { - libc::fcntl(file.as_raw_fd(), cmd, &flock) - }; - if ret == -1 { - Err(io::Error::last_os_error()) - } else { - Ok(Lock { file }) - } - } - - pub fn error_unsupported(err: &io::Error) -> bool { - matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS)) - } - } - - impl Drop for Lock { - fn drop(&mut self) { - let mut flock: libc::flock = unsafe { mem::zeroed() }; - flock.l_type = libc::F_UNLCK as libc::c_short; - flock.l_whence = libc::SEEK_SET as libc::c_short; - flock.l_start = 0; - flock.l_len = 0; - - unsafe { - libc::fcntl(self.file.as_raw_fd(), libc::F_SETLK, &flock); - } - } - } + mod unix; + use unix as imp; } else if #[cfg(windows)] { - use std::mem; - use std::os::windows::prelude::*; - - use winapi::shared::winerror::ERROR_INVALID_FUNCTION; - use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK}; - use winapi::um::fileapi::LockFileEx; - use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; - - #[derive(Debug)] - pub struct Lock { - _file: File, - } - - impl Lock { - pub fn new(p: &Path, - wait: bool, - create: bool, - exclusive: bool) - -> io::Result { - assert!(p.parent().unwrap().exists(), - "Parent directory of lock-file must exist: {}", - p.display()); - - let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; - - let mut open_options = OpenOptions::new(); - open_options.read(true) - .share_mode(share_mode); - - if create { - open_options.create(true) - .write(true); - } - - debug!("attempting to open lock file `{}`", p.display()); - let file = match open_options.open(p) { - Ok(file) => { - debug!("lock file opened successfully"); - file - } - Err(err) => { - debug!("error opening lock file: {}", err); - return Err(err) - } - }; - - let ret = unsafe { - let mut overlapped: OVERLAPPED = mem::zeroed(); - - let mut dwFlags = 0; - if !wait { - dwFlags |= LOCKFILE_FAIL_IMMEDIATELY; - } - - if exclusive { - dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; - } - - debug!("attempting to acquire lock on lock file `{}`", - p.display()); - LockFileEx(file.as_raw_handle(), - dwFlags, - 0, - 0xFFFF_FFFF, - 0xFFFF_FFFF, - &mut overlapped) - }; - if ret == 0 { - let err = io::Error::last_os_error(); - debug!("failed acquiring file lock: {}", err); - Err(err) - } else { - debug!("successfully acquired lock"); - Ok(Lock { _file: file }) - } - } - - pub fn error_unsupported(err: &io::Error) -> bool { - err.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32) - } - } - - // Note that we don't need a Drop impl on the Windows: The file is unlocked - // automatically when it's closed. + mod windows; + use windows as imp; } else { - #[derive(Debug)] - pub struct Lock(()); - - impl Lock { - pub fn new(_p: &Path, _wait: bool, _create: bool, _exclusive: bool) - -> io::Result - { - let msg = "file locks not supported on this platform"; - Err(io::Error::new(io::ErrorKind::Other, msg)) - } - - pub fn error_unsupported(_err: &io::Error) -> bool { - true - } - } + mod unsupported; + use unsupported as imp; } } + +pub use imp::Lock; diff --git a/compiler/rustc_data_structures/src/flock/linux.rs b/compiler/rustc_data_structures/src/flock/linux.rs new file mode 100644 index 0000000000000..bb3ecfbc370c0 --- /dev/null +++ b/compiler/rustc_data_structures/src/flock/linux.rs @@ -0,0 +1,40 @@ +//! We use `flock` rather than `fcntl` on Linux, because WSL1 does not support +//! `fcntl`-style advisory locks properly (rust-lang/rust#72157). For other Unix +//! targets we still use `fcntl` because it's more portable than `flock`. + +use std::fs::{File, OpenOptions}; +use std::io; +use std::os::unix::prelude::*; +use std::path::Path; + +#[derive(Debug)] +pub struct Lock { + _file: File, +} + +impl Lock { + pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result { + let file = OpenOptions::new() + .read(true) + .write(true) + .create(create) + .mode(libc::S_IRWXU as u32) + .open(p)?; + + let mut operation = if exclusive { libc::LOCK_EX } else { libc::LOCK_SH }; + if !wait { + operation |= libc::LOCK_NB + } + + let ret = unsafe { libc::flock(file.as_raw_fd(), operation) }; + if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { _file: file }) } + } + + pub fn error_unsupported(err: &io::Error) -> bool { + matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS)) + } +} + +// Note that we don't need a Drop impl to execute `flock(fd, LOCK_UN)`. A lock acquired by +// `flock` is associated with the file descriptor and closing the file releases it +// automatically. diff --git a/compiler/rustc_data_structures/src/flock/unix.rs b/compiler/rustc_data_structures/src/flock/unix.rs new file mode 100644 index 0000000000000..4e5297d582e07 --- /dev/null +++ b/compiler/rustc_data_structures/src/flock/unix.rs @@ -0,0 +1,51 @@ +use std::fs::{File, OpenOptions}; +use std::io; +use std::mem; +use std::os::unix::prelude::*; +use std::path::Path; + +#[derive(Debug)] +pub struct Lock { + file: File, +} + +impl Lock { + pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result { + let file = OpenOptions::new() + .read(true) + .write(true) + .create(create) + .mode(libc::S_IRWXU as u32) + .open(p)?; + + let lock_type = if exclusive { libc::F_WRLCK } else { libc::F_RDLCK }; + + let mut flock: libc::flock = unsafe { mem::zeroed() }; + flock.l_type = lock_type as libc::c_short; + flock.l_whence = libc::SEEK_SET as libc::c_short; + flock.l_start = 0; + flock.l_len = 0; + + let cmd = if wait { libc::F_SETLKW } else { libc::F_SETLK }; + let ret = unsafe { libc::fcntl(file.as_raw_fd(), cmd, &flock) }; + if ret == -1 { Err(io::Error::last_os_error()) } else { Ok(Lock { file }) } + } + + pub fn error_unsupported(err: &io::Error) -> bool { + matches!(err.raw_os_error(), Some(libc::ENOTSUP) | Some(libc::ENOSYS)) + } +} + +impl Drop for Lock { + fn drop(&mut self) { + let mut flock: libc::flock = unsafe { mem::zeroed() }; + flock.l_type = libc::F_UNLCK as libc::c_short; + flock.l_whence = libc::SEEK_SET as libc::c_short; + flock.l_start = 0; + flock.l_len = 0; + + unsafe { + libc::fcntl(self.file.as_raw_fd(), libc::F_SETLK, &flock); + } + } +} diff --git a/compiler/rustc_data_structures/src/flock/unsupported.rs b/compiler/rustc_data_structures/src/flock/unsupported.rs new file mode 100644 index 0000000000000..9245fca373dfc --- /dev/null +++ b/compiler/rustc_data_structures/src/flock/unsupported.rs @@ -0,0 +1,16 @@ +use std::io; +use std::path::Path; + +#[derive(Debug)] +pub struct Lock(()); + +impl Lock { + pub fn new(_p: &Path, _wait: bool, _create: bool, _exclusive: bool) -> io::Result { + let msg = "file locks not supported on this platform"; + Err(io::Error::new(io::ErrorKind::Other, msg)) + } + + pub fn error_unsupported(_err: &io::Error) -> bool { + true + } +} diff --git a/compiler/rustc_data_structures/src/flock/windows.rs b/compiler/rustc_data_structures/src/flock/windows.rs new file mode 100644 index 0000000000000..43e6caaa18dcd --- /dev/null +++ b/compiler/rustc_data_structures/src/flock/windows.rs @@ -0,0 +1,77 @@ +use std::fs::{File, OpenOptions}; +use std::io; +use std::mem; +use std::os::windows::prelude::*; +use std::path::Path; + +use winapi::shared::winerror::ERROR_INVALID_FUNCTION; +use winapi::um::fileapi::LockFileEx; +use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, OVERLAPPED}; +use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; + +#[derive(Debug)] +pub struct Lock { + _file: File, +} + +impl Lock { + pub fn new(p: &Path, wait: bool, create: bool, exclusive: bool) -> io::Result { + assert!( + p.parent().unwrap().exists(), + "Parent directory of lock-file must exist: {}", + p.display() + ); + + let share_mode = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE; + + let mut open_options = OpenOptions::new(); + open_options.read(true).share_mode(share_mode); + + if create { + open_options.create(true).write(true); + } + + debug!("attempting to open lock file `{}`", p.display()); + let file = match open_options.open(p) { + Ok(file) => { + debug!("lock file opened successfully"); + file + } + Err(err) => { + debug!("error opening lock file: {}", err); + return Err(err); + } + }; + + let ret = unsafe { + let mut overlapped: OVERLAPPED = mem::zeroed(); + + let mut dwFlags = 0; + if !wait { + dwFlags |= LOCKFILE_FAIL_IMMEDIATELY; + } + + if exclusive { + dwFlags |= LOCKFILE_EXCLUSIVE_LOCK; + } + + debug!("attempting to acquire lock on lock file `{}`", p.display()); + LockFileEx(file.as_raw_handle(), dwFlags, 0, 0xFFFF_FFFF, 0xFFFF_FFFF, &mut overlapped) + }; + if ret == 0 { + let err = io::Error::last_os_error(); + debug!("failed acquiring file lock: {}", err); + Err(err) + } else { + debug!("successfully acquired lock"); + Ok(Lock { _file: file }) + } + } + + pub fn error_unsupported(err: &io::Error) -> bool { + err.raw_os_error() == Some(ERROR_INVALID_FUNCTION as i32) + } +} + +// Note that we don't need a Drop impl on Windows: The file is unlocked +// automatically when it's closed. diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 919b89396d678..6ec929f98950e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -1659,49 +1659,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.const_eval_resolve(param_env_erased, unevaluated, span) } - /// If `typ` is a type variable of some kind, resolve it one level - /// (but do not resolve types found in the result). If `typ` is - /// not a type variable, just return it unmodified. - // FIXME(eddyb) inline into `ShallowResolver::visit_ty`. - fn shallow_resolve_ty(&self, typ: Ty<'tcx>) -> Ty<'tcx> { - match *typ.kind() { - ty::Infer(ty::TyVar(v)) => { - // Not entirely obvious: if `typ` is a type variable, - // it can be resolved to an int/float variable, which - // can then be recursively resolved, hence the - // recursion. Note though that we prevent type - // variables from unifying to other type variables - // directly (though they may be embedded - // structurally), and we prevent cycles in any case, - // so this recursion should always be of very limited - // depth. - // - // Note: if these two lines are combined into one we get - // dynamic borrow errors on `self.inner`. - let known = self.inner.borrow_mut().type_variables().probe(v).known(); - known.map_or(typ, |t| self.shallow_resolve_ty(t)) - } - - ty::Infer(ty::IntVar(v)) => self - .inner - .borrow_mut() - .int_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.tcx)) - .unwrap_or(typ), - - ty::Infer(ty::FloatVar(v)) => self - .inner - .borrow_mut() - .float_unification_table() - .probe_value(v) - .map(|v| v.to_type(self.tcx)) - .unwrap_or(typ), - - _ => typ, - } - } - /// `ty_or_const_infer_var_changed` is equivalent to one of these two: /// * `shallow_resolve(ty) != ty` (where `ty.kind = ty::Infer(_)`) /// * `shallow_resolve(ct) != ct` (where `ct.kind = ty::ConstKind::Infer(_)`) @@ -1831,8 +1788,46 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { self.infcx.tcx } + /// If `ty` is a type variable of some kind, resolve it one level + /// (but do not resolve types found in the result). If `typ` is + /// not a type variable, just return it unmodified. fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.infcx.shallow_resolve_ty(ty) + match *ty.kind() { + ty::Infer(ty::TyVar(v)) => { + // Not entirely obvious: if `typ` is a type variable, + // it can be resolved to an int/float variable, which + // can then be recursively resolved, hence the + // recursion. Note though that we prevent type + // variables from unifying to other type variables + // directly (though they may be embedded + // structurally), and we prevent cycles in any case, + // so this recursion should always be of very limited + // depth. + // + // Note: if these two lines are combined into one we get + // dynamic borrow errors on `self.inner`. + let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known(); + known.map_or(ty, |t| self.fold_ty(t)) + } + + ty::Infer(ty::IntVar(v)) => self + .infcx + .inner + .borrow_mut() + .int_unification_table() + .probe_value(v) + .map_or(ty, |v| v.to_type(self.infcx.tcx)), + + ty::Infer(ty::FloatVar(v)) => self + .infcx + .inner + .borrow_mut() + .float_unification_table() + .probe_value(v) + .map_or(ty, |v| v.to_type(self.infcx.tcx)), + + _ => ty, + } } fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index fae22c28628f8..195760c059081 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -1,5 +1,5 @@ use super::ScalarInt; -use rustc_macros::HashStable; +use rustc_macros::{HashStable, TyDecodable, TyEncodable}; #[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] #[derive(HashStable)] diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index f1956fb695bf7..cb6be8f412cf5 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1125,13 +1125,13 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::inline_const, span); } self.eat_keyword(kw::Const); - let blk = self.parse_block()?; + let (attrs, blk) = self.parse_inner_attrs_and_block()?; let anon_const = AnonConst { id: DUMMY_NODE_ID, value: self.mk_expr(blk.span, ExprKind::Block(blk, None), AttrVec::new()), }; let blk_span = anon_const.value.span; - Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::new())) + Ok(self.mk_expr(span.to(blk_span), ExprKind::ConstBlock(anon_const), AttrVec::from(attrs))) } /// Parses mutability (`mut` or nothing). diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c45326e1e6e6c..a9444972130a8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -80,6 +80,7 @@ impl CheckAttrVisitor<'_> { self.check_rustc_must_implement_one_of(attr, span, target) } sym::target_feature => self.check_target_feature(hir_id, attr, span, target), + sym::thread_local => self.check_thread_local(attr, span, target), sym::track_caller => { self.check_track_caller(hir_id, attr.span, attrs, span, target) } @@ -523,6 +524,21 @@ impl CheckAttrVisitor<'_> { } } + /// Checks if the `#[thread_local]` attribute on `item` is valid. Returns `true` if valid. + fn check_thread_local(&self, attr: &Attribute, span: Span, target: Target) -> bool { + match target { + Target::ForeignStatic | Target::Static => true, + _ => { + self.tcx + .sess + .struct_span_err(attr.span, "attribute should be applied to a static") + .span_label(span, "not a static") + .emit(); + false + } + } + } + fn doc_attr_str_error(&self, meta: &NestedMetaItem, attr_name: &str) { self.tcx .sess diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 62f3527525e0e..fffd94992093b 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -116,7 +116,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { name: None, attrs: Default::default(), visibility: Inherited, - def_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, + item_id: ItemId::Auto { trait_: trait_def_id, for_: item_def_id }, kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: new_generics, diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index 6f4b87750ff85..f0d87f7ce4cd5 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -105,7 +105,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { name: None, attrs: Default::default(), visibility: Inherited, - def_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, + item_id: ItemId::Blanket { impl_id: impl_def_id, for_: item_def_id }, kind: box ImplItem(Impl { unsafety: hir::Unsafety::Normal, generics: clean_ty_generics( diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 33db6583125ef..261eb39bf723d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -534,7 +534,7 @@ fn build_module( items.push(clean::Item { name: None, attrs: box clean::Attributes::default(), - def_id: ItemId::Primitive(prim_ty, did.krate), + item_id: ItemId::Primitive(prim_ty, did.krate), visibility: clean::Public, kind: box clean::ImportItem(clean::Import::new_simple( item.ident.name, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a6763d2827cec..21016afbf5f99 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2009,7 +2009,7 @@ fn clean_extern_crate( vec![Item { name: Some(name), attrs: box attrs.clean(cx), - def_id: crate_def_id.into(), + item_id: crate_def_id.into(), visibility: ty_vis.clean(cx), kind: box ExternCrateItem { src: orig_name }, cfg: attrs.cfg(cx.tcx, &cx.cache.hidden_cfg), diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index d2abfc35b932c..4b473df155f58 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -366,7 +366,7 @@ crate struct Item { /// Information about this item that is specific to what kind of item it is. /// E.g., struct vs enum vs function. crate kind: Box, - crate def_id: ItemId, + crate item_id: ItemId, crate cfg: Option>, } @@ -380,7 +380,7 @@ impl fmt::Debug for Item { let mut fmt = f.debug_struct("Item"); fmt.field("name", &self.name) .field("visibility", &self.visibility) - .field("def_id", &self.def_id); + .field("item_id", &self.item_id); // allow printing the full item if someone really wants to if alternate { fmt.field("attrs", &self.attrs).field("kind", &self.kind).field("cfg", &self.cfg); @@ -408,19 +408,19 @@ crate fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span { impl Item { crate fn stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { - self.def_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) + self.item_id.as_def_id().and_then(|did| tcx.lookup_stability(did)) } crate fn const_stability<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Option { - self.def_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did)) + self.item_id.as_def_id().and_then(|did| tcx.lookup_const_stability(did)) } crate fn deprecation(&self, tcx: TyCtxt<'_>) -> Option { - self.def_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did)) + self.item_id.as_def_id().and_then(|did| tcx.lookup_deprecation(did)) } crate fn inner_docs(&self, tcx: TyCtxt<'_>) -> bool { - self.def_id.as_def_id().map(|did| tcx.get_attrs(did).inner_docs()).unwrap_or(false) + self.item_id.as_def_id().map(|did| tcx.get_attrs(did).inner_docs()).unwrap_or(false) } crate fn span(&self, tcx: TyCtxt<'_>) -> Span { @@ -432,14 +432,14 @@ impl Item { ItemKind::ModuleItem(Module { span, .. }) => *span, ItemKind::ImplItem(Impl { kind: ImplKind::Auto, .. }) => Span::dummy(), ItemKind::ImplItem(Impl { kind: ImplKind::Blanket(_), .. }) => { - if let ItemId::Blanket { impl_id, .. } = self.def_id { + if let ItemId::Blanket { impl_id, .. } = self.item_id { rustc_span(impl_id, tcx) } else { panic!("blanket impl item has non-blanket ID") } } _ => { - self.def_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy) + self.item_id.as_def_id().map(|did| rustc_span(did, tcx)).unwrap_or_else(Span::dummy) } } } @@ -503,7 +503,7 @@ impl Item { cx.tcx.visibility(def_id).clean(cx) }; - Item { def_id: def_id.into(), kind: box kind, name, attrs, visibility, cfg } + Item { item_id: def_id.into(), kind: box kind, name, attrs, visibility, cfg } } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined @@ -517,7 +517,7 @@ impl Item { cx.cache() .intra_doc_links - .get(&self.def_id) + .get(&self.item_id) .map_or(&[][..], |v| v.as_slice()) .iter() .filter_map(|ItemLink { link: s, link_text, did, ref fragment }| { @@ -547,7 +547,7 @@ impl Item { crate fn link_names(&self, cache: &Cache) -> Vec { cache .intra_doc_links - .get(&self.def_id) + .get(&self.item_id) .map_or(&[][..], |v| v.as_slice()) .iter() .map(|ItemLink { link: s, link_text, .. }| RenderedLink { @@ -559,7 +559,7 @@ impl Item { } crate fn is_crate(&self) -> bool { - self.is_mod() && self.def_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.index == CRATE_DEF_INDEX) } crate fn is_mod(&self) -> bool { self.type_() == ItemType::Module @@ -695,7 +695,7 @@ impl Item { } let header = match *self.kind { ItemKind::ForeignFunctionItem(_) => { - let abi = tcx.fn_sig(self.def_id.as_def_id().unwrap()).abi(); + let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi(); hir::FnHeader { unsafety: if abi == Abi::RustIntrinsic { intrinsic_operation_unsafety(self.name.unwrap()) @@ -708,11 +708,11 @@ impl Item { } } ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => { - let def_id = self.def_id.as_def_id().unwrap(); + let def_id = self.item_id.as_def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } ItemKind::TyMethodItem(_) => { - build_fn_header(self.def_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync) + build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync) } _ => return None, }; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index fe6d680991f80..abfc5b80a3ef0 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -44,9 +44,9 @@ crate fn krate(cx: &mut DocContext<'_>) -> Crate { // `#[doc(masked)]` to the injected `extern crate` because it's unstable. if it.is_extern_crate() && (it.attrs.has_doc_flag(sym::masked) - || cx.tcx.is_compiler_builtins(it.def_id.krate())) + || cx.tcx.is_compiler_builtins(it.item_id.krate())) { - cx.cache.masked_crates.insert(it.def_id.krate()); + cx.cache.masked_crates.insert(it.item_id.krate()); } } } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 81c11dc30cb58..b9e20c41b681f 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -113,8 +113,8 @@ impl<'tcx> DocContext<'tcx> { /// Like `hir().local_def_id_to_hir_id()`, but skips calling it on fake DefIds. /// (This avoids a slice-index-out-of-bounds panic.) - crate fn as_local_hir_id(tcx: TyCtxt<'_>, def_id: ItemId) -> Option { - match def_id { + crate fn as_local_hir_id(tcx: TyCtxt<'_>, item_id: ItemId) -> Option { + match item_id { ItemId::DefId(real_id) => { real_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id)) } @@ -390,7 +390,7 @@ crate fn run_global_ctxt( ); tcx.struct_lint_node( crate::lint::MISSING_CRATE_LEVEL_DOCS, - DocContext::as_local_hir_id(tcx, krate.module.def_id).unwrap(), + DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(), |lint| { let mut diag = lint.build("no documentation found for this crate's top-level module"); diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 663e18fe9129f..e138e434c4e04 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -186,8 +186,8 @@ impl Cache { impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { fn fold_item(&mut self, item: clean::Item) -> Option { - if item.def_id.is_local() { - debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id); + if item.item_id.is_local() { + debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.item_id); } // If this is a stripped module, @@ -202,7 +202,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // If the impl is from a masked crate or references something from a // masked crate then remove it completely. if let clean::ImplItem(ref i) = *item.kind { - if self.cache.masked_crates.contains(&item.def_id.krate()) + if self.cache.masked_crates.contains(&item.item_id.krate()) || i.trait_ .as_ref() .map_or(false, |t| self.cache.masked_crates.contains(&t.def_id().krate)) @@ -217,7 +217,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // Propagate a trait method's documentation to all implementors of the // trait. if let clean::TraitItem(ref t) = *item.kind { - self.cache.traits.entry(item.def_id.expect_def_id()).or_insert_with(|| { + self.cache.traits.entry(item.item_id.expect_def_id()).or_insert_with(|| { clean::TraitWithExtraInfo { trait_: t.clone(), is_notable: item.attrs.has_doc_flag(sym::notable_trait), @@ -293,7 +293,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // 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.def_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) { + if item.item_id.index().map_or(false, |idx| idx != CRATE_DEF_INDEX) { let desc = item.doc_value().map_or_else(String::new, |x| { short_markdown_summary(x.as_str(), &item.link_names(self.cache)) }); @@ -351,11 +351,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { // `public_items` map, so we can skip inserting into the // paths map if there was already an entry present and we're // not a public item. - if !self.cache.paths.contains_key(&item.def_id.expect_def_id()) - || self.cache.access_levels.is_public(item.def_id.expect_def_id()) + if !self.cache.paths.contains_key(&item.item_id.expect_def_id()) + || self.cache.access_levels.is_public(item.item_id.expect_def_id()) { self.cache.paths.insert( - item.def_id.expect_def_id(), + item.item_id.expect_def_id(), (self.cache.stack.clone(), item.type_()), ); } @@ -364,7 +364,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { clean::PrimitiveItem(..) => { self.cache .paths - .insert(item.def_id.expect_def_id(), (self.cache.stack.clone(), item.type_())); + .insert(item.item_id.expect_def_id(), (self.cache.stack.clone(), item.type_())); } clean::ExternCrateItem { .. } @@ -396,7 +396,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { | clean::StructItem(..) | clean::UnionItem(..) | clean::VariantItem(..) => { - self.cache.parent_stack.push(item.def_id.expect_def_id()); + self.cache.parent_stack.push(item.item_id.expect_def_id()); self.cache.parent_is_trait_impl = false; true } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 90123655758cc..8e643107353dd 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -222,7 +222,7 @@ impl<'tcx> Context<'tcx> { &self.shared.style_files, ) } else { - if let Some(&(ref names, ty)) = self.cache().paths.get(&it.def_id.expect_def_id()) { + if let Some(&(ref names, ty)) = self.cache().paths.get(&it.item_id.expect_def_id()) { if self.current.len() + 1 != names.len() || self.current.iter().zip(names.iter()).any(|(a, b)| a != b) { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a4cc42e2a0185..7a4289b8e60e9 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -830,7 +830,7 @@ fn assoc_const( w, "{extra}{vis}const {name}: {ty}", extra = extra, - vis = it.visibility.print_with_space(it.def_id, cx), + vis = it.visibility.print_with_space(it.item_id, cx), href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), ty = ty.print(cx), @@ -884,7 +884,7 @@ fn assoc_method( ) { let header = meth.fn_header(cx.tcx()).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string(); + let vis = meth.visibility.print_with_space(meth.item_id, cx).to_string(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. let constness = match render_mode { @@ -2060,7 +2060,7 @@ fn small_url_encode(s: String) -> String { } fn sidebar_assoc_items(cx: &Context<'_>, out: &mut Buffer, it: &clean::Item) { - let did = it.def_id.expect_def_id(); + let did = it.item_id.expect_def_id(); let cache = cx.cache(); if let Some(v) = cache.impls.get(&did) { @@ -2412,7 +2412,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean ); let cache = cx.cache(); - if let Some(implementors) = cache.implementors.get(&it.def_id.expect_def_id()) { + if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) { let mut res = implementors .iter() .filter(|i| { @@ -2761,7 +2761,7 @@ const NUM_VISIBLE_LINES: usize = 10; /// Generates the HTML for example call locations generated via the --scrape-examples flag. fn render_call_locations(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item) { let tcx = cx.tcx(); - let def_id = item.def_id.expect_def_id(); + let def_id = item.item_id.expect_def_id(); let key = tcx.def_path_hash(def_id); let Some(call_locations) = cx.shared.call_locations.get(&key) else { return }; diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 1ed5c662c41cc..f1915920b6d05 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -264,7 +264,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl // (which is the position in the vector). indices.dedup_by_key(|i| { ( - items[*i].def_id, + items[*i].item_id, if items[*i].name.is_some() { Some(full_path(cx, &items[*i])) } else { None }, items[*i].type_(), if items[*i].is_import() { *i } else { 0 }, @@ -306,15 +306,15 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl Some(src) => write!( w, "
{}extern crate {} as {};", - myitem.visibility.print_with_space(myitem.def_id, cx), - anchor(myitem.def_id.expect_def_id(), src, cx), + myitem.visibility.print_with_space(myitem.item_id, cx), + anchor(myitem.item_id.expect_def_id(), src, cx), myitem.name.unwrap(), ), None => write!( w, "
{}extern crate {};", - myitem.visibility.print_with_space(myitem.def_id, cx), - anchor(myitem.def_id.expect_def_id(), myitem.name.unwrap(), cx), + myitem.visibility.print_with_space(myitem.item_id, cx), + anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx), ), } w.write_str("
"); @@ -328,7 +328,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl // Just need an item with the correct def_id and attrs let import_item = clean::Item { - def_id: import_def_id.into(), + item_id: import_def_id.into(), attrs: import_attrs, cfg: ast_attrs.cfg(cx.tcx(), &cx.cache().hidden_cfg), ..myitem.clone() @@ -352,7 +352,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
{stab_tags}
", stab = stab.unwrap_or_default(), add = add, - vis = myitem.visibility.print_with_space(myitem.def_id, cx), + vis = myitem.visibility.print_with_space(myitem.item_id, cx), imp = import.print(cx), stab_tags = stab_tags.unwrap_or_default(), ); @@ -468,7 +468,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: let unsafety = header.unsafety.print_with_space(); let abi = print_abi_with_space(header.abi).to_string(); let asyncness = header.asyncness.print_with_space(); - let visibility = it.visibility.print_with_space(it.def_id, cx).to_string(); + let visibility = it.visibility.print_with_space(it.item_id, cx).to_string(); let name = it.name.unwrap(); let generics_len = format!("{:#}", f.generics.print(cx)).len(); @@ -524,7 +524,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra write!( w, "{}{}{}trait {}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility.print_with_space(it.item_id, cx), t.unsafety.print_with_space(), if t.is_auto { "auto " } else { "" }, it.name.unwrap(), @@ -787,10 +787,10 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All); + render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All); let cache = cx.cache(); - if let Some(implementors) = cache.implementors.get(&it.def_id.expect_def_id()) { + if let Some(implementors) = cache.implementors.get(&it.item_id.expect_def_id()) { // The DefId is for the first Type found with that name. The bool is // if any Types with the same name but different DefId have been found. let mut implementor_dups: FxHashMap = FxHashMap::default(); @@ -827,7 +827,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra for implementor in foreign { let provided_methods = implementor.inner_impl().provided_trait_methods(cx.tcx()); let assoc_link = - AssocItemLink::GotoSource(implementor.impl_item.def_id, &provided_methods); + AssocItemLink::GotoSource(implementor.impl_item.item_id, &provided_methods); render_impl( w, cx, @@ -902,10 +902,10 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra .take(cx.current.len()) .chain(std::iter::once("implementors")) .collect(); - if it.def_id.is_local() { + if it.item_id.is_local() { js_src_path.extend(cx.current.iter().copied()); } else { - let (ref path, _) = cache.external_paths[&it.def_id.expect_def_id()]; + let (ref path, _) = cache.external_paths[&it.item_id.expect_def_id()]; js_src_path.extend(path[..path.len() - 1].iter().copied()); } js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), it.name.unwrap())); @@ -937,7 +937,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All) + render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All) } fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) { @@ -961,14 +961,14 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean: // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All) + render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); - write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); + write!(w, "{}", it.visibility.print_with_space(it.item_id, cx)); write!( w, "type {}{}{where_clause} = {type_};", @@ -984,7 +984,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::T document(w, cx, it, None, HeadingOffset::H2); - let def_id = it.def_id.expect_def_id(); + let def_id = it.item_id.expect_def_id(); // Render any items associated directly to this alias, as otherwise they // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but @@ -1037,7 +1037,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni document(w, cx, field, Some(it), HeadingOffset::H3); } } - let def_id = it.def_id.expect_def_id(); + let def_id = it.item_id.expect_def_id(); render_assoc_items(w, cx, it, def_id, AssocItemRender::All); document_type_layout(w, cx, def_id); } @@ -1062,7 +1062,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum write!( w, "{}enum {}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility.print_with_space(it.item_id, cx), it.name.unwrap(), e.generics.print(cx), print_where_clause(&e.generics, cx, 0, true), @@ -1197,7 +1197,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum document(w, cx, variant, Some(it), HeadingOffset::H4); } } - let def_id = it.def_id.expect_def_id(); + let def_id = it.item_id.expect_def_id(); render_assoc_items(w, cx, it, def_id, AssocItemRender::All); document_type_layout(w, cx, def_id); } @@ -1253,7 +1253,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { document(w, cx, it, None, HeadingOffset::H2); - render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All) + render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All) } fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) { @@ -1264,7 +1264,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean:: write!( w, "{vis}const {name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), + vis = it.visibility.print_with_space(it.item_id, cx), name = it.name.unwrap(), typ = c.type_.print(cx), ); @@ -1344,7 +1344,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St } } } - let def_id = it.def_id.expect_def_id(); + let def_id = it.item_id.expect_def_id(); render_assoc_items(w, cx, it, def_id, AssocItemRender::All); document_type_layout(w, cx, def_id); } @@ -1356,7 +1356,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St write!( w, "{vis}static {mutability}{name}: {typ}", - vis = it.visibility.print_with_space(it.def_id, cx), + vis = it.visibility.print_with_space(it.item_id, cx), mutability = s.mutability.print_with_space(), name = it.name.unwrap(), typ = s.type_.print(cx) @@ -1374,7 +1374,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { write!( w, " {}type {};\n}}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility.print_with_space(it.item_id, cx), it.name.unwrap(), ); }); @@ -1382,7 +1382,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { document(w, cx, it, None, HeadingOffset::H2); - render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All) + render_assoc_items(w, cx, it, it.item_id.expect_def_id(), AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) { @@ -1543,7 +1543,7 @@ fn render_union( tab: &str, cx: &Context<'_>, ) { - write!(w, "{}union {}", it.visibility.print_with_space(it.def_id, cx), it.name.unwrap()); + write!(w, "{}union {}", it.visibility.print_with_space(it.item_id, cx), it.name.unwrap()); if let Some(g) = g { write!(w, "{}", g.print(cx)); write!(w, "{}", print_where_clause(g, cx, 0, true)); @@ -1562,7 +1562,7 @@ fn render_union( write!( w, " {}{}: {},\n{}", - field.visibility.print_with_space(field.def_id, cx), + field.visibility.print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), tab @@ -1592,7 +1592,7 @@ fn render_struct( write!( w, "{}{}{}", - it.visibility.print_with_space(it.def_id, cx), + it.visibility.print_with_space(it.item_id, cx), if structhead { "struct " } else { "" }, it.name.unwrap() ); @@ -1618,7 +1618,7 @@ fn render_struct( w, "\n{} {}{}: {},", tab, - field.visibility.print_with_space(field.def_id, cx), + field.visibility.print_with_space(field.item_id, cx), field.name.unwrap(), ty.print(cx), ); @@ -1650,7 +1650,7 @@ fn render_struct( write!( w, "{}{}", - field.visibility.print_with_space(field.def_id, cx), + field.visibility.print_with_space(field.item_id, cx), ty.print(cx), ) } diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 3fa16c6c3b880..371d0e8408754 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -535,7 +535,7 @@ pub(super) fn write_shared( // // If the implementation is from another crate then that crate // should add it. - if imp.impl_item.def_id.krate() == did.krate || !imp.impl_item.def_id.is_local() { + if imp.impl_item.item_id.krate() == did.krate || !imp.impl_item.item_id.is_local() { None } else { Some(Implementor { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index a9a6a31fccd0d..0b5fb48059579 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -27,7 +27,7 @@ impl JsonRenderer<'_> { let links = self .cache .intra_doc_links - .get(&item.def_id) + .get(&item.item_id) .into_iter() .flatten() .map(|clean::ItemLink { link, did, .. }| (link.clone(), from_item_id((*did).into()))) @@ -40,14 +40,14 @@ impl JsonRenderer<'_> { .map(rustc_ast_pretty::pprust::attribute_to_string) .collect(); let span = item.span(self.tcx); - let clean::Item { name, attrs: _, kind: _, visibility, def_id, cfg: _ } = item; + let clean::Item { name, attrs: _, kind: _, visibility, item_id, cfg: _ } = item; let inner = match *item.kind { clean::StrippedItem(_) => return None, _ => from_clean_item(item, self.tcx), }; Some(Item { - id: from_item_id(def_id), - crate_id: def_id.krate().as_u32(), + id: from_item_id(item_id), + crate_id: item_id.krate().as_u32(), name: name.map(|sym| sym.to_string()), span: self.convert_span(span), visibility: self.convert_visibility(visibility), @@ -174,7 +174,7 @@ impl FromWithTcx for TypeBindingKind { } } -crate fn from_item_id(did: ItemId) -> Id { +crate fn from_item_id(item_id: ItemId) -> Id { struct DisplayDefId(DefId); impl fmt::Display for DisplayDefId { @@ -183,7 +183,7 @@ crate fn from_item_id(did: ItemId) -> Id { } } - match did { + match item_id { ItemId::DefId(did) => Id(format!("{}", DisplayDefId(did))), ItemId::Blanket { for_, impl_id } => { Id(format!("b:{}-{}", DisplayDefId(impl_id), DisplayDefId(for_))) @@ -732,5 +732,5 @@ impl FromWithTcx for ItemKind { } fn ids(items: impl IntoIterator) -> Vec { - items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_item_id(i.def_id)).collect() + items.into_iter().filter(|x| !x.is_stripped()).map(|i| from_item_id(i.item_id)).collect() } diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 126c5d89ca97c..e6e5bba7f0067 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -54,7 +54,7 @@ impl<'tcx> JsonRenderer<'tcx> { .map(|i| { let item = &i.impl_item; self.item(item.clone()).unwrap(); - from_item_id(item.def_id) + from_item_id(item.item_id) }) .collect() }) @@ -84,9 +84,9 @@ impl<'tcx> JsonRenderer<'tcx> { } } - if item.def_id.is_local() || is_primitive_impl { + if item.item_id.is_local() || is_primitive_impl { self.item(item.clone()).unwrap(); - Some(from_item_id(item.def_id)) + Some(from_item_id(item.item_id)) } else { None } @@ -176,18 +176,18 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { // Flatten items that recursively store other items item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap()); - let id = item.def_id; + let item_id = item.item_id; if let Some(mut new_item) = self.convert_item(item) { if let types::ItemEnum::Trait(ref mut t) = new_item.inner { - t.implementations = self.get_trait_implementors(id.expect_def_id()) + t.implementations = self.get_trait_implementors(item_id.expect_def_id()) } else if let types::ItemEnum::Struct(ref mut s) = new_item.inner { - s.impls = self.get_impls(id.expect_def_id()) + s.impls = self.get_impls(item_id.expect_def_id()) } else if let types::ItemEnum::Enum(ref mut e) = new_item.inner { - e.impls = self.get_impls(id.expect_def_id()) + e.impls = self.get_impls(item_id.expect_def_id()) } else if let types::ItemEnum::Union(ref mut u) = new_item.inner { - u.impls = self.get_impls(id.expect_def_id()) + u.impls = self.get_impls(item_id.expect_def_id()) } - let removed = self.index.borrow_mut().insert(from_item_id(id), new_item.clone()); + let removed = self.index.borrow_mut().insert(from_item_id(item_id), new_item.clone()); // FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check // to make sure the items are unique. The main place this happens is when an item, is diff --git a/src/librustdoc/passes/bare_urls.rs b/src/librustdoc/passes/bare_urls.rs index 81f371840ae46..1839a35a8b14b 100644 --- a/src/librustdoc/passes/bare_urls.rs +++ b/src/librustdoc/passes/bare_urls.rs @@ -61,7 +61,7 @@ crate fn check_bare_urls(krate: Crate, cx: &mut DocContext<'_>) -> Crate { impl<'a, 'tcx> DocVisitor for BareUrlsLinter<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { - let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.def_id) + let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else { // If non-local, no need to check anything. return; diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 6111c982de922..33d83aa339d95 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -185,7 +185,7 @@ impl<'a, 'b> CoverageCalculator<'a, 'b> { impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { fn visit_item(&mut self, i: &clean::Item) { - if !i.def_id.is_local() { + if !i.item_id.is_local() { // non-local items are skipped because they can be out of the users control, // especially in the case of trait impls, which rustdoc eagerly inlines return; @@ -223,7 +223,7 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { .ctx .tcx .hir() - .local_def_id_to_hir_id(i.def_id.expect_def_id().expect_local()); + .local_def_id_to_hir_id(i.item_id.expect_def_id().expect_local()); let (level, source) = self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id); // In case we have: @@ -237,7 +237,7 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { // there is no need to require documentation on the fields of tuple variants and // tuple structs. let should_be_ignored = i - .def_id + .item_id .as_def_id() .and_then(|def_id| self.ctx.tcx.parent(def_id)) .and_then(|def_id| self.ctx.tcx.hir().get_if_local(def_id)) diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs index d66dfca07f186..23d947c4d7227 100644 --- a/src/librustdoc/passes/check_code_block_syntax.rs +++ b/src/librustdoc/passes/check_code_block_syntax.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> { return; } - let Some(local_id) = item.def_id.as_def_id().and_then(|x| x.as_local()) + let Some(local_id) = item.item_id.as_def_id().and_then(|x| x.as_local()) else { // We don't need to check the syntax for other crates so returning // without doing anything should not be a problem. @@ -153,7 +153,7 @@ impl<'a, 'tcx> DocVisitor for SyntaxChecker<'a, 'tcx> { let sp = item.attr_span(self.cx.tcx); let extra = crate::html::markdown::ExtraInfo::new_did( self.cx.tcx, - item.def_id.expect_def_id(), + item.item_id.expect_def_id(), sp, ); for code_block in markdown::rust_code_blocks(dox, &extra) { diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs index b541fb63bd413..80a2683fde7f4 100644 --- a/src/librustdoc/passes/check_doc_test_visibility.rs +++ b/src/librustdoc/passes/check_doc_test_visibility.rs @@ -56,7 +56,7 @@ impl crate::doctest::Tester for Tests { } crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> bool { - if !cx.cache.access_levels.is_public(item.def_id.expect_def_id()) + if !cx.cache.access_levels.is_public(item.item_id.expect_def_id()) || matches!( *item.kind, clean::StructFieldItem(_) @@ -79,7 +79,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo // The `expect_def_id()` should be okay because `local_def_id_to_hir_id` // would presumably panic if a fake `DefIndex` were passed. - let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.def_id.expect_def_id().expect_local()); + let hir_id = cx.tcx.hir().local_def_id_to_hir_id(item.item_id.expect_def_id().expect_local()); // check if parent is trait impl if let Some(parent_hir_id) = cx.tcx.hir().find_parent_node(hir_id) { @@ -107,7 +107,7 @@ crate fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -> boo } crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { - let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.def_id) + let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id) else { // If non-local, no need to check anything. return; @@ -131,7 +131,7 @@ crate fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item) { ); } } else if tests.found_tests > 0 - && !cx.cache.access_levels.is_exported(item.def_id.expect_def_id()) + && !cx.cache.access_levels.is_exported(item.item_id.expect_def_id()) { cx.tcx.struct_span_lint_hir( crate::lint::PRIVATE_DOC_TESTS, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c1b1139ad8cf9..c48f8bd0c7cc5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1025,15 +1025,15 @@ fn is_derive_trait_collision(ns: &PerNS DocVisitor for LinkCollector<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { let parent_node = - item.def_id.as_def_id().and_then(|did| find_nearest_parent_module(self.cx.tcx, did)); + item.item_id.as_def_id().and_then(|did| find_nearest_parent_module(self.cx.tcx, did)); if parent_node.is_some() { - trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.def_id); + trace!("got parent node for {:?} {:?}, id {:?}", item.type_(), item.name, item.item_id); } let inner_docs = item.inner_docs(self.cx.tcx); if item.is_mod() && inner_docs { - self.mod_ids.push(item.def_id.expect_def_id()); + self.mod_ids.push(item.item_id.expect_def_id()); } // We want to resolve in the lexical scope of the documentation. @@ -1048,14 +1048,14 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> { for md_link in markdown_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.def_id).or_default().push(link); + self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link); } } } if item.is_mod() { if !inner_docs { - self.mod_ids.push(item.def_id.expect_def_id()); + self.mod_ids.push(item.item_id.expect_def_id()); } self.visit_item_recur(item); @@ -1246,7 +1246,7 @@ impl LinkCollector<'_, '_> { let (mut res, fragment) = self.resolve_with_disambiguator_cached( ResolutionInfo { - item_id: item.def_id, + item_id: item.item_id, module_id, dis: disambiguator, path_str: path_str.to_owned(), @@ -1302,7 +1302,7 @@ impl LinkCollector<'_, '_> { // FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether. // However I'm not sure how to check that across crates. if prim == PrimitiveType::RawPointer - && item.def_id.is_local() + && item.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers { self.report_rawptr_assoc_feature_gate(dox, &ori_link, item); @@ -1386,7 +1386,7 @@ impl LinkCollector<'_, '_> { // The `expect_def_id()` should be okay because `local_def_id_to_hir_id` // would presumably panic if a fake `DefIndex` were passed. .and_then(|dst_id| { - item.def_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id)) + item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id)) }) { if self.cx.tcx.privacy_access_levels(()).is_exported(src_id) @@ -1864,7 +1864,7 @@ fn report_diagnostic( DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>, decorate: impl FnOnce(&mut Diagnostic, Option), ) { - let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.def_id) + let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else { // If non-local, no need to check anything. info!("ignoring warning from parent crate: {}", msg); diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 4ab942c8f1bdc..65459913eeaa8 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -52,7 +52,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate // FIXME(eddyb) is this `doc(hidden)` check needed? if !cx.tcx.is_doc_hidden(def_id) { let impls = get_auto_trait_and_blanket_impls(cx, def_id); - new_items.extend(impls.filter(|i| cx.inlined.insert(i.def_id))); + new_items.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); } } } @@ -176,9 +176,9 @@ impl<'a, 'tcx> DocVisitor for SyntheticImplCollector<'a, 'tcx> { fn visit_item(&mut self, i: &Item) { if i.is_struct() || i.is_enum() || i.is_union() { // FIXME(eddyb) is this `doc(hidden)` check needed? - if !self.cx.tcx.is_doc_hidden(i.def_id.expect_def_id()) { + if !self.cx.tcx.is_doc_hidden(i.item_id.expect_def_id()) { self.impls - .extend(get_auto_trait_and_blanket_impls(self.cx, i.def_id.expect_def_id())); + .extend(get_auto_trait_and_blanket_impls(self.cx, i.item_id.expect_def_id())); } } @@ -199,7 +199,7 @@ impl ItemCollector { impl DocVisitor for ItemCollector { fn visit_item(&mut self, i: &Item) { - self.items.insert(i.def_id); + self.items.insert(i.item_id); self.visit_item_recur(i) } @@ -225,7 +225,7 @@ impl<'a> BadImplStripper<'a> { } } - fn keep_impl_with_def_id(&self, did: ItemId) -> bool { - self.items.contains(&did) + fn keep_impl_with_def_id(&self, item_id: ItemId) -> bool { + self.items.contains(&item_id) } } diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs index a620ffa987860..044f224e7885c 100644 --- a/src/librustdoc/passes/html_tags.rs +++ b/src/librustdoc/passes/html_tags.rs @@ -197,7 +197,7 @@ fn extract_tags( impl<'a, 'tcx> DocVisitor for InvalidHtmlTagsLinter<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { let tcx = self.cx.tcx; - let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.def_id) + let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) // If non-local, no need to check anything. else { return }; let dox = item.attrs.collapsed_doc_value().unwrap_or_default(); diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index e7a99ee7bfd84..6b052185bbdb8 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -53,7 +53,7 @@ impl<'a> DocFolder for Stripper<'a> { } } else { if self.update_retained { - self.retained.insert(i.def_id); + self.retained.insert(i.item_id); } } Some(self.fold_item_recur(i)) diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 82627aaf7a4cb..6a522bdacf997 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -45,7 +45,8 @@ impl<'a> DocFolder for Stripper<'a> { | clean::TraitAliasItem(..) | clean::MacroItem(..) | clean::ForeignTypeItem => { - if i.def_id.is_local() && !self.access_levels.is_exported(i.def_id.expect_def_id()) + if i.item_id.is_local() + && !self.access_levels.is_exported(i.item_id.expect_def_id()) { debug!("Stripper: stripping {:?} {:?}", i.type_(), i.name); return None; @@ -59,7 +60,7 @@ impl<'a> DocFolder for Stripper<'a> { } clean::ModuleItem(..) => { - if i.def_id.is_local() && !i.visibility.is_public() { + if i.item_id.is_local() && !i.visibility.is_public() { debug!("Stripper: stripping module {:?}", i.name); let old = mem::replace(&mut self.update_retained, false); let ret = strip_item(self.fold_item_recur(i)); @@ -100,7 +101,7 @@ impl<'a> DocFolder for Stripper<'a> { let i = if fastreturn { if self.update_retained { - self.retained.insert(i.def_id); + self.retained.insert(i.item_id); } return Some(i); } else { @@ -108,7 +109,7 @@ impl<'a> DocFolder for Stripper<'a> { }; if self.update_retained { - self.retained.insert(i.def_id); + self.retained.insert(i.item_id); } Some(i) } diff --git a/src/test/pretty/stmt_expr_attributes.rs b/src/test/pretty/stmt_expr_attributes.rs index 7ab22f1960c2d..c01379065d1cd 100644 --- a/src/test/pretty/stmt_expr_attributes.rs +++ b/src/test/pretty/stmt_expr_attributes.rs @@ -1,6 +1,8 @@ // pp-exact #![feature(box_syntax)] +#![feature(inline_const)] +#![feature(inline_const_pat)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] @@ -16,6 +18,7 @@ fn _1() { #[rustc_dummy] unsafe { + #![rustc_dummy] // code } } @@ -206,6 +209,12 @@ fn _11() { let _ = (); () }; + let const { + #![rustc_dummy] + } = + #[rustc_dummy] const { + #![rustc_dummy] + }; let mut x = 0; let _ = #[rustc_dummy] x = 15; let _ = #[rustc_dummy] x += 15; diff --git a/src/test/ui/thread-local/non-static.rs b/src/test/ui/thread-local/non-static.rs new file mode 100644 index 0000000000000..f1c4273870bff --- /dev/null +++ b/src/test/ui/thread-local/non-static.rs @@ -0,0 +1,30 @@ +// Check that #[thread_local] attribute is rejected on non-static items. +#![feature(thread_local)] + +#[thread_local] +//~^ ERROR attribute should be applied to a static +const A: u32 = 0; + +#[thread_local] +//~^ ERROR attribute should be applied to a static +fn main() { + #[thread_local] || {}; + //~^ ERROR attribute should be applied to a static +} + +struct S { + #[thread_local] + //~^ ERROR attribute should be applied to a static + a: String, + b: String, +} + +#[thread_local] +// Static. OK. +static B: u32 = 0; + +extern "C" { + #[thread_local] + // Foreign static. OK. + static C: u32; +} diff --git a/src/test/ui/thread-local/non-static.stderr b/src/test/ui/thread-local/non-static.stderr new file mode 100644 index 0000000000000..09a1618d6e710 --- /dev/null +++ b/src/test/ui/thread-local/non-static.stderr @@ -0,0 +1,38 @@ +error: attribute should be applied to a static + --> $DIR/non-static.rs:4:1 + | +LL | #[thread_local] + | ^^^^^^^^^^^^^^^ +LL | +LL | const A: u32 = 0; + | ----------------- not a static + +error: attribute should be applied to a static + --> $DIR/non-static.rs:8:1 + | +LL | #[thread_local] + | ^^^^^^^^^^^^^^^ +LL | +LL | / fn main() { +LL | | #[thread_local] || {}; +LL | | +LL | | } + | |_- not a static + +error: attribute should be applied to a static + --> $DIR/non-static.rs:11:5 + | +LL | #[thread_local] || {}; + | ^^^^^^^^^^^^^^^ ----- not a static + +error: attribute should be applied to a static + --> $DIR/non-static.rs:16:5 + | +LL | #[thread_local] + | ^^^^^^^^^^^^^^^ +LL | +LL | a: String, + | --------- not a static + +error: aborting due to 4 previous errors + diff --git a/src/tools/rustbook/Cargo.toml b/src/tools/rustbook/Cargo.toml index b8c67de26230b..f074eb941dca2 100644 --- a/src/tools/rustbook/Cargo.toml +++ b/src/tools/rustbook/Cargo.toml @@ -9,6 +9,6 @@ clap = "2.25.0" env_logger = "0.7.1" [dependencies.mdbook] -version = "0.4.14" +version = "0.4.18" default-features = false features = ["search"]