Skip to content

Commit 0ac70d8

Browse files
Implement RTN in resolve_bound_vars and HIR ty lowering
1 parent f3033f3 commit 0ac70d8

File tree

11 files changed

+411
-177
lines changed

11 files changed

+411
-177
lines changed

compiler/rustc_ast_lowering/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -487,11 +487,12 @@ enum ParamMode {
487487

488488
#[derive(Copy, Clone, Debug)]
489489
enum AllowReturnTypeNotation {
490+
/// Only in types, since RTN is denied later during HIR lowering.
490491
Yes,
492+
/// All other positions (path expr, method, use tree).
491493
No,
492494
}
493495

494-
#[derive(Copy, Clone, Debug)]
495496
enum GenericArgsMode {
496497
ParenSugar,
497498
ReturnTypeNotation,
@@ -1239,7 +1240,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12391240
qself,
12401241
path,
12411242
param_mode,
1242-
// We deny these after the fact in HIR->middle type lowering.
12431243
AllowReturnTypeNotation::Yes,
12441244
itctx,
12451245
None,

compiler/rustc_ast_lowering/src/path.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ use super::errors::{
1616
GenericTypeWithParentheses, UseAngleBrackets,
1717
};
1818
use super::{
19-
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes,
20-
LoweringContext, ParamMode, ResolverAstLoweringExt,
19+
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition,
20+
LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt,
2121
};
22-
use crate::ImplTraitPosition;
2322

2423
impl<'a, 'hir> LoweringContext<'a, 'hir> {
2524
#[instrument(level = "trace", skip(self))]

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
226226
for predicate in hir_generics.predicates {
227227
match predicate {
228228
hir::WherePredicate::BoundPredicate(bound_pred) => {
229-
let ty = icx.lower_ty(bound_pred.bounded_ty);
229+
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
230+
230231
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
231232
// Keep the type around in a dummy predicate, in case of no bounds.
232233
// That way, `where Ty:` is not a complete noop (see #53696) and `Ty`
@@ -757,6 +758,10 @@ impl<'tcx> ItemCtxt<'tcx> {
757758
continue;
758759
};
759760

761+
// Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
762+
// want to only consider predicates with `Self: ...`, but we don't want
763+
// `OnlySelfBounds(true)` since we want to collect the nested associated
764+
// type bound as well.
760765
let (only_self_bounds, assoc_name) = match filter {
761766
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
762767
(OnlySelfBounds(false), None)
@@ -767,14 +772,10 @@ impl<'tcx> ItemCtxt<'tcx> {
767772
}
768773
};
769774

770-
// Subtle: If we're collecting `SelfAndAssociatedTypeBounds`, then we
771-
// want to only consider predicates with `Self: ...`, but we don't want
772-
// `OnlySelfBounds(true)` since we want to collect the nested associated
773-
// type bound as well.
774775
let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
775776
ty
776777
} else if matches!(filter, PredicateFilter::All) {
777-
self.lower_ty(predicate.bounded_ty)
778+
self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty)
778779
} else {
779780
continue;
780781
};

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+109
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
890890
(pair, r)
891891
})
892892
.unzip();
893+
893894
self.record_late_bound_vars(hir_id, binders);
895+
896+
// If this is an RTN type in the self type, then append those to the binder.
897+
self.try_append_return_type_notation_params(hir_id, bounded_ty);
898+
894899
// Even if there are no lifetimes defined here, we still wrap it in a binder
895900
// scope. If there happens to be a nested poly trait ref (an error), that
896901
// will be `Concatenating` anyways, so we don't have to worry about the depth
@@ -1856,6 +1861,110 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
18561861
let old_value = self.map.defs.swap_remove(&lifetime_ref.hir_id);
18571862
assert_eq!(old_value, Some(bad_def));
18581863
}
1864+
1865+
// TODO:
1866+
fn try_append_return_type_notation_params(
1867+
&mut self,
1868+
hir_id: HirId,
1869+
hir_ty: &'tcx hir::Ty<'tcx>,
1870+
) {
1871+
let hir::TyKind::Path(qpath) = hir_ty.kind else {
1872+
// TODO:
1873+
return;
1874+
};
1875+
1876+
let (mut bound_vars, item_def_id, item_segment) = match qpath {
1877+
// TODO:
1878+
hir::QPath::Resolved(_, path)
1879+
if let [.., item_segment] = &path.segments[..]
1880+
&& item_segment.args.is_some_and(|args| {
1881+
matches!(
1882+
args.parenthesized,
1883+
hir::GenericArgsParentheses::ReturnTypeNotation
1884+
)
1885+
}) =>
1886+
{
1887+
let Res::Def(DefKind::AssocFn, item_def_id) = path.res else {
1888+
bug!();
1889+
};
1890+
(vec![], item_def_id, item_segment)
1891+
}
1892+
1893+
// TODO:
1894+
hir::QPath::TypeRelative(qself, item_segment)
1895+
if item_segment.args.is_some_and(|args| {
1896+
matches!(args.parenthesized, hir::GenericArgsParentheses::ReturnTypeNotation)
1897+
}) =>
1898+
{
1899+
let hir::TyKind::Path(hir::QPath::Resolved(None, path)) = qself.kind else {
1900+
return;
1901+
};
1902+
1903+
match path.res {
1904+
Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { trait_: _ } => {
1905+
let Some(generics) = self.tcx.hir_owner_node(hir_id.owner).generics()
1906+
else {
1907+
return;
1908+
};
1909+
1910+
let one_bound = generics.predicates.iter().find_map(|predicate| {
1911+
let hir::WherePredicate::BoundPredicate(predicate) = predicate else {
1912+
return None;
1913+
};
1914+
let hir::TyKind::Path(hir::QPath::Resolved(None, bounded_path)) =
1915+
predicate.bounded_ty.kind
1916+
else {
1917+
return None;
1918+
};
1919+
if bounded_path.res != path.res {
1920+
return None;
1921+
}
1922+
predicate.bounds.iter().find_map(|bound| {
1923+
let hir::GenericBound::Trait(trait_, _) = bound else {
1924+
return None;
1925+
};
1926+
BoundVarContext::supertrait_hrtb_vars(
1927+
self.tcx,
1928+
trait_.trait_ref.trait_def_id()?,
1929+
item_segment.ident,
1930+
ty::AssocKind::Fn,
1931+
)
1932+
})
1933+
});
1934+
let Some((bound_vars, assoc_item)) = one_bound else {
1935+
return;
1936+
};
1937+
(bound_vars, assoc_item.def_id, item_segment)
1938+
}
1939+
Res::SelfTyAlias { is_trait_impl: true, .. } => todo!(),
1940+
_ => return,
1941+
}
1942+
}
1943+
1944+
_ => return,
1945+
};
1946+
1947+
// TODO:
1948+
bound_vars.extend(self.tcx.generics_of(item_def_id).own_params.iter().map(|param| {
1949+
match param.kind {
1950+
ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region(
1951+
ty::BoundRegionKind::BrNamed(param.def_id, param.name),
1952+
),
1953+
ty::GenericParamDefKind::Type { .. } => {
1954+
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(param.def_id, param.name))
1955+
}
1956+
ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const,
1957+
}
1958+
}));
1959+
bound_vars.extend(self.tcx.fn_sig(item_def_id).instantiate_identity().bound_vars());
1960+
1961+
// TODO:
1962+
let existing_bound_vars = self.map.late_bound_vars.get_mut(&hir_id).unwrap();
1963+
let existing_bound_vars_saved = existing_bound_vars.clone();
1964+
existing_bound_vars.extend(bound_vars);
1965+
// TODO: subtle
1966+
self.record_late_bound_vars(item_segment.hir_id, existing_bound_vars_saved);
1967+
}
18591968
}
18601969

18611970
/// Detects late-bound lifetimes and inserts them into

0 commit comments

Comments
 (0)