about summary refs log tree commit diff
path: root/compiler/rustc_metadata/src
diff options
context:
space:
mode:
authorStuart Cook <Zalathar@users.noreply.github.com>2025-03-26 19:40:27 +1100
committerGitHub <noreply@github.com>2025-03-26 19:40:27 +1100
commit7eb27a9cf93f2c21626da278edab1235564d097c (patch)
tree824e6b708f973d626fee755c5457a5f502e8a87b /compiler/rustc_metadata/src
parent6e8abb5ec65ac50f934df6cf0e8f248dc8e8805e (diff)
parent6ccaea19895cc8c0861f3a8707f888a15f8be3a1 (diff)
Rollup merge of #138483 - azhogin:azhogin/target-modifiers-bool-fix, r=fee1-dead
Target modifiers fix for bool flags without value

Fixed support of boolean flags without values: `-Zbool-flag` is now consistent with `-Zbool-flag=true` in another crate.

When flag is explicitly set to default value, target modifier will not be set in crate metainfo (`-Zflag=false` when `false` is a default value for the flag).

Improved error notification when target modifier flag is absent in a crate ("-Zflag unset").
Example:
```
note: `-Zreg-struct-return=true` in this crate is incompatible with unset `-Zreg-struct-return` in dependency `default_reg_struct_return`
```
Diffstat (limited to 'compiler/rustc_metadata/src')
-rw-r--r--compiler/rustc_metadata/src/creader.rs69
-rw-r--r--compiler/rustc_metadata/src/errors.rs36
2 files changed, 85 insertions, 20 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 12503ffd1a6..b7f13e0afdc 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -358,30 +358,58 @@ impl CStore {
     ) {
         let span = krate.spans.inner_span.shrink_to_lo();
         let allowed_flag_mismatches = &tcx.sess.opts.cg.unsafe_allow_abi_mismatch;
-        let name = tcx.crate_name(LOCAL_CRATE);
+        let local_crate = tcx.crate_name(LOCAL_CRATE);
         let tmod_extender = |tmod: &TargetModifier| (tmod.extend(), tmod.clone());
         let report_diff = |prefix: &String,
                            opt_name: &String,
-                           flag_local_value: &String,
-                           flag_extern_value: &String| {
+                           flag_local_value: Option<&String>,
+                           flag_extern_value: Option<&String>| {
             if allowed_flag_mismatches.contains(&opt_name) {
                 return;
             }
-            tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
-                span,
-                extern_crate: data.name(),
-                local_crate: name,
-                flag_name: opt_name.clone(),
-                flag_name_prefixed: format!("-{}{}", prefix, opt_name),
-                flag_local_value: flag_local_value.to_string(),
-                flag_extern_value: flag_extern_value.to_string(),
-            });
+            let extern_crate = data.name();
+            let flag_name = opt_name.clone();
+            let flag_name_prefixed = format!("-{}{}", prefix, opt_name);
+
+            match (flag_local_value, flag_extern_value) {
+                (Some(local_value), Some(extern_value)) => {
+                    tcx.dcx().emit_err(errors::IncompatibleTargetModifiers {
+                        span,
+                        extern_crate,
+                        local_crate,
+                        flag_name,
+                        flag_name_prefixed,
+                        local_value: local_value.to_string(),
+                        extern_value: extern_value.to_string(),
+                    })
+                }
+                (None, Some(extern_value)) => {
+                    tcx.dcx().emit_err(errors::IncompatibleTargetModifiersLMissed {
+                        span,
+                        extern_crate,
+                        local_crate,
+                        flag_name,
+                        flag_name_prefixed,
+                        extern_value: extern_value.to_string(),
+                    })
+                }
+                (Some(local_value), None) => {
+                    tcx.dcx().emit_err(errors::IncompatibleTargetModifiersRMissed {
+                        span,
+                        extern_crate,
+                        local_crate,
+                        flag_name,
+                        flag_name_prefixed,
+                        local_value: local_value.to_string(),
+                    })
+                }
+                (None, None) => panic!("Incorrect target modifiers report_diff(None, None)"),
+            };
         };
         let mut it1 = mods.iter().map(tmod_extender);
         let mut it2 = dep_mods.iter().map(tmod_extender);
         let mut left_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
         let mut right_name_val: Option<(ExtendedTargetModifierInfo, TargetModifier)> = None;
-        let no_val = "*".to_string();
         loop {
             left_name_val = left_name_val.or_else(|| it1.next());
             right_name_val = right_name_val.or_else(|| it2.next());
@@ -389,26 +417,31 @@ impl CStore {
                 (Some(l), Some(r)) => match l.1.opt.cmp(&r.1.opt) {
                     cmp::Ordering::Equal => {
                         if l.0.tech_value != r.0.tech_value {
-                            report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &r.1.value_name);
+                            report_diff(
+                                &l.0.prefix,
+                                &l.0.name,
+                                Some(&l.1.value_name),
+                                Some(&r.1.value_name),
+                            );
                         }
                         left_name_val = None;
                         right_name_val = None;
                     }
                     cmp::Ordering::Greater => {
-                        report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
+                        report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
                         right_name_val = None;
                     }
                     cmp::Ordering::Less => {
-                        report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
+                        report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
                         left_name_val = None;
                     }
                 },
                 (Some(l), None) => {
-                    report_diff(&l.0.prefix, &l.0.name, &l.1.value_name, &no_val);
+                    report_diff(&l.0.prefix, &l.0.name, Some(&l.1.value_name), None);
                     left_name_val = None;
                 }
                 (None, Some(r)) => {
-                    report_diff(&r.0.prefix, &r.0.name, &no_val, &r.1.value_name);
+                    report_diff(&r.0.prefix, &r.0.name, None, Some(&r.1.value_name));
                     right_name_val = None;
                 }
                 (None, None) => break,
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index 2ad6389c0b4..0c54628598c 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -759,8 +759,40 @@ pub struct IncompatibleTargetModifiers {
     pub local_crate: Symbol,
     pub flag_name: String,
     pub flag_name_prefixed: String,
-    pub flag_local_value: String,
-    pub flag_extern_value: String,
+    pub local_value: String,
+    pub extern_value: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(metadata_incompatible_target_modifiers_l_missed)]
+#[help]
+#[note]
+#[help(metadata_incompatible_target_modifiers_help_fix_l_missed)]
+#[help(metadata_incompatible_target_modifiers_help_allow)]
+pub struct IncompatibleTargetModifiersLMissed {
+    #[primary_span]
+    pub span: Span,
+    pub extern_crate: Symbol,
+    pub local_crate: Symbol,
+    pub flag_name: String,
+    pub flag_name_prefixed: String,
+    pub extern_value: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(metadata_incompatible_target_modifiers_r_missed)]
+#[help]
+#[note]
+#[help(metadata_incompatible_target_modifiers_help_fix_r_missed)]
+#[help(metadata_incompatible_target_modifiers_help_allow)]
+pub struct IncompatibleTargetModifiersRMissed {
+    #[primary_span]
+    pub span: Span,
+    pub extern_crate: Symbol,
+    pub local_crate: Symbol,
+    pub flag_name: String,
+    pub flag_name_prefixed: String,
+    pub local_value: String,
 }
 
 #[derive(Diagnostic)]