Auto merge of #14152 - Veykril:path-opt, r=Veykril

Replace some often empty `Vec`s with boxed slices
This commit is contained in:
bors 2023-02-14 16:58:58 +00:00
commit 37608f306c
7 changed files with 55 additions and 39 deletions

View file

@ -659,15 +659,16 @@ fn desugar_future_path(orig: TypeRef) -> Path {
let path = path![core::future::Future]; let path = path![core::future::Future];
let mut generic_args: Vec<_> = let mut generic_args: Vec<_> =
std::iter::repeat(None).take(path.segments().len() - 1).collect(); std::iter::repeat(None).take(path.segments().len() - 1).collect();
let mut last = GenericArgs::empty();
let binding = AssociatedTypeBinding { let binding = AssociatedTypeBinding {
name: name![Output], name: name![Output],
args: None, args: None,
type_ref: Some(orig), type_ref: Some(orig),
bounds: Vec::new(), bounds: Box::default(),
}; };
last.bindings.push(binding); generic_args.push(Some(Interned::new(GenericArgs {
generic_args.push(Some(Interned::new(last))); bindings: Box::new([binding]),
..GenericArgs::empty()
})));
Path::from_known_path(path, generic_args) Path::from_known_path(path, generic_args)
} }

View file

@ -49,7 +49,7 @@ pub struct Path {
/// also includes bindings of associated types, like in `Iterator<Item = Foo>`. /// also includes bindings of associated types, like in `Iterator<Item = Foo>`.
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct GenericArgs { pub struct GenericArgs {
pub args: Vec<GenericArg>, pub args: Box<[GenericArg]>,
/// This specifies whether the args contain a Self type as the first /// 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 /// 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 /// `T` is actually a type parameter for the path `Trait` specifying the
@ -57,7 +57,7 @@ pub struct GenericArgs {
/// is left out. /// is left out.
pub has_self_type: bool, pub has_self_type: bool,
/// Associated type bindings like in `Iterator<Item = T>`. /// Associated type bindings like in `Iterator<Item = T>`.
pub bindings: Vec<AssociatedTypeBinding>, pub bindings: Box<[AssociatedTypeBinding]>,
/// Whether these generic args were desugared from `Trait(Arg) -> Output` /// Whether these generic args were desugared from `Trait(Arg) -> Output`
/// parenthesis notation typically used for the `Fn` traits. /// parenthesis notation typically used for the `Fn` traits.
pub desugared_from_fn: bool, pub desugared_from_fn: bool,
@ -77,7 +77,7 @@ pub struct AssociatedTypeBinding {
/// Bounds for the associated type, like in `Iterator<Item: /// Bounds for the associated type, like in `Iterator<Item:
/// SomeOtherTrait>`. (This is the unstable `associated_type_bounds` /// SomeOtherTrait>`. (This is the unstable `associated_type_bounds`
/// feature.) /// feature.)
pub bounds: Vec<Interned<TypeBound>>, pub bounds: Box<[Interned<TypeBound>]>,
} }
/// A single generic argument. /// A single generic argument.
@ -212,9 +212,9 @@ impl GenericArgs {
pub(crate) fn empty() -> GenericArgs { pub(crate) fn empty() -> GenericArgs {
GenericArgs { GenericArgs {
args: Vec::new(), args: Box::default(),
has_self_type: false, has_self_type: false,
bindings: Vec::new(), bindings: Box::default(),
desugared_from_fn: false, desugared_from_fn: false,
} }
} }

View file

@ -1,5 +1,7 @@
//! Transforms syntax into `Path` objects, ideally with accounting for hygiene //! Transforms syntax into `Path` objects, ideally with accounting for hygiene
use std::iter;
use crate::type_ref::ConstScalarOrPath; use crate::type_ref::ConstScalarOrPath;
use either::Either; 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); 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 // 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 last_segment = generic_args.get_mut(segments.len() - num_segments)?;
let mut args_inner = match last_segment { *last_segment = Some(Interned::new(match last_segment.take() {
Some(it) => it.as_ref().clone(), Some(it) => GenericArgs {
None => GenericArgs::empty(), args: iter::once(self_type)
}; .chain(it.args.iter().cloned())
args_inner.has_self_type = true; .collect(),
args_inner.args.insert(0, GenericArg::Type(self_type));
*last_segment = Some(Interned::new(args_inner)); 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()
},
}));
} }
} }
} }
@ -187,7 +200,7 @@ pub(super) fn lower_generic_args(
.map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it))) .map(|it| Interned::new(TypeBound::from_ast(lower_ctx, it)))
.collect() .collect()
} else { } else {
Vec::new() Box::default()
}; };
bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds }); bindings.push(AssociatedTypeBinding { name, args, type_ref, bounds });
} }
@ -208,7 +221,12 @@ pub(super) fn lower_generic_args(
if args.is_empty() && bindings.is_empty() { if args.is_empty() && bindings.is_empty() {
return None; return None;
} }
Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: false }) Some(GenericArgs {
args: args.into_boxed_slice(),
has_self_type: false,
bindings: bindings.into_boxed_slice(),
desugared_from_fn: false,
})
} }
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
@ -218,33 +236,30 @@ fn lower_generic_args_from_fn_path(
params: Option<ast::ParamList>, params: Option<ast::ParamList>,
ret_type: Option<ast::RetType>, ret_type: Option<ast::RetType>,
) -> Option<GenericArgs> { ) -> Option<GenericArgs> {
let mut args = Vec::new();
let mut bindings = Vec::new();
let params = params?; let params = params?;
let mut param_types = Vec::new(); let mut param_types = Vec::new();
for param in params.params() { for param in params.params() {
let type_ref = TypeRef::from_ast_opt(ctx, param.ty()); let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
param_types.push(type_ref); param_types.push(type_ref);
} }
let arg = GenericArg::Type(TypeRef::Tuple(param_types)); let args = Box::new([GenericArg::Type(TypeRef::Tuple(param_types))]);
args.push(arg); let bindings = if let Some(ret_type) = ret_type {
if let Some(ret_type) = ret_type {
let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty()); let type_ref = TypeRef::from_ast_opt(ctx, ret_type.ty());
bindings.push(AssociatedTypeBinding { Box::new([AssociatedTypeBinding {
name: name![Output], name: name![Output],
args: None, args: None,
type_ref: Some(type_ref), type_ref: Some(type_ref),
bounds: Vec::new(), bounds: Box::default(),
}); }])
} else { } else {
// -> () // -> ()
let type_ref = TypeRef::Tuple(Vec::new()); let type_ref = TypeRef::Tuple(Vec::new());
bindings.push(AssociatedTypeBinding { Box::new([AssociatedTypeBinding {
name: name![Output], name: name![Output],
args: None, args: None,
type_ref: Some(type_ref), type_ref: Some(type_ref),
bounds: Vec::new(), bounds: Box::default(),
}); }])
} };
Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: true }) Some(GenericArgs { args, has_self_type: false, bindings, desugared_from_fn: true })
} }

View file

@ -71,7 +71,7 @@ pub(crate) fn print_generic_args(generics: &GenericArgs, buf: &mut dyn Write) ->
first = false; first = false;
print_generic_arg(arg, buf)?; print_generic_arg(arg, buf)?;
} }
for binding in &generics.bindings { for binding in generics.bindings.iter() {
if !first { if !first {
write!(buf, ", ")?; write!(buf, ", ")?;
} }

View file

@ -292,7 +292,7 @@ impl TypeRef {
} }
for segment in path.segments().iter() { for segment in path.segments().iter() {
if let Some(args_and_bindings) = segment.args_and_bindings { 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 { match arg {
crate::path::GenericArg::Type(type_ref) => { crate::path::GenericArg::Type(type_ref) => {
go(type_ref, f); go(type_ref, f);
@ -301,11 +301,11 @@ impl TypeRef {
| crate::path::GenericArg::Lifetime(_) => {} | crate::path::GenericArg::Lifetime(_) => {}
} }
} }
for binding in &args_and_bindings.bindings { for binding in args_and_bindings.bindings.iter() {
if let Some(type_ref) = &binding.type_ref { if let Some(type_ref) = &binding.type_ref {
go(type_ref, f); go(type_ref, f);
} }
for bound in &binding.bounds { for bound in binding.bounds.iter() {
match bound.as_ref() { match bound.as_ref() {
TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => { TypeBound::Path(path, _) | TypeBound::ForLifetime(_, path) => {
go_path(path, f) go_path(path, f)

View file

@ -1419,7 +1419,7 @@ impl HirDisplay for Path {
write!(f, "<")?; write!(f, "<")?;
let mut first = true; let mut first = true;
for arg in &generic_args.args { for arg in generic_args.args.iter() {
if first { if first {
first = false; first = false;
if generic_args.has_self_type { if generic_args.has_self_type {
@ -1431,7 +1431,7 @@ impl HirDisplay for Path {
} }
arg.hir_fmt(f)?; arg.hir_fmt(f)?;
} }
for binding in &generic_args.bindings { for binding in generic_args.bindings.iter() {
if first { if first {
first = false; first = false;
} else { } else {
@ -1445,7 +1445,7 @@ impl HirDisplay for Path {
} }
None => { None => {
write!(f, ": ")?; write!(f, ": ")?;
f.write_joined(&binding.bounds, " + ")?; f.write_joined(binding.bounds.iter(), " + ")?;
} }
} }
} }

View file

@ -1025,7 +1025,7 @@ impl<'a> TyLoweringContext<'a> {
last_segment last_segment
.into_iter() .into_iter()
.filter_map(|segment| segment.args_and_bindings) .filter_map(|segment| segment.args_and_bindings)
.flat_map(|args_and_bindings| &args_and_bindings.bindings) .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
.flat_map(move |binding| { .flat_map(move |binding| {
let found = associated_type_by_name_including_super_traits( let found = associated_type_by_name_including_super_traits(
self.db, self.db,
@ -1068,7 +1068,7 @@ impl<'a> TyLoweringContext<'a> {
AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty };
preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq))); preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq)));
} }
for bound in &binding.bounds { for bound in binding.bounds.iter() {
preds.extend(self.lower_type_bound( preds.extend(self.lower_type_bound(
bound, bound,
TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner), TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner),