Skip to content

Commit a77659a

Browse files
committed
Auto merge of rust-lang#112420 - matthiaskrgr:rollup-spiavw5, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - rust-lang#109953 (Use 128 bits for TypeId hash) - rust-lang#112333 (Don't hold the active queries lock while calling `make_query`) - rust-lang#112339 (Fix rust-analyzer proc macro server) - rust-lang#112410 (Do `fix_*_builtin_expr` hacks on the writeback results) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e740925 + 909bfa3 commit a77659a

File tree

10 files changed

+117
-61
lines changed

10 files changed

+117
-61
lines changed

Diff for: compiler/rustc_const_eval/src/interpret/intrinsics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
7777
}
7878
sym::type_id => {
7979
ensure_monomorphic_enough(tcx, tp_ty)?;
80-
ConstValue::from_u64(tcx.type_id_hash(tp_ty).as_u64())
80+
ConstValue::from_u128(tcx.type_id_hash(tp_ty).as_u128())
8181
}
8282
sym::variant_count => match tp_ty.kind() {
8383
// Correctly handles non-monomorphic calls, so there is no need for ensure_monomorphic_enough.
@@ -169,7 +169,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
169169
let ty = match intrinsic_name {
170170
sym::pref_align_of | sym::variant_count => self.tcx.types.usize,
171171
sym::needs_drop => self.tcx.types.bool,
172-
sym::type_id => self.tcx.types.u64,
172+
sym::type_id => self.tcx.types.u128,
173173
sym::type_name => self.tcx.mk_static_str(),
174174
_ => bug!(),
175175
};

Diff for: compiler/rustc_hir_analysis/src/check/intrinsic.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
217217
sym::needs_drop => (1, Vec::new(), tcx.types.bool),
218218

219219
sym::type_name => (1, Vec::new(), tcx.mk_static_str()),
220-
sym::type_id => (1, Vec::new(), tcx.types.u64),
220+
sym::type_id => (1, Vec::new(), tcx.types.u128),
221221
sym::offset => (2, vec![param(0), param(1)], param(0)),
222222
sym::arith_offset => (
223223
1,

Diff for: compiler/rustc_hir_typeck/src/writeback.rs

+35-48
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use rustc_middle::mir::FakeReadCause;
1414
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast};
1515
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
1616
use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
17-
use rustc_middle::ty::TypeckResults;
1817
use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt};
1918
use rustc_span::symbol::sym;
2019
use rustc_span::Span;
@@ -148,31 +147,25 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
148147
fn fix_scalar_builtin_expr(&mut self, e: &hir::Expr<'_>) {
149148
match e.kind {
150149
hir::ExprKind::Unary(hir::UnOp::Neg | hir::UnOp::Not, inner) => {
151-
let inner_ty = self.fcx.node_ty(inner.hir_id);
152-
let inner_ty = self.fcx.resolve_vars_if_possible(inner_ty);
150+
let inner_ty = self.typeck_results.node_type(inner.hir_id);
153151

154152
if inner_ty.is_scalar() {
155-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
156-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
157-
typeck_results.node_substs_mut().remove(e.hir_id);
153+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
154+
self.typeck_results.node_substs_mut().remove(e.hir_id);
158155
}
159156
}
160157
hir::ExprKind::Binary(ref op, lhs, rhs) | hir::ExprKind::AssignOp(ref op, lhs, rhs) => {
161-
let lhs_ty = self.fcx.node_ty(lhs.hir_id);
162-
let lhs_ty = self.fcx.resolve_vars_if_possible(lhs_ty);
163-
164-
let rhs_ty = self.fcx.node_ty(rhs.hir_id);
165-
let rhs_ty = self.fcx.resolve_vars_if_possible(rhs_ty);
158+
let lhs_ty = self.typeck_results.node_type(lhs.hir_id);
159+
let rhs_ty = self.typeck_results.node_type(rhs.hir_id);
166160

167161
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
168-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
169-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
170-
typeck_results.node_substs_mut().remove(e.hir_id);
162+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
163+
self.typeck_results.node_substs_mut().remove(e.hir_id);
171164

172165
match e.kind {
173166
hir::ExprKind::Binary(..) => {
174167
if !op.node.is_by_value() {
175-
let mut adjustments = typeck_results.adjustments_mut();
168+
let mut adjustments = self.typeck_results.adjustments_mut();
176169
if let Some(a) = adjustments.get_mut(lhs.hir_id) {
177170
a.pop();
178171
}
@@ -182,7 +175,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
182175
}
183176
}
184177
hir::ExprKind::AssignOp(..)
185-
if let Some(a) = typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
178+
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(lhs.hir_id) =>
186179
{
187180
a.pop();
188181
}
@@ -200,16 +193,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
200193
// if they are not we don't modify the expr, hence we bypass the ICE
201194
fn is_builtin_index(
202195
&mut self,
203-
typeck_results: &TypeckResults<'tcx>,
204196
e: &hir::Expr<'_>,
205197
base_ty: Ty<'tcx>,
206198
index_ty: Ty<'tcx>,
207199
) -> bool {
208-
if let Some(elem_ty) = base_ty.builtin_index() {
209-
let Some(exp_ty) = typeck_results.expr_ty_opt(e) else {return false;};
210-
let resolved_exp_ty = self.resolve(exp_ty, &e.span);
211-
212-
elem_ty == resolved_exp_ty && index_ty == self.fcx.tcx.types.usize
200+
if let Some(elem_ty) = base_ty.builtin_index()
201+
&& let Some(exp_ty) = self.typeck_results.expr_ty_opt(e)
202+
{
203+
elem_ty == exp_ty && index_ty == self.fcx.tcx.types.usize
213204
} else {
214205
false
215206
}
@@ -221,38 +212,34 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
221212
// usize-ish
222213
fn fix_index_builtin_expr(&mut self, e: &hir::Expr<'_>) {
223214
if let hir::ExprKind::Index(ref base, ref index) = e.kind {
224-
let mut typeck_results = self.fcx.typeck_results.borrow_mut();
225-
226215
// All valid indexing looks like this; might encounter non-valid indexes at this point.
227-
let base_ty = typeck_results
228-
.expr_ty_adjusted_opt(base)
229-
.map(|t| self.fcx.resolve_vars_if_possible(t).kind());
216+
let base_ty = self.typeck_results.expr_ty_adjusted_opt(base);
230217
if base_ty.is_none() {
231218
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
232219
// that isn't in the type table. We assume more relevant errors have already been
233220
// emitted, so we delay an ICE if none have. (#64638)
234221
self.tcx().sess.delay_span_bug(e.span, format!("bad base: `{:?}`", base));
235222
}
236-
if let Some(ty::Ref(_, base_ty, _)) = base_ty {
237-
let index_ty = typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
238-
// When encountering `return [0][0]` outside of a `fn` body we would attempt
239-
// to access an nonexistent index. We assume that more relevant errors will
240-
// already have been emitted, so we only gate on this with an ICE if no
241-
// error has been emitted. (#64638)
242-
self.fcx.tcx.ty_error_with_message(
243-
e.span,
244-
format!("bad index {:?} for base: `{:?}`", index, base),
245-
)
246-
});
247-
let index_ty = self.fcx.resolve_vars_if_possible(index_ty);
248-
let resolved_base_ty = self.resolve(*base_ty, &base.span);
249-
250-
if self.is_builtin_index(&typeck_results, e, resolved_base_ty, index_ty) {
223+
if let Some(base_ty) = base_ty
224+
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
225+
{
226+
let index_ty =
227+
self.typeck_results.expr_ty_adjusted_opt(index).unwrap_or_else(|| {
228+
// When encountering `return [0][0]` outside of a `fn` body we would attempt
229+
// to access an nonexistent index. We assume that more relevant errors will
230+
// already have been emitted, so we only gate on this with an ICE if no
231+
// error has been emitted. (#64638)
232+
self.fcx.tcx.ty_error_with_message(
233+
e.span,
234+
format!("bad index {:?} for base: `{:?}`", index, base),
235+
)
236+
});
237+
if self.is_builtin_index(e, base_ty_inner, index_ty) {
251238
// Remove the method call record
252-
typeck_results.type_dependent_defs_mut().remove(e.hir_id);
253-
typeck_results.node_substs_mut().remove(e.hir_id);
239+
self.typeck_results.type_dependent_defs_mut().remove(e.hir_id);
240+
self.typeck_results.node_substs_mut().remove(e.hir_id);
254241

255-
if let Some(a) = typeck_results.adjustments_mut().get_mut(base.hir_id) {
242+
if let Some(a) = self.typeck_results.adjustments_mut().get_mut(base.hir_id) {
256243
// Discard the need for a mutable borrow
257244

258245
// Extra adjustment made when indexing causes a drop
@@ -283,9 +270,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
283270

284271
impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
285272
fn visit_expr(&mut self, e: &'tcx hir::Expr<'tcx>) {
286-
self.fix_scalar_builtin_expr(e);
287-
self.fix_index_builtin_expr(e);
288-
289273
match e.kind {
290274
hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
291275
let body = self.fcx.tcx.hir().body(body);
@@ -314,6 +298,9 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
314298

315299
self.visit_node_id(e.span, e.hir_id);
316300
intravisit::walk_expr(self, e);
301+
302+
self.fix_scalar_builtin_expr(e);
303+
self.fix_index_builtin_expr(e);
317304
}
318305

319306
fn visit_generic_param(&mut self, p: &'tcx hir::GenericParam<'tcx>) {

Diff for: compiler/rustc_middle/src/mir/interpret/value.rs

+9
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ impl<'tcx> ConstValue<'tcx> {
9797
ConstValue::Scalar(Scalar::from_u64(i))
9898
}
9999

100+
pub fn from_u128(i: u128) -> Self {
101+
ConstValue::Scalar(Scalar::from_u128(i))
102+
}
103+
100104
pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self {
101105
ConstValue::Scalar(Scalar::from_target_usize(i, cx))
102106
}
@@ -240,6 +244,11 @@ impl<Prov> Scalar<Prov> {
240244
Scalar::Int(i.into())
241245
}
242246

247+
#[inline]
248+
pub fn from_u128(i: u128) -> Self {
249+
Scalar::Int(i.into())
250+
}
251+
243252
#[inline]
244253
pub fn from_target_usize(i: u64, cx: &impl HasDataLayout) -> Self {
245254
Self::from_uint(i, cx.data_layout().pointer_size)

Diff for: compiler/rustc_middle/src/ty/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::ty::{
1111
use crate::ty::{GenericArgKind, SubstsRef};
1212
use rustc_apfloat::Float as _;
1313
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
14-
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
14+
use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
1515
use rustc_errors::ErrorGuaranteed;
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -129,7 +129,7 @@ impl IntTypeExt for IntegerType {
129129
impl<'tcx> TyCtxt<'tcx> {
130130
/// Creates a hash of the type `Ty` which will be the same no matter what crate
131131
/// context it's calculated within. This is used by the `type_id` intrinsic.
132-
pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash64 {
132+
pub fn type_id_hash(self, ty: Ty<'tcx>) -> Hash128 {
133133
// We want the type_id be independent of the types free regions, so we
134134
// erase them. The erase_regions() call will also anonymize bound
135135
// regions, which is desirable too.

Diff for: compiler/rustc_query_system/src/query/plumbing.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ where
6969
make_query: fn(Qcx, K) -> QueryStackFrame<D>,
7070
jobs: &mut QueryMap<D>,
7171
) -> Option<()> {
72+
let mut active = Vec::new();
73+
7274
#[cfg(parallel_compiler)]
7375
{
7476
// We use try_lock_shards here since we are called from the
@@ -77,8 +79,7 @@ where
7779
for shard in shards.iter() {
7880
for (k, v) in shard.iter() {
7981
if let QueryResult::Started(ref job) = *v {
80-
let query = make_query(qcx, *k);
81-
jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
82+
active.push((*k, job.clone()));
8283
}
8384
}
8485
}
@@ -91,12 +92,18 @@ where
9192
// really hurt much.)
9293
for (k, v) in self.active.try_lock()?.iter() {
9394
if let QueryResult::Started(ref job) = *v {
94-
let query = make_query(qcx, *k);
95-
jobs.insert(job.id, QueryJobInfo { query, job: job.clone() });
95+
active.push((*k, job.clone()));
9696
}
9797
}
9898
}
9999

100+
// Call `make_query` while we're not holding a `self.active` lock as `make_query` may call
101+
// queries leading to a deadlock.
102+
for (key, job) in active {
103+
let query = make_query(qcx, key);
104+
jobs.insert(job.id, QueryJobInfo { query, job });
105+
}
106+
100107
Some(())
101108
}
102109
}

Diff for: library/core/src/any.rs

+28-3
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
#![stable(feature = "rust1", since = "1.0.0")]
154154

155155
use crate::fmt;
156+
use crate::hash;
156157
use crate::intrinsics;
157158

158159
///////////////////////////////////////////////////////////////////////////////
@@ -662,10 +663,10 @@ impl dyn Any + Send + Sync {
662663
/// While `TypeId` implements `Hash`, `PartialOrd`, and `Ord`, it is worth
663664
/// noting that the hashes and ordering will vary between Rust releases. Beware
664665
/// of relying on them inside of your code!
665-
#[derive(Clone, Copy, Debug, Hash, Eq, PartialOrd, Ord)]
666+
#[derive(Clone, Copy, Debug, Eq, PartialOrd, Ord)]
666667
#[stable(feature = "rust1", since = "1.0.0")]
667668
pub struct TypeId {
668-
t: u64,
669+
t: u128,
669670
}
670671

671672
#[stable(feature = "rust1", since = "1.0.0")]
@@ -696,7 +697,31 @@ impl TypeId {
696697
#[stable(feature = "rust1", since = "1.0.0")]
697698
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
698699
pub const fn of<T: ?Sized + 'static>() -> TypeId {
699-
TypeId { t: intrinsics::type_id::<T>() }
700+
#[cfg(bootstrap)]
701+
let t = intrinsics::type_id::<T>() as u128;
702+
#[cfg(not(bootstrap))]
703+
let t: u128 = intrinsics::type_id::<T>();
704+
TypeId { t }
705+
}
706+
}
707+
708+
#[stable(feature = "rust1", since = "1.0.0")]
709+
impl hash::Hash for TypeId {
710+
#[inline]
711+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
712+
// We only hash the lower 64 bits of our (128 bit) internal numeric ID,
713+
// because:
714+
// - The hashing algorithm which backs `TypeId` is expected to be
715+
// unbiased and high quality, meaning further mixing would be somewhat
716+
// redundant compared to choosing (the lower) 64 bits arbitrarily.
717+
// - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
718+
// get from hashing the full value would probably not be useful
719+
// (especially given the previous point about the lower 64 bits being
720+
// high quality on their own).
721+
// - It is correct to do so -- only hashing a subset of `self` is still
722+
// with an `Eq` implementation that considers the entire value, as
723+
// ours does.
724+
(self.t as u64).hash(state);
700725
}
701726
}
702727

Diff for: library/core/src/intrinsics.rs

+17
Original file line numberDiff line numberDiff line change
@@ -1057,8 +1057,25 @@ extern "rust-intrinsic" {
10571057
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
10581058
#[rustc_safe_intrinsic]
10591059
#[rustc_nounwind]
1060+
#[cfg(bootstrap)]
10601061
pub fn type_id<T: ?Sized + 'static>() -> u64;
10611062

1063+
/// Gets an identifier which is globally unique to the specified type. This
1064+
/// function will return the same value for a type regardless of whichever
1065+
/// crate it is invoked in.
1066+
///
1067+
/// Note that, unlike most intrinsics, this is safe to call;
1068+
/// it does not require an `unsafe` block.
1069+
/// Therefore, implementations must not require the user to uphold
1070+
/// any safety invariants.
1071+
///
1072+
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
1073+
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
1074+
#[rustc_safe_intrinsic]
1075+
#[rustc_nounwind]
1076+
#[cfg(not(bootstrap))]
1077+
pub fn type_id<T: ?Sized + 'static>() -> u128;
1078+
10621079
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
10631080
/// This will statically either panic, or do nothing.
10641081
///

Diff for: src/bootstrap/tool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ impl Step for RustAnalyzerProcMacroSrv {
711711
tool: "rust-analyzer-proc-macro-srv",
712712
mode: Mode::ToolStd,
713713
path: "src/tools/rust-analyzer/crates/proc-macro-srv-cli",
714-
extra_features: vec!["proc-macro-srv/sysroot-abi".to_owned()],
714+
extra_features: vec!["sysroot-abi".to_owned()],
715715
is_optional_tool: false,
716716
source_type: SourceType::InTree,
717717
allow_features: RustAnalyzer::ALLOW_FEATURES,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
4+
const fn foo() {
5+
let mut x = [1, 2, 3];
6+
// We need to fix up `<<[i32; 3] as Index<usize>>::Output as AddAssign>`
7+
// to be treated like a built-in operation.
8+
x[1] += 5;
9+
}
10+
11+
fn main() {}

0 commit comments

Comments
 (0)