diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 07bbaa1926edf..b46a67d08eb03 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -1,14 +1,13 @@
//! Orphan checker: every impl either implements a trait defined in this
//! crate or pertains to a type defined in this crate.
+use crate::errors;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::LocalDefId;
use rustc_span::Span;
-use rustc_trait_selection::traits;
-
-use crate::errors;
+use rustc_trait_selection::traits::{self, IsFirstInputType};
#[instrument(skip(tcx), level = "debug")]
pub(crate) fn orphan_check_impl(
@@ -288,7 +287,7 @@ fn emit_orphan_check_error<'tcx>(
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
let mut sugg = None;
for &(mut ty, is_target_ty) in &tys {
- let span = if is_target_ty {
+ let span = if matches!(is_target_ty, IsFirstInputType::Yes) {
// Point at `D` in `impl for C in D`
self_ty_span
} else {
@@ -321,7 +320,8 @@ fn emit_orphan_check_error<'tcx>(
}
}
- let is_foreign = !trait_ref.def_id.is_local() && !is_target_ty;
+ let is_foreign =
+ !trait_ref.def_id.is_local() && matches!(is_target_ty, IsFirstInputType::No);
match &ty.kind() {
ty::Slice(_) => {
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index f663f02f87289..0d3169cec143c 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -598,9 +598,24 @@ pub fn trait_ref_is_local_or_fundamental<'tcx>(
trait_ref.def_id.krate == LOCAL_CRATE || tcx.has_attr(trait_ref.def_id, sym::fundamental)
}
+#[derive(Debug, Copy, Clone)]
+pub enum IsFirstInputType {
+ No,
+ Yes,
+}
+
+impl From for IsFirstInputType {
+ fn from(b: bool) -> IsFirstInputType {
+ match b {
+ false => IsFirstInputType::No,
+ true => IsFirstInputType::Yes,
+ }
+ }
+}
+
#[derive(Debug)]
pub enum OrphanCheckErr<'tcx> {
- NonLocalInputType(Vec<(Ty<'tcx>, bool /* Is this the first input type? */)>),
+ NonLocalInputType(Vec<(Ty<'tcx>, IsFirstInputType)>),
UncoveredTy(Ty<'tcx>, Option>),
}
@@ -751,7 +766,7 @@ struct OrphanChecker<'tcx, F> {
/// Ignore orphan check failures and exclusively search for the first
/// local type.
search_first_local_ty: bool,
- non_local_tys: Vec<(Ty<'tcx>, bool)>,
+ non_local_tys: Vec<(Ty<'tcx>, IsFirstInputType)>,
}
impl<'tcx, F, E> OrphanChecker<'tcx, F>
@@ -769,7 +784,7 @@ where
}
fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> {
- self.non_local_tys.push((t, self.in_self_ty));
+ self.non_local_tys.push((t, self.in_self_ty.into()));
ControlFlow::Continue(())
}
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 9eec60ea06c21..32447aca390a4 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -42,7 +42,7 @@ use std::fmt::Debug;
use std::ops::ControlFlow;
pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls};
-pub use self::coherence::{OrphanCheckErr, OverlapResult};
+pub use self::coherence::{IsFirstInputType, OrphanCheckErr, OverlapResult};
pub use self::engine::{ObligationCtxt, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
pub use self::normalize::NormalizeExt;