Add newtype for first input type
This commit is contained in:
parent
cb51c85023
commit
9bfc46c5d8
3 changed files with 24 additions and 9 deletions
|
@ -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(_) => {
|
||||||
|
|
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue