Skip to content

Commit 8a49772

Browse files
committed
Auto merge of #121271 - matthiaskrgr:rollup-56ru17w, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #118569 (Move `OsStr::slice_encoded_bytes` validation to platform modules) - #121067 (make "invalid fragment specifier" translatable) - #121224 (Remove unnecessary unit binding) - #121247 (Add help to `hir_analysis_unrecognized_intrinsic_function`) - #121257 (remove extraneous text from example config) - #121260 (Remove const_prop.rs) - #121266 (Add uncontroversial syscall doc aliases to std docs) r? `@ghost` `@rustbot` modify labels: rollup
2 parents c9c83cc + 5c03d0f commit 8a49772

29 files changed

+473
-248
lines changed

compiler/rustc_expand/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ expand_invalid_cfg_multiple_predicates = multiple `cfg` predicates are specified
6161
expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses
6262
expand_invalid_cfg_no_predicate = `cfg` predicate is not specified
6363
expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal
64+
65+
expand_invalid_fragment_specifier =
66+
invalid fragment specifier `{$fragment}`
67+
.help = {$help}
68+
6469
expand_macro_body_stability =
6570
macros cannot have body stability attributes
6671
.label = invalid body stability attribute

compiler/rustc_expand/src/errors.rs

+10
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,13 @@ pub struct DuplicateMatcherBinding {
408408
#[label(expand_label2)]
409409
pub prev: Span,
410410
}
411+
412+
#[derive(Diagnostic)]
413+
#[diag(expand_invalid_fragment_specifier)]
414+
#[help]
415+
pub struct InvalidFragmentSpecifier {
416+
#[primary_span]
417+
pub span: Span,
418+
pub fragment: Ident,
419+
pub help: String,
420+
}

compiler/rustc_expand/src/mbe/quoted.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::errors;
12
use crate::mbe::macro_parser::count_metavar_decls;
23
use crate::mbe::{Delimited, KleeneOp, KleeneToken, MetaVarExpr, SequenceRepetition, TokenTree};
34

@@ -60,11 +61,11 @@ pub(super) fn parse(
6061
Some(&tokenstream::TokenTree::Token(Token { kind: token::Colon, span }, _)) => {
6162
match trees.next() {
6263
Some(tokenstream::TokenTree::Token(token, _)) => match token.ident() {
63-
Some((frag, _)) => {
64+
Some((fragment, _)) => {
6465
let span = token.span.with_lo(start_sp.lo());
6566

6667
let kind =
67-
token::NonterminalKind::from_symbol(frag.name, || {
68+
token::NonterminalKind::from_symbol(fragment.name, || {
6869
// FIXME(#85708) - once we properly decode a foreign
6970
// crate's `SyntaxContext::root`, then we can replace
7071
// this with just `span.edition()`. A
@@ -81,14 +82,13 @@ pub(super) fn parse(
8182
})
8283
.unwrap_or_else(
8384
|| {
84-
let msg = format!(
85-
"invalid fragment specifier `{}`",
86-
frag.name
85+
sess.dcx().emit_err(
86+
errors::InvalidFragmentSpecifier {
87+
span,
88+
fragment,
89+
help: VALID_FRAGMENT_NAMES_MSG.into(),
90+
},
8791
);
88-
sess.dcx()
89-
.struct_span_err(span, msg)
90-
.with_help(VALID_FRAGMENT_NAMES_MSG)
91-
.emit();
9292
token::NonterminalKind::Ident
9393
},
9494
);

compiler/rustc_hir_analysis/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ hir_analysis_unrecognized_atomic_operation =
469469
hir_analysis_unrecognized_intrinsic_function =
470470
unrecognized intrinsic function: `{$name}`
471471
.label = unrecognized intrinsic
472+
.help = if you're adding an intrinsic, be sure to update `check_intrinsic_type`
472473
473474
hir_analysis_unused_associated_type_bounds =
474475
unnecessary associated type bound for not object safe associated type

compiler/rustc_hir_analysis/src/errors.rs

+1
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> {
143143

144144
#[derive(Diagnostic)]
145145
#[diag(hir_analysis_unrecognized_intrinsic_function, code = E0093)]
146+
#[help]
146147
pub struct UnrecognizedIntrinsicFunction {
147148
#[primary_span]
148149
#[label]

compiler/rustc_mir_transform/src/const_prop.rs

-161
This file was deleted.

compiler/rustc_mir_transform/src/const_prop_lint.rs

+127-5
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,14 @@ use rustc_const_eval::interpret::{
99
use rustc_data_structures::fx::FxHashSet;
1010
use rustc_hir::def::DefKind;
1111
use rustc_hir::HirId;
12-
use rustc_index::bit_set::BitSet;
13-
use rustc_index::{Idx, IndexVec};
14-
use rustc_middle::mir::visit::Visitor;
12+
use rustc_index::{bit_set::BitSet, Idx, IndexVec};
13+
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
1514
use rustc_middle::mir::*;
1615
use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
1716
use rustc_middle::ty::{self, ConstInt, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt};
1817
use rustc_span::Span;
1918
use rustc_target::abi::{Abi, FieldIdx, HasDataLayout, Size, TargetDataLayout, VariantIdx};
2019

21-
use crate::const_prop::CanConstProp;
22-
use crate::const_prop::ConstPropMode;
2320
use crate::dataflow_const_prop::DummyMachine;
2421
use crate::errors::{AssertLint, AssertLintKind};
2522
use crate::MirLint;
@@ -849,3 +846,128 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
849846
}
850847
}
851848
}
849+
850+
/// The maximum number of bytes that we'll allocate space for a local or the return value.
851+
/// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just
852+
/// Severely regress performance.
853+
const MAX_ALLOC_LIMIT: u64 = 1024;
854+
855+
/// The mode that `ConstProp` is allowed to run in for a given `Local`.
856+
#[derive(Clone, Copy, Debug, PartialEq)]
857+
pub enum ConstPropMode {
858+
/// The `Local` can be propagated into and reads of this `Local` can also be propagated.
859+
FullConstProp,
860+
/// The `Local` can only be propagated into and from its own block.
861+
OnlyInsideOwnBlock,
862+
/// The `Local` cannot be part of propagation at all. Any statement
863+
/// referencing it either for reading or writing will not get propagated.
864+
NoPropagation,
865+
}
866+
867+
pub struct CanConstProp {
868+
can_const_prop: IndexVec<Local, ConstPropMode>,
869+
// False at the beginning. Once set, no more assignments are allowed to that local.
870+
found_assignment: BitSet<Local>,
871+
}
872+
873+
impl CanConstProp {
874+
/// Returns true if `local` can be propagated
875+
pub fn check<'tcx>(
876+
tcx: TyCtxt<'tcx>,
877+
param_env: ParamEnv<'tcx>,
878+
body: &Body<'tcx>,
879+
) -> IndexVec<Local, ConstPropMode> {
880+
let mut cpv = CanConstProp {
881+
can_const_prop: IndexVec::from_elem(ConstPropMode::FullConstProp, &body.local_decls),
882+
found_assignment: BitSet::new_empty(body.local_decls.len()),
883+
};
884+
for (local, val) in cpv.can_const_prop.iter_enumerated_mut() {
885+
let ty = body.local_decls[local].ty;
886+
match tcx.layout_of(param_env.and(ty)) {
887+
Ok(layout) if layout.size < Size::from_bytes(MAX_ALLOC_LIMIT) => {}
888+
// Either the layout fails to compute, then we can't use this local anyway
889+
// or the local is too large, then we don't want to.
890+
_ => {
891+
*val = ConstPropMode::NoPropagation;
892+
continue;
893+
}
894+
}
895+
}
896+
// Consider that arguments are assigned on entry.
897+
for arg in body.args_iter() {
898+
cpv.found_assignment.insert(arg);
899+
}
900+
cpv.visit_body(body);
901+
cpv.can_const_prop
902+
}
903+
}
904+
905+
impl<'tcx> Visitor<'tcx> for CanConstProp {
906+
fn visit_place(&mut self, place: &Place<'tcx>, mut context: PlaceContext, loc: Location) {
907+
use rustc_middle::mir::visit::PlaceContext::*;
908+
909+
// Dereferencing just read the addess of `place.local`.
910+
if place.projection.first() == Some(&PlaceElem::Deref) {
911+
context = NonMutatingUse(NonMutatingUseContext::Copy);
912+
}
913+
914+
self.visit_local(place.local, context, loc);
915+
self.visit_projection(place.as_ref(), context, loc);
916+
}
917+
918+
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
919+
use rustc_middle::mir::visit::PlaceContext::*;
920+
match context {
921+
// These are just stores, where the storing is not propagatable, but there may be later
922+
// mutations of the same local via `Store`
923+
| MutatingUse(MutatingUseContext::Call)
924+
| MutatingUse(MutatingUseContext::AsmOutput)
925+
| MutatingUse(MutatingUseContext::Deinit)
926+
// Actual store that can possibly even propagate a value
927+
| MutatingUse(MutatingUseContext::Store)
928+
| MutatingUse(MutatingUseContext::SetDiscriminant) => {
929+
if !self.found_assignment.insert(local) {
930+
match &mut self.can_const_prop[local] {
931+
// If the local can only get propagated in its own block, then we don't have
932+
// to worry about multiple assignments, as we'll nuke the const state at the
933+
// end of the block anyway, and inside the block we overwrite previous
934+
// states as applicable.
935+
ConstPropMode::OnlyInsideOwnBlock => {}
936+
ConstPropMode::NoPropagation => {}
937+
other @ ConstPropMode::FullConstProp => {
938+
trace!(
939+
"local {:?} can't be propagated because of multiple assignments. Previous state: {:?}",
940+
local, other,
941+
);
942+
*other = ConstPropMode::OnlyInsideOwnBlock;
943+
}
944+
}
945+
}
946+
}
947+
// Reading constants is allowed an arbitrary number of times
948+
NonMutatingUse(NonMutatingUseContext::Copy)
949+
| NonMutatingUse(NonMutatingUseContext::Move)
950+
| NonMutatingUse(NonMutatingUseContext::Inspect)
951+
| NonMutatingUse(NonMutatingUseContext::PlaceMention)
952+
| NonUse(_) => {}
953+
954+
// These could be propagated with a smarter analysis or just some careful thinking about
955+
// whether they'd be fine right now.
956+
MutatingUse(MutatingUseContext::Yield)
957+
| MutatingUse(MutatingUseContext::Drop)
958+
| MutatingUse(MutatingUseContext::Retag)
959+
// These can't ever be propagated under any scheme, as we can't reason about indirect
960+
// mutation.
961+
| NonMutatingUse(NonMutatingUseContext::SharedBorrow)
962+
| NonMutatingUse(NonMutatingUseContext::FakeBorrow)
963+
| NonMutatingUse(NonMutatingUseContext::AddressOf)
964+
| MutatingUse(MutatingUseContext::Borrow)
965+
| MutatingUse(MutatingUseContext::AddressOf) => {
966+
trace!("local {:?} can't be propagated because it's used: {:?}", local, context);
967+
self.can_const_prop[local] = ConstPropMode::NoPropagation;
968+
}
969+
MutatingUse(MutatingUseContext::Projection)
970+
| NonMutatingUse(NonMutatingUseContext::Projection) => bug!("visit_place should not pass {context:?} for {local:?}"),
971+
}
972+
}
973+
}

0 commit comments

Comments
 (0)