Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 349a237

Browse files
Take RPITITs inherit the assumed_wf_types of their parent fn
1 parent 03a5725 commit 349a237

File tree

6 files changed

+57
-100
lines changed

6 files changed

+57
-100
lines changed

‎compiler/rustc_hir_analysis/src/check/wfcheck.rs‎

Lines changed: 11 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,17 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
284284
};
285285
check_object_unsafe_self_trait_by_name(tcx, trait_item);
286286
check_associated_item(tcx, def_id, span, method_sig);
287+
288+
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {
289+
for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) {
290+
check_associated_item(
291+
tcx,
292+
assoc_ty_def_id.expect_local(),
293+
tcx.def_span(assoc_ty_def_id),
294+
None,
295+
);
296+
}
297+
}
287298
}
288299

289300
/// Require that the user writes where clauses on GATs for the implicit
@@ -1466,13 +1477,6 @@ fn check_fn_or_method<'tcx>(
14661477

14671478
check_where_clauses(wfcx, span, def_id);
14681479

1469-
check_return_position_impl_trait_in_trait_bounds(
1470-
wfcx,
1471-
def_id,
1472-
sig.output(),
1473-
hir_decl.output.span(),
1474-
);
1475-
14761480
if sig.abi == Abi::RustCall {
14771481
let span = tcx.def_span(def_id);
14781482
let has_implicit_self = hir_decl.implicit_self != hir::ImplicitSelfKind::None;
@@ -1507,87 +1511,6 @@ fn check_fn_or_method<'tcx>(
15071511
}
15081512
}
15091513

1510-
/// Basically `check_associated_type_bounds`, but separated for now and should be
1511-
/// deduplicated when RPITITs get lowered into real associated items.
1512-
#[tracing::instrument(level = "trace", skip(wfcx))]
1513-
fn check_return_position_impl_trait_in_trait_bounds<'tcx>(
1514-
wfcx: &WfCheckingCtxt<'_, 'tcx>,
1515-
fn_def_id: LocalDefId,
1516-
fn_output: Ty<'tcx>,
1517-
span: Span,
1518-
) {
1519-
let tcx = wfcx.tcx();
1520-
let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) else {
1521-
return;
1522-
};
1523-
if assoc_item.container != ty::AssocItemContainer::TraitContainer {
1524-
return;
1525-
}
1526-
fn_output.visit_with(&mut ImplTraitInTraitFinder {
1527-
wfcx,
1528-
fn_def_id,
1529-
depth: ty::INNERMOST,
1530-
seen: FxHashSet::default(),
1531-
});
1532-
}
1533-
1534-
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering
1535-
// strategy, we can't just call `check_associated_item` on the new RPITITs,
1536-
// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail.
1537-
// That's because we need to check that the bounds of the RPITIT hold using
1538-
// the special args that we create during opaque type lowering, otherwise we're
1539-
// getting a bunch of early bound and free regions mixed up... Haven't looked too
1540-
// deep into this, though.
1541-
struct ImplTraitInTraitFinder<'a, 'tcx> {
1542-
wfcx: &'a WfCheckingCtxt<'a, 'tcx>,
1543-
fn_def_id: LocalDefId,
1544-
depth: ty::DebruijnIndex,
1545-
seen: FxHashSet<DefId>,
1546-
}
1547-
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
1548-
type BreakTy = !;
1549-
1550-
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<!> {
1551-
let tcx = self.wfcx.tcx();
1552-
if let ty::Alias(ty::Opaque, unshifted_opaque_ty) = *ty.kind()
1553-
&& self.seen.insert(unshifted_opaque_ty.def_id)
1554-
&& let Some(opaque_def_id) = unshifted_opaque_ty.def_id.as_local()
1555-
&& let origin = tcx.opaque_type_origin(opaque_def_id)
1556-
&& let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = origin
1557-
&& source == self.fn_def_id
1558-
{
1559-
let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, _depth| {
1560-
match re.kind() {
1561-
ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReError(_) | ty::ReStatic => re,
1562-
r => bug!("unexpected region: {r:?}"),
1563-
}
1564-
});
1565-
for (bound, bound_span) in tcx
1566-
.explicit_item_bounds(opaque_ty.def_id)
1567-
.iter_instantiated_copied(tcx, opaque_ty.args)
1568-
{
1569-
let bound = self.wfcx.normalize(bound_span, None, bound);
1570-
self.wfcx.register_obligations(traits::wf::predicate_obligations(
1571-
self.wfcx.infcx,
1572-
self.wfcx.param_env,
1573-
self.wfcx.body_def_id,
1574-
bound.as_predicate(),
1575-
bound_span,
1576-
));
1577-
// Set the debruijn index back to innermost here, since we already eagerly
1578-
// shifted the args that we use to generate these bounds. This is unfortunately
1579-
// subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`,
1580-
// but that function doesn't actually need to normalize the bound it's visiting
1581-
// (whereas we have to do so here)...
1582-
let old_depth = std::mem::replace(&mut self.depth, ty::INNERMOST);
1583-
bound.visit_with(self);
1584-
self.depth = old_depth;
1585-
}
1586-
}
1587-
ty.super_visit_with(self)
1588-
}
1589-
}
1590-
15911514
const HELP_FOR_SELF_TYPE: &str = "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
15921515
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
15931516
of the previous types except `Self`)";

‎compiler/rustc_ty_utils/src/implied_bounds.rs‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
use rustc_data_structures::fx::FxHashMap;
12
use rustc_hir as hir;
23
use rustc_hir::def::DefKind;
34
use rustc_hir::def_id::LocalDefId;
5+
use rustc_middle::middle::resolve_bound_vars as rbv;
46
use rustc_middle::query::Providers;
57
use rustc_middle::ty::{self, Ty, TyCtxt};
68
use rustc_span::Span;
@@ -42,6 +44,41 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
4244
let mut impl_spans = impl_spans(tcx, def_id);
4345
tcx.arena.alloc_from_iter(tys.into_iter().map(|ty| (ty, impl_spans.next().unwrap())))
4446
}
47+
DefKind::AssocTy if let Some(ty::ImplTraitInTraitData::Trait { fn_def_id, opaque_def_id }) = tcx.opt_rpitit_info(def_id.to_def_id()) => {
48+
let hir::OpaqueTy { lifetime_mapping, .. } =
49+
*tcx.hir().expect_item(opaque_def_id.expect_local()).expect_opaque_ty();
50+
let mut mapping = FxHashMap::default();
51+
let generics = tcx.generics_of(def_id);
52+
for &(lifetime, new_early_bound_def_id) in lifetime_mapping {
53+
if let Some(rbv::ResolvedArg::LateBound(_, _, def_id)) =
54+
tcx.named_bound_var(lifetime.hir_id)
55+
{
56+
let name = tcx.hir().name(lifetime.hir_id);
57+
let index = generics
58+
.param_def_id_to_index(tcx, new_early_bound_def_id.to_def_id())
59+
.unwrap();
60+
mapping.insert(
61+
ty::Region::new_free(
62+
tcx,
63+
fn_def_id,
64+
ty::BoundRegionKind::BrNamed(def_id, name),
65+
),
66+
ty::Region::new_early_bound(
67+
tcx,
68+
ty::EarlyBoundRegion {
69+
def_id: new_early_bound_def_id.to_def_id(),
70+
index,
71+
name,
72+
},
73+
),
74+
);
75+
}
76+
}
77+
let a = tcx.fold_regions(tcx.assumed_wf_types(fn_def_id.expect_local()).to_vec(), |re, _| {
78+
if let Some(re) = mapping.get(&re) { *re } else { re }
79+
});
80+
tcx.arena.alloc_from_iter(a)
81+
}
4582
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
4683
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
4784
DefKind::TyAlias => ty::List::empty(),

‎compiler/rustc_ty_utils/src/lib.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#![feature(assert_matches)]
99
#![feature(iterator_try_collect)]
1010
#![feature(let_chains)]
11+
#![feature(if_let_guard)]
1112
#![feature(never_type)]
1213
#![feature(box_patterns)]
1314
#![recursion_limit = "256"]

‎tests/ui/async-await/in-trait/async-generics-and-bounds.stderr‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
44
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
55
| ^^^^^^^
66
|
7-
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
7+
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
88
--> $DIR/async-generics-and-bounds.rs:12:18
99
|
1010
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
11-
| ^^^^^
11+
| ^
1212
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
1313
--> $DIR/async-generics-and-bounds.rs:12:28
1414
|
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
2121
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
2222
| ^^^^^^^
2323
|
24-
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
24+
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
2525
--> $DIR/async-generics-and-bounds.rs:12:18
2626
|
2727
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
28-
| ^^^^^
28+
| ^
2929
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
3030
--> $DIR/async-generics-and-bounds.rs:12:28
3131
|

‎tests/ui/async-await/in-trait/async-generics.stderr‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ error[E0311]: the parameter type `U` may not live long enough
44
LL | async fn foo(&self) -> &(T, U);
55
| ^^^^^^^
66
|
7-
note: the parameter type `U` must be valid for the anonymous lifetime defined here...
7+
note: the parameter type `U` must be valid for the anonymous lifetime as defined here...
88
--> $DIR/async-generics.rs:9:18
99
|
1010
LL | async fn foo(&self) -> &(T, U);
11-
| ^^^^^
11+
| ^
1212
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
1313
--> $DIR/async-generics.rs:9:28
1414
|
@@ -21,11 +21,11 @@ error[E0311]: the parameter type `T` may not live long enough
2121
LL | async fn foo(&self) -> &(T, U);
2222
| ^^^^^^^
2323
|
24-
note: the parameter type `T` must be valid for the anonymous lifetime defined here...
24+
note: the parameter type `T` must be valid for the anonymous lifetime as defined here...
2525
--> $DIR/async-generics.rs:9:18
2626
|
2727
LL | async fn foo(&self) -> &(T, U);
28-
| ^^^^^
28+
| ^
2929
note: ...so that the reference type `&(T, U)` does not outlive the data it points at
3030
--> $DIR/async-generics.rs:9:28
3131
|

‎tests/ui/impl-trait/in-trait/wf-bounds.stderr‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,6 @@ note: required by a bound in `NeedsDisplay`
4747
|
4848
LL | struct NeedsDisplay<T: Display>(T);
4949
| ^^^^^^^ required by this bound in `NeedsDisplay`
50-
help: consider restricting type parameter `T`
51-
|
52-
LL | fn nya4<T: std::fmt::Display>() -> impl Wf<NeedsDisplay<T>>;
53-
| +++++++++++++++++++
5450

5551
error: aborting due to 4 previous errors
5652

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /