diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index c51a7744a30a3..26ea95f0f0d50 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -207,13 +207,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
                 let cond_bitmap = coverage_context
                                     .try_get_mcdc_condition_bitmap(&instance, decision_depth)
                                     .expect("mcdc cond bitmap should have been allocated for merging into the global bitmap");
-                let bitmap_bytes = bx.tcx().coverage_ids_info(instance.def).mcdc_bitmap_bytes;
+                let bitmap_bytes = function_coverage_info.mcdc_bitmap_bytes;
                 assert!(bitmap_idx < bitmap_bytes, "bitmap index of the decision out of range");
-                assert!(
-                    bitmap_bytes <= function_coverage_info.mcdc_bitmap_bytes,
-                    "bitmap length disagreement: query says {bitmap_bytes} but function info only has {}",
-                    function_coverage_info.mcdc_bitmap_bytes
-                );
 
                 let fn_name = bx.get_pgo_func_name_var(instance);
                 let hash = bx.const_u64(function_coverage_info.function_source_hash);
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 1610135a0efad..18bb71bd99f73 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -896,7 +896,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         style: SuggestionStyle,
     ) -> &mut Self {
         suggestion.sort_unstable();
-        suggestion.dedup();
+        suggestion.dedup_by(|(s1, m1), (s2, m2)| s1.source_equal(*s2) && m1 == m2);
 
         let parts = suggestion
             .into_iter()
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index 8458b53933537..5ad3ff71a6d4a 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -347,5 +347,13 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
                 "reduce the glob import's visibility or increase visibility of imported items",
             );
         }
+        BuiltinLintDiag::MaybeTypo { span, name } => {
+            diag.span_suggestion_verbose(
+                span,
+                "an attribute with a similar name exists",
+                name,
+                Applicability::MachineApplicable,
+            );
+        }
     }
 }
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index ed165188787a5..e06e3e9b805f7 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -663,6 +663,10 @@ pub enum BuiltinLintDiag {
         span: Span,
         max_vis: String,
     },
+    MaybeTypo {
+        span: Span,
+        name: Symbol,
+    },
 }
 
 /// Lints that are buffered up early on in the `Session` before the
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 477303e2434f4..7f9a5a366d74e 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -129,17 +129,11 @@ pub enum CoverageKind {
     /// Marks the point in MIR control flow represented by a evaluated condition.
     ///
     /// This is eventually lowered to `llvm.instrprof.mcdc.condbitmap.update` in LLVM IR.
-    ///
-    /// If this statement does not survive MIR optimizations, the condition would never be
-    /// taken as evaluated.
     CondBitmapUpdate { id: ConditionId, value: bool, decision_depth: u16 },
 
     /// Marks the point in MIR control flow represented by a evaluated decision.
     ///
     /// This is eventually lowered to `llvm.instrprof.mcdc.tvbitmap.update` in LLVM IR.
-    ///
-    /// If this statement does not survive MIR optimizations, the decision would never be
-    /// taken as evaluated.
     TestVectorBitmapUpdate { bitmap_idx: u32, decision_depth: u16 },
 }
 
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 9a7af6135e46f..9d70231be3b0c 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -362,8 +362,4 @@ pub struct CoverageIdsInfo {
     /// InstrumentCoverage MIR pass, if the highest-numbered counter increments
     /// were removed by MIR optimizations.
     pub max_counter_id: mir::coverage::CounterId,
-
-    /// Coverage codegen for mcdc needs to know the size of the global bitmap so that it can
-    /// set the `bytemap-bytes` argument of the `llvm.instrprof.mcdc.tvbitmap.update` intrinsic.
-    pub mcdc_bitmap_bytes: u32,
 }
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 04ce3de887441..7f3d6a713d914 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1130,7 +1130,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for WeakAliasTypeExpander<'tcx> {
     }
 
     fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
-        if !ct.ty().has_type_flags(ty::TypeFlags::HAS_TY_WEAK) {
+        if !ct.has_type_flags(ty::TypeFlags::HAS_TY_WEAK) {
             return ct;
         }
         ct.super_fold_with(self)
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index f77ee63d02c20..65715253647a8 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -61,17 +61,7 @@ fn coverage_ids_info<'tcx>(
         .max()
         .unwrap_or(CounterId::ZERO);
 
-    let mcdc_bitmap_bytes = mir_body
-        .coverage_branch_info
-        .as_deref()
-        .map(|info| {
-            info.mcdc_decision_spans
-                .iter()
-                .fold(0, |acc, decision| acc + (1_u32 << decision.conditions_num).div_ceil(8))
-        })
-        .unwrap_or_default();
-
-    CoverageIdsInfo { max_counter_id, mcdc_bitmap_bytes }
+    CoverageIdsInfo { max_counter_id }
 }
 
 fn all_coverage_in_mir_body<'a, 'tcx>(
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 35bf3f761df39..e3cfe6a6e05a5 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -29,6 +29,7 @@ use rustc_session::lint::builtin::{LEGACY_DERIVE_HELPERS, SOFT_UNSTABLE};
 use rustc_session::lint::builtin::{UNUSED_MACROS, UNUSED_MACRO_RULES};
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::feature_err;
+use rustc_span::edit_distance::edit_distance;
 use rustc_span::edition::Edition;
 use rustc_span::hygiene::{self, ExpnData, ExpnKind, LocalExpnId};
 use rustc_span::hygiene::{AstPass, MacroKind};
@@ -568,15 +569,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         }
 
         if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
-            && path.segments.len() >= 2
-            && path.segments[0].ident.name == sym::diagnostic
-            && path.segments[1].ident.name != sym::on_unimplemented
+            && let [namespace, attribute, ..] = &*path.segments
+            && namespace.ident.name == sym::diagnostic
+            && attribute.ident.name != sym::on_unimplemented
         {
-            self.tcx.sess.psess.buffer_lint(
+            let distance =
+                edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5);
+
+            let help = if distance.is_some() {
+                BuiltinLintDiag::MaybeTypo { span: attribute.span(), name: sym::on_unimplemented }
+            } else {
+                BuiltinLintDiag::Normal
+            };
+            self.tcx.sess.psess.buffer_lint_with_diagnostic(
                 UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                path.segments[1].span(),
+                attribute.span(),
                 node_id,
                 "unknown diagnostic attribute",
+                help,
             );
         }
 
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.rs b/tests/ui/diagnostic_namespace/suggest_typos.rs
new file mode 100644
index 0000000000000..b25f097a8adc1
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/suggest_typos.rs
@@ -0,0 +1,18 @@
+#![deny(unknown_or_malformed_diagnostic_attributes)]
+
+#[diagnostic::onunimplemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait X{}
+
+#[diagnostic::un_onimplemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait Y{}
+
+#[diagnostic::on_implemented]
+//~^ERROR unknown diagnostic attribute
+//~^^HELP an attribute with a similar name exists
+trait Z{}
+
+fn main(){}
diff --git a/tests/ui/diagnostic_namespace/suggest_typos.stderr b/tests/ui/diagnostic_namespace/suggest_typos.stderr
new file mode 100644
index 0000000000000..307311258f274
--- /dev/null
+++ b/tests/ui/diagnostic_namespace/suggest_typos.stderr
@@ -0,0 +1,40 @@
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:3:15
+   |
+LL | #[diagnostic::onunimplemented]
+   |               ^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/suggest_typos.rs:1:9
+   |
+LL | #![deny(unknown_or_malformed_diagnostic_attributes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:8:15
+   |
+LL | #[diagnostic::un_onimplemented]
+   |               ^^^^^^^^^^^^^^^^
+   |
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: unknown diagnostic attribute
+  --> $DIR/suggest_typos.rs:13:15
+   |
+LL | #[diagnostic::on_implemented]
+   |               ^^^^^^^^^^^^^^
+   |
+help: an attribute with a similar name exists
+   |
+LL | #[diagnostic::on_unimplemented]
+   |               ~~~~~~~~~~~~~~~~
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/macros/macro-span-issue-116502.rs b/tests/ui/macros/macro-span-issue-116502.rs
new file mode 100644
index 0000000000000..4c254289ee684
--- /dev/null
+++ b/tests/ui/macros/macro-span-issue-116502.rs
@@ -0,0 +1,16 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+
+fn bug() {
+    macro_rules! m {
+        () => {
+            _ //~ ERROR the placeholder `_` is not allowed within types on item signatures for structs
+        };
+    }
+    struct S<T = m!()>(m!(), T)
+    where
+        T: Trait<m!()>;
+}
+trait Trait<T> {}
+
+fn main() {}
diff --git a/tests/ui/macros/macro-span-issue-116502.stderr b/tests/ui/macros/macro-span-issue-116502.stderr
new file mode 100644
index 0000000000000..da02855660a4f
--- /dev/null
+++ b/tests/ui/macros/macro-span-issue-116502.stderr
@@ -0,0 +1,30 @@
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for structs
+  --> $DIR/macro-span-issue-116502.rs:7:13
+   |
+LL |             _
+   |             ^
+   |             |
+   |             not allowed in type signatures
+   |             not allowed in type signatures
+   |             not allowed in type signatures
+...
+LL |     struct S<T = m!()>(m!(), T)
+   |                  ----  ---- in this macro invocation
+   |                  |
+   |                  in this macro invocation
+LL |     where
+LL |         T: Trait<m!()>;
+   |                  ---- in this macro invocation
+   |
+   = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use type parameters instead
+   |
+LL ~             U
+LL |         };
+LL |     }
+LL ~     struct S<U>(m!(), T)
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0121`.