Skip to content

Commit 2ba3cad

Browse files
committed
Preserve order of generic args
1 parent 355a4bd commit 2ba3cad

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+647
-415
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ exclude = ["crates/proc_macro_test/imp"]
55
[profile.dev]
66
# Disabling debug info speeds up builds a bunch,
77
# and we don't rely on it for debugging that much.
8-
debug = 0
8+
# debug = 0
99

1010
[profile.dev.package]
1111
# These speed up local tests.

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 {
@@ -136,8 +136,8 @@ impl HasSource for Impl {
136136
}
137137
}
138138

139-
impl HasSource for TypeParam {
140-
type Ast = Either<ast::TypeParam, ast::Trait>;
139+
impl HasSource for TypeOrConstParam {
140+
type Ast = Either<ast::TypeOrConstParam, ast::Trait>;
141141
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
142142
let child_source = self.id.parent.child_source(db.upcast());
143143
Some(child_source.map(|it| it[self.id.local_id].clone()))
@@ -151,11 +151,3 @@ impl HasSource for LifetimeParam {
151151
Some(child_source.map(|it| it[self.id.local_id].clone()))
152152
}
153153
}
154-
155-
impl HasSource for ConstParam {
156-
type Ast = ast::ConstParam;
157-
fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
158-
let child_source = self.id.parent.child_source(db.upcast());
159-
Some(child_source.map(|it| it[self.id.local_id].clone()))
160-
}
161-
}

crates/hir/src/lib.rs

+80-26
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ use hir_def::{
4444
nameres,
4545
per_ns::PerNs,
4646
resolver::{HasResolver, Resolver},
47-
AttrDefId, ConstId, ConstParamId, EnumId, FunctionId, GenericDefId, HasModule, LifetimeParamId,
48-
LocalEnumVariantId, LocalFieldId, StaticId, StructId, TypeAliasId, TypeParamId, UnionId,
47+
AttrDefId, ConstId, EnumId, FunctionId, GenericDefId, HasModule, LifetimeParamId,
48+
LocalEnumVariantId, LocalFieldId, StaticId, StructId, TypeAliasId, TypeOrConstParamId, UnionId,
4949
};
5050
use hir_expand::{name::name, MacroCallKind, MacroDefKind};
5151
use hir_ty::{
@@ -66,7 +66,7 @@ use itertools::Itertools;
6666
use nameres::diagnostics::DefDiagnosticKind;
6767
use once_cell::unsync::Lazy;
6868
use rustc_hash::FxHashSet;
69-
use stdx::{format_to, impl_from};
69+
use stdx::{format_to, impl_from, never};
7070
use syntax::{
7171
ast::{self, HasAttrs as _, HasName},
7272
AstNode, AstPtr, SmolStr, SyntaxKind, SyntaxNodePtr,
@@ -1958,32 +1958,31 @@ impl_from!(
19581958
impl GenericDef {
19591959
pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
19601960
let generics = db.generic_params(self.into());
1961-
let ty_params = generics
1962-
.types
1963-
.iter()
1964-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1965-
.map(GenericParam::TypeParam);
1961+
let ty_params = generics.types.iter().map(|(local_id, _)| {
1962+
let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } };
1963+
match toc.split(db) {
1964+
Either::Left(x) => GenericParam::ConstParam(x),
1965+
Either::Right(x) => GenericParam::TypeParam(x),
1966+
}
1967+
});
19661968
let lt_params = generics
19671969
.lifetimes
19681970
.iter()
19691971
.map(|(local_id, _)| LifetimeParam {
19701972
id: LifetimeParamId { parent: self.into(), local_id },
19711973
})
19721974
.map(GenericParam::LifetimeParam);
1973-
let const_params = generics
1974-
.consts
1975-
.iter()
1976-
.map(|(local_id, _)| ConstParam { id: ConstParamId { parent: self.into(), local_id } })
1977-
.map(GenericParam::ConstParam);
1978-
ty_params.chain(lt_params).chain(const_params).collect()
1975+
ty_params.chain(lt_params).collect()
19791976
}
19801977

1981-
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
1978+
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
19821979
let generics = db.generic_params(self.into());
19831980
generics
19841981
.types
19851982
.iter()
1986-
.map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
1983+
.map(|(local_id, _)| TypeOrConstParam {
1984+
id: TypeOrConstParamId { parent: self.into(), local_id },
1985+
})
19871986
.collect()
19881987
}
19891988
}
@@ -2129,38 +2128,41 @@ impl Label {
21292128
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
21302129
pub enum GenericParam {
21312130
TypeParam(TypeParam),
2132-
LifetimeParam(LifetimeParam),
21332131
ConstParam(ConstParam),
2132+
LifetimeParam(LifetimeParam),
21342133
}
2135-
impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam);
2134+
impl_from!(TypeParam, ConstParam, LifetimeParam for GenericParam);
21362135

21372136
impl GenericParam {
21382137
pub fn module(self, db: &dyn HirDatabase) -> Module {
21392138
match self {
21402139
GenericParam::TypeParam(it) => it.module(db),
2141-
GenericParam::LifetimeParam(it) => it.module(db),
21422140
GenericParam::ConstParam(it) => it.module(db),
2141+
GenericParam::LifetimeParam(it) => it.module(db),
21432142
}
21442143
}
21452144

21462145
pub fn name(self, db: &dyn HirDatabase) -> Name {
21472146
match self {
21482147
GenericParam::TypeParam(it) => it.name(db),
2149-
GenericParam::LifetimeParam(it) => it.name(db),
21502148
GenericParam::ConstParam(it) => it.name(db),
2149+
GenericParam::LifetimeParam(it) => it.name(db),
21512150
}
21522151
}
21532152
}
21542153

21552154
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
21562155
pub struct TypeParam {
2157-
pub(crate) id: TypeParamId,
2156+
pub(crate) id: TypeOrConstParamId,
21582157
}
21592158

21602159
impl TypeParam {
2160+
pub fn merge(self) -> TypeOrConstParam {
2161+
TypeOrConstParam { id: self.id }
2162+
}
2163+
21612164
pub fn name(self, db: &dyn HirDatabase) -> Name {
2162-
let params = db.generic_params(self.id.parent);
2163-
params.types[self.id.local_id].name.clone().unwrap_or_else(Name::missing)
2165+
self.merge().name(db)
21642166
}
21652167

21662168
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2220,13 +2222,23 @@ impl LifetimeParam {
22202222

22212223
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
22222224
pub struct ConstParam {
2223-
pub(crate) id: ConstParamId,
2225+
pub(crate) id: TypeOrConstParamId,
22242226
}
22252227

22262228
impl ConstParam {
2229+
pub fn merge(self) -> TypeOrConstParam {
2230+
TypeOrConstParam { id: self.id }
2231+
}
2232+
22272233
pub fn name(self, db: &dyn HirDatabase) -> Name {
22282234
let params = db.generic_params(self.id.parent);
2229-
params.consts[self.id.local_id].name.clone()
2235+
match params.types[self.id.local_id].name() {
2236+
Some(x) => x.clone(),
2237+
None => {
2238+
never!();
2239+
Name::missing()
2240+
}
2241+
}
22302242
}
22312243

22322244
pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -2240,7 +2252,49 @@ impl ConstParam {
22402252
pub fn ty(self, db: &dyn HirDatabase) -> Type {
22412253
let def = self.id.parent;
22422254
let krate = def.module(db.upcast()).krate();
2243-
Type::new(db, krate, def, db.const_param_ty(self.id))
2255+
Type::new(db, krate, def, db.const_param_ty(self.id).unwrap())
2256+
}
2257+
}
2258+
2259+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
2260+
pub struct TypeOrConstParam {
2261+
pub(crate) id: TypeOrConstParamId,
2262+
}
2263+
2264+
impl TypeOrConstParam {
2265+
pub fn name(self, db: &dyn HirDatabase) -> Name {
2266+
let params = db.generic_params(self.id.parent);
2267+
match params.types[self.id.local_id].name() {
2268+
Some(n) => n.clone(),
2269+
_ => Name::missing(),
2270+
}
2271+
}
2272+
2273+
pub fn module(self, db: &dyn HirDatabase) -> Module {
2274+
self.id.parent.module(db.upcast()).into()
2275+
}
2276+
2277+
pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef {
2278+
self.id.parent.into()
2279+
}
2280+
2281+
pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
2282+
let params = db.generic_params(self.id.parent);
2283+
match &params.types[self.id.local_id] {
2284+
hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
2285+
Either::Right(TypeParam { id: self.id })
2286+
}
2287+
hir_def::generics::TypeOrConstParamData::ConstParamData(_) => {
2288+
Either::Left(ConstParam { id: self.id })
2289+
}
2290+
}
2291+
}
2292+
2293+
pub fn ty(self, db: &dyn HirDatabase) -> Type {
2294+
match self.split(db) {
2295+
Either::Left(x) => x.ty(db),
2296+
Either::Right(x) => x.ty(db),
2297+
}
22442298
}
22452299
}
22462300

0 commit comments

Comments
 (0)