about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-06-20 07:52:43 +0200
committerGitHub <noreply@github.com>2024-06-20 07:52:43 +0200
commite7be3562b7a3cac6a8d945f02fad44bfc793ee74 (patch)
tree4ea07f9e0e86b073e947f811f3d6e041c8ef9767 /compiler/rustc_trait_selection/src
parent3d5d7a24f76006b391d8a53d903ae64c1b4a52d2 (diff)
parente4c9a8cf9b2e2a17c589dadcaffae0b9e6b62cbc (diff)
Rollup merge of #126620 - oli-obk:taint_errors, r=fee1-dead
Actually taint InferCtxt when a fulfillment error is emitted

And avoid checking the global error counter

fixes #122044
fixes #123255
fixes #123276
fixes #125799
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs188
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs23
2 files changed, 111 insertions, 100 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 038f11c60b8..33074c20f57 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2776,97 +2776,115 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 let mut this = "this bound";
                 let mut note = None;
                 let mut help = None;
-                if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder()
-                    && let ty::ClauseKind::Trait(trait_pred) = clause
-                {
-                    let def_id = trait_pred.def_id();
-                    let visible_item = if let Some(local) = def_id.as_local() {
-                        // Check for local traits being reachable.
-                        let vis = &tcx.resolutions(()).effective_visibilities;
-                        // Account for non-`pub` traits in the root of the local crate.
-                        let is_locally_reachable = tcx.parent(def_id).is_crate_root();
-                        vis.is_reachable(local) || is_locally_reachable
-                    } else {
-                        // Check for foreign traits being reachable.
-                        tcx.visible_parent_map(()).get(&def_id).is_some()
-                    };
-                    if tcx.is_lang_item(def_id, LangItem::Sized) {
-                        // Check if this is an implicit bound, even in foreign crates.
-                        if tcx
-                            .generics_of(item_def_id)
-                            .own_params
-                            .iter()
-                            .any(|param| tcx.def_span(param.def_id) == span)
-                        {
-                            a = "an implicit `Sized`";
-                            this = "the implicit `Sized` requirement on this type parameter";
-                        }
-                        if let Some(hir::Node::TraitItem(hir::TraitItem {
-                            generics,
-                            kind: hir::TraitItemKind::Type(bounds, None),
-                            ..
-                        })) = tcx.hir().get_if_local(item_def_id)
-                        // Do not suggest relaxing if there is an explicit `Sized` obligation.
-                        && !bounds.iter()
-                            .filter_map(|bound| bound.trait_ref())
-                            .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait())
-                        {
-                            let (span, separator) = if let [.., last] = bounds {
-                                (last.span().shrink_to_hi(), " +")
+                if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() {
+                    match clause {
+                        ty::ClauseKind::Trait(trait_pred) => {
+                            let def_id = trait_pred.def_id();
+                            let visible_item = if let Some(local) = def_id.as_local() {
+                                // Check for local traits being reachable.
+                                let vis = &tcx.resolutions(()).effective_visibilities;
+                                // Account for non-`pub` traits in the root of the local crate.
+                                let is_locally_reachable = tcx.parent(def_id).is_crate_root();
+                                vis.is_reachable(local) || is_locally_reachable
                             } else {
-                                (generics.span.shrink_to_hi(), ":")
+                                // Check for foreign traits being reachable.
+                                tcx.visible_parent_map(()).get(&def_id).is_some()
                             };
-                            err.span_suggestion_verbose(
-                                span,
-                                "consider relaxing the implicit `Sized` restriction",
-                                format!("{separator} ?Sized"),
-                                Applicability::MachineApplicable,
-                            );
+                            if tcx.is_lang_item(def_id, LangItem::Sized) {
+                                // Check if this is an implicit bound, even in foreign crates.
+                                if tcx
+                                    .generics_of(item_def_id)
+                                    .own_params
+                                    .iter()
+                                    .any(|param| tcx.def_span(param.def_id) == span)
+                                {
+                                    a = "an implicit `Sized`";
+                                    this =
+                                        "the implicit `Sized` requirement on this type parameter";
+                                }
+                                if let Some(hir::Node::TraitItem(hir::TraitItem {
+                                    generics,
+                                    kind: hir::TraitItemKind::Type(bounds, None),
+                                    ..
+                                })) = tcx.hir().get_if_local(item_def_id)
+                                    // Do not suggest relaxing if there is an explicit `Sized` obligation.
+                                    && !bounds.iter()
+                                        .filter_map(|bound| bound.trait_ref())
+                                        .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait())
+                                {
+                                    let (span, separator) = if let [.., last] = bounds {
+                                        (last.span().shrink_to_hi(), " +")
+                                    } else {
+                                        (generics.span.shrink_to_hi(), ":")
+                                    };
+                                    err.span_suggestion_verbose(
+                                        span,
+                                        "consider relaxing the implicit `Sized` restriction",
+                                        format!("{separator} ?Sized"),
+                                        Applicability::MachineApplicable,
+                                    );
+                                }
+                            }
+                            if let DefKind::Trait = tcx.def_kind(item_def_id)
+                                && !visible_item
+                            {
+                                note = Some(format!(
+                                    "`{short_item_name}` is a \"sealed trait\", because to implement it \
+                                    you also need to implement `{}`, which is not accessible; this is \
+                                    usually done to force you to use one of the provided types that \
+                                    already implement it",
+                                    with_no_trimmed_paths!(tcx.def_path_str(def_id)),
+                                ));
+                                let impls_of = tcx.trait_impls_of(def_id);
+                                let impls = impls_of
+                                    .non_blanket_impls()
+                                    .values()
+                                    .flatten()
+                                    .chain(impls_of.blanket_impls().iter())
+                                    .collect::<Vec<_>>();
+                                if !impls.is_empty() {
+                                    let len = impls.len();
+                                    let mut types = impls
+                                        .iter()
+                                        .map(|t| {
+                                            with_no_trimmed_paths!(format!(
+                                                "  {}",
+                                                tcx.type_of(*t).instantiate_identity(),
+                                            ))
+                                        })
+                                        .collect::<Vec<_>>();
+                                    let post = if types.len() > 9 {
+                                        types.truncate(8);
+                                        format!("\nand {} others", len - 8)
+                                    } else {
+                                        String::new()
+                                    };
+                                    help = Some(format!(
+                                        "the following type{} implement{} the trait:\n{}{post}",
+                                        pluralize!(len),
+                                        if len == 1 { "s" } else { "" },
+                                        types.join("\n"),
+                                    ));
+                                }
+                            }
                         }
-                    }
-                    if let DefKind::Trait = tcx.def_kind(item_def_id)
-                        && !visible_item
-                    {
-                        note = Some(format!(
-                            "`{short_item_name}` is a \"sealed trait\", because to implement it \
-                             you also need to implement `{}`, which is not accessible; this is \
-                             usually done to force you to use one of the provided types that \
-                             already implement it",
-                            with_no_trimmed_paths!(tcx.def_path_str(def_id)),
-                        ));
-                        let impls_of = tcx.trait_impls_of(def_id);
-                        let impls = impls_of
-                            .non_blanket_impls()
-                            .values()
-                            .flatten()
-                            .chain(impls_of.blanket_impls().iter())
-                            .collect::<Vec<_>>();
-                        if !impls.is_empty() {
-                            let len = impls.len();
-                            let mut types = impls
-                                .iter()
-                                .map(|t| {
-                                    with_no_trimmed_paths!(format!(
-                                        "  {}",
-                                        tcx.type_of(*t).instantiate_identity(),
-                                    ))
-                                })
-                                .collect::<Vec<_>>();
-                            let post = if types.len() > 9 {
-                                types.truncate(8);
-                                format!("\nand {} others", len - 8)
+                        ty::ClauseKind::ConstArgHasType(..) => {
+                            let descr =
+                                format!("required by a const generic parameter in `{item_name}`");
+                            if span.is_visible(sm) {
+                                let msg = format!(
+                                    "required by this const generic parameter in `{short_item_name}`"
+                                );
+                                multispan.push_span_label(span, msg);
+                                err.span_note(multispan, descr);
                             } else {
-                                String::new()
-                            };
-                            help = Some(format!(
-                                "the following type{} implement{} the trait:\n{}{post}",
-                                pluralize!(len),
-                                if len == 1 { "s" } else { "" },
-                                types.join("\n"),
-                            ));
+                                err.span_note(tcx.def_span(item_def_id), descr);
+                            }
+                            return;
                         }
+                        _ => (),
                     }
-                };
+                }
                 let descr = format!("required by {a} bound in `{item_name}`");
                 if span.is_visible(sm) {
                     let msg = format!("required by {this} in `{short_item_name}`");
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index e38f7951197..b5f2d34852f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -179,6 +179,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             for (error, suppressed) in iter::zip(&errors, &is_suppressed) {
                 if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
                     let guar = self.report_fulfillment_error(error);
+                    self.infcx.set_tainted_by_errors(guar);
                     reported = Some(guar);
                     // We want to ignore desugarings here: spans are equivalent even
                     // if one is the result of a desugaring and the other is not.
@@ -2686,22 +2687,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 }
             }
 
-            // Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as
-            // "type annotations needed: cannot satisfy the constant `_` has type `usize`"
-            // Instead we should emit a normal error suggesting the user to turbofish the
-            // const parameter that is currently being inferred. Unfortunately we cannot
-            // nicely emit such an error so we delay an ICE incase nobody else reports it
-            // for us.
-            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
-                return self.tcx.sess.dcx().span_delayed_bug(
+            ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self
+                .emit_inference_failure_err(
+                    obligation.cause.body_id,
                     span,
-                    format!(
-                        "`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`",
-                        ct, ty
-                    ),
-                );
-            }
-
+                    ct.into(),
+                    ErrorCode::E0284,
+                    true,
+                ),
             ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })
                 if term.is_infer() =>
             {