Skip to content

Commit 021d582

Browse files
bors[bot]Veykril
andauthored
Merge #10981
10981: internal: Remove some allocations r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents bcc720f + 1bbc255 commit 021d582

File tree

13 files changed

+78
-58
lines changed

13 files changed

+78
-58
lines changed

crates/hir/src/display.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use hir_ty::{
1212
},
1313
Interner, TraitRefExt, WhereClause,
1414
};
15-
use syntax::ast::{self, HasName};
15+
use syntax::{
16+
ast::{self, HasName},
17+
SmolStr,
18+
};
1619

1720
use crate::{
1821
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
@@ -247,7 +250,8 @@ impl HirDisplay for TypeParam {
247250
bounds.iter().cloned().map(|b| b.substitute(&Interner, &substs)).collect();
248251
let krate = self.id.parent.krate(f.db).id;
249252
let sized_trait =
250-
f.db.lang_item(krate, "sized".into()).and_then(|lang_item| lang_item.as_trait());
253+
f.db.lang_item(krate, SmolStr::new_inline("sized"))
254+
.and_then(|lang_item| lang_item.as_trait());
251255
let has_only_sized_bound = predicates.iter().all(move |pred| match pred.skip_binders() {
252256
WhereClause::Implemented(it) => Some(it.hir_trait_id()) == sized_trait,
253257
_ => false,

crates/hir/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,7 +2427,7 @@ impl Type {
24272427
let krate = self.krate;
24282428

24292429
let std_future_trait =
2430-
db.lang_item(krate, "future_trait".into()).and_then(|it| it.as_trait());
2430+
db.lang_item(krate, SmolStr::new_inline("future_trait")).and_then(|it| it.as_trait());
24312431
let std_future_trait = match std_future_trait {
24322432
Some(it) => it,
24332433
None => return false,
@@ -2516,7 +2516,7 @@ impl Type {
25162516
}
25172517

25182518
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
2519-
let lang_item = db.lang_item(self.krate, SmolStr::new("copy"));
2519+
let lang_item = db.lang_item(self.krate, SmolStr::new_inline("copy"));
25202520
let copy_trait = match lang_item {
25212521
Some(LangItemTarget::TraitId(it)) => it,
25222522
_ => return false,

crates/hir_ty/src/autoderef.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, VariableKind};
1010
use hir_def::lang_item::LangItemTarget;
1111
use hir_expand::name::name;
1212
use limit::Limit;
13+
use syntax::SmolStr;
1314
use tracing::{info, warn};
1415

1516
use crate::{
@@ -71,7 +72,10 @@ impl Iterator for Autoderef<'_> {
7172
}
7273

7374
let (kind, new_ty) = if let Some(derefed) = builtin_deref(&self.ty.value) {
74-
(AutoderefKind::Builtin, Canonical { value: derefed, binders: self.ty.binders.clone() })
75+
(
76+
AutoderefKind::Builtin,
77+
Canonical { value: derefed.clone(), binders: self.ty.binders.clone() },
78+
)
7579
} else {
7680
(
7781
AutoderefKind::Overloaded,
@@ -110,15 +114,17 @@ pub(crate) fn deref(
110114
) -> Option<Canonical<Ty>> {
111115
let _p = profile::span("deref");
112116
match builtin_deref(&ty.goal.value) {
113-
Some(derefed) => Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }),
117+
Some(derefed) => {
118+
Some(Canonical { value: derefed.clone(), binders: ty.goal.binders.clone() })
119+
}
114120
None => deref_by_trait(db, krate, ty),
115121
}
116122
}
117123

118-
fn builtin_deref(ty: &Ty) -> Option<Ty> {
124+
fn builtin_deref(ty: &Ty) -> Option<&Ty> {
119125
match ty.kind(&Interner) {
120-
TyKind::Ref(.., ty) => Some(ty.clone()),
121-
TyKind::Raw(.., ty) => Some(ty.clone()),
126+
TyKind::Ref(.., ty) => Some(ty),
127+
TyKind::Raw(.., ty) => Some(ty),
122128
_ => None,
123129
}
124130
}
@@ -129,7 +135,7 @@ fn deref_by_trait(
129135
ty: InEnvironment<&Canonical<Ty>>,
130136
) -> Option<Canonical<Ty>> {
131137
let _p = profile::span("deref_by_trait");
132-
let deref_trait = match db.lang_item(krate, "deref".into())? {
138+
let deref_trait = match db.lang_item(krate, SmolStr::new_inline("deref"))? {
133139
LangItemTarget::TraitId(it) => it,
134140
_ => return None,
135141
};

crates/hir_ty/src/chalk_db.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::sync::Arc;
44

55
use cov_mark::hit;
6+
use syntax::SmolStr;
67
use tracing::debug;
78

89
use chalk_ir::{cast::Cast, fold::shift::Shift, CanonicalVarKinds};
@@ -213,7 +214,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
213214
crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
214215
if let Some((future_trait, future_output)) = self
215216
.db
216-
.lang_item(self.krate, "future_trait".into())
217+
.lang_item(self.krate, SmolStr::new_inline("future_trait"))
217218
.and_then(|item| item.as_trait())
218219
.and_then(|trait_| {
219220
let alias =
@@ -419,7 +420,7 @@ pub(crate) fn associated_ty_data_query(
419420
if !ctx.unsized_types.borrow().contains(&self_ty) {
420421
let sized_trait = resolver
421422
.krate()
422-
.and_then(|krate| db.lang_item(krate, "sized".into()))
423+
.and_then(|krate| db.lang_item(krate, SmolStr::new_inline("sized")))
423424
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
424425
let sized_bound = sized_trait.into_iter().map(|sized_trait| {
425426
let trait_bound =

crates/hir_ty/src/chalk_ext.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use hir_def::{
66
type_ref::Rawness,
77
FunctionId, GenericDefId, HasModule, ItemContainerId, Lookup, TraitId,
88
};
9+
use syntax::SmolStr;
910

1011
use crate::{
1112
db::HirDatabase, from_assoc_type_id, from_chalk_trait_id, from_foreign_def_id,
@@ -187,7 +188,7 @@ impl TyExt for Ty {
187188
ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
188189
let krate = def.module(db.upcast()).krate();
189190
if let Some(future_trait) = db
190-
.lang_item(krate, "future_trait".into())
191+
.lang_item(krate, SmolStr::new_inline("future_trait"))
191192
.and_then(|item| item.as_trait())
192193
{
193194
// This is only used by type walking.

crates/hir_ty/src/diagnostics/match_check/deconstruct_pat.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ use std::{
5050
use hir_def::{EnumVariantId, HasModule, LocalFieldId, VariantId};
5151
use smallvec::{smallvec, SmallVec};
5252
use stdx::never;
53+
use syntax::SmolStr;
5354

5455
use crate::{AdtId, Interner, Scalar, Ty, TyExt, TyKind};
5556

@@ -905,7 +906,7 @@ fn is_field_list_non_exhaustive(variant_id: VariantId, cx: &MatchCheckCtx<'_>) -
905906

906907
fn adt_is_box(adt: hir_def::AdtId, cx: &MatchCheckCtx<'_>) -> bool {
907908
use hir_def::lang_item::LangItemTarget;
908-
match cx.db.lang_item(cx.module.krate(), "owned_box".into()) {
909+
match cx.db.lang_item(cx.module.krate(), SmolStr::new_inline("owned_box")) {
909910
Some(LangItemTarget::StructId(box_id)) => adt == box_id.into(),
910911
_ => false,
911912
}

crates/hir_ty/src/display.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use hir_def::{
2020
};
2121
use hir_expand::{hygiene::Hygiene, name::Name};
2222
use itertools::Itertools;
23+
use syntax::SmolStr;
2324

2425
use crate::{
2526
const_from_placeholder_idx,
@@ -774,8 +775,9 @@ impl SizedByDefault {
774775
match self {
775776
Self::NotSized => false,
776777
Self::Sized { anchor } => {
777-
let sized_trait =
778-
db.lang_item(anchor, "sized".into()).and_then(|lang_item| lang_item.as_trait());
778+
let sized_trait = db
779+
.lang_item(anchor, SmolStr::new_inline("sized"))
780+
.and_then(|lang_item| lang_item.as_trait());
779781
Some(trait_) == sized_trait
780782
}
781783
}

crates/hir_ty/src/infer/coerce.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::iter;
1010
use chalk_ir::{cast::Cast, Goal, Mutability, TyVariableKind};
1111
use hir_def::{expr::ExprId, lang_item::LangItemTarget};
1212
use stdx::always;
13+
use syntax::SmolStr;
1314

1415
use crate::{
1516
autoderef::{Autoderef, AutoderefKind},
@@ -536,10 +537,11 @@ impl<'a> InferenceContext<'a> {
536537
reborrow.as_ref().map_or_else(|| from_ty.clone(), |(_, adj)| adj.target.clone());
537538

538539
let krate = self.resolver.krate().unwrap();
539-
let coerce_unsized_trait = match self.db.lang_item(krate, "coerce_unsized".into()) {
540-
Some(LangItemTarget::TraitId(trait_)) => trait_,
541-
_ => return Err(TypeError),
542-
};
540+
let coerce_unsized_trait =
541+
match self.db.lang_item(krate, SmolStr::new_inline("coerce_unsized")) {
542+
Some(LangItemTarget::TraitId(trait_)) => trait_,
543+
_ => return Err(TypeError),
544+
};
543545

544546
let coerce_unsized_tref = {
545547
let b = TyBuilder::trait_ref(self.db, coerce_unsized_trait);

crates/hir_ty/src/lower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use la_arena::ArenaMap;
2828
use rustc_hash::FxHashSet;
2929
use smallvec::SmallVec;
3030
use stdx::impl_from;
31-
use syntax::ast;
31+
use syntax::{ast, SmolStr};
3232

3333
use crate::all_super_traits;
3434
use crate::{
@@ -797,7 +797,7 @@ impl<'a> TyLoweringContext<'a> {
797797
let sized_trait = self
798798
.resolver
799799
.krate()
800-
.and_then(|krate| self.db.lang_item(krate, "sized".into()))
800+
.and_then(|krate| self.db.lang_item(krate, SmolStr::new_inline("sized")))
801801
.and_then(|lang_item| lang_item.as_trait());
802802
// Don't lower associated type bindings as the only possible relaxed trait bound
803803
// `?Sized` has no of them.
@@ -895,7 +895,7 @@ impl<'a> TyLoweringContext<'a> {
895895
let krate = func.lookup(ctx.db.upcast()).module(ctx.db.upcast()).krate();
896896
let sized_trait = ctx
897897
.db
898-
.lang_item(krate, "sized".into())
898+
.lang_item(krate, SmolStr::new_inline("sized"))
899899
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
900900
let sized_clause = sized_trait.map(|trait_id| {
901901
let clause = WhereClause::Implemented(TraitRef {
@@ -1200,7 +1200,7 @@ fn implicitly_sized_clauses<'a>(
12001200
let generic_args = &substitution.as_slice(&Interner)[is_trait_def as usize..];
12011201
let sized_trait = resolver
12021202
.krate()
1203-
.and_then(|krate| db.lang_item(krate, "sized".into()))
1203+
.and_then(|krate| db.lang_item(krate, SmolStr::new_inline("sized")))
12041204
.and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id));
12051205

12061206
sized_trait.into_iter().flat_map(move |sized_trait| {

crates/hir_ty/src/method_resolution.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -541,19 +541,19 @@ pub fn iterate_method_candidates_dyn(
541541
// types*.
542542

543543
let deref_chain = autoderef_method_receiver(db, krate, ty);
544-
for i in 0..deref_chain.len() {
544+
let mut deref_chains = stdx::slice_tails(&deref_chain);
545+
deref_chains.try_for_each(|deref_chain| {
545546
iterate_method_candidates_with_autoref(
546-
&deref_chain[i..],
547+
deref_chain,
547548
db,
548549
env.clone(),
549550
krate,
550551
traits_in_scope,
551552
visible_from_module,
552553
name,
553554
callback,
554-
)?;
555-
}
556-
ControlFlow::Continue(())
555+
)
556+
})
557557
}
558558
LookupMode::Path => {
559559
// No autoderef for path lookups
@@ -716,15 +716,14 @@ fn iterate_trait_method_candidates(
716716
// if ty is `dyn Trait`, the trait doesn't need to be in scope
717717
let inherent_trait =
718718
self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
719-
let env_traits = match self_ty.value.kind(&Interner) {
720-
TyKind::Placeholder(_) => {
721-
// if we have `T: Trait` in the param env, the trait doesn't need to be in scope
719+
let env_traits = matches!(self_ty.value.kind(&Interner), TyKind::Placeholder(_))
720+
// if we have `T: Trait` in the param env, the trait doesn't need to be in scope
721+
.then(|| {
722722
env.traits_in_scope_from_clauses(self_ty.value.clone())
723723
.flat_map(|t| all_super_traits(db.upcast(), t))
724-
.collect()
725-
}
726-
_ => Vec::new(),
727-
};
724+
})
725+
.into_iter()
726+
.flatten();
728727
let traits = inherent_trait.chain(env_traits).chain(traits_in_scope.iter().copied());
729728

730729
'traits: for t in traits {
@@ -747,10 +746,10 @@ fn iterate_trait_method_candidates(
747746
// trait, but if we find out it doesn't, we'll skip the rest of the
748747
// iteration
749748
let mut known_implemented = false;
750-
for (_name, item) in data.items.iter() {
749+
for &(_, item) in data.items.iter() {
751750
// Don't pass a `visible_from_module` down to `is_valid_candidate`,
752751
// since only inherent methods should be included into visibility checking.
753-
if !is_valid_candidate(db, env.clone(), name, receiver_ty, *item, self_ty, None) {
752+
if !is_valid_candidate(db, env.clone(), name, receiver_ty, item, self_ty, None) {
754753
continue;
755754
}
756755
if !known_implemented {
@@ -761,7 +760,7 @@ fn iterate_trait_method_candidates(
761760
}
762761
known_implemented = true;
763762
// FIXME: we shouldn't be ignoring the binders here
764-
callback(self_ty, *item)?
763+
callback(self_ty, item)?
765764
}
766765
}
767766
ControlFlow::Continue(())
@@ -774,18 +773,14 @@ fn filter_inherent_impls_for_self_ty<'i>(
774773
// inherent methods on arrays are fingerprinted as [T; {unknown}], so we must also consider them when
775774
// resolving a method call on an array with a known len
776775
let array_impls = {
777-
if let TyKind::Array(parameters, array_len) = self_ty.kind(&Interner) {
778-
if !array_len.is_unknown() {
776+
match self_ty.kind(&Interner) {
777+
TyKind::Array(parameters, array_len) if !array_len.is_unknown() => {
779778
let unknown_array_len_ty =
780-
TyKind::Array(parameters.clone(), consteval::usize_const(None))
781-
.intern(&Interner);
779+
TyKind::Array(parameters.clone(), consteval::usize_const(None));
782780

783-
Some(impls.for_self_ty(&unknown_array_len_ty))
784-
} else {
785-
None
781+
Some(impls.for_self_ty(&unknown_array_len_ty.intern(&Interner)))
786782
}
787-
} else {
788-
None
783+
_ => None,
789784
}
790785
}
791786
.into_iter()

crates/hir_ty/src/traits.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use chalk_solve::{logging_db::LoggingRustIrDatabase, Solver};
99
use base_db::CrateId;
1010
use hir_def::{lang_item::LangItemTarget, TraitId};
1111
use stdx::panic_context;
12+
use syntax::SmolStr;
1213

1314
use crate::{
1415
db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment,
@@ -169,7 +170,7 @@ pub enum FnTrait {
169170
}
170171

171172
impl FnTrait {
172-
fn lang_item_name(self) -> &'static str {
173+
const fn lang_item_name(self) -> &'static str {
173174
match self {
174175
FnTrait::FnOnce => "fn_once",
175176
FnTrait::FnMut => "fn_mut",
@@ -178,7 +179,7 @@ impl FnTrait {
178179
}
179180

180181
pub fn get_id(&self, db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
181-
let target = db.lang_item(krate, self.lang_item_name().into())?;
182+
let target = db.lang_item(krate, SmolStr::new_inline(self.lang_item_name()))?;
182183
match target {
183184
LangItemTarget::TraitId(t) => Some(t),
184185
_ => None,

crates/hir_ty/src/utils.rs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use hir_def::{
1818
};
1919
use hir_expand::name::{name, Name};
2020
use rustc_hash::FxHashSet;
21+
use smallvec::{smallvec, SmallVec};
22+
use syntax::SmolStr;
2123

2224
use crate::{
2325
db::HirDatabase, ChalkTraitId, Interner, Substitution, TraitRef, TraitRefExt, TyKind,
@@ -26,16 +28,16 @@ use crate::{
2628

2729
pub(crate) fn fn_traits(db: &dyn DefDatabase, krate: CrateId) -> impl Iterator<Item = TraitId> {
2830
[
29-
db.lang_item(krate, "fn".into()),
30-
db.lang_item(krate, "fn_mut".into()),
31-
db.lang_item(krate, "fn_once".into()),
31+
db.lang_item(krate, SmolStr::new_inline("fn")),
32+
db.lang_item(krate, SmolStr::new_inline("fn_mut")),
33+
db.lang_item(krate, SmolStr::new_inline("fn_once")),
3234
]
3335
.into_iter()
3436
.flatten()
3537
.flat_map(|it| it.as_trait())
3638
}
3739

38-
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
40+
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
3941
let resolver = trait_.resolver(db);
4042
// returning the iterator directly doesn't easily work because of
4143
// lifetime problems, but since there usually shouldn't be more than a
@@ -100,13 +102,13 @@ fn direct_super_trait_refs(db: &dyn HirDatabase, trait_ref: &TraitRef) -> Vec<Tr
100102

101103
/// Returns an iterator over the whole super trait hierarchy (including the
102104
/// trait itself).
103-
pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
105+
pub fn all_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> SmallVec<[TraitId; 4]> {
104106
// we need to take care a bit here to avoid infinite loops in case of cycles
105107
// (i.e. if we have `trait A: B; trait B: A;`)
106-
let mut result = vec![trait_];
108+
109+
let mut result = smallvec![trait_];
107110
let mut i = 0;
108-
while i < result.len() {
109-
let t = result[i];
111+
while let Some(&t) = result.get(i) {
110112
// yeah this is quadratic, but trait hierarchies should be flat
111113
// enough that this doesn't matter
112114
for tt in direct_super_traits(db, t) {

0 commit comments

Comments
 (0)