Skip to content

Commit 953a5ca

Browse files
committed
Auto merge of #135048 - cuviper:beta-next, r=cuviper
[beta] backports - Do not call `extern_crate` on current trait on crate mismatch errors #133585 - Correctly handle comments in attributes in doctests source code #134260 - Correctly document CTFE behavior of is_null and methods that call is_null. #134325 - Make sure we handle `backwards_incompatible_lint` drops appropriately in drop elaboration #134486 - Bump compiler `cc` to 1.2.5 #134505 - Handle `DropKind::ForLint` in coroutines correctly #134575 - docs: inline `std::ffi::c_str` types to `std::ffi` #134791 - docs: inline `alloc::ffi::c_str` types to `alloc::ffi` #134851 r? cuviper
2 parents 0857a8e + f72c836 commit 953a5ca

28 files changed

+1034
-155
lines changed

Cargo.lock

+2-2
Original file line numberDiff line numberDiff line change
@@ -411,9 +411,9 @@ version = "0.1.0"
411411

412412
[[package]]
413413
name = "cc"
414-
version = "1.1.34"
414+
version = "1.2.5"
415415
source = "registry+https://github.com/rust-lang/crates.io-index"
416-
checksum = "67b9470d453346108f93a59222a9a1a5724db32d0a4727b7ab7ace4b4d822dc9"
416+
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
417417
dependencies = [
418418
"shlex",
419419
]

compiler/rustc_codegen_ssa/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ edition = "2021"
88
ar_archive_writer = "0.4.2"
99
arrayvec = { version = "0.7", default-features = false }
1010
bitflags = "2.4.1"
11-
cc = "1.1.23"
11+
# Pinned so `cargo update` bumps don't cause breakage. Please also update the
12+
# `cc` in `rustc_llvm` if you update the `cc` here.
13+
cc = "=1.2.5"
1214
either = "1.5.0"
1315
itertools = "0.12"
1416
jobserver = "0.1.28"

compiler/rustc_llvm/Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,7 @@ libc = "0.2.73"
1010

1111
[build-dependencies]
1212
# tidy-alphabetical-start
13-
cc = "1.1.23"
13+
# Pinned so `cargo update` bumps don't cause breakage. Please also update the
14+
# pinned `cc` in `rustc_codegen_ssa` if you update `cc` here.
15+
cc = "=1.2.5"
1416
# tidy-alphabetical-end

compiler/rustc_mir_build/src/build/scope.rs

+107-41
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,13 @@ struct DropData {
151151

152152
/// Whether this is a value Drop or a StorageDead.
153153
kind: DropKind,
154-
155-
/// Whether this is a backwards-incompatible drop lint
156-
backwards_incompatible_lint: bool,
157154
}
158155

159156
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
160157
pub(crate) enum DropKind {
161158
Value,
162159
Storage,
160+
ForLint,
163161
}
164162

165163
#[derive(Debug)]
@@ -248,7 +246,7 @@ impl Scope {
248246
/// use of optimizations in the MIR coroutine transform.
249247
fn needs_cleanup(&self) -> bool {
250248
self.drops.iter().any(|drop| match drop.kind {
251-
DropKind::Value => true,
249+
DropKind::Value | DropKind::ForLint => true,
252250
DropKind::Storage => false,
253251
})
254252
}
@@ -277,12 +275,8 @@ impl DropTree {
277275
// represents the block in the tree that should be jumped to once all
278276
// of the required drops have been performed.
279277
let fake_source_info = SourceInfo::outermost(DUMMY_SP);
280-
let fake_data = DropData {
281-
source_info: fake_source_info,
282-
local: Local::MAX,
283-
kind: DropKind::Storage,
284-
backwards_incompatible_lint: false,
285-
};
278+
let fake_data =
279+
DropData { source_info: fake_source_info, local: Local::MAX, kind: DropKind::Storage };
286280
let drops = IndexVec::from_raw(vec![DropNode { data: fake_data, next: DropIdx::MAX }]);
287281
Self { drops, entry_points: Vec::new(), existing_drops_map: FxHashMap::default() }
288282
}
@@ -411,6 +405,27 @@ impl DropTree {
411405
};
412406
cfg.terminate(block, drop_node.data.source_info, terminator);
413407
}
408+
DropKind::ForLint => {
409+
let stmt = Statement {
410+
source_info: drop_node.data.source_info,
411+
kind: StatementKind::BackwardIncompatibleDropHint {
412+
place: Box::new(drop_node.data.local.into()),
413+
reason: BackwardIncompatibleDropReason::Edition2024,
414+
},
415+
};
416+
cfg.push(block, stmt);
417+
let target = blocks[drop_node.next].unwrap();
418+
if target != block {
419+
// Diagnostics don't use this `Span` but debuginfo
420+
// might. Since we don't want breakpoints to be placed
421+
// here, especially when this is on an unwind path, we
422+
// use `DUMMY_SP`.
423+
let source_info =
424+
SourceInfo { span: DUMMY_SP, ..drop_node.data.source_info };
425+
let terminator = TerminatorKind::Goto { target };
426+
cfg.terminate(block, source_info, terminator);
427+
}
428+
}
414429
// Root nodes don't correspond to a drop.
415430
DropKind::Storage if drop_idx == ROOT_NODE => {}
416431
DropKind::Storage => {
@@ -770,12 +785,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
770785
let local =
771786
place.as_local().unwrap_or_else(|| bug!("projection in tail call args"));
772787

773-
Some(DropData {
774-
source_info,
775-
local,
776-
kind: DropKind::Value,
777-
backwards_incompatible_lint: false,
778-
})
788+
Some(DropData { source_info, local, kind: DropKind::Value })
779789
}
780790
Operand::Constant(_) => None,
781791
})
@@ -822,6 +832,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
822832
});
823833
block = next;
824834
}
835+
DropKind::ForLint => {
836+
self.cfg.push(block, Statement {
837+
source_info,
838+
kind: StatementKind::BackwardIncompatibleDropHint {
839+
place: Box::new(local.into()),
840+
reason: BackwardIncompatibleDropReason::Edition2024,
841+
},
842+
});
843+
}
825844
DropKind::Storage => {
826845
// Only temps and vars need their storage dead.
827846
assert!(local.index() > self.arg_count);
@@ -1021,7 +1040,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
10211040
drop_kind: DropKind,
10221041
) {
10231042
let needs_drop = match drop_kind {
1024-
DropKind::Value => {
1043+
DropKind::Value | DropKind::ForLint => {
10251044
if !self.local_decls[local].ty.needs_drop(self.tcx, self.typing_env()) {
10261045
return;
10271046
}
@@ -1101,7 +1120,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11011120
source_info: SourceInfo { span: scope_end, scope: scope.source_scope },
11021121
local,
11031122
kind: drop_kind,
1104-
backwards_incompatible_lint: false,
11051123
});
11061124

11071125
return;
@@ -1135,8 +1153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
11351153
scope.drops.push(DropData {
11361154
source_info: SourceInfo { span: scope_end, scope: scope.source_scope },
11371155
local,
1138-
kind: DropKind::Value,
1139-
backwards_incompatible_lint: true,
1156+
kind: DropKind::ForLint,
11401157
});
11411158

11421159
return;
@@ -1379,12 +1396,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
13791396
}
13801397

13811398
/// Builds drops for `pop_scope` and `leave_top_scope`.
1399+
///
1400+
/// # Parameters
1401+
///
1402+
/// * `unwind_drops`, the drop tree data structure storing what needs to be cleaned up if unwind occurs
1403+
/// * `scope`, describes the drops that will occur on exiting the scope in regular execution
1404+
/// * `block`, the block to branch to once drops are complete (assuming no unwind occurs)
1405+
/// * `unwind_to`, describes the drops that would occur at this point in the code if a
1406+
/// panic occurred (a subset of the drops in `scope`, since we sometimes elide StorageDead and other
1407+
/// instructions on unwinding)
1408+
/// * `storage_dead_on_unwind`, if true, then we should emit `StorageDead` even when unwinding
1409+
/// * `arg_count`, number of MIR local variables corresponding to fn arguments (used to assert that we don't drop those)
13821410
fn build_scope_drops<'tcx>(
13831411
cfg: &mut CFG<'tcx>,
13841412
unwind_drops: &mut DropTree,
13851413
scope: &Scope,
1386-
mut block: BasicBlock,
1387-
mut unwind_to: DropIdx,
1414+
block: BasicBlock,
1415+
unwind_to: DropIdx,
13881416
storage_dead_on_unwind: bool,
13891417
arg_count: usize,
13901418
) -> BlockAnd<()> {
@@ -1409,6 +1437,18 @@ fn build_scope_drops<'tcx>(
14091437
// drops for the unwind path should have already been generated by
14101438
// `diverge_cleanup_gen`.
14111439

1440+
// `unwind_to` indicates what needs to be dropped should unwinding occur.
1441+
// This is a subset of what needs to be dropped when exiting the scope.
1442+
// As we unwind the scope, we will also move `unwind_to` backwards to match,
1443+
// so that we can use it should a destructor panic.
1444+
let mut unwind_to = unwind_to;
1445+
1446+
// The block that we should jump to after drops complete. We start by building the final drop (`drops[n]`
1447+
// in the diagram above) and then build the drops (e.g., `drop[1]`, `drop[0]`) that come before it.
1448+
// block begins as the successor of `drops[n]` and then becomes `drops[n]` so that `drops[n-1]`
1449+
// will branch to `drops[n]`.
1450+
let mut block = block;
1451+
14121452
for drop_data in scope.drops.iter().rev() {
14131453
let source_info = drop_data.source_info;
14141454
let local = drop_data.local;
@@ -1418,6 +1458,9 @@ fn build_scope_drops<'tcx>(
14181458
// `unwind_to` should drop the value that we're about to
14191459
// schedule. If dropping this value panics, then we continue
14201460
// with the *next* value on the unwind path.
1461+
//
1462+
// We adjust this BEFORE we create the drop (e.g., `drops[n]`)
1463+
// because `drops[n]` should unwind to `drops[n-1]`.
14211464
debug_assert_eq!(unwind_drops.drops[unwind_to].data.local, drop_data.local);
14221465
debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind);
14231466
unwind_to = unwind_drops.drops[unwind_to].next;
@@ -1430,27 +1473,50 @@ fn build_scope_drops<'tcx>(
14301473
continue;
14311474
}
14321475

1433-
if drop_data.backwards_incompatible_lint {
1434-
cfg.push(block, Statement {
1435-
source_info,
1436-
kind: StatementKind::BackwardIncompatibleDropHint {
1437-
place: Box::new(local.into()),
1438-
reason: BackwardIncompatibleDropReason::Edition2024,
1439-
},
1440-
});
1441-
} else {
1442-
unwind_drops.add_entry_point(block, unwind_to);
1443-
let next = cfg.start_new_block();
1444-
cfg.terminate(block, source_info, TerminatorKind::Drop {
1445-
place: local.into(),
1446-
target: next,
1447-
unwind: UnwindAction::Continue,
1448-
replace: false,
1449-
});
1450-
block = next;
1476+
unwind_drops.add_entry_point(block, unwind_to);
1477+
let next = cfg.start_new_block();
1478+
cfg.terminate(block, source_info, TerminatorKind::Drop {
1479+
place: local.into(),
1480+
target: next,
1481+
unwind: UnwindAction::Continue,
1482+
replace: false,
1483+
});
1484+
block = next;
1485+
}
1486+
DropKind::ForLint => {
1487+
// As in the `DropKind::Storage` case below:
1488+
// normally lint-related drops are not emitted for unwind,
1489+
// so we can just leave `unwind_to` unmodified, but in some
1490+
// cases we emit things ALSO on the unwind path, so we need to adjust
1491+
// `unwind_to` in that case.
1492+
if storage_dead_on_unwind {
1493+
debug_assert_eq!(unwind_drops.drops[unwind_to].data.local, drop_data.local);
1494+
debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind);
1495+
unwind_to = unwind_drops.drops[unwind_to].next;
14511496
}
1497+
1498+
// If the operand has been moved, and we are not on an unwind
1499+
// path, then don't generate the drop. (We only take this into
1500+
// account for non-unwind paths so as not to disturb the
1501+
// caching mechanism.)
1502+
if scope.moved_locals.iter().any(|&o| o == local) {
1503+
continue;
1504+
}
1505+
1506+
cfg.push(block, Statement {
1507+
source_info,
1508+
kind: StatementKind::BackwardIncompatibleDropHint {
1509+
place: Box::new(local.into()),
1510+
reason: BackwardIncompatibleDropReason::Edition2024,
1511+
},
1512+
});
14521513
}
14531514
DropKind::Storage => {
1515+
// Ordinarily, storage-dead nodes are not emitted on unwind, so we don't
1516+
// need to adjust `unwind_to` on this path. However, in some specific cases
1517+
// we *do* emit storage-dead nodes on the unwind path, and in that case now that
1518+
// the storage-dead has completed, we need to adjust the `unwind_to` pointer
1519+
// so that any future drops we emit will not register storage-dead.
14541520
if storage_dead_on_unwind {
14551521
debug_assert_eq!(unwind_drops.drops[unwind_to].data.local, drop_data.local);
14561522
debug_assert_eq!(unwind_drops.drops[unwind_to].data.kind, drop_data.kind);
@@ -1489,7 +1555,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
14891555
let mut unwind_indices = IndexVec::from_elem_n(unwind_target, 1);
14901556
for (drop_idx, drop_node) in drops.drops.iter_enumerated().skip(1) {
14911557
match drop_node.data.kind {
1492-
DropKind::Storage => {
1558+
DropKind::Storage | DropKind::ForLint => {
14931559
if is_coroutine {
14941560
let unwind_drop = self
14951561
.scopes

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1732,6 +1732,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
17321732
span.push_span_label(self.tcx.def_span(trait_def_id), "this is the required trait");
17331733
for (sp, label) in [trait_def_id, other_trait_def_id]
17341734
.iter()
1735+
// The current crate-version might depend on another version of the same crate
1736+
// (Think "semver-trick"). Do not call `extern_crate` in that case for the local
1737+
// crate as that doesn't make sense and ICEs (#133563).
1738+
.filter(|def_id| !def_id.is_local())
17351739
.filter_map(|def_id| self.tcx.extern_crate(def_id.krate))
17361740
.map(|data| {
17371741
let dependency = if data.dependency_of == LOCAL_CRATE {

library/alloc/src/ffi/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
#[doc(inline)]
8484
#[stable(feature = "alloc_c_string", since = "1.64.0")]
8585
pub use self::c_str::CString;
86-
#[doc(no_inline)]
86+
#[doc(inline)]
8787
#[stable(feature = "alloc_c_string", since = "1.64.0")]
8888
pub use self::c_str::{FromVecWithNulError, IntoStringError, NulError};
8989

library/core/src/ffi/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
#[doc(inline)]
1313
#[stable(feature = "core_c_str", since = "1.64.0")]
1414
pub use self::c_str::CStr;
15-
#[doc(no_inline)]
15+
#[doc(inline)]
1616
#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
1717
pub use self::c_str::FromBytesUntilNulError;
18-
#[doc(no_inline)]
18+
#[doc(inline)]
1919
#[stable(feature = "core_c_str", since = "1.64.0")]
2020
pub use self::c_str::FromBytesWithNulError;
2121
use crate::fmt;

library/core/src/ptr/const_ptr.rs

+31-7
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ impl<T: ?Sized> *const T {
1212
/// Therefore, two pointers that are null may still not compare equal to
1313
/// each other.
1414
///
15-
/// ## Behavior during const evaluation
15+
/// # Panics during const evaluation
1616
///
17-
/// When this function is used during const evaluation, it may return `false` for pointers
18-
/// that turn out to be null at runtime. Specifically, when a pointer to some memory
19-
/// is offset beyond its bounds in such a way that the resulting pointer is null,
20-
/// the function will still return `false`. There is no way for CTFE to know
21-
/// the absolute position of that memory, so we cannot tell if the pointer is
22-
/// null or not.
17+
/// If this method is used during const evaluation, and `self` is a pointer
18+
/// that is offset beyond the bounds of the memory it initially pointed to,
19+
/// then there might not be enough information to determine whether the
20+
/// pointer is null. This is because the absolute address in memory is not
21+
/// known at compile time. If the nullness of the pointer cannot be
22+
/// determined, this method will panic.
23+
///
24+
/// In-bounds pointers are never null, so the method will never panic for
25+
/// such pointers.
2326
///
2427
/// # Examples
2528
///
@@ -255,6 +258,13 @@ impl<T: ?Sized> *const T {
255258
/// When calling this method, you have to ensure that *either* the pointer is null *or*
256259
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
257260
///
261+
/// # Panics during const evaluation
262+
///
263+
/// This method will panic during const evaluation if the pointer cannot be
264+
/// determined to be null or not. See [`is_null`] for more information.
265+
///
266+
/// [`is_null`]: #method.is_null
267+
///
258268
/// # Examples
259269
///
260270
/// ```
@@ -332,6 +342,13 @@ impl<T: ?Sized> *const T {
332342
/// When calling this method, you have to ensure that *either* the pointer is null *or*
333343
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
334344
///
345+
/// # Panics during const evaluation
346+
///
347+
/// This method will panic during const evaluation if the pointer cannot be
348+
/// determined to be null or not. See [`is_null`] for more information.
349+
///
350+
/// [`is_null`]: #method.is_null
351+
///
335352
/// # Examples
336353
///
337354
/// ```
@@ -1592,6 +1609,13 @@ impl<T> *const [T] {
15921609
///
15931610
/// [valid]: crate::ptr#safety
15941611
/// [allocated object]: crate::ptr#allocated-object
1612+
///
1613+
/// # Panics during const evaluation
1614+
///
1615+
/// This method will panic during const evaluation if the pointer cannot be
1616+
/// determined to be null or not. See [`is_null`] for more information.
1617+
///
1618+
/// [`is_null`]: #method.is_null
15951619
#[inline]
15961620
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
15971621
#[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]

0 commit comments

Comments
 (0)