Skip to content

Commit 1686871

Browse files
committed
fix: idx and type of lifetimes captured by opaque
1 parent 40d8557 commit 1686871

6 files changed

Lines changed: 48 additions & 32 deletions

File tree

crates/hir-def/src/hir/generics.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,10 @@ impl GenericParams {
306306

307307
#[inline]
308308
pub fn len_late_bound_lifetimes(&self) -> usize {
309-
self.lifetimes.iter().filter(|(_, p)| p.bound_type == LifetimeBoundType::LateBound).count()
309+
self.lifetimes
310+
.iter()
311+
.filter(|(_, p)| !p.is_opaque_captured && p.bound_type == LifetimeBoundType::LateBound)
312+
.count()
310313
}
311314

312315
#[inline]
@@ -409,18 +412,24 @@ impl GenericParams {
409412
pub fn late_bound_lifetime_idx(
410413
&self,
411414
lifetime_param_id: &LocalLifetimeParamId,
415+
is_opaque_lowering: bool,
412416
) -> Option<usize> {
413417
self.iter_late_bound_lt().position(|(id, data)| {
414-
data.bound_type == LifetimeBoundType::LateBound && id == *lifetime_param_id
418+
!(is_opaque_lowering && data.is_opaque_captured)
419+
&& data.bound_type == LifetimeBoundType::LateBound
420+
&& id == *lifetime_param_id
415421
})
416422
}
417423

418424
pub fn early_bound_lifetime_idx(
419425
&self,
420426
lifetime_param_id: &LocalLifetimeParamId,
427+
is_opaque_lowering: bool,
421428
) -> Option<usize> {
422429
self.iter_early_bound_lt().position(|(id, data)| {
423-
data.bound_type == LifetimeBoundType::EarlyBound && id == *lifetime_param_id
430+
((is_opaque_lowering && data.is_opaque_captured)
431+
|| data.bound_type == LifetimeBoundType::EarlyBound)
432+
&& id == *lifetime_param_id
424433
})
425434
}
426435
}

crates/hir-ty/src/generics.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,19 @@ impl<'db> Generics<'db> {
295295
}
296296

297297
// Rename this?
298-
pub(crate) fn lifetime_param_idx(&self, param: LifetimeParamId) -> (u32, bool) {
298+
pub(crate) fn lifetime_param_idx(
299+
&self,
300+
param: LifetimeParamId,
301+
is_opaque_lowering: bool,
302+
) -> (u32, bool) {
299303
let owner = self.find_owner(param.parent);
300-
if let Some(late_bound_idx) = owner.params.late_bound_lifetime_idx(&param.local_id) {
304+
if let Some(late_bound_idx) =
305+
owner.params.late_bound_lifetime_idx(&param.local_id, is_opaque_lowering)
306+
{
301307
return (late_bound_idx as u32, true);
302308
}
303309
let has_trait_self = matches!(owner.def, GenericDefId::TraitId(_));
304-
match owner.params.early_bound_lifetime_idx(&param.local_id) {
310+
match owner.params.early_bound_lifetime_idx(&param.local_id, is_opaque_lowering) {
305311
Some(idx) => {
306312
(owner.preceding_params_len + u32::from(has_trait_self) + (idx as u32), false)
307313
}

crates/hir-ty/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ pub fn type_or_const_param_idx(db: &dyn HirDatabase, id: TypeOrConstParamId) ->
220220
}
221221

222222
pub fn lifetime_param_idx(db: &dyn HirDatabase, id: LifetimeParamId) -> u32 {
223-
generics::generics(db, id.parent).lifetime_param_idx(id).0
223+
generics::generics(db, id.parent).lifetime_param_idx(id, false).0
224224
}
225225

226226
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]

crates/hir-ty/src/lower.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
238238
let impl_trait_mode = ImplTraitLoweringState::new(ImplTraitLoweringMode::Disallowed);
239239
let in_binders = DebruijnIndex::ZERO;
240240
let interner = DbInterner::new_with(db, resolver.krate());
241-
let bound_vars = Vec::from(&[Self::bound_vars(db, interner, generic_def.into())]);
241+
let bound_vars = Vec::from(&[Self::bound_vars(db, interner, generic_def)]);
242242
Self {
243243
db,
244244
// Can provide no block since we don't use it for trait solving.
@@ -1195,7 +1195,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> {
11951195
Some(resolution) => match resolution {
11961196
LifetimeNs::Static => Region::new_static(self.interner),
11971197
LifetimeNs::LifetimeParam(id) => {
1198-
let (idx, is_late_bound) = self.generics().lifetime_param_idx(id);
1198+
let is_opaque_lowering =
1199+
self.impl_trait_mode.mode == ImplTraitLoweringMode::Opaque;
1200+
let (idx, is_late_bound) =
1201+
self.generics().lifetime_param_idx(id, is_opaque_lowering);
11991202
self.region_param(id, idx, is_late_bound)
12001203
}
12011204
},

crates/hir-ty/src/tests/simple.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4305,22 +4305,3 @@ enum Enum {
43054305
"#]],
43064306
);
43074307
}
4308-
4309-
#[test]
4310-
fn rpit_with_lifetimes() {
4311-
check_infer(
4312-
r#"
4313-
struct Event<'a> {};
4314-
struct Range<T> {}
4315-
trait Iterator {
4316-
type Item;
4317-
}
4318-
4319-
struct Vec<T> {}
4320-
4321-
fn foo<'e>(events: &'e mut dyn Iterator<Item = (Event<'e>, Range<usize>)>) -> impl Iterator<Item = Event<'e>> {
4322-
4323-
}"#,
4324-
expect![[r#""#]],
4325-
);
4326-
}

crates/hir-ty/src/tests/traits.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,10 +1634,10 @@ fn test<'lifetime>(
16341634
) {}
16351635
"#,
16361636
expect![[r#"
1637-
39..40 'a': impl Trait + '?0.0
1638-
70..71 'b': impl '?0.0
1637+
39..40 'a': impl Trait + 'lifetime
1638+
70..71 'b': impl 'lifetime
16391639
93..94 'c': impl Trait
1640-
114..115 'd': impl '?0.0
1640+
114..115 'd': impl 'lifetime
16411641
139..140 'e': impl ?Sized
16421642
159..160 'f': impl Trait + ?Sized
16431643
184..186 '{}': ()
@@ -4875,14 +4875,31 @@ fn allowed3(baz: impl Baz<Assoc = Qux<impl Foo>>) {}
48754875
431..433 '{}': ()
48764876
447..450 'baz': impl Baz<Assoc = impl Foo>
48774877
480..482 '{}': ()
4878-
500..503 'baz': impl Baz<Assoc = &'?0.0 (impl Foo + '?0.0)>
4878+
500..503 'baz': impl Baz<Assoc = &'a (impl Foo + 'a)>
48794879
544..546 '{}': ()
48804880
560..563 'baz': impl Baz<Assoc = Qux<impl Foo>>
48814881
598..600 '{}': ()
48824882
"#]],
48834883
)
48844884
}
48854885

4886+
#[test]
4887+
fn rpit_with_lifetimes() {
4888+
check_no_mismatches(
4889+
r#"
4890+
struct Event<'a> {};
4891+
struct Range<T> {}
4892+
trait Iterator {
4893+
type Item;
4894+
}
4895+
4896+
struct Vec<T> {}
4897+
4898+
fn foo<'e>(events: &'e mut dyn Iterator<Item = (Event<'e>, Range<usize>)>) -> impl Iterator<Item = Event<'e>> {}
4899+
"#,
4900+
);
4901+
}
4902+
48864903
#[test]
48874904
fn recursive_tail_sized() {
48884905
check_infer(

0 commit comments

Comments
 (0)