@@ -962,221 +962,6 @@ extern "rust-intrinsic" {
962
962
/// value is not necessarily valid to be used to actually access memory.
963
963
pub fn arith_offset < T > ( dst : * const T , offset : isize ) -> * const T ;
964
964
965
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
966
- /// and destination must *not* overlap.
967
- ///
968
- /// For regions of memory which might overlap, use [`copy`] instead.
969
- ///
970
- /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
971
- /// with the argument order swapped.
972
- ///
973
- /// [`copy`]: ./fn.copy.html
974
- /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
975
- ///
976
- /// # Safety
977
- ///
978
- /// Behavior is undefined if any of the following conditions are violated:
979
- ///
980
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
981
- ///
982
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
983
- ///
984
- /// * Both `src` and `dst` must be properly aligned.
985
- ///
986
- /// * The region of memory beginning at `src` with a size of `count *
987
- /// size_of::<T>()` bytes must *not* overlap with the region of memory
988
- /// beginning at `dst` with the same size.
989
- ///
990
- /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
991
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
992
- /// in the region beginning at `*src` and the region beginning at `*dst` can
993
- /// [violate memory safety][read-ownership].
994
- ///
995
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
996
- /// `0`, the pointers must be non-NULL and properly aligned.
997
- ///
998
- /// [`Copy`]: ../marker/trait.Copy.html
999
- /// [`read`]: ../ptr/fn.read.html
1000
- /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1001
- /// [valid]: ../ptr/index.html#safety
1002
- ///
1003
- /// # Examples
1004
- ///
1005
- /// Manually implement [`Vec::append`]:
1006
- ///
1007
- /// ```
1008
- /// use std::ptr;
1009
- ///
1010
- /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1011
- /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1012
- /// let src_len = src.len();
1013
- /// let dst_len = dst.len();
1014
- ///
1015
- /// // Ensure that `dst` has enough capacity to hold all of `src`.
1016
- /// dst.reserve(src_len);
1017
- ///
1018
- /// unsafe {
1019
- /// // The call to offset is always safe because `Vec` will never
1020
- /// // allocate more than `isize::MAX` bytes.
1021
- /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
1022
- /// let src_ptr = src.as_ptr();
1023
- ///
1024
- /// // Truncate `src` without dropping its contents. We do this first,
1025
- /// // to avoid problems in case something further down panics.
1026
- /// src.set_len(0);
1027
- ///
1028
- /// // The two regions cannot overlap because mutable references do
1029
- /// // not alias, and two different vectors cannot own the same
1030
- /// // memory.
1031
- /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
1032
- ///
1033
- /// // Notify `dst` that it now holds the contents of `src`.
1034
- /// dst.set_len(dst_len + src_len);
1035
- /// }
1036
- /// }
1037
- ///
1038
- /// let mut a = vec!['r'];
1039
- /// let mut b = vec!['u', 's', 't'];
1040
- ///
1041
- /// append(&mut a, &mut b);
1042
- ///
1043
- /// assert_eq!(a, &['r', 'u', 's', 't']);
1044
- /// assert!(b.is_empty());
1045
- /// ```
1046
- ///
1047
- /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
1048
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1049
- pub fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
1050
-
1051
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1052
- /// and destination may overlap.
1053
- ///
1054
- /// If the source and destination will *never* overlap,
1055
- /// [`copy_nonoverlapping`] can be used instead.
1056
- ///
1057
- /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
1058
- /// order swapped. Copying takes place as if the bytes were copied from `src`
1059
- /// to a temporary array and then copied from the array to `dst`.
1060
- ///
1061
- /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1062
- /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
1063
- ///
1064
- /// # Safety
1065
- ///
1066
- /// Behavior is undefined if any of the following conditions are violated:
1067
- ///
1068
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1069
- ///
1070
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1071
- ///
1072
- /// * Both `src` and `dst` must be properly aligned.
1073
- ///
1074
- /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1075
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1076
- /// in the region beginning at `*src` and the region beginning at `*dst` can
1077
- /// [violate memory safety][read-ownership].
1078
- ///
1079
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1080
- /// `0`, the pointers must be non-NULL and properly aligned.
1081
- ///
1082
- /// [`Copy`]: ../marker/trait.Copy.html
1083
- /// [`read`]: ../ptr/fn.read.html
1084
- /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1085
- /// [valid]: ../ptr/index.html#safety
1086
- ///
1087
- /// # Examples
1088
- ///
1089
- /// Efficiently create a Rust vector from an unsafe buffer:
1090
- ///
1091
- /// ```
1092
- /// use std::ptr;
1093
- ///
1094
- /// # #[allow(dead_code)]
1095
- /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
1096
- /// let mut dst = Vec::with_capacity(elts);
1097
- /// dst.set_len(elts);
1098
- /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
1099
- /// dst
1100
- /// }
1101
- /// ```
1102
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1103
- pub fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
1104
-
1105
- /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1106
- /// `val`.
1107
- ///
1108
- /// `write_bytes` is similar to C's [`memset`], but sets `count *
1109
- /// size_of::<T>()` bytes to `val`.
1110
- ///
1111
- /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
1112
- ///
1113
- /// # Safety
1114
- ///
1115
- /// Behavior is undefined if any of the following conditions are violated:
1116
- ///
1117
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1118
- ///
1119
- /// * `dst` must be properly aligned.
1120
- ///
1121
- /// Additionally, the caller must ensure that writing `count *
1122
- /// size_of::<T>()` bytes to the given region of memory results in a valid
1123
- /// value of `T`. Using a region of memory typed as a `T` that contains an
1124
- /// invalid value of `T` is undefined behavior.
1125
- ///
1126
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1127
- /// `0`, the pointer must be non-NULL and properly aligned.
1128
- ///
1129
- /// [valid]: ../ptr/index.html#safety
1130
- ///
1131
- /// # Examples
1132
- ///
1133
- /// Basic usage:
1134
- ///
1135
- /// ```
1136
- /// use std::ptr;
1137
- ///
1138
- /// let mut vec = vec![0u32; 4];
1139
- /// unsafe {
1140
- /// let vec_ptr = vec.as_mut_ptr();
1141
- /// ptr::write_bytes(vec_ptr, 0xfe, 2);
1142
- /// }
1143
- /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
1144
- /// ```
1145
- ///
1146
- /// Creating an invalid value:
1147
- ///
1148
- /// ```
1149
- /// use std::ptr;
1150
- ///
1151
- /// let mut v = Box::new(0i32);
1152
- ///
1153
- /// unsafe {
1154
- /// // Leaks the previously held value by overwriting the `Box<T>` with
1155
- /// // a null pointer.
1156
- /// ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
1157
- /// }
1158
- ///
1159
- /// // At this point, using or dropping `v` results in undefined behavior.
1160
- /// // drop(v); // ERROR
1161
- ///
1162
- /// // Even leaking `v` "uses" it, and hence is undefined behavior.
1163
- /// // mem::forget(v); // ERROR
1164
- ///
1165
- /// // In fact, `v` is invalid according to basic type layout invariants, so *any*
1166
- /// // operation touching it is undefined behavior.
1167
- /// // let v2 = v; // ERROR
1168
- ///
1169
- /// unsafe {
1170
- /// // Let us instead put in a valid value
1171
- /// ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
1172
- /// }
1173
- ///
1174
- /// // Now the box is fine
1175
- /// assert_eq!(*v, 42);
1176
- /// ```
1177
- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1178
- pub fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
1179
-
1180
965
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
1181
966
/// a size of `count` * `size_of::<T>()` and an alignment of
1182
967
/// `min_align_of::<T>()`
@@ -1524,3 +1309,252 @@ extern "rust-intrinsic" {
1524
1309
/// Probably will never become stable.
1525
1310
pub fn nontemporal_store < T > ( ptr : * mut T , val : T ) ;
1526
1311
}
1312
+
1313
+ mod real_intrinsics {
1314
+ extern "rust-intrinsic" {
1315
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1316
+ /// and destination must *not* overlap.
1317
+ /// For the full docs, see the stabilized wrapper [`copy_nonoverlapping`].
1318
+ ///
1319
+ /// [`copy_nonoverlapping`]: ../../std/ptr/fn.copy_nonoverlapping.html
1320
+ pub fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
1321
+
1322
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1323
+ /// and destination may overlap.
1324
+ /// For the full docs, see the stabilized wrapper [`copy`].
1325
+ ///
1326
+ /// [`copy`]: ../../std/ptr/fn.copy.html
1327
+ pub fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
1328
+
1329
+ /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1330
+ /// `val`.
1331
+ /// For the full docs, see the stabilized wrapper [`write_bytes`].
1332
+ ///
1333
+ /// [`write_bytes`]: ../../std/ptr/fn.write_bytes.html
1334
+ pub fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
1335
+ }
1336
+ }
1337
+
1338
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1339
+ /// and destination must *not* overlap.
1340
+ ///
1341
+ /// For regions of memory which might overlap, use [`copy`] instead.
1342
+ ///
1343
+ /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
1344
+ /// with the argument order swapped.
1345
+ ///
1346
+ /// [`copy`]: ./fn.copy.html
1347
+ /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
1348
+ ///
1349
+ /// # Safety
1350
+ ///
1351
+ /// Behavior is undefined if any of the following conditions are violated:
1352
+ ///
1353
+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1354
+ ///
1355
+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1356
+ ///
1357
+ /// * Both `src` and `dst` must be properly aligned.
1358
+ ///
1359
+ /// * The region of memory beginning at `src` with a size of `count *
1360
+ /// size_of::<T>()` bytes must *not* overlap with the region of memory
1361
+ /// beginning at `dst` with the same size.
1362
+ ///
1363
+ /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
1364
+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
1365
+ /// in the region beginning at `*src` and the region beginning at `*dst` can
1366
+ /// [violate memory safety][read-ownership].
1367
+ ///
1368
+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1369
+ /// `0`, the pointers must be non-NULL and properly aligned.
1370
+ ///
1371
+ /// [`Copy`]: ../marker/trait.Copy.html
1372
+ /// [`read`]: ../ptr/fn.read.html
1373
+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1374
+ /// [valid]: ../ptr/index.html#safety
1375
+ ///
1376
+ /// # Examples
1377
+ ///
1378
+ /// Manually implement [`Vec::append`]:
1379
+ ///
1380
+ /// ```
1381
+ /// use std::ptr;
1382
+ ///
1383
+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1384
+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1385
+ /// let src_len = src.len();
1386
+ /// let dst_len = dst.len();
1387
+ ///
1388
+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
1389
+ /// dst.reserve(src_len);
1390
+ ///
1391
+ /// unsafe {
1392
+ /// // The call to offset is always safe because `Vec` will never
1393
+ /// // allocate more than `isize::MAX` bytes.
1394
+ /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
1395
+ /// let src_ptr = src.as_ptr();
1396
+ ///
1397
+ /// // Truncate `src` without dropping its contents. We do this first,
1398
+ /// // to avoid problems in case something further down panics.
1399
+ /// src.set_len(0);
1400
+ ///
1401
+ /// // The two regions cannot overlap because mutable references do
1402
+ /// // not alias, and two different vectors cannot own the same
1403
+ /// // memory.
1404
+ /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
1405
+ ///
1406
+ /// // Notify `dst` that it now holds the contents of `src`.
1407
+ /// dst.set_len(dst_len + src_len);
1408
+ /// }
1409
+ /// }
1410
+ ///
1411
+ /// let mut a = vec!['r'];
1412
+ /// let mut b = vec!['u', 's', 't'];
1413
+ ///
1414
+ /// append(&mut a, &mut b);
1415
+ ///
1416
+ /// assert_eq!(a, &['r', 'u', 's', 't']);
1417
+ /// assert!(b.is_empty());
1418
+ /// ```
1419
+ ///
1420
+ /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
1421
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1422
+ #[ inline]
1423
+ pub unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) {
1424
+ real_intrinsics:: copy_nonoverlapping ( src, dst, count) ;
1425
+ }
1426
+
1427
+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1428
+ /// and destination may overlap.
1429
+ ///
1430
+ /// If the source and destination will *never* overlap,
1431
+ /// [`copy_nonoverlapping`] can be used instead.
1432
+ ///
1433
+ /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
1434
+ /// order swapped. Copying takes place as if the bytes were copied from `src`
1435
+ /// to a temporary array and then copied from the array to `dst`.
1436
+ ///
1437
+ /// [`copy_nonoverlapping`]: ./fn.copy_nonoverlapping.html
1438
+ /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
1439
+ ///
1440
+ /// # Safety
1441
+ ///
1442
+ /// Behavior is undefined if any of the following conditions are violated:
1443
+ ///
1444
+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1445
+ ///
1446
+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1447
+ ///
1448
+ /// * Both `src` and `dst` must be properly aligned.
1449
+ ///
1450
+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1451
+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1452
+ /// in the region beginning at `*src` and the region beginning at `*dst` can
1453
+ /// [violate memory safety][read-ownership].
1454
+ ///
1455
+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1456
+ /// `0`, the pointers must be non-NULL and properly aligned.
1457
+ ///
1458
+ /// [`Copy`]: ../marker/trait.Copy.html
1459
+ /// [`read`]: ../ptr/fn.read.html
1460
+ /// [read-ownership]: ../ptr/fn.read.html#ownership-of-the-returned-value
1461
+ /// [valid]: ../ptr/index.html#safety
1462
+ ///
1463
+ /// # Examples
1464
+ ///
1465
+ /// Efficiently create a Rust vector from an unsafe buffer:
1466
+ ///
1467
+ /// ```
1468
+ /// use std::ptr;
1469
+ ///
1470
+ /// # #[allow(dead_code)]
1471
+ /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
1472
+ /// let mut dst = Vec::with_capacity(elts);
1473
+ /// dst.set_len(elts);
1474
+ /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
1475
+ /// dst
1476
+ /// }
1477
+ /// ```
1478
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1479
+ #[ inline]
1480
+ pub unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) {
1481
+ real_intrinsics:: copy ( src, dst, count)
1482
+ }
1483
+
1484
+ /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
1485
+ /// `val`.
1486
+ ///
1487
+ /// `write_bytes` is similar to C's [`memset`], but sets `count *
1488
+ /// size_of::<T>()` bytes to `val`.
1489
+ ///
1490
+ /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
1491
+ ///
1492
+ /// # Safety
1493
+ ///
1494
+ /// Behavior is undefined if any of the following conditions are violated:
1495
+ ///
1496
+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1497
+ ///
1498
+ /// * `dst` must be properly aligned.
1499
+ ///
1500
+ /// Additionally, the caller must ensure that writing `count *
1501
+ /// size_of::<T>()` bytes to the given region of memory results in a valid
1502
+ /// value of `T`. Using a region of memory typed as a `T` that contains an
1503
+ /// invalid value of `T` is undefined behavior.
1504
+ ///
1505
+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1506
+ /// `0`, the pointer must be non-NULL and properly aligned.
1507
+ ///
1508
+ /// [valid]: ../ptr/index.html#safety
1509
+ ///
1510
+ /// # Examples
1511
+ ///
1512
+ /// Basic usage:
1513
+ ///
1514
+ /// ```
1515
+ /// use std::ptr;
1516
+ ///
1517
+ /// let mut vec = vec![0u32; 4];
1518
+ /// unsafe {
1519
+ /// let vec_ptr = vec.as_mut_ptr();
1520
+ /// ptr::write_bytes(vec_ptr, 0xfe, 2);
1521
+ /// }
1522
+ /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
1523
+ /// ```
1524
+ ///
1525
+ /// Creating an invalid value:
1526
+ ///
1527
+ /// ```
1528
+ /// use std::ptr;
1529
+ ///
1530
+ /// let mut v = Box::new(0i32);
1531
+ ///
1532
+ /// unsafe {
1533
+ /// // Leaks the previously held value by overwriting the `Box<T>` with
1534
+ /// // a null pointer.
1535
+ /// ptr::write_bytes(&mut v as *mut Box<i32>, 0, 1);
1536
+ /// }
1537
+ ///
1538
+ /// // At this point, using or dropping `v` results in undefined behavior.
1539
+ /// // drop(v); // ERROR
1540
+ ///
1541
+ /// // Even leaking `v` "uses" it, and hence is undefined behavior.
1542
+ /// // mem::forget(v); // ERROR
1543
+ ///
1544
+ /// // In fact, `v` is invalid according to basic type layout invariants, so *any*
1545
+ /// // operation touching it is undefined behavior.
1546
+ /// // let v2 = v; // ERROR
1547
+ ///
1548
+ /// unsafe {
1549
+ /// // Let us instead put in a valid value
1550
+ /// ptr::write(&mut v as *mut Box<i32>, Box::new(42i32));
1551
+ /// }
1552
+ ///
1553
+ /// // Now the box is fine
1554
+ /// assert_eq!(*v, 42);
1555
+ /// ```
1556
+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1557
+ #[ inline]
1558
+ pub unsafe fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) {
1559
+ real_intrinsics:: write_bytes ( dst, val, count)
1560
+ }
0 commit comments