Skip to content

Commit 0345ecb

Browse files
committed
Auto merge of #157918 - lcnr:as-field, r=<try>
[perf] Rigid alias out of `AliasTy`/`Unevaluated`
2 parents 5ff740e + f27c8ad commit 0345ecb

250 files changed

Lines changed: 2138 additions & 1160 deletions

File tree

Some content is hidden

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

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
711711
));
712712
let can_subst = |ty: Ty<'tcx>| {
713713
// Normalize before comparing to see through type aliases and projections.
714-
let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
715-
let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args);
714+
let old_ty = ty::EarlyBinder::bind(tcx, ty).instantiate(tcx, generic_args);
715+
let new_ty = ty::EarlyBinder::bind(tcx, ty).instantiate(tcx, new_args);
716716
if let Ok(old_ty) = tcx.try_normalize_erasing_regions(
717717
self.infcx.typing_env(self.infcx.param_env),
718718
old_ty,

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
7676
"non-defining use of `{}` in the defining scope",
7777
Ty::new_opaque(
7878
infcx.tcx,
79+
ty::IsRigid::No,
7980
opaque_type_key.def_id.to_def_id(),
8081
opaque_type_key.args
8182
)
@@ -220,7 +221,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
220221
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
221222
// If we find an opaque in a local ty, then for each of its captured regions,
222223
// try to find a path between that captured regions and our borrow region...
223-
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) = *ty.kind()
224+
if let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) = *ty.kind()
224225
&& let hir::OpaqueTyOrigin::FnReturn { parent, in_trait_or_impl: None } =
225226
self.tcx.opaque_ty_origin(def_id)
226227
{
@@ -277,7 +278,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CheckExplicitRegionMentionAndCollectGen
277278

278279
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
279280
match *ty.kind() {
280-
ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
281+
ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) => {
281282
if self.seen_opaques.insert(def_id) {
282283
for (bound, _) in self
283284
.tcx

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
603603
let ErrorConstraintInfo { outlived_fr, span, .. } = errci;
604604

605605
let mut output_ty = self.regioncx.universal_regions().unnormalized_output_ty;
606-
if let ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
606+
if let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }) = *output_ty.kind() {
607607
output_ty = self.infcx.tcx.type_of(def_id).instantiate_identity().skip_norm_wip()
608608
};
609609

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,7 +1928,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
19281928
| ty::Never
19291929
| ty::Tuple(_)
19301930
| ty::UnsafeBinder(_)
1931-
| ty::Alias(_)
1931+
| ty::Alias(_, _)
19321932
| ty::Param(_)
19331933
| ty::Bound(_, _)
19341934
| ty::Infer(_)
@@ -1970,7 +1970,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
19701970
| ty::CoroutineWitness(..)
19711971
| ty::Never
19721972
| ty::UnsafeBinder(_)
1973-
| ty::Alias(_)
1973+
| ty::Alias(_, _)
19741974
| ty::Param(_)
19751975
| ty::Bound(_, _)
19761976
| ty::Infer(_)

compiler/rustc_borrowck/src/region_infer/opaque_types/member_constraints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for CollectMemberConstraintsVisitor<'_, '_,
176176
| ty::CoroutineClosure(def_id, args)
177177
| ty::Coroutine(def_id, args) => self.visit_closure_args(def_id, args),
178178

179-
ty::Alias(ty::AliasTy { kind, args, .. })
179+
ty::Alias(_, ty::AliasTy { kind, args, .. })
180180
if let Some(variances) = self.cx().opt_alias_variances(kind) =>
181181
{
182182
// Skip lifetime parameters that are not captured, since they do

compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ fn compute_definition_site_hidden_types_from_defining_uses<'tcx>(
367367
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
368368
// writeback.
369369
if !rcx.infcx.tcx.use_typing_mode_post_typeck_until_borrowck() {
370-
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
370+
if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
371371
hidden_type.ty.skip_binder().kind()
372372
&& def_id == opaque_type_key.def_id.to_def_id()
373373
&& args == opaque_type_key.args
@@ -500,7 +500,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
500500
Ty::new_coroutine(tcx, def_id, self.fold_closure_args(def_id, args)?)
501501
}
502502

503-
ty::Alias(ty::AliasTy { kind, args, .. })
503+
ty::Alias(_, ty::AliasTy { kind, args, .. })
504504
if let Some(variances) = tcx.opt_alias_variances(kind) =>
505505
{
506506
let args = tcx.mk_args_from_iter(std::iter::zip(variances, args.iter()).map(
@@ -512,7 +512,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for ToArgRegionsFolder<'_, 'tcx> {
512512
}
513513
},
514514
))?;
515-
ty::AliasTy::new_from_args(tcx, kind, args).to_ty(tcx)
515+
ty::AliasTy::new_from_args(tcx, kind, args).to_ty(tcx, ty::IsRigid::No)
516516
}
517517

518518
_ => ty.try_super_fold_with(self)?,
@@ -541,7 +541,7 @@ pub(crate) fn apply_definition_site_hidden_types<'tcx>(
541541
for &(key, hidden_type) in opaque_types {
542542
let Some(expected) = hidden_types.get(&key.def_id) else {
543543
if !tcx.use_typing_mode_post_typeck_until_borrowck() {
544-
if let &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
544+
if let &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, args, .. }) =
545545
hidden_type.ty.kind()
546546
&& def_id == key.def_id.to_def_id()
547547
&& args == key.args

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
469469
// Necessary for non-trivial patterns whose user-type annotation is an opaque type,
470470
// e.g. `let (_a,): Tait = whatever`, see #105897
471471
if !self.infcx.next_trait_solver()
472-
&& let ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
472+
&& let ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }) =
473473
curr_projected_ty.ty.kind()
474474
{
475475
// There is nothing that we can compare here if we go through an opaque type.
@@ -1760,7 +1760,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
17601760
let tcx = self.tcx();
17611761
let maybe_uneval = match constant.const_ {
17621762
Const::Ty(_, ct) => match ct.kind() {
1763-
ty::ConstKind::Unevaluated(uv) => match uv.kind {
1763+
ty::ConstKind::Unevaluated(_, uv) => match uv.kind {
17641764
ty::UnevaluatedConstKind::Projection { def_id }
17651765
| ty::UnevaluatedConstKind::Inherent { def_id }
17661766
| ty::UnevaluatedConstKind::Free { def_id }

compiler/rustc_borrowck/src/type_check/relate_tys.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,10 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
150150
};
151151

152152
let (a, b) = match (a.kind(), b.kind()) {
153-
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. }), _) => {
153+
(&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. }), _) => {
154154
(a, enable_subtyping(b, true)?)
155155
}
156-
(_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { .. }, .. })) => {
156+
(_, &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { .. }, .. })) => {
157157
(enable_subtyping(a, false)?, b)
158158
}
159159
_ => unreachable!(
@@ -386,8 +386,8 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
386386
}
387387

388388
(
389-
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
390-
&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
389+
&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: a_def_id }, .. }),
390+
&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id: b_def_id }, .. }),
391391
) if a_def_id == b_def_id || infcx.next_trait_solver() => {
392392
super_combine_tys(&infcx.infcx, self, a, b).map(|_| ()).or_else(|err| {
393393
// This behavior is only there for the old solver, the new solver
@@ -401,8 +401,8 @@ impl<'b, 'tcx> TypeRelation<TyCtxt<'tcx>> for NllTypeRelating<'_, 'b, 'tcx> {
401401
if a_def_id.is_local() { self.relate_opaques(a, b) } else { Err(err) }
402402
})?;
403403
}
404-
(&ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
405-
| (_, &ty::Alias(ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
404+
(&ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }), _)
405+
| (_, &ty::Alias(_, ty::AliasTy { kind: ty::Opaque { def_id }, .. }))
406406
if def_id.is_local() && !self.type_checker.infcx.next_trait_solver() =>
407407
{
408408
self.relate_opaques(a, b)?;

compiler/rustc_codegen_cranelift/src/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
349349
self.instance.instantiate_mir_and_normalize_erasing_regions(
350350
self.tcx,
351351
ty::TypingEnv::fully_monomorphized(),
352-
ty::EarlyBinder::bind(value),
352+
ty::EarlyBinder::bind(self.tcx, value),
353353
)
354354
}
355355

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
use std::collections::hash_map::Entry;
2+
3+
use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext};
4+
use rustc_codegen_ssa::traits::*;
5+
use rustc_data_structures::fx::FxHashMap;
6+
use rustc_index::bit_set::DenseBitSet;
7+
use rustc_middle::mir::{Body, SourceScope};
8+
use rustc_middle::ty::layout::{FnAbiOf, HasTypingEnv};
9+
use rustc_middle::ty::{self, Instance};
10+
use rustc_session::config::DebugInfo;
11+
use rustc_span::{BytePos, DUMMY_SP, hygiene};
12+
13+
use super::metadata::file_metadata;
14+
use super::utils::DIB;
15+
use crate::common::CodegenCx;
16+
use crate::llvm;
17+
use crate::llvm::debuginfo::{DILocation, DIScope};
18+
19+
/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
20+
// FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
21+
pub(crate) fn compute_mir_scopes<'ll, 'tcx>(
22+
cx: &CodegenCx<'ll, 'tcx>,
23+
instance: Instance<'tcx>,
24+
mir: &Body<'tcx>,
25+
debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
26+
) {
27+
// Find all scopes with variables defined in them.
28+
let variables = if cx.sess().opts.debuginfo == DebugInfo::Full {
29+
let mut vars = DenseBitSet::new_empty(mir.source_scopes.len());
30+
// FIXME(eddyb) take into account that arguments always have debuginfo,
31+
// irrespective of their name (assuming full debuginfo is enabled).
32+
// NOTE(eddyb) actually, on second thought, those are always in the
33+
// function scope, which always exists.
34+
for var_debug_info in &mir.var_debug_info {
35+
vars.insert(var_debug_info.source_info.scope);
36+
}
37+
Some(vars)
38+
} else {
39+
// Nothing to emit, of course.
40+
None
41+
};
42+
let mut instantiated = DenseBitSet::new_empty(mir.source_scopes.len());
43+
let mut discriminators = FxHashMap::default();
44+
// Instantiate all scopes.
45+
for scope in mir.source_scopes.indices() {
46+
make_mir_scope(
47+
cx,
48+
instance,
49+
mir,
50+
&variables,
51+
debug_context,
52+
&mut instantiated,
53+
&mut discriminators,
54+
scope,
55+
);
56+
}
57+
assert!(instantiated.count() == mir.source_scopes.len());
58+
}
59+
60+
fn make_mir_scope<'ll, 'tcx>(
61+
cx: &CodegenCx<'ll, 'tcx>,
62+
instance: Instance<'tcx>,
63+
mir: &Body<'tcx>,
64+
variables: &Option<DenseBitSet<SourceScope>>,
65+
debug_context: &mut FunctionDebugContext<'tcx, &'ll DIScope, &'ll DILocation>,
66+
instantiated: &mut DenseBitSet<SourceScope>,
67+
discriminators: &mut FxHashMap<BytePos, u32>,
68+
scope: SourceScope,
69+
) {
70+
if instantiated.contains(scope) {
71+
return;
72+
}
73+
74+
let scope_data = &mir.source_scopes[scope];
75+
let parent_scope = if let Some(parent) = scope_data.parent_scope {
76+
make_mir_scope(
77+
cx,
78+
instance,
79+
mir,
80+
variables,
81+
debug_context,
82+
instantiated,
83+
discriminators,
84+
parent,
85+
);
86+
debug_context.scopes[parent]
87+
} else {
88+
// The root is the function itself.
89+
let file = cx.sess().source_map().lookup_source_file(mir.span.lo());
90+
debug_context.scopes[scope] = DebugScope {
91+
file_start_pos: file.start_pos,
92+
file_end_pos: file.end_position(),
93+
..debug_context.scopes[scope]
94+
};
95+
instantiated.insert(scope);
96+
return;
97+
};
98+
99+
if let Some(vars) = variables
100+
&& !vars.contains(scope)
101+
&& scope_data.inlined.is_none()
102+
{
103+
// Do not create a DIScope if there are no variables defined in this
104+
// MIR `SourceScope`, and it's not `inlined`, to avoid debuginfo bloat.
105+
debug_context.scopes[scope] = parent_scope;
106+
instantiated.insert(scope);
107+
return;
108+
}
109+
110+
let loc = cx.lookup_debug_loc(scope_data.span.lo());
111+
let file_metadata = file_metadata(cx, &loc.file);
112+
113+
let dbg_scope = match scope_data.inlined {
114+
Some((callee, _)) => {
115+
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
116+
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
117+
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
118+
instance.args,
119+
cx.typing_env(),
120+
ty::EarlyBinder::bind(cx.tcx, callee),
121+
);
122+
debug_context.inlined_function_scopes.entry(callee).or_insert_with(|| {
123+
let callee_fn_abi = cx.fn_abi_of_instance(callee, ty::List::empty());
124+
cx.dbg_scope_fn(callee, callee_fn_abi, None)
125+
})
126+
}
127+
None => unsafe {
128+
llvm::LLVMDIBuilderCreateLexicalBlock(
129+
DIB(cx),
130+
parent_scope.dbg_scope,
131+
file_metadata,
132+
loc.line,
133+
loc.col,
134+
)
135+
},
136+
};
137+
138+
let inlined_at = scope_data.inlined.map(|(_, callsite_span)| {
139+
let callsite_span = hygiene::walk_chain_collapsed(callsite_span, mir.span);
140+
let callsite_scope = parent_scope.adjust_dbg_scope_for_span(cx, callsite_span);
141+
let loc = cx.dbg_loc(callsite_scope, parent_scope.inlined_at, callsite_span);
142+
143+
// NB: In order to produce proper debug info for variables (particularly
144+
// arguments) in multiply-inlined functions, LLVM expects to see a single
145+
// DILocalVariable with multiple different DILocations in the IR. While
146+
// the source information for each DILocation would be identical, their
147+
// inlinedAt attributes will be unique to the particular callsite.
148+
//
149+
// We generate DILocations here based on the callsite's location in the
150+
// source code. A single location in the source code usually can't
151+
// produce multiple distinct calls so this mostly works, until
152+
// macros get involved. A macro can generate multiple calls
153+
// at the same span, which breaks the assumption that we're going to
154+
// produce a unique DILocation for every scope we process here. We
155+
// have to explicitly add discriminators if we see inlines into the
156+
// same source code location.
157+
//
158+
// Note further that we can't key this hashtable on the span itself,
159+
// because these spans could have distinct SyntaxContexts. We have
160+
// to key on exactly what we're giving to LLVM.
161+
match discriminators.entry(callsite_span.lo()) {
162+
Entry::Occupied(mut o) => {
163+
*o.get_mut() += 1;
164+
// NB: We have to emit *something* here or we'll fail LLVM IR verification
165+
// in at least some circumstances (see issue #135322) so if the required
166+
// discriminant cannot be encoded fall back to the dummy location.
167+
unsafe { llvm::LLVMRustDILocationCloneWithBaseDiscriminator(loc, *o.get()) }
168+
.unwrap_or_else(|| {
169+
cx.dbg_loc(callsite_scope, parent_scope.inlined_at, DUMMY_SP)
170+
})
171+
}
172+
Entry::Vacant(v) => {
173+
v.insert(0);
174+
loc
175+
}
176+
}
177+
});
178+
179+
debug_context.scopes[scope] = DebugScope {
180+
dbg_scope,
181+
inlined_at: inlined_at.or(parent_scope.inlined_at),
182+
file_start_pos: loc.file.start_pos,
183+
file_end_pos: loc.file.end_position(),
184+
};
185+
instantiated.insert(scope);
186+
}

0 commit comments

Comments
 (0)