Skip to content

Commit

Permalink
Bug fix to type inference with placeholder types for nested types (Fu…
Browse files Browse the repository at this point in the history
…elLabs#3764)

This PR fixes a bug relating to type substitution for placeholder types.
The fix was to update the code path for placeholder type substitution
from "no substitution" to "substitute if a match is found".

This PR also changes the internal data structure of the `TypeMapping`
type from a `Vec<(TypeId, TypeId)>` to a `BTreeMap<TypeId, TypeId>`
because during debugging I noticed that there were duplicates and this
could lead to wasted compute.

Closes FuelLabs#3741

Co-authored-by: emilyaherbert <[email protected]>
  • Loading branch information
emilyaherbert and emilyaherbert authored Jan 12, 2023
1 parent 8f6b21d commit a2ccf3c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 9 deletions.
20 changes: 11 additions & 9 deletions sway-core/src/type_system/type_mapping.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt;
use std::{collections::BTreeMap, fmt};

use super::*;
use crate::engine_threading::*;
Expand All @@ -9,7 +9,7 @@ type DestinationType = TypeId;
/// The [TypeMapping] is used to create a mapping between a [SourceType] (LHS)
/// and a [DestinationType] (RHS).
pub(crate) struct TypeMapping {
mapping: Vec<(SourceType, DestinationType)>,
mapping: BTreeMap<SourceType, DestinationType>,
}

impl DisplayWithEngines for TypeMapping {
Expand Down Expand Up @@ -131,7 +131,7 @@ impl TypeMapping {
type_engine.look_up_type_id(subset),
) {
(TypeInfo::UnknownGeneric { .. }, _) => TypeMapping {
mapping: vec![(superset, subset)],
mapping: BTreeMap::from([(superset, subset)]),
},
(
TypeInfo::Custom {
Expand Down Expand Up @@ -241,10 +241,12 @@ impl TypeMapping {
| (TypeInfo::ErrorRecovery, TypeInfo::ErrorRecovery)
| (TypeInfo::Str(_), TypeInfo::Str(_))
| (TypeInfo::UnsignedInteger(_), TypeInfo::UnsignedInteger(_))
| (TypeInfo::ContractCaller { .. }, TypeInfo::ContractCaller { .. }) => {
TypeMapping { mapping: vec![] }
}
_ => TypeMapping { mapping: vec![] },
| (TypeInfo::ContractCaller { .. }, TypeInfo::ContractCaller { .. }) => TypeMapping {
mapping: BTreeMap::new(),
},
_ => TypeMapping {
mapping: BTreeMap::new(),
},
}
}

Expand Down Expand Up @@ -281,7 +283,7 @@ impl TypeMapping {
let mapping = type_parameters
.into_iter()
.zip(type_arguments.into_iter())
.collect::<Vec<_>>();
.collect();
TypeMapping { mapping }
}

Expand Down Expand Up @@ -309,7 +311,7 @@ impl TypeMapping {
match type_info {
TypeInfo::Custom { .. } => iter_for_match(engines, self, &type_info),
TypeInfo::UnknownGeneric { .. } => iter_for_match(engines, self, &type_info),
TypeInfo::Placeholder(_) => None,
TypeInfo::Placeholder(_) => iter_for_match(engines, self, &type_info),
TypeInfo::Struct {
fields,
name,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
script;

dep utils;

use std::assert::assert;

use utils::*;

struct CustomType {
name: str[3],
}
Expand All @@ -9,8 +15,37 @@ enum MyResult<T, E> {
Err: E,
}

struct SomeStruct<T> {
a: T,
}

fn simple_vec_test() {
let mut vec1 = Vec::new();
let mut vec2 = Vec::new();

vec2.push(54u32);
vec1.push(SomeStruct { a: 42 });

assert(vec1.get(0).unwrap().a == 42);
assert(vec2.get(0).unwrap() == 54u32);
}

fn complex_vec_test() {
let mut exp_vec_in_a_vec_in_a_struct_in_a_vec = Vec::new();
let mut inner_vec_1 = Vec::new();
let inner_inner_vec_1 = vec_from([0, 1, 2]);

inner_vec_1.push(inner_inner_vec_1);
exp_vec_in_a_vec_in_a_struct_in_a_vec.push(SomeStruct { a: inner_vec_1 });

assert(inner_vec_1.get(0).unwrap().get(1).unwrap() == 1);
assert(exp_vec_in_a_vec_in_a_struct_in_a_vec.get(0).unwrap().a.get(0).unwrap().get(2).unwrap() == 2);
}

fn main() {
sell_product();
simple_vec_test();
complex_vec_test();
}

fn sell_product() -> MyResult<bool, CustomType> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
library utils;

pub fn vec_from(vals: [u32; 3]) -> Vec<u32> {
let mut vec = Vec::new();
vec.push(vals[0]);
vec.push(vals[1]);
vec.push(vals[2]);
vec
}

0 comments on commit a2ccf3c

Please sign in to comment.