Skip to content

Commit fe9c64d

Browse files
committed
Auto merge of #97388 - Dylan-DPC:rollup-tfuc4tf, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #95953 (Modify MIR building to drop repeat expressions with length zero) - #96913 (RFC3239: Implement `cfg(target)` - Part 2) - #97233 ([RFC 2011] Library code) - #97370 (Minor improvement on else-no-if diagnostic) - #97384 (Fix metadata stats.) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4a99c5f + 3c11bf3 commit fe9c64d

26 files changed

+678
-113
lines changed

compiler/rustc_attr/src/builtin.rs

+83-58
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,15 @@ pub fn find_crate_name(sess: &Session, attrs: &[Attribute]) -> Option<Symbol> {
454454
sess.first_attr_value_str_by_name(attrs, sym::crate_name)
455455
}
456456

457+
#[derive(Clone, Debug)]
458+
pub struct Condition {
459+
pub name: Symbol,
460+
pub name_span: Span,
461+
pub value: Option<Symbol>,
462+
pub value_span: Option<Span>,
463+
pub span: Span,
464+
}
465+
457466
/// Tests if a cfg-pattern matches the cfg set
458467
pub fn cfg_matches(
459468
cfg: &ast::MetaItem,
@@ -462,70 +471,42 @@ pub fn cfg_matches(
462471
features: Option<&Features>,
463472
) -> bool {
464473
eval_condition(cfg, sess, features, &mut |cfg| {
465-
try_gate_cfg(cfg, sess, features);
466-
let error = |span, msg| {
467-
sess.span_diagnostic.span_err(span, msg);
468-
true
469-
};
470-
if cfg.path.segments.len() != 1 {
471-
return error(cfg.path.span, "`cfg` predicate key must be an identifier");
472-
}
473-
match &cfg.kind {
474-
MetaItemKind::List(..) => {
475-
error(cfg.span, "unexpected parentheses after `cfg` predicate key")
476-
}
477-
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
478-
handle_errors(
479-
sess,
480-
lit.span,
481-
AttrError::UnsupportedLiteral(
482-
"literal in `cfg` predicate value must be a string",
483-
lit.kind.is_bytestr(),
484-
),
474+
try_gate_cfg(cfg.name, cfg.span, sess, features);
475+
if let Some(names_valid) = &sess.check_config.names_valid {
476+
if !names_valid.contains(&cfg.name) {
477+
sess.buffer_lint_with_diagnostic(
478+
UNEXPECTED_CFGS,
479+
cfg.span,
480+
lint_node_id,
481+
"unexpected `cfg` condition name",
482+
BuiltinLintDiagnostics::UnexpectedCfg((cfg.name, cfg.name_span), None),
485483
);
486-
true
487484
}
488-
MetaItemKind::NameValue(..) | MetaItemKind::Word => {
489-
let ident = cfg.ident().expect("multi-segment cfg predicate");
490-
let name = ident.name;
491-
let value = cfg.value_str();
492-
if let Some(names_valid) = &sess.check_config.names_valid {
493-
if !names_valid.contains(&name) {
494-
sess.buffer_lint_with_diagnostic(
495-
UNEXPECTED_CFGS,
496-
cfg.span,
497-
lint_node_id,
498-
"unexpected `cfg` condition name",
499-
BuiltinLintDiagnostics::UnexpectedCfg((name, ident.span), None),
500-
);
501-
}
502-
}
503-
if let Some(value) = value {
504-
if let Some(values) = &sess.check_config.values_valid.get(&name) {
505-
if !values.contains(&value) {
506-
sess.buffer_lint_with_diagnostic(
507-
UNEXPECTED_CFGS,
508-
cfg.span,
509-
lint_node_id,
510-
"unexpected `cfg` condition value",
511-
BuiltinLintDiagnostics::UnexpectedCfg(
512-
(name, ident.span),
513-
Some((value, cfg.name_value_literal_span().unwrap())),
514-
),
515-
);
516-
}
517-
}
485+
}
486+
if let Some(value) = cfg.value {
487+
if let Some(values) = &sess.check_config.values_valid.get(&cfg.name) {
488+
if !values.contains(&value) {
489+
sess.buffer_lint_with_diagnostic(
490+
UNEXPECTED_CFGS,
491+
cfg.span,
492+
lint_node_id,
493+
"unexpected `cfg` condition value",
494+
BuiltinLintDiagnostics::UnexpectedCfg(
495+
(cfg.name, cfg.name_span),
496+
cfg.value_span.map(|vs| (value, vs)),
497+
),
498+
);
518499
}
519-
sess.config.contains(&(name, value))
520500
}
521501
}
502+
sess.config.contains(&(cfg.name, cfg.value))
522503
})
523504
}
524505

525-
fn try_gate_cfg(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) {
526-
let gate = find_gated_cfg(|sym| cfg.has_name(sym));
506+
fn try_gate_cfg(name: Symbol, span: Span, sess: &ParseSess, features: Option<&Features>) {
507+
let gate = find_gated_cfg(|sym| sym == name);
527508
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
528-
gate_cfg(&gated_cfg, cfg.span, sess, feats);
509+
gate_cfg(&gated_cfg, span, sess, feats);
529510
}
530511
}
531512

@@ -563,11 +544,11 @@ pub fn eval_condition(
563544
cfg: &ast::MetaItem,
564545
sess: &ParseSess,
565546
features: Option<&Features>,
566-
eval: &mut impl FnMut(&ast::MetaItem) -> bool,
547+
eval: &mut impl FnMut(Condition) -> bool,
567548
) -> bool {
568549
match cfg.kind {
569550
ast::MetaItemKind::List(ref mis) if cfg.name_or_empty() == sym::version => {
570-
try_gate_cfg(cfg, sess, features);
551+
try_gate_cfg(sym::version, cfg.span, sess, features);
571552
let (min_version, span) = match &mis[..] {
572553
[NestedMetaItem::Literal(Lit { kind: LitKind::Str(sym, ..), span, .. })] => {
573554
(sym, span)
@@ -649,6 +630,25 @@ pub fn eval_condition(
649630

650631
!eval_condition(mis[0].meta_item().unwrap(), sess, features, eval)
651632
}
633+
sym::target => {
634+
if let Some(features) = features && !features.cfg_target_compact {
635+
feature_err(
636+
sess,
637+
sym::cfg_target_compact,
638+
cfg.span,
639+
&"compact `cfg(target(..))` is experimental and subject to change"
640+
).emit();
641+
}
642+
643+
mis.iter().fold(true, |res, mi| {
644+
let mut mi = mi.meta_item().unwrap().clone();
645+
if let [seg, ..] = &mut mi.path.segments[..] {
646+
seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name));
647+
}
648+
649+
res & eval_condition(&mi, sess, features, eval)
650+
})
651+
}
652652
_ => {
653653
struct_span_err!(
654654
sess.span_diagnostic,
@@ -662,7 +662,32 @@ pub fn eval_condition(
662662
}
663663
}
664664
}
665-
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => eval(cfg),
665+
ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => {
666+
sess.span_diagnostic
667+
.span_err(cfg.path.span, "`cfg` predicate key must be an identifier");
668+
true
669+
}
670+
MetaItemKind::NameValue(ref lit) if !lit.kind.is_str() => {
671+
handle_errors(
672+
sess,
673+
lit.span,
674+
AttrError::UnsupportedLiteral(
675+
"literal in `cfg` predicate value must be a string",
676+
lit.kind.is_bytestr(),
677+
),
678+
);
679+
true
680+
}
681+
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
682+
let ident = cfg.ident().expect("multi-segment cfg predicate");
683+
eval(Condition {
684+
name: ident.name,
685+
name_span: ident.span,
686+
value: cfg.value_str(),
687+
value_span: cfg.name_value_literal_span(),
688+
span: cfg.span,
689+
})
690+
}
666691
}
667692
}
668693

compiler/rustc_attr/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! The goal is to move the definition of `MetaItem` and things that don't need to be in `syntax`
55
//! to this crate.
66
7+
#![feature(let_chains)]
78
#![feature(let_else)]
89

910
#[macro_use]

compiler/rustc_feature/src/active.rs

+2
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ declare_features! (
319319
(active, cfg_sanitize, "1.41.0", Some(39699), None),
320320
/// Allows `cfg(target_abi = "...")`.
321321
(active, cfg_target_abi, "1.55.0", Some(80970), None),
322+
/// Allows `cfg(target(abi = "..."))`.
323+
(active, cfg_target_compact, "1.63.0", Some(96901), None),
322324
/// Allows `cfg(target_has_atomic_load_store = "...")`.
323325
(active, cfg_target_has_atomic, "1.60.0", Some(94039), None),
324326
/// Allows `cfg(target_has_atomic_equal_alignment = "...")`.

compiler/rustc_metadata/src/rmeta/encoder.rs

+69-23
Original file line numberDiff line numberDiff line change
@@ -536,9 +536,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
536536

537537
fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
538538
let tcx = self.tcx;
539-
let mut i = self.position();
539+
let mut i = 0;
540+
let preamble_bytes = self.position() - i;
540541

541542
// Encode the crate deps
543+
i = self.position();
542544
let crate_deps = self.encode_crate_deps();
543545
let dylib_dependency_formats = self.encode_dylib_dependency_formats();
544546
let dep_bytes = self.position() - i;
@@ -564,7 +566,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
564566
let native_libraries = self.encode_native_libraries();
565567
let native_lib_bytes = self.position() - i;
566568

569+
i = self.position();
567570
let foreign_modules = self.encode_foreign_modules();
571+
let foreign_modules_bytes = self.position() - i;
568572

569573
// Encode DefPathTable
570574
i = self.position();
@@ -584,6 +588,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
584588
i = self.position();
585589
let incoherent_impls = self.encode_incoherent_impls();
586590
let incoherent_impls_bytes = self.position() - i;
591+
587592
// Encode MIR.
588593
i = self.position();
589594
self.encode_mir();
@@ -596,6 +601,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
596601
let item_bytes = self.position() - i;
597602

598603
// Encode the allocation index
604+
i = self.position();
599605
let interpret_alloc_index = {
600606
let mut interpret_alloc_index = Vec::new();
601607
let mut n = 0;
@@ -618,6 +624,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
618624
}
619625
self.lazy_array(interpret_alloc_index)
620626
};
627+
let interpret_alloc_index_bytes = self.position() - i;
621628

622629
// Encode the proc macro data. This affects 'tables',
623630
// so we need to do this before we encode the tables
@@ -662,9 +669,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
662669
let source_map = self.encode_source_map();
663670
let source_map_bytes = self.position() - i;
664671

672+
i = self.position();
665673
let attrs = tcx.hir().krate_attrs();
666674
let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
667-
668675
let root = self.lazy(CrateRoot {
669676
name: tcx.crate_name(LOCAL_CRATE),
670677
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
@@ -707,9 +714,34 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
707714
expn_hashes,
708715
def_path_hash_map,
709716
});
717+
let final_bytes = self.position() - i;
710718

711719
let total_bytes = self.position();
712720

721+
let computed_total_bytes = preamble_bytes
722+
+ dep_bytes
723+
+ lib_feature_bytes
724+
+ lang_item_bytes
725+
+ diagnostic_item_bytes
726+
+ native_lib_bytes
727+
+ foreign_modules_bytes
728+
+ def_path_table_bytes
729+
+ traits_bytes
730+
+ impls_bytes
731+
+ incoherent_impls_bytes
732+
+ mir_bytes
733+
+ item_bytes
734+
+ interpret_alloc_index_bytes
735+
+ proc_macro_data_bytes
736+
+ tables_bytes
737+
+ debugger_visualizers_bytes
738+
+ exported_symbols_bytes
739+
+ hygiene_bytes
740+
+ def_path_hash_map_bytes
741+
+ source_map_bytes
742+
+ final_bytes;
743+
assert_eq!(total_bytes, computed_total_bytes);
744+
713745
if tcx.sess.meta_stats() {
714746
let mut zero_bytes = 0;
715747
for e in self.opaque.data.iter() {
@@ -718,27 +750,41 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
718750
}
719751
}
720752

721-
eprintln!("metadata stats:");
722-
eprintln!(" dep bytes: {}", dep_bytes);
723-
eprintln!(" lib feature bytes: {}", lib_feature_bytes);
724-
eprintln!(" lang item bytes: {}", lang_item_bytes);
725-
eprintln!(" diagnostic item bytes: {}", diagnostic_item_bytes);
726-
eprintln!(" native bytes: {}", native_lib_bytes);
727-
eprintln!(" debugger visualizers bytes: {}", debugger_visualizers_bytes);
728-
eprintln!(" source_map bytes: {}", source_map_bytes);
729-
eprintln!(" traits bytes: {}", traits_bytes);
730-
eprintln!(" impls bytes: {}", impls_bytes);
731-
eprintln!(" incoherent_impls bytes: {}", incoherent_impls_bytes);
732-
eprintln!(" exp. symbols bytes: {}", exported_symbols_bytes);
733-
eprintln!(" def-path table bytes: {}", def_path_table_bytes);
734-
eprintln!(" def-path hashes bytes: {}", def_path_hash_map_bytes);
735-
eprintln!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
736-
eprintln!(" mir bytes: {}", mir_bytes);
737-
eprintln!(" item bytes: {}", item_bytes);
738-
eprintln!(" table bytes: {}", tables_bytes);
739-
eprintln!(" hygiene bytes: {}", hygiene_bytes);
740-
eprintln!(" zero bytes: {}", zero_bytes);
741-
eprintln!(" total bytes: {}", total_bytes);
753+
let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
754+
let p = |label, bytes| {
755+
eprintln!("{:>21}: {:>8} bytes ({:4.1}%)", label, bytes, perc(bytes));
756+
};
757+
758+
eprintln!("");
759+
eprintln!(
760+
"{} metadata bytes, of which {} bytes ({:.1}%) are zero",
761+
total_bytes,
762+
zero_bytes,
763+
perc(zero_bytes)
764+
);
765+
p("preamble", preamble_bytes);
766+
p("dep", dep_bytes);
767+
p("lib feature", lib_feature_bytes);
768+
p("lang item", lang_item_bytes);
769+
p("diagnostic item", diagnostic_item_bytes);
770+
p("native lib", native_lib_bytes);
771+
p("foreign modules", foreign_modules_bytes);
772+
p("def-path table", def_path_table_bytes);
773+
p("traits", traits_bytes);
774+
p("impls", impls_bytes);
775+
p("incoherent_impls", incoherent_impls_bytes);
776+
p("mir", mir_bytes);
777+
p("item", item_bytes);
778+
p("interpret_alloc_index", interpret_alloc_index_bytes);
779+
p("proc-macro-data", proc_macro_data_bytes);
780+
p("tables", tables_bytes);
781+
p("debugger visualizers", debugger_visualizers_bytes);
782+
p("exported symbols", exported_symbols_bytes);
783+
p("hygiene", hygiene_bytes);
784+
p("def-path hashes", def_path_hash_map_bytes);
785+
p("source_map", source_map_bytes);
786+
p("final", final_bytes);
787+
eprintln!("");
742788
}
743789

744790
root

0 commit comments

Comments
 (0)