Skip to content

Commit e1b28cd

Browse files
committed
Auto merge of rust-lang#100740 - Dylan-DPC:rollup-0td6yq4, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - rust-lang#99576 (Do not allow `Drop` impl on foreign fundamental types) - rust-lang#100081 (never consider unsafe blocks unused if they would be required with deny(unsafe_op_in_unsafe_fn)) - rust-lang#100208 (make NOP dyn casts not require anything about the vtable) - rust-lang#100494 (Cleanup rustdoc themes) - rust-lang#100522 (Only check the `DefId` for the recursion check in MIR inliner.) - rust-lang#100592 (Manually implement Debug for ImportKind.) - rust-lang#100598 (Don't fix builtin index when Where clause is found) - rust-lang#100721 (Add diagnostics lints to `rustc_type_ir` module) - rust-lang#100731 (rustdoc: count deref and non-deref as same set of used methods) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 468887e + ecd2885 commit e1b28cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+851
-992
lines changed

compiler/rustc_codegen_cranelift/src/unsize.rs

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub(crate) fn unsized_info<'tcx>(
2929
let old_info =
3030
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
3131
if data_a.principal_def_id() == data_b.principal_def_id() {
32+
// A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
3233
return old_info;
3334
}
3435

compiler/rustc_codegen_ssa/src/base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
151151
let old_info =
152152
old_info.expect("unsized_info: missing old info for trait upcasting coercion");
153153
if data_a.principal_def_id() == data_b.principal_def_id() {
154+
// A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
154155
return old_info;
155156
}
156157

compiler/rustc_const_eval/src/interpret/cast.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
298298
self.write_immediate(val, dest)
299299
}
300300
(&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
301-
let (old_data, old_vptr) = self.read_immediate(src)?.to_scalar_pair()?;
301+
let val = self.read_immediate(src)?;
302+
if data_a.principal() == data_b.principal() {
303+
// A NOP cast that doesn't actually change anything, should be allowed even with mismatching vtables.
304+
return self.write_immediate(*val, dest);
305+
}
306+
let (old_data, old_vptr) = val.to_scalar_pair()?;
302307
let old_vptr = old_vptr.to_pointer(self)?;
303308
let (ty, old_trait) = self.get_ptr_vtable(old_vptr)?;
304309
if old_trait != data_a.principal() {

compiler/rustc_error_messages/locales/en-US/typeck.ftl

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ typeck_lifetimes_or_bounds_mismatch_on_trait =
2424
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
2525
2626
typeck_drop_impl_on_wrong_item =
27-
the `Drop` trait may only be implemented for structs, enums, and unions
28-
.label = must be a struct, enum, or union
27+
the `Drop` trait may only be implemented for local structs, enums, and unions
28+
.label = must be a struct, enum, or union in the current crate
2929
3030
typeck_field_already_declared =
3131
field `{$field_name}` is already declared

compiler/rustc_errors/src/diagnostic_builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ impl Drop for DiagnosticBuilderInner<'_> {
566566
),
567567
));
568568
handler.emit_diagnostic(&mut self.diagnostic);
569-
panic!();
569+
panic!("error was constructed but not emitted");
570570
}
571571
}
572572
// `.emit()` was previously called, or maybe we're during `.cancel()`.

compiler/rustc_middle/src/mir/query.rs

+2-20
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::mir::{Body, ConstantKind, Promoted};
44
use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
5-
use rustc_data_structures::fx::FxHashMap;
5+
use rustc_data_structures::fx::FxHashSet;
66
use rustc_data_structures::vec_map::VecMap;
77
use rustc_errors::ErrorGuaranteed;
88
use rustc_hir as hir;
@@ -115,21 +115,6 @@ pub enum UnusedUnsafe {
115115
/// `unsafe` block nested under another (used) `unsafe` block
116116
/// > ``… because it's nested under this `unsafe` block``
117117
InUnsafeBlock(hir::HirId),
118-
/// `unsafe` block nested under `unsafe fn`
119-
/// > ``… because it's nested under this `unsafe fn` ``
120-
///
121-
/// the second HirId here indicates the first usage of the `unsafe` block,
122-
/// which allows retrieval of the LintLevelSource for why that operation would
123-
/// have been permitted without the block
124-
InUnsafeFn(hir::HirId, hir::HirId),
125-
}
126-
127-
#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
128-
pub enum UsedUnsafeBlockData {
129-
SomeDisallowedInUnsafeFn,
130-
// the HirId here indicates the first usage of the `unsafe` block
131-
// (i.e. the one that's first encountered in the MIR traversal of the unsafety check)
132-
AllAllowedInUnsafeFn(hir::HirId),
133118
}
134119

135120
#[derive(TyEncodable, TyDecodable, HashStable, Debug)]
@@ -138,10 +123,7 @@ pub struct UnsafetyCheckResult {
138123
pub violations: Vec<UnsafetyViolation>,
139124

140125
/// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
141-
///
142-
/// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
143-
/// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
144-
pub used_unsafe_blocks: FxHashMap<hir::HirId, UsedUnsafeBlockData>,
126+
pub used_unsafe_blocks: FxHashSet<hir::HirId>,
145127

146128
/// This is `Some` iff the item is not a closure.
147129
pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,

compiler/rustc_mir_build/src/check_unsafety.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
7575
match self.safety_context {
7676
SafetyContext::BuiltinUnsafeBlock => {}
7777
SafetyContext::UnsafeBlock { ref mut used, .. } => {
78-
if !self.body_unsafety.is_unsafe() || !unsafe_op_in_unsafe_fn_allowed {
79-
// Mark this block as useful
80-
*used = true;
81-
}
78+
// Mark this block as useful (even inside `unsafe fn`, where it is technically
79+
// redundant -- but we want to eventually enable `unsafe_op_in_unsafe_fn` by
80+
// default which will require those blocks:
81+
// https://github.com/rust-lang/rust/issues/71668#issuecomment-1203075594).
82+
*used = true;
8283
}
8384
SafetyContext::UnsafeFn if unsafe_op_in_unsafe_fn_allowed => {}
8485
SafetyContext::UnsafeFn => {

compiler/rustc_mir_transform/src/check_unsafety.rs

+17-71
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
use rustc_data_structures::fx::FxHashMap;
1+
use rustc_data_structures::fx::FxHashSet;
22
use rustc_errors::struct_span_err;
33
use rustc_hir as hir;
44
use rustc_hir::def_id::{DefId, LocalDefId};
55
use rustc_hir::hir_id::HirId;
66
use rustc_hir::intravisit;
77
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
8+
use rustc_middle::mir::*;
89
use rustc_middle::ty::query::Providers;
910
use rustc_middle::ty::{self, TyCtxt};
10-
use rustc_middle::{lint, mir::*};
1111
use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
1212
use rustc_session::lint::Level;
1313

14-
use std::collections::hash_map;
1514
use std::ops::Bound;
1615

1716
pub struct UnsafetyChecker<'a, 'tcx> {
@@ -23,10 +22,7 @@ pub struct UnsafetyChecker<'a, 'tcx> {
2322
param_env: ty::ParamEnv<'tcx>,
2423

2524
/// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
26-
///
27-
/// The keys are the used `unsafe` blocks, the UnusedUnsafeKind indicates whether
28-
/// or not any of the usages happen at a place that doesn't allow `unsafe_op_in_unsafe_fn`.
29-
used_unsafe_blocks: FxHashMap<HirId, UsedUnsafeBlockData>,
25+
used_unsafe_blocks: FxHashSet<HirId>,
3026
}
3127

3228
impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
@@ -130,10 +126,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
130126
&AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => {
131127
let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
132128
self.tcx.unsafety_check_result(def_id);
133-
self.register_violations(
134-
violations,
135-
used_unsafe_blocks.iter().map(|(&h, &d)| (h, d)),
136-
);
129+
self.register_violations(violations, used_unsafe_blocks.iter().copied());
137130
}
138131
},
139132
_ => {}
@@ -257,22 +250,8 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
257250
fn register_violations<'a>(
258251
&mut self,
259252
violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
260-
new_used_unsafe_blocks: impl IntoIterator<Item = (HirId, UsedUnsafeBlockData)>,
253+
new_used_unsafe_blocks: impl IntoIterator<Item = HirId>,
261254
) {
262-
use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
263-
264-
let update_entry = |this: &mut Self, hir_id, new_usage| {
265-
match this.used_unsafe_blocks.entry(hir_id) {
266-
hash_map::Entry::Occupied(mut entry) => {
267-
if new_usage == SomeDisallowedInUnsafeFn {
268-
*entry.get_mut() = SomeDisallowedInUnsafeFn;
269-
}
270-
}
271-
hash_map::Entry::Vacant(entry) => {
272-
entry.insert(new_usage);
273-
}
274-
};
275-
};
276255
let safety = self.body.source_scopes[self.source_info.scope]
277256
.local_data
278257
.as_ref()
@@ -299,22 +278,14 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
299278
}
300279
}),
301280
Safety::BuiltinUnsafe => {}
302-
Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|violation| {
303-
update_entry(
304-
self,
305-
hir_id,
306-
match self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, violation.lint_root).0
307-
{
308-
Level::Allow => AllAllowedInUnsafeFn(violation.lint_root),
309-
_ => SomeDisallowedInUnsafeFn,
310-
},
311-
)
281+
Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| {
282+
self.used_unsafe_blocks.insert(hir_id);
312283
}),
313284
};
314285

315-
new_used_unsafe_blocks
316-
.into_iter()
317-
.for_each(|(hir_id, usage_data)| update_entry(self, hir_id, usage_data));
286+
new_used_unsafe_blocks.into_iter().for_each(|hir_id| {
287+
self.used_unsafe_blocks.insert(hir_id);
288+
});
318289
}
319290
fn check_mut_borrowing_layout_constrained_field(
320291
&mut self,
@@ -411,34 +382,28 @@ enum Context {
411382

412383
struct UnusedUnsafeVisitor<'a, 'tcx> {
413384
tcx: TyCtxt<'tcx>,
414-
used_unsafe_blocks: &'a FxHashMap<HirId, UsedUnsafeBlockData>,
385+
used_unsafe_blocks: &'a FxHashSet<HirId>,
415386
context: Context,
416387
unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>,
417388
}
418389

419390
impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
420391
fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
421-
use UsedUnsafeBlockData::{AllAllowedInUnsafeFn, SomeDisallowedInUnsafeFn};
422-
423392
if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules {
424393
let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) {
425-
(Level::Allow, _) => Some(SomeDisallowedInUnsafeFn),
426-
_ => self.used_unsafe_blocks.get(&block.hir_id).copied(),
394+
(Level::Allow, _) => true,
395+
_ => self.used_unsafe_blocks.contains(&block.hir_id),
427396
};
428397
let unused_unsafe = match (self.context, used) {
429-
(_, None) => UnusedUnsafe::Unused,
430-
(Context::Safe, Some(_))
431-
| (Context::UnsafeFn(_), Some(SomeDisallowedInUnsafeFn)) => {
398+
(_, false) => UnusedUnsafe::Unused,
399+
(Context::Safe, true) | (Context::UnsafeFn(_), true) => {
432400
let previous_context = self.context;
433401
self.context = Context::UnsafeBlock(block.hir_id);
434402
intravisit::walk_block(self, block);
435403
self.context = previous_context;
436404
return;
437405
}
438-
(Context::UnsafeFn(hir_id), Some(AllAllowedInUnsafeFn(lint_root))) => {
439-
UnusedUnsafe::InUnsafeFn(hir_id, lint_root)
440-
}
441-
(Context::UnsafeBlock(hir_id), Some(_)) => UnusedUnsafe::InUnsafeBlock(hir_id),
406+
(Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id),
442407
};
443408
self.unused_unsafes.push((block.hir_id, unused_unsafe));
444409
}
@@ -462,7 +427,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
462427
fn check_unused_unsafe(
463428
tcx: TyCtxt<'_>,
464429
def_id: LocalDefId,
465-
used_unsafe_blocks: &FxHashMap<HirId, UsedUnsafeBlockData>,
430+
used_unsafe_blocks: &FxHashSet<HirId>,
466431
) -> Vec<(HirId, UnusedUnsafe)> {
467432
let body_id = tcx.hir().maybe_body_owned_by(def_id);
468433

@@ -535,25 +500,6 @@ fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
535500
"because it's nested under this `unsafe` block",
536501
);
537502
}
538-
UnusedUnsafe::InUnsafeFn(id, usage_lint_root) => {
539-
db.span_label(
540-
tcx.sess.source_map().guess_head_span(tcx.hir().span(id)),
541-
"because it's nested under this `unsafe` fn",
542-
)
543-
.note(
544-
"this `unsafe` block does contain unsafe operations, \
545-
but those are already allowed in an `unsafe fn`",
546-
);
547-
let (level, source) =
548-
tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, usage_lint_root);
549-
assert_eq!(level, Level::Allow);
550-
lint::explain_lint_level_source(
551-
UNSAFE_OP_IN_UNSAFE_FN,
552-
Level::Allow,
553-
source,
554-
&mut db,
555-
);
556-
}
557503
}
558504

559505
db.emit();

compiler/rustc_mir_transform/src/inline.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rustc_middle::mir::*;
1010
use rustc_middle::ty::subst::Subst;
1111
use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyCtxt};
1212
use rustc_session::config::OptLevel;
13+
use rustc_span::def_id::DefId;
1314
use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span};
1415
use rustc_target::spec::abi::Abi;
1516

@@ -103,8 +104,12 @@ struct Inliner<'tcx> {
103104
param_env: ParamEnv<'tcx>,
104105
/// Caller codegen attributes.
105106
codegen_fn_attrs: &'tcx CodegenFnAttrs,
106-
/// Stack of inlined Instances.
107-
history: Vec<ty::Instance<'tcx>>,
107+
/// Stack of inlined instances.
108+
/// We only check the `DefId` and not the substs because we want to
109+
/// avoid inlining cases of polymorphic recursion.
110+
/// The number of `DefId`s is finite, so checking history is enough
111+
/// to ensure that we do not loop endlessly while inlining.
112+
history: Vec<DefId>,
108113
/// Indicates that the caller body has been modified.
109114
changed: bool,
110115
}
@@ -132,7 +137,7 @@ impl<'tcx> Inliner<'tcx> {
132137
Ok(new_blocks) => {
133138
debug!("inlined {}", callsite.callee);
134139
self.changed = true;
135-
self.history.push(callsite.callee);
140+
self.history.push(callsite.callee.def_id());
136141
self.process_blocks(caller_body, new_blocks);
137142
self.history.pop();
138143
}
@@ -308,7 +313,7 @@ impl<'tcx> Inliner<'tcx> {
308313
return None;
309314
}
310315

311-
if self.history.contains(&callee) {
316+
if self.history.contains(&callee.def_id()) {
312317
return None;
313318
}
314319

compiler/rustc_resolve/src/imports.rs

+39-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use std::{mem, ptr};
3131
type Res = def::Res<NodeId>;
3232

3333
/// Contains data for specific kinds of imports.
34-
#[derive(Clone, Debug)]
34+
#[derive(Clone)]
3535
pub enum ImportKind<'a> {
3636
Single {
3737
/// `source` in `use prefix::source as target`.
@@ -62,6 +62,44 @@ pub enum ImportKind<'a> {
6262
MacroUse,
6363
}
6464

65+
/// Manually implement `Debug` for `ImportKind` because the `source/target_bindings`
66+
/// contain `Cell`s which can introduce infinite loops while printing.
67+
impl<'a> std::fmt::Debug for ImportKind<'a> {
68+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69+
use ImportKind::*;
70+
match self {
71+
Single {
72+
ref source,
73+
ref target,
74+
ref type_ns_only,
75+
ref nested,
76+
ref additional_ids,
77+
// Ignore the following to avoid an infinite loop while printing.
78+
source_bindings: _,
79+
target_bindings: _,
80+
} => f
81+
.debug_struct("Single")
82+
.field("source", source)
83+
.field("target", target)
84+
.field("type_ns_only", type_ns_only)
85+
.field("nested", nested)
86+
.field("additional_ids", additional_ids)
87+
.finish_non_exhaustive(),
88+
Glob { ref is_prelude, ref max_vis } => f
89+
.debug_struct("Glob")
90+
.field("is_prelude", is_prelude)
91+
.field("max_vis", max_vis)
92+
.finish(),
93+
ExternCrate { ref source, ref target } => f
94+
.debug_struct("ExternCrate")
95+
.field("source", source)
96+
.field("target", target)
97+
.finish(),
98+
MacroUse => f.debug_struct("MacroUse").finish(),
99+
}
100+
}
101+
}
102+
65103
/// One import.
66104
#[derive(Debug, Clone)]
67105
pub(crate) struct Import<'a> {

compiler/rustc_type_ir/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![feature(fmt_helpers_for_derive)]
22
#![feature(min_specialization)]
33
#![feature(rustc_attrs)]
4+
#![deny(rustc::untranslatable_diagnostic)]
5+
#![deny(rustc::diagnostic_outside_of_impl)]
46

57
#[macro_use]
68
extern crate bitflags;

0 commit comments

Comments
 (0)