about summary refs log tree commit diff
path: root/compiler/rustc_trait_selection/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src')
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs5
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs163
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs18
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs38
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs29
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs37
11 files changed, 164 insertions, 149 deletions
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index 1db05ced8d2..022d549a9df 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -1303,7 +1303,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             && let Some(args) = self.node_args_opt(expr.hir_id)
             && args.iter().any(|arg| self.generic_arg_contains_target(arg))
             && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
-            && self.tecx.tcx.trait_of_item(def_id).is_some()
+            && self.tecx.tcx.trait_of_assoc(def_id).is_some()
             && !has_impl_trait(def_id)
             // FIXME(fn_delegation): In delegation item argument spans are equal to last path
             // segment. This leads to ICE's when emitting `multipart_suggestion`.
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
index 772a7f01332..2a3268d3339 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/nice_region_error/trait_impl_difference.rs
@@ -104,10 +104,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             ty::AssocKind::Fn { .. } => {
                 if let Some(hir_id) =
                     assoc_item.def_id.as_local().map(|id| self.tcx().local_def_id_to_hir_id(id))
+                    && let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id)
                 {
-                    if let Some(decl) = self.tcx().hir_fn_decl_by_hir_id(hir_id) {
-                        visitor.visit_fn_decl(decl);
-                    }
+                    visitor.visit_fn_decl(decl);
                 }
             }
             _ => {}
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
index c0daf08ce07..44baa213b28 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/suggest.rs
@@ -91,51 +91,51 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     ) {
         // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with
         // some modifications due to that being in typeck and this being in infer.
-        if let ObligationCauseCode::Pattern { .. } = cause.code() {
-            if let ty::Adt(expected_adt, args) = exp_found.expected.kind() {
-                let compatible_variants: Vec<_> = expected_adt
-                    .variants()
-                    .iter()
-                    .filter(|variant| {
-                        variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
-                    })
-                    .filter_map(|variant| {
-                        let sole_field = &variant.single_field();
-                        let sole_field_ty = sole_field.ty(self.tcx, args);
-                        if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
-                            let variant_path =
-                                with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
-                            // FIXME #56861: DRYer prelude filtering
-                            if let Some(path) = variant_path.strip_prefix("std::prelude::") {
-                                if let Some((_, path)) = path.split_once("::") {
-                                    return Some(path.to_string());
-                                }
-                            }
-                            Some(variant_path)
-                        } else {
-                            None
+        if let ObligationCauseCode::Pattern { .. } = cause.code()
+            && let ty::Adt(expected_adt, args) = exp_found.expected.kind()
+        {
+            let compatible_variants: Vec<_> = expected_adt
+                .variants()
+                .iter()
+                .filter(|variant| {
+                    variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn)
+                })
+                .filter_map(|variant| {
+                    let sole_field = &variant.single_field();
+                    let sole_field_ty = sole_field.ty(self.tcx, args);
+                    if self.same_type_modulo_infer(sole_field_ty, exp_found.found) {
+                        let variant_path =
+                            with_no_trimmed_paths!(self.tcx.def_path_str(variant.def_id));
+                        // FIXME #56861: DRYer prelude filtering
+                        if let Some(path) = variant_path.strip_prefix("std::prelude::")
+                            && let Some((_, path)) = path.split_once("::")
+                        {
+                            return Some(path.to_string());
                         }
-                    })
-                    .collect();
-                match &compatible_variants[..] {
-                    [] => {}
-                    [variant] => {
-                        let sugg = SuggestTuplePatternOne {
-                            variant: variant.to_owned(),
-                            span_low: cause.span.shrink_to_lo(),
-                            span_high: cause.span.shrink_to_hi(),
-                        };
-                        diag.subdiagnostic(sugg);
-                    }
-                    _ => {
-                        // More than one matching variant.
-                        let sugg = SuggestTuplePatternMany {
-                            path: self.tcx.def_path_str(expected_adt.did()),
-                            cause_span: cause.span,
-                            compatible_variants,
-                        };
-                        diag.subdiagnostic(sugg);
+                        Some(variant_path)
+                    } else {
+                        None
                     }
+                })
+                .collect();
+            match &compatible_variants[..] {
+                [] => {}
+                [variant] => {
+                    let sugg = SuggestTuplePatternOne {
+                        variant: variant.to_owned(),
+                        span_low: cause.span.shrink_to_lo(),
+                        span_high: cause.span.shrink_to_hi(),
+                    };
+                    diag.subdiagnostic(sugg);
+                }
+                _ => {
+                    // More than one matching variant.
+                    let sugg = SuggestTuplePatternMany {
+                        path: self.tcx.def_path_str(expected_adt.did()),
+                        cause_span: cause.span,
+                        compatible_variants,
+                    };
+                    diag.subdiagnostic(sugg);
                 }
             }
         }
@@ -288,19 +288,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                 .filter(|field| field.vis.is_accessible_from(field.did, self.tcx))
                 .map(|field| (field.name, field.ty(self.tcx, expected_args)))
                 .find(|(_, ty)| self.same_type_modulo_infer(*ty, exp_found.found))
+                && let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code()
+                && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
             {
-                if let ObligationCauseCode::Pattern { span: Some(span), .. } = *cause.code() {
-                    if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
-                        let suggestion = if expected_def.is_struct() {
-                            SuggestAccessingField::Safe { span, snippet, name, ty }
-                        } else if expected_def.is_union() {
-                            SuggestAccessingField::Unsafe { span, snippet, name, ty }
-                        } else {
-                            return;
-                        };
-                        diag.subdiagnostic(suggestion);
-                    }
-                }
+                let suggestion = if expected_def.is_struct() {
+                    SuggestAccessingField::Safe { span, snippet, name, ty }
+                } else if expected_def.is_union() {
+                    SuggestAccessingField::Unsafe { span, snippet, name, ty }
+                } else {
+                    return;
+                };
+                diag.subdiagnostic(suggestion);
             }
         }
     }
@@ -540,38 +538,35 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     ) -> Option<SuggestAsRefKind> {
         if let (ty::Adt(exp_def, exp_args), ty::Ref(_, found_ty, _)) =
             (expected.kind(), found.kind())
+            && let ty::Adt(found_def, found_args) = *found_ty.kind()
         {
-            if let ty::Adt(found_def, found_args) = *found_ty.kind() {
-                if exp_def == &found_def {
-                    let have_as_ref = &[
-                        (sym::Option, SuggestAsRefKind::Option),
-                        (sym::Result, SuggestAsRefKind::Result),
-                    ];
-                    if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
-                        self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
-                    }) {
-                        let mut show_suggestion = true;
-                        for (exp_ty, found_ty) in
-                            std::iter::zip(exp_args.types(), found_args.types())
-                        {
-                            match *exp_ty.kind() {
-                                ty::Ref(_, exp_ty, _) => {
-                                    match (exp_ty.kind(), found_ty.kind()) {
-                                        (_, ty::Param(_))
-                                        | (_, ty::Infer(_))
-                                        | (ty::Param(_), _)
-                                        | (ty::Infer(_), _) => {}
-                                        _ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
-                                        _ => show_suggestion = false,
-                                    };
-                                }
-                                ty::Param(_) | ty::Infer(_) => {}
-                                _ => show_suggestion = false,
+            if exp_def == &found_def {
+                let have_as_ref = &[
+                    (sym::Option, SuggestAsRefKind::Option),
+                    (sym::Result, SuggestAsRefKind::Result),
+                ];
+                if let Some(msg) = have_as_ref.iter().find_map(|(name, msg)| {
+                    self.tcx.is_diagnostic_item(*name, exp_def.did()).then_some(msg)
+                }) {
+                    let mut show_suggestion = true;
+                    for (exp_ty, found_ty) in std::iter::zip(exp_args.types(), found_args.types()) {
+                        match *exp_ty.kind() {
+                            ty::Ref(_, exp_ty, _) => {
+                                match (exp_ty.kind(), found_ty.kind()) {
+                                    (_, ty::Param(_))
+                                    | (_, ty::Infer(_))
+                                    | (ty::Param(_), _)
+                                    | (ty::Infer(_), _) => {}
+                                    _ if self.same_type_modulo_infer(exp_ty, found_ty) => {}
+                                    _ => show_suggestion = false,
+                                };
                             }
+                            ty::Param(_) | ty::Infer(_) => {}
+                            _ => show_suggestion = false,
                         }
-                        if show_suggestion {
-                            return Some(*msg);
-                        }
+                    }
+                    if show_suggestion {
+                        return Some(*msg);
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index 98f67257fd1..cdf1402252a 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -360,7 +360,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                             },
                         ] = path.segments
                         && data.trait_ref.def_id == *trait_id
-                        && self.tcx.trait_of_item(*item_id) == Some(*trait_id)
+                        && self.tcx.trait_of_assoc(*item_id) == Some(*trait_id)
                         && let None = self.tainted_by_errors()
                     {
                         let assoc_item = self.tcx.associated_item(item_id);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
index 2344bc79f21..5765dfd891d 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/on_unimplemented.rs
@@ -381,15 +381,15 @@ impl IgnoredDiagnosticOption {
         old: Option<Span>,
         option_name: &'static str,
     ) {
-        if let (Some(new_item), Some(old_item)) = (new, old) {
-            if let Some(item_def_id) = item_def_id.as_local() {
-                tcx.emit_node_span_lint(
-                    MALFORMED_DIAGNOSTIC_ATTRIBUTES,
-                    tcx.local_def_id_to_hir_id(item_def_id),
-                    new_item,
-                    IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
-                );
-            }
+        if let (Some(new_item), Some(old_item)) = (new, old)
+            && let Some(item_def_id) = item_def_id.as_local()
+        {
+            tcx.emit_node_span_lint(
+                MALFORMED_DIAGNOSTIC_ATTRIBUTES,
+                tcx.local_def_id_to_hir_id(item_def_id),
+                new_item,
+                IgnoredDiagnosticOption { span: new_item, prev_span: old_item, option_name },
+            );
         }
     }
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
index bf7d4257b62..c182fd99b17 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -987,7 +987,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     else {
                         return false;
                     };
-                    if self.tcx.trait_of_item(did) != Some(clone_trait) {
+                    if self.tcx.trait_of_assoc(did) != Some(clone_trait) {
                         return false;
                     }
                     Some(ident.span)
@@ -2213,26 +2213,26 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         span: Span,
         trait_ref: DefId,
     ) {
-        if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id) {
-            if let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind {
-                err.note(format!(
-                    "{}s cannot be accessed directly on a `trait`, they can only be \
+        if let Some(assoc_item) = self.tcx.opt_associated_item(item_def_id)
+            && let ty::AssocKind::Const { .. } | ty::AssocKind::Type { .. } = assoc_item.kind
+        {
+            err.note(format!(
+                "{}s cannot be accessed directly on a `trait`, they can only be \
                         accessed through a specific `impl`",
-                    self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
-                ));
+                self.tcx.def_kind_descr(assoc_item.as_def_kind(), item_def_id)
+            ));
 
-                if !assoc_item.is_impl_trait_in_trait() {
-                    err.span_suggestion_verbose(
-                        span,
-                        "use the fully qualified path to an implementation",
-                        format!(
-                            "<Type as {}>::{}",
-                            self.tcx.def_path_str(trait_ref),
-                            assoc_item.name()
-                        ),
-                        Applicability::HasPlaceholders,
-                    );
-                }
+            if !assoc_item.is_impl_trait_in_trait() {
+                err.span_suggestion_verbose(
+                    span,
+                    "use the fully qualified path to an implementation",
+                    format!(
+                        "<Type as {}>::{}",
+                        self.tcx.def_path_str(trait_ref),
+                        assoc_item.name()
+                    ),
+                    Applicability::HasPlaceholders,
+                );
             }
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 3ce0f025512..01bdae7435d 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -197,6 +197,12 @@ where
                     delegate.compute_goal_fast_path(goal, obligation.cause.span)
                 {
                     match certainty {
+                        // This fast path doesn't depend on region identity so it doesn't
+                        // matter if the goal contains inference variables or not, so we
+                        // don't need to call `push_hir_typeck_potentially_region_dependent_goal`
+                        // here.
+                        //
+                        // Only goals proven via the trait solver should be region dependent.
                         Certainty::Yes => {}
                         Certainty::Maybe(_) => {
                             self.obligations.register(obligation, None);
@@ -207,7 +213,7 @@ where
 
                 let result = delegate.evaluate_root_goal(goal, obligation.cause.span, stalled_on);
                 self.inspect_evaluated_obligation(infcx, &obligation, &result);
-                let GoalEvaluation { certainty, has_changed, stalled_on } = match result {
+                let GoalEvaluation { goal, certainty, has_changed, stalled_on } = match result {
                     Ok(result) => result,
                     Err(NoSolution) => {
                         errors.push(E::from_solver_error(
@@ -218,6 +224,10 @@ where
                     }
                 };
 
+                // We've resolved the goal in `evaluate_root_goal`, avoid redoing this work
+                // in the next iteration. This does not resolve the inference variables
+                // constrained by evaluating the goal.
+                obligation.predicate = goal.predicate;
                 if has_changed == HasChanged::Yes {
                     // We increment the recursion depth here to track the number of times
                     // this goal has resulted in inference progress. This doesn't precisely
@@ -230,7 +240,22 @@ where
                 }
 
                 match certainty {
-                    Certainty::Yes => {}
+                    Certainty::Yes => {
+                        // Goals may depend on structural identity. Region uniquification at the
+                        // start of MIR borrowck may cause things to no longer be so, potentially
+                        // causing an ICE.
+                        //
+                        // While we uniquify root goals in HIR this does not handle cases where
+                        // regions are hidden inside of a type or const inference variable.
+                        //
+                        // FIXME(-Znext-solver): This does not handle inference variables hidden
+                        // inside of an opaque type, e.g. if there's `Opaque = (?x, ?x)` in the
+                        // storage, we can also rely on structural identity of `?x` even if we
+                        // later uniquify it in MIR borrowck.
+                        if infcx.in_hir_typeck && obligation.has_non_region_infer() {
+                            infcx.push_hir_typeck_potentially_region_dependent_goal(obligation);
+                        }
+                    }
                     Certainty::Maybe(_) => self.obligations.register(obligation, stalled_on),
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index f50f01a285b..07e78da37b3 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -695,15 +695,14 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
                 source: CandidateSource::Impl(def_id),
                 result: Ok(_),
             } = cand.kind()
+                && let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id)
             {
-                if let ty::ImplPolarity::Reservation = infcx.tcx.impl_polarity(def_id) {
-                    let message = infcx
-                        .tcx
-                        .get_attr(def_id, sym::rustc_reservation_impl)
-                        .and_then(|a| a.value_str());
-                    if let Some(message) = message {
-                        self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
-                    }
+                let message = infcx
+                    .tcx
+                    .get_attr(def_id, sym::rustc_reservation_impl)
+                    .and_then(|a| a.value_str());
+                if let Some(message) = message {
+                    self.causes.insert(IntercrateAmbiguityCause::ReservationImpl { message });
                 }
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 91c41544f78..9b5e59ce0fd 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -759,7 +759,7 @@ fn instantiate_and_check_impossible_predicates<'tcx>(
 
     // Specifically check trait fulfillment to avoid an error when trying to resolve
     // associated items.
-    if let Some(trait_def_id) = tcx.trait_of_item(key.0) {
+    if let Some(trait_def_id) = tcx.trait_of_assoc(key.0) {
         let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, key.1);
         predicates.push(trait_ref.upcast(tcx));
     }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 28b5b7cf391..581191b2036 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1507,7 +1507,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
     let tcx = selcx.tcx();
     let self_ty = obligation.predicate.self_ty();
     let item_def_id = obligation.predicate.def_id;
-    let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
+    let trait_def_id = tcx.trait_of_assoc(item_def_id).unwrap();
     let args = tcx.mk_args(&[self_ty.into()]);
     let (term, obligations) = if tcx.is_lang_item(trait_def_id, LangItem::DiscriminantKind) {
         let discriminant_def_id =
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index f90316f520b..d7c3543cb3f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -781,16 +781,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                         self,
                                         &project_obligation,
                                     )
-                                {
-                                    if let Some(cached_res) = self
+                                    && let Some(cached_res) = self
                                         .infcx
                                         .inner
                                         .borrow_mut()
                                         .projection_cache()
                                         .is_complete(key)
-                                    {
-                                        break 'compute_res Ok(cached_res);
-                                    }
+                                {
+                                    break 'compute_res Ok(cached_res);
                                 }
 
                                 // Need to explicitly set the depth of nested goals here as
@@ -1436,24 +1434,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
         let tcx = self.tcx();
         // Treat reservation impls as ambiguity.
-        if let ImplCandidate(def_id) = candidate {
-            if let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id) {
-                if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
-                    let message = tcx
-                        .get_attr(def_id, sym::rustc_reservation_impl)
-                        .and_then(|a| a.value_str());
-                    if let Some(message) = message {
-                        debug!(
-                            "filter_reservation_impls: \
+        if let ImplCandidate(def_id) = candidate
+            && let ty::ImplPolarity::Reservation = tcx.impl_polarity(def_id)
+        {
+            if let Some(intercrate_ambiguity_clauses) = &mut self.intercrate_ambiguity_causes {
+                let message =
+                    tcx.get_attr(def_id, sym::rustc_reservation_impl).and_then(|a| a.value_str());
+                if let Some(message) = message {
+                    debug!(
+                        "filter_reservation_impls: \
                                  reservation impl ambiguity on {:?}",
-                            def_id
-                        );
-                        intercrate_ambiguity_clauses
-                            .insert(IntercrateAmbiguityCause::ReservationImpl { message });
-                    }
+                        def_id
+                    );
+                    intercrate_ambiguity_clauses
+                        .insert(IntercrateAmbiguityCause::ReservationImpl { message });
                 }
-                return Ok(None);
             }
+            return Ok(None);
         }
         Ok(Some(candidate))
     }