Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the concept of semantic similarity to the type system #1958

Merged
merged 50 commits into from
Jun 21, 2022
Merged
Show file tree
Hide file tree
Changes from 49 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
bf6fdc3
Do not rely on TypeMapping when type checking declarations.
Jun 10, 2022
681ce59
Prevent leaking types in impls.
Jun 10, 2022
3f0e80c
Prevent unconstrained type parameters.
Jun 10, 2022
fde6b33
WIP
Jun 13, 2022
a1a968e
Merge with master.
Jun 13, 2022
4e34bf6
Merge remote-tracking branch 'origin/master' into emilyaherbert/preve…
Jun 13, 2022
503a183
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
ec9881e
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
e4fbc35
Merge branch 'emilyaherbert/type-parameters' into emilyaherbert/preve…
Jun 13, 2022
577ed59
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
56a1c6b
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
966f110
Merge remote-tracking branch 'origin/master' into emilyaherbert/type-…
Jun 13, 2022
b6c8389
Merge branch 'emilyaherbert/type-parameters' into emilyaherbert/preve…
Jun 13, 2022
8f173f1
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
ba48b7f
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
ba2574a
Merge branch 'master' into emilyaherbert/prevent-leaking-types
emilyaherbert Jun 13, 2022
60ed360
clippy
Jun 13, 2022
5b23513
Merge branch 'emilyaherbert/prevent-leaking-types' into emilyaherbert…
emilyaherbert Jun 13, 2022
5224c7e
Merge remote-tracking branch 'origin' into emilyaherbert-1898-2/seman…
Jun 13, 2022
90038d6
Merge remote-tracking branch 'origin/emilyaherbert-1143-3/disallow-un…
Jun 13, 2022
6650bf2
WIP
Jun 13, 2022
b403607
Use TypeId in TypeMapping and in TraitMap.
Jun 13, 2022
83d4674
Merge remote-tracking branch 'origin/emilyaherbert/use-type-id' into …
Jun 13, 2022
6f8c116
Add semantic type constraints.
Jun 13, 2022
1e90bce
Merge remote-tracking branch 'origin/master' into emilyaherbert-1898-…
Jun 13, 2022
d8a7b91
Update test case.
Jun 13, 2022
bdfa17e
Merge remote-tracking branch 'origin/master' into emilyaherbert-1143-…
Jun 14, 2022
f43e418
Merge remote-tracking branch 'origin/master' into emilyaherbert/use-t…
Jun 14, 2022
9163a4a
Merge branch 'emilyaherbert-1143-3/disallow-unconstrained-type-parame…
Jun 14, 2022
0b59080
Merge branch 'emilyaherbert/use-type-id' into emilyaherbert-1898-2/se…
Jun 14, 2022
1e7d3ce
fix
Jun 14, 2022
bccc7a0
Merge remote-tracking branch 'origin/master' into emilyaherbert-1898-…
Jun 16, 2022
ff97c79
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 16, 2022
8f1ace7
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 16, 2022
3942946
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 16, 2022
dc600b2
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 16, 2022
b422009
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 16, 2022
1adbaca
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 17, 2022
3b5e2f1
Bug is fixed.
Jun 17, 2022
22207cc
Merge branch 'emilyaherbert-1898-2/semantic-type-constraints' of gith…
Jun 17, 2022
60ff0aa
Add forc.lock.
Jun 17, 2022
a7b19ef
update
Jun 17, 2022
61b6968
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 17, 2022
d7e81c5
Move test to inside of the SDK.
Jun 20, 2022
40dbda6
Merge branch 'emilyaherbert-1898-2/semantic-type-constraints' of gith…
Jun 20, 2022
997747e
Fix test cases.
Jun 20, 2022
c80f9a7
Merge remote-tracking branch 'origin/master' into emilyaherbert-1898-…
Jun 20, 2022
75efbef
Add lock files.
Jun 20, 2022
7e98ff0
Fix test.
Jun 20, 2022
fbcc1b0
Merge branch 'master' into emilyaherbert-1898-2/semantic-type-constra…
emilyaherbert Jun 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sway-core/src/ir_generation/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn const_eval_typed_expr(
TypedExpressionVariant::StructExpression { fields, .. } => {
let (field_typs, field_vals): (Vec<_>, Vec<_>) = fields
.iter()
.filter_map(|TypedStructExpressionField { name: _, value }| {
.filter_map(|TypedStructExpressionField { name: _, value, .. }| {
const_eval_typed_expr(context, module, known_consts, value)
.map(|cv| (value.return_type, cv))
})
Expand Down
11 changes: 10 additions & 1 deletion sway-core/src/parse_tree/declaration/type_parameter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::{error::*, parse_tree::*, semantic_analysis::*, type_engine::*};

use sway_types::{ident::Ident, span::Span, Spanned};

use std::hash::{Hash, Hasher};
use std::{
fmt,
hash::{Hash, Hasher},
};

#[derive(Debug, Clone, Eq)]
pub struct TypeParameter {
Expand Down Expand Up @@ -57,6 +60,12 @@ impl ReplaceSelfType for TypeParameter {
}
}

impl fmt::Display for TypeParameter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.name_ident, self.type_id)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we say {} (id {}) instead? {}: {} introduces ambiguity IMO because it looks like a trait constraint

}
}

impl TypeParameter {
pub(crate) fn type_check(
type_parameter: TypeParameter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ where

fn monomorphize(
self,
type_arguments: Vec<TypeArgument>,
mut type_arguments: Vec<TypeArgument>,
enforce_type_arguments: EnforceTypeArguments,
self_type: Option<TypeId>,
call_site_span: Option<&Span>,
Expand Down Expand Up @@ -107,7 +107,6 @@ where
err(warnings, errors)
}
(false, false) => {
let mut type_arguments = type_arguments;
for type_argument in type_arguments.iter_mut() {
let type_id = match self_type {
Some(self_type) => namespace.resolve_type_with_self(
Expand Down Expand Up @@ -191,13 +190,15 @@ pub(crate) trait MonomorphizeHelper {
fn monomorphize_inner(self, type_mapping: &TypeMapping, namespace: &mut Items) -> Self::Output;
}

pub(crate) fn monomorphize_inner<T>(decl: T, type_mapping: &TypeMapping, namespace: &mut Items) -> T
pub(crate) fn monomorphize_inner<T>(
decl: T,
type_mapping: &TypeMapping,
_namespace: &mut Items,
) -> T
where
T: CopyTypes + CreateTypeId,
{
let old_type_id = decl.create_type_id();
let mut new_decl = decl;
new_decl.copy_types(type_mapping);
namespace.copy_methods_to_type(old_type_id, new_decl.create_type_id(), type_mapping);
new_decl
}
27 changes: 0 additions & 27 deletions sway-core/src/semantic_analysis/namespace/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,33 +138,6 @@ impl Items {
.get_methods_for_type(implementing_for_type_id)
}

// Given a TypeInfo old_type with a set of methods available to it, make those same methods
// available to TypeInfo new_type. This is useful in situations where old_type is being
// monomorphized to new_type and and we want `get_methods_for_type()` to return the same set of
// methods for new_type as it does for old_type.
pub(crate) fn copy_methods_to_type(
&mut self,
old_type: TypeId,
new_type: TypeId,
type_mapping: &TypeMapping,
) {
// This map grabs all (trait name, vec of methods) from self.implemented_traits
// corresponding to `old_type`.
let methods = self
.implemented_traits
.get_methods_for_type_by_trait(old_type);

// Insert into `self.implemented_traits` the contents of the map above but with `new_type`
// as the `TypeInfo` key.
for (trait_name, mut trait_methods) in methods.into_iter() {
trait_methods
.iter_mut()
.for_each(|method| method.copy_types(type_mapping));
self.implemented_traits
.insert(trait_name, new_type, trait_methods);
}
}

pub(crate) fn get_canonical_path(&self, symbol: &Ident) -> &[Ident] {
self.use_synonyms.get(symbol).map(|v| &v[..]).unwrap_or(&[])
}
Expand Down
40 changes: 11 additions & 29 deletions sway-core/src/semantic_analysis/namespace/trait_map.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use crate::{
type_engine::{look_up_type_id, TypeId},
type_engine::{create_type_mapping, look_up_type_id, CopyTypes, TypeId},
CallPath, TypeInfo, TypedFunctionDeclaration,
};

use std::collections::HashMap;

type TraitName = CallPath;

// This cannot be a HashMap because of how TypeInfo's are handled.
Expand Down Expand Up @@ -46,8 +44,7 @@ impl TraitMap {
) {
let mut methods_map = im::HashMap::new();
for method in methods.into_iter() {
let method_name = method.name.as_str().to_string();
methods_map.insert(method_name, method);
methods_map.insert(method.name.as_str().to_string(), method);
}
self.trait_map
.push_back(((trait_name, incoming_type_id), methods_map));
Expand All @@ -69,7 +66,7 @@ impl TraitMap {
) -> Vec<((CallPath, TypeId), Vec<TypedFunctionDeclaration>)> {
let mut ret = vec![];
for ((call_path, map_type_id), methods) in self.trait_map.iter() {
if look_up_type_id(*map_type_id) == look_up_type_id(incoming_type_id) {
if look_up_type_id(incoming_type_id).is_subset_of(&look_up_type_id(*map_type_id)) {
ret.push((
(call_path.clone(), *map_type_id),
methods.values().cloned().collect(),
Expand All @@ -88,29 +85,14 @@ impl TraitMap {
if look_up_type_id(incoming_type_id) == TypeInfo::ErrorRecovery {
return methods;
}
for ((_, map_type_id), l_methods) in self.trait_map.iter() {
if look_up_type_id(*map_type_id) == look_up_type_id(incoming_type_id) {
methods.append(&mut l_methods.values().cloned().collect());
}
}
methods
}

pub(crate) fn get_methods_for_type_by_trait(
&self,
incoming_type_id: TypeId,
) -> HashMap<TraitName, Vec<TypedFunctionDeclaration>> {
let mut methods: HashMap<TraitName, Vec<TypedFunctionDeclaration>> = HashMap::new();
// small performance gain in bad case
if look_up_type_id(incoming_type_id) == TypeInfo::ErrorRecovery {
return methods;
}
for ((trait_name, map_type_id), trait_methods) in self.trait_map.iter() {
if look_up_type_id(*map_type_id) == look_up_type_id(incoming_type_id) {
methods.insert(
(*trait_name).clone(),
trait_methods.values().cloned().collect(),
);
for ((_, map_type_id), trait_methods) in self.trait_map.iter() {
if look_up_type_id(incoming_type_id).is_subset_of(&look_up_type_id(*map_type_id)) {
let type_mapping = create_type_mapping(*map_type_id, incoming_type_id);
let mut trait_methods = trait_methods.values().cloned().collect::<Vec<_>>();
trait_methods
.iter_mut()
.for_each(|x| x.copy_types(&type_mapping));
methods.append(&mut trait_methods);
}
}
methods
Expand Down
Loading