Skip to content

Commit f32ced6

Browse files
committedAug 19, 2023
Auto merge of #115009 - matthiaskrgr:rollup-ainf2gb, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #114605 (Increase clarity about Hash - Eq consistency in HashMap and HashSet docs) - #114934 (instantiate response: no unnecessary new universe) - #114950 (Inline strlen_rt in CStr::from_ptr) - #114973 (Expose core::error::request_value in std) - #114983 (Usage zero as language id for `FormatMessageW()`) - #114991 (remove redundant var rebindings) - #114992 (const-eval: ensure we never const-execute a function marked rustc_do_not_const_check) - #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

Lines changed: 21 additions & 32 deletions
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

Lines changed: 11 additions & 10 deletions
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

Lines changed: 2 additions & 5 deletions
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

Lines changed: 5 additions & 4 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 0 additions & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 4 additions & 2 deletions
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

Lines changed: 4 additions & 3 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 6 deletions
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
}
Lines changed: 73 additions & 0 deletions
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+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// known-bug: trait-system-refactor-initiative#60
3+
4+
// Generalizing a projection containing an inference variable
5+
// which cannot be named by the `root_vid` can result in ambiguity.
6+
//
7+
// Because we do not decrement the universe index when exiting a forall,
8+
// this can cause unexpected failures.
9+
//
10+
// See generalize-proj-new-universe-index-1.rs for more details.
11+
12+
// For this reproduction we need:
13+
// - an inference variable with a lower universe
14+
// - enter a binder to increment the current universe
15+
// - create a new inference variable which is constrained by proving a goal
16+
// - equate a projection containing the new variable with the first variable
17+
// - generalization creates yet another inference variable which is then
18+
// part of an alias-relate, resulting this to fail with ambiguity.
19+
//
20+
// Because we need to enter the binder in-between the creation of the first
21+
// and second inference variable, this is easiest via
22+
// `assemble_candidates_after_normalizing_self_ty` because eagerly call
23+
// `try_evaluate_added_goals` there before creating the inference variables
24+
// for the impl parameters.
25+
trait Id {
26+
type Assoc: ?Sized;
27+
}
28+
impl<T: ?Sized> Id for T {
29+
type Assoc = T;
30+
}
31+
32+
// By adding an higher ranked bound to the impl we currently
33+
// propagate this bound to the caller, forcing us to create a new
34+
// universe.
35+
trait IdHigherRankedBound {
36+
type Assoc: ?Sized;
37+
}
38+
39+
impl<T: ?Sized> IdHigherRankedBound for T
40+
where
41+
for<'a> T: 'a,
42+
{
43+
type Assoc = T;
44+
}
45+
46+
trait WithAssoc<T: ?Sized> {
47+
type Assoc: ?Sized;
48+
}
49+
50+
51+
struct Leaf;
52+
struct Wrapper<U: ?Sized>(U);
53+
struct Rigid;
54+
55+
impl<U: ?Sized> WithAssoc<U> for Leaf {
56+
type Assoc = U;
57+
}
58+
59+
60+
impl<Ur: ?Sized> WithAssoc<Wrapper<Ur>> for Rigid
61+
where
62+
Leaf: WithAssoc<Ur>,
63+
{
64+
type Assoc = <<Leaf as WithAssoc<Ur>>::Assoc as Id>::Assoc;
65+
}
66+
67+
fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
68+
where
69+
T: WithAssoc<U, Assoc = V>,
70+
{
71+
}
72+
73+
fn main() {
74+
bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
75+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/generalize-proj-new-universe-index-2.rs:74:5
3+
|
4+
LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)
Please sign in to comment.