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.
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(".."); |