Where bounds are checked on inherent impls
This commit is contained in:
parent
f4bd1e14bd
commit
d96faef913
3 changed files with 61 additions and 2 deletions
|
@ -7,7 +7,7 @@
|
||||||
use crate::infer::outlives::env::OutlivesEnvironment;
|
use crate::infer::outlives::env::OutlivesEnvironment;
|
||||||
use crate::infer::{CombinedSnapshot, InferOk, RegionckMode};
|
use crate::infer::{CombinedSnapshot, InferOk, RegionckMode};
|
||||||
use crate::traits::select::IntercrateAmbiguityCause;
|
use crate::traits::select::IntercrateAmbiguityCause;
|
||||||
use crate::traits::util::impl_trait_ref_and_oblig;
|
use crate::traits::util::{impl_trait_ref_and_oblig, inherent_impl_and_oblig};
|
||||||
use crate::traits::SkipLeakCheck;
|
use crate::traits::SkipLeakCheck;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
|
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
|
||||||
|
@ -338,7 +338,13 @@ fn impl_subject_and_obligations<'cx, 'tcx>(
|
||||||
|
|
||||||
(ImplSubject::Trait(impl2_trait_ref), Box::new(obligations))
|
(ImplSubject::Trait(impl2_trait_ref), Box::new(obligations))
|
||||||
} else {
|
} else {
|
||||||
(infcx.tcx.impl_subject(impl2_def_id), Box::new(iter::empty()))
|
// Attempt to prove that impl2 applies, given all of the above.
|
||||||
|
let selcx = &mut SelectionContext::new(&infcx);
|
||||||
|
let impl2_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl2_def_id);
|
||||||
|
let (impl2_ty, obligations) =
|
||||||
|
inherent_impl_and_oblig(selcx, impl_env, impl2_def_id, impl2_substs);
|
||||||
|
|
||||||
|
(ImplSubject::Inherent(impl2_ty), Box::new(obligations))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,6 +218,34 @@ pub fn impl_trait_ref_and_oblig<'a, 'tcx>(
|
||||||
(impl_trait_ref, impl_obligations)
|
(impl_trait_ref, impl_obligations)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Instantiate all bound parameters of the impl with the given substs,
|
||||||
|
/// returning the resulting trait ref and all obligations that arise.
|
||||||
|
/// The obligations are closed under normalization.
|
||||||
|
pub fn inherent_impl_and_oblig<'a, 'tcx>(
|
||||||
|
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||||
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
|
impl_def_id: DefId,
|
||||||
|
impl_substs: SubstsRef<'tcx>,
|
||||||
|
) -> (Ty<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
|
||||||
|
let ty = selcx.tcx().type_of(impl_def_id);
|
||||||
|
let ty = ty.subst(selcx.tcx(), impl_substs);
|
||||||
|
let Normalized { value: ty, obligations: normalization_obligations1 } =
|
||||||
|
super::normalize(selcx, param_env, ObligationCause::dummy(), ty);
|
||||||
|
|
||||||
|
let predicates = selcx.tcx().predicates_of(impl_def_id);
|
||||||
|
let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
|
||||||
|
let Normalized { value: predicates, obligations: normalization_obligations2 } =
|
||||||
|
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
|
||||||
|
let impl_obligations =
|
||||||
|
predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates);
|
||||||
|
|
||||||
|
let impl_obligations = impl_obligations
|
||||||
|
.chain(normalization_obligations1.into_iter())
|
||||||
|
.chain(normalization_obligations2.into_iter());
|
||||||
|
|
||||||
|
(ty, impl_obligations)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn predicates_for_generics<'tcx>(
|
pub fn predicates_for_generics<'tcx>(
|
||||||
cause: ObligationCause<'tcx>,
|
cause: ObligationCause<'tcx>,
|
||||||
recursion_depth: usize,
|
recursion_depth: usize,
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(negative_impls)]
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
#![feature(with_negative_coherence)]
|
||||||
|
|
||||||
|
trait Foo {}
|
||||||
|
|
||||||
|
impl !Foo for u32 {}
|
||||||
|
|
||||||
|
#[rustc_strict_coherence]
|
||||||
|
struct MyStruct<T>(T);
|
||||||
|
|
||||||
|
impl MyStruct<u32> {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MyStruct<T>
|
||||||
|
where
|
||||||
|
T: Foo,
|
||||||
|
{
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue