Skip to content

Commit f4918a4

Browse files
committed
Preserve order of generic args
1 parent 342c3c4 commit f4918a4

40 files changed

+642
-414
lines changed

crates/hir/src/attrs.rs

+1-2
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

+37-22
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

+6-4
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

+4-12
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

+82-28
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, SyntaxNodePtr, T,
@@ -2007,32 +2007,31 @@ impl_from!(
20072007
impl GenericDef {
20082008
pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
20092009
let generics = db.generic_params(self.into());
2010-
let ty_params = generics
2011-
.types
2012-
.iter()
2013-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
2014-
.map(GenericParam::TypeParam);
2010+
let ty_params = generics.types.iter().map(|(local_id, _)| {
2011+
let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
2012+
match toc.split(db) {
2013+
Either::Left(x) => GenericParam::ConstParam(x),
2014+
Either::Right(x) => GenericParam::TypeParam(x),
2015+
}
2016+
});
20152017
let lt_params = generics
20162018
.lifetimes
20172019
.iter()
20182020
.map(|(local_id, _)| LifetimeParam {
20192021
id: LifetimeParamId { parent: self.into(), local_id },
20202022
})
20212023
.map(GenericParam::LifetimeParam);
2022-
let const_params = generics
2023-
.consts
2024-
.iter()
2025-
.map(|(local_id, _)| ConstParam { id: ConstParamId { parent: self.into(), local_id } })
2026-
.map(GenericParam::ConstParam);
2027-
ty_params.chain(lt_params).chain(const_params).collect()
2024+
ty_params.chain(lt_params).collect()
20282025
}
20292026

2030-
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
2027+
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
20312028
let generics = db.generic_params(self.into());
20322029
generics
20332030
.types
20342031
.iter()
2035-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
2032+
.map(|(local_id, _)| TypeOrConstParam {
2033+
id: TypeOrConstParamId { parent: self.into(), local_id },
2034+
})
20362035
.collect()
20372036
}
20382037
}
@@ -2221,38 +2220,41 @@ impl Label {
22212220
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22222221
pub enum GenericParam {
22232222
TypeParam(TypeParam),
2224-
LifetimeParam(LifetimeParam),
22252223
ConstParam(ConstParam),
2224+
LifetimeParam(LifetimeParam),
22262225
}
2227-
impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam);
2226+
impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
22282227

22292228
impl GenericParam {
22302229
pub fn module(self, db: &dyn HirDatabase) -> Module {
22312230
match self {
22322231
GenericParam::TypeParam(it) => it.module(db),
2233-
GenericParam::LifetimeParam(it) => it.module(db),
22342232
GenericParam::ConstParam(it) => it.module(db),
2233+
GenericParam::LifetimeParam(it) => it.module(db),
22352234
}
22362235
}
22372236

22382237
pub fn name(self, db: &dyn HirDatabase) -> Name {
22392238
match self {
22402239
GenericParam::TypeParam(it) => it.name(db),
2241-
GenericParam::LifetimeParam(it) => it.name(db),
22422240
GenericParam::ConstParam(it) => it.name(db),
2241+
GenericParam::LifetimeParam(it) => it.name(db),
22432242
}
22442243
}
22452244
}
22462245

22472246
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22482247
pub struct TypeParam {
2249-
pub(crate) id: TypeParamId,
2248+
pub(crate) id: TypeOrConstParamId,
22502249
}
22512250

22522251
impl TypeParam {
2252+
pub fn merge(self) -> TypeOrConstParam {
2253+
TypeOrConstParam { id: self.id }
2254+
}
2255+
22532256
pub fn name(self, db: &dyn HirDatabase) -> Name {
2254-
let params = db.generic_params(self.id.parent);
2255-
params.types[self.id.local_id].name.clone().unwrap_or_else(Name::missing)
2257+
self.merge().name(db)
22562258
}
22572259

22582260
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2315,13 +2317,23 @@ impl LifetimeParam {
23152317

23162318
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
23172319
pub struct ConstParam {
2318-
pub(crate) id: ConstParamId,
2320+
pub(crate) id: TypeOrConstParamId,
23192321
}
23202322

23212323
impl ConstParam {
2324+
pub fn merge(self) -> TypeOrConstParam {
2325+
TypeOrConstParam { id: self.id }
2326+
}
2327+
23222328
pub fn name(self, db: &dyn HirDatabase) -> Name {
23232329
let params = db.generic_params(self.id.parent);
2324-
params.consts[self.id.local_id].name.clone()
2330+
match params.types[self.id.local_id].name() {
2331+
Some(x) => x.clone(),
2332+
None => {
2333+
never!();
2334+
Name::missing()
2335+
}
2336+
}
23252337
}
23262338

23272339
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2335,7 +2347,49 @@ impl ConstParam {
23352347
pub fn ty(self, db: &dyn HirDatabase) -> Type {
23362348
let def = self.id.parent;
23372349
let krate = def.module(db.upcast()).krate();
2338-
Type::new(db, krate, def, db.const_param_ty(self.id))
2350+
Type::new(db, krate, def, db.const_param_ty(self.id).unwrap())
2351+
}
2352+
}
2353+
2354+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2355+
pub struct TypeOrConstParam {
2356+
pub(crate) id: TypeOrConstParamId,
2357+
}
2358+
2359+
impl TypeOrConstParam {
2360+
pub fn name(self, db: &dyn HirDatabase) -> Name {
2361+
let params = db.generic_params(self.id.parent);
2362+
match params.types[self.id.local_id].name() {
2363+
Some(n) => n.clone(),
2364+
_ => Name::missing(),
2365+
}
2366+
}
2367+
2368+
pub fn module(self, db: &dyn HirDatabase) -> Module {
2369+
self.id.parent.module(db.upcast()).into()
2370+
}
2371+
2372+
pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
2373+
self.id.parent.into()
2374+
}
2375+
2376+
pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
2377+
let params = db.generic_params(self.id.parent);
2378+
match &params.types[self.id.local_id] {
2379+
hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
2380+
Either::Right(TypeParam { id: self.id })
2381+
}
2382+
hir_def::generics::TypeOrConstParamData::ConstParamData(_) => {
2383+
Either::Left(ConstParam { id: self.id })
2384+
}
2385+
}
2386+
}
2387+
2388+
pub fn ty(self, db: &dyn HirDatabase) -> Type {
2389+
match self.split(db) {
2390+
Either::Left(x) => x.ty(db),
2391+
Either::Right(x) => x.ty(db),
2392+
}
23392393
}
23402394
}
23412395

crates/hir/src/semantics.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl PathResolution {
7070
| PathResolution::Local(_)
7171
| PathResolution::Macro(_)
7272
| PathResolution::ConstParam(_) => None,
73-
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
73+
PathResolution::TypeParam(param) => Some(TypeNs::GenericParam(param.merge().into())),
7474
PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
7575
PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
7676
PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {

0 commit comments

Comments
 (0)