mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 06:11:35 +00:00
Handle associated type shorthand (T::Item
)
This is only allowed for generic parameters (including `Self` in traits), and special care needs to be taken to not run into cycles while resolving it, because we use the where clauses of the generic parameter to find candidates for the trait containing the associated type, but the where clauses may themselves contain instances of short-hand associated types. In some cases this is even fine, e.g. we might have `T: Trait<U::Item>, U: Iterator`. If there is a cycle, we'll currently panic, which isn't great, but better than overflowing the stack...
This commit is contained in:
parent
468e1d14c1
commit
18bf278c25
7 changed files with 538 additions and 392 deletions
|
@ -26,8 +26,9 @@ pub struct GenericParam {
|
|||
}
|
||||
|
||||
/// Data about the generic parameters of a function, struct, impl, etc.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Default)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct GenericParams {
|
||||
pub(crate) def: GenericDef,
|
||||
pub(crate) parent_params: Option<Arc<GenericParams>>,
|
||||
pub(crate) params: Vec<GenericParam>,
|
||||
pub(crate) where_predicates: Vec<WherePredicate>,
|
||||
|
@ -69,7 +70,6 @@ impl GenericParams {
|
|||
db: &(impl DefDatabase + AstDatabase),
|
||||
def: GenericDef,
|
||||
) -> Arc<GenericParams> {
|
||||
let mut generics = GenericParams::default();
|
||||
let parent = match def {
|
||||
GenericDef::Function(it) => it.container(db).map(GenericDef::from),
|
||||
GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from),
|
||||
|
@ -77,7 +77,12 @@ impl GenericParams {
|
|||
GenericDef::Adt(_) | GenericDef::Trait(_) => None,
|
||||
GenericDef::ImplBlock(_) => None,
|
||||
};
|
||||
generics.parent_params = parent.map(|p| db.generic_params(p));
|
||||
let mut generics = GenericParams {
|
||||
def,
|
||||
params: Vec::new(),
|
||||
parent_params: parent.map(|p| db.generic_params(p)),
|
||||
where_predicates: Vec::new(),
|
||||
};
|
||||
let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32;
|
||||
// FIXME: add `: Sized` bound for everything except for `Self` in traits
|
||||
match def {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue