Skip to content

Commit 6a0e442

Browse files
committed
Auto merge of #126297 - jhpratt:rollup-ntic8q6, r=jhpratt
Rollup of 6 pull requests Successful merges: - #123374 (DOC: Add FFI example for slice::from_raw_parts()) - #126127 (Spell out other trait diagnostic) - #126228 (Provide correct parent for nested anon const) - #126249 (Simplify `[T; N]::try_map` signature) - #126256 (Add {{target}} substitution to compiletest) - #126263 (Make issue-122805.rs big endian compatible) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 9a7bf4a + 8732f19 commit 6a0e442

File tree

48 files changed

+450
-362
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+450
-362
lines changed

compiler/rustc_hir_analysis/src/collect/generics_of.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_session::lint;
1111
use rustc_span::symbol::{kw, Symbol};
1212
use rustc_span::Span;
1313

14+
#[instrument(level = "debug", skip(tcx))]
1415
pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
1516
use rustc_hir::*;
1617

@@ -66,7 +67,22 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
6667
// FIXME(#43408) always enable this once `lazy_normalization` is
6768
// stable enough and does not need a feature gate anymore.
6869
Node::AnonConst(_) => {
69-
let parent_def_id = tcx.hir().get_parent_item(hir_id);
70+
let parent_did = tcx.parent(def_id.to_def_id());
71+
72+
// We don't do this unconditionally because the `DefId` parent of an anon const
73+
// might be an implicitly created closure during `async fn` desugaring. This would
74+
// have the wrong generics.
75+
//
76+
// i.e. `async fn foo<'a>() { let a = [(); { 1 + 2 }]; bar().await() }`
77+
// would implicitly have a closure in its body that would be the parent of
78+
// the `{ 1 + 2 }` anon const. This closure's generics is simply a witness
79+
// instead of `['a]`.
80+
let parent_did = if let DefKind::AnonConst = tcx.def_kind(parent_did) {
81+
parent_did
82+
} else {
83+
tcx.hir().get_parent_item(hir_id).to_def_id()
84+
};
85+
debug!(?parent_did);
7086

7187
let mut in_param_ty = false;
7288
for (_parent, node) in tcx.hir().parent_iter(hir_id) {
@@ -121,7 +137,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
121137
//
122138
// This has some implications for how we get the predicates available to the anon const
123139
// see `explicit_predicates_of` for more information on this
124-
let generics = tcx.generics_of(parent_def_id.to_def_id());
140+
let generics = tcx.generics_of(parent_did);
125141
let param_def_idx = generics.param_def_id_to_index[&param_id.to_def_id()];
126142
// In the above example this would be .params[..N#0]
127143
let own_params = generics.params_to(param_def_idx as usize, tcx).to_owned();
@@ -147,7 +163,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
147163
//
148164
// Note that we do not supply the parent generics when using
149165
// `min_const_generics`.
150-
Some(parent_def_id.to_def_id())
166+
Some(parent_did)
151167
}
152168
} else {
153169
let parent_node = tcx.parent_hir_node(hir_id);
@@ -159,7 +175,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
159175
Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
160176
if constant.hir_id() == hir_id =>
161177
{
162-
Some(parent_def_id.to_def_id())
178+
Some(parent_did)
163179
}
164180
// Exclude `GlobalAsm` here which cannot have generics.
165181
Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
@@ -171,7 +187,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
171187
_ => false,
172188
}) =>
173189
{
174-
Some(parent_def_id.to_def_id())
190+
Some(parent_did)
175191
}
176192
_ => None,
177193
}

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2064,7 +2064,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
20642064
if all_traits_equal {
20652065
format!("\n {}", c.self_ty())
20662066
} else {
2067-
format!("\n {c}")
2067+
format!("\n `{}` implements `{}`", c.self_ty(), c.print_only_trait_path())
20682068
}
20692069
})
20702070
.collect();

library/core/src/array/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -533,11 +533,9 @@ impl<T, const N: usize> [T; N] {
533533
/// assert_eq!(c, Some(a));
534534
/// ```
535535
#[unstable(feature = "array_try_map", issue = "79711")]
536-
pub fn try_map<F, R>(self, f: F) -> ChangeOutputType<R, [R::Output; N]>
536+
pub fn try_map<R>(self, f: impl FnMut(T) -> R) -> ChangeOutputType<R, [R::Output; N]>
537537
where
538-
F: FnMut(T) -> R,
539-
R: Try,
540-
R::Residual: Residual<[R::Output; N]>,
538+
R: Try<Residual: Residual<[R::Output; N]>>,
541539
{
542540
drain_array_with(self, |iter| try_from_trusted_iterator(iter.map(f)))
543541
}

library/core/src/ops/try_trait.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,9 @@ pub trait Residual<O> {
363363
}
364364

365365
#[unstable(feature = "pub_crate_should_not_need_unstable_attr", issue = "none")]
366-
pub(crate) type ChangeOutputType<T, V> = <<T as Try>::Residual as Residual<V>>::TryType;
366+
#[allow(type_alias_bounds)]
367+
pub(crate) type ChangeOutputType<T: Try<Residual: Residual<V>>, V> =
368+
<T::Residual as Residual<V>>::TryType;
367369

368370
/// An adapter for implementing non-try methods via the `Try` implementation.
369371
///

library/core/src/slice/raw.rs

+33
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,39 @@ use crate::ub_checks;
8282
/// }
8383
/// ```
8484
///
85+
/// ### FFI: Handling null pointers
86+
///
87+
/// In languages such as C++, pointers to empty collections are not guaranteed to be non-null.
88+
/// When accepting such pointers, they have to be checked for null-ness to avoid undefined
89+
/// behavior.
90+
///
91+
/// ```
92+
/// use std::slice;
93+
///
94+
/// /// Sum the elements of an FFI slice.
95+
/// ///
96+
/// /// # Safety
97+
/// ///
98+
/// /// If ptr is not NULL, it must be correctly aligned and
99+
/// /// point to `len` initialized items of type `f32`.
100+
/// unsafe extern "C" fn sum_slice(ptr: *const f32, len: usize) -> f32 {
101+
/// let data = if ptr.is_null() {
102+
/// // `len` is assumed to be 0.
103+
/// &[]
104+
/// } else {
105+
/// // SAFETY: see function docstring.
106+
/// unsafe { slice::from_raw_parts(ptr, len) }
107+
/// };
108+
/// data.into_iter().sum()
109+
/// }
110+
///
111+
/// // This could be the result of C++'s std::vector::data():
112+
/// let ptr = std::ptr::null();
113+
/// // And this could be std::vector::size():
114+
/// let len = 0;
115+
/// assert_eq!(unsafe { sum_slice(ptr, len) }, 0.0);
116+
/// ```
117+
///
85118
/// [valid]: ptr#safety
86119
/// [`NonNull::dangling()`]: ptr::NonNull::dangling
87120
#[inline]

src/tools/compiletest/src/header.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ fn expand_variables(mut value: String, config: &Config) -> String {
12811281
const BUILD_BASE: &str = "{{build-base}}";
12821282
const SYSROOT_BASE: &str = "{{sysroot-base}}";
12831283
const TARGET_LINKER: &str = "{{target-linker}}";
1284+
const TARGET: &str = "{{target}}";
12841285

12851286
if value.contains(CWD) {
12861287
let cwd = env::current_dir().unwrap();
@@ -1303,6 +1304,10 @@ fn expand_variables(mut value: String, config: &Config) -> String {
13031304
value = value.replace(TARGET_LINKER, config.target_linker.as_deref().unwrap_or(""));
13041305
}
13051306

1307+
if value.contains(TARGET) {
1308+
value = value.replace(TARGET, &config.target);
1309+
}
1310+
13061311
value
13071312
}
13081313

src/tools/tidy/src/target_specific_tests.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ pub fn check(path: &Path, bad: &mut bool) {
5353
} else if directive.starts_with(COMPILE_FLAGS_HEADER) {
5454
let compile_flags = &directive[COMPILE_FLAGS_HEADER.len()..];
5555
if let Some((_, v)) = compile_flags.split_once("--target") {
56-
if let Some((arch, _)) =
57-
v.trim_start_matches(|c| c == ' ' || c == '=').split_once("-")
58-
{
56+
let v = v.trim_start_matches(|c| c == ' ' || c == '=');
57+
let v = if v == "{{target}}" { Some((v, v)) } else { v.split_once("-") };
58+
if let Some((arch, _)) = v {
5959
let info = header_map.entry(revision).or_insert(RevisionInfo::default());
6060
info.target_arch.replace(arch);
6161
} else {

tests/codegen/issues/issue-122805.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,20 @@
3939
// OPT3WINX64-NEXT: store <8 x i16>
4040
// CHECK-NEXT: ret void
4141
#[no_mangle]
42-
#[cfg(target_endian = "little")]
4342
pub fn convert(value: [u16; 8]) -> [u8; 16] {
43+
#[cfg(target_endian = "little")]
44+
let bswap = u16::to_be;
45+
#[cfg(target_endian = "big")]
46+
let bswap = u16::to_le;
4447
let addr16 = [
45-
value[0].to_be(),
46-
value[1].to_be(),
47-
value[2].to_be(),
48-
value[3].to_be(),
49-
value[4].to_be(),
50-
value[5].to_be(),
51-
value[6].to_be(),
52-
value[7].to_be(),
48+
bswap(value[0]),
49+
bswap(value[1]),
50+
bswap(value[2]),
51+
bswap(value[3]),
52+
bswap(value[4]),
53+
bswap(value[5]),
54+
bswap(value[6]),
55+
bswap(value[7]),
5356
];
5457
unsafe { core::mem::transmute::<_, [u8; 16]>(addr16) }
5558
}

tests/ui/binop/binary-op-suggest-deref.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,10 @@ LL | let _ = FOO & (*"Sized".to_string().into_boxed_str());
303303
|
304304
= help: the trait `BitAnd<str>` is not implemented for `i32`
305305
= help: the following other types implement trait `BitAnd<Rhs>`:
306-
<&'a i32 as BitAnd<i32>>
307-
<&i32 as BitAnd<&i32>>
308-
<i32 as BitAnd<&i32>>
309-
<i32 as BitAnd>
306+
`&'a i32` implements `BitAnd<i32>`
307+
`&i32` implements `BitAnd<&i32>`
308+
`i32` implements `BitAnd<&i32>`
309+
`i32` implements `BitAnd`
310310

311311
error[E0277]: the size for values of type `str` cannot be known at compilation time
312312
--> $DIR/binary-op-suggest-deref.rs:78:17

tests/ui/binop/binop-mul-i32-f32.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ LL | x * y
66
|
77
= help: the trait `Mul<f32>` is not implemented for `i32`
88
= help: the following other types implement trait `Mul<Rhs>`:
9-
<&'a i32 as Mul<i32>>
10-
<&i32 as Mul<&i32>>
11-
<i32 as Mul<&i32>>
12-
<i32 as Mul>
9+
`&'a i32` implements `Mul<i32>`
10+
`&i32` implements `Mul<&i32>`
11+
`i32` implements `Mul<&i32>`
12+
`i32` implements `Mul`
1313

1414
error: aborting due to 1 previous error
1515

tests/ui/binop/shift-various-bad-types.stderr

+24-24
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ LL | 22 >> p.char;
66
|
77
= help: the trait `Shr<char>` is not implemented for `{integer}`
88
= help: the following other types implement trait `Shr<Rhs>`:
9-
<&'a i128 as Shr<i128>>
10-
<&'a i128 as Shr<i16>>
11-
<&'a i128 as Shr<i32>>
12-
<&'a i128 as Shr<i64>>
13-
<&'a i128 as Shr<i8>>
14-
<&'a i128 as Shr<isize>>
15-
<&'a i128 as Shr<u128>>
16-
<&'a i128 as Shr<u16>>
9+
`&'a i128` implements `Shr<i128>`
10+
`&'a i128` implements `Shr<i16>`
11+
`&'a i128` implements `Shr<i32>`
12+
`&'a i128` implements `Shr<i64>`
13+
`&'a i128` implements `Shr<i8>`
14+
`&'a i128` implements `Shr<isize>`
15+
`&'a i128` implements `Shr<u128>`
16+
`&'a i128` implements `Shr<u16>`
1717
and 568 others
1818

1919
error[E0277]: no implementation for `{integer} >> &str`
@@ -24,14 +24,14 @@ LL | 22 >> p.str;
2424
|
2525
= help: the trait `Shr<&str>` is not implemented for `{integer}`
2626
= help: the following other types implement trait `Shr<Rhs>`:
27-
<&'a i128 as Shr<i128>>
28-
<&'a i128 as Shr<i16>>
29-
<&'a i128 as Shr<i32>>
30-
<&'a i128 as Shr<i64>>
31-
<&'a i128 as Shr<i8>>
32-
<&'a i128 as Shr<isize>>
33-
<&'a i128 as Shr<u128>>
34-
<&'a i128 as Shr<u16>>
27+
`&'a i128` implements `Shr<i128>`
28+
`&'a i128` implements `Shr<i16>`
29+
`&'a i128` implements `Shr<i32>`
30+
`&'a i128` implements `Shr<i64>`
31+
`&'a i128` implements `Shr<i8>`
32+
`&'a i128` implements `Shr<isize>`
33+
`&'a i128` implements `Shr<u128>`
34+
`&'a i128` implements `Shr<u16>`
3535
and 568 others
3636

3737
error[E0277]: no implementation for `{integer} >> &Panolpy`
@@ -42,14 +42,14 @@ LL | 22 >> p;
4242
|
4343
= help: the trait `Shr<&Panolpy>` is not implemented for `{integer}`
4444
= help: the following other types implement trait `Shr<Rhs>`:
45-
<&'a i128 as Shr<i128>>
46-
<&'a i128 as Shr<i16>>
47-
<&'a i128 as Shr<i32>>
48-
<&'a i128 as Shr<i64>>
49-
<&'a i128 as Shr<i8>>
50-
<&'a i128 as Shr<isize>>
51-
<&'a i128 as Shr<u128>>
52-
<&'a i128 as Shr<u16>>
45+
`&'a i128` implements `Shr<i128>`
46+
`&'a i128` implements `Shr<i16>`
47+
`&'a i128` implements `Shr<i32>`
48+
`&'a i128` implements `Shr<i64>`
49+
`&'a i128` implements `Shr<i8>`
50+
`&'a i128` implements `Shr<isize>`
51+
`&'a i128` implements `Shr<u128>`
52+
`&'a i128` implements `Shr<u16>`
5353
and 568 others
5454

5555
error[E0308]: mismatched types

tests/ui/const-generics/exhaustive-value.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ LL | <() as Foo<N>>::test()
55
| ^^ the trait `Foo<N>` is not implemented for `()`
66
|
77
= help: the following other types implement trait `Foo<N>`:
8-
<() as Foo<0>>
9-
<() as Foo<100>>
10-
<() as Foo<101>>
11-
<() as Foo<102>>
12-
<() as Foo<103>>
13-
<() as Foo<104>>
14-
<() as Foo<105>>
15-
<() as Foo<106>>
8+
`()` implements `Foo<0>`
9+
`()` implements `Foo<100>`
10+
`()` implements `Foo<101>`
11+
`()` implements `Foo<102>`
12+
`()` implements `Foo<103>`
13+
`()` implements `Foo<104>`
14+
`()` implements `Foo<105>`
15+
`()` implements `Foo<106>`
1616
and 248 others
1717

1818
error: aborting due to 1 previous error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Given an anon const `a`: `{ N }` and some anon const `b` which references the
2+
// first anon const: `{ [1; a] }`. `b` should not have any generics as it is not
3+
// a simple `N` argument nor is it a repeat expr count.
4+
//
5+
// On the other hand `b` *is* a repeat expr count and so it should inherit its
6+
// parents generics as part of the `const_evaluatable_unchecked` fcw (#76200).
7+
//
8+
// In this specific case however `b`'s parent should be `a` and so it should wind
9+
// up not having any generics after all. If `a` were to inherit its generics from
10+
// the enclosing item then the reference to `a` from `b` would contain generic
11+
// parameters not usable by `b` which would cause us to ICE.
12+
13+
fn bar<const N: usize>() {}
14+
15+
fn foo<const N: usize>() {
16+
bar::<{ [1; N] }>();
17+
//~^ ERROR: generic parameters may not be used in const operations
18+
}
19+
20+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
error: generic parameters may not be used in const operations
2+
--> $DIR/repeat_expr_hack_gives_right_generics.rs:16:17
3+
|
4+
LL | bar::<{ [1; N] }>();
5+
| ^ cannot perform const operation using `N`
6+
|
7+
= help: const parameters may only be used as standalone arguments, i.e. `N`
8+
= help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
9+
10+
error: aborting due to 1 previous error
11+

tests/ui/consts/const-eval/const-eval-overflow-3b.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | = [0; (i8::MAX + 1u8) as usize];
1212
|
1313
= help: the trait `Add<u8>` is not implemented for `i8`
1414
= help: the following other types implement trait `Add<Rhs>`:
15-
<&'a i8 as Add<i8>>
16-
<&i8 as Add<&i8>>
17-
<i8 as Add<&i8>>
18-
<i8 as Add>
15+
`&'a i8` implements `Add<i8>`
16+
`&i8` implements `Add<&i8>`
17+
`i8` implements `Add<&i8>`
18+
`i8` implements `Add`
1919

2020
error: aborting due to 2 previous errors
2121

tests/ui/consts/const-eval/const-eval-overflow-4b.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
1212
|
1313
= help: the trait `Add<u8>` is not implemented for `i8`
1414
= help: the following other types implement trait `Add<Rhs>`:
15-
<&'a i8 as Add<i8>>
16-
<&i8 as Add<&i8>>
17-
<i8 as Add<&i8>>
18-
<i8 as Add>
15+
`&'a i8` implements `Add<i8>`
16+
`&i8` implements `Add<&i8>`
17+
`i8` implements `Add<&i8>`
18+
`i8` implements `Add`
1919

2020
error[E0604]: only `u8` can be cast as `char`, not `i8`
2121
--> $DIR/const-eval-overflow-4b.rs:22:13

0 commit comments

Comments
 (0)