| 1788 |
1788 |
|
try super::expectErrorKind(&result, resolver::ErrorKind::ImmutableBinding); |
| 1789 |
1789 |
|
} |
| 1790 |
1790 |
|
} |
| 1791 |
1791 |
|
} |
| 1792 |
1792 |
|
|
|
1793 |
+ |
|
|
1794 |
+ |
@test unsafe fn testNamedPatternBorrowRegions() throws (testing::TestError) { |
|
1795 |
+ |
for program in [ |
|
1796 |
+ |
"record B: 'r { values: &'r mut [u32] } fn f 'r (b: &'r B 'r) -> &'r [u32] { return &b.values[..]; }", |
|
1797 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r U 'r) -> &'r [u32] { match u { case U::Some(b) => return &b.values[..], else => panic, } }", |
|
1798 |
+ |
"record B: 'r { values: &'r mut [u32] } record S: 'r { items: [?B 'r; 1] } fn f 'r (s: &'r S 'r) -> &'r [u32] { match &s.items[0] { case nil => panic, b => return &b.values[..], } }", |
|
1799 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn values 'r (b: &'r B 'r) -> &'r [u32] { return &b.values[..]; } fn f 'r (u: &'r U 'r) -> &'r [u32] { match u { case U::Some(b) => return values(b), else => panic, } }", |
|
1800 |
+ |
"record B: 'r { values: &'r mut [u32] } record S: 'r { items: [?B 'r; 1] } fn values 'r (b: &'r B 'r) -> &'r [u32] { return &b.values[..]; } fn f 'r (s: &'r S 'r) -> &'r [u32] { let mut found: ?&'r B 'r = nil; match &s.items[0] { case nil => panic, b => set found = b, } let b = found else panic; return values(b); }", |
|
1801 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r U 'r) -> &'r [u32] { if let case U::Some(b) = u { return &b.values[..]; } panic; }", |
|
1802 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r U 'r) -> &'r [u32] { let case U::Some(b) = u else panic; return &b.values[..]; }", |
|
1803 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r U 'r) -> &'r [u32] { while let case U::Some(b) = u { return &b.values[..]; } panic; }", |
|
1804 |
+ |
] { |
|
1805 |
+ |
let mut arena = super::testArena(); |
|
1806 |
+ |
let storage: 'test = &mut arena in { |
|
1807 |
+ |
let mut res = super::testResolver(storage); |
|
1808 |
+ |
let result = try super::resolveProgramStr(&mut res, program); |
|
1809 |
+ |
try super::expectNoErrors(&result); |
|
1810 |
+ |
} |
|
1811 |
+ |
} |
|
1812 |
+ |
} |
|
1813 |
+ |
|
|
1814 |
+ |
|
|
1815 |
+ |
@test unsafe fn testPointerPatternBindingClasses() throws (testing::TestError) { |
|
1816 |
+ |
for program in [ |
|
1817 |
+ |
"record B { value: u32 } union U { Some(B), None } fn f(u: *U) { match u { case U::Some(b) => { assert b.value == 0; }, else => {}, } }", |
|
1818 |
+ |
"record B { value: u32 } union U { Some(B), None } unsafe fn f(u: *unsafe U) { match u { case U::Some(b) => { assert b.value == 0; }, else => {}, } }", |
|
1819 |
+ |
] { |
|
1820 |
+ |
let mut arena = super::testArena(); |
|
1821 |
+ |
let storage: 'test = &mut arena in { |
|
1822 |
+ |
let mut res = super::testResolver(storage); |
|
1823 |
+ |
let result = try super::resolveProgramStr(&mut res, program); |
|
1824 |
+ |
try super::expectNoErrors(&result); |
|
1825 |
+ |
let func = try super::getBlockStmt(result.root, 2); |
|
1826 |
+ |
let fnType = resolver::typeFor(&res, func) else throw testing::TestError::Failed; |
|
1827 |
+ |
let case resolver::Type::Fn(info) = fnType else throw testing::TestError::Failed; |
|
1828 |
+ |
let subject = resolver::unwrapMatchSubject(*info.paramTypes[0]); |
|
1829 |
+ |
let case resolver::MatchBy::Ref(types::PointerClass::Ref) = subject.by |
|
1830 |
+ |
else throw testing::TestError::Failed; |
|
1831 |
+ |
let case ast::NodeValue::FnDecl(decl) = func.value else throw testing::TestError::Failed; |
|
1832 |
+ |
let body = decl.body else throw testing::TestError::Failed; |
|
1833 |
+ |
let statement = try super::getBlockStmt(body, 0); |
|
1834 |
+ |
let case ast::NodeValue::Match(matchStmt) = statement.value else throw testing::TestError::Failed; |
|
1835 |
+ |
let case ast::NodeValue::MatchProng(prong) = matchStmt.prongs[0].value |
|
1836 |
+ |
else throw testing::TestError::Failed; |
|
1837 |
+ |
let case ast::ProngArm::Case(patterns) = prong.arm else throw testing::TestError::Failed; |
|
1838 |
+ |
let case ast::NodeValue::Call(call) = patterns[0].value else throw testing::TestError::Failed; |
|
1839 |
+ |
let bindingType = resolver::typeFor(&res, call.args[0]) else throw testing::TestError::Failed; |
|
1840 |
+ |
let case resolver::Type::Pointer { class: types::PointerClass::Ref, .. } = bindingType |
|
1841 |
+ |
else throw testing::TestError::Failed; |
|
1842 |
+ |
} |
|
1843 |
+ |
} |
|
1844 |
+ |
} |
|
1845 |
+ |
|
|
1846 |
+ |
|
|
1847 |
+ |
@test unsafe fn testMutablePatternBindingEscape() throws (testing::TestError) { |
|
1848 |
+ |
let programs = [ |
|
1849 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r mut U 'r) -> &'r [u32] { match u { case U::Some(b) => return &b.values[..], else => panic, } }", |
|
1850 |
+ |
]; |
|
1851 |
+ |
for program in programs { |
|
1852 |
+ |
let mut arena = super::testArena(); |
|
1853 |
+ |
let storage: 'test = &mut arena in { |
|
1854 |
+ |
let mut res = super::testResolver(storage); |
|
1855 |
+ |
let result = try super::resolveProgramStr(&mut res, program); |
|
1856 |
+ |
let error = try super::expectError(&result); |
|
1857 |
+ |
let case resolver::ErrorKind::TypeMismatch(_) = error.kind |
|
1858 |
+ |
else throw testing::TestError::Failed; |
|
1859 |
+ |
} |
|
1860 |
+ |
} |
|
1861 |
+ |
for program in [ |
|
1862 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r mut U 'r) { match u { case U::Some(b) => { let held = &b.values[..]; set *u = U::None; assert held.len == 0; }, else => {}, } }", |
|
1863 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r (u: &'r mut U 'r) { let mut held: ?&'r B 'r = nil; match &*u { case U::Some(b) => set held = b, else => {}, } set *u = U::None; let b = held else return; assert b.values.len == 0; }", |
|
1864 |
+ |
] { |
|
1865 |
+ |
let mut arena = super::testArena(); |
|
1866 |
+ |
let storage: 'test = &mut arena in { |
|
1867 |
+ |
let mut res = super::testResolver(storage); |
|
1868 |
+ |
let result = try super::resolveProgramStr(&mut res, program); |
|
1869 |
+ |
let error = try super::expectError(&result); |
|
1870 |
+ |
let case resolver::ErrorKind::BorrowConflict(_) = error.kind |
|
1871 |
+ |
else throw testing::TestError::Failed; |
|
1872 |
+ |
} |
|
1873 |
+ |
} |
|
1874 |
+ |
} |
|
1875 |
+ |
|
|
1876 |
+ |
|
|
1877 |
+ |
@test unsafe fn testNamedPatternBorrowRejectsShortOwner() throws (testing::TestError) { |
|
1878 |
+ |
for program in [ |
|
1879 |
+ |
"record B: 'r { values: &'r mut [u32] } union U: 'r { Some(B 'r), None } fn f 'r 's (u: &'s U 'r) -> &'r [u32] where 'r: 's { match u { case U::Some(b) => return &b.values[..], else => panic, } }", |
|
1880 |
+ |
"record B: 'r { values: &'r mut [u32] } record S: 'r { items: [?B 'r; 1] } fn f 'r 's (s: &'s S 'r) -> &'r [u32] where 'r: 's { match &s.items[0] { case nil => panic, b => return &b.values[..], } }", |
|
1881 |
+ |
] { |
|
1882 |
+ |
let mut arena = super::testArena(); |
|
1883 |
+ |
let storage: 'test = &mut arena in { |
|
1884 |
+ |
let mut res = super::testResolver(storage); |
|
1885 |
+ |
let result = try super::resolveProgramStr(&mut res, program); |
|
1886 |
+ |
let error = try super::expectError(&result); |
|
1887 |
+ |
let case resolver::ErrorKind::TypeMismatch(_) = error.kind |
|
1888 |
+ |
else throw testing::TestError::Failed; |
|
1889 |
+ |
} |
|
1890 |
+ |
} |
|
1891 |
+ |
} |
|
1892 |
+ |
|
| 1793 |
1893 |
|
|
| 1794 |
1894 |
|
@test unsafe fn testExclusiveOwnerBorrowLifetimes() throws (testing::TestError) { |
| 1795 |
1895 |
|
for program in [ |
| 1796 |
1896 |
|
"record H: 'r { item: &'r mut u32 } fn f 'r 's (h: &'s H 'r) -> &'r u32 where 'r: 's { let p: &'r u32 = h.item; return p; }", |
| 1797 |
1897 |
|
"record H: 'r { item: ?&'r mut u32 } fn f 'r 's (h: &'s H 'r) -> ?&'r u32 where 'r: 's { let p: ?&'r u32 = h.item; return p; }", |