diff --git a/askama_derive/src/config.rs b/askama_derive/src/config.rs index 079d8259..afc23b52 100644 --- a/askama_derive/src/config.rs +++ b/askama_derive/src/config.rs @@ -1,5 +1,5 @@ use std::borrow::{Borrow, Cow}; -use std::collections::btree_map::{BTreeMap, Entry}; +use std::collections::hash_map::Entry; use std::mem::ManuallyDrop; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -12,12 +12,12 @@ use proc_macro2::Span; #[cfg(feature = "config")] use serde_derive::Deserialize; -use crate::{CompileError, FileInfo, OnceMap}; +use crate::{CompileError, FileInfo, HashMap, OnceMap}; #[derive(Debug)] pub(crate) struct Config { pub(crate) dirs: Vec, - pub(crate) syntaxes: BTreeMap>, + pub(crate) syntaxes: HashMap>, pub(crate) default_syntax: &'static str, pub(crate) escapers: Vec<(Vec>, Cow<'static, str>)>, pub(crate) whitespace: Whitespace, @@ -107,7 +107,7 @@ impl Config { let default_dirs = vec![root.join("templates")]; - let mut syntaxes = BTreeMap::new(); + let mut syntaxes = HashMap::default(); syntaxes.insert(DEFAULT_SYNTAX_NAME.to_string(), SyntaxAndCache::default()); let raw = if s.is_empty() { diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs index e3f59f16..5d5cc7b0 100644 --- a/askama_derive/src/generator.rs +++ b/askama_derive/src/generator.rs @@ -4,7 +4,6 @@ mod helpers; mod node; use std::borrow::Cow; -use std::collections::hash_map::HashMap; use std::env::current_dir; use std::ops::Deref; use std::path::{Path, PathBuf}; @@ -15,7 +14,6 @@ use parser::node::{Call, Macro, Whitespace}; use parser::{CharLit, Expr, FloatKind, IntKind, Num, StrLit, WithSpan}; use proc_macro2::TokenStream; use quote::{ToTokens, quote_spanned}; -use rustc_hash::FxBuildHasher; use syn::Token; use crate::generator::helpers::{clean_path, diff_paths}; @@ -23,12 +21,12 @@ use crate::heritage::{Context, Heritage}; use crate::html::write_escaped_str; use crate::input::{Source, TemplateInput}; use crate::integration::{Buffer, impl_everything, write_header}; -use crate::{CompileError, FileInfo, field_new, quote_into}; +use crate::{CompileError, FileInfo, HashMap, field_new, quote_into}; pub(crate) fn template_to_string( buf: &mut Buffer, input: &TemplateInput<'_>, - contexts: &HashMap<&Arc, Context<'_>, FxBuildHasher>, + contexts: &HashMap<&Arc, Context<'_>>, heritage: Option<&Heritage<'_, '_>>, tmpl_kind: TmplKind<'_>, ) -> Result { @@ -69,7 +67,7 @@ struct Generator<'a, 'h> { /// The template input state: original struct AST and attributes input: &'a TemplateInput<'a>, /// All contexts, keyed by the package-relative template path - contexts: &'a HashMap<&'a Arc, Context<'a>, FxBuildHasher>, + contexts: &'a HashMap<&'a Arc, Context<'a>>, /// The heritage contains references to blocks and their ancestry heritage: Option<&'h Heritage<'a, 'h>>, /// Variables accessible directly from the current scope (not redirected to context) @@ -102,7 +100,7 @@ enum CallerDir { impl<'a, 'h> Generator<'a, 'h> { fn new( input: &'a TemplateInput<'a>, - contexts: &'a HashMap<&'a Arc, Context<'a>, FxBuildHasher>, + contexts: &'a HashMap<&'a Arc, Context<'a>>, heritage: Option<&'h Heritage<'a, 'h>>, locals: MapChain<'a>, buf_writable_discard: bool, @@ -619,7 +617,7 @@ impl<'a> LocalMeta<'a> { } struct MapChain<'a> { - scopes: Vec, LocalMeta<'a>, FxBuildHasher>>, + scopes: Vec, LocalMeta<'a>>>, } impl<'a> MapChain<'a> { diff --git a/askama_derive/src/generator/helpers/macro_invocation.rs b/askama_derive/src/generator/helpers/macro_invocation.rs index 3e97998d..5b5eec9a 100644 --- a/askama_derive/src/generator/helpers/macro_invocation.rs +++ b/askama_derive/src/generator/helpers/macro_invocation.rs @@ -1,19 +1,17 @@ use core::fmt; use std::borrow::Cow; -use std::collections::HashMap; use std::fmt::Write; use std::mem; use parser::node::{Call, Macro, Ws}; use parser::{Expr, Span, WithSpan}; use quote::quote_spanned; -use rustc_hash::FxBuildHasher; use crate::generator::node::AstLevel; use crate::generator::{Generator, LocalMeta, is_copyable}; use crate::heritage::Context; use crate::integration::Buffer; -use crate::{CompileError, field_new, quote_into}; +use crate::{CompileError, HashMap, field_new, quote_into}; /// Helper to generate the code for macro invocations pub(crate) struct MacroInvocation<'a, 'b> { @@ -97,14 +95,14 @@ impl<'a, 'b> MacroInvocation<'a, 'b> { buf: &'b mut Buffer, generator: &mut Generator<'a, 'h>, ) -> Result<(), CompileError> { - let mut named_arguments: HashMap<&str, _, FxBuildHasher> = HashMap::default(); + let mut named_arguments = HashMap::default(); if let Some(Expr::NamedArgument(_, _)) = self.call_args.last().map(|expr| &***expr) { // First we check that all named arguments actually exist in the called item. for (index, arg) in self.call_args.iter().enumerate().rev() { - let Expr::NamedArgument(arg_name, _) = &***arg else { + let &Expr::NamedArgument(arg_name, _) = &***arg else { break; }; - if !self.macro_def.args.iter().any(|(arg, _)| arg == arg_name) { + if !self.macro_def.args.iter().any(|&(arg, _)| arg == arg_name) { return Err(self.callsite_ctx.generate_error( format_args!( "no argument named `{arg_name}` in macro {}", diff --git a/askama_derive/src/generator/node.rs b/askama_derive/src/generator/node.rs index d0f57d33..cf78ac1a 100644 --- a/askama_derive/src/generator/node.rs +++ b/askama_derive/src/generator/node.rs @@ -1,5 +1,5 @@ use std::borrow::Cow; -use std::collections::hash_map::{Entry, HashMap}; +use std::collections::hash_map::Entry; use std::fmt::Debug; use std::mem; use std::ops::ControlFlow; @@ -12,13 +12,14 @@ use parser::node::{ use parser::{Expr, Node, Span, Target, WithSpan}; use proc_macro2::TokenStream; use quote::quote_spanned; +use rustc_hash::FxBuildHasher; use syn::Token; use super::{DisplayWrap, Generator, LocalMeta, MapChain, compile_time_escape, is_copyable}; use crate::generator::{LocalCallerMeta, Writable, helpers, logic_op}; use crate::heritage::{Context, Heritage}; use crate::integration::{Buffer, string_escape}; -use crate::{CompileError, FileInfo, field_new, fmt_left, fmt_right, quote_into}; +use crate::{CompileError, FileInfo, HashMap, field_new, fmt_left, fmt_right, quote_into}; impl<'a> Generator<'a, '_> { pub(super) fn impl_template_inner( @@ -1270,7 +1271,8 @@ impl<'a> Generator<'a, '_> { let mut targets = Buffer::new(); let mut lines = Buffer::new(); - let mut expr_cache = HashMap::with_capacity(self.buf_writable.len()); + let mut expr_cache = + HashMap::with_capacity_and_hasher(self.buf_writable.len(), FxBuildHasher); // the `last_line` contains any sequence of trailing simple `writer.write_str()` calls let mut trailing_simple_lines = Vec::new(); diff --git a/askama_derive/src/heritage.rs b/askama_derive/src/heritage.rs index b489eb14..d98efac9 100644 --- a/askama_derive/src/heritage.rs +++ b/askama_derive/src/heritage.rs @@ -1,15 +1,13 @@ use core::fmt; -use std::collections::HashMap; use std::path::Path; use std::sync::Arc; use parser::node::{BlockDef, Macro}; use parser::{Node, Parsed, Span}; -use rustc_hash::FxBuildHasher; use crate::config::Config; use crate::input::LiteralOrSpan; -use crate::{CompileError, FileInfo}; +use crate::{CompileError, FileInfo, HashMap}; pub(crate) struct Heritage<'a, 'h> { pub(crate) root: &'h Context<'a>, @@ -19,7 +17,7 @@ pub(crate) struct Heritage<'a, 'h> { impl<'a, 'h> Heritage<'a, 'h> { pub(crate) fn new( mut root: &'h Context<'a>, - contexts: &'a HashMap<&'a Arc, Context<'a>, FxBuildHasher>, + contexts: &'a HashMap<&'a Arc, Context<'a>>, ) -> Self { let mut blocks: BlockAncestry<'a, 'h> = root .blocks @@ -38,16 +36,15 @@ impl<'a, 'h> Heritage<'a, 'h> { } } -type BlockAncestry<'a, 'h> = - HashMap<&'a str, Vec<(&'h Context<'a>, &'a BlockDef<'a>)>, FxBuildHasher>; +type BlockAncestry<'a, 'h> = HashMap<&'a str, Vec<(&'h Context<'a>, &'a BlockDef<'a>)>>; #[derive(Clone)] pub(crate) struct Context<'a> { pub(crate) nodes: &'a [Box>], pub(crate) extends: Option>, - pub(crate) blocks: HashMap<&'a str, &'a BlockDef<'a>, FxBuildHasher>, - pub(crate) macros: HashMap<&'a str, &'a Macro<'a>, FxBuildHasher>, - pub(crate) imports: HashMap<&'a str, Arc, FxBuildHasher>, + pub(crate) blocks: HashMap<&'a str, &'a BlockDef<'a>>, + pub(crate) macros: HashMap<&'a str, &'a Macro<'a>>, + pub(crate) imports: HashMap<&'a str, Arc>, pub(crate) path: Option<&'a Path>, pub(crate) parsed: &'a Parsed, pub(crate) literal: Option, diff --git a/askama_derive/src/input.rs b/askama_derive/src/input.rs index d7e0de03..01c0a1e8 100644 --- a/askama_derive/src/input.rs +++ b/askama_derive/src/input.rs @@ -1,5 +1,4 @@ use std::borrow::Cow; -use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::str::FromStr; use std::sync::Arc; @@ -7,13 +6,12 @@ use std::sync::Arc; use parser::node::Whitespace; use parser::{Node, Parsed}; use proc_macro2::Span; -use rustc_hash::FxBuildHasher; use syn::punctuated::Punctuated; use syn::spanned::Spanned; use syn::{Attribute, Expr, ExprLit, ExprPath, Ident, Lit, LitBool, LitStr, Meta, Token}; use crate::config::{Config, SyntaxAndCache}; -use crate::{CompileError, FileInfo, MsgValidEscapers}; +use crate::{CompileError, FileInfo, HashMap, MsgValidEscapers}; #[derive(Clone, Debug)] pub(crate) enum LiteralOrSpan { @@ -178,7 +176,7 @@ impl TemplateInput<'_> { pub(crate) fn find_used_templates( &self, - map: &mut HashMap, Arc, FxBuildHasher>, + map: &mut HashMap, Arc>, ) -> Result<(), CompileError> { let (source, source_path) = match &self.source { Source::Source(s) => (s.clone(), None), diff --git a/askama_derive/src/lib.rs b/askama_derive/src/lib.rs index ecef3cb7..d110633e 100644 --- a/askama_derive/src/lib.rs +++ b/askama_derive/src/lib.rs @@ -23,7 +23,7 @@ pub mod __macro_support { } use std::borrow::{Borrow, Cow}; -use std::collections::hash_map::{Entry, HashMap}; +use std::collections::hash_map::Entry; use std::fmt; use std::hash::{BuildHasher, Hash}; use std::path::Path; @@ -623,7 +623,7 @@ fn var_expr_n(n: usize, span: proc_macro2::Span) -> Ident { } #[derive(Debug)] -struct OnceMap([Mutex>; 8]); +struct OnceMap([Mutex>; 8]); impl Default for OnceMap { fn default() -> Self { @@ -718,3 +718,5 @@ macro_rules! quote_into { } pub(crate) use {fmt_left, fmt_right, quote_into}; + +type HashMap = std::collections::hash_map::HashMap; diff --git a/askama_parser/Cargo.toml b/askama_parser/Cargo.toml index 22046480..11476fec 100644 --- a/askama_parser/Cargo.toml +++ b/askama_parser/Cargo.toml @@ -21,6 +21,7 @@ name = "from_str" harness = false [dependencies] +rustc-hash = "2.0.0" serde = { version = "1.0", optional = true } serde_derive = { version = "1.0", optional = true } unicode-ident = "1.0.12" diff --git a/askama_parser/src/expr.rs b/askama_parser/src/expr.rs index af799ae7..4cda0958 100644 --- a/askama_parser/src/expr.rs +++ b/askama_parser/src/expr.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::str; use winnow::Parser; @@ -11,9 +10,9 @@ use winnow::token::{one_of, take_until}; use crate::node::CondTest; use crate::{ - CharLit, ErrorContext, Level, Num, ParseResult, PathOrIdentifier, StrLit, StrPrefix, WithSpan, - can_be_variable_name, char_lit, cut_error, filter, identifier, keyword, not_suffix_with_hash, - num_lit, path_or_identifier, skip_ws0, skip_ws1, str_lit, ws, + CharLit, ErrorContext, HashSet, Level, Num, ParseResult, PathOrIdentifier, StrLit, StrPrefix, + WithSpan, can_be_variable_name, char_lit, cut_error, filter, identifier, keyword, + not_suffix_with_hash, num_lit, path_or_identifier, skip_ws0, skip_ws1, str_lit, ws, }; macro_rules! expr_prec_layer { @@ -253,7 +252,7 @@ impl<'a> Expr<'a> { level: Level<'_>, ) -> ParseResult<'a, Vec>>> { let _level_guard = level.nest(i)?; - let mut named_arguments = HashSet::new(); + let mut named_arguments = HashSet::default(); let start = *i; preceded( diff --git a/askama_parser/src/lib.rs b/askama_parser/src/lib.rs index 4732495f..0a2b3511 100644 --- a/askama_parser/src/lib.rs +++ b/askama_parser/src/lib.rs @@ -18,6 +18,7 @@ use std::path::Path; use std::sync::Arc; use std::{fmt, str}; +use rustc_hash::FxBuildHasher; use winnow::ascii::take_escaped; use winnow::combinator::{ alt, cut_err, delimited, empty, fail, not, opt, peek, preceded, repeat, terminated, @@ -1463,6 +1464,8 @@ fn cut_context_err<'a, T>(gen_err: impl FnOnce() -> ErrorContext<'a>) -> ParseRe Err(ErrMode::Cut(gen_err())) } +type HashSet = std::collections::hash_set::HashSet; + #[cfg(not(windows))] #[cfg(test)] mod test { diff --git a/askama_parser/src/node.rs b/askama_parser/src/node.rs index fcdd7ef2..5a304be3 100644 --- a/askama_parser/src/node.rs +++ b/askama_parser/src/node.rs @@ -1,4 +1,3 @@ -use std::collections::HashSet; use std::str::{self, FromStr}; use winnow::combinator::{ @@ -11,8 +10,8 @@ use winnow::token::{any, rest, take_until}; use winnow::{ModalParser, Parser}; use crate::{ - ErrorContext, Expr, Filter, ParseResult, Span, State, Target, WithSpan, cut_error, filter, - identifier, is_rust_keyword, keyword, skip_ws0, str_lit_without_prefix, ws, + ErrorContext, Expr, Filter, HashSet, ParseResult, Span, State, Target, WithSpan, cut_error, + filter, identifier, is_rust_keyword, keyword, skip_ws0, str_lit_without_prefix, ws, }; #[derive(Debug, PartialEq)] @@ -685,7 +684,7 @@ impl<'a> Macro<'a> { } if let Some(ref params) = params { - let mut names = HashSet::new(); + let mut names = HashSet::default(); let mut iter = params.iter(); while let Some((arg_name, default_value)) = iter.next() {