Move refinement check out of compare_impl_item
This commit is contained in:
parent
a3623f20ae
commit
1e655ef213
5 changed files with 48 additions and 9 deletions
|
@ -1045,7 +1045,24 @@ fn check_impl_items_against_trait<'tcx>(
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = tcx.ensure().compare_impl_item(impl_item.expect_local());
|
let res = tcx.ensure().compare_impl_item(impl_item.expect_local());
|
||||||
|
|
||||||
|
if res.is_ok() {
|
||||||
|
match ty_impl_item.kind {
|
||||||
|
ty::AssocKind::Fn => {
|
||||||
|
compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
|
||||||
|
tcx,
|
||||||
|
ty_impl_item,
|
||||||
|
ty_trait_item,
|
||||||
|
tcx.impl_trait_ref(ty_impl_item.container_id(tcx))
|
||||||
|
.unwrap()
|
||||||
|
.instantiate_identity(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ty::AssocKind::Const => {}
|
||||||
|
ty::AssocKind::Type => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
check_specialization_validity(
|
check_specialization_validity(
|
||||||
tcx,
|
tcx,
|
||||||
|
|
|
@ -33,7 +33,7 @@ use tracing::{debug, instrument};
|
||||||
use super::potentially_plural_count;
|
use super::potentially_plural_count;
|
||||||
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
|
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
|
||||||
|
|
||||||
mod refine;
|
pub(super) mod refine;
|
||||||
|
|
||||||
/// Call the query `tcx.compare_impl_item()` directly instead.
|
/// Call the query `tcx.compare_impl_item()` directly instead.
|
||||||
pub(super) fn compare_impl_item(
|
pub(super) fn compare_impl_item(
|
||||||
|
@ -70,12 +70,6 @@ fn compare_impl_method<'tcx>(
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
|
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
|
||||||
compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
|
compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
|
||||||
refine::check_refining_return_position_impl_trait_in_trait(
|
|
||||||
tcx,
|
|
||||||
impl_m,
|
|
||||||
trait_m,
|
|
||||||
impl_trait_ref,
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt;
|
||||||
use rustc_trait_selection::traits::{ObligationCtxt, elaborate, normalize_param_env_or_error};
|
use rustc_trait_selection::traits::{ObligationCtxt, elaborate, normalize_param_env_or_error};
|
||||||
|
|
||||||
/// Check that an implementation does not refine an RPITIT from a trait method signature.
|
/// Check that an implementation does not refine an RPITIT from a trait method signature.
|
||||||
pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_m: ty::AssocItem,
|
impl_m: ty::AssocItem,
|
||||||
trait_m: ty::AssocItem,
|
trait_m: ty::AssocItem,
|
||||||
|
|
|
@ -219,6 +219,8 @@ fn resolve_associated_item<'tcx>(
|
||||||
// We check that the impl item is compatible with the trait item
|
// We check that the impl item is compatible with the trait item
|
||||||
// because otherwise we may ICE in const eval due to type mismatches,
|
// because otherwise we may ICE in const eval due to type mismatches,
|
||||||
// signature incompatibilities, etc.
|
// signature incompatibilities, etc.
|
||||||
|
// NOTE: We could also only enforce this in `PostAnalysis`, which
|
||||||
|
// is what CTFE and MIR inlining would care about anyways.
|
||||||
if trait_item_id != leaf_def.item.def_id
|
if trait_item_id != leaf_def.item.def_id
|
||||||
&& let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
|
&& let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
|
||||||
{
|
{
|
||||||
|
|
26
tests/ui/impl-trait/in-trait/refine-cycle.rs
Normal file
26
tests/ui/impl-trait/in-trait/refine-cycle.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Make sure that refinement checking doesn't cause a cycle in `Instance::resolve`
|
||||||
|
// which calls `compare_impl_item`.
|
||||||
|
|
||||||
|
trait Foo {
|
||||||
|
fn test() -> impl IntoIterator<Item = ()> + Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
impl Foo for A {
|
||||||
|
fn test() -> impl IntoIterator<Item = ()> + Send {
|
||||||
|
B::test()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B;
|
||||||
|
impl Foo for B {
|
||||||
|
fn test() -> impl IntoIterator<Item = ()> + Send {
|
||||||
|
for () in A::test() {}
|
||||||
|
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue