Skip to content

Commit 5e93f6e

Browse files
committed
Auto merge of rust-lang#91539 - matthiaskrgr:rollup-rnl10yb, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#89642 (environ on macos uses directly libc which has the correct signature.) - rust-lang#90022 (Explain why `Self` is invalid in generic parameters) - rust-lang#90023 (Postpone the evaluation of constant expressions that depend on inference variables) - rust-lang#91215 (Implement VecDeque::retain_mut) - rust-lang#91355 (std: Stabilize the `thread_local_const_init` feature) - rust-lang#91528 (LLVM support .insn directive) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents efec545 + 2ba5917 commit 5e93f6e

File tree

27 files changed

+396
-88
lines changed

27 files changed

+396
-88
lines changed

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

+66-26
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::infer::type_variable::TypeVariableOriginKind;
22
use crate::infer::InferCtxt;
3+
use crate::rustc_middle::ty::TypeFoldable;
34
use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder};
45
use rustc_hir as hir;
56
use rustc_hir::def::{DefKind, Namespace};
@@ -400,36 +401,75 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
400401
}
401402
}
402403
GenericArgKind::Const(ct) => {
403-
if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.val {
404-
let origin =
405-
self.inner.borrow_mut().const_unification_table().probe_value(vid).origin;
406-
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
407-
origin.kind
408-
{
409-
return InferenceDiagnosticsData {
410-
name: name.to_string(),
404+
match ct.val {
405+
ty::ConstKind::Infer(InferConst::Var(vid)) => {
406+
let origin = self
407+
.inner
408+
.borrow_mut()
409+
.const_unification_table()
410+
.probe_value(vid)
411+
.origin;
412+
if let ConstVariableOriginKind::ConstParameterDefinition(name, def_id) =
413+
origin.kind
414+
{
415+
return InferenceDiagnosticsData {
416+
name: name.to_string(),
417+
span: Some(origin.span),
418+
kind: UnderspecifiedArgKind::Const { is_parameter: true },
419+
parent: InferenceDiagnosticsParentData::for_def_id(
420+
self.tcx, def_id,
421+
),
422+
};
423+
}
424+
425+
debug_assert!(!origin.span.is_dummy());
426+
let mut s = String::new();
427+
let mut printer =
428+
ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
429+
if let Some(highlight) = highlight {
430+
printer.region_highlight_mode = highlight;
431+
}
432+
let _ = ct.print(printer);
433+
InferenceDiagnosticsData {
434+
name: s,
411435
span: Some(origin.span),
412-
kind: UnderspecifiedArgKind::Const { is_parameter: true },
413-
parent: InferenceDiagnosticsParentData::for_def_id(self.tcx, def_id),
414-
};
436+
kind: UnderspecifiedArgKind::Const { is_parameter: false },
437+
parent: None,
438+
}
415439
}
416-
417-
debug_assert!(!origin.span.is_dummy());
418-
let mut s = String::new();
419-
let mut printer =
420-
ty::print::FmtPrinter::new(self.tcx, &mut s, Namespace::ValueNS);
421-
if let Some(highlight) = highlight {
422-
printer.region_highlight_mode = highlight;
440+
ty::ConstKind::Unevaluated(ty::Unevaluated {
441+
substs_: Some(substs), ..
442+
}) => {
443+
assert!(substs.has_infer_types_or_consts());
444+
445+
// FIXME: We only use the first inference variable we encounter in
446+
// `substs` here, this gives insufficiently informative diagnostics
447+
// in case there are multiple inference variables
448+
for s in substs.iter() {
449+
match s.unpack() {
450+
GenericArgKind::Type(t) => match t.kind() {
451+
ty::Infer(_) => {
452+
return self.extract_inference_diagnostics_data(s, None);
453+
}
454+
_ => {}
455+
},
456+
GenericArgKind::Const(c) => match c.val {
457+
ty::ConstKind::Infer(InferConst::Var(_)) => {
458+
return self.extract_inference_diagnostics_data(s, None);
459+
}
460+
_ => {}
461+
},
462+
_ => {}
463+
}
464+
}
465+
bug!(
466+
"expected an inference variable in substs of unevaluated const {:?}",
467+
ct
468+
);
423469
}
424-
let _ = ct.print(printer);
425-
InferenceDiagnosticsData {
426-
name: s,
427-
span: Some(origin.span),
428-
kind: UnderspecifiedArgKind::Const { is_parameter: false },
429-
parent: None,
470+
_ => {
471+
bug!("unexpect const: {:?}", ct);
430472
}
431-
} else {
432-
bug!("unexpect const: {:?}", ct);
433473
}
434474
}
435475
GenericArgKind::Lifetime(_) => bug!("unexpected lifetime"),

compiler/rustc_infer/src/infer/mod.rs

+19-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2121
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
2222
use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
2323
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
24+
use rustc_middle::mir::interpret::ErrorHandled;
2425
use rustc_middle::mir::interpret::EvalToConstValueResult;
2526
use rustc_middle::traits::select;
2627
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -1584,13 +1585,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15841585
unevaluated: ty::Unevaluated<'tcx>,
15851586
span: Option<Span>,
15861587
) -> EvalToConstValueResult<'tcx> {
1587-
let mut original_values = OriginalQueryValues::default();
1588-
let canonical = self.canonicalize_query((param_env, unevaluated), &mut original_values);
1588+
let mut substs = unevaluated.substs(self.tcx);
1589+
substs = self.resolve_vars_if_possible(substs);
1590+
1591+
// Postpone the evaluation of constants whose substs depend on inference
1592+
// variables
1593+
if substs.has_infer_types_or_consts() {
1594+
return Err(ErrorHandled::TooGeneric);
1595+
}
1596+
1597+
let param_env_erased = self.tcx.erase_regions(param_env);
1598+
let substs_erased = self.tcx.erase_regions(substs);
1599+
1600+
let unevaluated = ty::Unevaluated {
1601+
def: unevaluated.def,
1602+
substs_: Some(substs_erased),
1603+
promoted: unevaluated.promoted,
1604+
};
15891605

1590-
let (param_env, unevaluated) = canonical.value;
15911606
// The return value is the evaluated value which doesn't contain any reference to inference
15921607
// variables, thus we don't need to substitute back the original values.
1593-
self.tcx.const_eval_resolve(param_env, unevaluated, span)
1608+
self.tcx.const_eval_resolve(param_env_erased, unevaluated, span)
15941609
}
15951610

15961611
/// If `typ` is a type variable of some kind, resolve it one level

compiler/rustc_middle/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
#![feature(control_flow_enum)]
5252
#![feature(associated_type_defaults)]
5353
#![feature(iter_zip)]
54-
#![feature(thread_local_const_init)]
5554
#![feature(trusted_step)]
5655
#![feature(try_blocks)]
5756
#![feature(try_reserve_kind)]

compiler/rustc_parse/src/parser/generics.rs

+13
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ impl<'a> Parser<'a> {
9292
let attrs = self.parse_outer_attributes()?;
9393
let param =
9494
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
95+
if this.eat_keyword_noexpect(kw::SelfUpper) {
96+
// `Self` as a generic param is invalid. Here we emit the diagnostic and continue parsing
97+
// as if `Self` never existed.
98+
this.struct_span_err(
99+
this.prev_token.span,
100+
"unexpected keyword `Self` in generic parameters",
101+
)
102+
.note("you cannot use `Self` as a generic parameter because it is reserved for associated items")
103+
.emit();
104+
105+
this.eat(&token::Comma);
106+
}
107+
95108
let param = if this.check_lifetime() {
96109
let lifetime = this.expect_lifetime();
97110
// Parse lifetime parameter.

compiler/rustc_query_system/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#![feature(iter_zip)]
66
#![feature(let_else)]
77
#![feature(min_specialization)]
8-
#![feature(thread_local_const_init)]
98
#![feature(extern_types)]
109

1110
#[macro_use]

compiler/rustc_span/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#![feature(negative_impls)]
2121
#![feature(nll)]
2222
#![feature(min_specialization)]
23-
#![feature(thread_local_const_init)]
2423

2524
#[macro_use]
2625
extern crate rustc_macros;

library/alloc/src/collections/vec_deque/mod.rs

+34-3
Original file line numberDiff line numberDiff line change
@@ -2148,14 +2148,45 @@ impl<T, A: Allocator> VecDeque<T, A> {
21482148
pub fn retain<F>(&mut self, mut f: F)
21492149
where
21502150
F: FnMut(&T) -> bool,
2151+
{
2152+
self.retain_mut(|elem| f(elem));
2153+
}
2154+
2155+
/// Retains only the elements specified by the predicate.
2156+
///
2157+
/// In other words, remove all elements `e` such that `f(&e)` returns false.
2158+
/// This method operates in place, visiting each element exactly once in the
2159+
/// original order, and preserves the order of the retained elements.
2160+
///
2161+
/// # Examples
2162+
///
2163+
/// ```
2164+
/// #![feature(vec_retain_mut)]
2165+
///
2166+
/// use std::collections::VecDeque;
2167+
///
2168+
/// let mut buf = VecDeque::new();
2169+
/// buf.extend(1..5);
2170+
/// buf.retain_mut(|x| if *x % 2 == 0 {
2171+
/// *x += 1;
2172+
/// true
2173+
/// } else {
2174+
/// false
2175+
/// });
2176+
/// assert_eq!(buf, [3, 5]);
2177+
/// ```
2178+
#[unstable(feature = "vec_retain_mut", issue = "90829")]
2179+
pub fn retain_mut<F>(&mut self, mut f: F)
2180+
where
2181+
F: FnMut(&mut T) -> bool,
21512182
{
21522183
let len = self.len();
21532184
let mut idx = 0;
21542185
let mut cur = 0;
21552186

21562187
// Stage 1: All values are retained.
21572188
while cur < len {
2158-
if !f(&self[cur]) {
2189+
if !f(&mut self[cur]) {
21592190
cur += 1;
21602191
break;
21612192
}
@@ -2164,7 +2195,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
21642195
}
21652196
// Stage 2: Swap retained value into current idx.
21662197
while cur < len {
2167-
if !f(&self[cur]) {
2198+
if !f(&mut self[cur]) {
21682199
cur += 1;
21692200
continue;
21702201
}
@@ -2173,7 +2204,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
21732204
cur += 1;
21742205
idx += 1;
21752206
}
2176-
// Stage 3: Trancate all values after idx.
2207+
// Stage 3: Truncate all values after idx.
21772208
if cur != idx {
21782209
self.truncate(idx);
21792210
}

library/std/src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,7 @@
216216
// std may use features in a platform-specific way
217217
#![allow(unused_features)]
218218
#![feature(rustc_allow_const_fn_unstable)]
219-
#![cfg_attr(
220-
test,
221-
feature(internal_output_capture, print_internals, update_panic_count, thread_local_const_init)
222-
)]
219+
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))]
223220
#![cfg_attr(
224221
all(target_vendor = "fortanix", target_env = "sgx"),
225222
feature(slice_index_methods, coerce_unsized, sgx_platform)

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

+1-4
Original file line numberDiff line numberDiff line change
@@ -473,10 +473,7 @@ impl Iterator for Env {
473473

474474
#[cfg(target_os = "macos")]
475475
pub unsafe fn environ() -> *mut *const *const c_char {
476-
extern "C" {
477-
fn _NSGetEnviron() -> *mut *const *const c_char;
478-
}
479-
_NSGetEnviron()
476+
libc::_NSGetEnviron() as *mut *const *const c_char
480477
}
481478

482479
#[cfg(not(target_os = "macos"))]

library/std/src/thread/local.rs

-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,6 @@ macro_rules! __thread_local_inner {
178178
(@key $t:ty, const $init:expr) => {{
179179
#[cfg_attr(not(windows), inline)] // see comments below
180180
unsafe fn __getit() -> $crate::option::Option<&'static $t> {
181-
const _REQUIRE_UNSTABLE: () = $crate::thread::require_unstable_const_init_thread_local();
182181
const INIT_EXPR: $t = $init;
183182

184183
// wasm without atomics maps directly to `static mut`, and dtors

library/std/src/thread/mod.rs

-7
Original file line numberDiff line numberDiff line change
@@ -204,13 +204,6 @@ pub use self::local::os::Key as __OsLocalKeyInner;
204204
#[doc(hidden)]
205205
pub use self::local::statik::Key as __StaticLocalKeyInner;
206206

207-
// This is only used to make thread locals with `const { .. }` initialization
208-
// expressions unstable. If and/or when that syntax is stabilized with thread
209-
// locals this will simply be removed.
210-
#[doc(hidden)]
211-
#[unstable(feature = "thread_local_const_init", issue = "84223")]
212-
pub const fn require_unstable_const_init_thread_local() {}
213-
214207
////////////////////////////////////////////////////////////////////////////////
215208
// Builder
216209
////////////////////////////////////////////////////////////////////////////////

src/test/codegen/auxiliary/thread_local_aux.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![crate_type = "lib"]
2-
#![feature(thread_local_const_init)]
32

43
use std::cell::Cell;
54

src/test/codegen/thread-local.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
// ignore-android does not use #[thread_local]
77

88
#![crate_type = "lib"]
9-
#![feature(thread_local_const_init)]
109

1110
extern crate thread_local_aux as aux;
1211

src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// run-pass
21
#![feature(generic_const_exprs)]
32
#![allow(incomplete_features)]
43

@@ -22,8 +21,11 @@ where
2221
}
2322

2423
fn main() {
25-
// Test that we can correctly infer `T` which requires evaluating
26-
// `{ N + 1 }` which has substs containing an inference var
24+
// FIXME(generic_const_exprs): We can't correctly infer `T` which requires
25+
// evaluating `{ N + 1 }` which has substs containing an inference var
2726
let mut _q = Default::default();
27+
//~^ ERROR type annotations needed
28+
2829
_q = foo::<_, 2>(_q);
30+
//~^ ERROR type annotations needed
2931
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/const_eval_resolve_canonical.rs:26:9
3+
|
4+
LL | let mut _q = Default::default();
5+
| ^^^^^^ consider giving `_q` a type
6+
7+
error[E0283]: type annotations needed
8+
--> $DIR/const_eval_resolve_canonical.rs:29:10
9+
|
10+
LL | _q = foo::<_, 2>(_q);
11+
| ^^^^^^^^^^^ cannot infer type
12+
|
13+
note: multiple `impl`s satisfying `(): Foo<{ N + 1 }>` found
14+
--> $DIR/const_eval_resolve_canonical.rs:8:1
15+
|
16+
LL | impl Foo<0> for () {
17+
| ^^^^^^^^^^^^^^^^^^
18+
...
19+
LL | impl Foo<3> for () {
20+
| ^^^^^^^^^^^^^^^^^^
21+
note: required by a bound in `foo`
22+
--> $DIR/const_eval_resolve_canonical.rs:18:9
23+
|
24+
LL | fn foo<T, const N: usize>(_: T) -> <() as Foo<{ N + 1 }>>::Assoc
25+
| --- required by a bound in this
26+
LL | where
27+
LL | (): Foo<{ N + 1 }>,
28+
| ^^^^^^^^^^^^^^ required by this bound in `foo`
29+
30+
error: aborting due to 2 previous errors
31+
32+
Some errors have detailed explanations: E0282, E0283.
33+
For more information about an error, try `rustc --explain E0282`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![allow(incomplete_features)]
2+
#![feature(generic_const_exprs)]
3+
4+
trait Foo {
5+
const N: usize;
6+
}
7+
8+
impl Foo for u8 {
9+
const N: usize = 1;
10+
}
11+
12+
fn foo<T: Foo>(_: [u8; T::N]) -> T {
13+
todo!()
14+
}
15+
16+
pub fn bar() {
17+
let _: u8 = foo([0; 1]);
18+
19+
let _ = foo([0; 1]);
20+
//~^ ERROR type annotations needed
21+
}
22+
23+
fn main() {}

0 commit comments

Comments
 (0)