Changeset - b374c6bff853
[Not reviewed]
0 5 0
MH - 4 years ago 2021-12-14 22:09:53
contact@maxhenger.nl
Fix introduced bugs
5 files changed with 58 insertions and 14 deletions:
0 comments (0 inline, 0 general)
src/protocol/mod.rs
Show inline comments
 
@@ -125,13 +125,13 @@ impl ProtocolDescription {
 
                return Err(ComponentCreationError::InvalidArgumentType(arg_idx));
 
            }
 
        }
 

	
 
        // By now we're sure that all of the arguments are correct. So create
 
        // the connector.
 
        return Ok(Prompt::new(&self.types, &self.heap, definition_id, 0, arguments));
 
        return Ok(Prompt::new(&self.types, &self.heap, definition_id, mono_index, arguments));
 
    }
 

	
 
    fn lookup_module_root(&self, module_name: &[u8]) -> Option<RootId> {
 
        for module in self.modules.iter() {
 
            match &module.name {
 
                Some(name) => if name.as_bytes() == module_name {
src/protocol/parser/pass_typing.rs
Show inline comments
 
@@ -834,13 +834,13 @@ pub(crate) type ResolveQueue = Vec<ResolveQueueElement>;
 

	
 
#[derive(Clone)]
 
struct InferenceExpression {
 
    expr_type: InferenceType,       // result type from expression
 
    expr_id: ExpressionId,          // expression that is evaluated
 
    field_or_monomorph_idx: i32,    // index of field, of index of monomorph array in type table
 
    extra_data_idx: i32,     // index of extra data needed for inference
 
    extra_data_idx: i32,            // index of extra data needed for inference
 
}
 

	
 
impl Default for InferenceExpression {
 
    fn default() -> Self {
 
        Self{
 
            expr_type: InferenceType::default(),
 
@@ -1498,13 +1498,12 @@ impl PassTyping {
 
            // Expression is fine, check if any extra data is attached
 
            if infer_expr.extra_data_idx < 0 { continue; }
 

	
 
            // Extra data is attached, perform typechecking and transfer
 
            // resolved information to the expression
 
            let extra_data = &self.extra_data[infer_expr.extra_data_idx as usize];
 
            if extra_data.poly_vars.is_empty() { continue; }
 

	
 
            // Note that only call and literal expressions need full inference.
 
            // Select expressions also use `extra_data`, but only for temporary
 
            // storage of the struct type whose field it is selecting.
 
            match &ctx.heap[extra_data.expr_id] {
 
                Expression::Call(expr) => {
src/protocol/parser/type_table.rs
Show inline comments
 
@@ -427,13 +427,14 @@ impl Hash for MonomorphKey {
 
    }
 
}
 

	
 
impl PartialEq for MonomorphKey {
 
    fn eq(&self, other: &Self) -> bool {
 
        if self.in_use.is_empty() {
 
            return self.parts == other.parts;
 
            let temp_result = self.parts == other.parts;
 
            return temp_result;
 
        } else {
 
            // Outer type does not match
 
            if self.parts[0] != other.parts[0] {
 
                return false;
 
            }
 

	
 
@@ -488,13 +489,13 @@ impl MonomorphTable {
 
        return Self {
 
            lookup: HashMap::with_capacity(256),
 
            monomorphs: Vec::with_capacity(256),
 
            key: UnsafeCell::new(MonomorphKey{
 
                parts: Vec::with_capacity(32),
 
                in_use: Vec::with_capacity(32),
 
            })
 
            }),
 
        }
 
    }
 

	
 
    fn insert_with_zero_size_and_alignment(&mut self, concrete_type: ConcreteType, in_use: &[PolymorphicVariable], variant: MonomorphVariant) -> i32 {
 
        let key = MonomorphKey{
 
            parts: Vec::from(concrete_type.parts.as_slice()),
 
@@ -511,15 +512,14 @@ impl MonomorphTable {
 
        });
 

	
 
        return index as i32;
 
    }
 

	
 
    fn get_monomorph_index(&self, parts: &[ConcreteTypePart], in_use: &[PolymorphicVariable]) -> Option<i32> {
 
        // Note: the entire goal of this internal `MonomorphKey` is to prevent
 
        // allocation. So:
 
        let key = unsafe {
 
            // Clear-and-extend to, at some point, prevent future allocations
 
            let key = &mut *self.key.get();
 
            key.parts.clear();
 
            key.parts.extend_from_slice(parts);
 
            key.in_use.clear();
 
            key.in_use.extend(in_use.iter().map(|v| v.is_in_use));
 

	
 
@@ -1040,15 +1040,21 @@ impl TypeTable {
 
        Self::check_identifier_collision(
 
            modules, root_id, &arguments, |arg| &arg.identifier, "connector argument"
 
        )?;
 
        Self::check_poly_args_collision(modules, ctx, root_id, &definition.poly_vars)?;
 

	
 
        // Construct internal representation of component
 
        // FIXME: Marking used polymorphic variables on procedures requires
 
        //  making sure that each is used in the body. For now, mark them all
 
        //  as required.
 
        let mut poly_vars = Self::create_polymorphic_variables(&definition.poly_vars);
 
        for argument in &arguments {
 
            Self::mark_used_polymorphic_variables(&mut poly_vars, &argument.parser_type);
 
        // for argument in &arguments {
 
        //     Self::mark_used_polymorphic_variables(&mut poly_vars, &argument.parser_type);
 
        // }
 
        for poly_var in &mut poly_vars {
 
            poly_var.is_in_use = true;
 
        }
 

	
 
        let is_polymorph = poly_vars.iter().any(|arg| arg.is_in_use);
 

	
 
        self.type_lookup.insert(definition_id, DefinedType{
 
            ast_root: root_id,
 
@@ -1761,13 +1767,13 @@ impl TypeTable {
 

	
 
                    breadcrumb.next_member += 1;
 
                }
 

	
 
                // If here then we can compute the memory layout of the tuple.
 
                let mut cur_offset = 0;
 
                let mut max_alignment = 0;
 
                let mut max_alignment = 1;
 

	
 
                let mono_info = self.mono_lookup.get_mut(breadcrumb.monomorph_idx);
 
                let mono_tuple = mono_info.variant.as_tuple_mut();
 
                let mut size_alignment_index = breadcrumb.first_size_alignment_idx;
 
                for member_index in 0..num_members {
 
                    let (member_size, member_alignment) = self.size_alignment_stack[size_alignment_index];
src/protocol/tests/parser_validation.rs
Show inline comments
 
@@ -419,20 +419,51 @@ fn test_correct_tuple_polymorph_args() {
 
            auto c = Option<(Option<(u8, s8)>, Option<(s8, u8)>)>::None;
 
            return 0;
 
        }
 
        "
 
    ).for_union("Option", |u| { u
 
        .assert_has_monomorph("Option<()>")
 
        .assert_has_monomorph("Option<(u32, u64)>")
 
        .assert_has_monomorph("Option<(Option<(u8,s8)>,Option<(s8,u8)>)>");
 
        .assert_has_monomorph("Option<(u32,u64)>")
 
        .assert_has_monomorph("Option<(Option<(u8,s8)>,Option<(s8,u8)>)>")
 
        .assert_size_alignment("Option<()>", 1, 1, 0, 0)
 
        .assert_size_alignment("Option<(u32,u64)>", 24, 8, 0, 0) // (u32, u64) becomes size 16, alignment 8. Hence union tag is aligned to 8
 
        .assert_size_alignment("Option<(Option<(u8,s8)>,Option<(s8,u8)>)>", 7, 1, 0, 0); // inner unions are size 3, alignment 1. Two of those with a tag is size 7
 
    });
 
}
 

	
 
#[test]
 
fn test_incorrect_tuple_polymorph_args() {
 
    todo!("write");
 
    // Do some mismatching brackets. I don't know what else to test
 
    Tester::new_single_source_expect_err(
 
        "mismatch angle bracket",
 
        "
 
        union Option<T>{ Some(T), None }
 
        func f() -> u32 {
 
            auto a = Option<(u32>)::None;
 
            return 0;
 
        }"
 
    ).error(|e| { e
 
        .assert_num(2)
 
        .assert_msg_has(0, "closing '>'").assert_occurs_at(0, ">)::None")
 
        .assert_msg_has(1, "match this '('").assert_occurs_at(1, "(u32>");
 
    });
 

	
 
    Tester::new_single_source_expect_err(
 
        "wrongly placed angle",
 
        "
 
        union O<T>{ S(T), N }
 
        func f() -> u32 {
 
            auto a = O<(<u32>)>::None;
 
            return 0;
 
        }
 
        "
 
    ).error(|e| { e
 
        .assert_num(1)
 
        .assert_msg_has(0, "expected typename")
 
        .assert_occurs_at(0, "<u32");
 
    });
 
}
 

	
 
#[test]
 
fn test_polymorph_array_types() {
 
    Tester::new_single_source_expect_ok(
 
        "array of polymorph in struct",
src/protocol/tests/utils.rs
Show inline comments
 
@@ -970,13 +970,21 @@ fn has_monomorph(ctx: TestCtx, definition_id: DefinitionId, serialized_monomorph
 

	
 
        full_buffer.push('"');
 
    };
 

	
 
    // Bit wasteful, but this is (temporary?) testing code:
 
    for (mono_idx, mono) in ctx.types.mono_lookup.monomorphs.iter().enumerate() {
 
        append_to_full_buffer(&mono.concrete_type, mono_idx);
 
        let got_definition_id = match &mono.concrete_type.parts[0] {
 
            ConcreteTypePart::Instance(v, _) |
 
            ConcreteTypePart::Function(v, _) |
 
            ConcreteTypePart::Component(v, _) => *v,
 
            _ => DefinitionId::new_invalid(),
 
        };
 
        if got_definition_id == definition_id {
 
            append_to_full_buffer(&mono.concrete_type, mono_idx);
 
        }
 
    }
 

	
 
    full_buffer.push(']');
 

	
 
    (has_match, full_buffer)
 
}
0 comments (0 inline, 0 general)