Skip to content

Commit 629cc29

Browse files
committed
Add trait type parameters to the type engine.
1 parent 2485bfd commit 629cc29

File tree

6 files changed

+60
-25
lines changed

6 files changed

+60
-25
lines changed

sway-core/src/abi_generation/abi_str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl TypeInfo {
9393
Never => "never".into(),
9494
UnknownGeneric { name, .. } => name.to_string(),
9595
Placeholder(_) => "_".to_string(),
96-
TypeParam(n) => format!("typeparam({n})"),
96+
TypeParam(param) => format!("typeparam({})", param.name),
9797
StringSlice => "str".into(),
9898
StringArray(length) => format!("str[{}]", length.val()),
9999
UnsignedInteger(x) => match x {

sway-core/src/abi_generation/evm_abi.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ pub fn abi_str(type_info: &TypeInfo, engines: &Engines) -> String {
6969
Never => "never".into(),
7070
UnknownGeneric { name, .. } => name.to_string(),
7171
Placeholder(_) => "_".to_string(),
72-
TypeParam(n) => format!("typeparam({n})"),
72+
TypeParam(param) => format!("typeparam({})", param.name),
7373
StringSlice => "str".into(),
7474
StringArray(x) => format!("str[{}]", x.val()),
7575
UnsignedInteger(x) => match x {

sway-core/src/semantic_analysis/namespace/trait_map.rs

+8-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
},
2525
type_system::{SubstTypes, TypeId},
2626
IncludeSelf, SubstTypesContext, TraitConstraint, TypeArgument, TypeEngine, TypeInfo,
27-
TypeParameter, TypeSubstMap, UnifyCheck,
27+
TypeSubstMap, UnifyCheck,
2828
};
2929

3030
use super::Module;
@@ -102,17 +102,16 @@ type TraitName = Arc<CallPath<TraitSuffix>>;
102102
pub(crate) struct TraitKey {
103103
pub(crate) name: TraitName,
104104
pub(crate) type_id: TypeId,
105-
pub(crate) impl_type_parameters: Vec<TypeParameter>,
105+
pub(crate) impl_type_parameters: Vec<TypeId>,
106106
pub(crate) trait_decl_span: Option<Span>,
107107
}
108108

109109
impl OrdWithEngines for TraitKey {
110110
fn cmp(&self, other: &Self, ctx: &OrdWithEnginesContext) -> std::cmp::Ordering {
111111
self.name.cmp(&other.name, ctx).then_with(|| {
112-
self.type_id.cmp(&other.type_id).then_with(|| {
113-
self.impl_type_parameters
114-
.cmp(&other.impl_type_parameters, ctx)
115-
})
112+
self.type_id
113+
.cmp(&other.type_id)
114+
.then_with(|| self.impl_type_parameters.cmp(&other.impl_type_parameters))
116115
})
117116
}
118117
}
@@ -174,7 +173,6 @@ pub(crate) enum TypeRootFilter {
174173
Unknown,
175174
Never,
176175
Placeholder,
177-
TypeParam(usize),
178176
StringSlice,
179177
StringArray(usize),
180178
U8,
@@ -234,7 +232,7 @@ impl TraitMap {
234232
trait_name: CallPath,
235233
trait_type_args: Vec<TypeArgument>,
236234
type_id: TypeId,
237-
impl_type_parameters: Vec<TypeParameter>,
235+
impl_type_parameters: Vec<TypeId>,
238236
items: &[ResolvedTraitImplItem],
239237
impl_span: &Span,
240238
trait_decl_span: Option<Span>,
@@ -465,7 +463,7 @@ impl TraitMap {
465463
impl_span: Span,
466464
trait_decl_span: Option<Span>,
467465
type_id: TypeId,
468-
impl_type_parameters: Vec<TypeParameter>,
466+
impl_type_parameters: Vec<TypeId>,
469467
trait_methods: TraitItems,
470468
engines: &Engines,
471469
) {
@@ -1491,7 +1489,7 @@ impl TraitMap {
14911489
Unknown => TypeRootFilter::Unknown,
14921490
Never => TypeRootFilter::Never,
14931491
UnknownGeneric { .. } | Placeholder(_) => TypeRootFilter::Placeholder,
1494-
TypeParam(n) => TypeRootFilter::TypeParam(*n),
1492+
TypeParam(_param) => unreachable!(),
14951493
StringSlice => TypeRootFilter::StringSlice,
14961494
StringArray(x) => TypeRootFilter::StringArray(x.val()),
14971495
UnsignedInteger(x) => match x {

sway-core/src/semantic_analysis/type_check_context.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,11 @@ impl<'a> TypeCheckContext<'a> {
13071307
})
13081308
});
13091309

1310+
let impl_type_parameters_ids = impl_type_parameters
1311+
.iter()
1312+
.map(|type_parameter| engines.te().new_type_param(type_parameter.clone()))
1313+
.collect::<Vec<_>>();
1314+
13101315
// CallPath::to_fullpath gives a resolvable path, but is not guaranteed to provide the path
13111316
// to the actual trait declaration. Since the path of the trait declaration is used as a key
13121317
// in the trait map, we need to find the actual declaration path.
@@ -1325,7 +1330,7 @@ impl<'a> TypeCheckContext<'a> {
13251330
canonical_trait_path,
13261331
trait_type_args,
13271332
type_id,
1328-
impl_type_parameters,
1333+
impl_type_parameters_ids,
13291334
&items,
13301335
impl_span,
13311336
trait_decl_span,

sway-core/src/type_system/engine.rs

+37-5
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,24 @@ impl TypeEngine {
393393
)
394394
}
395395

396+
/// Inserts a new [TypeInfo::TypeParam] into the [TypeEngine] and returns its [TypeId].
397+
///
398+
/// [TypeInfo::TypeParam] is an always replaceable type and the method
399+
/// guarantees that a new (or unused) [TypeId] will be returned on every
400+
/// call.
401+
pub(crate) fn new_type_param(&self, type_parameter: TypeParameter) -> TypeId {
402+
self.new_type_param_impl(TypeInfo::TypeParam(type_parameter))
403+
}
404+
405+
fn new_type_param_impl(&self, type_param: TypeInfo) -> TypeId {
406+
let source_id = self.get_type_parameter_fallback_source_id(&type_param);
407+
let tsi = TypeSourceInfo {
408+
type_info: type_param.into(),
409+
source_id,
410+
};
411+
TypeId::new(self.slab.insert(tsi))
412+
}
413+
396414
/// Inserts a new [TypeInfo::Placeholder] into the [TypeEngine] and returns its [TypeId].
397415
///
398416
/// [TypeInfo::Placeholder] is an always replaceable type and the method
@@ -831,6 +849,7 @@ impl TypeEngine {
831849
TypeInfo::Unknown => return self.new_unknown(),
832850
TypeInfo::Numeric => return self.new_numeric(),
833851
TypeInfo::Placeholder(_) => return self.new_placeholder_impl(ty),
852+
TypeInfo::TypeParam(_) => return self.new_type_param_impl(ty),
834853
TypeInfo::UnknownGeneric { .. } => return self.new_unknown_generic_impl(ty),
835854
_ => (),
836855
}
@@ -1000,9 +1019,6 @@ impl TypeEngine {
10001019
| TypeInfo::Contract
10011020
| TypeInfo::Never => false,
10021021

1003-
// Note that `TypeParam` is currently not used at all.
1004-
TypeInfo::TypeParam(_) => false,
1005-
10061022
// `StringArray`s are not changeable. We will have one shared
10071023
// `TypeInfo` instance for every string size. Note that in case
10081024
// of explicitly defined string arrays, e.g. in the storage or type ascriptions
@@ -1015,6 +1031,7 @@ impl TypeEngine {
10151031
TypeInfo::Unknown
10161032
| TypeInfo::Numeric
10171033
| TypeInfo::Placeholder(_)
1034+
| TypeInfo::TypeParam(_)
10181035
| TypeInfo::UnknownGeneric { .. } => true,
10191036

10201037
// The `ContractCaller` can be replaceable, and thus, sometimes changeable.
@@ -1104,8 +1121,7 @@ impl TypeEngine {
11041121
| TypeInfo::Never
11051122
| TypeInfo::Unknown
11061123
| TypeInfo::Numeric
1107-
| TypeInfo::Contract
1108-
| TypeInfo::TypeParam(_) => false,
1124+
| TypeInfo::Contract => false,
11091125

11101126
// Types that are always distinguishable because they have the `name: Ident`.
11111127
//
@@ -1232,6 +1248,7 @@ impl TypeEngine {
12321248
// The above reasoning for `TypeArgument`s applies also for the `TypeParameter`s.
12331249
// We only need to check if the `tp` is annotated.
12341250
TypeInfo::Placeholder(tp) => tp.is_annotated(),
1251+
TypeInfo::TypeParam(tp) => tp.is_annotated(),
12351252

12361253
// TODO: Improve handling of `TypeInfo::Custom` and `TypeInfo::TraitType`` within the `TypeEngine`:
12371254
// https://github.com/FuelLabs/sway/issues/6601
@@ -1718,6 +1735,21 @@ impl TypeEngine {
17181735
self.get_source_id_from_type_parameter(tp)
17191736
}
17201737

1738+
fn get_type_parameter_fallback_source_id(&self, type_param: &TypeInfo) -> Option<SourceId> {
1739+
// `TypeInfo::TypeParam` is an always replaceable type and we know we will
1740+
// get a new instance of it in the engine for every trait type parameter occurrence. This means
1741+
// that it can never happen that instances from different source files point
1742+
// to the same `TypeSourceInfo`. Therefore, we can safely remove an instance
1743+
// of a `TypeParam` from the engine if its source file is garbage collected.
1744+
//
1745+
// The source file itself is always the one in which the `name` is situated.
1746+
let TypeInfo::TypeParam(tp) = &type_param else {
1747+
unreachable!("The `placeholder` is checked to be of variant `TypeInfo::TypeParam`.");
1748+
};
1749+
1750+
self.get_source_id_from_type_parameter(tp)
1751+
}
1752+
17211753
fn get_unknown_generic_fallback_source_id(unknown_generic: &TypeInfo) -> Option<SourceId> {
17221754
// `TypeInfo::UnknownGeneric` is an always replaceable type and we know we will
17231755
// get a new instance of it in the engine for every, e.g., "<T1>", "<T2>", etc. occurrence.

sway-core/src/type_system/info.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub enum TypeInfo {
107107
///
108108
/// NOTE: This type is *not used yet*.
109109
// https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/enum.TyKind.html#variant.Param
110-
TypeParam(usize),
110+
TypeParam(TypeParameter),
111111
StringSlice,
112112
StringArray(NumericLength),
113113
UnsignedInteger(IntegerBits),
@@ -226,8 +226,8 @@ impl HashWithEngines for TypeInfo {
226226
TypeInfo::Placeholder(ty) => {
227227
ty.hash(state, engines);
228228
}
229-
TypeInfo::TypeParam(n) => {
230-
n.hash(state);
229+
TypeInfo::TypeParam(param) => {
230+
param.hash(state, engines);
231231
}
232232
TypeInfo::Alias { name, ty } => {
233233
name.hash(state);
@@ -287,7 +287,7 @@ impl PartialEqWithEngines for TypeInfo {
287287
},
288288
) => l == r && ltc.eq(rtc, ctx),
289289
(Self::Placeholder(l), Self::Placeholder(r)) => l.eq(r, ctx),
290-
(Self::TypeParam(l), Self::TypeParam(r)) => l == r,
290+
(Self::TypeParam(l), Self::TypeParam(r)) => l.eq(r, ctx),
291291
(
292292
Self::Custom {
293293
qualified_call_path: l_name,
@@ -544,7 +544,7 @@ impl DisplayWithEngines for TypeInfo {
544544
Never => "!".into(),
545545
UnknownGeneric { name, .. } => name.to_string(),
546546
Placeholder(type_param) => type_param.name.to_string(),
547-
TypeParam(n) => format!("{n}"),
547+
TypeParam(param) => format!("{}", param.name),
548548
StringSlice => "str".into(),
549549
StringArray(x) => format!("str[{}]", x.val()),
550550
UnsignedInteger(x) => match x {
@@ -662,7 +662,7 @@ impl DebugWithEngines for TypeInfo {
662662
}
663663
}
664664
Placeholder(t) => format!("placeholder({:?})", engines.help_out(t)),
665-
TypeParam(n) => format!("typeparam({n})"),
665+
TypeParam(param) => format!("typeparam({})", param.name),
666666
StringSlice => "str".into(),
667667
StringArray(x) => format!("str[{}]", x.val()),
668668
UnsignedInteger(x) => match x {
@@ -1650,7 +1650,7 @@ impl TypeInfo {
16501650
Never => "never".into(),
16511651
UnknownGeneric { name, .. } => name.to_string(),
16521652
Placeholder(_) => "_".to_string(),
1653-
TypeParam(n) => format!("typeparam({n})"),
1653+
TypeParam(param) => format!("typeparam({})", param.name),
16541654
StringSlice => "str".into(),
16551655
StringArray(x) => format!("str[{}]", x.val()),
16561656
UnsignedInteger(x) => match x {

0 commit comments

Comments
 (0)