about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-01 10:44:25 +0000
committerbors <bors@rust-lang.org>2022-10-01 10:44:25 +0000
commit744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1 (patch)
tree1721987352b5f0a8548fc46984821d974b661934 /compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
parent277bb6653b55475b5fbce6309e9852fa2100dabe (diff)
parentb5b3ffe3fc9cfb524a6432ec60a0fc95c514d2e1 (diff)
downloadrust-744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1.tar.gz
rust-744e397d8855f7da87d70aa8d0bd9e0f5f0b51a1.zip
Auto merge of #101986 - WaffleLapkin:move_lint_note_to_the_bottom, r=estebank
Move lint level source explanation to the bottom

So, uhhhhh

r? `@estebank`

## User-facing change

"note: `#[warn(...)]` on by default" and such are moved to the bottom of the diagnostic:
```diff
-   = note: `#[warn(unsupported_calling_conventions)]` on by default
   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
   = note: for more information, see issue #87678 <https://github.com/rust-lang/rust/issues/87678>
+   = note: `#[warn(unsupported_calling_conventions)]` on by default
```

Why warning is enabled is the least important thing, so it shouldn't be the first note the user reads, IMO.

## Developer-facing change

`struct_span_lint` and similar methods have a different signature.

Before: `..., impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>)`
After: `..., impl Into<DiagnosticMessage>, impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>) -> &'b mut DiagnosticBuilder<'a, ()>`

The reason for this is that `struct_span_lint` needs to edit the diagnostic _after_ `decorate` closure is called. This also makes lint code a little bit nicer in my opinion.

Another option is to use `impl for<'a> FnOnce(LintDiagnosticBuilder<'a, ()>) -> DiagnosticBuilder<'a, ()>` altough I don't _really_ see reasons to do `let lint = lint.build(message)` everywhere.

## Subtle problem

By moving the message outside of the closure (that may not be called if the lint is disabled) `format!(...)` is executed earlier, possibly formatting `Ty` which may call a query that trims paths that crashes the compiler if there were no warnings...

I don't think it's that big of a deal, considering that we move from `format!(...)` to `fluent` (which is lazy by-default) anyway, however this required adding a workaround which is unfortunate.

## P.S.

I'm sorry, I do not how to make this PR smaller/easier to review. Changes to the lint API affect SO MUCH 😢
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/const_evaluatable.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs48
1 files changed, 26 insertions, 22 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index dc585fca34f..3f98db6b2a9 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -235,14 +235,18 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
                   .emit()
             }
 
-            Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
-                NotConstEvaluatable::MentionsInfer
+            Err(ErrorHandled::TooGeneric) => {
+                let err = if uv.has_infer_types_or_consts() {
+                    NotConstEvaluatable::MentionsInfer
                 } else if uv.has_param_types_or_consts() {
-                NotConstEvaluatable::MentionsParam
-            } else {
-                let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?"));
-                NotConstEvaluatable::Error(guar)
-            }),
+                    NotConstEvaluatable::MentionsParam
+                } else {
+                    let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?"));
+                    NotConstEvaluatable::Error(guar)
+                };
+
+                Err(err)
+            },
             Err(ErrorHandled::Linted) => {
                 let reported =
                     infcx.tcx.sess.delay_span_bug(span, "constant in type had error reported as lint");
@@ -250,23 +254,23 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
             }
             Err(ErrorHandled::Reported(e)) => Err(NotConstEvaluatable::Error(e)),
             Ok(_) => {
-              if uv.substs.has_param_types_or_consts() {
-                  assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
-                  let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
+                if uv.substs.has_param_types_or_consts() {
+                    assert!(matches!(infcx.tcx.def_kind(uv.def.did), DefKind::AnonConst));
+                    let mir_body = infcx.tcx.mir_for_ctfe_opt_const_arg(uv.def);
 
-                  if mir_body.is_polymorphic {
-                      let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
-                      tcx.struct_span_lint_hir(
-                          lint::builtin::CONST_EVALUATABLE_UNCHECKED,
-                          tcx.hir().local_def_id_to_hir_id(local_def_id),
-                          span,
-                          |err| {
-                              err.build("cannot use constants which depend on generic parameters in types").emit();
-                        })
-                  }
-              }
+                    if mir_body.is_polymorphic {
+                        let Some(local_def_id) = uv.def.did.as_local() else { return Ok(()) };
+                        tcx.struct_span_lint_hir(
+                            lint::builtin::CONST_EVALUATABLE_UNCHECKED,
+                            tcx.hir().local_def_id_to_hir_id(local_def_id),
+                            span,
+                            "cannot use constants which depend on generic parameters in types",
+                            |err| err
+                        )
+                    }
+                }
 
-              Ok(())
+                Ok(())
             },
         }
     }