1
Fork 0

Add newtype for first input type

This commit is contained in:
clubby789 2024-02-13 23:57:43 +00:00
parent cb51c85023
commit 9bfc46c5d8
3 changed files with 24 additions and 9 deletions

View file

@ -1,14 +1,13 @@
//! Orphan checker: every impl either implements a trait defined in this //! Orphan checker: every impl either implements a trait defined in this
//! crate or pertains to a type defined in this crate. //! crate or pertains to a type defined in this crate.
use crate::errors;
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, AliasKind, Ty, TyCtxt, TypeVisitableExt};
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::traits; use rustc_trait_selection::traits::{self, IsFirstInputType};
use crate::errors;
#[instrument(skip(tcx), level = "debug")] #[instrument(skip(tcx), level = "debug")]
pub(crate) fn orphan_check_impl( 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()); (Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
let mut sugg = None; let mut sugg = None;
for &(mut ty, is_target_ty) in &tys { 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<A>` in `impl<A, B> for C<B> in D<A>` // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
self_ty_span self_ty_span
} else { } 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() { match &ty.kind() {
ty::Slice(_) => { ty::Slice(_) => {

View file

@ -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) 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<bool> for IsFirstInputType {
fn from(b: bool) -> IsFirstInputType {
match b {
false => IsFirstInputType::No,
true => IsFirstInputType::Yes,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum OrphanCheckErr<'tcx> { pub enum OrphanCheckErr<'tcx> {
NonLocalInputType(Vec<(Ty<'tcx>, bool /* Is this the first input type? */)>), NonLocalInputType(Vec<(Ty<'tcx>, IsFirstInputType)>),
UncoveredTy(Ty<'tcx>, Option<Ty<'tcx>>), UncoveredTy(Ty<'tcx>, Option<Ty<'tcx>>),
} }
@ -751,7 +766,7 @@ struct OrphanChecker<'tcx, F> {
/// Ignore orphan check failures and exclusively search for the first /// Ignore orphan check failures and exclusively search for the first
/// local type. /// local type.
search_first_local_ty: bool, 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> impl<'tcx, F, E> OrphanChecker<'tcx, F>
@ -769,7 +784,7 @@ where
} }
fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> { fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<OrphanCheckEarlyExit<'tcx, E>> {
self.non_local_tys.push((t, self.in_self_ty)); self.non_local_tys.push((t, self.in_self_ty.into()));
ControlFlow::Continue(()) ControlFlow::Continue(())
} }

View file

@ -42,7 +42,7 @@ use std::fmt::Debug;
use std::ops::ControlFlow; use std::ops::ControlFlow;
pub use self::coherence::{add_placeholder_note, orphan_check, overlapping_impls}; 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::engine::{ObligationCtxt, TraitEngineExt};
pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation}; pub use self::fulfill::{FulfillmentContext, PendingPredicateObligation};
pub use self::normalize::NormalizeExt; pub use self::normalize::NormalizeExt;