Skip to content

Commit 0b475c7

Browse files
committed
Auto merge of rust-lang#112624 - matthiaskrgr:rollup-db6ta1b, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#98202 (Implement `TryFrom<&OsStr>` for `&str`) - rust-lang#107619 (Specify behavior of HashSet::insert) - rust-lang#109814 (Stabilize String::leak) - rust-lang#111974 (Update runtime guarantee for `select_nth_unstable`) - rust-lang#112109 (Don't print unsupported split-debuginfo modes with `-Zunstable-options`) - rust-lang#112506 (Properly check associated consts for infer placeholders) r? `@ghost` `@rustbot` modify labels: rollup
2 parents afa9fef + c1b4d07 commit 0b475c7

22 files changed

+140
-65
lines changed

compiler/rustc_driver_impl/src/lib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -771,9 +771,7 @@ fn print_crate_info(
771771
use rustc_target::spec::SplitDebuginfo::{Off, Packed, Unpacked};
772772

773773
for split in &[Off, Packed, Unpacked] {
774-
let stable = sess.target.options.supported_split_debuginfo.contains(split);
775-
let unstable_ok = sess.unstable_options();
776-
if stable || unstable_ok {
774+
if sess.target.options.supported_split_debuginfo.contains(split) {
777775
safe_println!("{split}");
778776
}
779777
}

compiler/rustc_hir_analysis/src/collect.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -666,17 +666,15 @@ fn convert_trait_item(tcx: TyCtxt<'_>, trait_item_id: hir::TraitItemId) {
666666
tcx.ensure().fn_sig(def_id);
667667
}
668668

669-
hir::TraitItemKind::Const(.., Some(_)) => {
669+
hir::TraitItemKind::Const(ty, body_id) => {
670670
tcx.ensure().type_of(def_id);
671-
}
672-
673-
hir::TraitItemKind::Const(hir_ty, _) => {
674-
tcx.ensure().type_of(def_id);
675-
// Account for `const C: _;`.
676-
let mut visitor = HirPlaceholderCollector::default();
677-
visitor.visit_trait_item(trait_item);
678-
if !tcx.sess.diagnostic().has_stashed_diagnostic(hir_ty.span, StashKey::ItemNoType) {
679-
placeholder_type_error(tcx, None, visitor.0, false, None, "constant");
671+
if !tcx.sess.diagnostic().has_stashed_diagnostic(ty.span, StashKey::ItemNoType)
672+
&& !(is_suggestable_infer_ty(ty) && body_id.is_some())
673+
{
674+
// Account for `const C: _;`.
675+
let mut visitor = HirPlaceholderCollector::default();
676+
visitor.visit_trait_item(trait_item);
677+
placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant");
680678
}
681679
}
682680

@@ -721,7 +719,14 @@ fn convert_impl_item(tcx: TyCtxt<'_>, impl_item_id: hir::ImplItemId) {
721719

722720
placeholder_type_error(tcx, None, visitor.0, false, None, "associated type");
723721
}
724-
hir::ImplItemKind::Const(..) => {}
722+
hir::ImplItemKind::Const(ty, _) => {
723+
// Account for `const T: _ = ..;`
724+
if !is_suggestable_infer_ty(ty) {
725+
let mut visitor = HirPlaceholderCollector::default();
726+
visitor.visit_impl_item(impl_item);
727+
placeholder_type_error(tcx, None, visitor.0, false, None, "associated constant");
728+
}
729+
}
725730
}
726731
}
727732

compiler/rustc_hir_analysis/src/collect/type_of.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,12 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
341341
.and_then(|body_id| {
342342
is_suggestable_infer_ty(ty).then(|| {
343343
infer_placeholder_type(
344-
tcx, def_id, body_id, ty.span, item.ident, "constant",
344+
tcx,
345+
def_id,
346+
body_id,
347+
ty.span,
348+
item.ident,
349+
"associated constant",
345350
)
346351
})
347352
})
@@ -359,7 +364,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
359364
}
360365
ImplItemKind::Const(ty, body_id) => {
361366
if is_suggestable_infer_ty(ty) {
362-
infer_placeholder_type(tcx, def_id, body_id, ty.span, item.ident, "constant")
367+
infer_placeholder_type(
368+
tcx,
369+
def_id,
370+
body_id,
371+
ty.span,
372+
item.ident,
373+
"associated constant",
374+
)
363375
} else {
364376
icx.to_ty(ty)
365377
}

library/alloc/src/string.rs

+8-7
Original file line numberDiff line numberDiff line change
@@ -1853,26 +1853,27 @@ impl String {
18531853
/// Consumes and leaks the `String`, returning a mutable reference to the contents,
18541854
/// `&'a mut str`.
18551855
///
1856-
/// This is mainly useful for data that lives for the remainder of
1857-
/// the program's life. Dropping the returned reference will cause a memory
1858-
/// leak.
1856+
/// The caller has free choice over the returned lifetime, including `'static`. Indeed,
1857+
/// this function is ideally used for data that lives for the remainder of the program's life,
1858+
/// as dropping the returned reference will cause a memory leak.
18591859
///
18601860
/// It does not reallocate or shrink the `String`,
18611861
/// so the leaked allocation may include unused capacity that is not part
1862-
/// of the returned slice.
1862+
/// of the returned slice. If you don't want that, call [`into_boxed_str`],
1863+
/// and then [`Box::leak`].
1864+
///
1865+
/// [`into_boxed_str`]: Self::into_boxed_str
18631866
///
18641867
/// # Examples
18651868
///
18661869
/// Simple usage:
18671870
///
18681871
/// ```
1869-
/// #![feature(string_leak)]
1870-
///
18711872
/// let x = String::from("bucket");
18721873
/// let static_ref: &'static mut str = x.leak();
18731874
/// assert_eq!(static_ref, "bucket");
18741875
/// ```
1875-
#[unstable(feature = "string_leak", issue = "102929")]
1876+
#[stable(feature = "string_leak", since = "CURRENT_RUSTC_VERSION")]
18761877
#[inline]
18771878
pub fn leak<'a>(self) -> &'a mut str {
18781879
let slice = self.vec.leak();

library/core/src/slice/mod.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -2995,7 +2995,7 @@ impl<T> [T] {
29952995
/// This reordering has the additional property that any value at position `i < index` will be
29962996
/// less than or equal to any value at a position `j > index`. Additionally, this reordering is
29972997
/// unstable (i.e. any number of equal elements may end up at position `index`), in-place
2998-
/// (i.e. does not allocate), and *O*(*n*) on average. The worst-case performance is *O*(*n* log *n*).
2998+
/// (i.e. does not allocate), and runs in *O*(*n*) time.
29992999
/// This function is also known as "kth element" in other libraries.
30003000
///
30013001
/// It returns a triplet of the following from the reordered slice:
@@ -3045,9 +3045,8 @@ impl<T> [T] {
30453045
/// This reordering has the additional property that any value at position `i < index` will be
30463046
/// less than or equal to any value at a position `j > index` using the comparator function.
30473047
/// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
3048-
/// position `index`), in-place (i.e. does not allocate), and *O*(*n*) on average.
3049-
/// The worst-case performance is *O*(*n* log *n*). This function is also known as
3050-
/// "kth element" in other libraries.
3048+
/// position `index`), in-place (i.e. does not allocate), and runs in *O*(*n*) time.
3049+
/// This function is also known as "kth element" in other libraries.
30513050
///
30523051
/// It returns a triplet of the following from
30533052
/// the slice reordered according to the provided comparator function: the subslice prior to
@@ -3101,8 +3100,7 @@ impl<T> [T] {
31013100
/// This reordering has the additional property that any value at position `i < index` will be
31023101
/// less than or equal to any value at a position `j > index` using the key extraction function.
31033102
/// Additionally, this reordering is unstable (i.e. any number of equal elements may end up at
3104-
/// position `index`), in-place (i.e. does not allocate), and *O*(*n*) on average.
3105-
/// The worst-case performance is *O*(*n* log *n*).
3103+
/// position `index`), in-place (i.e. does not allocate), and runs in *O*(*n*) time.
31063104
/// This function is also known as "kth element" in other libraries.
31073105
///
31083106
/// It returns a triplet of the following from

library/std/src/collections/hash/set.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,9 @@ where
868868
/// Returns whether the value was newly inserted. That is:
869869
///
870870
/// - If the set did not previously contain this value, `true` is returned.
871-
/// - If the set already contained this value, `false` is returned.
871+
/// - If the set already contained this value, `false` is returned,
872+
/// and the set is not modified: original value is not replaced,
873+
/// and the value passed as argument is dropped.
872874
///
873875
/// # Examples
874876
///

library/std/src/collections/hash/set/tests.rs

+20
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::HashSet;
33

44
use crate::panic::{catch_unwind, AssertUnwindSafe};
55
use crate::sync::atomic::{AtomicU32, Ordering};
6+
use crate::sync::Arc;
67

78
#[test]
89
fn test_zero_capacities() {
@@ -502,3 +503,22 @@ fn const_with_hasher() {
502503
const X: HashSet<(), ()> = HashSet::with_hasher(());
503504
assert_eq!(X.len(), 0);
504505
}
506+
507+
#[test]
508+
fn test_insert_does_not_overwrite_the_value() {
509+
let first_value = Arc::new(17);
510+
let second_value = Arc::new(17);
511+
512+
let mut set = HashSet::new();
513+
let inserted = set.insert(first_value.clone());
514+
assert!(inserted);
515+
516+
let inserted = set.insert(second_value);
517+
assert!(!inserted);
518+
519+
assert!(
520+
Arc::ptr_eq(set.iter().next().unwrap(), &first_value),
521+
"Insert must not overwrite the value, so the contained value pointer \
522+
must be the same as first value pointer we inserted"
523+
);
524+
}

library/std/src/ffi/os_str.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ impl OsStr {
745745
without modifying the original"]
746746
#[inline]
747747
pub fn to_str(&self) -> Option<&str> {
748-
self.inner.to_str()
748+
self.inner.to_str().ok()
749749
}
750750

751751
/// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
@@ -1165,6 +1165,24 @@ impl<'a> From<Cow<'a, OsStr>> for OsString {
11651165
}
11661166
}
11671167

1168+
#[stable(feature = "str_tryfrom_osstr_impl", since = "CURRENT_RUSTC_VERSION")]
1169+
impl<'a> TryFrom<&'a OsStr> for &'a str {
1170+
type Error = crate::str::Utf8Error;
1171+
1172+
/// Tries to convert an `&OsStr` to a `&str`.
1173+
///
1174+
/// ```
1175+
/// use std::ffi::OsStr;
1176+
///
1177+
/// let os_str = OsStr::new("foo");
1178+
/// let as_str = <&str>::try_from(os_str).unwrap();
1179+
/// assert_eq!(as_str, "foo");
1180+
/// ```
1181+
fn try_from(value: &'a OsStr) -> Result<Self, Self::Error> {
1182+
value.inner.to_str()
1183+
}
1184+
}
1185+
11681186
#[stable(feature = "box_default_extra", since = "1.17.0")]
11691187
impl Default for Box<OsStr> {
11701188
#[inline]

library/std/src/sys/unix/os_str.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ impl Slice {
207207
unsafe { Slice::from_os_str_bytes_unchecked(s.as_bytes()) }
208208
}
209209

210-
pub fn to_str(&self) -> Option<&str> {
211-
str::from_utf8(&self.inner).ok()
210+
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
211+
str::from_utf8(&self.inner)
212212
}
213213

214214
pub fn to_string_lossy(&self) -> Cow<'_, str> {

library/std/src/sys/windows/os_str.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl Slice {
166166
unsafe { mem::transmute(Wtf8::from_str(s)) }
167167
}
168168

169-
pub fn to_str(&self) -> Option<&str> {
169+
pub fn to_str(&self) -> Result<&str, crate::str::Utf8Error> {
170170
self.inner.as_str()
171171
}
172172

library/std/src/sys_common/wtf8.rs

+2-7
Original file line numberDiff line numberDiff line change
@@ -626,13 +626,8 @@ impl Wtf8 {
626626
///
627627
/// This does not copy the data.
628628
#[inline]
629-
pub fn as_str(&self) -> Option<&str> {
630-
// Well-formed WTF-8 is also well-formed UTF-8
631-
// if and only if it contains no surrogate.
632-
match self.next_surrogate(0) {
633-
None => Some(unsafe { str::from_utf8_unchecked(&self.bytes) }),
634-
Some(_) => None,
635-
}
629+
pub fn as_str(&self) -> Result<&str, str::Utf8Error> {
630+
str::from_utf8(&self.bytes)
636631
}
637632

638633
/// Creates an owned `Wtf8Buf` from a borrowed `Wtf8`.

library/std/src/sys_common/wtf8/tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -521,11 +521,11 @@ fn wtf8_code_points() {
521521

522522
#[test]
523523
fn wtf8_as_str() {
524-
assert_eq!(Wtf8::from_str("").as_str(), Some(""));
525-
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Some("aé 💩"));
524+
assert_eq!(Wtf8::from_str("").as_str(), Ok(""));
525+
assert_eq!(Wtf8::from_str("aé 💩").as_str(), Ok("aé 💩"));
526526
let mut string = Wtf8Buf::new();
527527
string.push(CodePoint::from_u32(0xD800).unwrap());
528-
assert_eq!(string.as_str(), None);
528+
assert!(string.as_str().is_err());
529529
}
530530

531531
#[test]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
trait Trait {
2+
const ASSOC: i32;
3+
}
4+
5+
impl Trait for () {
6+
const ASSOC: &dyn Fn(_) = 1i32;
7+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
8+
}
9+
10+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
2+
--> $DIR/infer-placeholder-in-non-suggestable-pos.rs:6:26
3+
|
4+
LL | const ASSOC: &dyn Fn(_) = 1i32;
5+
| ^ not allowed in type signatures
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0121`.

tests/ui/const-generics/generic_arg_infer/in-signature.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
3333
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for static variables
3434
trait ArrAssocConst {
3535
const ARR: [u8; _];
36-
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
36+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
3737
}
3838
trait TyAssocConst {
3939
const ARR: Bar<i32, _>;
40-
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
40+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
4141
}
4242
trait TyAssocConstMixed {
4343
const ARR: Bar<_, _>;
44-
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants
44+
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated constants
4545
}
4646

4747
trait AssocTy {

tests/ui/const-generics/generic_arg_infer/in-signature.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,19 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::<i32, 3>(0);
7474
| not allowed in type signatures
7575
| help: replace with the correct type: `Bar<i32, 3>`
7676

77-
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
77+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
7878
--> $DIR/in-signature.rs:35:21
7979
|
8080
LL | const ARR: [u8; _];
8181
| ^ not allowed in type signatures
8282

83-
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
83+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
8484
--> $DIR/in-signature.rs:39:25
8585
|
8686
LL | const ARR: Bar<i32, _>;
8787
| ^ not allowed in type signatures
8888

89-
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
89+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
9090
--> $DIR/in-signature.rs:43:20
9191
|
9292
LL | const ARR: Bar<_, _>;

tests/ui/typeck/type-placeholder-fn-in-const.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ struct MyStruct;
33
trait Test {
44
const TEST: fn() -> _;
55
//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121]
6-
//~| ERROR: the placeholder `_` is not allowed within types on item signatures for constants [E0121]
6+
//~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121]
77
}
88

99
impl Test for MyStruct {
1010
const TEST: fn() -> _ = 42;
1111
//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for functions [E0121]
12+
//~| ERROR: the placeholder `_` is not allowed within types on item signatures for associated constants [E0121]
1213
}
1314

1415
fn main() {}

tests/ui/typeck/type-placeholder-fn-in-const.stderr

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
44
LL | const TEST: fn() -> _;
55
| ^ not allowed in type signatures
66

7-
error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
7+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
88
--> $DIR/type-placeholder-fn-in-const.rs:4:25
99
|
1010
LL | const TEST: fn() -> _;
@@ -16,6 +16,12 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures
1616
LL | const TEST: fn() -> _ = 42;
1717
| ^ not allowed in type signatures
1818

19-
error: aborting due to 3 previous errors
19+
error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
20+
--> $DIR/type-placeholder-fn-in-const.rs:10:25
21+
|
22+
LL | const TEST: fn() -> _ = 42;
23+
| ^ not allowed in type signatures
24+
25+
error: aborting due to 4 previous errors
2026

2127
For more information about this error, try `rustc --explain E0121`.

0 commit comments

Comments
 (0)