From db32a2e4211f9444ef4f10b633e400d27ed2662e Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 10 Apr 2020 22:05:46 +0200 Subject: Implement inline associated type bounds Like `Iterator`. This is an unstable feature, but it's used in the standard library e.g. in the definition of Flatten, so we can't get away with not implementing it :) --- crates/ra_hir_def/src/path/lower.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src/path/lower.rs') diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 0f806d6fb..9ec2e0dcd 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -9,11 +9,12 @@ use hir_expand::{ hygiene::Hygiene, name::{name, AsName}, }; -use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner}; +use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; +use super::AssociatedTypeBinding; use crate::{ path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, - type_ref::TypeRef, + type_ref::{TypeBound, TypeRef}, }; pub(super) use lower_use::lower_use_tree; @@ -136,10 +137,16 @@ pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option // lifetimes ignored for now let mut bindings = Vec::new(); for assoc_type_arg in node.assoc_type_args() { + let assoc_type_arg: ast::AssocTypeArg = assoc_type_arg; if let Some(name_ref) = assoc_type_arg.name_ref() { let name = name_ref.as_name(); - let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref()); - bindings.push((name, type_ref)); + let type_ref = assoc_type_arg.type_ref().map(TypeRef::from_ast); + let bounds = if let Some(l) = assoc_type_arg.type_bound_list() { + l.bounds().map(TypeBound::from_ast).collect() + } else { + Vec::new() + }; + bindings.push(AssociatedTypeBinding { name, type_ref, bounds }); } } if args.is_empty() && bindings.is_empty() { @@ -168,7 +175,11 @@ fn lower_generic_args_from_fn_path( } if let Some(ret_type) = ret_type { let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); - bindings.push((name![Output], type_ref)) + bindings.push(AssociatedTypeBinding { + name: name![Output], + type_ref: Some(type_ref), + bounds: Vec::new(), + }); } if args.is_empty() && bindings.is_empty() { None -- cgit v1.2.3