Skip to content

Commit f32ced6

Browse files
committed
Auto merge of rust-lang#115009 - matthiaskrgr:rollup-ainf2gb, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#114605 (Increase clarity about Hash - Eq consistency in HashMap and HashSet docs) - rust-lang#114934 (instantiate response: no unnecessary new universe) - rust-lang#114950 (Inline strlen_rt in CStr::from_ptr) - rust-lang#114973 (Expose core::error::request_value in std) - rust-lang#114983 (Usage zero as language id for `FormatMessageW()`) - rust-lang#114991 (remove redundant var rebindings) - rust-lang#114992 (const-eval: ensure we never const-execute a function marked rustc_do_not_const_check) - rust-lang#115001 (clippy::perf stuff) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 6ef7d16 + d49b1ab commit f32ced6

File tree

16 files changed

+213
-69
lines changed

16 files changed

+213
-69
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+21-32
Original file line numberDiff line numberDiff line change
@@ -427,52 +427,41 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
427427

428428
fn find_mir_or_eval_fn(
429429
ecx: &mut InterpCx<'mir, 'tcx, Self>,
430-
instance: ty::Instance<'tcx>,
430+
orig_instance: ty::Instance<'tcx>,
431431
_abi: CallAbi,
432432
args: &[FnArg<'tcx>],
433433
dest: &PlaceTy<'tcx>,
434434
ret: Option<mir::BasicBlock>,
435435
_unwind: mir::UnwindAction, // unwinding is not supported in consts
436436
) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> {
437-
debug!("find_mir_or_eval_fn: {:?}", instance);
437+
debug!("find_mir_or_eval_fn: {:?}", orig_instance);
438+
439+
// Replace some functions.
440+
let Some(instance) = ecx.hook_special_const_fn(orig_instance, args, dest, ret)? else {
441+
// Call has already been handled.
442+
return Ok(None);
443+
};
438444

439445
// Only check non-glue functions
440446
if let ty::InstanceDef::Item(def) = instance.def {
441447
// Execution might have wandered off into other crates, so we cannot do a stability-
442-
// sensitive check here. But we can at least rule out functions that are not const
443-
// at all.
444-
if !ecx.tcx.is_const_fn_raw(def) {
445-
// allow calling functions inside a trait marked with #[const_trait].
446-
if !ecx.tcx.is_const_default_method(def) {
447-
// We certainly do *not* want to actually call the fn
448-
// though, so be sure we return here.
449-
throw_unsup_format!("calling non-const function `{}`", instance)
450-
}
451-
}
452-
453-
let Some(new_instance) = ecx.hook_special_const_fn(instance, args, dest, ret)? else {
454-
return Ok(None);
455-
};
456-
457-
if new_instance != instance {
458-
// We call another const fn instead.
459-
// However, we return the *original* instance to make backtraces work out
460-
// (and we hope this does not confuse the FnAbi checks too much).
461-
return Ok(Self::find_mir_or_eval_fn(
462-
ecx,
463-
new_instance,
464-
_abi,
465-
args,
466-
dest,
467-
ret,
468-
_unwind,
469-
)?
470-
.map(|(body, _instance)| (body, instance)));
448+
// sensitive check here. But we can at least rule out functions that are not const at
449+
// all. That said, we have to allow calling functions inside a trait marked with
450+
// #[const_trait]. These *are* const-checked!
451+
// FIXME: why does `is_const_fn_raw` not classify them as const?
452+
if (!ecx.tcx.is_const_fn_raw(def) && !ecx.tcx.is_const_default_method(def))
453+
|| ecx.tcx.has_attr(def, sym::rustc_do_not_const_check)
454+
{
455+
// We certainly do *not* want to actually call the fn
456+
// though, so be sure we return here.
457+
throw_unsup_format!("calling non-const function `{}`", instance)
471458
}
472459
}
473460

474461
// This is a const fn. Call it.
475-
Ok(Some((ecx.load_mir(instance.def, None)?, instance)))
462+
// In case of replacement, we return the *original* instance to make backtraces work out
463+
// (and we hope this does not confuse the FnAbi checks too much).
464+
Ok(Some((ecx.load_mir(instance.def, None)?, orig_instance)))
476465
}
477466

478467
fn call_intrinsic(

compiler/rustc_hir_typeck/src/method/prelude2021.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_span::symbol::kw::{Empty, Underscore};
1414
use rustc_span::symbol::{sym, Ident};
1515
use rustc_span::Span;
1616
use rustc_trait_selection::infer::InferCtxtExt;
17+
use std::fmt::Write;
1718

1819
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1920
pub(super) fn lint_dot_call_from_2018(
@@ -143,16 +144,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
143144

144145
let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp);
145146
if precise {
146-
let args = args
147-
.iter()
148-
.map(|arg| {
149-
let span = arg.span.find_ancestor_inside(sp).unwrap_or_default();
150-
format!(
151-
", {}",
152-
self.sess().source_map().span_to_snippet(span).unwrap()
153-
)
154-
})
155-
.collect::<String>();
147+
let args = args.iter().fold(String::new(), |mut string, arg| {
148+
let span = arg.span.find_ancestor_inside(sp).unwrap_or_default();
149+
write!(
150+
string,
151+
", {}",
152+
self.sess().source_map().span_to_snippet(span).unwrap()
153+
)
154+
.unwrap();
155+
string
156+
});
156157

157158
lint.span_suggestion(
158159
sp,

compiler/rustc_middle/src/hir/mod.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,15 @@ pub fn provide(providers: &mut Providers) {
164164
tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
165165
};
166166
providers.def_span = |tcx, def_id| {
167-
let def_id = def_id;
168167
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
169168
tcx.hir().opt_span(hir_id).unwrap_or(DUMMY_SP)
170169
};
171170
providers.def_ident_span = |tcx, def_id| {
172-
let def_id = def_id;
173171
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
174172
tcx.hir().opt_ident_span(hir_id)
175173
};
176-
providers.fn_arg_names = |tcx, id| {
174+
providers.fn_arg_names = |tcx, def_id| {
177175
let hir = tcx.hir();
178-
let def_id = id;
179176
let hir_id = hir.local_def_id_to_hir_id(def_id);
180177
if let Some(body_id) = hir.maybe_body_owned_by(def_id) {
181178
tcx.arena.alloc_from_iter(hir.body_param_names(body_id))
@@ -190,7 +187,7 @@ pub fn provide(providers: &mut Providers) {
190187
{
191188
idents
192189
} else {
193-
span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", id);
190+
span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", def_id);
194191
}
195192
};
196193
providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id);

compiler/rustc_middle/src/ty/diagnostics.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Diagnostics related methods for `Ty`.
22
33
use std::borrow::Cow;
4+
use std::fmt::Write;
45
use std::ops::ControlFlow;
56

67
use crate::ty::{
@@ -335,10 +336,10 @@ pub fn suggest_constraining_type_params<'a>(
335336
// - insert: `, X: Bar`
336337
suggestions.push((
337338
generics.tail_span_for_predicate_suggestion(),
338-
constraints
339-
.iter()
340-
.map(|&(constraint, _)| format!(", {param_name}: {constraint}"))
341-
.collect::<String>(),
339+
constraints.iter().fold(String::new(), |mut string, &(constraint, _)| {
340+
write!(string, ", {param_name}: {constraint}").unwrap();
341+
string
342+
}),
342343
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty: param_name },
343344
));
344345
continue;

compiler/rustc_mir_transform/src/coverage/debug.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ impl DebugOptions {
199199

200200
fn bool_option_val(option: &str, some_strval: Option<&str>) -> bool {
201201
if let Some(val) = some_strval {
202-
if vec!["yes", "y", "on", "true"].contains(&val) {
202+
if ["yes", "y", "on", "true"].contains(&val) {
203203
true
204-
} else if vec!["no", "n", "off", "false"].contains(&val) {
204+
} else if ["no", "n", "off", "false"].contains(&val) {
205205
false
206206
} else {
207207
bug!(

compiler/rustc_passes/src/layout_test.rs

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
2727
}
2828

2929
fn dump_layout_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
30-
let tcx = tcx;
3130
let param_env = tcx.param_env(item_def_id);
3231
let ty = tcx.type_of(item_def_id).instantiate_identity();
3332
match tcx.layout_of(param_env.and(ty)) {

compiler/rustc_passes/src/liveness.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1105,7 +1105,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11051105
}
11061106

11071107
// Then do a second pass for inputs
1108-
let mut succ = succ;
11091108
for (op, _op_sp) in asm.operands.iter().rev() {
11101109
match op {
11111110
hir::InlineAsmOperand::In { expr, .. } => {

compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
215215
// created inside of the query directly instead of returning them to the
216216
// caller.
217217
let prev_universe = self.infcx.universe();
218-
let universes_created_in_query = response.max_universe.index() + 1;
218+
let universes_created_in_query = response.max_universe.index();
219219
for _ in 0..universes_created_in_query {
220220
self.infcx.create_next_universe();
221221
}

library/core/src/ffi/c_str.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl CStr {
253253
/// ```
254254
///
255255
/// [valid]: core::ptr#safety
256-
#[inline]
256+
#[inline] // inline is necessary for codegen to see strlen.
257257
#[must_use]
258258
#[stable(feature = "rust1", since = "1.0.0")]
259259
#[rustc_const_unstable(feature = "const_cstr_from_ptr", issue = "113219")]
@@ -280,6 +280,8 @@ impl CStr {
280280
len
281281
}
282282

283+
// `inline` is necessary for codegen to see strlen.
284+
#[inline]
283285
fn strlen_rt(s: *const c_char) -> usize {
284286
extern "C" {
285287
/// Provided by libc or compiler_builtins.

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ use crate::sys;
4949
/// ```
5050
///
5151
/// In other words, if two keys are equal, their hashes must be equal.
52+
/// Violating this property is a logic error.
5253
///
53-
/// It is a logic error for a key to be modified in such a way that the key's
54+
/// It is also a logic error for a key to be modified in such a way that the key's
5455
/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
5556
/// the [`Eq`] trait, changes while it is in the map. This is normally only
5657
/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
57-
/// The behavior resulting from such a logic error is not specified, but will
58+
///
59+
/// The behavior resulting from either logic error is not specified, but will
5860
/// be encapsulated to the `HashMap` that observed the logic error and not
5961
/// result in undefined behavior. This could include panics, incorrect results,
6062
/// aborts, memory leaks, and non-termination.

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ use super::map::{map_try_reserve_error, RandomState};
2424
/// ```
2525
///
2626
/// In other words, if two keys are equal, their hashes must be equal.
27+
/// Violating this property is a logic error.
2728
///
28-
///
29-
/// It is a logic error for a key to be modified in such a way that the key's
29+
/// It is also a logic error for a key to be modified in such a way that the key's
3030
/// hash, as determined by the [`Hash`] trait, or its equality, as determined by
3131
/// the [`Eq`] trait, changes while it is in the map. This is normally only
3232
/// possible through [`Cell`], [`RefCell`], global state, I/O, or unsafe code.
33-
/// The behavior resulting from such a logic error is not specified, but will
33+
///
34+
/// The behavior resulting from either logic error is not specified, but will
3435
/// be encapsulated to the `HashSet` that observed the logic error and not
3536
/// result in undefined behavior. This could include panics, incorrect results,
3637
/// aborts, memory leaks, and non-termination.

library/std/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::fmt::{self, Write};
1010
#[stable(feature = "rust1", since = "1.0.0")]
1111
pub use core::error::Error;
1212
#[unstable(feature = "error_generic_member_access", issue = "99301")]
13-
pub use core::error::{request_ref, Request};
13+
pub use core::error::{request_ref, request_value, Request};
1414

1515
mod private {
1616
// This is a hack to prevent `type_id` from being overridden by `Error`

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

+2-6
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ pub fn errno() -> i32 {
2525

2626
/// Gets a detailed string description for the given error number.
2727
pub fn error_string(mut errnum: i32) -> String {
28-
// This value is calculated from the macro
29-
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
30-
let langId = 0x0800 as c::DWORD;
31-
3228
let mut buf = [0 as c::WCHAR; 2048];
3329

3430
unsafe {
@@ -56,13 +52,13 @@ pub fn error_string(mut errnum: i32) -> String {
5652
flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS,
5753
module,
5854
errnum as c::DWORD,
59-
langId,
55+
0,
6056
buf.as_mut_ptr(),
6157
buf.len() as c::DWORD,
6258
ptr::null(),
6359
) as usize;
6460
if res == 0 {
65-
// Sometimes FormatMessageW can fail e.g., system doesn't like langId,
61+
// Sometimes FormatMessageW can fail e.g., system doesn't like 0 as langId,
6662
let fm_err = errno();
6763
return format!("OS Error {errnum} (FormatMessageW() returned error {fm_err})");
6864
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
// A minimization of an ambiguity when using typenum. See
5+
// https://github.com/rust-lang/trait-system-refactor-initiative/issues/55
6+
// for more details.
7+
trait Id {
8+
type Assoc: ?Sized;
9+
}
10+
impl<T: ?Sized> Id for T {
11+
type Assoc = T;
12+
}
13+
14+
trait WithAssoc<T: ?Sized> {
15+
type Assoc: ?Sized;
16+
}
17+
18+
19+
struct Leaf;
20+
struct Wrapper<U: ?Sized>(U);
21+
22+
impl<U: ?Sized> WithAssoc<U> for Leaf {
23+
type Assoc = U;
24+
}
25+
26+
impl<Ul: ?Sized, Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Wrapper<Ul>
27+
where
28+
Ul: WithAssoc<Ur>,
29+
{
30+
type Assoc = <<Ul as WithAssoc<Ur>>::Assoc as Id>::Assoc;
31+
}
32+
33+
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
34+
where
35+
T: WithAssoc<U, Assoc = V>,
36+
{
37+
}
38+
39+
// normalize self type to `Wrapper<Leaf>`
40+
// This succeeds, HOWEVER, instantiating the query response previously
41+
// incremented the universe index counter.
42+
// equate impl headers:
43+
// <Wrapper<Leaf> as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>
44+
// <Wrapper<?2t> as WithAssoc<Wrapper<?3t>>>
45+
// ~> AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
46+
// add where bounds:
47+
// ~> Leaf: WithAssoc<?3t>
48+
// equate with assoc type:
49+
// ?0t
50+
// <Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc
51+
// ~> AliasRelate(
52+
// <<Leaf as WithAssoc<?3t>>::Assoc as Id>::Assoc,
53+
// Equate,
54+
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
55+
// )
56+
//
57+
// We do not reuse `?3t` during generalization because `?0t` cannot name `?4t` as we created
58+
// it after incrementing the universe index while normalizing the self type.
59+
//
60+
// evaluate_added_goals_and_make_query_response:
61+
// AliasRelate(<Wrapper<Leaf> as Id>::Assoc, Equate, Wrapper<?3t>)
62+
// YES, constrains ?3t to Leaf
63+
// AliasRelate(
64+
// <<Leaf as WithAssoc<Leaf>>::Assoc as Id>::Assoc,
65+
// Equate,
66+
// <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc,
67+
// )
68+
//
69+
// Normalizing <<Leaf as WithAssoc<?4t>>::Assoc as Id>::Assoc then *correctly*
70+
// results in ambiguity.
71+
fn main() {
72+
bound::<<Wrapper<Leaf> as Id>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
73+
}

0 commit comments

Comments
 (0)