Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 953a5ca

Browse files
committedJan 3, 2025
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

File tree

28 files changed

+1034
-155
lines changed

28 files changed

+1034
-155
lines changed
 

‎Cargo.lock

Lines changed: 2 additions & 2 deletions
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 107 additions & 41 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 31 additions & 7 deletions
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")]

‎library/core/src/ptr/mut_ptr.rs

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,17 @@ impl<T: ?Sized> *mut 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
///
@@ -244,6 +247,13 @@ impl<T: ?Sized> *mut T {
244247
/// When calling this method, you have to ensure that *either* the pointer is null *or*
245248
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
246249
///
250+
/// # Panics during const evaluation
251+
///
252+
/// This method will panic during const evaluation if the pointer cannot be
253+
/// determined to be null or not. See [`is_null`] for more information.
254+
///
255+
/// [`is_null`]: #method.is_null-1
256+
///
247257
/// # Examples
248258
///
249259
/// ```
@@ -328,6 +338,13 @@ impl<T: ?Sized> *mut T {
328338
/// Note that because the created reference is to `MaybeUninit<T>`, the
329339
/// source pointer can point to uninitialized memory.
330340
///
341+
/// # Panics during const evaluation
342+
///
343+
/// This method will panic during const evaluation if the pointer cannot be
344+
/// determined to be null or not. See [`is_null`] for more information.
345+
///
346+
/// [`is_null`]: #method.is_null-1
347+
///
331348
/// # Examples
332349
///
333350
/// ```
@@ -592,6 +609,12 @@ impl<T: ?Sized> *mut T {
592609
/// the pointer is null *or*
593610
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
594611
///
612+
/// # Panics during const evaluation
613+
///
614+
/// This method will panic during const evaluation if the pointer cannot be
615+
/// determined to be null or not. See [`is_null`] for more information.
616+
///
617+
/// [`is_null`]: #method.is_null-1
595618
///
596619
/// # Examples
597620
///
@@ -675,6 +698,13 @@ impl<T: ?Sized> *mut T {
675698
///
676699
/// When calling this method, you have to ensure that *either* the pointer is null *or*
677700
/// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
701+
///
702+
/// # Panics during const evaluation
703+
///
704+
/// This method will panic during const evaluation if the pointer cannot be
705+
/// determined to be null or not. See [`is_null`] for more information.
706+
///
707+
/// [`is_null`]: #method.is_null-1
678708
#[inline]
679709
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
680710
#[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
@@ -1947,6 +1977,13 @@ impl<T> *mut [T] {
19471977
///
19481978
/// [valid]: crate::ptr#safety
19491979
/// [allocated object]: crate::ptr#allocated-object
1980+
///
1981+
/// # Panics during const evaluation
1982+
///
1983+
/// This method will panic during const evaluation if the pointer cannot be
1984+
/// determined to be null or not. See [`is_null`] for more information.
1985+
///
1986+
/// [`is_null`]: #method.is_null-1
19501987
#[inline]
19511988
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
19521989
#[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
@@ -1999,6 +2036,13 @@ impl<T> *mut [T] {
19992036
///
20002037
/// [valid]: crate::ptr#safety
20012038
/// [allocated object]: crate::ptr#allocated-object
2039+
///
2040+
/// # Panics during const evaluation
2041+
///
2042+
/// This method will panic during const evaluation if the pointer cannot be
2043+
/// determined to be null or not. See [`is_null`] for more information.
2044+
///
2045+
/// [`is_null`]: #method.is_null-1
20022046
#[inline]
20032047
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
20042048
#[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]

‎library/core/src/ptr/non_null.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,13 @@ impl<T: ?Sized> NonNull<T> {
202202

203203
/// Creates a new `NonNull` if `ptr` is non-null.
204204
///
205+
/// # Panics during const evaluation
206+
///
207+
/// This method will panic during const evaluation if the pointer cannot be
208+
/// determined to be null or not. See [`is_null`] for more information.
209+
///
210+
/// [`is_null`]: ../primitive.pointer.html#method.is_null-1
211+
///
205212
/// # Examples
206213
///
207214
/// ```

‎library/std/src/ffi/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,19 +179,19 @@ pub use core::ffi::{
179179
c_ulong, c_ulonglong, c_ushort,
180180
};
181181

182-
#[doc(no_inline)]
182+
#[doc(inline)]
183183
#[stable(feature = "cstr_from_bytes_until_nul", since = "1.69.0")]
184184
pub use self::c_str::FromBytesUntilNulError;
185-
#[doc(no_inline)]
185+
#[doc(inline)]
186186
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
187187
pub use self::c_str::FromBytesWithNulError;
188-
#[doc(no_inline)]
188+
#[doc(inline)]
189189
#[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")]
190190
pub use self::c_str::FromVecWithNulError;
191-
#[doc(no_inline)]
191+
#[doc(inline)]
192192
#[stable(feature = "cstring_into", since = "1.7.0")]
193193
pub use self::c_str::IntoStringError;
194-
#[doc(no_inline)]
194+
#[doc(inline)]
195195
#[stable(feature = "rust1", since = "1.0.0")]
196196
pub use self::c_str::NulError;
197197
#[doc(inline)]

‎src/librustdoc/doctest/make.rs

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,17 @@ impl DocTestBuilder {
5151
!lang_str.compile_fail && !lang_str.test_harness && !lang_str.standalone_crate
5252
});
5353

54-
let SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else } =
55-
partition_source(source, edition);
54+
let Some(SourceInfo { crate_attrs, maybe_crate_attrs, crates, everything_else }) =
55+
partition_source(source, edition)
56+
else {
57+
return Self::invalid(
58+
String::new(),
59+
String::new(),
60+
String::new(),
61+
source.to_string(),
62+
test_id,
63+
);
64+
};
5665

5766
// Uses librustc_ast to parse the doctest and find if there's a main fn and the extern
5867
// crate already is included.
@@ -77,18 +86,7 @@ impl DocTestBuilder {
7786
else {
7887
// If the parser panicked due to a fatal error, pass the test code through unchanged.
7988
// The error will be reported during compilation.
80-
return Self {
81-
supports_color: false,
82-
has_main_fn: false,
83-
crate_attrs,
84-
maybe_crate_attrs,
85-
crates,
86-
everything_else,
87-
already_has_extern_crate: false,
88-
test_id,
89-
failed_ast: true,
90-
can_be_merged: false,
91-
};
89+
return Self::invalid(crate_attrs, maybe_crate_attrs, crates, everything_else, test_id);
9290
};
9391
// If the AST returned an error, we don't want this doctest to be merged with the
9492
// others. Same if it contains `#[feature]` or `#[no_std]`.
@@ -113,6 +111,27 @@ impl DocTestBuilder {
113111
}
114112
}
115113

114+
fn invalid(
115+
crate_attrs: String,
116+
maybe_crate_attrs: String,
117+
crates: String,
118+
everything_else: String,
119+
test_id: Option<String>,
120+
) -> Self {
121+
Self {
122+
supports_color: false,
123+
has_main_fn: false,
124+
crate_attrs,
125+
maybe_crate_attrs,
126+
crates,
127+
everything_else,
128+
already_has_extern_crate: false,
129+
test_id,
130+
failed_ast: true,
131+
can_be_merged: false,
132+
}
133+
}
134+
116135
/// Transforms a test into code that can be compiled into a Rust binary, and returns the number of
117136
/// lines before the test code begins.
118137
pub(crate) fn generate_unique_doctest(
@@ -518,8 +537,8 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit
518537
push_to.push('\n');
519538
// If it's complete, then we can clear the pending content.
520539
mod_attr_pending.clear();
521-
} else if mod_attr_pending.ends_with('\\') {
522-
mod_attr_pending.push('n');
540+
} else {
541+
mod_attr_pending.push_str("\n");
523542
}
524543
}
525544

@@ -531,7 +550,7 @@ struct SourceInfo {
531550
everything_else: String,
532551
}
533552

534-
fn partition_source(s: &str, edition: Edition) -> SourceInfo {
553+
fn partition_source(s: &str, edition: Edition) -> Option<SourceInfo> {
535554
#[derive(Copy, Clone, PartialEq)]
536555
enum PartitionState {
537556
Attrs,
@@ -606,11 +625,16 @@ fn partition_source(s: &str, edition: Edition) -> SourceInfo {
606625
}
607626
}
608627

628+
if !mod_attr_pending.is_empty() {
629+
debug!("invalid doctest code: {s:?}");
630+
return None;
631+
}
632+
609633
source_info.everything_else = source_info.everything_else.trim().to_string();
610634

611635
debug!("crate_attrs:\n{}{}", source_info.crate_attrs, source_info.maybe_crate_attrs);
612636
debug!("crates:\n{}", source_info.crates);
613637
debug!("after:\n{}", source_info.everything_else);
614638

615-
source_info
639+
Some(source_info)
616640
}

‎src/tools/run-make-support/src/external_deps/rustc.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,12 @@ impl Rustc {
227227
self
228228
}
229229

230+
/// Normalize the line number in the stderr output
231+
pub fn ui_testing(&mut self) -> &mut Self {
232+
self.cmd.arg(format!("-Zui-testing"));
233+
self
234+
}
235+
230236
/// Specify the target triple, or a path to a custom target json spec file.
231237
pub fn target<S: AsRef<str>>(&mut self, target: S) -> &mut Self {
232238
let target = target.as_ref();
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// MIR for `method_1` after ElaborateDrops
2+
3+
fn method_1(_1: Guard) -> () {
4+
debug g => _1;
5+
let mut _0: ();
6+
let mut _2: std::result::Result<OtherDrop, ()>;
7+
let mut _3: &Guard;
8+
let _4: &Guard;
9+
let _5: Guard;
10+
let mut _6: &Guard;
11+
let mut _7: isize;
12+
let _8: OtherDrop;
13+
let _9: ();
14+
let mut _10: bool;
15+
let mut _11: isize;
16+
let mut _12: isize;
17+
let mut _13: isize;
18+
scope 1 {
19+
debug other_drop => _8;
20+
}
21+
scope 2 {
22+
debug err => _9;
23+
}
24+
25+
bb0: {
26+
_10 = const false;
27+
StorageLive(_2);
28+
StorageLive(_3);
29+
StorageLive(_4);
30+
StorageLive(_5);
31+
StorageLive(_6);
32+
_6 = &_1;
33+
_5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb13];
34+
}
35+
36+
bb1: {
37+
StorageDead(_6);
38+
_4 = &_5;
39+
_3 = &(*_4);
40+
_2 = method_2(move _3) -> [return: bb2, unwind: bb12];
41+
}
42+
43+
bb2: {
44+
_10 = const true;
45+
StorageDead(_3);
46+
PlaceMention(_2);
47+
_7 = discriminant(_2);
48+
switchInt(move _7) -> [0: bb5, 1: bb4, otherwise: bb3];
49+
}
50+
51+
bb3: {
52+
unreachable;
53+
}
54+
55+
bb4: {
56+
StorageLive(_9);
57+
_9 = copy ((_2 as Err).0: ());
58+
_0 = const ();
59+
StorageDead(_9);
60+
goto -> bb7;
61+
}
62+
63+
bb5: {
64+
StorageLive(_8);
65+
_8 = move ((_2 as Ok).0: OtherDrop);
66+
_0 = const ();
67+
drop(_8) -> [return: bb6, unwind: bb11];
68+
}
69+
70+
bb6: {
71+
StorageDead(_8);
72+
goto -> bb7;
73+
}
74+
75+
bb7: {
76+
backward incompatible drop(_2);
77+
backward incompatible drop(_5);
78+
goto -> bb21;
79+
}
80+
81+
bb8: {
82+
drop(_5) -> [return: bb9, unwind: bb13];
83+
}
84+
85+
bb9: {
86+
StorageDead(_5);
87+
StorageDead(_4);
88+
_10 = const false;
89+
StorageDead(_2);
90+
drop(_1) -> [return: bb10, unwind: bb14];
91+
}
92+
93+
bb10: {
94+
return;
95+
}
96+
97+
bb11 (cleanup): {
98+
goto -> bb25;
99+
}
100+
101+
bb12 (cleanup): {
102+
drop(_5) -> [return: bb13, unwind terminate(cleanup)];
103+
}
104+
105+
bb13 (cleanup): {
106+
drop(_1) -> [return: bb14, unwind terminate(cleanup)];
107+
}
108+
109+
bb14 (cleanup): {
110+
resume;
111+
}
112+
113+
bb15: {
114+
goto -> bb8;
115+
}
116+
117+
bb16 (cleanup): {
118+
goto -> bb12;
119+
}
120+
121+
bb17 (cleanup): {
122+
goto -> bb12;
123+
}
124+
125+
bb18: {
126+
goto -> bb15;
127+
}
128+
129+
bb19: {
130+
goto -> bb15;
131+
}
132+
133+
bb20 (cleanup): {
134+
goto -> bb12;
135+
}
136+
137+
bb21: {
138+
_11 = discriminant(_2);
139+
switchInt(move _11) -> [0: bb18, otherwise: bb19];
140+
}
141+
142+
bb22 (cleanup): {
143+
_12 = discriminant(_2);
144+
switchInt(move _12) -> [0: bb16, otherwise: bb20];
145+
}
146+
147+
bb23 (cleanup): {
148+
goto -> bb12;
149+
}
150+
151+
bb24 (cleanup): {
152+
goto -> bb12;
153+
}
154+
155+
bb25 (cleanup): {
156+
_13 = discriminant(_2);
157+
switchInt(move _13) -> [0: bb23, otherwise: bb24];
158+
}
159+
}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
// MIR for `method_1` after ElaborateDrops
2+
3+
fn method_1(_1: Guard) -> () {
4+
debug g => _1;
5+
let mut _0: ();
6+
let mut _2: std::result::Result<OtherDrop, ()>;
7+
let mut _3: &Guard;
8+
let _4: &Guard;
9+
let _5: Guard;
10+
let mut _6: &Guard;
11+
let mut _7: isize;
12+
let _8: OtherDrop;
13+
let _9: ();
14+
let mut _10: bool;
15+
let mut _11: isize;
16+
let mut _12: isize;
17+
let mut _13: isize;
18+
scope 1 {
19+
debug other_drop => _8;
20+
}
21+
scope 2 {
22+
debug err => _9;
23+
}
24+
25+
bb0: {
26+
_10 = const false;
27+
StorageLive(_2);
28+
StorageLive(_3);
29+
StorageLive(_4);
30+
StorageLive(_5);
31+
StorageLive(_6);
32+
_6 = &_1;
33+
_5 = <Guard as Clone>::clone(move _6) -> [return: bb1, unwind: bb13];
34+
}
35+
36+
bb1: {
37+
StorageDead(_6);
38+
_4 = &_5;
39+
_3 = &(*_4);
40+
_2 = method_2(move _3) -> [return: bb2, unwind: bb12];
41+
}
42+
43+
bb2: {
44+
_10 = const true;
45+
StorageDead(_3);
46+
PlaceMention(_2);
47+
_7 = discriminant(_2);
48+
switchInt(move _7) -> [0: bb5, 1: bb4, otherwise: bb3];
49+
}
50+
51+
bb3: {
52+
unreachable;
53+
}
54+
55+
bb4: {
56+
StorageLive(_9);
57+
_9 = copy ((_2 as Err).0: ());
58+
_0 = const ();
59+
StorageDead(_9);
60+
goto -> bb7;
61+
}
62+
63+
bb5: {
64+
StorageLive(_8);
65+
_8 = move ((_2 as Ok).0: OtherDrop);
66+
_0 = const ();
67+
drop(_8) -> [return: bb6, unwind: bb11];
68+
}
69+
70+
bb6: {
71+
StorageDead(_8);
72+
goto -> bb7;
73+
}
74+
75+
bb7: {
76+
backward incompatible drop(_2);
77+
backward incompatible drop(_5);
78+
goto -> bb21;
79+
}
80+
81+
bb8: {
82+
drop(_5) -> [return: bb9, unwind: bb13];
83+
}
84+
85+
bb9: {
86+
StorageDead(_5);
87+
StorageDead(_4);
88+
_10 = const false;
89+
StorageDead(_2);
90+
drop(_1) -> [return: bb10, unwind: bb14];
91+
}
92+
93+
bb10: {
94+
return;
95+
}
96+
97+
bb11 (cleanup): {
98+
goto -> bb25;
99+
}
100+
101+
bb12 (cleanup): {
102+
drop(_5) -> [return: bb13, unwind terminate(cleanup)];
103+
}
104+
105+
bb13 (cleanup): {
106+
drop(_1) -> [return: bb14, unwind terminate(cleanup)];
107+
}
108+
109+
bb14 (cleanup): {
110+
resume;
111+
}
112+
113+
bb15: {
114+
goto -> bb8;
115+
}
116+
117+
bb16 (cleanup): {
118+
goto -> bb12;
119+
}
120+
121+
bb17 (cleanup): {
122+
goto -> bb12;
123+
}
124+
125+
bb18: {
126+
goto -> bb15;
127+
}
128+
129+
bb19: {
130+
goto -> bb15;
131+
}
132+
133+
bb20 (cleanup): {
134+
goto -> bb12;
135+
}
136+
137+
bb21: {
138+
_11 = discriminant(_2);
139+
switchInt(move _11) -> [0: bb18, otherwise: bb19];
140+
}
141+
142+
bb22 (cleanup): {
143+
_12 = discriminant(_2);
144+
switchInt(move _12) -> [0: bb16, otherwise: bb20];
145+
}
146+
147+
bb23 (cleanup): {
148+
goto -> bb12;
149+
}
150+
151+
bb24 (cleanup): {
152+
goto -> bb12;
153+
}
154+
155+
bb25 (cleanup): {
156+
_13 = discriminant(_2);
157+
switchInt(move _13) -> [0: bb23, otherwise: bb24];
158+
}
159+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// skip-filecheck
2+
// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
3+
// EMIT_MIR tail_expr_drop_order_unwind.method_1.ElaborateDrops.after.mir
4+
5+
#![deny(tail_expr_drop_order)]
6+
7+
use std::backtrace::Backtrace;
8+
9+
#[derive(Clone)]
10+
struct Guard;
11+
impl Drop for Guard {
12+
fn drop(&mut self) {
13+
println!("Drop!");
14+
}
15+
}
16+
17+
#[derive(Clone)]
18+
struct OtherDrop;
19+
impl Drop for OtherDrop {
20+
fn drop(&mut self) {
21+
println!("Drop!");
22+
}
23+
}
24+
25+
fn method_1(g: Guard) {
26+
match method_2(&g.clone()) {
27+
Ok(other_drop) => {
28+
// repro needs something else being dropped too.
29+
}
30+
Err(err) => {}
31+
}
32+
}
33+
34+
fn method_2(_: &Guard) -> Result<OtherDrop, ()> {
35+
panic!("Method 2 panics!");
36+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![crate_type = "lib"]
2+
#![crate_name = "foo"]
3+
4+
extern crate foo;
5+
6+
pub struct Struct;
7+
pub trait Trait {}
8+
impl Trait for Struct {}
9+
10+
fn check_trait<T: Trait>() {}
11+
12+
fn ice() {
13+
check_trait::<foo::Struct>();
14+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![crate_type = "lib"]
2+
#![crate_name = "foo"]
3+
4+
pub struct Struct;
5+
pub trait Trait {}
6+
impl Trait for Struct {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0277]: the trait bound `foo::Struct: Trait` is not satisfied because the trait comes from a different crate version
2+
--> foo-current.rs:13:19
3+
|
4+
13 | check_trait::<foo::Struct>();
5+
| ^^^^^^^^^^^ the trait `Trait` is not implemented for `foo::Struct`
6+
|
7+
note: there are multiple different versions of crate `foo` in the dependency graph
8+
--> foo-current.rs:7:1
9+
|
10+
4 | extern crate foo;
11+
| ----------------- one version of crate `foo` is used here, as a direct dependency of the current crate
12+
5 |
13+
6 | pub struct Struct;
14+
| ----------------- this type implements the required trait
15+
7 | pub trait Trait {}
16+
| ^^^^^^^^^^^^^^^ this is the required trait
17+
|
18+
::: foo-prev.rs:X:Y
19+
|
20+
4 | pub struct Struct;
21+
| ----------------- this type doesn't implement the required trait
22+
5 | pub trait Trait {}
23+
| --------------- this is the found trait
24+
= note: two types coming from two different versions of the same crate are different types even if they look the same
25+
= help: you can use `cargo tree` to explore your dependency tree
26+
27+
error: aborting due to 1 previous error
28+
29+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//@ only-linux
2+
//@ ignore-wasm32
3+
//@ ignore-wasm64
4+
// ignore-tidy-linelength
5+
6+
// Verify that if the current crate depends on a different version of the same crate, *and* types
7+
// and traits of the different versions are mixed, we produce diagnostic output and not an ICE.
8+
// #133563
9+
10+
use run_make_support::{diff, rust_lib_name, rustc};
11+
12+
fn main() {
13+
rustc().input("foo-prev.rs").run();
14+
15+
let out = rustc()
16+
.extra_filename("current")
17+
.metadata("current")
18+
.input("foo-current.rs")
19+
.extern_("foo", rust_lib_name("foo"))
20+
.run_fail()
21+
.stderr_utf8();
22+
23+
// We don't remap the path of the `foo-prev` crate, so we remap it here.
24+
let mut lines: Vec<_> = out.lines().collect();
25+
for line in &mut lines {
26+
if line.starts_with(" ::: ") {
27+
*line = " ::: foo-prev.rs:X:Y";
28+
}
29+
}
30+
diff().expected_file("foo.stderr").actual_text("(rustc)", &lines.join("\n")).run();
31+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
2+
--> replaced
3+
|
4+
LL | do_something(Type);
5+
| ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
6+
|
7+
note: there are multiple different versions of crate `dependency` in the dependency graph
8+
--> replaced
9+
|
10+
LL | pub struct Type(pub i32);
11+
| --------------- this type implements the required trait
12+
LL | pub trait Trait {
13+
| ^^^^^^^^^^^^^^^ this is the required trait
14+
|
15+
::: replaced
16+
|
17+
LL | extern crate dep_2_reexport;
18+
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
19+
LL | extern crate dependency;
20+
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
21+
|
22+
::: replaced
23+
|
24+
LL | pub struct Type;
25+
| --------------- this type doesn't implement the required trait
26+
LL | pub trait Trait {
27+
| --------------- this is the found trait
28+
= note: two types coming from two different versions of the same crate are different types even if they look the same
29+
= help: you can use `cargo tree` to explore your dependency tree
30+
31+
error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
32+
--> replaced
33+
|
34+
LL | Type.foo();
35+
| ^^^ method not found in `Type`
36+
|
37+
note: there are multiple different versions of crate `dependency` in the dependency graph
38+
--> replaced
39+
|
40+
LL | pub trait Trait {
41+
| ^^^^^^^^^^^^^^^ this is the trait that is needed
42+
LL | fn foo(&self);
43+
| -------------- the method is available for `dep_2_reexport::Type` here
44+
|
45+
::: replaced
46+
|
47+
LL | use dependency::{Trait, do_something};
48+
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
49+
|
50+
::: replaced
51+
|
52+
LL | pub trait Trait {
53+
| --------------- this is the trait that was imported
54+
55+
error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
56+
--> replaced
57+
|
58+
LL | Type::bar();
59+
| ^^^ function or associated item not found in `Type`
60+
|
61+
note: there are multiple different versions of crate `dependency` in the dependency graph
62+
--> replaced
63+
|
64+
LL | pub trait Trait {
65+
| ^^^^^^^^^^^^^^^ this is the trait that is needed
66+
LL | fn foo(&self);
67+
LL | fn bar();
68+
| --------- the associated function is available for `dep_2_reexport::Type` here
69+
|
70+
::: replaced
71+
|
72+
LL | use dependency::{Trait, do_something};
73+
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`
74+
|
75+
::: replaced
76+
|
77+
LL | pub trait Trait {
78+
| --------------- this is the trait that was imported
79+
80+
error[E0277]: the trait bound `OtherType: Trait` is not satisfied because the trait comes from a different crate version
81+
--> replaced
82+
|
83+
LL | do_something(OtherType);
84+
| ^^^^^^^^^ the trait `Trait` is not implemented for `OtherType`
85+
|
86+
note: there are multiple different versions of crate `dependency` in the dependency graph
87+
--> replaced
88+
|
89+
LL | pub trait Trait {
90+
| ^^^^^^^^^^^^^^^ this is the required trait
91+
|
92+
::: replaced
93+
|
94+
LL | extern crate dep_2_reexport;
95+
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
96+
LL | extern crate dependency;
97+
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate
98+
|
99+
::: replaced
100+
|
101+
LL | pub struct OtherType;
102+
| -------------------- this type doesn't implement the required trait
103+
|
104+
::: replaced
105+
|
106+
LL | pub trait Trait {
107+
| --------------- this is the found trait
108+
= help: you can use `cargo tree` to explore your dependency tree
109+
110+
error: aborting due to 4 previous errors
111+
112+
Some errors have detailed explanations: E0277, E0599.
113+
For more information about an error, try `rustc --explain E0277`.

‎tests/run-make/crate-loading/rmake.rs

Lines changed: 19 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//@ ignore-wasm64
44
// ignore-tidy-linelength
55

6-
use run_make_support::{rust_lib_name, rustc};
6+
use run_make_support::{diff, rust_lib_name, rustc};
77

88
fn main() {
99
rustc().input("multiple-dep-versions-1.rs").run();
@@ -13,77 +13,26 @@ fn main() {
1313
.extern_("dependency", rust_lib_name("dependency2"))
1414
.run();
1515

16-
rustc()
16+
let out = rustc()
1717
.input("multiple-dep-versions.rs")
1818
.extern_("dependency", rust_lib_name("dependency"))
1919
.extern_("dep_2_reexport", rust_lib_name("foo"))
20+
.ui_testing()
2021
.run_fail()
21-
.assert_stderr_contains(r#"error[E0277]: the trait bound `dep_2_reexport::Type: Trait` is not satisfied because the trait comes from a different crate version
22-
--> multiple-dep-versions.rs:7:18
23-
|
24-
7 | do_something(Type);
25-
| ^^^^ the trait `Trait` is not implemented for `dep_2_reexport::Type`
26-
|
27-
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
28-
.assert_stderr_contains(r#"
29-
3 | pub struct Type(pub i32);
30-
| --------------- this type implements the required trait
31-
4 | pub trait Trait {
32-
| ^^^^^^^^^^^^^^^ this is the required trait
33-
"#)
34-
.assert_stderr_contains(r#"
35-
1 | extern crate dep_2_reexport;
36-
| ---------------------------- one version of crate `dependency` is used here, as a dependency of crate `foo`
37-
2 | extern crate dependency;
38-
| ------------------------ one version of crate `dependency` is used here, as a direct dependency of the current crate"#)
39-
.assert_stderr_contains(r#"
40-
3 | pub struct Type;
41-
| --------------- this type doesn't implement the required trait
42-
4 | pub trait Trait {
43-
| --------------- this is the found trait
44-
= note: two types coming from two different versions of the same crate are different types even if they look the same
45-
= help: you can use `cargo tree` to explore your dependency tree"#)
46-
.assert_stderr_contains(r#"error[E0599]: no method named `foo` found for struct `dep_2_reexport::Type` in the current scope
47-
--> multiple-dep-versions.rs:8:10
48-
|
49-
8 | Type.foo();
50-
| ^^^ method not found in `Type`
51-
|
52-
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
53-
.assert_stderr_contains(r#"
54-
4 | pub trait Trait {
55-
| ^^^^^^^^^^^^^^^ this is the trait that is needed
56-
5 | fn foo(&self);
57-
| -------------- the method is available for `dep_2_reexport::Type` here
58-
|
59-
::: multiple-dep-versions.rs:4:18
60-
|
61-
4 | use dependency::{Trait, do_something};
62-
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
63-
.assert_stderr_contains(r#"
64-
4 | pub trait Trait {
65-
| --------------- this is the trait that was imported"#)
66-
.assert_stderr_contains(r#"
67-
error[E0599]: no function or associated item named `bar` found for struct `dep_2_reexport::Type` in the current scope
68-
--> multiple-dep-versions.rs:9:11
69-
|
70-
9 | Type::bar();
71-
| ^^^ function or associated item not found in `Type`
72-
|
73-
note: there are multiple different versions of crate `dependency` in the dependency graph"#)
74-
.assert_stderr_contains(r#"
75-
4 | pub trait Trait {
76-
| ^^^^^^^^^^^^^^^ this is the trait that is needed
77-
5 | fn foo(&self);
78-
6 | fn bar();
79-
| --------- the associated function is available for `dep_2_reexport::Type` here
80-
|
81-
::: multiple-dep-versions.rs:4:18
82-
|
83-
4 | use dependency::{Trait, do_something};
84-
| ----- `Trait` imported here doesn't correspond to the right version of crate `dependency`"#)
85-
.assert_stderr_contains(
86-
r#"
87-
6 | pub struct OtherType;
88-
| -------------------- this type doesn't implement the required trait"#);
22+
.stderr_utf8();
23+
24+
// We don't remap all the paths, so we remap it here.
25+
let mut lines: Vec<_> = out.lines().collect();
26+
for line in &mut lines {
27+
if line.starts_with(" --> ") {
28+
*line = " --> replaced";
29+
}
30+
if line.starts_with(" ::: ") {
31+
*line = " ::: replaced";
32+
}
33+
}
34+
diff()
35+
.expected_file("multiple-dep-versions.stderr")
36+
.actual_text("(rustc)", &lines.join("\n"))
37+
.run();
8938
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//@ compile-flags:--test --test-args --test-threads=1
2+
//@ failure-status: 101
3+
//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
4+
//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
5+
//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
6+
7+
//! ```
8+
#![doc = "#![all\
9+
ow(unused)]"]
10+
//! ```
11+
//!
12+
//! ```
13+
#![doc = r#"#![all\
14+
ow(unused)]"#]
15+
//! ```
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
running 2 tests
3+
test $DIR/comment-in-attr-134221-2.rs - (line 11) ... FAILED
4+
test $DIR/comment-in-attr-134221-2.rs - (line 7) ... ok
5+
6+
failures:
7+
8+
---- $DIR/comment-in-attr-134221-2.rs - (line 11) stdout ----
9+
error: unknown start of token: \
10+
--> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL
11+
|
12+
LL | #![all\
13+
| ^
14+
15+
error: expected one of `(`, `::`, `=`, `[`, `]`, or `{`, found `ow`
16+
--> $DIR/comment-in-attr-134221-2.rs:$LINE:$COL
17+
|
18+
LL | #![all\
19+
| - expected one of `(`, `::`, `=`, `[`, `]`, or `{`
20+
LL | ow(unused)]
21+
| ^^ unexpected token
22+
23+
error: aborting due to 2 previous errors
24+
25+
Couldn't compile the test.
26+
27+
failures:
28+
$DIR/comment-in-attr-134221-2.rs - (line 11)
29+
30+
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
31+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/134221>.
2+
// It checks that even if there are comments in the attributes, the attributes
3+
// will still be generated correctly (and therefore fail in this test).
4+
5+
//@ compile-flags:--test --test-args --test-threads=1
6+
//@ failure-status: 101
7+
//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
8+
//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
9+
//@ normalize-stdout-test: ".rs:\d+:\d+" -> ".rs:$$LINE:$$COL"
10+
11+
/*!
12+
```rust
13+
#![feature(
14+
foo, //
15+
)]
16+
```
17+
18+
```rust
19+
#![feature(
20+
foo,
21+
)]
22+
```
23+
24+
```rust
25+
#![
26+
```
27+
*/
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
running 3 tests
3+
test $DIR/comment-in-attr-134221.rs - (line 11) ... FAILED
4+
test $DIR/comment-in-attr-134221.rs - (line 17) ... FAILED
5+
test $DIR/comment-in-attr-134221.rs - (line 23) ... FAILED
6+
7+
failures:
8+
9+
---- $DIR/comment-in-attr-134221.rs - (line 11) stdout ----
10+
error[E0635]: unknown feature `foo`
11+
--> $DIR/comment-in-attr-134221.rs:$LINE:$COL
12+
|
13+
LL | foo, //
14+
| ^^^
15+
16+
error: aborting due to 1 previous error
17+
18+
For more information about this error, try `rustc --explain E0635`.
19+
Couldn't compile the test.
20+
---- $DIR/comment-in-attr-134221.rs - (line 17) stdout ----
21+
error[E0635]: unknown feature `foo`
22+
--> $DIR/comment-in-attr-134221.rs:$LINE:$COL
23+
|
24+
LL | foo,
25+
| ^^^
26+
27+
error: aborting due to 1 previous error
28+
29+
For more information about this error, try `rustc --explain E0635`.
30+
Couldn't compile the test.
31+
---- $DIR/comment-in-attr-134221.rs - (line 23) stdout ----
32+
error: this file contains an unclosed delimiter
33+
--> $DIR/comment-in-attr-134221.rs:$LINE:$COL
34+
|
35+
LL | #![
36+
| -^
37+
| |
38+
| unclosed delimiter
39+
40+
error: aborting due to 1 previous error
41+
42+
Couldn't compile the test.
43+
44+
failures:
45+
$DIR/comment-in-attr-134221.rs - (line 11)
46+
$DIR/comment-in-attr-134221.rs - (line 17)
47+
$DIR/comment-in-attr-134221.rs - (line 23)
48+
49+
test result: FAILED. 0 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
50+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//@ edition: 2021
2+
//@ build-fail
3+
4+
// Make sure we don't ICE when emitting the "lint" drop statement
5+
// used for tail_expr_drop_order.
6+
7+
#![deny(tail_expr_drop_order)]
8+
9+
struct Drop;
10+
impl std::ops::Drop for Drop {
11+
fn drop(&mut self) {}
12+
}
13+
14+
async fn func() -> Result<(), Drop> {
15+
todo!()
16+
}
17+
18+
async fn retry_db() -> Result<(), Drop> {
19+
loop {
20+
match func().await {
21+
//~^ ERROR relative drop order changing in Rust 2024
22+
//~| WARNING this changes meaning in Rust 2024
23+
Ok(()) => return Ok(()),
24+
Err(e) => {}
25+
}
26+
}
27+
}
28+
29+
fn main() {}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
error: relative drop order changing in Rust 2024
2+
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:20:15
3+
|
4+
LL | match func().await {
5+
| ^^^^^^^-----
6+
| | |
7+
| | this value will be stored in a temporary; let us call it `#1`
8+
| | `#1` will be dropped later as of Edition 2024
9+
| this value will be stored in a temporary; let us call it `#2`
10+
| up until Edition 2021 `#2` is dropped last but will be dropped earlier in Edition 2024
11+
...
12+
LL | Err(e) => {}
13+
| -
14+
| |
15+
| `e` calls a custom destructor
16+
| `e` will be dropped later as of Edition 2024
17+
LL | }
18+
LL | }
19+
| - now the temporary value is dropped here, before the local variables in the block or statement
20+
|
21+
= warning: this changes meaning in Rust 2024
22+
= note: for more information, see issue #123739 <https://github.com/rust-lang/rust/issues/123739>
23+
note: `#2` invokes this custom destructor
24+
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
25+
|
26+
LL | / impl std::ops::Drop for Drop {
27+
LL | | fn drop(&mut self) {}
28+
LL | | }
29+
| |_^
30+
note: `#1` invokes this custom destructor
31+
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
32+
|
33+
LL | / impl std::ops::Drop for Drop {
34+
LL | | fn drop(&mut self) {}
35+
LL | | }
36+
| |_^
37+
note: `e` invokes this custom destructor
38+
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:10:1
39+
|
40+
LL | / impl std::ops::Drop for Drop {
41+
LL | | fn drop(&mut self) {}
42+
LL | | }
43+
| |_^
44+
= note: most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
45+
note: the lint level is defined here
46+
--> $DIR/tail_expr_drop_order-on-coroutine-unwind.rs:7:9
47+
|
48+
LL | #![deny(tail_expr_drop_order)]
49+
| ^^^^^^^^^^^^^^^^^^^^
50+
51+
error: aborting due to 1 previous error
52+

0 commit comments

Comments
 (0)
Please sign in to comment.