Skip to content

Commit c51caa5

Browse files
committed
Preserve order of generic args
1 parent ac8806d commit c51caa5

40 files changed

+644
-416
lines changed

crates/hir/src/attrs.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,8 @@ fn resolve_doc_path(
139139
AttrDefId::ImplId(it) => it.resolver(db.upcast()),
140140
AttrDefId::ExternBlockId(it) => it.resolver(db.upcast()),
141141
AttrDefId::GenericParamId(it) => match it {
142-
GenericParamId::TypeParamId(it) => it.parent,
142+
GenericParamId::TypeParamId(it) | GenericParamId::ConstParamId(it) => it.parent,
143143
GenericParamId::LifetimeParamId(it) => it.parent,
144-
GenericParamId::ConstParamId(it) => it.parent,
145144
}
146145
.resolver(db.upcast()),
147146
// FIXME

crates/hir/src/display.rs

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
//! HirDisplay implementations for various hir types.
22
use hir_def::{
33
adt::VariantData,
4-
generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
4+
generics::{
5+
TypeOrConstParamData, TypeParamProvenance, WherePredicate, WherePredicateTypeTarget,
6+
},
57
type_ref::{TypeBound, TypeRef},
68
AdtId, GenericDefId,
79
};
@@ -16,8 +18,8 @@ use syntax::SmolStr;
1618

1719
use crate::{
1820
Adt, Const, ConstParam, Enum, Field, Function, GenericParam, HasCrate, HasVisibility,
19-
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeParam, Union,
20-
Variant,
21+
LifetimeParam, Module, Static, Struct, Trait, TyBuilder, Type, TypeAlias, TypeOrConstParam,
22+
TypeParam, Union, Variant,
2123
};
2224

2325
impl HirDisplay for Function {
@@ -226,8 +228,17 @@ impl HirDisplay for GenericParam {
226228
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
227229
match self {
228230
GenericParam::TypeParam(it) => it.hir_fmt(f),
229-
GenericParam::LifetimeParam(it) => it.hir_fmt(f),
230231
GenericParam::ConstParam(it) => it.hir_fmt(f),
232+
GenericParam::LifetimeParam(it) => it.hir_fmt(f),
233+
}
234+
}
235+
}
236+
237+
impl HirDisplay for TypeOrConstParam {
238+
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
239+
match self.split(f.db) {
240+
either::Either::Left(x) => x.hir_fmt(f),
241+
either::Either::Right(x) => x.hir_fmt(f),
231242
}
232243
}
233244
}
@@ -276,11 +287,11 @@ impl HirDisplay for ConstParam {
276287
fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
277288
let params = f.db.generic_params(def);
278289
if params.lifetimes.is_empty()
279-
&& params.consts.is_empty()
280290
&& params
281291
.types
282292
.iter()
283-
.all(|(_, param)| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
293+
.filter_map(|x| x.1.type_param())
294+
.all(|param| !matches!(param.provenance, TypeParamProvenance::TypeParamList))
284295
{
285296
return Ok(());
286297
}
@@ -300,23 +311,27 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H
300311
write!(f, "{}", lifetime.name)?;
301312
}
302313
for (_, ty) in params.types.iter() {
303-
if ty.provenance != TypeParamProvenance::TypeParamList {
304-
continue;
305-
}
306-
if let Some(name) = &ty.name {
307-
delim(f)?;
308-
write!(f, "{}", name)?;
309-
if let Some(default) = &ty.default {
310-
write!(f, " = ")?;
311-
default.hir_fmt(f)?;
314+
if let Some(name) = &ty.name() {
315+
match ty {
316+
TypeOrConstParamData::TypeParamData(ty) => {
317+
if ty.provenance != TypeParamProvenance::TypeParamList {
318+
continue;
319+
}
320+
delim(f)?;
321+
write!(f, "{}", name)?;
322+
if let Some(default) = &ty.default {
323+
write!(f, " = ")?;
324+
default.hir_fmt(f)?;
325+
}
326+
}
327+
TypeOrConstParamData::ConstParamData(c) => {
328+
delim(f)?;
329+
write!(f, "const {}: ", name)?;
330+
c.ty.hir_fmt(f)?;
331+
}
312332
}
313333
}
314334
}
315-
for (_, konst) in params.consts.iter() {
316-
delim(f)?;
317-
write!(f, "const {}: ", konst.name)?;
318-
konst.ty.hir_fmt(f)?;
319-
}
320335

321336
write!(f, ">")?;
322337
Ok(())
@@ -328,7 +343,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir
328343
// unnamed type targets are displayed inline with the argument itself, e.g. `f: impl Y`.
329344
let is_unnamed_type_target = |target: &WherePredicateTypeTarget| match target {
330345
WherePredicateTypeTarget::TypeRef(_) => false,
331-
WherePredicateTypeTarget::TypeParam(id) => params.types[*id].name.is_none(),
346+
WherePredicateTypeTarget::TypeOrConstParam(id) => params.types[*id].name().is_none(),
332347
};
333348

334349
let has_displayable_predicate = params
@@ -344,7 +359,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir
344359

345360
let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter| match target {
346361
WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f),
347-
WherePredicateTypeTarget::TypeParam(id) => match &params.types[*id].name {
362+
WherePredicateTypeTarget::TypeOrConstParam(id) => match &params.types[*id].name() {
348363
Some(name) => write!(f, "{}", name),
349364
None => write!(f, "{{unnamed}}"),
350365
},

crates/hir/src/from_id.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ from_id![
4141
(hir_def::ConstId, crate::Const),
4242
(hir_def::FunctionId, crate::Function),
4343
(hir_def::ImplId, crate::Impl),
44-
(hir_def::TypeParamId, crate::TypeParam),
44+
(hir_def::TypeOrConstParamId, crate::TypeOrConstParam),
45+
// I'm not happy with these two, but what should we do?
46+
(hir_def::TypeOrConstParamId, crate::TypeParam),
47+
(hir_def::TypeOrConstParamId, crate::ConstParam),
4548
(hir_def::LifetimeParamId, crate::LifetimeParam),
46-
(hir_def::ConstParamId, crate::ConstParam),
4749
(hir_expand::MacroDefId, crate::MacroDef)
4850
];
4951

@@ -71,18 +73,18 @@ impl From<GenericParamId> for GenericParam {
7173
fn from(id: GenericParamId) -> Self {
7274
match id {
7375
GenericParamId::TypeParamId(it) => GenericParam::TypeParam(it.into()),
74-
GenericParamId::LifetimeParamId(it) => GenericParam::LifetimeParam(it.into()),
7576
GenericParamId::ConstParamId(it) => GenericParam::ConstParam(it.into()),
77+
GenericParamId::LifetimeParamId(it) => GenericParam::LifetimeParam(it.into()),
7678
}
7779
}
7880
}
7981

8082
impl From<GenericParam> for GenericParamId {
8183
fn from(id: GenericParam) -> Self {
8284
match id {
83-
GenericParam::TypeParam(it) => GenericParamId::TypeParamId(it.id),
8485
GenericParam::LifetimeParam(it) => GenericParamId::LifetimeParamId(it.id),
8586
GenericParam::ConstParam(it) => GenericParamId::ConstParamId(it.id),
87+
GenericParam::TypeParam(it) => GenericParamId::TypeParamId(it.id),
8688
}
8789
}
8890
}

crates/hir/src/has_source.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use hir_expand::InFile;
1010
use syntax::ast;
1111

1212
use crate::{
13-
db::HirDatabase, Adt, Const, ConstParam, Enum, Field, FieldSource, Function, Impl,
14-
LifetimeParam, MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
13+
db::HirDatabase, Adt, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef,
14+
Module, Static, Struct, Trait, TypeAlias, TypeOrConstParam, Union, Variant,
1515
};
1616

1717
pub trait HasSource {
@@ -139,8 +139,8 @@ impl HasSource for Impl {
139139
}
140140
}
141141

142-
impl HasSource for TypeParam {
143-
type Ast = Either<ast::TypeParam, ast::Trait>;
142+
impl HasSource for TypeOrConstParam {
143+
type Ast = Either<ast::TypeOrConstParam, ast::Trait>;
144144
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
145145
let child_source = self.id.parent.child_source(db.upcast());
146146
Some(child_source.map(|it| it[self.id.local_id].clone()))
@@ -154,11 +154,3 @@ impl HasSource for LifetimeParam {
154154
Some(child_source.map(|it| it[self.id.local_id].clone()))
155155
}
156156
}
157-
158-
impl HasSource for ConstParam {
159-
type Ast = ast::ConstParam;
160-
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
161-
let child_source = self.id.parent.child_source(db.upcast());
162-
Some(child_source.map(|it| it[self.id.local_id].clone()))
163-
}
164-
}

crates/hir/src/lib.rs

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ use hir_def::{
4747
per_ns::PerNs,
4848
resolver::{HasResolver, Resolver},
4949
src::HasSource as _,
50-
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
51-
FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
52-
LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
53-
TypeParamId, UnionId,
50+
AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId, FunctionId,
51+
GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId, LocalEnumVariantId,
52+
LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
53+
UnionId,
5454
};
5555
use hir_expand::{name::name, MacroCallKind, MacroDefId, MacroDefKind};
5656
use hir_ty::{
@@ -71,7 +71,7 @@ use itertools::Itertools;
7171
use nameres::diagnostics::DefDiagnosticKind;
7272
use once_cell::unsync::Lazy;
7373
use rustc_hash::FxHashSet;
74-
use stdx::{format_to, impl_from};
74+
use stdx::{format_to, impl_from, never};
7575
use syntax::{
7676
ast::{self, HasAttrs as _, HasDocComments, HasName},
7777
AstNode, AstPtr, SmolStr, SyntaxKind, SyntaxNodePtr,
@@ -1981,32 +1981,31 @@ impl_from!(
19811981
impl GenericDef {
19821982
pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
19831983
let generics = db.generic_params(self.into());
1984-
let ty_params = generics
1985-
.types
1986-
.iter()
1987-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1988-
.map(GenericParam::TypeParam);
1984+
let ty_params = generics.types.iter().map(|(local_id, _)| {
1985+
let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
1986+
match toc.split(db) {
1987+
Either::Left(x) => GenericParam::ConstParam(x),
1988+
Either::Right(x) => GenericParam::TypeParam(x),
1989+
}
1990+
});
19891991
let lt_params = generics
19901992
.lifetimes
19911993
.iter()
19921994
.map(|(local_id, _)| LifetimeParam {
19931995
id: LifetimeParamId { parent: self.into(), local_id },
19941996
})
19951997
.map(GenericParam::LifetimeParam);
1996-
let const_params = generics
1997-
.consts
1998-
.iter()
1999-
.map(|(local_id, _)| ConstParam { id: ConstParamId { parent: self.into(), local_id } })
2000-
.map(GenericParam::ConstParam);
2001-
ty_params.chain(lt_params).chain(const_params).collect()
1998+
ty_params.chain(lt_params).collect()
20021999
}
20032000

2004-
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
2001+
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
20052002
let generics = db.generic_params(self.into());
20062003
generics
20072004
.types
20082005
.iter()
2009-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
2006+
.map(|(local_id, _)| TypeOrConstParam {
2007+
id: TypeOrConstParamId { parent: self.into(), local_id },
2008+
})
20102009
.collect()
20112010
}
20122011
}
@@ -2190,38 +2189,41 @@ impl Label {
21902189
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
21912190
pub enum GenericParam {
21922191
TypeParam(TypeParam),
2193-
LifetimeParam(LifetimeParam),
21942192
ConstParam(ConstParam),
2193+
LifetimeParam(LifetimeParam),
21952194
}
2196-
impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam);
2195+
impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
21972196

21982197
impl GenericParam {
21992198
pub fn module(self, db: &dyn HirDatabase) -> Module {
22002199
match self {
22012200
GenericParam::TypeParam(it) => it.module(db),
2202-
GenericParam::LifetimeParam(it) => it.module(db),
22032201
GenericParam::ConstParam(it) => it.module(db),
2202+
GenericParam::LifetimeParam(it) => it.module(db),
22042203
}
22052204
}
22062205

22072206
pub fn name(self, db: &dyn HirDatabase) -> Name {
22082207
match self {
22092208
GenericParam::TypeParam(it) => it.name(db),
2210-
GenericParam::LifetimeParam(it) => it.name(db),
22112209
GenericParam::ConstParam(it) => it.name(db),
2210+
GenericParam::LifetimeParam(it) => it.name(db),
22122211
}
22132212
}
22142213
}
22152214

22162215
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22172216
pub struct TypeParam {
2218-
pub(crate) id: TypeParamId,
2217+
pub(crate) id: TypeOrConstParamId,
22192218
}
22202219

22212220
impl TypeParam {
2221+
pub fn merge(self) -> TypeOrConstParam {
2222+
TypeOrConstParam { id: self.id }
2223+
}
2224+
22222225
pub fn name(self, db: &dyn HirDatabase) -> Name {
2223-
let params = db.generic_params(self.id.parent);
2224-
params.types[self.id.local_id].name.clone().unwrap_or_else(Name::missing)
2226+
self.merge().name(db)
22252227
}
22262228

22272229
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2281,13 +2283,23 @@ impl LifetimeParam {
22812283

22822284
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22832285
pub struct ConstParam {
2284-
pub(crate) id: ConstParamId,
2286+
pub(crate) id: TypeOrConstParamId,
22852287
}
22862288

22872289
impl ConstParam {
2290+
pub fn merge(self) -> TypeOrConstParam {
2291+
TypeOrConstParam { id: self.id }
2292+
}
2293+
22882294
pub fn name(self, db: &dyn HirDatabase) -> Name {
22892295
let params = db.generic_params(self.id.parent);
2290-
params.consts[self.id.local_id].name.clone()
2296+
match params.types[self.id.local_id].name() {
2297+
Some(x) => x.clone(),
2298+
None => {
2299+
never!();
2300+
Name::missing()
2301+
}
2302+
}
22912303
}
22922304

22932305
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2301,7 +2313,49 @@ impl ConstParam {
23012313
pub fn ty(self, db: &dyn HirDatabase) -> Type {
23022314
let def = self.id.parent;
23032315
let krate = def.module(db.upcast()).krate();
2304-
Type::new(db, krate, def, db.const_param_ty(self.id))
2316+
Type::new(db, krate, def, db.const_param_ty(self.id).unwrap())
2317+
}
2318+
}
2319+
2320+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2321+
pub struct TypeOrConstParam {
2322+
pub(crate) id: TypeOrConstParamId,
2323+
}
2324+
2325+
impl TypeOrConstParam {
2326+
pub fn name(self, db: &dyn HirDatabase) -> Name {
2327+
let params = db.generic_params(self.id.parent);
2328+
match params.types[self.id.local_id].name() {
2329+
Some(n) => n.clone(),
2330+
_ => Name::missing(),
2331+
}
2332+
}
2333+
2334+
pub fn module(self, db: &dyn HirDatabase) -> Module {
2335+
self.id.parent.module(db.upcast()).into()
2336+
}
2337+
2338+
pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
2339+
self.id.parent.into()
2340+
}
2341+
2342+
pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
2343+
let params = db.generic_params(self.id.parent);
2344+
match &params.types[self.id.local_id] {
2345+
hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
2346+
Either::Right(TypeParam { id: self.id })
2347+
}
2348+
hir_def::generics::TypeOrConstParamData::ConstParamData(_) => {
2349+
Either::Left(ConstParam { id: self.id })
2350+
}
2351+
}
2352+
}
2353+
2354+
pub fn ty(self, db: &dyn HirDatabase) -> Type {
2355+
match self.split(db) {
2356+
Either::Left(x) => x.ty(db),
2357+
Either::Right(x) => x.ty(db),
2358+
}
23052359
}
23062360
}
23072361

crates/hir/src/semantics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl PathResolution {
7272
| PathResolution::Local(_)
7373
| PathResolution::Macro(_)
7474
| PathResolution::ConstParam(_) => None,
75-
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
75+
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam(param.merge().into())),
7676
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
7777
PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
7878
PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {

0 commit comments

Comments
 (0)