Skip to content

Commit 52f8235

Browse files
Make things actually work
1 parent eff2cb7 commit 52f8235

File tree

5 files changed

+151
-93
lines changed

5 files changed

+151
-93
lines changed

compiler/rustc_hir_analysis/src/astconv/mod.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -2598,6 +2598,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
25982598
&self,
25992599
opt_self_ty: Option<Ty<'tcx>>,
26002600
path: &hir::Path<'_>,
2601+
hir_id: hir::HirId,
26012602
permit_variants: bool,
26022603
) -> Ty<'tcx> {
26032604
let tcx = self.tcx();
@@ -2661,11 +2662,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
26612662
}
26622663
});
26632664

2664-
let def_id = def_id.expect_local();
2665-
let item_def_id = tcx.hir().ty_param_owner(def_id);
2666-
let generics = tcx.generics_of(item_def_id);
2667-
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2668-
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
2665+
match tcx.named_bound_var(hir_id) {
2666+
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2667+
let name =
2668+
tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
2669+
let br = ty::BoundTy {
2670+
var: ty::BoundVar::from_u32(index),
2671+
kind: ty::BoundTyKind::Param(def_id, name),
2672+
};
2673+
tcx.mk_ty(ty::Bound(debruijn, br))
2674+
}
2675+
Some(rbv::ResolvedArg::EarlyBound(_)) => {
2676+
let def_id = def_id.expect_local();
2677+
let item_def_id = tcx.hir().ty_param_owner(def_id);
2678+
let generics = tcx.generics_of(item_def_id);
2679+
let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2680+
tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id))
2681+
}
2682+
arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2683+
}
26692684
}
26702685
Res::SelfTyParam { .. } => {
26712686
// `Self` in trait or type alias.
@@ -2888,7 +2903,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
28882903
hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
28892904
debug!(?maybe_qself, ?path);
28902905
let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
2891-
self.res_to_ty(opt_self_ty, path, false)
2906+
self.res_to_ty(opt_self_ty, path, ast_ty.hir_id, false)
28922907
}
28932908
&hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
28942909
let opaque_ty = tcx.hir().item(item_id);

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+120-83
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ trait RegionExt {
3535

3636
impl RegionExt for ResolvedArg {
3737
fn early(param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
38-
debug!("Region::early: def_id={:?}", param.def_id);
38+
debug!("ResolvedArg::early: def_id={:?}", param.def_id);
3939
(param.def_id, ResolvedArg::EarlyBound(param.def_id.to_def_id()))
4040
}
4141

4242
fn late(idx: u32, param: &GenericParam<'_>) -> (LocalDefId, ResolvedArg) {
4343
let depth = ty::INNERMOST;
4444
debug!(
45-
"Region::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
45+
"ResolvedArg::late: idx={:?}, param={:?} depth={:?} def_id={:?}",
4646
idx, param, depth, param.def_id,
4747
);
4848
(param.def_id, ResolvedArg::LateBound(depth, idx, param.def_id.to_def_id()))
@@ -278,13 +278,25 @@ fn resolve_bound_vars(tcx: TyCtxt<'_>, local_def_id: hir::OwnerId) -> ResolveBou
278278
rl
279279
}
280280

281-
fn late_region_as_bound_region(tcx: TyCtxt<'_>, region: &ResolvedArg) -> ty::BoundVariableKind {
282-
match region {
281+
fn late_arg_as_bound_arg<'tcx>(
282+
tcx: TyCtxt<'tcx>,
283+
arg: &ResolvedArg,
284+
param: &GenericParam<'tcx>,
285+
) -> ty::BoundVariableKind {
286+
match arg {
283287
ResolvedArg::LateBound(_, _, def_id) => {
284288
let name = tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
285-
ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
289+
match param.kind {
290+
GenericParamKind::Lifetime { .. } => {
291+
ty::BoundVariableKind::Region(ty::BrNamed(*def_id, name))
292+
}
293+
GenericParamKind::Type { .. } => {
294+
ty::BoundVariableKind::Ty(ty::BoundTyKind::Param(*def_id, name))
295+
}
296+
GenericParamKind::Const { .. } => ty::BoundVariableKind::Const,
297+
}
286298
}
287-
_ => bug!("{:?} is not a late argument", region),
299+
_ => bug!("{:?} is not a late argument", arg),
288300
}
289301
}
290302

@@ -391,11 +403,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
391403
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
392404
bound_generic_params
393405
.iter()
394-
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
395406
.enumerate()
396407
.map(|(late_bound_idx, param)| {
397408
let pair = ResolvedArg::late(late_bound_idx as u32, param);
398-
let r = late_region_as_bound_region(self.tcx, &pair.1);
409+
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
399410
(pair, r)
400411
})
401412
.unzip();
@@ -481,7 +492,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
481492
}
482493
}
483494
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
484-
origin: hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_),
495+
origin: hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent),
485496
generics,
486497
..
487498
}) => {
@@ -490,26 +501,24 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
490501
let mut bound_vars = FxIndexMap::default();
491502
debug!(?generics.params);
492503
for param in generics.params {
493-
match param.kind {
494-
GenericParamKind::Lifetime { .. } => {
495-
let (def_id, reg) = ResolvedArg::early(&param);
496-
bound_vars.insert(def_id, reg);
497-
}
498-
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {}
499-
}
504+
let (def_id, reg) = ResolvedArg::early(&param);
505+
bound_vars.insert(def_id, reg);
500506
}
501507

502-
let scope = Scope::Binder {
503-
hir_id: item.hir_id(),
504-
bound_vars,
505-
s: self.scope,
506-
scope_type: BinderScopeType::Normal,
507-
where_bound_origin: None,
508-
};
508+
let scope = Scope::Root { opt_parent_item: Some(parent) };
509509
self.with(scope, |this| {
510-
let scope = Scope::TraitRefBoundary { s: this.scope };
511-
this.with(scope, |this| intravisit::walk_item(this, item))
512-
});
510+
let scope = Scope::Binder {
511+
hir_id: item.hir_id(),
512+
bound_vars,
513+
s: this.scope,
514+
scope_type: BinderScopeType::Normal,
515+
where_bound_origin: None,
516+
};
517+
this.with(scope, |this| {
518+
let scope = Scope::TraitRefBoundary { s: this.scope };
519+
this.with(scope, |this| intravisit::walk_item(this, item))
520+
});
521+
})
513522
}
514523
hir::ItemKind::TyAlias(_, generics)
515524
| hir::ItemKind::Enum(_, generics)
@@ -519,14 +528,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
519528
| hir::ItemKind::TraitAlias(generics, ..)
520529
| hir::ItemKind::Impl(&hir::Impl { generics, .. }) => {
521530
// These kinds of items have only early-bound lifetime parameters.
522-
let bound_vars = generics
523-
.params
524-
.iter()
525-
.filter_map(|param| match param.kind {
526-
GenericParamKind::Lifetime { .. } => Some(ResolvedArg::early(param)),
527-
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
528-
})
529-
.collect();
531+
let bound_vars = generics.params.iter().map(ResolvedArg::early).collect();
530532
self.record_late_bound_vars(item.hir_id(), vec![]);
531533
let scope = Scope::Binder {
532534
hir_id: item.hir_id(),
@@ -568,11 +570,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
568570
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = c
569571
.generic_params
570572
.iter()
571-
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
572573
.enumerate()
573574
.map(|(late_bound_idx, param)| {
574575
let pair = ResolvedArg::late(late_bound_idx as u32, param);
575-
let r = late_region_as_bound_region(self.tcx, &pair.1);
576+
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
576577
(pair, r)
577578
})
578579
.unzip();
@@ -725,14 +726,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
725726
}
726727
Type(bounds, ty) => {
727728
let generics = &trait_item.generics;
728-
let bound_vars = generics
729-
.params
730-
.iter()
731-
.filter_map(|param| match param.kind {
732-
GenericParamKind::Lifetime { .. } => Some(ResolvedArg::early(param)),
733-
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
734-
})
735-
.collect();
729+
let bound_vars = generics.params.iter().map(ResolvedArg::early).collect();
736730
self.record_late_bound_vars(trait_item.hir_id(), vec![]);
737731
let scope = Scope::Binder {
738732
hir_id: trait_item.hir_id(),
@@ -771,14 +765,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
771765
}),
772766
Type(ty) => {
773767
let generics = &impl_item.generics;
774-
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = generics
775-
.params
776-
.iter()
777-
.filter_map(|param| match param.kind {
778-
GenericParamKind::Lifetime { .. } => Some(ResolvedArg::early(param)),
779-
GenericParamKind::Const { .. } | GenericParamKind::Type { .. } => None,
780-
})
781-
.collect();
768+
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> =
769+
generics.params.iter().map(ResolvedArg::early).collect();
782770
self.record_late_bound_vars(impl_item.hir_id(), vec![]);
783771
let scope = Scope::Binder {
784772
hir_id: impl_item.hir_id(),
@@ -819,13 +807,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
819807
}
820808
}
821809

822-
fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
810+
fn visit_path(&mut self, path: &hir::Path<'tcx>, hir_id: hir::HirId) {
823811
for (i, segment) in path.segments.iter().enumerate() {
824812
let depth = path.segments.len() - i - 1;
825813
if let Some(args) = segment.args {
826814
self.visit_segment_args(path.res, depth, args);
827815
}
828816
}
817+
if let Res::Def(DefKind::TyParam | DefKind::ConstParam, param_def_id) = path.res {
818+
self.resolve_type_ref(param_def_id.expect_local(), hir_id);
819+
}
829820
}
830821

831822
fn visit_fn(
@@ -874,24 +865,17 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
874865
origin,
875866
..
876867
}) => {
877-
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> =
868+
869+
let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) =
878870
bound_generic_params
879-
.iter()
880-
.filter(|param| {
881-
matches!(param.kind, GenericParamKind::Lifetime { .. })
882-
})
883-
.enumerate()
884-
.map(|(late_bound_idx, param)| {
885-
ResolvedArg::late(late_bound_idx as u32, param)
886-
})
887-
.collect();
888-
let binders: Vec<_> =
889-
bound_vars
890-
.iter()
891-
.map(|(_, region)| {
892-
late_region_as_bound_region(this.tcx, region)
893-
})
894-
.collect();
871+
.iter()
872+
.enumerate()
873+
.map(|(late_bound_idx, param)| {
874+
let pair = ResolvedArg::late(late_bound_idx as u32, param);
875+
let r = late_arg_as_bound_arg(this.tcx, &pair.1, param);
876+
(pair, r)
877+
})
878+
.unzip();
895879
this.record_late_bound_vars(hir_id, binders.clone());
896880
// Even if there are no lifetimes defined here, we still wrap it in a binder
897881
// scope. If there happens to be a nested poly trait ref (an error), that
@@ -989,14 +973,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
989973

990974
let initial_bound_vars = binders.len() as u32;
991975
let mut bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = FxIndexMap::default();
992-
let binders_iter = trait_ref
993-
.bound_generic_params
994-
.iter()
995-
.filter(|param| matches!(param.kind, GenericParamKind::Lifetime { .. }))
996-
.enumerate()
997-
.map(|(late_bound_idx, param)| {
976+
let binders_iter =
977+
trait_ref.bound_generic_params.iter().enumerate().map(|(late_bound_idx, param)| {
998978
let pair = ResolvedArg::late(initial_bound_vars + late_bound_idx as u32, param);
999-
let r = late_region_as_bound_region(self.tcx, &pair.1);
979+
let r = late_arg_as_bound_arg(self.tcx, &pair.1, param);
1000980
bound_vars.insert(pair.0, pair.1);
1001981
r
1002982
});
@@ -1121,17 +1101,19 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11211101
let bound_vars: FxIndexMap<LocalDefId, ResolvedArg> = generics
11221102
.params
11231103
.iter()
1124-
.filter_map(|param| match param.kind {
1104+
.map(|param| match param.kind {
11251105
GenericParamKind::Lifetime { .. } => {
11261106
if self.tcx.is_late_bound(param.hir_id) {
11271107
let late_bound_idx = named_late_bound_vars;
11281108
named_late_bound_vars += 1;
1129-
Some(ResolvedArg::late(late_bound_idx, param))
1109+
ResolvedArg::late(late_bound_idx, param)
11301110
} else {
1131-
Some(ResolvedArg::early(param))
1111+
ResolvedArg::early(param)
11321112
}
11331113
}
1134-
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => None,
1114+
GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => {
1115+
ResolvedArg::early(param)
1116+
}
11351117
})
11361118
.collect();
11371119

@@ -1145,7 +1127,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11451127
.enumerate()
11461128
.map(|(late_bound_idx, param)| {
11471129
let pair = ResolvedArg::late(late_bound_idx as u32, param);
1148-
late_region_as_bound_region(self.tcx, &pair.1)
1130+
late_arg_as_bound_arg(self.tcx, &pair.1, param)
11491131
})
11501132
.collect();
11511133
self.record_late_bound_vars(hir_id, binders);
@@ -1182,7 +1164,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11821164
Scope::Root { opt_parent_item } => {
11831165
if let Some(parent_item) = opt_parent_item
11841166
&& let parent_generics = self.tcx.generics_of(parent_item)
1185-
&& parent_generics.param_def_id_to_index.contains_key(&region_def_id.to_def_id())
1167+
&& parent_generics.param_def_id_to_index(self.tcx, region_def_id.to_def_id()).is_some()
11861168
{
11871169
break Some(ResolvedArg::EarlyBound(region_def_id.to_def_id()));
11881170
}
@@ -1334,6 +1316,61 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
13341316
);
13351317
}
13361318

1319+
fn resolve_type_ref(&mut self, param_def_id: LocalDefId, hir_id: hir::HirId) {
1320+
// Walk up the scope chain, tracking the number of fn scopes
1321+
// that we pass through, until we find a lifetime with the
1322+
// given name or we run out of scopes.
1323+
// search.
1324+
let mut late_depth = 0;
1325+
let mut scope = self.scope;
1326+
let result = loop {
1327+
match *scope {
1328+
Scope::Body { s, .. } => {
1329+
scope = s;
1330+
}
1331+
1332+
Scope::Root { opt_parent_item } => {
1333+
if let Some(parent_item) = opt_parent_item
1334+
&& let parent_generics = self.tcx.generics_of(parent_item)
1335+
&& parent_generics.param_def_id_to_index(self.tcx, param_def_id.to_def_id()).is_some()
1336+
{
1337+
break Some(ResolvedArg::EarlyBound(param_def_id.to_def_id()));
1338+
}
1339+
break None;
1340+
}
1341+
1342+
Scope::Binder { ref bound_vars, scope_type, s, .. } => {
1343+
if let Some(&def) = bound_vars.get(&param_def_id) {
1344+
break Some(def.shifted(late_depth));
1345+
}
1346+
match scope_type {
1347+
BinderScopeType::Normal => late_depth += 1,
1348+
BinderScopeType::Concatenating => {}
1349+
}
1350+
scope = s;
1351+
}
1352+
1353+
Scope::Elision { s, .. }
1354+
| Scope::ObjectLifetimeDefault { s, .. }
1355+
| Scope::Supertrait { s, .. }
1356+
| Scope::TraitRefBoundary { s, .. } => {
1357+
scope = s;
1358+
}
1359+
}
1360+
};
1361+
1362+
if let Some(def) = result {
1363+
self.map.defs.insert(hir_id, def);
1364+
return;
1365+
}
1366+
1367+
span_bug!(
1368+
self.tcx.hir().span(hir_id),
1369+
"could not resolve {param_def_id:?}, scopes: {:#?}",
1370+
self.scope
1371+
);
1372+
}
1373+
13371374
#[instrument(level = "debug", skip(self))]
13381375
fn visit_segment_args(
13391376
&mut self,

0 commit comments

Comments
 (0)