lang: Rename Linear marker to Once

b6abab3681d90482de5514902eca21b6d37680764ee6853ef815bfd47b0c4234
Alexis Sellier committed ago 1 parent 702b8915
lib/std/lang/resolver.rad +4 -4
168 168
export record RecordType: Copy {
169 169
    fields: *[RecordField],
170 170
    labeled: bool,
171 171
    /// Cached layout.
172 172
    layout: Layout,
173 -
    /// Whether the declaration explicitly carries the `Linear` marker.
173 +
    /// Whether the declaration explicitly carries the `Once` marker.
174 174
    declaredLinear: bool,
175 175
    /// Whether the declaration explicitly carries the `Copy` marker.
176 176
    declaredCopy: bool,
177 177
}
178 178
183 183
    layout: Layout,
184 184
    /// Cached payload offset within the union aggregate.
185 185
    valOffset: u32,
186 186
    /// If all variants have void payloads.
187 187
    isAllVoid: bool,
188 -
    /// Whether the declaration explicitly carries the `Linear` marker.
188 +
    /// Whether the declaration explicitly carries the `Once` marker.
189 189
    declaredLinear: bool,
190 190
    /// Whether the declaration explicitly carries the `Copy` marker.
191 191
    declaredCopy: bool,
192 192
}
193 193
617 617
    LinearOverwrite,
618 618
    /// `undefined` cannot initialize a linear type.
619 619
    LinearUndefined,
620 620
    /// A `Copy` declaration contains a non-copy field or variant.
621 621
    CopyContainsNonCopy,
622 -
    /// A declaration carries both `Copy` and `Linear`.
622 +
    /// A declaration carries both `Copy` and `Once`.
623 623
    ConflictingOwnershipMarkers,
624 624
    /// A reference appears in a storable or escaping position.
625 625
    InvalidRefPosition,
626 626
    /// A reference cannot be bound to a local.
627 627
    RefBinding,
3462 3462
    throws (ResolveError)
3463 3463
{
3464 3464
    let mut result = OwnershipMarkers { linear: false, copy: false };
3465 3465
    for derive in derives {
3466 3466
        let name = try nodeName(self, derive);
3467 -
        if mem::eq(name, "Linear") {
3467 +
        if mem::eq(name, "Once") {
3468 3468
            if result.linear {
3469 3469
                throw emitError(self, derive, ErrorKind::DuplicateBinding(name));
3470 3470
            }
3471 3471
            if result.copy {
3472 3472
                throw emitError(self, derive, ErrorKind::ConflictingOwnershipMarkers);
lib/std/lang/resolver/printer.rad +1 -1
525 525
        }
526 526
        case super::ErrorKind::CopyContainsNonCopy => {
527 527
            io::print("`Copy` composite contains a non-copy value");
528 528
        }
529 529
        case super::ErrorKind::ConflictingOwnershipMarkers => {
530 -
            io::print("a composite cannot be both `Copy` and `Linear`");
530 +
            io::print("a composite cannot be both `Copy` and `Once`");
531 531
        }
532 532
        case super::ErrorKind::InvalidRefPosition => {
533 533
            io::print("reference type is only allowed as a function parameter");
534 534
        }
535 535
        case super::ErrorKind::RefBinding => {
lib/std/lang/resolver/tests.rad +39 -39
5171 5171
}
5172 5172
5173 5173
/// References cannot escape through return types.
5174 5174
@test fn testRefReturnRejected() throws (testing::TestError) {
5175 5175
    let mut a = testResolver();
5176 -
    let program = "record Marker: Linear {} fn bad(value: &u32) -> &u32 { return value; }";
5176 +
    let program = "record Marker: Once {} fn bad(value: &u32) -> &u32 { return value; }";
5177 5177
    let result = try resolveProgramStr(&mut a, program);
5178 5178
    try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5179 5179
}
5180 5180
5181 5181
/// Case-pattern fallbacks must terminate instead of synthesizing bindings.
5195 5195
}
5196 5196
5197 5197
/// Unsafe pointer dereference requires an unsafe declaration.
5198 5198
@test fn testUnsafePointerOperationRejected() throws (testing::TestError) {
5199 5199
    let mut a = testResolver();
5200 -
    let program = "record Marker: Linear {} fn load(pointer: *unsafe u32) -> u32 { return *pointer; }";
5200 +
    let program = "record Marker: Once {} fn load(pointer: *unsafe u32) -> u32 { return *pointer; }";
5201 5201
    let result = try resolveProgramStr(&mut a, program);
5202 5202
    try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5203 5203
}
5204 5204
5205 5205
/// Unsafe pointers remain freely copyable inside an unsafe declaration.
5206 5206
@test fn testUnsafePointerOperationAllowed() throws (testing::TestError) {
5207 -
    let program = "record Marker: Linear {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; }";
5207 +
    let program = "record Marker: Once {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; }";
5208 5208
    try expectAnalyzeOk(program);
5209 5209
}
5210 5210
5211 5211
/// Safe code cannot call a function that accepts unsafe operations.
5212 5212
@test fn testUnsafeFunctionCallRejected() throws (testing::TestError) {
5213 5213
    let mut a = testResolver();
5214 -
    let program = "record Marker: Linear {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; } fn run(pointer: *unsafe u32) -> u32 { return load(pointer); }";
5214 +
    let program = "record Marker: Once {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; } fn run(pointer: *unsafe u32) -> u32 { return load(pointer); }";
5215 5215
    let result = try resolveProgramStr(&mut a, program);
5216 5216
    try expectErrorKind(&result, super::ErrorKind::UnsafeCall);
5217 5217
}
5218 5218
5219 5219
/// Unsafe function values retain their call-site safety requirement.
5225 5225
}
5226 5226
5227 5227
/// References cannot be embedded in aggregate fields.
5228 5228
@test fn testRefFieldRejected() throws (testing::TestError) {
5229 5229
    let mut a = testResolver();
5230 -
    let program = "record Marker: Linear {} record Bad { value: &u32 }";
5230 +
    let program = "record Marker: Once {} record Bad { value: &u32 }";
5231 5231
    let result = try resolveProgramStr(&mut a, program);
5232 5232
    try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5233 5233
}
5234 5234
5235 5235
/// Trait methods may use reference receivers.
5236 5236
@test fn testTraitRefReceiver() throws (testing::TestError) {
5237 -
    let program = "record Marker: Linear {} record Value { number: i32 } trait Read { fn (&Read) get() -> i32; } instance Read for Value { fn (value: &Value) get() -> i32 { return value.number; } } fn inspect(object: &opaque Read) -> i32 { return object.get(); } fn call(value: &Value) -> i32 { return inspect(value); }";
5237 +
    let program = "record Marker: Once {} record Value { number: i32 } trait Read { fn (&Read) get() -> i32; } instance Read for Value { fn (value: &Value) get() -> i32 { return value.number; } } fn inspect(object: &opaque Read) -> i32 { return object.get(); } fn call(value: &Value) -> i32 { return inspect(value); }";
5238 5238
    try expectAnalyzeOk(program);
5239 5239
}
5240 5240
5241 5241
/// Trait implementations must preserve the receiver pointer class.
5242 5242
@test fn testTraitReceiverClassMismatch() throws (testing::TestError) {
5281 5281
}
5282 5282
5283 5283
/// A composite cannot carry conflicting ownership markers.
5284 5284
@test fn testConflictingOwnershipMarkersRejected() throws (testing::TestError) {
5285 5285
    let mut a = testResolver();
5286 -
    let program = "record Value: Copy + Linear { number: u32 }";
5286 +
    let program = "record Value: Copy + Once { number: u32 }";
5287 5287
    let result = try resolveProgramStr(&mut a, program);
5288 5288
    try expectErrorKind(&result, super::ErrorKind::ConflictingOwnershipMarkers);
5289 5289
}
5290 5290
5291 5291
/// Linear composites still require one consuming use.
5292 5292
@test fn testLinearCompositeMustBeConsumed() throws (testing::TestError) {
5293 5293
    let mut a = testResolver();
5294 -
    let program = "record Token: Linear { number: u32 } fn run() { let token = Token { number: 1 }; }";
5294 +
    let program = "record Token: Once { number: u32 } fn run() { let token = Token { number: 1 }; }";
5295 5295
    let result = try resolveProgramStr(&mut a, program);
5296 5296
    try expectErrorKind(&result, super::ErrorKind::LinearNotConsumed("token"));
5297 5297
}
5298 5298
5299 5299
/// The compiler-known marker cannot be derived more than once.
5300 -
@test fn testDuplicateLinearMarkerRejected() throws (testing::TestError) {
5300 +
@test fn testDuplicateOnceMarkerRejected() throws (testing::TestError) {
5301 5301
    let mut a = testResolver();
5302 -
    let program = "record Token: Linear + Linear { value: u32 }";
5302 +
    let program = "record Token: Once + Once { value: u32 }";
5303 5303
    let result = try resolveProgramStr(&mut a, program);
5304 -
    try expectErrorKind(&result, super::ErrorKind::DuplicateBinding("Linear"));
5304 +
    try expectErrorKind(&result, super::ErrorKind::DuplicateBinding("Once"));
5305 5305
}
5306 5306
5307 -
/// A `Linear` marker does not change legacy pointer inference.
5308 -
@test fn testLinearMarkerKeepsLegacyPointerInference() throws (testing::TestError) {
5309 -
    let program = "record Marker: Linear {} fn run() { let value: u32 = 0; let pointer: *u32 = &value; pointer; }";
5307 +
/// A `Once` marker does not change legacy pointer inference.
5308 +
@test fn testOnceMarkerKeepsLegacyPointerInference() throws (testing::TestError) {
5309 +
    let program = "record Marker: Once {} fn run() { let value: u32 = 0; let pointer: *u32 = &value; pointer; }";
5310 5310
    try expectAnalyzeOk(program);
5311 5311
}
5312 5312
5313 5313
/// References are rejected from every nested or storable type position.
5314 5314
@test fn testNestedRefPositionsRejected() throws (testing::TestError) {
5315 5315
    {
5316 5316
        let mut a = testResolver();
5317 -
        let program = "record Marker: Linear {} union Bad { Value(&u32) }";
5317 +
        let program = "record Marker: Once {} union Bad { Value(&u32) }";
5318 5318
        let result = try resolveProgramStr(&mut a, program);
5319 5319
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5320 5320
    } {
5321 5321
        let mut a = testResolver();
5322 -
        let program = "record Marker: Linear {} fn bad(value: ?&u32) {}";
5322 +
        let program = "record Marker: Once {} fn bad(value: ?&u32) {}";
5323 5323
        let result = try resolveProgramStr(&mut a, program);
5324 5324
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5325 5325
    } {
5326 5326
        let mut a = testResolver();
5327 -
        let program = "record Marker: Linear {} fn bad(value: [&u32; 1]) {}";
5327 +
        let program = "record Marker: Once {} fn bad(value: [&u32; 1]) {}";
5328 5328
        let result = try resolveProgramStr(&mut a, program);
5329 5329
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5330 5330
    } {
5331 5331
        let mut a = testResolver();
5332 -
        let program = "record Marker: Linear {} fn bad(value: *&u32) {}";
5332 +
        let program = "record Marker: Once {} fn bad(value: *&u32) {}";
5333 5333
        let result = try resolveProgramStr(&mut a, program);
5334 5334
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5335 5335
    } {
5336 5336
        let mut a = testResolver();
5337 -
        let program = "record Marker: Linear {} static BAD: &u32 = undefined;";
5337 +
        let program = "record Marker: Once {} static BAD: &u32 = undefined;";
5338 5338
        let result = try resolveProgramStr(&mut a, program);
5339 5339
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5340 5340
    } {
5341 5341
        let mut a = testResolver();
5342 -
        let program = "record Marker: Linear {} fn bad(callback: fn() -> &u32) {}";
5342 +
        let program = "record Marker: Once {} fn bad(callback: fn() -> &u32) {}";
5343 5343
        let result = try resolveProgramStr(&mut a, program);
5344 5344
        try expectErrorKind(&result, super::ErrorKind::InvalidRefPosition);
5345 5345
    }
5346 5346
}
5347 5347
5348 5348
/// Function pointer parameter references remain call-scoped and valid.
5349 5349
@test fn testFunctionPointerRefParameterAllowed() throws (testing::TestError) {
5350 -
    let program = "record Marker: Linear {} fn invoke(callback: fn(&u32), value: &u32) { callback(value); }";
5350 +
    let program = "record Marker: Once {} fn invoke(callback: fn(&u32), value: &u32) { callback(value); }";
5351 5351
    try expectAnalyzeOk(program);
5352 5352
}
5353 5353
5354 5354
/// Pointer and slice casts cannot change reference ownership.
5355 5355
@test fn testRefCastClassPreserved() throws (testing::TestError) {
5356 5356
    {
5357 5357
        let mut a = testResolver();
5358 -
        let program = "record Marker: Linear {} fn cast(value: &u32) { value as *u32; }";
5358 +
        let program = "record Marker: Once {} fn cast(value: &u32) { value as *u32; }";
5359 5359
        let result = try resolveProgramStr(&mut a, program);
5360 5360
        let err = try expectError(&result);
5361 5361
        let case super::ErrorKind::InvalidAsCast(_) = err.kind
5362 5362
            else throw testing::TestError::Failed;
5363 5363
    } {
5364 5364
        let mut a = testResolver();
5365 -
        let program = "record Marker: Linear {} fn cast(values: &[u32]) { values as *[u32]; }";
5365 +
        let program = "record Marker: Once {} fn cast(values: &[u32]) { values as *[u32]; }";
5366 5366
        let result = try resolveProgramStr(&mut a, program);
5367 5367
        let err = try expectError(&result);
5368 5368
        let case super::ErrorKind::InvalidAsCast(_) = err.kind
5369 5369
            else throw testing::TestError::Failed;
5370 5370
    }
5372 5372
5373 5373
/// Every operation that interprets an unsafe address requires an unsafe declaration.
5374 5374
@test fn testUnsafePointerOperationsRejected() throws (testing::TestError) {
5375 5375
    {
5376 5376
        let mut a = testResolver();
5377 -
        let program = "record Marker: Linear {} fn cast(pointer: *unsafe u32) -> u64 { return pointer as u64; }";
5377 +
        let program = "record Marker: Once {} fn cast(pointer: *unsafe u32) -> u64 { return pointer as u64; }";
5378 5378
        let result = try resolveProgramStr(&mut a, program);
5379 5379
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5380 5380
    } {
5381 5381
        let mut a = testResolver();
5382 -
        let program = "record Marker: Linear {} fn compare(pointer: *unsafe u32) -> bool { return pointer == pointer; }";
5382 +
        let program = "record Marker: Once {} fn compare(pointer: *unsafe u32) -> bool { return pointer == pointer; }";
5383 5383
        let result = try resolveProgramStr(&mut a, program);
5384 5384
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5385 5385
    } {
5386 5386
        let mut a = testResolver();
5387 -
        let program = "record Marker: Linear {} fn offset(pointer: *unsafe u32) -> *unsafe u32 { return pointer + 1; }";
5387 +
        let program = "record Marker: Once {} fn offset(pointer: *unsafe u32) -> *unsafe u32 { return pointer + 1; }";
5388 5388
        let result = try resolveProgramStr(&mut a, program);
5389 5389
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5390 5390
    } {
5391 5391
        let mut a = testResolver();
5392 -
        let program = "record Marker: Linear {} fn index(values: *unsafe [u32]) -> u32 { return values[0]; }";
5392 +
        let program = "record Marker: Once {} fn index(values: *unsafe [u32]) -> u32 { return values[0]; }";
5393 5393
        let result = try resolveProgramStr(&mut a, program);
5394 5394
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5395 5395
    } {
5396 5396
        let mut a = testResolver();
5397 -
        let program = "record Marker: Linear {} record Cell { value: u32 } fn field(cell: *unsafe Cell) -> u32 { return cell.value; }";
5397 +
        let program = "record Marker: Once {} record Cell { value: u32 } fn field(cell: *unsafe Cell) -> u32 { return cell.value; }";
5398 5398
        let result = try resolveProgramStr(&mut a, program);
5399 5399
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5400 5400
    } {
5401 5401
        let mut a = testResolver();
5402 -
        let program = "record Marker: Linear {} fn store(pointer: *unsafe mut u32) { set *pointer = 1; }";
5402 +
        let program = "record Marker: Once {} fn store(pointer: *unsafe mut u32) { set *pointer = 1; }";
5403 5403
        let result = try resolveProgramStr(&mut a, program);
5404 5404
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5405 5405
    } {
5406 5406
        let mut a = testResolver();
5407 -
        let program = "record Marker: Linear {} fn cast() { let value: u32 = 0; let pointer = &value as *unsafe u32; }";
5407 +
        let program = "record Marker: Once {} fn cast() { let value: u32 = 0; let pointer = &value as *unsafe u32; }";
5408 5408
        let result = try resolveProgramStr(&mut a, program);
5409 5409
        try expectErrorKind(&result, super::ErrorKind::UnsafeOperation);
5410 5410
    }
5411 5411
}
5412 5412
5413 5413
/// Unsafe declarations may compose unsafe operations and calls.
5414 5414
@test fn testUnsafePointerOperationsAllowed() throws (testing::TestError) {
5415 -
    let program = "record Marker: Linear {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; } unsafe fn run(pointer: *unsafe u32) -> u32 { let next = pointer + 1; let same = pointer == next; return load(pointer); }";
5415 +
    let program = "record Marker: Once {} unsafe fn load(pointer: *unsafe u32) -> u32 { return *pointer; } unsafe fn run(pointer: *unsafe u32) -> u32 { let next = pointer + 1; let same = pointer == next; return load(pointer); }";
5416 5416
    try expectAnalyzeOk(program);
5417 5417
}
5418 5418
5419 5419
/// Unsafe code may drop a checked reference to an unsafe pointer.
5420 5420
@test fn testUnsafePointerFromReference() throws (testing::TestError) {
5421 -
    let program = "record Marker: Linear {} unsafe fn store(pointer: *unsafe mut u32) { set *pointer = 42; } unsafe fn run() { let mut value: u32 = 0; store(&mut value as *unsafe mut u32); }";
5421 +
    let program = "record Marker: Once {} unsafe fn store(pointer: *unsafe mut u32) { set *pointer = 42; } unsafe fn run() { let mut value: u32 = 0; store(&mut value as *unsafe mut u32); }";
5422 5422
    try expectAnalyzeOk(program);
5423 5423
}
5424 5424
5425 5425
/// Dropping a reference to an unsafe pointer cannot add mutability.
5426 5426
@test fn testUnsafePointerCastCannotAddMutability() throws (testing::TestError) {
5427 5427
    let mut a = testResolver();
5428 -
    let program = "record Marker: Linear {} unsafe fn run(value: &u32) { value as *unsafe mut u32; }";
5428 +
    let program = "record Marker: Once {} unsafe fn run(value: &u32) { value as *unsafe mut u32; }";
5429 5429
    let result = try resolveProgramStr(&mut a, program);
5430 5430
    let err = try expectError(&result);
5431 5431
    let case super::ErrorKind::InvalidAsCast(_) = err.kind
5432 5432
        else throw testing::TestError::Failed;
5433 5433
}
5434 5434
5435 5435
/// Recursive cast validation cannot hide a checked-to-unsafe transition.
5436 5436
@test fn testNestedUnsafePointerCastRejected() throws (testing::TestError) {
5437 5437
    let mut a = testResolver();
5438 -
    let program = "record Marker: Linear {} fn run(value: **u32) { value as **unsafe u32; }";
5438 +
    let program = "record Marker: Once {} fn run(value: **u32) { value as **unsafe u32; }";
5439 5439
    let result = try resolveProgramStr(&mut a, program);
5440 5440
    let err = try expectError(&result);
5441 5441
    let case super::ErrorKind::InvalidAsCast(_) = err.kind
5442 5442
        else throw testing::TestError::Failed;
5443 5443
}
5444 5444
5445 5445
/// Unsafe code may drop a checked slice reference to an unsafe slice.
5446 5446
@test fn testUnsafeSliceFromReference() throws (testing::TestError) {
5447 -
    let program = "record Marker: Linear {} unsafe fn run(values: &[u32]) { let raw: *unsafe [u32] = values as *unsafe [u32]; }";
5447 +
    let program = "record Marker: Once {} unsafe fn run(values: &[u32]) { let raw: *unsafe [u32] = values as *unsafe [u32]; }";
5448 5448
    try expectAnalyzeOk(program);
5449 5449
}
5450 5450
5451 5451
/// Slice casts cannot add mutability.
5452 5452
@test fn testSliceCastCannotAddMutability() throws (testing::TestError) {
5453 5453
    let mut a = testResolver();
5454 -
    let program = "record Marker: Linear {} fn run(values: &[u32]) { values as &mut [u32]; }";
5454 +
    let program = "record Marker: Once {} fn run(values: &[u32]) { values as &mut [u32]; }";
5455 5455
    let result = try resolveProgramStr(&mut a, program);
5456 5456
    let err = try expectError(&result);
5457 5457
    let case super::ErrorKind::InvalidAsCast(_) = err.kind
5458 5458
        else throw testing::TestError::Failed;
5459 5459
}
5460 5460
5461 5461
/// Mutable unsafe receivers do not create checked exclusive loans.
5462 5462
@test fn testUnsafeReceiverDoesNotBorrowExclusively() throws (testing::TestError) {
5463 -
    let program = "record Marker: Linear {} record Value { number: u32 } unsafe fn (value: *unsafe mut Value) update(other: *unsafe mut Value) {} unsafe fn run(value: *unsafe mut Value) { value.update(value); }";
5463 +
    let program = "record Marker: Once {} record Value { number: u32 } unsafe fn (value: *unsafe mut Value) update(other: *unsafe mut Value) {} unsafe fn run(value: *unsafe mut Value) { value.update(value); }";
5464 5464
    try expectAnalyzeOk(program);
5465 5465
}
5466 5466
5467 5467
/// Unsafe instance-method attributes enable unsafe operations in the body.
5468 5468
@test fn testUnsafeInstanceMethodBody() throws (testing::TestError) {
5469 -
    let program = "record Marker: Linear {} record Value { number: u32 } trait Read { unsafe fn (*unsafe Read) get() -> u32; } instance Read for Value { unsafe fn (value: *unsafe Value) get() -> u32 { return value.number; } }";
5469 +
    let program = "record Marker: Once {} record Value { number: u32 } trait Read { unsafe fn (*unsafe Read) get() -> u32; } instance Read for Value { unsafe fn (value: *unsafe Value) get() -> u32 { return value.number; } }";
5470 5470
    try expectAnalyzeOk(program);
5471 5471
}
5472 5472
5473 5473
/// Unsafe instance methods cannot implement safe trait contracts.
5474 5474
@test fn testUnsafeInstanceMethodSafetyMismatch() throws (testing::TestError) {
5479 5479
}
5480 5480
5481 5481
/// Unsafe trait methods retain their call-site requirement through dispatch.
5482 5482
@test fn testUnsafeTraitMethodCallRejected() throws (testing::TestError) {
5483 5483
    let mut a = testResolver();
5484 -
    let program = "record Marker: Linear {} record Value { number: u32 } trait Read { unsafe fn (&Read) get() -> u32; } instance Read for Value { unsafe fn (value: &Value) get() -> u32 { return value.number; } } fn inspect(object: &opaque Read) -> u32 { return object.get(); }";
5484 +
    let program = "record Marker: Once {} record Value { number: u32 } trait Read { unsafe fn (&Read) get() -> u32; } instance Read for Value { unsafe fn (value: &Value) get() -> u32 { return value.number; } } fn inspect(object: &opaque Read) -> u32 { return object.get(); }";
5485 5485
    let result = try resolveProgramStr(&mut a, program);
5486 5486
    try expectErrorKind(&result, super::ErrorKind::UnsafeCall);
5487 5487
}
test/tests/linear.ownership.rad +1 -1
1 1
//! returns: 42
2 2
3 3
/// Linear token consumed by the test.
4 -
union Token: Linear {
4 +
union Token: Once {
5 5
    /// Token payload.
6 6
    Value(u32),
7 7
}
8 8
9 9
/// Consume a token and return its payload.
test/tests/linear.reference.rad +1 -1
1 1
//! returns: 42
2 2
3 3
/// Linear counter borrowed and consumed by the test.
4 -
union Counter: Linear {
4 +
union Counter: Once {
5 5
    /// Counter value.
6 6
    Value(u32),
7 7
}
8 8
9 9
/// Increment a borrowed counter.
test/tests/linear.unsafe.rad +2 -2
1 1
//! returns: 42
2 2
3 -
/// Linear marker used with unsafe pointer syntax.
4 -
record Marker: Linear {}
3 +
/// Once marker used with unsafe pointer syntax.
4 +
record Marker: Once {}
5 5
6 6
/// Load a value through an unsafe pointer.
7 7
unsafe fn load(pointer: *unsafe u32) -> u32 {
8 8
    return *pointer;
9 9
}
vim/radiance.vim +1 -1
17 17
" Keywords
18 18
syntax keyword radianceKeyword mod fn return if else while true false and or not case align static
19 19
syntax keyword radianceKeyword export break continue use loop in for match nil undefined
20 20
syntax keyword radianceKeyword let mut set as register device constant log record union trait instance
21 21
syntax keyword radianceKeyword throws throw try catch panic assert super unsafe
22 -
syntax keyword radianceType i8 i16 i32 i64 u8 u16 u32 u64 f32 void bool bit opaque Copy Linear
22 +
syntax keyword radianceType i8 i16 i32 i64 u8 u16 u32 u64 f32 void bool bit opaque Copy Once
23 23
24 24
" Double-quoted strings
25 25
syntax region radianceString start=/"/ skip=/\\"/ end=/"/ contains=radianceEscape
26 26
" Characters
27 27
syntax region radianceCharacter start=/'/ skip=/\\'|\\\\/ end=/'/ oneline contains=radianceEscape