Skip to content

Commit df548aa

Browse files
committed
Auto merge of #120441 - matthiaskrgr:rollup-s06vd7k, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #116677 (References refer to allocated objects) - #118533 (Suppress unhelpful diagnostics for unresolved top level attributes) - #120232 (Add support for custom JSON targets when using build-std.) - #120238 (Always check the result of `pthread_mutex_lock`) - #120266 (Improve documentation for [A]Rc::into_inner) - #120373 (Adjust Behaviour of `read_dir` and `ReadDir` in Windows Implementation: Check Whether Path to Search In Exists) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6351247 + 9e81462 commit df548aa

37 files changed

+232
-247
lines changed

compiler/rustc_errors/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ pub enum StashKey {
509509
MaybeForgetReturn,
510510
/// Query cycle detected, stashing in favor of a better error.
511511
Cycle,
512+
UndeterminedMacroResolution,
512513
}
513514

514515
fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {

compiler/rustc_passes/src/check_attr.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
//! item.
66
77
use crate::{errors, fluent_generated as fluent};
8-
use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem};
8+
use rustc_ast::{ast, AttrKind, AttrStyle, Attribute, LitKind};
9+
use rustc_ast::{MetaItemKind, MetaItemLit, NestedMetaItem};
910
use rustc_data_structures::fx::FxHashMap;
11+
use rustc_errors::StashKey;
1012
use rustc_errors::{Applicability, DiagCtxt, IntoDiagnosticArg, MultiSpan};
1113
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
1214
use rustc_hir as hir;
@@ -2530,6 +2532,14 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
25302532
if attr.style == AttrStyle::Inner {
25312533
for attr_to_check in ATTRS_TO_CHECK {
25322534
if attr.has_name(*attr_to_check) {
2535+
if let AttrKind::Normal(ref p) = attr.kind
2536+
&& let Some(diag) = tcx.dcx().steal_diagnostic(
2537+
p.item.path.span,
2538+
StashKey::UndeterminedMacroResolution,
2539+
)
2540+
{
2541+
diag.cancel();
2542+
}
25332543
let item = tcx
25342544
.hir()
25352545
.items()

compiler/rustc_resolve/src/macros.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! A bunch of methods and structures more or less related to resolving macros and
22
//! interface provided by `Resolver` to macro expander.
33
4-
use crate::errors::{
5-
self, AddAsNonDerive, CannotDetermineMacroResolution, CannotFindIdentInThisScope,
6-
MacroExpectedFound, RemoveSurroundingDerive,
7-
};
4+
use crate::errors::CannotDetermineMacroResolution;
5+
use crate::errors::{self, AddAsNonDerive, CannotFindIdentInThisScope};
6+
use crate::errors::{MacroExpectedFound, RemoveSurroundingDerive};
87
use crate::Namespace::*;
98
use crate::{BuiltinMacroState, Determinacy, MacroData};
109
use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet};
@@ -15,6 +14,7 @@ use rustc_ast_pretty::pprust;
1514
use rustc_attr::StabilityLevel;
1615
use rustc_data_structures::intern::Interned;
1716
use rustc_data_structures::sync::Lrc;
17+
use rustc_errors::StashKey;
1818
use rustc_errors::{struct_span_code_err, Applicability};
1919
use rustc_expand::base::{Annotatable, DeriveResolutions, Indeterminate, ResolverExpand};
2020
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
@@ -25,9 +25,8 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
2525
use rustc_middle::middle::stability;
2626
use rustc_middle::ty::RegisteredTools;
2727
use rustc_middle::ty::{TyCtxt, Visibility};
28-
use rustc_session::lint::builtin::{
29-
LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
30-
};
28+
use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
29+
use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
3130
use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
3231
use rustc_session::lint::BuiltinLintDiagnostics;
3332
use rustc_session::parse::feature_err;
@@ -703,21 +702,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
703702
// situations should be reported as errors, so this is a bug.
704703
this.dcx().span_delayed_bug(span, "inconsistent resolution for a macro");
705704
}
706-
} else {
705+
} else if this.tcx.dcx().has_errors().is_none() && this.privacy_errors.is_empty() {
707706
// It's possible that the macro was unresolved (indeterminate) and silently
708707
// expanded into a dummy fragment for recovery during expansion.
709708
// Now, post-expansion, the resolution may succeed, but we can't change the
710709
// past and need to report an error.
711710
// However, non-speculative `resolve_path` can successfully return private items
712711
// even if speculative `resolve_path` returned nothing previously, so we skip this
713-
// less informative error if the privacy error is reported elsewhere.
714-
if this.privacy_errors.is_empty() {
715-
this.dcx().emit_err(CannotDetermineMacroResolution {
716-
span,
717-
kind: kind.descr(),
718-
path: Segment::names_to_string(path),
719-
});
720-
}
712+
// less informative error if no other error is reported elsewhere.
713+
714+
let err = this.dcx().create_err(CannotDetermineMacroResolution {
715+
span,
716+
kind: kind.descr(),
717+
path: Segment::names_to_string(path),
718+
});
719+
err.stash(span, StashKey::UndeterminedMacroResolution);
721720
}
722721
};
723722

library/alloc/src/rc.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -939,8 +939,11 @@ impl<T, A: Allocator> Rc<T, A> {
939939
/// it is guaranteed that exactly one of the calls returns the inner value.
940940
/// This means in particular that the inner value is not dropped.
941941
///
942-
/// This is equivalent to `Rc::try_unwrap(this).ok()`. (Note that these are not equivalent for
943-
/// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`.)
942+
/// [`Rc::try_unwrap`] is conceptually similar to `Rc::into_inner`.
943+
/// And while they are meant for different use-cases, `Rc::into_inner(this)`
944+
/// is in fact equivalent to <code>[Rc::try_unwrap]\(this).[ok][Result::ok]()</code>.
945+
/// (Note that the same kind of equivalence does **not** hold true for
946+
/// [`Arc`](crate::sync::Arc), due to race conditions that do not apply to `Rc`!)
944947
#[inline]
945948
#[stable(feature = "rc_into_inner", since = "1.70.0")]
946949
pub fn into_inner(this: Self) -> Option<T> {

library/alloc/src/sync.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -983,9 +983,13 @@ impl<T, A: Allocator> Arc<T, A> {
983983
/// it is guaranteed that exactly one of the calls returns the inner value.
984984
/// This means in particular that the inner value is not dropped.
985985
///
986-
/// The similar expression `Arc::try_unwrap(this).ok()` does not
987-
/// offer such a guarantee. See the last example below
988-
/// and the documentation of [`Arc::try_unwrap`].
986+
/// [`Arc::try_unwrap`] is conceptually similar to `Arc::into_inner`, but it
987+
/// is meant for different use-cases. If used as a direct replacement
988+
/// for `Arc::into_inner` anyway, such as with the expression
989+
/// <code>[Arc::try_unwrap]\(this).[ok][Result::ok]()</code>, then it does
990+
/// **not** give the same guarantee as described in the previous paragraph.
991+
/// For more information, see the examples below and read the documentation
992+
/// of [`Arc::try_unwrap`].
989993
///
990994
/// # Examples
991995
///

library/core/src/primitive_docs.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,30 @@ mod prim_usize {}
13841384
/// work on references as well as they do on owned values! The implementations described here are
13851385
/// meant for generic contexts, where the final type `T` is a type parameter or otherwise not
13861386
/// locally known.
1387+
///
1388+
/// # Safety
1389+
///
1390+
/// For all types, `T: ?Sized`, and for all `t: &T` or `t: &mut T`, when such values cross an API
1391+
/// boundary, the following invariants must generally be upheld:
1392+
///
1393+
/// * `t` is aligned to `align_of_val(t)`
1394+
/// * `t` is dereferenceable for `size_of_val(t)` many bytes
1395+
///
1396+
/// If `t` points at address `a`, being "dereferenceable" for N bytes means that the memory range
1397+
/// `[a, a + N)` is all contained within a single [allocated object].
1398+
///
1399+
/// For instance, this means that unsafe code in a safe function may assume these invariants are
1400+
/// ensured of arguments passed by the caller, and it may assume that these invariants are ensured
1401+
/// of return values from any safe functions it calls. In most cases, the inverse is also true:
1402+
/// unsafe code must not violate these invariants when passing arguments to safe functions or
1403+
/// returning values from safe functions; such violations may result in undefined behavior. Where
1404+
/// exceptions to this latter requirement exist, they will be called out explicitly in documentation.
1405+
///
1406+
/// It is not decided yet whether unsafe code may violate these invariants temporarily on internal
1407+
/// data. As a consequence, unsafe code which violates these invariants temporarily on internal data
1408+
/// may become unsound in future versions of Rust depending on how this question is decided.
1409+
///
1410+
/// [allocated object]: ptr#allocated-object
13871411
#[stable(feature = "rust1", since = "1.0.0")]
13881412
mod prim_ref {}
13891413

library/profiler_builtins/build.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ fn main() {
1212
return;
1313
}
1414

15-
let target = env::var("TARGET").expect("TARGET was not set");
15+
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
16+
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
1617
let cfg = &mut cc::Build::new();
1718

1819
// FIXME: `rerun-if-changed` directives are not currently emitted and the build script
@@ -40,7 +41,7 @@ fn main() {
4041
"InstrProfilingBiasVar.c",
4142
];
4243

43-
if target.contains("msvc") {
44+
if target_env == "msvc" {
4445
// Don't pull in extra libraries on MSVC
4546
cfg.flag("/Zl");
4647
profile_sources.push("WindowsMMap.c");
@@ -55,7 +56,7 @@ fn main() {
5556
cfg.flag("-fno-builtin");
5657
cfg.flag("-fomit-frame-pointer");
5758
cfg.define("VISIBILITY_HIDDEN", None);
58-
if !target.contains("windows") {
59+
if target_os != "windows" {
5960
cfg.flag("-fvisibility=hidden");
6061
cfg.define("COMPILER_RT_HAS_UNAME", Some("1"));
6162
} else {

library/std/build.rs

+41-36
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,46 @@ use std::env;
22

33
fn main() {
44
println!("cargo:rerun-if-changed=build.rs");
5-
let target = env::var("TARGET").expect("TARGET was not set");
6-
if target.contains("linux")
7-
|| target.contains("netbsd")
8-
|| target.contains("dragonfly")
9-
|| target.contains("openbsd")
10-
|| target.contains("freebsd")
11-
|| target.contains("solaris")
12-
|| target.contains("illumos")
13-
|| target.contains("apple-darwin")
14-
|| target.contains("apple-ios")
15-
|| target.contains("apple-tvos")
16-
|| target.contains("apple-watchos")
17-
|| target.contains("uwp")
18-
|| target.contains("windows")
19-
|| target.contains("fuchsia")
20-
|| (target.contains("sgx") && target.contains("fortanix"))
21-
|| target.contains("hermit")
22-
|| target.contains("l4re")
23-
|| target.contains("redox")
24-
|| target.contains("haiku")
25-
|| target.contains("vxworks")
26-
|| target.contains("wasm32")
27-
|| target.contains("wasm64")
28-
|| target.contains("espidf")
29-
|| target.contains("solid")
30-
|| target.contains("nintendo-3ds")
31-
|| target.contains("vita")
32-
|| target.contains("aix")
33-
|| target.contains("nto")
34-
|| target.contains("xous")
35-
|| target.contains("hurd")
36-
|| target.contains("uefi")
37-
|| target.contains("teeos")
38-
|| target.contains("zkvm")
39-
// See src/bootstrap/synthetic_targets.rs
5+
let target_arch = env::var("CARGO_CFG_TARGET_ARCH").expect("CARGO_CFG_TARGET_ARCH was not set");
6+
let target_os = env::var("CARGO_CFG_TARGET_OS").expect("CARGO_CFG_TARGET_OS was not set");
7+
let target_vendor =
8+
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
9+
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
10+
11+
if target_os == "linux"
12+
|| target_os == "netbsd"
13+
|| target_os == "dragonfly"
14+
|| target_os == "openbsd"
15+
|| target_os == "freebsd"
16+
|| target_os == "solaris"
17+
|| target_os == "illumos"
18+
|| target_os == "macos"
19+
|| target_os == "ios"
20+
|| target_os == "tvos"
21+
|| target_os == "watchos"
22+
|| target_os == "windows"
23+
|| target_os == "fuchsia"
24+
|| (target_vendor == "fortranix" && target_env == "sgx")
25+
|| target_os == "hermit"
26+
|| target_os == "l4re"
27+
|| target_os == "redox"
28+
|| target_os == "haiku"
29+
|| target_os == "vxworks"
30+
|| target_arch == "wasm32"
31+
|| target_arch == "wasm64"
32+
|| target_os == "espidf"
33+
|| target_os.starts_with("solid")
34+
|| (target_vendor == "nintendo" && target_env == "newlib")
35+
|| target_os == "vita"
36+
|| target_os == "aix"
37+
|| target_os == "nto"
38+
|| target_os == "xous"
39+
|| target_os == "hurd"
40+
|| target_os == "uefi"
41+
|| target_os == "teeos"
42+
|| target_os == "zkvm"
43+
44+
// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
4045
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
4146
{
4247
// These platforms don't have any special requirements.
@@ -48,7 +53,7 @@ fn main() {
4853
// - mipsel-sony-psp
4954
// - nvptx64-nvidia-cuda
5055
// - arch=avr
51-
// - JSON targets
56+
// - JSON targets not describing an excluded target above.
5257
// - Any new targets that have not been explicitly added above.
5358
println!("cargo:rustc-cfg=feature=\"restricted-std\"");
5459
}

library/std/src/sys/pal/unix/locks/pthread_mutex.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::cell::UnsafeCell;
2+
use crate::io::Error;
23
use crate::mem::{forget, MaybeUninit};
34
use crate::sys::cvt_nz;
45
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
@@ -103,8 +104,24 @@ impl Mutex {
103104

104105
#[inline]
105106
pub unsafe fn lock(&self) {
107+
#[cold]
108+
#[inline(never)]
109+
fn fail() -> ! {
110+
let error = Error::last_os_error();
111+
panic!("failed to lock mutex: {error}");
112+
}
113+
106114
let r = libc::pthread_mutex_lock(raw(self));
107-
debug_assert_eq!(r, 0);
115+
// As we set the mutex type to `PTHREAD_MUTEX_NORMAL` above, we expect
116+
// the lock call to never fail. Unfortunately however, some platforms
117+
// (Solaris) do not conform to the standard, and instead always provide
118+
// deadlock detection. How kind of them! Unfortunately that means that
119+
// we need to check the error code here. To save us from UB on other
120+
// less well-behaved platforms in the future, we do it even on "good"
121+
// platforms like macOS. See #120147 for more context.
122+
if r != 0 {
123+
fail()
124+
}
108125
}
109126

110127
#[inline]

library/std/src/sys/pal/windows/fs.rs

+33-1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,13 @@ impl fmt::Debug for ReadDir {
112112
impl Iterator for ReadDir {
113113
type Item = io::Result<DirEntry>;
114114
fn next(&mut self) -> Option<io::Result<DirEntry>> {
115+
if self.handle.0 == c::INVALID_HANDLE_VALUE {
116+
// This iterator was initialized with an `INVALID_HANDLE_VALUE` as its handle.
117+
// Simply return `None` because this is only the case when `FindFirstFileW` in
118+
// the construction of this iterator returns `ERROR_FILE_NOT_FOUND` which means
119+
// no matchhing files can be found.
120+
return None;
121+
}
115122
if let Some(first) = self.first.take() {
116123
if let Some(e) = DirEntry::new(&self.root, &first) {
117124
return Some(Ok(e));
@@ -1068,14 +1075,39 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
10681075
unsafe {
10691076
let mut wfd = mem::zeroed();
10701077
let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
1078+
10711079
if find_handle != c::INVALID_HANDLE_VALUE {
10721080
Ok(ReadDir {
10731081
handle: FindNextFileHandle(find_handle),
10741082
root: Arc::new(root),
10751083
first: Some(wfd),
10761084
})
10771085
} else {
1078-
Err(Error::last_os_error())
1086+
// The status `ERROR_FILE_NOT_FOUND` is returned by the `FindFirstFileW` function
1087+
// if no matching files can be found, but not necessarily that the path to find the
1088+
// files in does not exist.
1089+
//
1090+
// Hence, a check for whether the path to search in exists is added when the last
1091+
// os error returned by Windows is `ERROR_FILE_NOT_FOUND` to handle this scenario.
1092+
// If that is the case, an empty `ReadDir` iterator is returned as it returns `None`
1093+
// in the initial `.next()` invocation because `ERROR_NO_MORE_FILES` would have been
1094+
// returned by the `FindNextFileW` function.
1095+
//
1096+
// See issue #120040: https://github.com/rust-lang/rust/issues/120040.
1097+
let last_error = api::get_last_error();
1098+
if last_error.code == c::ERROR_FILE_NOT_FOUND {
1099+
return Ok(ReadDir {
1100+
handle: FindNextFileHandle(find_handle),
1101+
root: Arc::new(root),
1102+
first: None,
1103+
});
1104+
}
1105+
1106+
// Just return the error constructed from the raw OS error if the above is not the case.
1107+
//
1108+
// Note: `ERROR_PATH_NOT_FOUND` would have been returned by the `FindFirstFileW` function
1109+
// when the path to search in does not exist in the first place.
1110+
Err(Error::from_raw_os_error(last_error.code as i32))
10791111
}
10801112
}
10811113
}

tests/ui/derives/issue-36617.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
#![derive(Copy)] //~ ERROR cannot determine resolution for the attribute macro `derive`
1+
#![derive(Copy)]
22
//~^ ERROR `derive` attribute cannot be used at crate level
33

4-
#![test]//~ ERROR cannot determine resolution for the attribute macro `test`
4+
#![test]
55
//~^ ERROR `test` attribute cannot be used at crate level
66

7-
#![test_case]//~ ERROR cannot determine resolution for the attribute macro `test_case`
7+
#![test_case]
88
//~^ ERROR `test_case` attribute cannot be used at crate level
99

10-
#![bench]//~ ERROR cannot determine resolution for the attribute macro `bench`
10+
#![bench]
1111
//~^ ERROR `bench` attribute cannot be used at crate level
1212

13-
#![global_allocator]//~ ERROR cannot determine resolution for the attribute macro `global_allocator`
13+
#![global_allocator]
1414
//~^ ERROR `global_allocator` attribute cannot be used at crate level
1515

1616
fn main() {}

0 commit comments

Comments
 (0)