Skip to content

Commit 1e655ef

Browse files
Move refinement check out of compare_impl_item
1 parent a3623f2 commit 1e655ef

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,24 @@ fn check_impl_items_against_trait<'tcx>(
10451045
continue;
10461046
};
10471047

1048-
let _ = tcx.ensure().compare_impl_item(impl_item.expect_local());
1048+
let res = tcx.ensure().compare_impl_item(impl_item.expect_local());
1049+
1050+
if res.is_ok() {
1051+
match ty_impl_item.kind {
1052+
ty::AssocKind::Fn => {
1053+
compare_impl_item::refine::check_refining_return_position_impl_trait_in_trait(
1054+
tcx,
1055+
ty_impl_item,
1056+
ty_trait_item,
1057+
tcx.impl_trait_ref(ty_impl_item.container_id(tcx))
1058+
.unwrap()
1059+
.instantiate_identity(),
1060+
);
1061+
}
1062+
ty::AssocKind::Const => {}
1063+
ty::AssocKind::Type => {}
1064+
}
1065+
}
10491066

10501067
check_specialization_validity(
10511068
tcx,

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use tracing::{debug, instrument};
3333
use super::potentially_plural_count;
3434
use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
3535

36-
mod refine;
36+
pub(super) mod refine;
3737

3838
/// Call the query `tcx.compare_impl_item()` directly instead.
3939
pub(super) fn compare_impl_item(
@@ -70,12 +70,6 @@ fn compare_impl_method<'tcx>(
7070
) -> Result<(), ErrorGuaranteed> {
7171
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
7272
compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
73-
refine::check_refining_return_position_impl_trait_in_trait(
74-
tcx,
75-
impl_m,
76-
trait_m,
77-
impl_trait_ref,
78-
);
7973
Ok(())
8074
}
8175

compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt;
1717
use rustc_trait_selection::traits::{ObligationCtxt, elaborate, normalize_param_env_or_error};
1818

1919
/// Check that an implementation does not refine an RPITIT from a trait method signature.
20-
pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
20+
pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
2121
tcx: TyCtxt<'tcx>,
2222
impl_m: ty::AssocItem,
2323
trait_m: ty::AssocItem,

compiler/rustc_ty_utils/src/instance.rs

+2
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ fn resolve_associated_item<'tcx>(
219219
// We check that the impl item is compatible with the trait item
220220
// because otherwise we may ICE in const eval due to type mismatches,
221221
// signature incompatibilities, etc.
222+
// NOTE: We could also only enforce this in `PostAnalysis`, which
223+
// is what CTFE and MIR inlining would care about anyways.
222224
if trait_item_id != leaf_def.item.def_id
223225
&& let Some(leaf_def_item) = leaf_def.item.def_id.as_local()
224226
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//@ check-pass
2+
3+
// Make sure that refinement checking doesn't cause a cycle in `Instance::resolve`
4+
// which calls `compare_impl_item`.
5+
6+
trait Foo {
7+
fn test() -> impl IntoIterator<Item = ()> + Send;
8+
}
9+
10+
struct A;
11+
impl Foo for A {
12+
fn test() -> impl IntoIterator<Item = ()> + Send {
13+
B::test()
14+
}
15+
}
16+
17+
struct B;
18+
impl Foo for B {
19+
fn test() -> impl IntoIterator<Item = ()> + Send {
20+
for () in A::test() {}
21+
22+
[]
23+
}
24+
}
25+
26+
fn main() {}

0 commit comments

Comments
 (0)