Skip to content

Commit c5eaf59

Browse files
committed
Auto merge of rust-lang#17175 - Veykril:fix-implicit-ty-args, r=Veykril
fix: Fix implicit ty args being lowered where they shouldn't Fixes rust-lang/rust-analyzer#17173
2 parents 675197a + f190ce6 commit c5eaf59

File tree

4 files changed

+116
-120
lines changed

4 files changed

+116
-120
lines changed

src/tools/rust-analyzer/crates/hir-def/src/generics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ impl GenericParamsCollector {
377377
}
378378
}
379379

380-
pub(crate) fn fill_implicit_impl_trait_args(
380+
fn fill_implicit_impl_trait_args(
381381
&mut self,
382382
db: &dyn DefDatabase,
383383
exp: &mut Lazy<(Arc<DefMap>, Expander), impl FnOnce() -> (Arc<DefMap>, Expander)>,

src/tools/rust-analyzer/crates/hir-def/src/item_tree/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ impl<'a> Ctx<'a> {
662662
let attrs = RawAttrs::new(self.db.upcast(), &param, self.body_ctx.span_map());
663663
debug_assert!(self.generic_param_attr_buffer.insert(item, attrs).is_none());
664664
};
665-
665+
self.body_ctx.take_impl_traits_bounds();
666666
let mut generics = GenericParamsCollector::default();
667667

668668
if let HasImplicitSelf::Yes(bounds) = has_implicit_self {

src/tools/rust-analyzer/crates/hir-ty/src/lower.rs

Lines changed: 93 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -345,51 +345,43 @@ impl<'a> TyLoweringContext<'a> {
345345
}
346346
ImplTraitLoweringState::Param(counter) => {
347347
let idx = counter.get();
348-
// FIXME we're probably doing something wrong here
349-
counter.set(idx + count_impl_traits(type_ref) as u16);
350-
if let Some(generics) = self.generics() {
351-
let param = generics
352-
.iter()
353-
.filter(|(_, data)| {
354-
matches!(
355-
data,
356-
GenericParamDataRef::TypeParamData(data)
357-
if data.provenance == TypeParamProvenance::ArgumentImplTrait
358-
)
359-
})
360-
.nth(idx as usize)
361-
.map_or(TyKind::Error, |(id, _)| {
362-
if let GenericParamId::TypeParamId(id) = id {
363-
TyKind::Placeholder(to_placeholder_idx(self.db, id.into()))
364-
} else {
365-
// we just filtered them out
366-
unreachable!("Unexpected lifetime or const argument");
367-
}
368-
});
369-
param.intern(Interner)
370-
} else {
371-
TyKind::Error.intern(Interner)
372-
}
348+
counter.set(idx + 1);
349+
let kind = self
350+
.generics()
351+
.expect("param impl trait lowering must be in a generic def")
352+
.iter()
353+
.filter_map(|(id, data)| match (id, data) {
354+
(
355+
GenericParamId::TypeParamId(id),
356+
GenericParamDataRef::TypeParamData(data),
357+
) if data.provenance == TypeParamProvenance::ArgumentImplTrait => {
358+
Some(id)
359+
}
360+
_ => None,
361+
})
362+
.nth(idx as usize)
363+
.map_or(TyKind::Error, |id| {
364+
TyKind::Placeholder(to_placeholder_idx(self.db, id.into()))
365+
});
366+
kind.intern(Interner)
373367
}
374368
ImplTraitLoweringState::Variable(counter) => {
375369
let idx = counter.get();
376-
// FIXME we're probably doing something wrong here
377-
counter.set(idx + count_impl_traits(type_ref) as u16);
370+
counter.set(idx + 1);
378371
let (
379372
_parent_params,
380373
self_params,
381-
list_params,
374+
type_params,
382375
const_params,
383376
_impl_trait_params,
384377
_lifetime_params,
385-
) = if let Some(generics) = self.generics() {
386-
generics.provenance_split()
387-
} else {
388-
(0, 0, 0, 0, 0, 0)
389-
};
378+
) = self
379+
.generics()
380+
.expect("variable impl trait lowering must be in a generic def")
381+
.provenance_split();
390382
TyKind::BoundVar(BoundVar::new(
391383
self.in_binders,
392-
idx as usize + self_params + list_params + const_params,
384+
idx as usize + self_params + type_params + const_params,
393385
))
394386
.intern(Interner)
395387
}
@@ -1150,84 +1142,77 @@ impl<'a> TyLoweringContext<'a> {
11501142
binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
11511143
);
11521144
if let Some(type_ref) = &binding.type_ref {
1153-
if let (
1154-
TypeRef::ImplTrait(bounds),
1155-
ImplTraitLoweringState::Param(_)
1156-
| ImplTraitLoweringState::Variable(_)
1157-
| ImplTraitLoweringState::Disallowed,
1158-
) = (type_ref, &self.impl_trait_mode)
1159-
{
1160-
for bound in bounds {
1161-
predicates.extend(
1162-
self.lower_type_bound(
1163-
bound,
1164-
TyKind::Alias(AliasTy::Projection(projection_ty.clone()))
1165-
.intern(Interner),
1166-
false,
1167-
),
1168-
);
1145+
match (type_ref, &self.impl_trait_mode) {
1146+
(TypeRef::ImplTrait(_), ImplTraitLoweringState::Disallowed) => (),
1147+
(
1148+
_,
1149+
ImplTraitLoweringState::Disallowed | ImplTraitLoweringState::Opaque(_),
1150+
) => {
1151+
let ty = self.lower_ty(type_ref);
1152+
let alias_eq =
1153+
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
1154+
predicates
1155+
.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
11691156
}
1170-
} else {
1171-
let ty = 'ty: {
1172-
if matches!(
1173-
self.impl_trait_mode,
1174-
ImplTraitLoweringState::Param(_)
1175-
| ImplTraitLoweringState::Variable(_)
1176-
) {
1177-
// Find the generic index for the target of our `bound`
1178-
let target_param_idx = self
1179-
.resolver
1180-
.where_predicates_in_scope()
1181-
.find_map(|(p, _)| match p {
1182-
WherePredicate::TypeBound {
1183-
target: WherePredicateTypeTarget::TypeOrConstParam(idx),
1184-
bound: b,
1185-
} if b == bound => Some(idx),
1186-
_ => None,
1187-
});
1188-
if let Some(target_param_idx) = target_param_idx {
1189-
let mut counter = 0;
1190-
let generics = self.generics().expect("generics in scope");
1191-
for (idx, data) in generics.params.type_or_consts.iter() {
1192-
// Count the number of `impl Trait` things that appear before
1193-
// the target of our `bound`.
1194-
// Our counter within `impl_trait_mode` should be that number
1195-
// to properly lower each types within `type_ref`
1196-
if data.type_param().is_some_and(|p| {
1197-
p.provenance == TypeParamProvenance::ArgumentImplTrait
1198-
}) {
1199-
counter += 1;
1200-
}
1201-
if idx == *target_param_idx {
1202-
break;
1203-
}
1157+
(
1158+
_,
1159+
ImplTraitLoweringState::Param(_) | ImplTraitLoweringState::Variable(_),
1160+
) => {
1161+
// Find the generic index for the target of our `bound`
1162+
let target_param_idx = self
1163+
.resolver
1164+
.where_predicates_in_scope()
1165+
.find_map(|(p, _)| match p {
1166+
WherePredicate::TypeBound {
1167+
target: WherePredicateTypeTarget::TypeOrConstParam(idx),
1168+
bound: b,
1169+
} if b == bound => Some(idx),
1170+
_ => None,
1171+
});
1172+
let ty = if let Some(target_param_idx) = target_param_idx {
1173+
let mut counter = 0;
1174+
let generics = self.generics().expect("generics in scope");
1175+
for (idx, data) in generics.params.type_or_consts.iter() {
1176+
// Count the number of `impl Trait` things that appear before
1177+
// the target of our `bound`.
1178+
// Our counter within `impl_trait_mode` should be that number
1179+
// to properly lower each types within `type_ref`
1180+
if data.type_param().is_some_and(|p| {
1181+
p.provenance == TypeParamProvenance::ArgumentImplTrait
1182+
}) {
1183+
counter += 1;
12041184
}
1205-
let mut ext = TyLoweringContext::new_maybe_unowned(
1206-
self.db,
1207-
self.resolver,
1208-
self.owner,
1209-
)
1210-
.with_type_param_mode(self.type_param_mode);
1211-
match &self.impl_trait_mode {
1212-
ImplTraitLoweringState::Param(_) => {
1213-
ext.impl_trait_mode =
1214-
ImplTraitLoweringState::Param(Cell::new(counter));
1215-
}
1216-
ImplTraitLoweringState::Variable(_) => {
1217-
ext.impl_trait_mode = ImplTraitLoweringState::Variable(
1218-
Cell::new(counter),
1219-
);
1220-
}
1221-
_ => unreachable!(),
1185+
if idx == *target_param_idx {
1186+
break;
12221187
}
1223-
break 'ty ext.lower_ty(type_ref);
12241188
}
1225-
}
1226-
self.lower_ty(type_ref)
1227-
};
1228-
let alias_eq =
1229-
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
1230-
predicates.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
1189+
let mut ext = TyLoweringContext::new_maybe_unowned(
1190+
self.db,
1191+
self.resolver,
1192+
self.owner,
1193+
)
1194+
.with_type_param_mode(self.type_param_mode);
1195+
match &self.impl_trait_mode {
1196+
ImplTraitLoweringState::Param(_) => {
1197+
ext.impl_trait_mode =
1198+
ImplTraitLoweringState::Param(Cell::new(counter));
1199+
}
1200+
ImplTraitLoweringState::Variable(_) => {
1201+
ext.impl_trait_mode =
1202+
ImplTraitLoweringState::Variable(Cell::new(counter));
1203+
}
1204+
_ => unreachable!(),
1205+
}
1206+
ext.lower_ty(type_ref)
1207+
} else {
1208+
self.lower_ty(type_ref)
1209+
};
1210+
1211+
let alias_eq =
1212+
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
1213+
predicates
1214+
.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
1215+
}
12311216
}
12321217
}
12331218
for bound in binding.bounds.iter() {
@@ -1394,16 +1379,6 @@ impl<'a> TyLoweringContext<'a> {
13941379
}
13951380
}
13961381

1397-
fn count_impl_traits(type_ref: &TypeRef) -> usize {
1398-
let mut count = 0;
1399-
type_ref.walk(&mut |type_ref| {
1400-
if matches!(type_ref, TypeRef::ImplTrait(_)) {
1401-
count += 1;
1402-
}
1403-
});
1404-
count
1405-
}
1406-
14071382
/// Build the signature of a callable item (function, struct or enum variant).
14081383
pub(crate) fn callable_item_sig(db: &dyn HirDatabase, def: CallableDefId) -> PolyFnSig {
14091384
match def {

src/tools/rust-analyzer/crates/hir-ty/src/tests/regression.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1975,3 +1975,24 @@ impl<#[cfg(feature = "a-feature")] A> Bar for (){}
19751975
"#,
19761976
)
19771977
}
1978+
1979+
#[test]
1980+
fn nested_anon_generics_and_where_bounds_17173() {
1981+
check_types(
1982+
r#"
1983+
//- minicore: sized
1984+
pub trait Lookup {
1985+
type Data;
1986+
fn lookup(&self) -> Self::Data;
1987+
}
1988+
pub trait ItemTreeLoc {
1989+
type Id;
1990+
}
1991+
fn id_to_generics(id: impl Lookup<Data = impl ItemTreeLoc<Id = ()>>)
1992+
//^^ impl Lookup<Data = impl ItemTreeLoc<Id = ()>>
1993+
where
1994+
(): Sized,
1995+
{}
1996+
"#,
1997+
);
1998+
}

0 commit comments

Comments
 (0)