2020-11-15 12:36:28 -08:00
|
|
|
//! # The MIR Visitor
|
|
|
|
//!
|
|
|
|
//! ## Overview
|
|
|
|
//!
|
|
|
|
//! There are two visitors, one for immutable and one for mutable references,
|
2022-12-16 16:24:14 +02:00
|
|
|
//! but both are generated by the `make_mir_visitor` macro.
|
2022-12-14 05:31:56 +02:00
|
|
|
//! The code is written according to the following conventions:
|
2020-11-15 12:36:28 -08:00
|
|
|
//!
|
|
|
|
//! - introduce a `visit_foo` and a `super_foo` method for every MIR type
|
|
|
|
//! - `visit_foo`, by default, calls `super_foo`
|
|
|
|
//! - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
|
|
|
|
//!
|
2022-12-14 05:31:56 +02:00
|
|
|
//! This allows you to override `visit_foo` for types you are
|
|
|
|
//! interested in, and invoke (within that method call)
|
2020-11-15 12:36:28 -08:00
|
|
|
//! `self.super_foo` to get the default behavior. Just as in an OO
|
|
|
|
//! language, you should never call `super` methods ordinarily except
|
|
|
|
//! in that circumstance.
|
|
|
|
//!
|
|
|
|
//! For the most part, we do not destructure things external to the
|
|
|
|
//! MIR, e.g., types, spans, etc, but simply visit them and stop. This
|
|
|
|
//! avoids duplication with other visitors like `TypeFoldable`.
|
|
|
|
//!
|
|
|
|
//! ## Updating
|
|
|
|
//!
|
|
|
|
//! The code is written in a very deliberate style intended to minimize
|
|
|
|
//! the chance of things being overlooked. You'll notice that we always
|
|
|
|
//! use pattern matching to reference fields and we ensure that all
|
|
|
|
//! matches are exhaustive.
|
|
|
|
//!
|
|
|
|
//! For example, the `super_basic_block_data` method begins like this:
|
|
|
|
//!
|
2022-04-15 15:04:34 -07:00
|
|
|
//! ```ignore (pseudo-rust)
|
2022-07-01 16:21:21 +02:00
|
|
|
//! fn super_basic_block_data(
|
|
|
|
//! &mut self,
|
|
|
|
//! block: BasicBlock,
|
|
|
|
//! data: & $($mutability)? BasicBlockData<'tcx>
|
|
|
|
//! ) {
|
2020-11-15 12:36:28 -08:00
|
|
|
//! let BasicBlockData {
|
|
|
|
//! statements,
|
|
|
|
//! terminator,
|
|
|
|
//! is_cleanup: _
|
|
|
|
//! } = *data;
|
|
|
|
//!
|
|
|
|
//! for statement in statements {
|
|
|
|
//! self.visit_statement(block, statement);
|
|
|
|
//! }
|
|
|
|
//!
|
|
|
|
//! ...
|
|
|
|
//! }
|
|
|
|
//! ```
|
|
|
|
//!
|
|
|
|
//! Here we used `let BasicBlockData { <fields> } = *data` deliberately,
|
|
|
|
//! rather than writing `data.statements` in the body. This is because if one
|
|
|
|
//! adds a new field to `BasicBlockData`, one will be forced to revise this code,
|
|
|
|
//! and hence one will (hopefully) invoke the correct visit methods (if any).
|
|
|
|
//!
|
|
|
|
//! For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
|
|
|
|
//! That means you never write `..` to skip over fields, nor do you write `_`
|
|
|
|
//! to skip over variants in a `match`.
|
|
|
|
//!
|
|
|
|
//! The only place that `_` is acceptable is to match a field (or
|
|
|
|
//! variant argument) that does not require visiting, as in
|
|
|
|
//! `is_cleanup` above.
|
|
|
|
|
2019-02-05 11:20:45 -06:00
|
|
|
use crate::mir::*;
|
2023-07-11 22:35:29 +01:00
|
|
|
use crate::ty::GenericArgsRef;
|
2023-05-08 23:38:54 +03:00
|
|
|
use crate::ty::{self, CanonicalUserTypeAnnotation, Ty};
|
2019-12-31 20:15:40 +03:00
|
|
|
use rustc_span::Span;
|
2015-11-03 06:33:59 -05:00
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
macro_rules! make_mir_visitor {
|
2019-02-09 16:29:31 +00:00
|
|
|
($visitor_trait_name:ident, $($mutability:ident)?) => {
|
2016-01-07 05:49:46 -05:00
|
|
|
pub trait $visitor_trait_name<'tcx> {
|
|
|
|
// Override these, and call `self.super_xxx` to revert back to the
|
|
|
|
// default behavior.
|
2015-11-03 06:33:59 -05:00
|
|
|
|
2019-10-10 23:16:44 -04:00
|
|
|
fn visit_body(
|
|
|
|
&mut self,
|
2020-04-12 10:31:00 -07:00
|
|
|
body: &$($mutability)? Body<'tcx>,
|
2019-10-10 23:16:44 -04:00
|
|
|
) {
|
2019-11-06 12:00:46 -05:00
|
|
|
self.super_body(body);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-08-02 20:06:16 -07:00
|
|
|
extra_body_methods!($($mutability)?);
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_basic_block_data(
|
|
|
|
&mut self,
|
|
|
|
block: BasicBlock,
|
|
|
|
data: & $($mutability)? BasicBlockData<'tcx>,
|
|
|
|
) {
|
2016-01-07 05:49:46 -05:00
|
|
|
self.super_basic_block_data(block, data);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_source_scope_data(
|
|
|
|
&mut self,
|
|
|
|
scope_data: & $($mutability)? SourceScopeData<'tcx>,
|
|
|
|
) {
|
2018-05-28 14:16:09 +03:00
|
|
|
self.super_source_scope_data(scope_data);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_statement(
|
|
|
|
&mut self,
|
|
|
|
statement: & $($mutability)? Statement<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2019-04-22 21:07:14 +01:00
|
|
|
self.super_statement(statement, location);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_assign(
|
|
|
|
&mut self,
|
|
|
|
place: & $($mutability)? Place<'tcx>,
|
|
|
|
rvalue: & $($mutability)? Rvalue<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2019-04-22 21:07:14 +01:00
|
|
|
self.super_assign(place, rvalue, location);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_terminator(
|
|
|
|
&mut self,
|
|
|
|
terminator: & $($mutability)? Terminator<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2019-04-22 21:07:14 +01:00
|
|
|
self.super_terminator(terminator, location);
|
2015-10-26 14:35:18 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_assert_message(
|
|
|
|
&mut self,
|
|
|
|
msg: & $($mutability)? AssertMessage<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.super_assert_message(msg, location);
|
2016-05-25 08:39:32 +03:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_rvalue(
|
|
|
|
&mut self,
|
|
|
|
rvalue: & $($mutability)? Rvalue<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.super_rvalue(rvalue, location);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_operand(
|
|
|
|
&mut self,
|
|
|
|
operand: & $($mutability)? Operand<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.super_operand(operand, location);
|
2015-12-14 23:27:58 +02:00
|
|
|
}
|
2015-11-03 06:33:59 -05:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_ascribe_user_ty(
|
|
|
|
&mut self,
|
|
|
|
place: & $($mutability)? Place<'tcx>,
|
2022-07-04 09:40:58 +02:00
|
|
|
variance: $(& $mutability)? ty::Variance,
|
2022-07-01 16:21:21 +02:00
|
|
|
user_ty: & $($mutability)? UserTypeProjection,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2018-10-10 17:07:10 -04:00
|
|
|
self.super_ascribe_user_ty(place, variance, user_ty, location);
|
2018-02-23 20:52:05 +00:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_coverage(
|
|
|
|
&mut self,
|
|
|
|
coverage: & $($mutability)? Coverage,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2020-08-15 04:42:13 -07:00
|
|
|
self.super_coverage(coverage, location);
|
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_retag(
|
|
|
|
&mut self,
|
2022-07-04 09:40:58 +02:00
|
|
|
kind: $(& $mutability)? RetagKind,
|
2022-07-01 16:21:21 +02:00
|
|
|
place: & $($mutability)? Place<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2018-12-11 19:54:38 +01:00
|
|
|
self.super_retag(kind, place, location);
|
2018-10-24 13:47:48 +02:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_place(
|
|
|
|
&mut self,
|
|
|
|
place: & $($mutability)? Place<'tcx>,
|
|
|
|
context: PlaceContext,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2017-12-01 14:39:51 +02:00
|
|
|
self.super_place(place, context, location);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2019-10-08 12:16:26 -03:00
|
|
|
visit_place_fns!($($mutability)?);
|
2019-10-02 18:03:23 -03:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_constant(
|
|
|
|
&mut self,
|
|
|
|
constant: & $($mutability)? Constant<'tcx>,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.super_constant(constant, location);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2023-05-02 18:04:52 +01:00
|
|
|
fn visit_ty_const(
|
|
|
|
&mut self,
|
2023-05-04 11:22:11 +01:00
|
|
|
ct: $( & $mutability)? ty::Const<'tcx>,
|
2023-05-02 18:04:52 +01:00
|
|
|
location: Location,
|
|
|
|
) {
|
|
|
|
self.super_ty_const(ct, location);
|
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_span(
|
|
|
|
&mut self,
|
|
|
|
span: $(& $mutability)? Span,
|
|
|
|
) {
|
2016-01-07 05:49:46 -05:00
|
|
|
self.super_span(span);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_source_info(
|
|
|
|
&mut self,
|
|
|
|
source_info: & $($mutability)? SourceInfo,
|
|
|
|
) {
|
2016-06-07 19:21:56 +03:00
|
|
|
self.super_source_info(source_info);
|
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_ty(
|
|
|
|
&mut self,
|
|
|
|
ty: $(& $mutability)? Ty<'tcx>,
|
|
|
|
_: TyContext,
|
|
|
|
) {
|
2016-03-24 06:12:19 -04:00
|
|
|
self.super_ty(ty);
|
|
|
|
}
|
|
|
|
|
2018-10-22 11:58:06 +02:00
|
|
|
fn visit_user_type_projection(
|
|
|
|
&mut self,
|
2019-03-28 18:00:17 -07:00
|
|
|
ty: & $($mutability)? UserTypeProjection,
|
2018-10-22 11:58:06 +02:00
|
|
|
) {
|
|
|
|
self.super_user_type_projection(ty);
|
|
|
|
}
|
|
|
|
|
2018-10-15 09:31:38 -04:00
|
|
|
fn visit_user_type_annotation(
|
|
|
|
&mut self,
|
2018-11-16 22:56:18 +01:00
|
|
|
index: UserTypeAnnotationIndex,
|
2019-02-09 16:29:31 +00:00
|
|
|
ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
|
2018-10-15 09:31:38 -04:00
|
|
|
) {
|
2018-11-16 22:56:18 +01:00
|
|
|
self.super_user_type_annotation(index, ty);
|
2018-08-09 06:18:00 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_region(
|
|
|
|
&mut self,
|
|
|
|
region: $(& $mutability)? ty::Region<'tcx>,
|
|
|
|
_: Location,
|
|
|
|
) {
|
2017-08-04 11:25:13 +03:00
|
|
|
self.super_region(region);
|
|
|
|
}
|
|
|
|
|
2023-07-11 22:35:29 +01:00
|
|
|
fn visit_args(
|
2022-07-01 16:21:21 +02:00
|
|
|
&mut self,
|
2023-07-11 22:35:29 +01:00
|
|
|
args: & $($mutability)? GenericArgsRef<'tcx>,
|
2022-07-01 16:21:21 +02:00
|
|
|
_: Location,
|
|
|
|
) {
|
2023-07-11 22:35:29 +01:00
|
|
|
self.super_args(args);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_local_decl(
|
|
|
|
&mut self,
|
|
|
|
local: Local,
|
|
|
|
local_decl: & $($mutability)? LocalDecl<'tcx>,
|
|
|
|
) {
|
2017-10-26 19:53:31 -04:00
|
|
|
self.super_local_decl(local, local_decl);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_var_debug_info(
|
|
|
|
&mut self,
|
|
|
|
var_debug_info: & $($mutability)* VarDebugInfo<'tcx>,
|
|
|
|
) {
|
2018-05-16 18:58:54 +03:00
|
|
|
self.super_var_debug_info(var_debug_info);
|
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_local(
|
|
|
|
&mut self,
|
|
|
|
_local: $(& $mutability)? Local,
|
|
|
|
_context: PlaceContext,
|
|
|
|
_location: Location,
|
|
|
|
) {}
|
2016-12-26 14:34:03 +01:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn visit_source_scope(
|
|
|
|
&mut self,
|
|
|
|
scope: $(& $mutability)? SourceScope,
|
|
|
|
) {
|
2018-05-28 14:16:09 +03:00
|
|
|
self.super_source_scope(scope);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
// The `super_xxx` methods comprise the default behavior and are
|
2016-02-09 11:52:39 -05:00
|
|
|
// not meant to be overridden.
|
2015-11-03 06:33:59 -05:00
|
|
|
|
2019-10-10 23:16:44 -04:00
|
|
|
fn super_body(
|
|
|
|
&mut self,
|
2020-04-12 10:31:00 -07:00
|
|
|
body: &$($mutability)? Body<'tcx>,
|
2019-10-10 23:16:44 -04:00
|
|
|
) {
|
2022-08-02 20:06:16 -07:00
|
|
|
super_body!(self, body, $($mutability, true)?);
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_basic_block_data(&mut self,
|
|
|
|
block: BasicBlock,
|
2019-02-09 16:29:31 +00:00
|
|
|
data: & $($mutability)? BasicBlockData<'tcx>) {
|
2016-03-24 06:12:19 -04:00
|
|
|
let BasicBlockData {
|
2019-02-09 16:29:31 +00:00
|
|
|
statements,
|
|
|
|
terminator,
|
2016-03-24 06:12:19 -04:00
|
|
|
is_cleanup: _
|
2019-02-09 16:29:31 +00:00
|
|
|
} = data;
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2016-08-08 18:46:06 -07:00
|
|
|
let mut index = 0;
|
2016-03-24 06:12:19 -04:00
|
|
|
for statement in statements {
|
2020-12-29 22:02:47 +01:00
|
|
|
let location = Location { block, statement_index: index };
|
2019-04-22 21:07:14 +01:00
|
|
|
self.visit_statement(statement, location);
|
2016-08-08 18:46:06 -07:00
|
|
|
index += 1;
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
if let Some(terminator) = terminator {
|
2020-12-29 22:02:47 +01:00
|
|
|
let location = Location { block, statement_index: index };
|
2019-04-22 21:07:14 +01:00
|
|
|
self.visit_terminator(terminator, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
|
|
|
|
2020-02-08 21:31:09 +02:00
|
|
|
fn super_source_scope_data(
|
|
|
|
&mut self,
|
|
|
|
scope_data: & $($mutability)? SourceScopeData<'tcx>,
|
|
|
|
) {
|
2018-05-28 14:16:09 +03:00
|
|
|
let SourceScopeData {
|
2019-02-09 16:29:31 +00:00
|
|
|
span,
|
|
|
|
parent_scope,
|
2020-02-08 21:31:09 +02:00
|
|
|
inlined,
|
2020-09-21 06:52:37 +03:00
|
|
|
inlined_parent_scope,
|
2019-11-26 22:17:35 +02:00
|
|
|
local_data: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
} = scope_data;
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_span($(& $mutability)? *span);
|
2019-02-09 16:29:31 +00:00
|
|
|
if let Some(parent_scope) = parent_scope {
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_source_scope($(& $mutability)? *parent_scope);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
2020-02-08 21:31:09 +02:00
|
|
|
if let Some((callee, callsite_span)) = inlined {
|
2023-02-16 18:46:25 -08:00
|
|
|
let location = Location::START;
|
2020-02-08 21:31:09 +02:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_span($(& $mutability)? *callsite_span);
|
2020-02-08 21:31:09 +02:00
|
|
|
|
2023-07-11 22:35:29 +01:00
|
|
|
let ty::Instance { def: callee_def, args: callee_args } = callee;
|
2020-02-08 21:31:09 +02:00
|
|
|
match callee_def {
|
|
|
|
ty::InstanceDef::Item(_def_id) => {}
|
|
|
|
|
|
|
|
ty::InstanceDef::Intrinsic(_def_id) |
|
2022-07-19 19:57:44 -04:00
|
|
|
ty::InstanceDef::VTableShim(_def_id) |
|
2020-02-08 21:31:09 +02:00
|
|
|
ty::InstanceDef::ReifyShim(_def_id) |
|
|
|
|
ty::InstanceDef::Virtual(_def_id, _) |
|
2023-02-03 09:04:12 +01:00
|
|
|
ty::InstanceDef::ThreadLocalShim(_def_id) |
|
Support `#[track_caller]` on closures and generators
This PR allows applying a `#[track_caller]` attribute to a
closure/generator expression. The attribute as interpreted as applying
to the compiler-generated implementation of the corresponding trait
method (`FnOnce::call_once`, `FnMut::call_mut`, `Fn::call`, or
`Generator::resume`).
This feature does not have its own feature gate - however, it requires
`#![feature(stmt_expr_attributes)]` in order to actually apply
an attribute to a closure or generator.
This is implemented in the same way as for functions - an extra
location argument is appended to the end of the ABI. For closures,
this argument is *not* part of the 'tupled' argument storing the
parameters - the final closure argument for `#[track_caller]` closures
is no longer a tuple.
For direct (monomorphized) calls, the necessary support was already
implemented - we just needeed to adjust some assertions around checking
the ABI and argument count to take closures into account.
For calls through a trait object, more work was needed.
When creating a `ReifyShim`, we need to create a shim
for the trait method (e.g. `FnOnce::call_mut`) - unlike normal
functions, closures are never invoked directly, and always go through a
trait method.
Additional handling was needed for `InstanceDef::ClosureOnceShim`. In
order to pass location information throgh a direct (monomorphized) call
to `FnOnce::call_once` on an `FnMut` closure, we need to make
`ClosureOnceShim` aware of `#[tracked_caller]`. A new field
`track_caller` is added to `ClosureOnceShim` - this is used by
`InstanceDef::requires_caller` location, allowing codegen to
pass through the extra location argument.
Since `ClosureOnceShim.track_caller` is only used by codegen,
we end up generating two identical MIR shims - one for
`track_caller == true`, and one for `track_caller == false`. However,
these two shims are used by the entire crate (i.e. it's two shims total,
not two shims per unique closure), so this shouldn't a big deal.
2021-06-27 14:01:11 -05:00
|
|
|
ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
|
2020-02-08 21:31:09 +02:00
|
|
|
ty::InstanceDef::DropGlue(_def_id, None) => {}
|
|
|
|
|
|
|
|
ty::InstanceDef::FnPtrShim(_def_id, ty) |
|
|
|
|
ty::InstanceDef::DropGlue(_def_id, Some(ty)) |
|
2022-07-20 14:32:58 +02:00
|
|
|
ty::InstanceDef::CloneShim(_def_id, ty) |
|
|
|
|
ty::InstanceDef::FnPtrAddrShim(_def_id, ty) => {
|
2020-02-08 21:31:09 +02:00
|
|
|
// FIXME(eddyb) use a better `TyContext` here.
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
2020-02-08 21:31:09 +02:00
|
|
|
}
|
|
|
|
}
|
2023-07-11 22:35:29 +01:00
|
|
|
self.visit_args(callee_args, location);
|
2020-02-08 21:31:09 +02:00
|
|
|
}
|
2020-09-21 06:52:37 +03:00
|
|
|
if let Some(inlined_parent_scope) = inlined_parent_scope {
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_source_scope($(& $mutability)? *inlined_parent_scope);
|
2020-09-21 06:52:37 +03:00
|
|
|
}
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_statement(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
statement: & $($mutability)? Statement<'tcx>,
|
2016-08-08 18:46:06 -07:00
|
|
|
location: Location) {
|
2016-03-24 06:12:19 -04:00
|
|
|
let Statement {
|
2019-02-09 16:29:31 +00:00
|
|
|
source_info,
|
|
|
|
kind,
|
|
|
|
} = statement;
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2016-06-07 19:21:56 +03:00
|
|
|
self.visit_source_info(source_info);
|
2019-02-09 16:29:31 +00:00
|
|
|
match kind {
|
2019-09-11 16:05:45 -03:00
|
|
|
StatementKind::Assign(
|
2022-07-04 09:40:58 +02:00
|
|
|
box (place, rvalue)
|
2019-09-11 16:05:45 -03:00
|
|
|
) => {
|
2019-04-22 21:07:14 +01:00
|
|
|
self.visit_assign(place, rvalue, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2021-03-29 22:48:44 -04:00
|
|
|
StatementKind::FakeRead(box (_, place)) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
|
|
|
|
location
|
|
|
|
);
|
2018-05-04 12:04:33 +02:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
StatementKind::SetDiscriminant { place, .. } => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
2022-04-11 06:04:53 -04:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::SetDiscriminant),
|
2018-10-26 13:22:45 +02:00
|
|
|
location
|
|
|
|
);
|
2016-08-04 16:14:33 -07:00
|
|
|
}
|
2022-04-05 17:14:59 -04:00
|
|
|
StatementKind::Deinit(place) => {
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
2022-04-11 06:04:53 -04:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Deinit),
|
2022-04-05 17:14:59 -04:00
|
|
|
location
|
|
|
|
)
|
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
StatementKind::StorageLive(local) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_local(
|
2022-07-01 16:21:21 +02:00
|
|
|
$(& $mutability)? *local,
|
2018-10-26 13:22:45 +02:00
|
|
|
PlaceContext::NonUse(NonUseContext::StorageLive),
|
|
|
|
location
|
|
|
|
);
|
2016-08-14 06:34:14 +03:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
StatementKind::StorageDead(local) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_local(
|
2022-07-01 16:21:21 +02:00
|
|
|
$(& $mutability)? *local,
|
2018-10-26 13:22:45 +02:00
|
|
|
PlaceContext::NonUse(NonUseContext::StorageDead),
|
|
|
|
location
|
|
|
|
);
|
2016-08-14 06:34:14 +03:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
StatementKind::Retag(kind, place) => {
|
2022-07-04 09:40:58 +02:00
|
|
|
self.visit_retag($(& $mutability)? *kind, place, location);
|
2018-10-24 13:47:48 +02:00
|
|
|
}
|
2022-09-06 18:41:01 +02:00
|
|
|
StatementKind::PlaceMention(place) => {
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
2023-04-25 20:09:54 +00:00
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::PlaceMention),
|
2022-09-06 18:41:01 +02:00
|
|
|
location
|
|
|
|
);
|
|
|
|
}
|
2019-09-11 16:05:45 -03:00
|
|
|
StatementKind::AscribeUserType(
|
2022-07-04 09:40:58 +02:00
|
|
|
box (place, user_ty),
|
2019-09-11 16:05:45 -03:00
|
|
|
variance
|
|
|
|
) => {
|
2022-07-04 09:40:58 +02:00
|
|
|
self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location);
|
2018-02-23 20:52:05 +00:00
|
|
|
}
|
2020-08-15 04:42:13 -07:00
|
|
|
StatementKind::Coverage(coverage) => {
|
|
|
|
self.visit_coverage(
|
|
|
|
coverage,
|
|
|
|
location
|
|
|
|
)
|
|
|
|
}
|
2022-07-12 10:05:00 +00:00
|
|
|
StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => {
|
|
|
|
match intrinsic {
|
|
|
|
NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location),
|
|
|
|
NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
|
|
|
|
self.visit_operand(src, location);
|
|
|
|
self.visit_operand(dst, location);
|
|
|
|
self.visit_operand(count, location);
|
|
|
|
}
|
|
|
|
}
|
2022-06-30 08:16:05 +00:00
|
|
|
}
|
2022-12-20 00:51:17 +00:00
|
|
|
StatementKind::ConstEvalCounter => {}
|
2016-09-15 18:17:58 -07:00
|
|
|
StatementKind::Nop => {}
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-11-03 06:33:59 -05:00
|
|
|
}
|
2015-12-08 14:07:25 -05:00
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_assign(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
place: &$($mutability)? Place<'tcx>,
|
|
|
|
rvalue: &$($mutability)? Rvalue<'tcx>,
|
2016-08-08 18:46:06 -07:00
|
|
|
location: Location) {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
|
|
|
location
|
|
|
|
);
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_rvalue(rvalue, location);
|
2015-12-08 14:07:25 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_terminator(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
terminator: &$($mutability)? Terminator<'tcx>,
|
2020-06-10 10:03:26 +02:00
|
|
|
location: Location) {
|
2019-02-09 16:29:31 +00:00
|
|
|
let Terminator { source_info, kind } = terminator;
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2016-06-07 19:21:56 +03:00
|
|
|
self.visit_source_info(source_info);
|
2019-02-09 16:29:31 +00:00
|
|
|
match kind {
|
2019-04-26 21:36:36 +01:00
|
|
|
TerminatorKind::Goto { .. } |
|
2023-08-19 13:10:25 +02:00
|
|
|
TerminatorKind::UnwindResume |
|
|
|
|
TerminatorKind::UnwindTerminate |
|
2019-04-26 21:36:36 +01:00
|
|
|
TerminatorKind::GeneratorDrop |
|
|
|
|
TerminatorKind::Unreachable |
|
2020-06-02 09:15:24 +02:00
|
|
|
TerminatorKind::FalseEdge { .. } |
|
2022-07-04 09:40:58 +02:00
|
|
|
TerminatorKind::FalseUnwind { .. } => {}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2020-05-09 16:08:04 +02:00
|
|
|
TerminatorKind::Return => {
|
|
|
|
// `return` logically moves from the return place `_0`. Note that the place
|
|
|
|
// cannot be changed by any visitor, though.
|
|
|
|
let $($mutability)? local = RETURN_PLACE;
|
|
|
|
self.visit_local(
|
2022-07-01 16:21:21 +02:00
|
|
|
$(& $mutability)? local,
|
2020-05-09 16:08:04 +02:00
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
|
2020-06-10 10:03:26 +02:00
|
|
|
location,
|
2020-05-09 16:08:04 +02:00
|
|
|
);
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
local,
|
|
|
|
RETURN_PLACE,
|
|
|
|
"`MutVisitor` tried to mutate return place of `return` terminator"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
TerminatorKind::SwitchInt {
|
|
|
|
discr,
|
2019-04-26 21:36:36 +01:00
|
|
|
targets: _
|
2019-02-09 16:29:31 +00:00
|
|
|
} => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(discr, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
TerminatorKind::Drop {
|
2020-06-10 09:56:54 +02:00
|
|
|
place,
|
2019-04-26 21:36:36 +01:00
|
|
|
target: _,
|
|
|
|
unwind: _,
|
2023-05-25 17:30:23 +00:00
|
|
|
replace: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
} => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
2020-06-10 09:56:54 +02:00
|
|
|
place,
|
2018-10-26 13:22:45 +02:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Drop),
|
2020-06-10 10:03:26 +02:00
|
|
|
location
|
2018-10-26 13:22:45 +02:00
|
|
|
);
|
2016-05-17 01:06:52 +03:00
|
|
|
}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
TerminatorKind::Call {
|
|
|
|
func,
|
|
|
|
args,
|
|
|
|
destination,
|
2022-04-16 09:27:54 -04:00
|
|
|
target: _,
|
2022-10-08 23:47:59 +01:00
|
|
|
unwind: _,
|
2023-06-18 05:24:38 +00:00
|
|
|
call_source: _,
|
2020-06-09 15:34:23 -04:00
|
|
|
fn_span: _
|
2019-02-09 16:29:31 +00:00
|
|
|
} => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(func, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
for arg in args {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(arg, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2022-04-16 09:27:54 -04:00
|
|
|
self.visit_place(
|
|
|
|
destination,
|
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Call),
|
|
|
|
location
|
|
|
|
);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2016-05-25 08:39:32 +03:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
TerminatorKind::Assert {
|
|
|
|
cond,
|
|
|
|
expected: _,
|
|
|
|
msg,
|
2019-04-26 21:36:36 +01:00
|
|
|
target: _,
|
2022-10-08 23:47:59 +01:00
|
|
|
unwind: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
} => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(cond, location);
|
|
|
|
self.visit_assert_message(msg, location);
|
2016-05-25 08:39:32 +03:00
|
|
|
}
|
2016-12-26 14:34:03 +01:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
TerminatorKind::Yield {
|
|
|
|
value,
|
2019-04-26 21:36:36 +01:00
|
|
|
resume: _,
|
2020-01-25 02:30:46 +01:00
|
|
|
resume_arg,
|
2019-04-26 21:36:36 +01:00
|
|
|
drop: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
} => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(value, location);
|
2020-01-25 02:30:46 +01:00
|
|
|
self.visit_place(
|
|
|
|
resume_arg,
|
2020-04-02 10:54:24 -07:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Yield),
|
2020-06-10 10:03:26 +02:00
|
|
|
location,
|
2020-01-25 02:30:46 +01:00
|
|
|
);
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
|
|
|
|
2020-02-14 18:17:50 +00:00
|
|
|
TerminatorKind::InlineAsm {
|
|
|
|
template: _,
|
|
|
|
operands,
|
|
|
|
options: _,
|
2020-05-26 20:07:59 +01:00
|
|
|
line_spans: _,
|
2020-02-14 18:17:50 +00:00
|
|
|
destination: _,
|
2022-10-08 23:47:59 +01:00
|
|
|
unwind: _,
|
2020-02-14 18:17:50 +00:00
|
|
|
} => {
|
|
|
|
for op in operands {
|
|
|
|
match op {
|
2021-04-06 05:50:55 +01:00
|
|
|
InlineAsmOperand::In { value, .. } => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(value, location);
|
2020-02-14 18:17:50 +00:00
|
|
|
}
|
2021-08-16 17:30:23 +02:00
|
|
|
InlineAsmOperand::Out { place: Some(place), .. } => {
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
2021-08-30 01:23:33 +01:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
|
2021-08-16 17:30:23 +02:00
|
|
|
location,
|
|
|
|
);
|
2020-02-14 18:17:50 +00:00
|
|
|
}
|
|
|
|
InlineAsmOperand::InOut { in_value, out_place, .. } => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_operand(in_value, location);
|
2020-02-14 18:17:50 +00:00
|
|
|
if let Some(out_place) = out_place {
|
|
|
|
self.visit_place(
|
|
|
|
out_place,
|
2021-08-30 01:23:33 +01:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::AsmOutput),
|
2020-06-10 10:03:26 +02:00
|
|
|
location,
|
2020-02-14 18:17:50 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2021-04-06 05:50:55 +01:00
|
|
|
InlineAsmOperand::Const { value }
|
|
|
|
| InlineAsmOperand::SymFn { value } => {
|
2020-06-10 10:03:26 +02:00
|
|
|
self.visit_constant(value, location);
|
2020-02-14 18:17:50 +00:00
|
|
|
}
|
2021-08-16 17:30:23 +02:00
|
|
|
InlineAsmOperand::Out { place: None, .. }
|
|
|
|
| InlineAsmOperand::SymStatic { def_id: _ } => {}
|
2020-02-14 18:17:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-05-25 08:39:32 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn super_assert_message(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
msg: & $($mutability)? AssertMessage<'tcx>,
|
2016-08-08 18:46:06 -07:00
|
|
|
location: Location) {
|
2020-02-12 19:40:31 +01:00
|
|
|
use crate::mir::AssertKind::*;
|
2019-07-24 10:24:55 +02:00
|
|
|
match msg {
|
|
|
|
BoundsCheck { len, index } => {
|
|
|
|
self.visit_operand(len, location);
|
|
|
|
self.visit_operand(index, location);
|
|
|
|
}
|
2020-06-19 18:57:15 +02:00
|
|
|
Overflow(_, l, r) => {
|
|
|
|
self.visit_operand(l, location);
|
|
|
|
self.visit_operand(r, location);
|
|
|
|
}
|
|
|
|
OverflowNeg(op) | DivisionByZero(op) | RemainderByZero(op) => {
|
|
|
|
self.visit_operand(op, location);
|
|
|
|
}
|
2019-11-26 00:30:07 +00:00
|
|
|
ResumedAfterReturn(_) | ResumedAfterPanic(_) => {
|
2019-07-24 10:24:55 +02:00
|
|
|
// Nothing to visit
|
|
|
|
}
|
2022-11-10 11:37:28 -05:00
|
|
|
MisalignedPointerDereference { required, found } => {
|
|
|
|
self.visit_operand(required, location);
|
|
|
|
self.visit_operand(found, location);
|
|
|
|
}
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_rvalue(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
rvalue: & $($mutability)? Rvalue<'tcx>,
|
2016-08-08 18:46:06 -07:00
|
|
|
location: Location) {
|
2019-02-09 16:29:31 +00:00
|
|
|
match rvalue {
|
|
|
|
Rvalue::Use(operand) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(operand, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2023-05-02 18:04:52 +01:00
|
|
|
Rvalue::Repeat(value, ct) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(value, location);
|
2023-05-04 11:22:11 +01:00
|
|
|
self.visit_ty_const($(&$mutability)? *ct, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2020-05-02 21:44:25 +02:00
|
|
|
Rvalue::ThreadLocalRef(_) => {}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::Ref(r, bk, path) => {
|
2022-01-28 11:25:15 +11:00
|
|
|
self.visit_region($(& $mutability)? *r, location);
|
2018-10-26 13:22:45 +02:00
|
|
|
let ctx = match bk {
|
|
|
|
BorrowKind::Shared => PlaceContext::NonMutatingUse(
|
2019-04-24 19:41:43 +01:00
|
|
|
NonMutatingUseContext::SharedBorrow
|
2018-10-26 13:22:45 +02:00
|
|
|
),
|
|
|
|
BorrowKind::Shallow => PlaceContext::NonMutatingUse(
|
2019-04-24 19:41:43 +01:00
|
|
|
NonMutatingUseContext::ShallowBorrow
|
2018-10-26 13:22:45 +02:00
|
|
|
),
|
|
|
|
BorrowKind::Mut { .. } =>
|
2019-04-24 19:41:43 +01:00
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Borrow),
|
2018-10-26 13:22:45 +02:00
|
|
|
};
|
|
|
|
self.visit_place(path, ctx, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2022-06-13 16:37:41 +03:00
|
|
|
Rvalue::CopyForDeref(place) => {
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
|
|
|
|
location
|
|
|
|
);
|
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2018-12-23 19:00:58 +00:00
|
|
|
Rvalue::AddressOf(m, path) => {
|
|
|
|
let ctx = match m {
|
|
|
|
Mutability::Mut => PlaceContext::MutatingUse(
|
|
|
|
MutatingUseContext::AddressOf
|
|
|
|
),
|
|
|
|
Mutability::Not => PlaceContext::NonMutatingUse(
|
|
|
|
NonMutatingUseContext::AddressOf
|
|
|
|
),
|
|
|
|
};
|
|
|
|
self.visit_place(path, ctx, location);
|
|
|
|
}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::Len(path) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
path,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
|
|
|
|
location
|
|
|
|
);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::Cast(_cast_kind, operand, ty) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(operand, location);
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2021-03-05 09:32:47 +00:00
|
|
|
Rvalue::BinaryOp(_bin_op, box(lhs, rhs))
|
|
|
|
| Rvalue::CheckedBinaryOp(_bin_op, box(lhs, rhs)) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(lhs, location);
|
|
|
|
self.visit_operand(rhs, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::UnaryOp(_un_op, op) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(op, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::Discriminant(place) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
|
|
|
|
location
|
|
|
|
);
|
2017-01-31 01:10:54 +02:00
|
|
|
}
|
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::NullaryOp(_op, ty) => {
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
Rvalue::Aggregate(kind, operands) => {
|
|
|
|
let kind = &$($mutability)? **kind;
|
|
|
|
match kind {
|
|
|
|
AggregateKind::Array(ty) => {
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
AggregateKind::Tuple => {
|
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
AggregateKind::Adt(
|
|
|
|
_adt_def,
|
|
|
|
_variant_index,
|
2023-07-11 22:35:29 +01:00
|
|
|
args,
|
|
|
|
_user_args,
|
2019-02-09 16:29:31 +00:00
|
|
|
_active_field_index
|
|
|
|
) => {
|
2023-07-11 22:35:29 +01:00
|
|
|
self.visit_args(args, location);
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
AggregateKind::Closure(
|
2019-04-26 21:36:36 +01:00
|
|
|
_,
|
2023-07-11 22:35:29 +01:00
|
|
|
closure_args
|
2019-02-09 16:29:31 +00:00
|
|
|
) => {
|
2023-07-11 22:35:29 +01:00
|
|
|
self.visit_args(closure_args, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
AggregateKind::Generator(
|
2019-04-26 21:36:36 +01:00
|
|
|
_,
|
2023-07-11 22:35:29 +01:00
|
|
|
generator_args,
|
2019-02-09 16:29:31 +00:00
|
|
|
_movability,
|
|
|
|
) => {
|
2023-07-11 22:35:29 +01:00
|
|
|
self.visit_args(generator_args, location);
|
2016-12-26 14:34:03 +01:00
|
|
|
}
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
|
|
|
|
2016-03-24 06:12:19 -04:00
|
|
|
for operand in operands {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_operand(operand, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
|
|
|
}
|
2021-09-06 18:33:23 +01:00
|
|
|
|
|
|
|
Rvalue::ShallowInitBox(operand, ty) => {
|
|
|
|
self.visit_operand(operand, location);
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
2021-09-06 18:33:23 +01:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
fn super_operand(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
operand: & $($mutability)? Operand<'tcx>,
|
2016-08-08 18:46:06 -07:00
|
|
|
location: Location) {
|
2019-02-09 16:29:31 +00:00
|
|
|
match operand {
|
|
|
|
Operand::Copy(place) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
|
|
|
|
location
|
|
|
|
);
|
2017-11-17 17:19:57 +02:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
Operand::Move(place) => {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Move),
|
|
|
|
location
|
|
|
|
);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2019-02-09 16:29:31 +00:00
|
|
|
Operand::Constant(constant) => {
|
2016-08-08 18:46:06 -07:00
|
|
|
self.visit_constant(constant, location);
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-31 18:59:35 -04:00
|
|
|
fn super_ascribe_user_ty(&mut self,
|
2019-02-09 16:29:31 +00:00
|
|
|
place: & $($mutability)? Place<'tcx>,
|
2023-05-08 23:38:54 +03:00
|
|
|
variance: $(& $mutability)? ty::Variance,
|
2019-03-28 18:00:17 -07:00
|
|
|
user_ty: & $($mutability)? UserTypeProjection,
|
2018-08-31 18:59:35 -04:00
|
|
|
location: Location) {
|
2018-10-26 13:22:45 +02:00
|
|
|
self.visit_place(
|
|
|
|
place,
|
2023-05-08 23:38:54 +03:00
|
|
|
PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)),
|
2018-10-26 13:22:45 +02:00
|
|
|
location
|
|
|
|
);
|
2018-10-22 11:58:06 +02:00
|
|
|
self.visit_user_type_projection(user_ty);
|
2018-02-23 20:52:05 +00:00
|
|
|
}
|
|
|
|
|
2020-08-15 04:42:13 -07:00
|
|
|
fn super_coverage(&mut self,
|
Updates to experimental coverage counter injection
This is a combination of 18 commits.
Commit #2:
Additional examples and some small improvements.
Commit #3:
fixed mir-opt non-mir extensions and spanview title elements
Corrected a fairly recent assumption in runtest.rs that all MIR dump
files end in .mir. (It was appending .mir to the graphviz .dot and
spanview .html file names when generating blessed output files. That
also left outdated files in the baseline alongside the files with the
incorrect names, which I've now removed.)
Updated spanview HTML title elements to match their content, replacing a
hardcoded and incorrect name that was left in accidentally when
originally submitted.
Commit #4:
added more test examples
also improved Makefiles with support for non-zero exit status and to
force validation of tests unless a specific test overrides it with a
specific comment.
Commit #5:
Fixed rare issues after testing on real-world crate
Commit #6:
Addressed PR feedback, and removed temporary -Zexperimental-coverage
-Zinstrument-coverage once again supports the latest capabilities of
LLVM instrprof coverage instrumentation.
Also fixed a bug in spanview.
Commit #7:
Fix closure handling, add tests for closures and inner items
And cleaned up other tests for consistency, and to make it more clear
where spans start/end by breaking up lines.
Commit #8:
renamed "typical" test results "expected"
Now that the `llvm-cov show` tests are improved to normally expect
matching actuals, and to allow individual tests to override that
expectation.
Commit #9:
test coverage of inline generic struct function
Commit #10:
Addressed review feedback
* Removed unnecessary Unreachable filter.
* Replaced a match wildcard with remining variants.
* Added more comments to help clarify the role of successors() in the
CFG traversal
Commit #11:
refactoring based on feedback
* refactored `fn coverage_spans()`.
* changed the way I expand an empty coverage span to improve performance
* fixed a typo that I had accidently left in, in visit.rs
Commit #12:
Optimized use of SourceMap and SourceFile
Commit #13:
Fixed a regression, and synched with upstream
Some generated test file names changed due to some new change upstream.
Commit #14:
Stripping out crate disambiguators from demangled names
These can vary depending on the test platform.
Commit #15:
Ignore llvm-cov show diff on test with generics, expand IO error message
Tests with generics produce llvm-cov show results with demangled names
that can include an unstable "crate disambiguator" (hex value). The
value changes when run in the Rust CI Windows environment. I added a sed
filter to strip them out (in a prior commit), but sed also appears to
fail in the same environment. Until I can figure out a workaround, I'm
just going to ignore this specific test result. I added a FIXME to
follow up later, but it's not that critical.
I also saw an error with Windows GNU, but the IO error did not
specify a path for the directory or file that triggered the error. I
updated the error messages to provide more info for next, time but also
noticed some other tests with similar steps did not fail. Looks
spurious.
Commit #16:
Modify rust-demangler to strip disambiguators by default
Commit #17:
Remove std::process::exit from coverage tests
Due to Issue #77553, programs that call std::process::exit() do not
generate coverage results on Windows MSVC.
Commit #18:
fix: test file paths exceeding Windows max path len
2020-09-01 16:15:17 -07:00
|
|
|
_coverage: & $($mutability)? Coverage,
|
2020-08-15 04:42:13 -07:00
|
|
|
_location: Location) {
|
|
|
|
}
|
|
|
|
|
2018-10-24 13:47:48 +02:00
|
|
|
fn super_retag(&mut self,
|
2022-07-04 09:40:58 +02:00
|
|
|
_kind: $(& $mutability)? RetagKind,
|
2019-02-09 16:29:31 +00:00
|
|
|
place: & $($mutability)? Place<'tcx>,
|
2018-10-24 13:47:48 +02:00
|
|
|
location: Location) {
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Retag),
|
|
|
|
location,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2016-09-25 01:38:27 +02:00
|
|
|
fn super_local_decl(&mut self,
|
2017-10-26 19:53:31 -04:00
|
|
|
local: Local,
|
2019-02-09 16:29:31 +00:00
|
|
|
local_decl: & $($mutability)? LocalDecl<'tcx>) {
|
2016-09-25 01:38:27 +02:00
|
|
|
let LocalDecl {
|
2016-03-24 06:12:19 -04:00
|
|
|
mutability: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
ty,
|
|
|
|
user_ty,
|
|
|
|
source_info,
|
2018-05-29 17:37:24 +03:00
|
|
|
internal: _,
|
2019-11-18 23:04:06 +00:00
|
|
|
local_info: _,
|
2019-02-09 16:29:31 +00:00
|
|
|
} = local_decl;
|
2016-03-24 06:12:19 -04:00
|
|
|
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::LocalDecl {
|
2017-10-26 19:53:31 -04:00
|
|
|
local,
|
2018-05-29 21:31:33 +03:00
|
|
|
source_info: *source_info,
|
2017-10-26 19:53:31 -04:00
|
|
|
});
|
2020-05-06 12:41:15 +10:00
|
|
|
if let Some(user_ty) = user_ty {
|
|
|
|
for (user_ty, _) in & $($mutability)? user_ty.contents {
|
|
|
|
self.visit_user_type_projection(user_ty);
|
|
|
|
}
|
2018-09-10 10:54:31 -04:00
|
|
|
}
|
2018-05-29 21:31:33 +03:00
|
|
|
self.visit_source_info(source_info);
|
2018-05-16 18:58:54 +03:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn super_var_debug_info(
|
|
|
|
&mut self,
|
|
|
|
var_debug_info: & $($mutability)? VarDebugInfo<'tcx>
|
|
|
|
) {
|
2018-05-16 18:58:54 +03:00
|
|
|
let VarDebugInfo {
|
|
|
|
name: _,
|
|
|
|
source_info,
|
2020-05-30 15:02:32 -04:00
|
|
|
value,
|
2023-03-21 21:48:03 +11:00
|
|
|
argument_index: _,
|
2018-05-16 18:58:54 +03:00
|
|
|
} = var_debug_info;
|
|
|
|
|
|
|
|
self.visit_source_info(source_info);
|
2023-02-16 18:46:25 -08:00
|
|
|
let location = Location::START;
|
2020-05-30 15:02:32 -04:00
|
|
|
match value {
|
|
|
|
VarDebugInfoContents::Const(c) => self.visit_constant(c, location),
|
|
|
|
VarDebugInfoContents::Place(place) =>
|
|
|
|
self.visit_place(
|
|
|
|
place,
|
|
|
|
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
|
|
|
|
location
|
|
|
|
),
|
2022-10-01 23:10:36 +02:00
|
|
|
VarDebugInfoContents::Composite { ty, fragments } => {
|
|
|
|
// FIXME(eddyb) use a better `TyContext` here.
|
|
|
|
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
|
|
|
for VarDebugInfoFragment { projection: _, contents } in fragments {
|
|
|
|
self.visit_place(
|
|
|
|
contents,
|
|
|
|
PlaceContext::NonUse(NonUseContext::VarDebugInfo),
|
|
|
|
location,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2020-05-30 15:02:32 -04:00
|
|
|
}
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn super_source_scope(
|
|
|
|
&mut self,
|
|
|
|
_scope: $(& $mutability)? SourceScope
|
|
|
|
) {}
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn super_constant(
|
|
|
|
&mut self,
|
|
|
|
constant: & $($mutability)? Constant<'tcx>,
|
|
|
|
location: Location
|
|
|
|
) {
|
2016-03-25 13:10:32 -04:00
|
|
|
let Constant {
|
2019-02-09 16:29:31 +00:00
|
|
|
span,
|
2023-03-26 16:18:30 +02:00
|
|
|
user_ty: _, // no visit method for this
|
2019-02-09 16:29:31 +00:00
|
|
|
literal,
|
|
|
|
} = constant;
|
2016-03-25 13:10:32 -04:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_span($(& $mutability)? *span);
|
2021-03-08 16:18:03 +00:00
|
|
|
match literal {
|
2023-05-04 11:22:11 +01:00
|
|
|
ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
2022-06-27 16:32:47 +02:00
|
|
|
ConstantKind::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
2021-03-08 16:18:03 +00:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
|
|
|
|
2023-05-02 18:04:52 +01:00
|
|
|
fn super_ty_const(
|
|
|
|
&mut self,
|
2023-05-04 11:22:11 +01:00
|
|
|
_ct: $(& $mutability)? ty::Const<'tcx>,
|
2023-05-02 18:04:52 +01:00
|
|
|
_location: Location,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
fn super_span(&mut self, _span: $(& $mutability)? Span) {
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
2016-03-24 06:12:19 -04:00
|
|
|
|
2019-02-09 16:29:31 +00:00
|
|
|
fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) {
|
2016-06-07 19:21:56 +03:00
|
|
|
let SourceInfo {
|
2019-02-09 16:29:31 +00:00
|
|
|
span,
|
|
|
|
scope,
|
|
|
|
} = source_info;
|
2016-06-07 19:21:56 +03:00
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_span($(& $mutability)? *span);
|
|
|
|
self.visit_source_scope($(& $mutability)? *scope);
|
2016-06-07 19:21:56 +03:00
|
|
|
}
|
|
|
|
|
2018-10-22 11:58:06 +02:00
|
|
|
fn super_user_type_projection(
|
|
|
|
&mut self,
|
2019-03-28 18:00:17 -07:00
|
|
|
_ty: & $($mutability)? UserTypeProjection,
|
2018-10-22 11:58:06 +02:00
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
2018-10-15 09:31:38 -04:00
|
|
|
fn super_user_type_annotation(
|
|
|
|
&mut self,
|
2018-11-16 22:56:18 +01:00
|
|
|
_index: UserTypeAnnotationIndex,
|
2019-02-09 16:29:31 +00:00
|
|
|
ty: & $($mutability)? CanonicalUserTypeAnnotation<'tcx>,
|
2018-10-15 09:31:38 -04:00
|
|
|
) {
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_span($(& $mutability)? ty.span);
|
Overhaul `TyS` and `Ty`.
Specifically, change `Ty` from this:
```
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
```
to this
```
pub struct Ty<'tcx>(Interned<'tcx, TyS<'tcx>>);
```
There are two benefits to this.
- It's now a first class type, so we can define methods on it. This
means we can move a lot of methods away from `TyS`, leaving `TyS` as a
barely-used type, which is appropriate given that it's not meant to
be used directly.
- The uniqueness requirement is now explicit, via the `Interned` type.
E.g. the pointer-based `Eq` and `Hash` comes from `Interned`, rather
than via `TyS`, which wasn't obvious at all.
Much of this commit is boring churn. The interesting changes are in
these files:
- compiler/rustc_middle/src/arena.rs
- compiler/rustc_middle/src/mir/visit.rs
- compiler/rustc_middle/src/ty/context.rs
- compiler/rustc_middle/src/ty/mod.rs
Specifically:
- Most mentions of `TyS` are removed. It's very much a dumb struct now;
`Ty` has all the smarts.
- `TyS` now has `crate` visibility instead of `pub`.
- `TyS::make_for_test` is removed in favour of the static `BOOL_TY`,
which just works better with the new structure.
- The `Eq`/`Ord`/`Hash` impls are removed from `TyS`. `Interned`s impls
of `Eq`/`Hash` now suffice. `Ord` is now partly on `Interned`
(pointer-based, for the `Equal` case) and partly on `TyS`
(contents-based, for the other cases).
- There are many tedious sigil adjustments, i.e. adding or removing `*`
or `&`. They seem to be unavoidable.
2022-01-25 14:13:38 +11:00
|
|
|
self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
|
2018-08-09 06:18:00 -04:00
|
|
|
}
|
|
|
|
|
2019-04-25 22:54:19 +02:00
|
|
|
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2022-01-28 11:25:15 +11:00
|
|
|
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
|
2017-08-04 11:25:13 +03:00
|
|
|
}
|
|
|
|
|
2023-07-11 22:35:29 +01:00
|
|
|
fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {
|
2016-03-24 06:12:19 -04:00
|
|
|
}
|
|
|
|
|
2016-09-15 18:18:40 -07:00
|
|
|
// Convenience methods
|
2019-10-04 00:55:28 -04:00
|
|
|
|
2019-10-10 23:16:44 -04:00
|
|
|
fn visit_location(
|
|
|
|
&mut self,
|
2020-04-12 10:31:00 -07:00
|
|
|
body: &$($mutability)? Body<'tcx>,
|
2019-10-10 23:16:44 -04:00
|
|
|
location: Location
|
|
|
|
) {
|
2022-08-02 20:06:16 -07:00
|
|
|
let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block];
|
2019-10-04 00:55:28 -04:00
|
|
|
if basic_block.statements.len() == location.statement_index {
|
|
|
|
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
|
|
|
|
self.visit_terminator(terminator, location)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
let statement = & $($mutability)?
|
|
|
|
basic_block.statements[location.statement_index];
|
|
|
|
self.visit_statement(statement, location)
|
2016-09-15 18:18:40 -07:00
|
|
|
}
|
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
|
|
|
}
|
2016-01-07 05:49:46 -05:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2022-08-02 20:06:16 -07:00
|
|
|
macro_rules! basic_blocks {
|
|
|
|
($body:ident, mut, true) => {
|
|
|
|
$body.basic_blocks.as_mut()
|
|
|
|
};
|
|
|
|
($body:ident, mut, false) => {
|
|
|
|
$body.basic_blocks.as_mut_preserves_cfg()
|
|
|
|
};
|
|
|
|
($body:ident,) => {
|
2022-07-05 00:00:00 +00:00
|
|
|
$body.basic_blocks
|
2022-08-02 20:06:16 -07:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! basic_blocks_iter {
|
|
|
|
($body:ident, mut, $invalidate:tt) => {
|
|
|
|
basic_blocks!($body, mut, $invalidate).iter_enumerated_mut()
|
|
|
|
};
|
|
|
|
($body:ident,) => {
|
|
|
|
basic_blocks!($body,).iter_enumerated()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! extra_body_methods {
|
|
|
|
(mut) => {
|
|
|
|
fn visit_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
|
|
|
|
self.super_body_preserves_cfg(body);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn super_body_preserves_cfg(&mut self, body: &mut Body<'tcx>) {
|
|
|
|
super_body!(self, body, mut, false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
() => {};
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! super_body {
|
|
|
|
($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
|
|
|
|
let span = $body.span;
|
|
|
|
if let Some(gen) = &$($mutability)? $body.generator {
|
|
|
|
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
|
|
|
|
$self.visit_ty(
|
|
|
|
yield_ty,
|
|
|
|
TyContext::YieldTy(SourceInfo::outermost(span))
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (bb, data) in basic_blocks_iter!($body, $($mutability, $invalidate)?) {
|
|
|
|
$self.visit_basic_block_data(bb, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
for scope in &$($mutability)? $body.source_scopes {
|
|
|
|
$self.visit_source_scope_data(scope);
|
|
|
|
}
|
|
|
|
|
|
|
|
$self.visit_ty(
|
|
|
|
$(& $mutability)? $body.return_ty(),
|
|
|
|
TyContext::ReturnTy(SourceInfo::outermost($body.span))
|
|
|
|
);
|
|
|
|
|
|
|
|
for local in $body.local_decls.indices() {
|
|
|
|
$self.visit_local_decl(local, & $($mutability)? $body.local_decls[local]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(unused_macro_rules)]
|
|
|
|
macro_rules! type_annotations {
|
|
|
|
(mut) => ($body.user_type_annotations.iter_enumerated_mut());
|
|
|
|
() => ($body.user_type_annotations.iter_enumerated());
|
|
|
|
}
|
|
|
|
|
|
|
|
for (index, annotation) in type_annotations!($($mutability)?) {
|
|
|
|
$self.visit_user_type_annotation(
|
|
|
|
index, annotation
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
for var_debug_info in &$($mutability)? $body.var_debug_info {
|
|
|
|
$self.visit_var_debug_info(var_debug_info);
|
|
|
|
}
|
|
|
|
|
|
|
|
$self.visit_span($(& $mutability)? $body.span);
|
|
|
|
|
|
|
|
for const_ in &$($mutability)? $body.required_consts {
|
2023-02-16 18:46:25 -08:00
|
|
|
let location = Location::START;
|
2022-08-02 20:06:16 -07:00
|
|
|
$self.visit_constant(const_, location);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-08 12:16:26 -03:00
|
|
|
macro_rules! visit_place_fns {
|
2020-04-11 01:39:50 +02:00
|
|
|
(mut) => {
|
2019-10-20 16:11:04 -04:00
|
|
|
fn tcx<'a>(&'a self) -> TyCtxt<'tcx>;
|
|
|
|
|
2019-10-08 12:16:26 -03:00
|
|
|
fn super_place(
|
|
|
|
&mut self,
|
2019-10-08 15:33:19 -03:00
|
|
|
place: &mut Place<'tcx>,
|
|
|
|
context: PlaceContext,
|
|
|
|
location: Location,
|
2019-10-08 12:16:26 -03:00
|
|
|
) {
|
2020-04-21 17:11:00 -03:00
|
|
|
self.visit_local(&mut place.local, context, location);
|
2019-10-08 15:33:19 -03:00
|
|
|
|
2020-04-11 01:39:50 +02:00
|
|
|
if let Some(new_projection) = self.process_projection(&place.projection, location) {
|
2023-02-17 14:33:08 +11:00
|
|
|
place.projection = self.tcx().mk_place_elems(&new_projection);
|
2019-10-08 23:46:14 -03:00
|
|
|
}
|
2019-10-08 15:33:19 -03:00
|
|
|
}
|
|
|
|
|
2021-12-15 19:32:30 -05:00
|
|
|
fn process_projection<'a>(
|
2019-10-08 15:33:19 -03:00
|
|
|
&mut self,
|
2019-10-08 23:46:14 -03:00
|
|
|
projection: &'a [PlaceElem<'tcx>],
|
2020-04-11 01:39:50 +02:00
|
|
|
location: Location,
|
2019-10-20 16:11:04 -04:00
|
|
|
) -> Option<Vec<PlaceElem<'tcx>>> {
|
2019-10-08 23:46:14 -03:00
|
|
|
let mut projection = Cow::Borrowed(projection);
|
2019-10-08 15:33:19 -03:00
|
|
|
|
2019-10-08 23:46:14 -03:00
|
|
|
for i in 0..projection.len() {
|
2020-05-23 12:02:54 +02:00
|
|
|
if let Some(&elem) = projection.get(i) {
|
2020-04-11 01:39:50 +02:00
|
|
|
if let Some(elem) = self.process_projection_elem(elem, location) {
|
2019-10-20 16:11:04 -04:00
|
|
|
// This converts the borrowed projection into `Cow::Owned(_)` and returns a
|
|
|
|
// clone of the projection so we can mutate and reintern later.
|
2019-10-08 23:46:14 -03:00
|
|
|
let vec = projection.to_mut();
|
|
|
|
vec[i] = elem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
match projection {
|
|
|
|
Cow::Borrowed(_) => None,
|
2019-10-20 16:11:04 -04:00
|
|
|
Cow::Owned(vec) => Some(vec),
|
2019-10-08 23:46:14 -03:00
|
|
|
}
|
2019-10-08 15:33:19 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn process_projection_elem(
|
|
|
|
&mut self,
|
2020-05-23 12:02:54 +02:00
|
|
|
elem: PlaceElem<'tcx>,
|
2020-04-11 01:39:50 +02:00
|
|
|
location: Location,
|
2019-10-08 23:46:14 -03:00
|
|
|
) -> Option<PlaceElem<'tcx>> {
|
2020-04-11 01:39:50 +02:00
|
|
|
match elem {
|
|
|
|
PlaceElem::Index(local) => {
|
2020-05-23 12:02:54 +02:00
|
|
|
let mut new_local = local;
|
2020-04-11 01:39:50 +02:00
|
|
|
self.visit_local(
|
|
|
|
&mut new_local,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
|
|
|
|
location,
|
|
|
|
);
|
|
|
|
|
2022-07-04 21:30:31 +02:00
|
|
|
if new_local == local { None } else { Some(PlaceElem::Index(new_local)) }
|
2020-04-11 01:39:50 +02:00
|
|
|
}
|
2021-10-16 14:03:30 +02:00
|
|
|
PlaceElem::Field(field, ty) => {
|
|
|
|
let mut new_ty = ty;
|
|
|
|
self.visit_ty(&mut new_ty, TyContext::Location(location));
|
2022-07-04 21:30:31 +02:00
|
|
|
if ty != new_ty { Some(PlaceElem::Field(field, new_ty)) } else { None }
|
2021-10-16 14:03:30 +02:00
|
|
|
}
|
2022-07-27 11:58:34 +00:00
|
|
|
PlaceElem::OpaqueCast(ty) => {
|
|
|
|
let mut new_ty = ty;
|
|
|
|
self.visit_ty(&mut new_ty, TyContext::Location(location));
|
|
|
|
if ty != new_ty { Some(PlaceElem::OpaqueCast(new_ty)) } else { None }
|
|
|
|
}
|
2020-04-11 01:39:50 +02:00
|
|
|
PlaceElem::Deref
|
|
|
|
| PlaceElem::ConstantIndex { .. }
|
|
|
|
| PlaceElem::Subslice { .. }
|
|
|
|
| PlaceElem::Downcast(..) => None,
|
|
|
|
}
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
2020-04-11 01:39:50 +02:00
|
|
|
};
|
2019-10-08 12:16:26 -03:00
|
|
|
|
2020-04-11 01:39:50 +02:00
|
|
|
() => {
|
2019-10-08 12:16:26 -03:00
|
|
|
fn visit_projection(
|
|
|
|
&mut self,
|
2021-02-16 14:20:36 +05:30
|
|
|
place_ref: PlaceRef<'tcx>,
|
2019-10-08 12:16:26 -03:00
|
|
|
context: PlaceContext,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2021-02-20 16:46:05 +05:30
|
|
|
self.super_projection(place_ref, context, location);
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_projection_elem(
|
|
|
|
&mut self,
|
2023-06-25 20:38:01 -04:00
|
|
|
place_ref: PlaceRef<'tcx>,
|
2020-05-23 12:02:54 +02:00
|
|
|
elem: PlaceElem<'tcx>,
|
2019-10-08 12:16:26 -03:00
|
|
|
context: PlaceContext,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2023-06-25 20:38:01 -04:00
|
|
|
self.super_projection_elem(place_ref, elem, context, location);
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
|
2020-04-11 01:39:50 +02:00
|
|
|
fn super_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
|
2019-10-08 12:16:26 -03:00
|
|
|
let mut context = context;
|
|
|
|
|
|
|
|
if !place.projection.is_empty() {
|
2020-11-15 12:58:34 -08:00
|
|
|
if context.is_use() {
|
2020-11-22 17:33:06 -08:00
|
|
|
// ^ Only change the context if it is a real use, not a "use" in debuginfo.
|
2020-11-15 12:58:34 -08:00
|
|
|
context = if context.is_mutating_use() {
|
|
|
|
PlaceContext::MutatingUse(MutatingUseContext::Projection)
|
|
|
|
} else {
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
|
|
|
|
};
|
|
|
|
}
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
|
2022-07-01 16:21:21 +02:00
|
|
|
self.visit_local(place.local, context, location);
|
2019-10-08 12:16:26 -03:00
|
|
|
|
2021-02-16 14:20:36 +05:30
|
|
|
self.visit_projection(place.as_ref(), context, location);
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn super_projection(
|
|
|
|
&mut self,
|
2021-02-20 16:46:05 +05:30
|
|
|
place_ref: PlaceRef<'tcx>,
|
2019-10-08 12:16:26 -03:00
|
|
|
context: PlaceContext,
|
|
|
|
location: Location,
|
|
|
|
) {
|
2022-07-11 14:42:49 +01:00
|
|
|
for (base, elem) in place_ref.iter_projections().rev() {
|
2023-06-25 20:38:01 -04:00
|
|
|
self.visit_projection_elem(base, elem, context, location);
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn super_projection_elem(
|
|
|
|
&mut self,
|
2023-06-25 20:38:01 -04:00
|
|
|
_place_ref: PlaceRef<'tcx>,
|
2020-05-23 12:02:54 +02:00
|
|
|
elem: PlaceElem<'tcx>,
|
2019-10-08 12:16:26 -03:00
|
|
|
_context: PlaceContext,
|
|
|
|
location: Location,
|
|
|
|
) {
|
|
|
|
match elem {
|
2022-07-27 11:58:34 +00:00
|
|
|
ProjectionElem::OpaqueCast(ty) | ProjectionElem::Field(_, ty) => {
|
2019-10-08 12:16:26 -03:00
|
|
|
self.visit_ty(ty, TyContext::Location(location));
|
|
|
|
}
|
|
|
|
ProjectionElem::Index(local) => {
|
|
|
|
self.visit_local(
|
2022-07-01 16:21:21 +02:00
|
|
|
local,
|
2019-10-08 12:16:26 -03:00
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
|
2020-04-11 01:39:50 +02:00
|
|
|
location,
|
2019-10-08 12:16:26 -03:00
|
|
|
);
|
|
|
|
}
|
2020-04-11 01:39:50 +02:00
|
|
|
ProjectionElem::Deref
|
|
|
|
| ProjectionElem::Subslice { from: _, to: _, from_end: _ }
|
|
|
|
| ProjectionElem::ConstantIndex { offset: _, min_length: _, from_end: _ }
|
|
|
|
| ProjectionElem::Downcast(_, _) => {}
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
}
|
2020-04-11 01:39:50 +02:00
|
|
|
};
|
2019-10-08 12:16:26 -03:00
|
|
|
}
|
|
|
|
|
2016-01-07 05:49:46 -05:00
|
|
|
make_mir_visitor!(Visitor,);
|
|
|
|
make_mir_visitor!(MutVisitor, mut);
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2017-12-12 11:59:09 -03:00
|
|
|
pub trait MirVisitable<'tcx> {
|
|
|
|
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
|
|
|
|
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
2019-04-22 21:07:14 +01:00
|
|
|
visitor.visit_statement(self, location)
|
2017-12-12 11:59:09 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
|
|
|
|
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
2019-04-22 21:07:14 +01:00
|
|
|
visitor.visit_terminator(self, location)
|
2017-12-12 11:59:09 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
|
|
|
|
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
2019-04-22 21:07:14 +01:00
|
|
|
visitor.visit_terminator(self.as_ref().unwrap(), location)
|
2017-12-12 11:59:09 -03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-26 19:53:31 -04:00
|
|
|
/// Extra information passed to `visit_ty` and friends to give context
|
|
|
|
/// about where the type etc appears.
|
2022-11-08 16:27:01 +01:00
|
|
|
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
2017-10-26 19:53:31 -04:00
|
|
|
pub enum TyContext {
|
|
|
|
LocalDecl {
|
|
|
|
/// The index of the local variable we are visiting.
|
|
|
|
local: Local,
|
|
|
|
|
|
|
|
/// The source location where this local variable was declared.
|
|
|
|
source_info: SourceInfo,
|
|
|
|
},
|
|
|
|
|
2019-01-12 14:55:23 +00:00
|
|
|
/// The inferred type of a user type annotation.
|
|
|
|
UserTy(Span),
|
|
|
|
|
2017-11-07 04:30:06 -05:00
|
|
|
/// The return type of the function.
|
|
|
|
ReturnTy(SourceInfo),
|
2017-10-26 19:53:31 -04:00
|
|
|
|
2018-01-19 19:18:02 -03:00
|
|
|
YieldTy(SourceInfo),
|
|
|
|
|
2017-11-07 04:30:06 -05:00
|
|
|
/// A type found at some location.
|
|
|
|
Location(Location),
|
2017-07-18 22:31:38 -04:00
|
|
|
}
|
|
|
|
|
2016-08-16 04:59:50 +03:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2019-04-24 19:41:43 +01:00
|
|
|
pub enum NonMutatingUseContext {
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Being inspected in some way, like loading a len.
|
|
|
|
Inspect,
|
|
|
|
/// Consumed as part of an operand.
|
|
|
|
Copy,
|
|
|
|
/// Consumed as part of an operand.
|
|
|
|
Move,
|
|
|
|
/// Shared borrow.
|
2019-04-24 19:41:43 +01:00
|
|
|
SharedBorrow,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Shallow borrow.
|
2019-04-24 19:41:43 +01:00
|
|
|
ShallowBorrow,
|
2018-12-23 19:00:58 +00:00
|
|
|
/// AddressOf for *const pointer.
|
|
|
|
AddressOf,
|
2023-04-25 20:09:54 +00:00
|
|
|
/// PlaceMention statement.
|
2023-04-29 16:16:41 +00:00
|
|
|
///
|
|
|
|
/// This statement is executed as a check that the `Place` is live without reading from it,
|
|
|
|
/// so it must be considered as a non-mutating use.
|
2023-04-25 20:09:54 +00:00
|
|
|
PlaceMention,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Used as base for another place, e.g., `x` in `x.y`. Will not mutate the place.
|
2018-10-26 13:22:45 +02:00
|
|
|
/// For example, the projection `x.y` is not marked as a mutation in these cases:
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```ignore (illustrative)
|
|
|
|
/// z = x.y;
|
|
|
|
/// f(&x.y);
|
|
|
|
/// ```
|
2018-10-26 13:22:45 +02:00
|
|
|
Projection,
|
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2019-04-24 19:41:43 +01:00
|
|
|
pub enum MutatingUseContext {
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Appears as LHS of an assignment.
|
|
|
|
Store,
|
2022-04-11 06:04:53 -04:00
|
|
|
/// Appears on `SetDiscriminant`
|
|
|
|
SetDiscriminant,
|
|
|
|
/// Appears on `Deinit`
|
|
|
|
Deinit,
|
2021-08-30 01:23:33 +01:00
|
|
|
/// Output operand of an inline assembly block.
|
2017-12-19 17:05:14 -05:00
|
|
|
AsmOutput,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Destination of a call.
|
2016-04-04 19:21:27 +12:00
|
|
|
Call,
|
2020-04-02 10:54:24 -07:00
|
|
|
/// Destination of a yield.
|
|
|
|
Yield,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Being dropped.
|
2016-01-07 05:49:46 -05:00
|
|
|
Drop,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Mutable borrow.
|
2019-04-24 19:41:43 +01:00
|
|
|
Borrow,
|
2018-12-23 19:00:58 +00:00
|
|
|
/// AddressOf for *mut pointer.
|
|
|
|
AddressOf,
|
2018-11-27 02:59:49 +00:00
|
|
|
/// Used as base for another place, e.g., `x` in `x.y`. Could potentially mutate the place.
|
2018-10-26 13:22:45 +02:00
|
|
|
/// For example, the projection `x.y` is marked as a mutation in these cases:
|
2022-04-15 15:04:34 -07:00
|
|
|
/// ```ignore (illustrative)
|
|
|
|
/// x.y = ...;
|
|
|
|
/// f(&mut x.y);
|
|
|
|
/// ```
|
2018-10-26 13:22:45 +02:00
|
|
|
Projection,
|
2018-11-06 11:04:10 +01:00
|
|
|
/// Retagging, a "Stacked Borrows" shadow state operation
|
2018-10-24 11:47:17 +02:00
|
|
|
Retag,
|
2018-10-26 13:22:45 +02:00
|
|
|
}
|
2015-12-08 14:09:16 -05:00
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
|
|
pub enum NonUseContext {
|
|
|
|
/// Starting a storage live range.
|
2016-08-14 06:34:14 +03:00
|
|
|
StorageLive,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Ending a storage live range.
|
2016-08-14 06:34:14 +03:00
|
|
|
StorageDead,
|
2018-10-26 13:22:45 +02:00
|
|
|
/// User type annotation assertions for NLL.
|
2023-05-08 23:38:54 +03:00
|
|
|
AscribeUserTy(ty::Variance),
|
2021-08-22 18:15:49 +02:00
|
|
|
/// The data of a user variable, for debug info.
|
2018-05-16 18:58:54 +03:00
|
|
|
VarDebugInfo,
|
2015-12-08 14:09:16 -05:00
|
|
|
}
|
2016-09-15 18:18:40 -07:00
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2019-04-24 19:41:43 +01:00
|
|
|
pub enum PlaceContext {
|
|
|
|
NonMutatingUse(NonMutatingUseContext),
|
|
|
|
MutatingUse(MutatingUseContext),
|
2018-10-26 13:22:45 +02:00
|
|
|
NonUse(NonUseContext),
|
|
|
|
}
|
|
|
|
|
2019-06-11 12:21:38 +03:00
|
|
|
impl PlaceContext {
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Returns `true` if this place context represents a drop.
|
2021-02-26 00:00:00 +00:00
|
|
|
#[inline]
|
2016-09-15 18:18:40 -07:00
|
|
|
pub fn is_drop(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
matches!(self, PlaceContext::MutatingUse(MutatingUseContext::Drop))
|
2018-10-26 13:22:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if this place context represents a borrow.
|
|
|
|
pub fn is_borrow(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
matches!(
|
|
|
|
self,
|
2020-04-16 17:38:52 -07:00
|
|
|
PlaceContext::NonMutatingUse(
|
2023-05-29 17:15:48 +02:00
|
|
|
NonMutatingUseContext::SharedBorrow | NonMutatingUseContext::ShallowBorrow
|
2020-09-21 04:53:44 +02:00
|
|
|
) | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
|
|
|
|
)
|
2016-09-15 18:18:40 -07:00
|
|
|
}
|
|
|
|
|
2022-10-07 01:10:10 +02:00
|
|
|
/// Returns `true` if this place context represents an address-of.
|
|
|
|
pub fn is_address_of(&self) -> bool {
|
|
|
|
matches!(
|
|
|
|
self,
|
|
|
|
PlaceContext::NonMutatingUse(NonMutatingUseContext::AddressOf)
|
|
|
|
| PlaceContext::MutatingUse(MutatingUseContext::AddressOf)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Returns `true` if this place context represents a storage live or storage dead marker.
|
2021-02-26 00:00:00 +00:00
|
|
|
#[inline]
|
2016-09-15 18:18:40 -07:00
|
|
|
pub fn is_storage_marker(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
matches!(
|
|
|
|
self,
|
|
|
|
PlaceContext::NonUse(NonUseContext::StorageLive | NonUseContext::StorageDead)
|
|
|
|
)
|
2016-09-15 18:18:40 -07:00
|
|
|
}
|
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Returns `true` if this place context represents a use that potentially changes the value.
|
2021-02-26 00:00:00 +00:00
|
|
|
#[inline]
|
2016-09-15 18:18:40 -07:00
|
|
|
pub fn is_mutating_use(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
matches!(self, PlaceContext::MutatingUse(..))
|
2016-09-15 18:18:40 -07:00
|
|
|
}
|
|
|
|
|
2018-10-26 13:22:45 +02:00
|
|
|
/// Returns `true` if this place context represents a use.
|
2021-02-26 00:00:00 +00:00
|
|
|
#[inline]
|
2016-09-15 18:18:40 -07:00
|
|
|
pub fn is_use(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
!matches!(self, PlaceContext::NonUse(..))
|
2018-10-26 13:22:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `true` if this place context represents an assignment statement.
|
|
|
|
pub fn is_place_assignment(&self) -> bool {
|
2020-09-21 04:53:44 +02:00
|
|
|
matches!(
|
|
|
|
self,
|
2020-04-16 17:38:52 -07:00
|
|
|
PlaceContext::MutatingUse(
|
|
|
|
MutatingUseContext::Store
|
2020-09-21 04:53:44 +02:00
|
|
|
| MutatingUseContext::Call
|
|
|
|
| MutatingUseContext::AsmOutput,
|
|
|
|
)
|
|
|
|
)
|
2016-09-15 18:18:40 -07:00
|
|
|
}
|
|
|
|
}
|