mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-18 18:53:04 +00:00
handle nested generics in Generics::type_param/region_param
Fixes #44952.
This commit is contained in:
parent
0defa208dc
commit
622a78cd54
@ -795,7 +795,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
// Account for the case where `did` corresponds to `Self`, which doesn't have
|
||||
// the expected type argument.
|
||||
if generics.types.len() > 0 {
|
||||
let type_param = generics.type_param(param);
|
||||
let type_param = generics.type_param(param, self.tcx);
|
||||
let hir = &self.tcx.hir;
|
||||
hir.as_local_node_id(type_param.def_id).map(|id| {
|
||||
// Get the `hir::TyParam` to verify wether it already has any bounds.
|
||||
|
@ -729,7 +729,7 @@ pub struct Generics {
|
||||
pub has_late_bound_regions: Option<Span>,
|
||||
}
|
||||
|
||||
impl Generics {
|
||||
impl<'a, 'gcx, 'tcx> Generics {
|
||||
pub fn parent_count(&self) -> usize {
|
||||
self.parent_regions as usize + self.parent_types as usize
|
||||
}
|
||||
@ -742,14 +742,28 @@ impl Generics {
|
||||
self.parent_count() + self.own_count()
|
||||
}
|
||||
|
||||
pub fn region_param(&self, param: &EarlyBoundRegion) -> &RegionParameterDef {
|
||||
assert_eq!(self.parent_count(), 0);
|
||||
&self.regions[param.index as usize - self.has_self as usize]
|
||||
pub fn region_param(&'tcx self,
|
||||
param: &EarlyBoundRegion,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||
-> &'tcx RegionParameterDef
|
||||
{
|
||||
if let Some(index) = param.index.checked_sub(self.parent_count() as u32) {
|
||||
&self.regions[index as usize - self.has_self as usize]
|
||||
} else {
|
||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
||||
.region_param(param, tcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_param(&self, param: &ParamTy) -> &TypeParameterDef {
|
||||
assert_eq!(self.parent_count(), 0);
|
||||
&self.types[param.idx as usize - self.has_self as usize - self.regions.len()]
|
||||
pub fn type_param(&'tcx self,
|
||||
param: &ParamTy,
|
||||
tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &TypeParameterDef {
|
||||
if let Some(idx) = param.idx.checked_sub(self.parent_count() as u32) {
|
||||
&self.types[idx as usize - self.has_self as usize - self.regions.len()]
|
||||
} else {
|
||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
||||
.type_param(param, tcx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -515,11 +515,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
let result = item_substs.iter().zip(impl_substs.iter())
|
||||
.filter(|&(_, &k)| {
|
||||
if let Some(&ty::RegionKind::ReEarlyBound(ref ebr)) = k.as_region() {
|
||||
!impl_generics.region_param(ebr).pure_wrt_drop
|
||||
!impl_generics.region_param(ebr, self).pure_wrt_drop
|
||||
} else if let Some(&ty::TyS {
|
||||
sty: ty::TypeVariants::TyParam(ref pt), ..
|
||||
}) = k.as_type() {
|
||||
!impl_generics.type_param(pt).pure_wrt_drop
|
||||
!impl_generics.type_param(pt, self).pure_wrt_drop
|
||||
} else {
|
||||
// not a type or region param - this should be reported
|
||||
// as an error.
|
||||
|
@ -28,4 +28,14 @@ struct Foo<T> {
|
||||
foo: &'static T
|
||||
}
|
||||
|
||||
trait X<T> {}
|
||||
|
||||
struct Nested<K>(K);
|
||||
impl<K> Nested<K> {
|
||||
fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
|
||||
}
|
||||
fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -26,5 +26,38 @@ note: ...so that the reference type `&'static T` does not outlive the data it po
|
||||
28 | foo: &'static T
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0309]: the parameter type `K` may not live long enough
|
||||
--> $DIR/lifetime-doesnt-live-long-enough.rs:35:5
|
||||
|
|
||||
34 | impl<K> Nested<K> {
|
||||
| - help: consider adding an explicit lifetime bound `K: 'a`...
|
||||
35 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
|
||||
36 | | }
|
||||
| |_____^
|
||||
|
|
||||
note: ...so that the reference type `&'a Nested<K>` does not outlive the data it points at
|
||||
--> $DIR/lifetime-doesnt-live-long-enough.rs:35:5
|
||||
|
|
||||
35 | / fn generic_in_parent<'a, L: X<&'a Nested<K>>>() {
|
||||
36 | | }
|
||||
| |_____^
|
||||
|
||||
error[E0309]: the parameter type `M` may not live long enough
|
||||
--> $DIR/lifetime-doesnt-live-long-enough.rs:37:5
|
||||
|
|
||||
37 | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
|
||||
| ^ -- help: consider adding an explicit lifetime bound `M: 'a`...
|
||||
| _____|
|
||||
| |
|
||||
38 | | }
|
||||
| |_____^
|
||||
|
|
||||
note: ...so that the reference type `&'a Nested<M>` does not outlive the data it points at
|
||||
--> $DIR/lifetime-doesnt-live-long-enough.rs:37:5
|
||||
|
|
||||
37 | / fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() {
|
||||
38 | | }
|
||||
| |_____^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user