Skip to content

Commit

Permalink
Add newtype for first input type
Browse files Browse the repository at this point in the history
  • Loading branch information
clubby789 committed Feb 20, 2024
1 parent cb51c85 commit 9bfc46c
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 9 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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<A>` in `impl<A, B> for C<B> in D<A>`
self_ty_span
} else {
Expand Down Expand Up @@ -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(_) => {
Expand Down
21 changes: 18 additions & 3 deletions compiler/rustc_trait_selection/src/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<bool> 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<Ty<'tcx>>),
}

Expand Down Expand Up @@ -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>
Expand All @@ -769,7 +784,7 @@ where
}

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(())
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 9bfc46c

Please sign in to comment.