Add layout for trait object in resolver

ffdd11dde6247cc5fceebb698a968dac3f9b3a1fbdb803edfbf3ad15676b9de4
After this commit, `*opaque Allocator` and `*mut opaque Allocator` are
valid types that can appear in function signatures, let bindings,
and record fields.
Alexis Sellier committed ago 1 parent 40c5b38c
lib/std/lang/lower.rad +1 -0
3681 3681
        case resolver::Type::Nominal(_) => {
3682 3682
            // Void unions are small enough to pass by value.
3683 3683
            return not resolver::isVoidUnion(typ);
3684 3684
        }
3685 3685
        case resolver::Type::Slice { .. } => return true,
3686 +
        case resolver::Type::TraitObject { .. } => return true,
3686 3687
        case resolver::Type::Array(_) => return true,
3687 3688
        case resolver::Type::Nil => return true,
3688 3689
        else => {
3689 3690
            // Optional pointers are scalar (single word). All other
3690 3691
            // optionals, including optional slices with NPO, are aggregates.
lib/std/lang/resolver.rad +17 -3
256 256
    Optional(*Type),
257 257
    /// Eg. `fn id(i32) -> i32`.
258 258
    Fn(*FnType),
259 259
    /// Named, ie. user-defined types, includes union variants.
260 260
    Nominal(*NominalType),
261 +
    /// Trait object. An erased type with v-table.
262 +
    TraitObject {
263 +
        /// Trait definition.
264 +
        traitInfo: *TraitType,
265 +
        /// Whether the pointer is mutable.
266 +
        mutable: bool,
267 +
    },
261 268
}
262 269
263 270
/// Structured diagnostic payload for type mismatches.
264 271
pub record TypeMismatch {
265 272
    expected: Type,
1307 1314
        case Type::Slice { .. } => return Layout { size: PTR_SIZE * 2, alignment: PTR_SIZE },
1308 1315
        case Type::Array(arr) => return getArrayLayout(arr),
1309 1316
        case Type::Optional(inner) => return getOptionalLayout(*inner),
1310 1317
        case Type::Nominal(info) => return getNominalLayout(*info),
1311 1318
        case Type::Fn(_) => return Layout { size: PTR_SIZE, alignment: PTR_SIZE },
1319 +
        case Type::TraitObject { .. } => return Layout { size: PTR_SIZE * 2, alignment: PTR_SIZE },
1312 1320
        else => {
1313 1321
            panic "getTypeLayout: the given type cannot be layed out";
1314 1322
        }
1315 1323
    }
1316 1324
}
5582 5590
            } else {
5583 5591
                fnType.returnType = allocType(self, Type::Void);
5584 5592
            }
5585 5593
            return Type::Fn(allocFnType(self, fnType));
5586 5594
        }
5587 -
        case ast::TypeSig::TraitObject { .. } => {
5588 -
            // TODO.
5589 -
            throw emitError(self, node, ErrorKind::Internal);
5595 +
        case ast::TypeSig::TraitObject { traitName, mutable } => {
5596 +
            let name = try nodeName(self, traitName);
5597 +
            let sym = findAnySymbol(self.scope, name)
5598 +
                else throw emitError(self, traitName, ErrorKind::UnresolvedSymbol(name));
5599 +
            let case SymbolData::Trait(traitInfo) = sym.data
5600 +
                else throw emitError(self, traitName, ErrorKind::Internal);
5601 +
            try setNodeSymbol(self, traitName, sym);
5602 +
5603 +
            return Type::TraitObject { traitInfo, mutable };
5590 5604
        }
5591 5605
    }
5592 5606
}
5593 5607
5594 5608
/// Check if a type can be used for inferrence.
lib/std/lang/resolver/printer.rad +8 -0
136 136
                printNominalTypeName(info);
137 137
            } else {
138 138
                printNominalType(info);
139 139
            }
140 140
        }
141 +
        case super::Type::TraitObject { traitInfo, mutable } => {
142 +
            io::print("*");
143 +
            if mutable {
144 +
                io::print("mut ");
145 +
            }
146 +
            io::print("opaque ");
147 +
            io::print(traitInfo.name);
148 +
        }
141 149
        case super::Type::Range { start, end } => {
142 150
            if let s = start {
143 151
                printTypeBody(*s, brief);
144 152
            }
145 153
            io::print("..");