Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/path.rs4
-rw-r--r--crates/hir-def/src/path/lower.rs33
-rw-r--r--crates/hir-def/src/type_ref.rs2
-rw-r--r--crates/hir-ty/src/display.rs2
4 files changed, 26 insertions, 15 deletions
diff --git a/crates/hir-def/src/path.rs b/crates/hir-def/src/path.rs
index 0ebc5c9562..36d4c36a26 100644
--- a/crates/hir-def/src/path.rs
+++ b/crates/hir-def/src/path.rs
@@ -49,7 +49,7 @@ pub struct Path {
/// also includes bindings of associated types, like in `Iterator<Item = Foo>`.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericArgs {
- pub args: Vec<GenericArg>,
+ pub args: Box<[GenericArg]>,
/// This specifies whether the args contain a Self type as the first
/// element. This is the case for path segments like `<T as Trait>`, where
/// `T` is actually a type parameter for the path `Trait` specifying the
@@ -212,7 +212,7 @@ impl GenericArgs {
pub(crate) fn empty() -> GenericArgs {
GenericArgs {
- args: Vec::new(),
+ args: Box::default(),
has_self_type: false,
bindings: Box::default(),
desugared_from_fn: false,
diff --git a/crates/hir-def/src/path/lower.rs b/crates/hir-def/src/path/lower.rs
index e82f6b786d..c85a11db6d 100644
--- a/crates/hir-def/src/path/lower.rs
+++ b/crates/hir-def/src/path/lower.rs
@@ -1,5 +1,7 @@
//! Transforms syntax into `Path` objects, ideally with accounting for hygiene
+use std::iter;
+
use crate::type_ref::ConstScalarOrPath;
use either::Either;
@@ -86,15 +88,26 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
generic_args.resize(segments.len(), None);
}
+ let self_type = GenericArg::Type(self_type);
+
// Insert the type reference (T in the above example) as Self parameter for the trait
let last_segment = generic_args.get_mut(segments.len() - num_segments)?;
- let mut args_inner = match last_segment {
- Some(it) => it.as_ref().clone(),
- None => GenericArgs::empty(),
- };
- args_inner.has_self_type = true;
- args_inner.args.insert(0, GenericArg::Type(self_type));
- *last_segment = Some(Interned::new(args_inner));
+ *last_segment = Some(Interned::new(match last_segment.take() {
+ Some(it) => GenericArgs {
+ args: iter::once(self_type)
+ .chain(it.args.iter().cloned())
+ .collect(),
+
+ has_self_type: true,
+ bindings: it.bindings.clone(),
+ desugared_from_fn: it.desugared_from_fn,
+ },
+ None => GenericArgs {
+ args: Box::new([self_type]),
+ has_self_type: true,
+ ..GenericArgs::empty()
+ },
+ }));
}
}
}
@@ -209,7 +222,7 @@ pub(super) fn lower_generic_args(
return None;
}
Some(GenericArgs {
- args,
+ args: args.into_boxed_slice(),
has_self_type: false,
bindings: bindings.into_boxed_slice(),
desugared_from_fn: false,
@@ -223,15 +236,13 @@ fn lower_generic_args_from_fn_path(
params: Option<ast::ParamList>,
ret_type: Option<ast::RetType>,
) -> Option<GenericArgs> {
- let mut args = Vec::new();
let params = params?;
let mut param_types = Vec::new();
for param in params.params() {
let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
param_types.push(type_ref);
}
- let arg = GenericArg::Type(TypeRef::Tuple(param_types));
- args.push(arg);
+ let args = Box::new([GenericArg::Type(TypeRef::Tuple(param_types))]);
let bindings = if let Some(ret_type) = ret_type {
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
Box::new([AssociatedTypeBinding {
diff --git a/crates/hir-def/src/type_ref.rs b/crates/hir-def/src/type_ref.rs
index 7f3c315480..9652b01b91 100644
--- a/crates/hir-def/src/type_ref.rs
+++ b/crates/hir-def/src/type_ref.rs
@@ -292,7 +292,7 @@ impl TypeRef {
}
for segment in path.segments().iter() {
if let Some(args_and_bindings) = segment.args_and_bindings {
- for arg in &args_and_bindings.args {
+ for arg in args_and_bindings.args.iter() {
match arg {
crate::path::GenericArg::Type(type_ref) => {
go(type_ref, f);
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index 3390c7b1e5..b22064d8c4 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -1419,7 +1419,7 @@ impl HirDisplay for Path {
write!(f, "<")?;
let mut first = true;
- for arg in &generic_args.args {
+ for arg in generic_args.args.iter() {
if first {
first = false;
if generic_args.has_self_type {