Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 991a9dc

Browse files
committedFeb 5, 2024
Auto merge of rust-lang#120497 - compiler-errors:modulize, r=lcnr
Move predicate, region, and const stuff into their own modules in middle This PR mostly moves things around, and in a few cases adds some `ty::` to the beginning of names to avoid one-off imports. I don't mean this to be the most *thorough* move/refactor. I just generally wanted to begin to split up `ty/mod.rs` and `ty/sty.rs` which are huge and hard to distinguish, and have a lot of non-ty stuff in them. r? lcnr
2 parents 4d87c4a + 233b213 commit 991a9dc

File tree

5 files changed

+1491
-1456
lines changed

5 files changed

+1491
-1456
lines changed
 

‎compiler/rustc_middle/src/ty/consts.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir as hir;
77
use rustc_hir::def::{DefKind, Res};
88
use rustc_hir::def_id::LocalDefId;
99
use rustc_macros::HashStable;
10+
use rustc_type_ir::ConstKind as IrConstKind;
1011
use rustc_type_ir::{ConstTy, IntoKind, TypeFlags, WithCachedTypeInfo};
1112

1213
mod int;
@@ -19,7 +20,7 @@ use rustc_span::Span;
1920
use rustc_span::DUMMY_SP;
2021
pub use valtree::*;
2122

22-
use super::sty::ConstKind;
23+
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
2324

2425
/// Use this rather than `ConstData`, whenever possible.
2526
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 22 additions & 696 deletions
Large diffs are not rendered by default.

‎compiler/rustc_middle/src/ty/predicate.rs

Lines changed: 1062 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 399 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,399 @@
1+
use polonius_engine::Atom;
2+
use rustc_data_structures::intern::Interned;
3+
use rustc_errors::MultiSpan;
4+
use rustc_hir::def_id::DefId;
5+
use rustc_index::Idx;
6+
use rustc_span::symbol::sym;
7+
use rustc_span::symbol::{kw, Symbol};
8+
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
9+
use rustc_type_ir::RegionKind as IrRegionKind;
10+
use std::ops::Deref;
11+
12+
use crate::ty::{self, BoundVar, TyCtxt, TypeFlags};
13+
14+
pub type RegionKind<'tcx> = IrRegionKind<TyCtxt<'tcx>>;
15+
16+
/// Use this rather than `RegionKind`, whenever possible.
17+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable)]
18+
#[rustc_pass_by_value]
19+
pub struct Region<'tcx>(pub Interned<'tcx, RegionKind<'tcx>>);
20+
21+
impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
22+
type Kind = RegionKind<'tcx>;
23+
24+
fn kind(self) -> RegionKind<'tcx> {
25+
*self
26+
}
27+
}
28+
29+
impl<'tcx> Region<'tcx> {
30+
#[inline]
31+
pub fn new_early_param(
32+
tcx: TyCtxt<'tcx>,
33+
early_bound_region: ty::EarlyParamRegion,
34+
) -> Region<'tcx> {
35+
tcx.intern_region(ty::ReEarlyParam(early_bound_region))
36+
}
37+
38+
#[inline]
39+
pub fn new_bound(
40+
tcx: TyCtxt<'tcx>,
41+
debruijn: ty::DebruijnIndex,
42+
bound_region: ty::BoundRegion,
43+
) -> Region<'tcx> {
44+
// Use a pre-interned one when possible.
45+
if let ty::BoundRegion { var, kind: ty::BrAnon } = bound_region
46+
&& let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
47+
&& let Some(re) = inner.get(var.as_usize()).copied()
48+
{
49+
re
50+
} else {
51+
tcx.intern_region(ty::ReBound(debruijn, bound_region))
52+
}
53+
}
54+
55+
#[inline]
56+
pub fn new_late_param(
57+
tcx: TyCtxt<'tcx>,
58+
scope: DefId,
59+
bound_region: ty::BoundRegionKind,
60+
) -> Region<'tcx> {
61+
tcx.intern_region(ty::ReLateParam(ty::LateParamRegion { scope, bound_region }))
62+
}
63+
64+
#[inline]
65+
pub fn new_var(tcx: TyCtxt<'tcx>, v: ty::RegionVid) -> Region<'tcx> {
66+
// Use a pre-interned one when possible.
67+
tcx.lifetimes
68+
.re_vars
69+
.get(v.as_usize())
70+
.copied()
71+
.unwrap_or_else(|| tcx.intern_region(ty::ReVar(v)))
72+
}
73+
74+
#[inline]
75+
pub fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderRegion) -> Region<'tcx> {
76+
tcx.intern_region(ty::RePlaceholder(placeholder))
77+
}
78+
79+
/// Constructs a `RegionKind::ReError` region.
80+
#[track_caller]
81+
pub fn new_error(tcx: TyCtxt<'tcx>, reported: ErrorGuaranteed) -> Region<'tcx> {
82+
tcx.intern_region(ty::ReError(reported))
83+
}
84+
85+
/// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` to ensure it
86+
/// gets used.
87+
#[track_caller]
88+
pub fn new_error_misc(tcx: TyCtxt<'tcx>) -> Region<'tcx> {
89+
Region::new_error_with_message(
90+
tcx,
91+
DUMMY_SP,
92+
"RegionKind::ReError constructed but no error reported",
93+
)
94+
}
95+
96+
/// Constructs a `RegionKind::ReError` region and registers a `span_delayed_bug` with the given
97+
/// `msg` to ensure it gets used.
98+
#[track_caller]
99+
pub fn new_error_with_message<S: Into<MultiSpan>>(
100+
tcx: TyCtxt<'tcx>,
101+
span: S,
102+
msg: &'static str,
103+
) -> Region<'tcx> {
104+
let reported = tcx.dcx().span_delayed_bug(span, msg);
105+
Region::new_error(tcx, reported)
106+
}
107+
108+
/// Avoid this in favour of more specific `new_*` methods, where possible,
109+
/// to avoid the cost of the `match`.
110+
pub fn new_from_kind(tcx: TyCtxt<'tcx>, kind: RegionKind<'tcx>) -> Region<'tcx> {
111+
match kind {
112+
ty::ReEarlyParam(region) => Region::new_early_param(tcx, region),
113+
ty::ReBound(debruijn, region) => Region::new_bound(tcx, debruijn, region),
114+
ty::ReLateParam(ty::LateParamRegion { scope, bound_region }) => {
115+
Region::new_late_param(tcx, scope, bound_region)
116+
}
117+
ty::ReStatic => tcx.lifetimes.re_static,
118+
ty::ReVar(vid) => Region::new_var(tcx, vid),
119+
ty::RePlaceholder(region) => Region::new_placeholder(tcx, region),
120+
ty::ReErased => tcx.lifetimes.re_erased,
121+
ty::ReError(reported) => Region::new_error(tcx, reported),
122+
}
123+
}
124+
}
125+
126+
/// Region utilities
127+
impl<'tcx> Region<'tcx> {
128+
pub fn kind(self) -> RegionKind<'tcx> {
129+
*self.0.0
130+
}
131+
132+
pub fn get_name(self) -> Option<Symbol> {
133+
if self.has_name() {
134+
match *self {
135+
ty::ReEarlyParam(ebr) => Some(ebr.name),
136+
ty::ReBound(_, br) => br.kind.get_name(),
137+
ty::ReLateParam(fr) => fr.bound_region.get_name(),
138+
ty::ReStatic => Some(kw::StaticLifetime),
139+
ty::RePlaceholder(placeholder) => placeholder.bound.kind.get_name(),
140+
_ => None,
141+
}
142+
} else {
143+
None
144+
}
145+
}
146+
147+
pub fn get_name_or_anon(self) -> Symbol {
148+
match self.get_name() {
149+
Some(name) => name,
150+
None => sym::anon,
151+
}
152+
}
153+
154+
/// Is this region named by the user?
155+
pub fn has_name(self) -> bool {
156+
match *self {
157+
ty::ReEarlyParam(ebr) => ebr.has_name(),
158+
ty::ReBound(_, br) => br.kind.is_named(),
159+
ty::ReLateParam(fr) => fr.bound_region.is_named(),
160+
ty::ReStatic => true,
161+
ty::ReVar(..) => false,
162+
ty::RePlaceholder(placeholder) => placeholder.bound.kind.is_named(),
163+
ty::ReErased => false,
164+
ty::ReError(_) => false,
165+
}
166+
}
167+
168+
#[inline]
169+
pub fn is_error(self) -> bool {
170+
matches!(*self, ty::ReError(_))
171+
}
172+
173+
#[inline]
174+
pub fn is_static(self) -> bool {
175+
matches!(*self, ty::ReStatic)
176+
}
177+
178+
#[inline]
179+
pub fn is_erased(self) -> bool {
180+
matches!(*self, ty::ReErased)
181+
}
182+
183+
#[inline]
184+
pub fn is_bound(self) -> bool {
185+
matches!(*self, ty::ReBound(..))
186+
}
187+
188+
#[inline]
189+
pub fn is_placeholder(self) -> bool {
190+
matches!(*self, ty::RePlaceholder(..))
191+
}
192+
193+
#[inline]
194+
pub fn bound_at_or_above_binder(self, index: ty::DebruijnIndex) -> bool {
195+
match *self {
196+
ty::ReBound(debruijn, _) => debruijn >= index,
197+
_ => false,
198+
}
199+
}
200+
201+
pub fn type_flags(self) -> TypeFlags {
202+
let mut flags = TypeFlags::empty();
203+
204+
match *self {
205+
ty::ReVar(..) => {
206+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
207+
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
208+
flags = flags | TypeFlags::HAS_RE_INFER;
209+
}
210+
ty::RePlaceholder(..) => {
211+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
212+
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
213+
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
214+
}
215+
ty::ReEarlyParam(..) => {
216+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
217+
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
218+
flags = flags | TypeFlags::HAS_RE_PARAM;
219+
}
220+
ty::ReLateParam { .. } => {
221+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
222+
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
223+
}
224+
ty::ReStatic => {
225+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
226+
}
227+
ty::ReBound(..) => {
228+
flags = flags | TypeFlags::HAS_RE_BOUND;
229+
}
230+
ty::ReErased => {
231+
flags = flags | TypeFlags::HAS_RE_ERASED;
232+
}
233+
ty::ReError(_) => {
234+
flags = flags | TypeFlags::HAS_FREE_REGIONS;
235+
}
236+
}
237+
238+
debug!("type_flags({:?}) = {:?}", self, flags);
239+
240+
flags
241+
}
242+
243+
/// Given an early-bound or free region, returns the `DefId` where it was bound.
244+
/// For example, consider the regions in this snippet of code:
245+
///
246+
/// ```ignore (illustrative)
247+
/// impl<'a> Foo {
248+
/// // ^^ -- early bound, declared on an impl
249+
///
250+
/// fn bar<'b, 'c>(x: &self, y: &'b u32, z: &'c u64) where 'static: 'c
251+
/// // ^^ ^^ ^ anonymous, late-bound
252+
/// // | early-bound, appears in where-clauses
253+
/// // late-bound, appears only in fn args
254+
/// {..}
255+
/// }
256+
/// ```
257+
///
258+
/// Here, `free_region_binding_scope('a)` would return the `DefId`
259+
/// of the impl, and for all the other highlighted regions, it
260+
/// would return the `DefId` of the function. In other cases (not shown), this
261+
/// function might return the `DefId` of a closure.
262+
pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId {
263+
match *self {
264+
ty::ReEarlyParam(br) => tcx.parent(br.def_id),
265+
ty::ReLateParam(fr) => fr.scope,
266+
_ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self),
267+
}
268+
}
269+
270+
/// True for free regions other than `'static`.
271+
pub fn is_param(self) -> bool {
272+
matches!(*self, ty::ReEarlyParam(_) | ty::ReLateParam(_))
273+
}
274+
275+
/// True for free region in the current context.
276+
///
277+
/// This is the case for `'static` and param regions.
278+
pub fn is_free(self) -> bool {
279+
match *self {
280+
ty::ReStatic | ty::ReEarlyParam(..) | ty::ReLateParam(..) => true,
281+
ty::ReVar(..)
282+
| ty::RePlaceholder(..)
283+
| ty::ReBound(..)
284+
| ty::ReErased
285+
| ty::ReError(..) => false,
286+
}
287+
}
288+
289+
pub fn is_var(self) -> bool {
290+
matches!(self.kind(), ty::ReVar(_))
291+
}
292+
293+
pub fn as_var(self) -> RegionVid {
294+
match self.kind() {
295+
ty::ReVar(vid) => vid,
296+
_ => bug!("expected region {:?} to be of kind ReVar", self),
297+
}
298+
}
299+
}
300+
301+
impl<'tcx> Deref for Region<'tcx> {
302+
type Target = RegionKind<'tcx>;
303+
304+
#[inline]
305+
fn deref(&self) -> &RegionKind<'tcx> {
306+
self.0.0
307+
}
308+
}
309+
310+
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)]
311+
#[derive(HashStable)]
312+
pub struct EarlyParamRegion {
313+
pub def_id: DefId,
314+
pub index: u32,
315+
pub name: Symbol,
316+
}
317+
318+
impl std::fmt::Debug for EarlyParamRegion {
319+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320+
write!(f, "{:?}, {}, {}", self.def_id, self.index, self.name)
321+
}
322+
}
323+
324+
rustc_index::newtype_index! {
325+
/// A **region** (lifetime) **v**ariable **ID**.
326+
#[derive(HashStable)]
327+
#[encodable]
328+
#[orderable]
329+
#[debug_format = "'?{}"]
330+
pub struct RegionVid {}
331+
}
332+
333+
impl Atom for RegionVid {
334+
fn index(self) -> usize {
335+
Idx::index(self)
336+
}
337+
}
338+
339+
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
340+
#[derive(HashStable)]
341+
/// The parameter representation of late-bound function parameters, "some region
342+
/// at least as big as the scope `fr.scope`".
343+
pub struct LateParamRegion {
344+
pub scope: DefId,
345+
pub bound_region: BoundRegionKind,
346+
}
347+
348+
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, TyEncodable, TyDecodable, Copy)]
349+
#[derive(HashStable)]
350+
pub enum BoundRegionKind {
351+
/// An anonymous region parameter for a given fn (&T)
352+
BrAnon,
353+
354+
/// Named region parameters for functions (a in &'a T)
355+
///
356+
/// The `DefId` is needed to distinguish free regions in
357+
/// the event of shadowing.
358+
BrNamed(DefId, Symbol),
359+
360+
/// Anonymous region for the implicit env pointer parameter
361+
/// to a closure
362+
BrEnv,
363+
}
364+
365+
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, Debug, PartialOrd, Ord)]
366+
#[derive(HashStable)]
367+
pub struct BoundRegion {
368+
pub var: BoundVar,
369+
pub kind: BoundRegionKind,
370+
}
371+
372+
impl BoundRegionKind {
373+
pub fn is_named(&self) -> bool {
374+
match *self {
375+
BoundRegionKind::BrNamed(_, name) => {
376+
name != kw::UnderscoreLifetime && name != kw::Empty
377+
}
378+
_ => false,
379+
}
380+
}
381+
382+
pub fn get_name(&self) -> Option<Symbol> {
383+
if self.is_named() {
384+
match *self {
385+
BoundRegionKind::BrNamed(_, name) => return Some(name),
386+
_ => unreachable!(),
387+
}
388+
}
389+
390+
None
391+
}
392+
393+
pub fn get_id(&self) -> Option<DefId> {
394+
match *self {
395+
BoundRegionKind::BrNamed(id, _) => return Some(id),
396+
_ => None,
397+
}
398+
}
399+
}

‎compiler/rustc_middle/src/ty/sty.rs

Lines changed: 6 additions & 759 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.