Merge from rustc
This commit is contained in:
commit
4bd2757b4c
290 changed files with 2907 additions and 2219 deletions
18
Cargo.lock
18
Cargo.lock
|
|
@ -986,14 +986,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
name = "derive-where"
|
||||
version = "1.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
checksum = "62d671cc41a825ebabc75757b62d3d168c577f9149b2d49ece1dad1f72119d25"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
"syn 2.0.67",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -3882,7 +3882,6 @@ dependencies = [
|
|||
"termcolor",
|
||||
"termize",
|
||||
"tracing",
|
||||
"unicode-width",
|
||||
"windows",
|
||||
]
|
||||
|
||||
|
|
@ -4249,7 +4248,7 @@ name = "rustc_middle"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"derive-where",
|
||||
"either",
|
||||
"field-offset",
|
||||
"gsgdt",
|
||||
|
|
@ -4379,7 +4378,7 @@ name = "rustc_next_trait_solver"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"derive-where",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_index",
|
||||
|
|
@ -4629,7 +4628,7 @@ dependencies = [
|
|||
name = "rustc_span"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"derivative",
|
||||
"derive-where",
|
||||
"indexmap",
|
||||
"itoa",
|
||||
"md-5",
|
||||
|
|
@ -4769,7 +4768,7 @@ name = "rustc_type_ir"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"derivative",
|
||||
"derive-where",
|
||||
"indexmap",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
|
|
@ -5206,6 +5205,7 @@ name = "stable_mir"
|
|||
version = "0.1.0-preview"
|
||||
dependencies = [
|
||||
"scoped-tls",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Version 1.80 (2024-07-25)
|
||||
Version 1.80.0 (2024-07-25)
|
||||
==========================
|
||||
|
||||
<a id="1.80-Language"></a>
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
|||
use rustc_span::source_map::{respan, Spanned};
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
use std::cmp;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
|
@ -2264,6 +2265,42 @@ bitflags::bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
impl InlineAsmOptions {
|
||||
pub fn human_readable_names(&self) -> Vec<&'static str> {
|
||||
let mut options = vec![];
|
||||
|
||||
if self.contains(InlineAsmOptions::PURE) {
|
||||
options.push("pure");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::NOMEM) {
|
||||
options.push("nomem");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::READONLY) {
|
||||
options.push("readonly");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
options.push("preserves_flags");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::NORETURN) {
|
||||
options.push("noreturn");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::NOSTACK) {
|
||||
options.push("nostack");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
options.push("att_syntax");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::RAW) {
|
||||
options.push("raw");
|
||||
}
|
||||
if self.contains(InlineAsmOptions::MAY_UNWIND) {
|
||||
options.push("may_unwind");
|
||||
}
|
||||
|
||||
options
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for InlineAsmOptions {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
bitflags::parser::to_writer(self, f)
|
||||
|
|
@ -2272,7 +2309,7 @@ impl std::fmt::Debug for InlineAsmOptions {
|
|||
|
||||
#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Hash, HashStable_Generic)]
|
||||
pub enum InlineAsmTemplatePiece {
|
||||
String(String),
|
||||
String(Cow<'static, str>),
|
||||
Placeholder { operand_idx: usize, modifier: Option<char>, span: Span },
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -155,8 +155,6 @@ ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters
|
|||
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
|
||||
.help = remove one of these features
|
||||
|
||||
ast_passes_incompatible_trait_bound_modifiers = `{$left}` and `{$right}` are mutually exclusive
|
||||
|
||||
ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation}
|
||||
.because = {$annotation} because of this
|
||||
.type = inherent impl for this type
|
||||
|
|
|
|||
|
|
@ -1366,17 +1366,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
{
|
||||
self.dcx().emit_err(errors::TildeConstDisallowed { span, reason });
|
||||
}
|
||||
(
|
||||
_,
|
||||
BoundConstness::Always(_) | BoundConstness::Maybe(_),
|
||||
BoundPolarity::Negative(_) | BoundPolarity::Maybe(_),
|
||||
) => {
|
||||
self.dcx().emit_err(errors::IncompatibleTraitBoundModifiers {
|
||||
span: bound.span(),
|
||||
left: modifiers.constness.as_str(),
|
||||
right: modifiers.polarity.as_str(),
|
||||
});
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -656,15 +656,6 @@ pub enum TildeConstReason {
|
|||
Item,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_incompatible_trait_bound_modifiers)]
|
||||
pub struct IncompatibleTraitBoundModifiers {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub left: &'static str,
|
||||
pub right: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes_const_and_async)]
|
||||
pub struct ConstAndAsync {
|
||||
|
|
|
|||
|
|
@ -1505,35 +1505,7 @@ impl<'a> State<'a> {
|
|||
AsmArg::Options(opts) => {
|
||||
s.word("options");
|
||||
s.popen();
|
||||
let mut options = vec![];
|
||||
if opts.contains(InlineAsmOptions::PURE) {
|
||||
options.push("pure");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOMEM) {
|
||||
options.push("nomem");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::READONLY) {
|
||||
options.push("readonly");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
options.push("preserves_flags");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NORETURN) {
|
||||
options.push("noreturn");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::NOSTACK) {
|
||||
options.push("nostack");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::ATT_SYNTAX) {
|
||||
options.push("att_syntax");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::RAW) {
|
||||
options.push("raw");
|
||||
}
|
||||
if opts.contains(InlineAsmOptions::MAY_UNWIND) {
|
||||
options.push("may_unwind");
|
||||
}
|
||||
s.commasep(Inconsistent, &options, |s, &opt| {
|
||||
s.commasep(Inconsistent, &opts.human_readable_names(), |s, &opt| {
|
||||
s.word(opt);
|
||||
});
|
||||
s.pclose();
|
||||
|
|
|
|||
|
|
@ -4304,17 +4304,35 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
|||
// search for relevant arguments.
|
||||
let mut arguments = Vec::new();
|
||||
for (index, argument) in sig.inputs().skip_binder().iter().enumerate() {
|
||||
if let ty::Ref(argument_region, _, _) = argument.kind() {
|
||||
if argument_region == return_region {
|
||||
// Need to use the `rustc_middle::ty` types to compare against the
|
||||
// `return_region`. Then use the `rustc_hir` type to get only
|
||||
// the lifetime span.
|
||||
if let hir::TyKind::Ref(lifetime, _) = &fn_decl.inputs[index].kind {
|
||||
if let ty::Ref(argument_region, _, _) = argument.kind()
|
||||
&& argument_region == return_region
|
||||
{
|
||||
// Need to use the `rustc_middle::ty` types to compare against the
|
||||
// `return_region`. Then use the `rustc_hir` type to get only
|
||||
// the lifetime span.
|
||||
match &fn_decl.inputs[index].kind {
|
||||
hir::TyKind::Ref(lifetime, _) => {
|
||||
// With access to the lifetime, we can get
|
||||
// the span of it.
|
||||
arguments.push((*argument, lifetime.ident.span));
|
||||
} else {
|
||||
bug!("ty type is a ref but hir type is not");
|
||||
}
|
||||
// Resolve `self` whose self type is `&T`.
|
||||
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => {
|
||||
if let Res::SelfTyAlias { alias_to, .. } = path.res
|
||||
&& let Some(alias_to) = alias_to.as_local()
|
||||
&& let hir::Impl { self_ty, .. } = self
|
||||
.infcx
|
||||
.tcx
|
||||
.hir_node_by_def_id(alias_to)
|
||||
.expect_item()
|
||||
.expect_impl()
|
||||
&& let hir::TyKind::Ref(lifetime, _) = self_ty.kind
|
||||
{
|
||||
arguments.push((*argument, lifetime.ident.span));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Don't ICE though. It might be a type alias.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ fn expand_preparsed_asm(
|
|||
|
||||
for (i, template_expr) in args.templates.into_iter().enumerate() {
|
||||
if i != 0 {
|
||||
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
|
||||
template.push(ast::InlineAsmTemplatePiece::String("\n".into()));
|
||||
}
|
||||
|
||||
let msg = "asm template must be a string literal";
|
||||
|
|
@ -527,7 +527,7 @@ fn expand_preparsed_asm(
|
|||
|
||||
// Don't treat raw asm as a format string.
|
||||
if args.options.contains(ast::InlineAsmOptions::RAW) {
|
||||
template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string()));
|
||||
template.push(ast::InlineAsmTemplatePiece::String(template_str.to_string().into()));
|
||||
let template_num_lines = 1 + template_str.matches('\n').count();
|
||||
line_spans.extend(std::iter::repeat(template_sp).take(template_num_lines));
|
||||
continue;
|
||||
|
|
@ -577,7 +577,7 @@ fn expand_preparsed_asm(
|
|||
for piece in unverified_pieces {
|
||||
match piece {
|
||||
parse::Piece::String(s) => {
|
||||
template.push(ast::InlineAsmTemplatePiece::String(s.to_string()))
|
||||
template.push(ast::InlineAsmTemplatePiece::String(s.to_string().into()))
|
||||
}
|
||||
parse::Piece::NextArgument(arg) => {
|
||||
let span = arg_spans.next().unwrap_or(template_sp);
|
||||
|
|
|
|||
|
|
@ -46,9 +46,7 @@ pub(crate) fn codegen_inline_asm_terminator<'tcx>(
|
|||
// Used by panic_abort on Windows, but uses a syntax which only happens to work with
|
||||
// asm!() by accident and breaks with the GNU assembler as well as global_asm!() for
|
||||
// the LLVM backend.
|
||||
if template.len() == 1
|
||||
&& template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string())
|
||||
{
|
||||
if template.len() == 1 && template[0] == InlineAsmTemplatePiece::String("int $$0x29".into()) {
|
||||
fx.bcx.ins().trap(TrapCode::User(1));
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
shl rdx, 32
|
||||
or rax, rdx
|
||||
"
|
||||
.to_string(),
|
||||
.into(),
|
||||
)],
|
||||
&[
|
||||
CInlineAsmOperand::In {
|
||||
|
|
@ -471,7 +471,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
// into 0x80000000 for which Cranelift doesn't have a native instruction.
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("cvtps2dq xmm0, xmm0"))],
|
||||
&[InlineAsmTemplatePiece::String("cvtps2dq xmm0, xmm0".into())],
|
||||
&[CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
_late: true,
|
||||
|
|
@ -875,7 +875,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(asm.to_string())],
|
||||
&[InlineAsmTemplatePiece::String(asm.into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
|
||||
|
|
@ -914,7 +914,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("pcmpestri xmm0, xmm1, {imm8}"))],
|
||||
&[InlineAsmTemplatePiece::String(format!("pcmpestri xmm0, xmm1, {imm8}").into())],
|
||||
&[
|
||||
CInlineAsmOperand::In {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -967,7 +967,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("pcmpestrm xmm0, xmm1, {imm8}"))],
|
||||
&[InlineAsmTemplatePiece::String(format!("pcmpestrm xmm0, xmm1, {imm8}").into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1015,7 +1015,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}"))],
|
||||
&[InlineAsmTemplatePiece::String(format!("pclmulqdq xmm0, xmm1, {imm8}").into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1052,7 +1052,9 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("aeskeygenassist xmm0, xmm0, {imm8}"))],
|
||||
&[InlineAsmTemplatePiece::String(
|
||||
format!("aeskeygenassist xmm0, xmm0, {imm8}").into(),
|
||||
)],
|
||||
&[CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
_late: true,
|
||||
|
|
@ -1071,7 +1073,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("aesimc xmm0, xmm0".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("aesimc xmm0, xmm0".into())],
|
||||
&[CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
_late: true,
|
||||
|
|
@ -1091,7 +1093,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("aesenc xmm0, xmm1".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("aesenc xmm0, xmm1".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1117,7 +1119,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("aesenclast xmm0, xmm1".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("aesenclast xmm0, xmm1".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1143,7 +1145,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("aesdec xmm0, xmm1".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("aesdec xmm0, xmm1".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1169,7 +1171,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("aesdeclast xmm0, xmm1".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("aesdeclast xmm0, xmm1".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm0)),
|
||||
|
|
@ -1207,7 +1209,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String(format!("sha1rnds4 xmm1, xmm2, {func}"))],
|
||||
&[InlineAsmTemplatePiece::String(format!("sha1rnds4 xmm1, xmm2, {func}").into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1233,7 +1235,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha1msg1 xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha1msg1 xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1259,7 +1261,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha1msg2 xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha1msg2 xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1285,7 +1287,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha1nexte xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha1nexte xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1312,7 +1314,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha256rnds2 xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha256rnds2 xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1343,7 +1345,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha256msg1 xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha256msg1 xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1369,7 +1371,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("sha256msg2 xmm1, xmm2".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("sha256msg2 xmm1, xmm2".into())],
|
||||
&[
|
||||
CInlineAsmOperand::InOut {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::xmm1)),
|
||||
|
|
@ -1435,7 +1437,7 @@ pub(crate) fn codegen_x86_llvm_intrinsic_call<'tcx>(
|
|||
let edx_place = res_place.place_field(fx, FieldIdx::new(1));
|
||||
codegen_inline_asm_inner(
|
||||
fx,
|
||||
&[InlineAsmTemplatePiece::String("rdtsc".to_string())],
|
||||
&[InlineAsmTemplatePiece::String("rdtsc".into())],
|
||||
&[
|
||||
CInlineAsmOperand::Out {
|
||||
reg: InlineAsmRegOrRegClass::Reg(InlineAsmReg::X86(X86InlineAsmReg::ax)),
|
||||
|
|
|
|||
|
|
@ -330,7 +330,7 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
|
||||
// If this assertion triggers, there's something wrong with commandline
|
||||
// argument validation.
|
||||
debug_assert!(
|
||||
assert!(
|
||||
!(self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
|
||||
&& self.tcx.sess.target.is_like_windows
|
||||
&& self.tcx.sess.opts.cg.prefer_dynamic)
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
) -> DINodeCreationResult<'ll> {
|
||||
// The debuginfo generated by this function is only valid if `ptr_type` is really just
|
||||
// a (fat) pointer. Make sure it is not called for e.g. `Box<T, NonZSTAllocator>`.
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_and_align_of(ptr_type),
|
||||
cx.size_and_align_of(Ty::new_mut_ptr(cx.tcx, pointee_type))
|
||||
);
|
||||
|
|
@ -185,7 +185,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
match fat_pointer_kind(cx, pointee_type) {
|
||||
None => {
|
||||
// This is a thin pointer. Create a regular pointer type and give it the correct name.
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
(data_layout.pointer_size, data_layout.pointer_align.abi),
|
||||
cx.size_and_align_of(ptr_type),
|
||||
"ptr_type={ptr_type}, pointee_type={pointee_type}",
|
||||
|
|
@ -240,8 +240,8 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
|
|||
FatPtrKind::Slice => ("data_ptr", "length"),
|
||||
};
|
||||
|
||||
debug_assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
debug_assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
assert_eq!(abi::FAT_PTR_ADDR, 0);
|
||||
assert_eq!(abi::FAT_PTR_EXTRA, 1);
|
||||
|
||||
// The data pointer type is a regular, thin pointer, regardless of whether this
|
||||
// is a slice or a trait object.
|
||||
|
|
@ -498,7 +498,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
|
|||
}
|
||||
};
|
||||
|
||||
debug_assert_eq!(di_node_for_uid as *const _, di_node as *const _);
|
||||
assert_eq!(di_node_for_uid as *const _, di_node as *const _);
|
||||
} else {
|
||||
debug_context(cx).type_map.insert(unique_type_id, di_node);
|
||||
}
|
||||
|
|
@ -1060,7 +1060,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
|
|||
let ty::Adt(adt_def, _) = struct_type.kind() else {
|
||||
bug!("build_struct_type_di_node() called with non-struct-type: {:?}", struct_type);
|
||||
};
|
||||
debug_assert!(adt_def.is_struct());
|
||||
assert!(adt_def.is_struct());
|
||||
let containing_scope = get_namespace_for_item(cx, adt_def.did());
|
||||
let struct_type_and_layout = cx.layout_of(struct_type);
|
||||
let variant_def = adt_def.non_enum_variant();
|
||||
|
|
@ -1130,7 +1130,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
|
|||
}
|
||||
};
|
||||
|
||||
debug_assert!(
|
||||
assert!(
|
||||
up_var_tys.iter().all(|t| t == cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
let enum_type_and_layout = cx.layout_of(enum_type);
|
||||
let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
|
@ -279,7 +279,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
|
@ -517,7 +517,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
|||
if is_128_bits {
|
||||
DiscrKind::Exact128(discr_val)
|
||||
} else {
|
||||
debug_assert_eq!(discr_val, discr_val as u64 as u128);
|
||||
assert_eq!(discr_val, discr_val as u64 as u128);
|
||||
DiscrKind::Exact(discr_val as u64)
|
||||
}
|
||||
}
|
||||
|
|
@ -526,8 +526,8 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
|
|||
if is_128_bits {
|
||||
DiscrKind::Range128(min, max)
|
||||
} else {
|
||||
debug_assert_eq!(min, min as u64 as u128);
|
||||
debug_assert_eq!(max, max as u64 as u128);
|
||||
assert_eq!(min, min as u64 as u128);
|
||||
assert_eq!(max, max as u64 as u128);
|
||||
DiscrKind::Range(min as u64, max as u64)
|
||||
}
|
||||
}
|
||||
|
|
@ -815,7 +815,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
|
|||
}
|
||||
}));
|
||||
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
|
||||
cx.size_and_align_of(super::tag_base_type(cx, enum_type_and_layout))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ fn tag_base_type<'ll, 'tcx>(
|
|||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
enum_type_and_layout: TyAndLayout<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert!(match enum_type_and_layout.ty.kind() {
|
||||
assert!(match enum_type_and_layout.ty.kind() {
|
||||
ty::Coroutine(..) => true,
|
||||
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
||||
_ => false,
|
||||
|
|
@ -251,7 +251,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
|
|||
variant_layout: TyAndLayout<'tcx>,
|
||||
di_flags: DIFlags,
|
||||
) -> &'ll DIType {
|
||||
debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
|
||||
assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
|
|||
|
||||
let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
|
||||
|
||||
type_map::build_type_with_children(
|
||||
cx,
|
||||
|
|
@ -142,7 +142,7 @@ pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
|
|||
let containing_scope = get_namespace_for_item(cx, coroutine_def_id);
|
||||
let coroutine_type_and_layout = cx.layout_of(coroutine_type);
|
||||
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
|
||||
|
||||
let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ mod private {
|
|||
|
||||
/// A unique identifier for anything that we create a debuginfo node for.
|
||||
/// The types it contains are expected to already be normalized (which
|
||||
/// is debug_asserted in the constructors).
|
||||
/// is asserted in the constructors).
|
||||
///
|
||||
/// Note that there are some things that only show up in debuginfo, like
|
||||
/// the separate type descriptions for each enum variant. These get an ID
|
||||
|
|
@ -58,12 +58,12 @@ pub(super) enum UniqueTypeId<'tcx> {
|
|||
|
||||
impl<'tcx> UniqueTypeId<'tcx> {
|
||||
pub fn for_ty(tcx: TyCtxt<'tcx>, t: Ty<'tcx>) -> Self {
|
||||
debug_assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
|
||||
assert_eq!(t, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t));
|
||||
UniqueTypeId::Ty(t, private::HiddenZst)
|
||||
}
|
||||
|
||||
pub fn for_enum_variant_part(tcx: TyCtxt<'tcx>, enum_ty: Ty<'tcx>) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantPart(enum_ty, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantStructType(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
enum_ty: Ty<'tcx>,
|
||||
variant_idx: VariantIdx,
|
||||
) -> Self {
|
||||
debug_assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
assert_eq!(enum_ty, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), enum_ty));
|
||||
UniqueTypeId::VariantStructTypeCppLikeWrapper(enum_ty, variant_idx, private::HiddenZst)
|
||||
}
|
||||
|
||||
|
|
@ -90,11 +90,8 @@ impl<'tcx> UniqueTypeId<'tcx> {
|
|||
self_type: Ty<'tcx>,
|
||||
implemented_trait: Option<PolyExistentialTraitRef<'tcx>>,
|
||||
) -> Self {
|
||||
debug_assert_eq!(
|
||||
self_type,
|
||||
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type)
|
||||
);
|
||||
debug_assert_eq!(
|
||||
assert_eq!(self_type, tcx.normalize_erasing_regions(ParamEnv::reveal_all(), self_type));
|
||||
assert_eq!(
|
||||
implemented_trait,
|
||||
tcx.normalize_erasing_regions(ParamEnv::reveal_all(), implemented_trait)
|
||||
);
|
||||
|
|
@ -252,10 +249,7 @@ pub(super) fn build_type_with_children<'ll, 'tcx>(
|
|||
members: impl FnOnce(&CodegenCx<'ll, 'tcx>, &'ll DIType) -> SmallVec<&'ll DIType>,
|
||||
generics: impl FnOnce(&CodegenCx<'ll, 'tcx>) -> SmallVec<&'ll DIType>,
|
||||
) -> DINodeCreationResult<'ll> {
|
||||
debug_assert_eq!(
|
||||
debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id),
|
||||
None
|
||||
);
|
||||
assert_eq!(debug_context(cx).type_map.di_node_for_unique_id(stub_info.unique_type_id), None);
|
||||
|
||||
debug_context(cx).type_map.insert(stub_info.unique_type_id, stub_info.metadata);
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>(
|
|||
ty::Dynamic(..) => Some(FatPtrKind::Dyn),
|
||||
ty::Foreign(_) => {
|
||||
// Assert that pointers to foreign types really are thin:
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
cx.size_of(Ty::new_imm_ptr(cx.tcx, pointee_tail_ty)),
|
||||
cx.size_of(Ty::new_imm_ptr(cx.tcx, cx.tcx.types.u8))
|
||||
);
|
||||
|
|
|
|||
|
|
@ -305,7 +305,6 @@ pub enum TypeKind {
|
|||
Pointer = 12,
|
||||
Vector = 13,
|
||||
Metadata = 14,
|
||||
X86_MMX = 15,
|
||||
Token = 16,
|
||||
ScalableVector = 17,
|
||||
BFloat = 18,
|
||||
|
|
@ -330,7 +329,6 @@ impl TypeKind {
|
|||
TypeKind::Pointer => rustc_codegen_ssa::common::TypeKind::Pointer,
|
||||
TypeKind::Vector => rustc_codegen_ssa::common::TypeKind::Vector,
|
||||
TypeKind::Metadata => rustc_codegen_ssa::common::TypeKind::Metadata,
|
||||
TypeKind::X86_MMX => rustc_codegen_ssa::common::TypeKind::X86_MMX,
|
||||
TypeKind::Token => rustc_codegen_ssa::common::TypeKind::Token,
|
||||
TypeKind::ScalableVector => rustc_codegen_ssa::common::TypeKind::ScalableVector,
|
||||
TypeKind::BFloat => rustc_codegen_ssa::common::TypeKind::BFloat,
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ fn exported_symbols_provider_local(
|
|||
}
|
||||
MonoItem::Fn(Instance { def: InstanceKind::DropGlue(def_id, Some(ty)), args }) => {
|
||||
// A little sanity-check
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
args.non_erasable_generics(tcx, def_id).next(),
|
||||
Some(GenericArgKind::Type(ty))
|
||||
);
|
||||
|
|
@ -370,7 +370,7 @@ fn exported_symbols_provider_local(
|
|||
args,
|
||||
}) => {
|
||||
// A little sanity-check
|
||||
debug_assert_eq!(
|
||||
assert_eq!(
|
||||
args.non_erasable_generics(tcx, def_id).next(),
|
||||
Some(GenericArgKind::Type(ty))
|
||||
);
|
||||
|
|
@ -462,7 +462,7 @@ fn upstream_monomorphizations_for_provider(
|
|||
tcx: TyCtxt<'_>,
|
||||
def_id: DefId,
|
||||
) -> Option<&UnordMap<GenericArgsRef<'_>, CrateNum>> {
|
||||
debug_assert!(!def_id.is_local());
|
||||
assert!(!def_id.is_local());
|
||||
tcx.upstream_monomorphizations(()).get(&def_id)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1512,7 +1512,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
|||
// We reduce the `running` counter by one. The
|
||||
// `tokens.truncate()` below will take care of
|
||||
// giving the Token back.
|
||||
debug_assert!(running_with_own_token > 0);
|
||||
assert!(running_with_own_token > 0);
|
||||
running_with_own_token -= 1;
|
||||
main_thread_state = MainThreadState::Lending;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -91,7 +91,6 @@ pub enum TypeKind {
|
|||
Pointer,
|
||||
Vector,
|
||||
Metadata,
|
||||
X86_MMX,
|
||||
Token,
|
||||
ScalableVector,
|
||||
BFloat,
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||
output: &mut String,
|
||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||
) {
|
||||
debug_assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
|
||||
assert!(!wants_c_like_enum_debuginfo(ty_and_layout));
|
||||
output.push_str("enum2$<");
|
||||
push_inner(output, visited);
|
||||
push_close_angle_bracket(true, output);
|
||||
|
|
@ -660,7 +660,7 @@ fn push_generic_params_internal<'tcx>(
|
|||
output: &mut String,
|
||||
visited: &mut FxHashSet<Ty<'tcx>>,
|
||||
) -> bool {
|
||||
debug_assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||
assert_eq!(args, tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), args));
|
||||
let mut args = args.non_erasable_generics(tcx, def_id).peekable();
|
||||
if args.peek().is_none() {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
|
|||
}
|
||||
if is_cleanupret {
|
||||
// Cross-funclet jump - need a trampoline
|
||||
debug_assert!(base::wants_new_eh_instructions(fx.cx.tcx().sess));
|
||||
assert!(base::wants_new_eh_instructions(fx.cx.tcx().sess));
|
||||
debug!("llbb_with_cleanup: creating cleanup trampoline for {:?}", target);
|
||||
let name = &format!("{:?}_cleanup_trampoline_{:?}", self.bb, target);
|
||||
let trampoline_llbb = Bx::append_block(fx.cx, fx.llfn, name);
|
||||
|
|
|
|||
|
|
@ -194,7 +194,7 @@ fn calculate_debuginfo_offset<
|
|||
}
|
||||
_ => {
|
||||
// Sanity check for `can_use_in_debuginfo`.
|
||||
debug_assert!(!elem.can_use_in_debuginfo());
|
||||
assert!(!elem.can_use_in_debuginfo());
|
||||
bug!("unsupported var debuginfo projection `{:?}`", projection)
|
||||
}
|
||||
}
|
||||
|
|
@ -502,7 +502,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } =
|
||||
calculate_debuginfo_offset(bx, &fragment.projection, var_layout);
|
||||
debug_assert!(indirect_offsets.is_empty());
|
||||
assert!(indirect_offsets.is_empty());
|
||||
|
||||
if fragment_layout.size == Size::ZERO {
|
||||
// Fragment is a ZST, so does not represent anything. Avoid generating anything
|
||||
|
|
|
|||
|
|
@ -565,7 +565,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
for elem in place_ref.projection.iter() {
|
||||
match elem {
|
||||
mir::ProjectionElem::Field(ref f, _) => {
|
||||
debug_assert!(
|
||||
assert!(
|
||||
!o.layout.ty.is_any_ptr(),
|
||||
"Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
|
||||
but tried to access field {f:?} of pointer {o:?}",
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ impl<V: CodegenObject> PlaceValue<V> {
|
|||
|
||||
/// Creates a `PlaceRef` to this location with the given type.
|
||||
pub fn with_type<'tcx>(self, layout: TyAndLayout<'tcx>) -> PlaceRef<'tcx, V> {
|
||||
debug_assert!(
|
||||
assert!(
|
||||
layout.is_unsized() || layout.abi.is_uninhabited() || self.llextra.is_none(),
|
||||
"Had pointer metadata {:?} for sized type {layout:?}",
|
||||
self.llextra,
|
||||
|
|
@ -488,7 +488,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
cg_base = match *elem {
|
||||
mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
|
||||
mir::ProjectionElem::Field(ref field, _) => {
|
||||
debug_assert!(
|
||||
assert!(
|
||||
!cg_base.layout.ty.is_any_ptr(),
|
||||
"Bad PlaceRef: destructing pointers should use cast/PtrMetadata, \
|
||||
but tried to access field {field:?} of pointer {cg_base:?}",
|
||||
|
|
|
|||
|
|
@ -168,8 +168,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
dst: PlaceRef<'tcx, Bx::Value>,
|
||||
) {
|
||||
// The MIR validator enforces no unsized transmutes.
|
||||
debug_assert!(src.layout.is_sized());
|
||||
debug_assert!(dst.layout.is_sized());
|
||||
assert!(src.layout.is_sized());
|
||||
assert!(dst.layout.is_sized());
|
||||
|
||||
if let Some(val) = self.codegen_transmute_operand(bx, src, dst.layout) {
|
||||
val.store(bx, dst);
|
||||
|
|
@ -223,8 +223,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
|
||||
match operand.val {
|
||||
OperandValue::Ref(source_place_val) => {
|
||||
debug_assert_eq!(source_place_val.llextra, None);
|
||||
debug_assert!(matches!(operand_kind, OperandValueKind::Ref));
|
||||
assert_eq!(source_place_val.llextra, None);
|
||||
assert!(matches!(operand_kind, OperandValueKind::Ref));
|
||||
Some(bx.load_operand(source_place_val.with_type(cast)).val)
|
||||
}
|
||||
OperandValue::ZeroSized => {
|
||||
|
|
@ -295,7 +295,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
to_scalar: abi::Scalar,
|
||||
to_backend_ty: Bx::Type,
|
||||
) -> Bx::Value {
|
||||
debug_assert_eq!(from_scalar.size(self.cx), to_scalar.size(self.cx));
|
||||
assert_eq!(from_scalar.size(self.cx), to_scalar.size(self.cx));
|
||||
|
||||
use abi::Primitive::*;
|
||||
imm = bx.from_immediate(imm);
|
||||
|
|
@ -639,9 +639,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
(OperandValue::Immediate(llval), operand.layout)
|
||||
}
|
||||
mir::UnOp::PtrMetadata => {
|
||||
debug_assert!(
|
||||
operand.layout.ty.is_unsafe_ptr() || operand.layout.ty.is_ref(),
|
||||
);
|
||||
assert!(operand.layout.ty.is_unsafe_ptr() || operand.layout.ty.is_ref(),);
|
||||
let (_, meta) = operand.val.pointer_parts();
|
||||
assert_eq!(operand.layout.fields.count() > 1, meta.is_some());
|
||||
if let Some(meta) = meta {
|
||||
|
|
@ -651,7 +649,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
}
|
||||
};
|
||||
debug_assert!(
|
||||
assert!(
|
||||
val.is_expected_variant_for_type(self.cx, layout),
|
||||
"Made wrong variant {val:?} for type {layout:?}",
|
||||
);
|
||||
|
|
@ -742,7 +740,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bug!("Field {field_idx:?} is {p:?} making {layout:?}");
|
||||
});
|
||||
let scalars = self.value_kind(op.layout).scalars().unwrap();
|
||||
debug_assert_eq!(values.len(), scalars.len());
|
||||
assert_eq!(values.len(), scalars.len());
|
||||
inputs.extend(values);
|
||||
input_scalars.extend(scalars);
|
||||
}
|
||||
|
|
@ -760,7 +758,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
);
|
||||
|
||||
let val = OperandValue::from_immediates(inputs);
|
||||
debug_assert!(
|
||||
assert!(
|
||||
val.is_expected_variant_for_type(self.cx, layout),
|
||||
"Made wrong variant {val:?} for type {layout:?}",
|
||||
);
|
||||
|
|
@ -805,7 +803,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
let val = cg_place.val.address();
|
||||
|
||||
let ty = cg_place.layout.ty;
|
||||
debug_assert!(
|
||||
assert!(
|
||||
if bx.cx().type_has_metadata(ty) {
|
||||
matches!(val, OperandValue::Pair(..))
|
||||
} else {
|
||||
|
|
@ -927,7 +925,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
}
|
||||
mir::BinOp::Cmp => {
|
||||
use std::cmp::Ordering;
|
||||
debug_assert!(!is_float);
|
||||
assert!(!is_float);
|
||||
let pred = |op| base::bin_op_to_icmp_predicate(op, is_signed);
|
||||
if bx.cx().tcx().sess.opts.optimize == OptLevel::No {
|
||||
// FIXME: This actually generates tighter assembly, and is a classic trick
|
||||
|
|
@ -1111,7 +1109,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
if layout.is_zst() {
|
||||
OperandValueKind::ZeroSized
|
||||
} else if self.cx.is_backend_immediate(layout) {
|
||||
debug_assert!(!self.cx.is_backend_scalar_pair(layout));
|
||||
assert!(!self.cx.is_backend_scalar_pair(layout));
|
||||
OperandValueKind::Immediate(match layout.abi {
|
||||
abi::Abi::Scalar(s) => s,
|
||||
abi::Abi::Vector { element, .. } => element,
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
size: Size,
|
||||
) -> Self::Value;
|
||||
fn load_from_place(&mut self, ty: Self::Type, place: PlaceValue<Self::Value>) -> Self::Value {
|
||||
debug_assert_eq!(place.llextra, None);
|
||||
assert_eq!(place.llextra, None);
|
||||
self.load(ty, place.llval, place.align)
|
||||
}
|
||||
fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>)
|
||||
|
|
@ -184,7 +184,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
|
||||
fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value;
|
||||
fn store_to_place(&mut self, val: Self::Value, place: PlaceValue<Self::Value>) -> Self::Value {
|
||||
debug_assert_eq!(place.llextra, None);
|
||||
assert_eq!(place.llextra, None);
|
||||
self.store(val, place.llval, place.align)
|
||||
}
|
||||
fn store_with_flags(
|
||||
|
|
@ -200,7 +200,7 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
place: PlaceValue<Self::Value>,
|
||||
flags: MemFlags,
|
||||
) -> Self::Value {
|
||||
debug_assert_eq!(place.llextra, None);
|
||||
assert_eq!(place.llextra, None);
|
||||
self.store_with_flags(val, place.llval, place.align, flags)
|
||||
}
|
||||
fn atomic_store(
|
||||
|
|
@ -320,9 +320,9 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||
layout: TyAndLayout<'tcx>,
|
||||
flags: MemFlags,
|
||||
) {
|
||||
debug_assert!(layout.is_sized(), "cannot typed-copy an unsigned type");
|
||||
debug_assert!(src.llextra.is_none(), "cannot directly copy from unsized values");
|
||||
debug_assert!(dst.llextra.is_none(), "cannot directly copy into unsized values");
|
||||
assert!(layout.is_sized(), "cannot typed-copy an unsigned type");
|
||||
assert!(src.llextra.is_none(), "cannot directly copy from unsized values");
|
||||
assert!(dst.llextra.is_none(), "cannot directly copy into unsized values");
|
||||
if flags.contains(MemFlags::NONTEMPORAL) {
|
||||
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
|
||||
let ty = self.backend_type(layout);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ use super::{
|
|||
Pointer, Projectable, Scalar, ValueVisitor,
|
||||
};
|
||||
|
||||
// for the validation errors
|
||||
#[rustfmt::skip]
|
||||
use super::InterpError::UndefinedBehavior as Ub;
|
||||
use super::InterpError::Unsupported as Unsup;
|
||||
use super::UndefinedBehaviorInfo::*;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ serde_json = "1.0.59"
|
|||
termcolor = "1.2.0"
|
||||
termize = "0.1.1"
|
||||
tracing = "0.1"
|
||||
unicode-width = "0.1.4"
|
||||
# tidy-alphabetical-end
|
||||
|
||||
[target.'cfg(windows)'.dependencies.windows]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
//! The output types are defined in `rustc_session::config::ErrorOutputType`.
|
||||
|
||||
use rustc_span::source_map::SourceMap;
|
||||
use rustc_span::{FileLines, FileName, SourceFile, Span};
|
||||
use rustc_span::{char_width, FileLines, FileName, SourceFile, Span};
|
||||
|
||||
use crate::snippet::{
|
||||
Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString,
|
||||
|
|
@ -677,10 +677,7 @@ impl HumanEmitter {
|
|||
.skip(left)
|
||||
.take_while(|ch| {
|
||||
// Make sure that the trimming on the right will fall within the terminal width.
|
||||
// FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char`
|
||||
// is. For now, just accept that sometimes the code line will be longer than
|
||||
// desired.
|
||||
let next = unicode_width::UnicodeWidthChar::width(*ch).unwrap_or(1);
|
||||
let next = char_width(*ch);
|
||||
if taken + next > right - left {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -742,11 +739,7 @@ impl HumanEmitter {
|
|||
let left = margin.left(source_string.len());
|
||||
|
||||
// Account for unicode characters of width !=0 that were removed.
|
||||
let left = source_string
|
||||
.chars()
|
||||
.take(left)
|
||||
.map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
|
||||
.sum();
|
||||
let left = source_string.chars().take(left).map(|ch| char_width(ch)).sum();
|
||||
|
||||
self.draw_line(
|
||||
buffer,
|
||||
|
|
@ -2039,7 +2032,7 @@ impl HumanEmitter {
|
|||
let sub_len: usize =
|
||||
if is_whitespace_addition { &part.snippet } else { part.snippet.trim() }
|
||||
.chars()
|
||||
.map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
|
||||
.map(|ch| char_width(ch))
|
||||
.sum();
|
||||
|
||||
let offset: isize = offsets
|
||||
|
|
@ -2076,11 +2069,8 @@ impl HumanEmitter {
|
|||
}
|
||||
|
||||
// length of the code after substitution
|
||||
let full_sub_len = part
|
||||
.snippet
|
||||
.chars()
|
||||
.map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
|
||||
.sum::<usize>() as isize;
|
||||
let full_sub_len =
|
||||
part.snippet.chars().map(|ch| char_width(ch)).sum::<usize>() as isize;
|
||||
|
||||
// length of the code to be substituted
|
||||
let snippet_len = span_end_pos as isize - span_start_pos as isize;
|
||||
|
|
@ -2568,18 +2558,53 @@ fn num_decimal_digits(num: usize) -> usize {
|
|||
}
|
||||
|
||||
// We replace some characters so the CLI output is always consistent and underlines aligned.
|
||||
// Keep the following list in sync with `rustc_span::char_width`.
|
||||
const OUTPUT_REPLACEMENTS: &[(char, &str)] = &[
|
||||
('\t', " "), // We do our own tab replacement
|
||||
('\t', " "), // We do our own tab replacement
|
||||
('\u{200D}', ""), // Replace ZWJ with nothing for consistent terminal output of grapheme clusters.
|
||||
('\u{202A}', ""), // The following unicode text flow control characters are inconsistently
|
||||
('\u{202B}', ""), // supported across CLIs and can cause confusion due to the bytes on disk
|
||||
('\u{202D}', ""), // not corresponding to the visible source code, so we replace them always.
|
||||
('\u{202E}', ""),
|
||||
('\u{2066}', ""),
|
||||
('\u{2067}', ""),
|
||||
('\u{2068}', ""),
|
||||
('\u{202C}', ""),
|
||||
('\u{2069}', ""),
|
||||
('\u{202A}', "<EFBFBD>"), // The following unicode text flow control characters are inconsistently
|
||||
('\u{202B}', "<EFBFBD>"), // supported across CLIs and can cause confusion due to the bytes on disk
|
||||
('\u{202D}', "<EFBFBD>"), // not corresponding to the visible source code, so we replace them always.
|
||||
('\u{202E}', "<EFBFBD>"),
|
||||
('\u{2066}', "<EFBFBD>"),
|
||||
('\u{2067}', "<EFBFBD>"),
|
||||
('\u{2068}', "<EFBFBD>"),
|
||||
('\u{202C}', "<EFBFBD>"),
|
||||
('\u{2069}', "<EFBFBD>"),
|
||||
// In terminals without Unicode support the following will be garbled, but in *all* terminals
|
||||
// the underlying codepoint will be as well. We could gate this replacement behind a "unicode
|
||||
// support" gate.
|
||||
('\u{0000}', "␀"),
|
||||
('\u{0001}', "␁"),
|
||||
('\u{0002}', "␂"),
|
||||
('\u{0003}', "␃"),
|
||||
('\u{0004}', "␄"),
|
||||
('\u{0005}', "␅"),
|
||||
('\u{0006}', "␆"),
|
||||
('\u{0007}', "␇"),
|
||||
('\u{0008}', "␈"),
|
||||
('\u{000B}', "␋"),
|
||||
('\u{000C}', "␌"),
|
||||
('\u{000D}', "␍"),
|
||||
('\u{000E}', "␎"),
|
||||
('\u{000F}', "␏"),
|
||||
('\u{0010}', "␐"),
|
||||
('\u{0011}', "␑"),
|
||||
('\u{0012}', "␒"),
|
||||
('\u{0013}', "␓"),
|
||||
('\u{0014}', "␔"),
|
||||
('\u{0015}', "␕"),
|
||||
('\u{0016}', "␖"),
|
||||
('\u{0017}', "␗"),
|
||||
('\u{0018}', "␘"),
|
||||
('\u{0019}', "␙"),
|
||||
('\u{001A}', "␚"),
|
||||
('\u{001B}', "␛"),
|
||||
('\u{001C}', "␜"),
|
||||
('\u{001D}', "␝"),
|
||||
('\u{001E}', "␞"),
|
||||
('\u{001F}', "␟"),
|
||||
('\u{007F}', "␡"),
|
||||
];
|
||||
|
||||
fn normalize_whitespace(str: &str) -> String {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ use rustc_data_structures::fx::FxHashSet;
|
|||
use rustc_errors::{codes::*, struct_span_code_err, ErrorGuaranteed};
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::util::CheckRegions;
|
||||
use rustc_middle::ty::GenericArgsRef;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_middle::ty::{GenericArgsRef, Ty};
|
||||
use rustc_trait_selection::regions::InferCtxtRegionExt;
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
|
||||
|
|
@ -115,8 +115,9 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
|||
Err(err.emit())
|
||||
}
|
||||
|
||||
/// Confirms that every predicate imposed by dtor_predicates is
|
||||
/// implied by assuming the predicates attached to self_type_did.
|
||||
/// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
|
||||
/// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
|
||||
/// implied by the ADT being well formed.
|
||||
fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
drop_impl_def_id: LocalDefId,
|
||||
|
|
@ -126,6 +127,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
|||
let infcx = tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
|
||||
|
||||
let impl_span = tcx.def_span(drop_impl_def_id.to_def_id());
|
||||
|
||||
// Take the param-env of the adt and instantiate the args that show up in
|
||||
// the implementation's self type. This gives us the assumptions that the
|
||||
// self ty of the implementation is allowed to know just from it being a
|
||||
|
|
@ -135,14 +138,27 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
|||
// We don't need to normalize this param-env or anything, since we're only
|
||||
// instantiating it with free params, so no additional param-env normalization
|
||||
// can occur on top of what has been done in the param_env query itself.
|
||||
let param_env =
|
||||
//
|
||||
// Note: Ideally instead of instantiating the `ParamEnv` with the arguments from the impl ty we
|
||||
// could instead use identity args for the adt. Unfortunately this would cause any errors to
|
||||
// reference the params from the ADT instead of from the impl which is bad UX. To resolve
|
||||
// this we "rename" the ADT's params to be the impl's params which should not affect behaviour.
|
||||
let impl_adt_ty = Ty::new_adt(tcx, tcx.adt_def(adt_def_id), adt_to_impl_args);
|
||||
let adt_env =
|
||||
ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);
|
||||
|
||||
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {
|
||||
let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id());
|
||||
let fresh_adt_ty =
|
||||
tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
|
||||
|
||||
ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty)
|
||||
.unwrap();
|
||||
|
||||
for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) {
|
||||
let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
|
||||
let pred = ocx.normalize(&normalize_cause, param_env, pred);
|
||||
let pred = ocx.normalize(&normalize_cause, adt_env, clause);
|
||||
let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl);
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, pred));
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred));
|
||||
}
|
||||
|
||||
// All of the custom error reporting logic is to preserve parity with the old
|
||||
|
|
@ -176,7 +192,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
|||
return Err(guar.unwrap());
|
||||
}
|
||||
|
||||
let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(param_env));
|
||||
let errors = ocx.infcx.resolve_regions(&OutlivesEnvironment::new(adt_env));
|
||||
if !errors.is_empty() {
|
||||
let mut guar = None;
|
||||
for error in errors {
|
||||
|
|
|
|||
|
|
@ -1298,35 +1298,7 @@ impl<'a> State<'a> {
|
|||
AsmArg::Options(opts) => {
|
||||
s.word("options");
|
||||
s.popen();
|
||||
let mut options = vec![];
|
||||
if opts.contains(ast::InlineAsmOptions::PURE) {
|
||||
options.push("pure");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::NOMEM) {
|
||||
options.push("nomem");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::READONLY) {
|
||||
options.push("readonly");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::PRESERVES_FLAGS) {
|
||||
options.push("preserves_flags");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::NORETURN) {
|
||||
options.push("noreturn");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::NOSTACK) {
|
||||
options.push("nostack");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::ATT_SYNTAX) {
|
||||
options.push("att_syntax");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::RAW) {
|
||||
options.push("raw");
|
||||
}
|
||||
if opts.contains(ast::InlineAsmOptions::MAY_UNWIND) {
|
||||
options.push("may_unwind");
|
||||
}
|
||||
s.commasep(Inconsistent, &options, |s, &opt| {
|
||||
s.commasep(Inconsistent, &opts.human_readable_names(), |s, &opt| {
|
||||
s.word(opt);
|
||||
});
|
||||
s.pclose();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ lint_ambiguous_glob_reexport = ambiguous glob re-exports
|
|||
.label_first_reexport = the name `{$name}` in the {$namespace} namespace is first re-exported here
|
||||
.label_duplicate_reexport = but the name `{$name}` in the {$namespace} namespace is also re-exported here
|
||||
|
||||
lint_ambiguous_negative_literals = `-` has lower precedence than method calls, which might be unexpected
|
||||
.example = e.g. `-4.abs()` equals `-4`; while `(-4).abs()` equals `4`
|
||||
.negative_literal = add parentheses around the `-` and the literal to call the method on a negative literal
|
||||
.current_behavior = add parentheses around the literal and the method call to keep the current behavior
|
||||
|
||||
lint_ambiguous_wide_pointer_comparisons = ambiguous wide pointer comparison, the comparison includes metadata which may not be expected
|
||||
.addr_metadata_suggestion = use explicit `std::ptr::eq` method to compare metadata and addresses
|
||||
.addr_suggestion = use `std::ptr::addr_eq` or untyped pointers to only compare their addresses
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ mod noop_method_call;
|
|||
mod opaque_hidden_inferred_bound;
|
||||
mod pass_by_value;
|
||||
mod passes;
|
||||
mod precedence;
|
||||
mod ptr_nulls;
|
||||
mod redundant_semicolon;
|
||||
mod reference_casting;
|
||||
|
|
@ -111,6 +112,7 @@ use nonstandard_style::*;
|
|||
use noop_method_call::*;
|
||||
use opaque_hidden_inferred_bound::*;
|
||||
use pass_by_value::*;
|
||||
use precedence::*;
|
||||
use ptr_nulls::*;
|
||||
use redundant_semicolon::*;
|
||||
use reference_casting::*;
|
||||
|
|
@ -120,6 +122,7 @@ use types::*;
|
|||
use unit_bindings::*;
|
||||
use unused::*;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub use builtin::{MissingDoc, SoftLints};
|
||||
pub use context::{CheckLintNameResult, FindLintError, LintStore};
|
||||
pub use context::{EarlyContext, LateContext, LintContext};
|
||||
|
|
@ -174,6 +177,7 @@ early_lint_methods!(
|
|||
RedundantSemicolons: RedundantSemicolons,
|
||||
UnusedDocComment: UnusedDocComment,
|
||||
Expr2024: Expr2024,
|
||||
Precedence: Precedence,
|
||||
]
|
||||
]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1499,6 +1499,35 @@ pub struct NonLocalDefinitionsCargoUpdateNote {
|
|||
pub crate_name: Symbol,
|
||||
}
|
||||
|
||||
// precedence.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_ambiguous_negative_literals)]
|
||||
#[note(lint_example)]
|
||||
pub struct AmbiguousNegativeLiteralsDiag {
|
||||
#[subdiagnostic]
|
||||
pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
|
||||
#[subdiagnostic]
|
||||
pub current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")]
|
||||
pub struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
|
||||
#[suggestion_part(code = "(")]
|
||||
pub start_span: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub end_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")]
|
||||
pub struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
|
||||
#[suggestion_part(code = "(")]
|
||||
pub start_span: Span,
|
||||
#[suggestion_part(code = ")")]
|
||||
pub end_span: Span,
|
||||
}
|
||||
|
||||
// pass_by_value.rs
|
||||
#[derive(LintDiagnostic)]
|
||||
#[diag(lint_pass_by_value)]
|
||||
|
|
|
|||
70
compiler/rustc_lint/src/precedence.rs
Normal file
70
compiler/rustc_lint/src/precedence.rs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use rustc_ast::token::LitKind;
|
||||
use rustc_ast::{Expr, ExprKind, MethodCall, UnOp};
|
||||
use rustc_session::{declare_lint, declare_lint_pass};
|
||||
|
||||
use crate::lints::{
|
||||
AmbiguousNegativeLiteralsCurrentBehaviorSuggestion, AmbiguousNegativeLiteralsDiag,
|
||||
AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
|
||||
};
|
||||
use crate::{EarlyContext, EarlyLintPass, LintContext};
|
||||
|
||||
declare_lint! {
|
||||
/// The `ambiguous_negative_literals` lint checks for cases that are
|
||||
/// confusing between a negative literal and a negation that's not part
|
||||
/// of the literal.
|
||||
///
|
||||
/// ### Example
|
||||
///
|
||||
/// ```rust,compile_fail
|
||||
/// # #![allow(unused)]
|
||||
/// -1i32.abs(); // equals -1, while `(-1i32).abs()` equals 1
|
||||
/// ```
|
||||
///
|
||||
/// {{produces}}
|
||||
///
|
||||
/// ### Explanation
|
||||
///
|
||||
/// Method calls take precedence over unary precedence. Setting the
|
||||
/// precedence explicitly makes the code clearer and avoid potential bugs.
|
||||
pub AMBIGUOUS_NEGATIVE_LITERALS,
|
||||
Deny,
|
||||
"ambiguous negative literals operations",
|
||||
report_in_external_macro
|
||||
}
|
||||
|
||||
declare_lint_pass!(Precedence => [AMBIGUOUS_NEGATIVE_LITERALS]);
|
||||
|
||||
impl EarlyLintPass for Precedence {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
|
||||
let ExprKind::Unary(UnOp::Neg, operand) = &expr.kind else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut arg = operand;
|
||||
let mut at_least_one = false;
|
||||
while let ExprKind::MethodCall(box MethodCall { receiver, .. }) = &arg.kind {
|
||||
at_least_one = true;
|
||||
arg = receiver;
|
||||
}
|
||||
|
||||
if at_least_one
|
||||
&& let ExprKind::Lit(lit) = &arg.kind
|
||||
&& let LitKind::Integer | LitKind::Float = &lit.kind
|
||||
{
|
||||
cx.emit_span_lint(
|
||||
AMBIGUOUS_NEGATIVE_LITERALS,
|
||||
expr.span,
|
||||
AmbiguousNegativeLiteralsDiag {
|
||||
negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
|
||||
start_span: expr.span.shrink_to_lo(),
|
||||
end_span: arg.span.shrink_to_hi(),
|
||||
},
|
||||
current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
|
||||
start_span: operand.span.shrink_to_lo(),
|
||||
end_span: operand.span.shrink_to_hi(),
|
||||
},
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1419,8 +1419,6 @@ extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
|
|||
return LLVMPointerTypeKind;
|
||||
case Type::FixedVectorTyID:
|
||||
return LLVMVectorTypeKind;
|
||||
case Type::X86_MMXTyID:
|
||||
return LLVMX86_MMXTypeKind;
|
||||
case Type::TokenTyID:
|
||||
return LLVMTokenTypeKind;
|
||||
case Type::ScalableVectorTyID:
|
||||
|
|
|
|||
|
|
@ -1728,7 +1728,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
source_len,
|
||||
lines,
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
stable_id,
|
||||
..
|
||||
|
|
@ -1780,7 +1779,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
|||
self.cnum,
|
||||
lines,
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
source_file_index,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
bitflags = "2.4.1"
|
||||
derivative = "2.2.0"
|
||||
derive-where = "1.2.7"
|
||||
either = "1.5.0"
|
||||
field-offset = "0.3.5"
|
||||
gsgdt = "0.1.2"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use crate::mir;
|
||||
use crate::ty::{self, CoroutineArgsExt, OpaqueHiddenType, Ty, TyCtxt};
|
||||
use derive_where::derive_where;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
|
|
@ -224,13 +225,7 @@ rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
|
|||
/// See also `rustc_const_eval::borrow_check::constraints`.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)]
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
PartialOrd,
|
||||
Ord,
|
||||
PartialOrd = "feature_allow_slow_enum",
|
||||
Ord = "feature_allow_slow_enum"
|
||||
)]
|
||||
#[derive_where(PartialOrd, Ord)]
|
||||
pub enum ConstraintCategory<'tcx> {
|
||||
Return(ReturnConstraint),
|
||||
Yield,
|
||||
|
|
@ -240,7 +235,7 @@ pub enum ConstraintCategory<'tcx> {
|
|||
Cast {
|
||||
/// Whether this is an unsizing cast and if yes, this contains the target type.
|
||||
/// Region variables are erased to ReErased.
|
||||
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||
#[derive_where(skip)]
|
||||
unsize_to: Option<Ty<'tcx>>,
|
||||
},
|
||||
|
||||
|
|
@ -250,7 +245,7 @@ pub enum ConstraintCategory<'tcx> {
|
|||
ClosureBounds,
|
||||
|
||||
/// Contains the function type if available.
|
||||
CallArgument(#[derivative(PartialOrd = "ignore", Ord = "ignore")] Option<Ty<'tcx>>),
|
||||
CallArgument(#[derive_where(skip)] Option<Ty<'tcx>>),
|
||||
CopyBound,
|
||||
SizedBound,
|
||||
Assignment,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use crate::thir::cx::region::Scope;
|
|||
use crate::thir::cx::Cx;
|
||||
use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
use itertools::Itertools;
|
||||
use rustc_ast::LitKind;
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
|
||||
|
|
@ -22,8 +21,7 @@ use rustc_middle::ty::{
|
|||
self, AdtKind, InlineConstArgs, InlineConstArgsParts, ScalarInt, Ty, UpvarArgs, UserType,
|
||||
};
|
||||
use rustc_middle::{bug, span_bug};
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_span::{sym, Span, DUMMY_SP};
|
||||
use rustc_span::{sym, Span};
|
||||
use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
|
||||
use tracing::{debug, info, instrument, trace};
|
||||
|
||||
|
|
@ -899,14 +897,10 @@ impl<'tcx> Cx<'tcx> {
|
|||
let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
|
||||
let generics = self.tcx.generics_of(hir_id.owner);
|
||||
let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
|
||||
let guar = self.tcx.dcx().has_errors().unwrap();
|
||||
// We already errored about a late bound const
|
||||
|
||||
let lit = self
|
||||
.tcx
|
||||
.hir_arena
|
||||
.alloc(Spanned { span: DUMMY_SP, node: LitKind::Err(guar) });
|
||||
return ExprKind::Literal { lit, neg: false };
|
||||
span_bug!(
|
||||
expr.span,
|
||||
"Should have already errored about late bound consts: {def_id:?}"
|
||||
);
|
||||
};
|
||||
let name = self.tcx.hir().name(hir_id);
|
||||
let param = ty::ParamConst::new(index, name);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
bitflags = "2.4.1"
|
||||
derivative = "2.2.0"
|
||||
derive-where = "1.2.7"
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
rustc_index = { path = "../rustc_index", default-features = false }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt::Debug;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
use rustc_type_ir::{self as ty, InferCtxtLike, Interner};
|
||||
|
|
@ -108,15 +109,13 @@ impl From<bool> for IsFirstInputType {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = "T: Debug"))]
|
||||
#[derive_where(Debug; I: Interner, T: Debug)]
|
||||
pub enum OrphanCheckErr<I: Interner, T> {
|
||||
NonLocalInputType(Vec<(I::Ty, IsFirstInputType)>),
|
||||
UncoveredTyParams(UncoveredTyParams<I, T>),
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = "T: Debug"))]
|
||||
#[derive_where(Debug; I: Interner, T: Debug)]
|
||||
pub struct UncoveredTyParams<I: Interner, T> {
|
||||
pub uncovered: T,
|
||||
pub local_ty: Option<I::Ty>,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
pub(super) mod structural_traits;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir::elaborate;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use rustc_type_ir::inherent::*;
|
||||
|
|
@ -21,8 +22,7 @@ use crate::solve::{
|
|||
///
|
||||
/// It consists of both the `source`, which describes how that goal would be proven,
|
||||
/// and the `result` when using the given `source`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""), Clone(bound = ""))]
|
||||
#[derive_where(Clone, Debug; I: Interner)]
|
||||
pub(super) struct Candidate<I: Interner> {
|
||||
pub(super) source: CandidateSource<I>,
|
||||
pub(super) result: CanonicalResponse<I>,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Code which is used by built-in goals that match "structurally", such a auto
|
||||
//! traits, `Copy`/`Clone`.
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_ast_ir::{Movability, Mutability};
|
||||
use rustc_type_ir::data_structures::HashMap;
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
|
|
@ -384,8 +385,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
|
|||
|
||||
/// Relevant types for an async callable, including its inputs, output,
|
||||
/// and the return type you get from awaiting the output.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub(in crate::solve) struct AsyncCallableRelevantTypes<I: Interner> {
|
||||
pub tupled_inputs_ty: I::Ty,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir::data_structures::ensure_sufficient_stack;
|
||||
|
|
@ -87,8 +88,7 @@ where
|
|||
pub(super) inspect: ProofTreeBuilder<D>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))]
|
||||
#[derive_where(Clone, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
// FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate.
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::{self as ty, search_graph, Interner};
|
||||
|
||||
|
|
@ -51,8 +52,7 @@ where
|
|||
/// in the code, only one or two variants are actually possible.
|
||||
///
|
||||
/// We simply ICE in case that assumption is broken.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""))]
|
||||
#[derive_where(Debug; I: Interner)]
|
||||
enum DebugSolver<I: Interner> {
|
||||
Root,
|
||||
GoalEvaluation(WipGoalEvaluation<I>),
|
||||
|
|
@ -78,8 +78,7 @@ impl<I: Interner> From<WipCanonicalGoalEvaluationStep<I>> for DebugSolver<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
struct WipGoalEvaluation<I: Interner> {
|
||||
pub uncanonicalized_goal: Goal<I, I::Predicate>,
|
||||
pub orig_values: Vec<I::GenericArg>,
|
||||
|
|
@ -96,8 +95,7 @@ impl<I: Interner> WipGoalEvaluation<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq; I: Interner)]
|
||||
pub(in crate::solve) enum WipCanonicalGoalEvaluationKind<I: Interner> {
|
||||
Overflow,
|
||||
CycleInStack,
|
||||
|
|
@ -118,8 +116,7 @@ impl<I: Interner> std::fmt::Debug for WipCanonicalGoalEvaluationKind<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
struct WipCanonicalGoalEvaluation<I: Interner> {
|
||||
goal: CanonicalInput<I>,
|
||||
kind: Option<WipCanonicalGoalEvaluationKind<I>>,
|
||||
|
|
@ -153,8 +150,7 @@ impl<I: Interner> WipCanonicalGoalEvaluation<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
struct WipCanonicalGoalEvaluationStep<I: Interner> {
|
||||
/// Unlike `EvalCtxt::var_values`, we append a new
|
||||
/// generic arg here whenever we create a new inference
|
||||
|
|
@ -193,8 +189,7 @@ impl<I: Interner> WipCanonicalGoalEvaluationStep<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
struct WipProbe<I: Interner> {
|
||||
initial_num_var_values: usize,
|
||||
steps: Vec<WipProbeStep<I>>,
|
||||
|
|
@ -212,8 +207,7 @@ impl<I: Interner> WipProbe<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
enum WipProbeStep<I: Interner> {
|
||||
AddGoal(GoalSource, inspect::CanonicalState<I, Goal<I, I::Predicate>>),
|
||||
NestedProbe(WipProbe<I>),
|
||||
|
|
|
|||
|
|
@ -53,6 +53,12 @@ parse_bare_cr = {$double_quotes ->
|
|||
|
||||
parse_bare_cr_in_raw_string = bare CR not allowed in raw string
|
||||
|
||||
parse_binder_and_polarity = `for<...>` binder not allowed with `{$polarity}` trait polarity modifier
|
||||
.label = there is not a well-defined meaning for a higher-ranked `{$polarity}` trait
|
||||
|
||||
parse_binder_before_modifiers = `for<...>` binder should be placed before trait bound modifiers
|
||||
.label = place the `for<...>` binder before any modifiers
|
||||
|
||||
parse_bounds_not_allowed_on_trait_aliases = bounds are not allowed on trait aliases
|
||||
|
||||
parse_box_not_pat = expected pattern, found {$descr}
|
||||
|
|
@ -577,6 +583,9 @@ parse_missing_trait_in_trait_impl = missing trait in a trait impl
|
|||
parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds
|
||||
.suggestion = remove the `{$modifier}`
|
||||
|
||||
parse_modifiers_and_polarity = `{$modifiers_concatenated}` trait not allowed with `{$polarity}` trait polarity modifier
|
||||
.label = there is not a well-defined meaning for a `{$modifiers_concatenated} {$polarity}` trait
|
||||
|
||||
parse_more_than_one_char = character literal may only contain one codepoint
|
||||
.followed_by = this `{$chr}` is followed by the combining {$len ->
|
||||
[one] mark
|
||||
|
|
|
|||
|
|
@ -3212,3 +3212,33 @@ pub struct UnsafeAttrOutsideUnsafeSuggestion {
|
|||
#[suggestion_part(code = ")")]
|
||||
pub right: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_binder_before_modifiers)]
|
||||
pub struct BinderBeforeModifiers {
|
||||
#[primary_span]
|
||||
pub binder_span: Span,
|
||||
#[label]
|
||||
pub modifiers_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_binder_and_polarity)]
|
||||
pub struct BinderAndPolarity {
|
||||
#[primary_span]
|
||||
pub polarity_span: Span,
|
||||
#[label]
|
||||
pub binder_span: Span,
|
||||
pub polarity: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_modifiers_and_polarity)]
|
||||
pub struct PolarityAndModifiers {
|
||||
#[primary_span]
|
||||
pub polarity_span: Span,
|
||||
#[label]
|
||||
pub modifiers_span: Span,
|
||||
pub polarity: &'static str,
|
||||
pub modifiers_concatenated: String,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2773,7 +2773,14 @@ impl<'a> Parser<'a> {
|
|||
let snapshot = p.create_snapshot_for_diagnostic();
|
||||
let param = p.parse_param_general(req_name, first_param).or_else(|e| {
|
||||
let guar = e.emit();
|
||||
let lo = p.prev_token.span;
|
||||
// When parsing a param failed, we should check to make the span of the param
|
||||
// not contain '(' before it.
|
||||
// For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
|
||||
let lo = if let TokenKind::OpenDelim(Delimiter::Parenthesis) = p.prev_token.kind {
|
||||
p.prev_token.span.shrink_to_hi()
|
||||
} else {
|
||||
p.prev_token.span
|
||||
};
|
||||
p.restore_snapshot(snapshot);
|
||||
// Skip every token until next possible arg or end.
|
||||
p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(Delimiter::Parenthesis)]);
|
||||
|
|
|
|||
|
|
@ -935,9 +935,14 @@ impl<'a> Parser<'a> {
|
|||
/// If no modifiers are present, this does not consume any tokens.
|
||||
///
|
||||
/// ```ebnf
|
||||
/// TRAIT_BOUND_MODIFIERS = [["~"] "const"] ["async"] ["?" | "!"]
|
||||
/// CONSTNESS = [["~"] "const"]
|
||||
/// ASYNCNESS = ["async"]
|
||||
/// POLARITY = ["?" | "!"]
|
||||
/// ```
|
||||
///
|
||||
/// See `parse_generic_ty_bound` for the complete grammar of trait bound modifiers.
|
||||
fn parse_trait_bound_modifiers(&mut self) -> PResult<'a, TraitBoundModifiers> {
|
||||
let modifier_lo = self.token.span;
|
||||
let constness = if self.eat(&token::Tilde) {
|
||||
let tilde = self.prev_token.span;
|
||||
self.expect_keyword(kw::Const)?;
|
||||
|
|
@ -970,6 +975,7 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
BoundAsyncness::Normal
|
||||
};
|
||||
let modifier_hi = self.prev_token.span;
|
||||
|
||||
let polarity = if self.eat(&token::Question) {
|
||||
BoundPolarity::Maybe(self.prev_token.span)
|
||||
|
|
@ -980,13 +986,40 @@ impl<'a> Parser<'a> {
|
|||
BoundPolarity::Positive
|
||||
};
|
||||
|
||||
// Enforce the mutual-exclusivity of `const`/`async` and `?`/`!`.
|
||||
match polarity {
|
||||
BoundPolarity::Positive => {
|
||||
// All trait bound modifiers allowed to combine with positive polarity
|
||||
}
|
||||
BoundPolarity::Maybe(polarity_span) | BoundPolarity::Negative(polarity_span) => {
|
||||
match (asyncness, constness) {
|
||||
(BoundAsyncness::Normal, BoundConstness::Never) => {
|
||||
// Ok, no modifiers.
|
||||
}
|
||||
(_, _) => {
|
||||
let constness = constness.as_str();
|
||||
let asyncness = asyncness.as_str();
|
||||
let glue =
|
||||
if !constness.is_empty() && !asyncness.is_empty() { " " } else { "" };
|
||||
let modifiers_concatenated = format!("{constness}{glue}{asyncness}");
|
||||
self.dcx().emit_err(errors::PolarityAndModifiers {
|
||||
polarity_span,
|
||||
polarity: polarity.as_str(),
|
||||
modifiers_span: modifier_lo.to(modifier_hi),
|
||||
modifiers_concatenated,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TraitBoundModifiers { constness, asyncness, polarity })
|
||||
}
|
||||
|
||||
/// Parses a type bound according to:
|
||||
/// ```ebnf
|
||||
/// TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
|
||||
/// TY_BOUND_NOPAREN = [TRAIT_BOUND_MODIFIERS] [for<LT_PARAM_DEFS>] SIMPLE_PATH
|
||||
/// TY_BOUND_NOPAREN = [for<GENERIC_PARAMS> CONSTNESS ASYNCNESS | POLARITY] SIMPLE_PATH
|
||||
/// ```
|
||||
///
|
||||
/// For example, this grammar accepts `for<'a: 'b> ~const ?m::Trait<'a>`.
|
||||
|
|
@ -996,9 +1029,25 @@ impl<'a> Parser<'a> {
|
|||
has_parens: bool,
|
||||
leading_token: &Token,
|
||||
) -> PResult<'a, GenericBound> {
|
||||
let modifiers = self.parse_trait_bound_modifiers()?;
|
||||
let (mut lifetime_defs, binder_span) = self.parse_late_bound_lifetime_defs()?;
|
||||
|
||||
let modifiers_lo = self.token.span;
|
||||
let modifiers = self.parse_trait_bound_modifiers()?;
|
||||
let modifiers_span = modifiers_lo.to(self.prev_token.span);
|
||||
|
||||
if let Some(binder_span) = binder_span {
|
||||
match modifiers.polarity {
|
||||
BoundPolarity::Negative(polarity_span) | BoundPolarity::Maybe(polarity_span) => {
|
||||
self.dcx().emit_err(errors::BinderAndPolarity {
|
||||
binder_span,
|
||||
polarity_span,
|
||||
polarity: modifiers.polarity.as_str(),
|
||||
});
|
||||
}
|
||||
BoundPolarity::Positive => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Recover erroneous lifetime bound with modifiers or binder.
|
||||
// e.g. `T: for<'a> 'a` or `T: ~const 'a`.
|
||||
if self.token.is_lifetime() {
|
||||
|
|
@ -1006,6 +1055,11 @@ impl<'a> Parser<'a> {
|
|||
return self.parse_generic_lt_bound(lo, has_parens);
|
||||
}
|
||||
|
||||
if let (more_lifetime_defs, Some(binder_span)) = self.parse_late_bound_lifetime_defs()? {
|
||||
lifetime_defs.extend(more_lifetime_defs);
|
||||
self.dcx().emit_err(errors::BinderBeforeModifiers { binder_span, modifiers_span });
|
||||
}
|
||||
|
||||
let mut path = if self.token.is_keyword(kw::Fn)
|
||||
&& self.look_ahead(1, |tok| tok.kind == TokenKind::OpenDelim(Delimiter::Parenthesis))
|
||||
&& let Some(path) = self.recover_path_from_fn()
|
||||
|
|
|
|||
|
|
@ -244,22 +244,19 @@ impl<'tcx> CheckInlineAssembly<'tcx> {
|
|||
self.tcx.dcx().emit_err(NakedFunctionsOperands { unsupported_operands });
|
||||
}
|
||||
|
||||
let unsupported_options: Vec<&'static str> = [
|
||||
(InlineAsmOptions::MAY_UNWIND, "`may_unwind`"),
|
||||
(InlineAsmOptions::NOMEM, "`nomem`"),
|
||||
(InlineAsmOptions::NOSTACK, "`nostack`"),
|
||||
(InlineAsmOptions::PRESERVES_FLAGS, "`preserves_flags`"),
|
||||
(InlineAsmOptions::PURE, "`pure`"),
|
||||
(InlineAsmOptions::READONLY, "`readonly`"),
|
||||
]
|
||||
.iter()
|
||||
.filter_map(|&(option, name)| if asm.options.contains(option) { Some(name) } else { None })
|
||||
.collect();
|
||||
let supported_options =
|
||||
InlineAsmOptions::RAW | InlineAsmOptions::NORETURN | InlineAsmOptions::ATT_SYNTAX;
|
||||
let unsupported_options = asm.options.difference(supported_options);
|
||||
|
||||
if !unsupported_options.is_empty() {
|
||||
self.tcx.dcx().emit_err(NakedFunctionsAsmOptions {
|
||||
span,
|
||||
unsupported_options: unsupported_options.join(", "),
|
||||
unsupported_options: unsupported_options
|
||||
.human_readable_names()
|
||||
.into_iter()
|
||||
.map(|name| format!("`{name}`"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
|
|||
source_len: _,
|
||||
lines: _,
|
||||
ref multibyte_chars,
|
||||
ref non_narrow_chars,
|
||||
ref normalized_pos,
|
||||
} = *self;
|
||||
|
||||
|
|
@ -98,11 +97,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for SourceFile {
|
|||
char_pos.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
non_narrow_chars.len().hash_stable(hcx, hasher);
|
||||
for &char_pos in non_narrow_chars.iter() {
|
||||
char_pos.hash_stable(hcx, hasher);
|
||||
}
|
||||
|
||||
normalized_pos.len().hash_stable(hcx, hasher);
|
||||
for &char_pos in normalized_pos.iter() {
|
||||
char_pos.hash_stable(hcx, hasher);
|
||||
|
|
|
|||
|
|
@ -2012,7 +2012,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
)
|
||||
} else if ident.name == sym::core {
|
||||
(
|
||||
format!("maybe a missing crate `{ident}`?"),
|
||||
format!("you might be missing crate `{ident}`"),
|
||||
Some((
|
||||
vec![(ident.span, "std".to_string())],
|
||||
"try using `std` instead of `core`".to_string(),
|
||||
|
|
@ -2021,7 +2021,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
)
|
||||
} else if self.tcx.sess.is_rust_2015() {
|
||||
(
|
||||
format!("maybe a missing crate `{ident}`?"),
|
||||
format!("you might be missing crate `{ident}`"),
|
||||
Some((
|
||||
vec![],
|
||||
format!(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
derivative = "2.2.0"
|
||||
derive-where = "1.2.7"
|
||||
indexmap = { version = "2.0.0" }
|
||||
itoa = "1.0"
|
||||
md5 = { package = "md-5", version = "0.10.0" }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use super::*;
|
||||
use unicode_width::UnicodeWidthChar;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
@ -9,15 +8,12 @@ mod tests;
|
|||
///
|
||||
/// This function will use an SSE2 enhanced implementation if hardware support
|
||||
/// is detected at runtime.
|
||||
pub fn analyze_source_file(
|
||||
src: &str,
|
||||
) -> (Vec<RelativeBytePos>, Vec<MultiByteChar>, Vec<NonNarrowChar>) {
|
||||
pub fn analyze_source_file(src: &str) -> (Vec<RelativeBytePos>, Vec<MultiByteChar>) {
|
||||
let mut lines = vec![RelativeBytePos::from_u32(0)];
|
||||
let mut multi_byte_chars = vec![];
|
||||
let mut non_narrow_chars = vec![];
|
||||
|
||||
// Calls the right implementation, depending on hardware support available.
|
||||
analyze_source_file_dispatch(src, &mut lines, &mut multi_byte_chars, &mut non_narrow_chars);
|
||||
analyze_source_file_dispatch(src, &mut lines, &mut multi_byte_chars);
|
||||
|
||||
// The code above optimistically registers a new line *after* each \n
|
||||
// it encounters. If that point is already outside the source_file, remove
|
||||
|
|
@ -30,7 +26,7 @@ pub fn analyze_source_file(
|
|||
}
|
||||
}
|
||||
|
||||
(lines, multi_byte_chars, non_narrow_chars)
|
||||
(lines, multi_byte_chars)
|
||||
}
|
||||
|
||||
cfg_match! {
|
||||
|
|
@ -39,11 +35,10 @@ cfg_match! {
|
|||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
non_narrow_chars: &mut Vec<NonNarrowChar>,
|
||||
) {
|
||||
if is_x86_feature_detected!("sse2") {
|
||||
unsafe {
|
||||
analyze_source_file_sse2(src, lines, multi_byte_chars, non_narrow_chars);
|
||||
analyze_source_file_sse2(src, lines, multi_byte_chars);
|
||||
}
|
||||
} else {
|
||||
analyze_source_file_generic(
|
||||
|
|
@ -52,7 +47,6 @@ cfg_match! {
|
|||
RelativeBytePos::from_u32(0),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
non_narrow_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +60,6 @@ cfg_match! {
|
|||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
non_narrow_chars: &mut Vec<NonNarrowChar>,
|
||||
) {
|
||||
#[cfg(target_arch = "x86")]
|
||||
use std::arch::x86::*;
|
||||
|
|
@ -159,7 +152,6 @@ cfg_match! {
|
|||
RelativeBytePos::from_usize(scan_start),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
non_narrow_chars,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +164,6 @@ cfg_match! {
|
|||
RelativeBytePos::from_usize(tail_start),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
non_narrow_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -183,7 +174,6 @@ cfg_match! {
|
|||
src: &str,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
non_narrow_chars: &mut Vec<NonNarrowChar>,
|
||||
) {
|
||||
analyze_source_file_generic(
|
||||
src,
|
||||
|
|
@ -191,7 +181,6 @@ cfg_match! {
|
|||
RelativeBytePos::from_u32(0),
|
||||
lines,
|
||||
multi_byte_chars,
|
||||
non_narrow_chars,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -205,7 +194,6 @@ fn analyze_source_file_generic(
|
|||
output_offset: RelativeBytePos,
|
||||
lines: &mut Vec<RelativeBytePos>,
|
||||
multi_byte_chars: &mut Vec<MultiByteChar>,
|
||||
non_narrow_chars: &mut Vec<NonNarrowChar>,
|
||||
) -> usize {
|
||||
assert!(src.len() >= scan_len);
|
||||
let mut i = 0;
|
||||
|
|
@ -227,16 +215,8 @@ fn analyze_source_file_generic(
|
|||
|
||||
let pos = RelativeBytePos::from_usize(i) + output_offset;
|
||||
|
||||
match byte {
|
||||
b'\n' => {
|
||||
lines.push(pos + RelativeBytePos(1));
|
||||
}
|
||||
b'\t' => {
|
||||
non_narrow_chars.push(NonNarrowChar::Tab(pos));
|
||||
}
|
||||
_ => {
|
||||
non_narrow_chars.push(NonNarrowChar::ZeroWidth(pos));
|
||||
}
|
||||
if let b'\n' = byte {
|
||||
lines.push(pos + RelativeBytePos(1));
|
||||
}
|
||||
} else if byte >= 127 {
|
||||
// The slow path:
|
||||
|
|
@ -252,14 +232,6 @@ fn analyze_source_file_generic(
|
|||
let mbc = MultiByteChar { pos, bytes: char_len as u8 };
|
||||
multi_byte_chars.push(mbc);
|
||||
}
|
||||
|
||||
// Assume control characters are zero width.
|
||||
// FIXME: How can we decide between `width` and `width_cjk`?
|
||||
let char_width = UnicodeWidthChar::width(c).unwrap_or(0);
|
||||
|
||||
if char_width != 1 {
|
||||
non_narrow_chars.push(NonNarrowChar::new(pos, char_width));
|
||||
}
|
||||
}
|
||||
|
||||
i += char_len;
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ macro_rules! test {
|
|||
(case: $test_name:ident,
|
||||
text: $text:expr,
|
||||
lines: $lines:expr,
|
||||
multi_byte_chars: $multi_byte_chars:expr,
|
||||
non_narrow_chars: $non_narrow_chars:expr,) => {
|
||||
multi_byte_chars: $multi_byte_chars:expr,) => {
|
||||
#[test]
|
||||
fn $test_name() {
|
||||
let (lines, multi_byte_chars, non_narrow_chars) = analyze_source_file($text);
|
||||
let (lines, multi_byte_chars) = analyze_source_file($text);
|
||||
|
||||
let expected_lines: Vec<RelativeBytePos> =
|
||||
$lines.into_iter().map(RelativeBytePos).collect();
|
||||
|
|
@ -21,13 +20,6 @@ macro_rules! test {
|
|||
.collect();
|
||||
|
||||
assert_eq!(multi_byte_chars, expected_mbcs);
|
||||
|
||||
let expected_nncs: Vec<NonNarrowChar> = $non_narrow_chars
|
||||
.into_iter()
|
||||
.map(|(pos, width)| NonNarrowChar::new(RelativeBytePos(pos), width))
|
||||
.collect();
|
||||
|
||||
assert_eq!(non_narrow_chars, expected_nncs);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -37,7 +29,6 @@ test!(
|
|||
text: "",
|
||||
lines: vec![],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -45,7 +36,6 @@ test!(
|
|||
text: "a\nc",
|
||||
lines: vec![0, 2],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -53,7 +43,6 @@ test!(
|
|||
text: "012345678\nabcdef012345678\na",
|
||||
lines: vec![0, 10, 26],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -61,7 +50,6 @@ test!(
|
|||
text: "01234β789\nbcdef0123456789abcdef",
|
||||
lines: vec![0, 11],
|
||||
multi_byte_chars: vec![(5, 2)],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -69,7 +57,6 @@ test!(
|
|||
text: "01234\u{07}6789\nbcdef0123456789abcdef",
|
||||
lines: vec![0, 11],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![(5, 0)],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -77,7 +64,6 @@ test!(
|
|||
text: "aβc",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![(1, 2)],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -85,7 +71,6 @@ test!(
|
|||
text: "0123456789abcΔf012345β",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![(13, 2), (22, 2)],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -93,7 +78,6 @@ test!(
|
|||
text: "0123456789abcdeΔ123456789abcdef01234",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![(15, 2)],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -101,7 +85,6 @@ test!(
|
|||
text: "0123456789abcdeΔ....",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![(15, 2)],
|
||||
non_narrow_chars: vec![],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -109,7 +92,6 @@ test!(
|
|||
text: "0\t2",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![(1, 4)],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -117,7 +99,6 @@ test!(
|
|||
text: "01\t3456789abcdef01234567\u{07}9",
|
||||
lines: vec![0],
|
||||
multi_byte_chars: vec![],
|
||||
non_narrow_chars: vec![(2, 4), (24, 0)],
|
||||
);
|
||||
|
||||
test!(
|
||||
|
|
@ -125,5 +106,4 @@ test!(
|
|||
text: "01\t345\n789abcΔf01234567\u{07}9\nbcΔf",
|
||||
lines: vec![0, 7, 27],
|
||||
multi_byte_chars: vec![(13, 2), (29, 2)],
|
||||
non_narrow_chars: vec![(2, 4), (24, 0)],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
// this crate without this line making `rustc_span` available.
|
||||
extern crate self as rustc_span;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_data_structures::{outline, AtomicRef};
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
|
||||
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
|
||||
|
|
@ -467,18 +468,18 @@ impl FileName {
|
|||
/// `SpanData` is public because `Span` uses a thread-local interner and can't be
|
||||
/// sent to other threads, but some pieces of performance infra run in a separate thread.
|
||||
/// Using `Span` is generally preferred.
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq, derivative::Derivative)]
|
||||
#[derivative(PartialOrd, Ord)]
|
||||
#[derive(Clone, Copy, Hash, PartialEq, Eq)]
|
||||
#[derive_where(PartialOrd, Ord)]
|
||||
pub struct SpanData {
|
||||
pub lo: BytePos,
|
||||
pub hi: BytePos,
|
||||
/// Information about where the macro came from, if this piece of
|
||||
/// code was created by a macro expansion.
|
||||
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||
#[derive_where(skip)]
|
||||
// `SyntaxContext` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
pub ctxt: SyntaxContext,
|
||||
#[derivative(PartialOrd = "ignore", Ord = "ignore")]
|
||||
#[derive_where(skip)]
|
||||
// `LocalDefId` does not implement `Ord`.
|
||||
// The other fields are enough to determine in-file order.
|
||||
pub parent: Option<LocalDefId>,
|
||||
|
|
@ -1345,68 +1346,6 @@ pub struct MultiByteChar {
|
|||
pub bytes: u8,
|
||||
}
|
||||
|
||||
/// Identifies an offset of a non-narrow character in a `SourceFile`.
|
||||
#[derive(Copy, Clone, Encodable, Decodable, Eq, PartialEq, Debug, HashStable_Generic)]
|
||||
pub enum NonNarrowChar {
|
||||
/// Represents a zero-width character.
|
||||
ZeroWidth(RelativeBytePos),
|
||||
/// Represents a wide (full-width) character.
|
||||
Wide(RelativeBytePos),
|
||||
/// Represents a tab character, represented visually with a width of 4 characters.
|
||||
Tab(RelativeBytePos),
|
||||
}
|
||||
|
||||
impl NonNarrowChar {
|
||||
fn new(pos: RelativeBytePos, width: usize) -> Self {
|
||||
match width {
|
||||
0 => NonNarrowChar::ZeroWidth(pos),
|
||||
2 => NonNarrowChar::Wide(pos),
|
||||
4 => NonNarrowChar::Tab(pos),
|
||||
_ => panic!("width {width} given for non-narrow character"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relative offset of the character in the `SourceFile`.
|
||||
pub fn pos(&self) -> RelativeBytePos {
|
||||
match *self {
|
||||
NonNarrowChar::ZeroWidth(p) | NonNarrowChar::Wide(p) | NonNarrowChar::Tab(p) => p,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the width of the character, 0 (zero-width) or 2 (wide).
|
||||
pub fn width(&self) -> usize {
|
||||
match *self {
|
||||
NonNarrowChar::ZeroWidth(_) => 0,
|
||||
NonNarrowChar::Wide(_) => 2,
|
||||
NonNarrowChar::Tab(_) => 4,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<RelativeBytePos> for NonNarrowChar {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: RelativeBytePos) -> Self {
|
||||
match self {
|
||||
NonNarrowChar::ZeroWidth(pos) => NonNarrowChar::ZeroWidth(pos + rhs),
|
||||
NonNarrowChar::Wide(pos) => NonNarrowChar::Wide(pos + rhs),
|
||||
NonNarrowChar::Tab(pos) => NonNarrowChar::Tab(pos + rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<RelativeBytePos> for NonNarrowChar {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: RelativeBytePos) -> Self {
|
||||
match self {
|
||||
NonNarrowChar::ZeroWidth(pos) => NonNarrowChar::ZeroWidth(pos - rhs),
|
||||
NonNarrowChar::Wide(pos) => NonNarrowChar::Wide(pos - rhs),
|
||||
NonNarrowChar::Tab(pos) => NonNarrowChar::Tab(pos - rhs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifies an offset of a character that was normalized away from `SourceFile`.
|
||||
#[derive(Copy, Clone, Encodable, Decodable, Eq, PartialEq, Debug, HashStable_Generic)]
|
||||
pub struct NormalizedPos {
|
||||
|
|
@ -1581,8 +1520,6 @@ pub struct SourceFile {
|
|||
pub lines: FreezeLock<SourceFileLines>,
|
||||
/// Locations of multi-byte characters in the source code.
|
||||
pub multibyte_chars: Vec<MultiByteChar>,
|
||||
/// Width of characters that are not narrow in the source code.
|
||||
pub non_narrow_chars: Vec<NonNarrowChar>,
|
||||
/// Locations of characters removed during normalization.
|
||||
pub normalized_pos: Vec<NormalizedPos>,
|
||||
/// A hash of the filename & crate-id, used for uniquely identifying source
|
||||
|
|
@ -1604,7 +1541,6 @@ impl Clone for SourceFile {
|
|||
source_len: self.source_len,
|
||||
lines: self.lines.clone(),
|
||||
multibyte_chars: self.multibyte_chars.clone(),
|
||||
non_narrow_chars: self.non_narrow_chars.clone(),
|
||||
normalized_pos: self.normalized_pos.clone(),
|
||||
stable_id: self.stable_id,
|
||||
cnum: self.cnum,
|
||||
|
|
@ -1679,7 +1615,6 @@ impl<S: SpanEncoder> Encodable<S> for SourceFile {
|
|||
}
|
||||
|
||||
self.multibyte_chars.encode(s);
|
||||
self.non_narrow_chars.encode(s);
|
||||
self.stable_id.encode(s);
|
||||
self.normalized_pos.encode(s);
|
||||
self.cnum.encode(s);
|
||||
|
|
@ -1706,7 +1641,6 @@ impl<D: SpanDecoder> Decodable<D> for SourceFile {
|
|||
}
|
||||
};
|
||||
let multibyte_chars: Vec<MultiByteChar> = Decodable::decode(d);
|
||||
let non_narrow_chars: Vec<NonNarrowChar> = Decodable::decode(d);
|
||||
let stable_id = Decodable::decode(d);
|
||||
let normalized_pos: Vec<NormalizedPos> = Decodable::decode(d);
|
||||
let cnum: CrateNum = Decodable::decode(d);
|
||||
|
|
@ -1721,7 +1655,6 @@ impl<D: SpanDecoder> Decodable<D> for SourceFile {
|
|||
external_src: FreezeLock::frozen(ExternalSource::Unneeded),
|
||||
lines: FreezeLock::new(lines),
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
stable_id,
|
||||
cnum,
|
||||
|
|
@ -1809,8 +1742,7 @@ impl SourceFile {
|
|||
let source_len = src.len();
|
||||
let source_len = u32::try_from(source_len).map_err(|_| OffsetOverflowError)?;
|
||||
|
||||
let (lines, multibyte_chars, non_narrow_chars) =
|
||||
analyze_source_file::analyze_source_file(&src);
|
||||
let (lines, multibyte_chars) = analyze_source_file::analyze_source_file(&src);
|
||||
|
||||
Ok(SourceFile {
|
||||
name,
|
||||
|
|
@ -1821,7 +1753,6 @@ impl SourceFile {
|
|||
source_len: RelativeBytePos::from_u32(source_len),
|
||||
lines: FreezeLock::frozen(SourceFileLines::Lines(lines)),
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
stable_id,
|
||||
cnum: LOCAL_CRATE,
|
||||
|
|
@ -2130,41 +2061,45 @@ impl SourceFile {
|
|||
let pos = self.relative_position(pos);
|
||||
let (line, col_or_chpos) = self.lookup_file_pos(pos);
|
||||
if line > 0 {
|
||||
let col = col_or_chpos;
|
||||
let linebpos = self.lines()[line - 1];
|
||||
let col_display = {
|
||||
let start_width_idx = self
|
||||
.non_narrow_chars
|
||||
.binary_search_by_key(&linebpos, |x| x.pos())
|
||||
.unwrap_or_else(|x| x);
|
||||
let end_width_idx = self
|
||||
.non_narrow_chars
|
||||
.binary_search_by_key(&pos, |x| x.pos())
|
||||
.unwrap_or_else(|x| x);
|
||||
let special_chars = end_width_idx - start_width_idx;
|
||||
let non_narrow: usize = self.non_narrow_chars[start_width_idx..end_width_idx]
|
||||
.iter()
|
||||
.map(|x| x.width())
|
||||
.sum();
|
||||
col.0 - special_chars + non_narrow
|
||||
let Some(code) = self.get_line(line - 1) else {
|
||||
// If we don't have the code available, it is ok as a fallback to return the bytepos
|
||||
// instead of the "display" column, which is only used to properly show underlines
|
||||
// in the terminal.
|
||||
// FIXME: we'll want better handling of this in the future for the sake of tools
|
||||
// that want to use the display col instead of byte offsets to modify Rust code, but
|
||||
// that is a problem for another day, the previous code was already incorrect for
|
||||
// both displaying *and* third party tools using the json output naïvely.
|
||||
tracing::info!("couldn't find line {line} {:?}", self.name);
|
||||
return (line, col_or_chpos, col_or_chpos.0);
|
||||
};
|
||||
(line, col, col_display)
|
||||
let display_col = code.chars().take(col_or_chpos.0).map(|ch| char_width(ch)).sum();
|
||||
(line, col_or_chpos, display_col)
|
||||
} else {
|
||||
let chpos = col_or_chpos;
|
||||
let col_display = {
|
||||
let end_width_idx = self
|
||||
.non_narrow_chars
|
||||
.binary_search_by_key(&pos, |x| x.pos())
|
||||
.unwrap_or_else(|x| x);
|
||||
let non_narrow: usize =
|
||||
self.non_narrow_chars[0..end_width_idx].iter().map(|x| x.width()).sum();
|
||||
chpos.0 - end_width_idx + non_narrow
|
||||
};
|
||||
(0, chpos, col_display)
|
||||
// This is never meant to happen?
|
||||
(0, col_or_chpos, col_or_chpos.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn char_width(ch: char) -> usize {
|
||||
// FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is. For now,
|
||||
// just accept that sometimes the code line will be longer than desired.
|
||||
match ch {
|
||||
'\t' => 4,
|
||||
// Keep the following list in sync with `rustc_errors::emitter::OUTPUT_REPLACEMENTS`. These
|
||||
// are control points that we replace before printing with a visible codepoint for the sake
|
||||
// of being able to point at them with underlines.
|
||||
'\u{0000}' | '\u{0001}' | '\u{0002}' | '\u{0003}' | '\u{0004}' | '\u{0005}'
|
||||
| '\u{0006}' | '\u{0007}' | '\u{0008}' | '\u{000B}' | '\u{000C}' | '\u{000D}'
|
||||
| '\u{000E}' | '\u{000F}' | '\u{0010}' | '\u{0011}' | '\u{0012}' | '\u{0013}'
|
||||
| '\u{0014}' | '\u{0015}' | '\u{0016}' | '\u{0017}' | '\u{0018}' | '\u{0019}'
|
||||
| '\u{001A}' | '\u{001B}' | '\u{001C}' | '\u{001D}' | '\u{001E}' | '\u{001F}'
|
||||
| '\u{007F}' | '\u{202A}' | '\u{202B}' | '\u{202D}' | '\u{202E}' | '\u{2066}'
|
||||
| '\u{2067}' | '\u{2068}' | '\u{202C}' | '\u{2069}' => 1,
|
||||
_ => unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1),
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalizes the source code and records the normalizations.
|
||||
fn normalize_src(src: &mut String) -> Vec<NormalizedPos> {
|
||||
let mut normalized_pos = vec![];
|
||||
|
|
|
|||
|
|
@ -330,7 +330,6 @@ impl SourceMap {
|
|||
cnum: CrateNum,
|
||||
file_local_lines: FreezeLock<SourceFileLines>,
|
||||
multibyte_chars: Vec<MultiByteChar>,
|
||||
non_narrow_chars: Vec<NonNarrowChar>,
|
||||
normalized_pos: Vec<NormalizedPos>,
|
||||
metadata_index: u32,
|
||||
) -> Lrc<SourceFile> {
|
||||
|
|
@ -348,7 +347,6 @@ impl SourceMap {
|
|||
source_len,
|
||||
lines: file_local_lines,
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
stable_id,
|
||||
cnum,
|
||||
|
|
|
|||
|
|
@ -232,7 +232,6 @@ fn t10() {
|
|||
source_len,
|
||||
lines,
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
stable_id,
|
||||
..
|
||||
|
|
@ -246,7 +245,6 @@ fn t10() {
|
|||
CrateNum::ZERO,
|
||||
FreezeLock::new(lines.read().clone()),
|
||||
multibyte_chars,
|
||||
non_narrow_chars,
|
||||
normalized_pos,
|
||||
0,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -12,17 +12,16 @@ use super::elaborate;
|
|||
|
||||
use crate::infer::TyCtxtInferExt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{self, Obligation, ObligationCause};
|
||||
use crate::traits::{util, Obligation, ObligationCause};
|
||||
use rustc_errors::FatalError;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::{
|
||||
self, EarlyBinder, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitor,
|
||||
self, EarlyBinder, ExistentialPredicateStableCmpExt as _, GenericArgs, Ty, TyCtxt,
|
||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable,
|
||||
TypeVisitableExt, TypeVisitor, Upcast,
|
||||
};
|
||||
use rustc_middle::ty::{GenericArg, GenericArgs};
|
||||
use rustc_middle::ty::{TypeVisitableExt, Upcast};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::abi::Abi;
|
||||
|
|
@ -195,7 +194,13 @@ fn predicates_reference_self(
|
|||
.predicates
|
||||
.iter()
|
||||
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, trait_ref), sp))
|
||||
.filter_map(|predicate| predicate_references_self(tcx, predicate))
|
||||
.filter_map(|(clause, sp)| {
|
||||
// Super predicates cannot allow self projections, since they're
|
||||
// impossible to make into existential bounds without eager resolution
|
||||
// or something.
|
||||
// e.g. `trait A: B<Item = Self::Assoc>`.
|
||||
predicate_references_self(tcx, trait_def_id, clause, sp, AllowSelfProjections::No)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
@ -204,20 +209,25 @@ fn bounds_reference_self(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span
|
|||
.in_definition_order()
|
||||
.filter(|item| item.kind == ty::AssocKind::Type)
|
||||
.flat_map(|item| tcx.explicit_item_bounds(item.def_id).iter_identity_copied())
|
||||
.filter_map(|c| predicate_references_self(tcx, c))
|
||||
.filter_map(|(clause, sp)| {
|
||||
// Item bounds *can* have self projections, since they never get
|
||||
// their self type erased.
|
||||
predicate_references_self(tcx, trait_def_id, clause, sp, AllowSelfProjections::Yes)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn predicate_references_self<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(predicate, sp): (ty::Clause<'tcx>, Span),
|
||||
trait_def_id: DefId,
|
||||
predicate: ty::Clause<'tcx>,
|
||||
sp: Span,
|
||||
allow_self_projections: AllowSelfProjections,
|
||||
) -> Option<Span> {
|
||||
let self_ty = tcx.types.self_param;
|
||||
let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk().any(|arg| arg == self_ty.into());
|
||||
match predicate.kind().skip_binder() {
|
||||
ty::ClauseKind::Trait(ref data) => {
|
||||
// In the case of a trait predicate, we can skip the "self" type.
|
||||
data.trait_ref.args[1..].iter().any(has_self_ty).then_some(sp)
|
||||
data.trait_ref.args[1..].iter().any(|&arg| contains_illegal_self_type_reference(tcx, trait_def_id, arg, allow_self_projections)).then_some(sp)
|
||||
}
|
||||
ty::ClauseKind::Projection(ref data) => {
|
||||
// And similarly for projections. This should be redundant with
|
||||
|
|
@ -235,9 +245,9 @@ fn predicate_references_self<'tcx>(
|
|||
//
|
||||
// This is ALT2 in issue #56288, see that for discussion of the
|
||||
// possible alternatives.
|
||||
data.projection_term.args[1..].iter().any(has_self_ty).then_some(sp)
|
||||
data.projection_term.args[1..].iter().any(|&arg| contains_illegal_self_type_reference(tcx, trait_def_id, arg, allow_self_projections)).then_some(sp)
|
||||
}
|
||||
ty::ClauseKind::ConstArgHasType(_ct, ty) => has_self_ty(&ty.into()).then_some(sp),
|
||||
ty::ClauseKind::ConstArgHasType(_ct, ty) => contains_illegal_self_type_reference(tcx, trait_def_id, ty, allow_self_projections).then_some(sp),
|
||||
|
||||
ty::ClauseKind::WellFormed(..)
|
||||
| ty::ClauseKind::TypeOutlives(..)
|
||||
|
|
@ -383,7 +393,12 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
let mut errors = Vec::new();
|
||||
|
||||
for (i, &input_ty) in sig.skip_binder().inputs().iter().enumerate().skip(1) {
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) {
|
||||
if contains_illegal_self_type_reference(
|
||||
tcx,
|
||||
trait_def_id,
|
||||
sig.rebind(input_ty),
|
||||
AllowSelfProjections::Yes,
|
||||
) {
|
||||
let span = if let Some(hir::Node::TraitItem(hir::TraitItem {
|
||||
kind: hir::TraitItemKind::Fn(sig, _),
|
||||
..
|
||||
|
|
@ -396,7 +411,12 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
errors.push(MethodViolationCode::ReferencesSelfInput(span));
|
||||
}
|
||||
}
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
|
||||
if contains_illegal_self_type_reference(
|
||||
tcx,
|
||||
trait_def_id,
|
||||
sig.output(),
|
||||
AllowSelfProjections::Yes,
|
||||
) {
|
||||
errors.push(MethodViolationCode::ReferencesSelfOutput);
|
||||
}
|
||||
if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
|
||||
|
|
@ -482,7 +502,7 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
return false;
|
||||
}
|
||||
|
||||
contains_illegal_self_type_reference(tcx, trait_def_id, pred)
|
||||
contains_illegal_self_type_reference(tcx, trait_def_id, pred, AllowSelfProjections::Yes)
|
||||
}) {
|
||||
errors.push(MethodViolationCode::WhereClauseReferencesSelf);
|
||||
}
|
||||
|
|
@ -711,121 +731,181 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
infcx.predicate_must_hold_modulo_regions(&obligation)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum AllowSelfProjections {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
/// This is somewhat subtle. In general, we want to forbid
|
||||
/// references to `Self` in the argument and return types,
|
||||
/// since the value of `Self` is erased. However, there is one
|
||||
/// exception: it is ok to reference `Self` in order to access
|
||||
/// an associated type of the current trait, since we retain
|
||||
/// the value of those associated types in the object type
|
||||
/// itself.
|
||||
///
|
||||
/// ```rust,ignore (example)
|
||||
/// trait SuperTrait {
|
||||
/// type X;
|
||||
/// }
|
||||
///
|
||||
/// trait Trait : SuperTrait {
|
||||
/// type Y;
|
||||
/// fn foo(&self, x: Self) // bad
|
||||
/// fn foo(&self) -> Self // bad
|
||||
/// fn foo(&self) -> Option<Self> // bad
|
||||
/// fn foo(&self) -> Self::Y // OK, desugars to next example
|
||||
/// fn foo(&self) -> <Self as Trait>::Y // OK
|
||||
/// fn foo(&self) -> Self::X // OK, desugars to next example
|
||||
/// fn foo(&self) -> <Self as SuperTrait>::X // OK
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// However, it is not as simple as allowing `Self` in a projected
|
||||
/// type, because there are illegal ways to use `Self` as well:
|
||||
///
|
||||
/// ```rust,ignore (example)
|
||||
/// trait Trait : SuperTrait {
|
||||
/// ...
|
||||
/// fn foo(&self) -> <Self as SomeOtherTrait>::X;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Here we will not have the type of `X` recorded in the
|
||||
/// object type, and we cannot resolve `Self as SomeOtherTrait`
|
||||
/// without knowing what `Self` is.
|
||||
fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
value: T,
|
||||
allow_self_projections: AllowSelfProjections,
|
||||
) -> bool {
|
||||
// This is somewhat subtle. In general, we want to forbid
|
||||
// references to `Self` in the argument and return types,
|
||||
// since the value of `Self` is erased. However, there is one
|
||||
// exception: it is ok to reference `Self` in order to access
|
||||
// an associated type of the current trait, since we retain
|
||||
// the value of those associated types in the object type
|
||||
// itself.
|
||||
//
|
||||
// ```rust
|
||||
// trait SuperTrait {
|
||||
// type X;
|
||||
// }
|
||||
//
|
||||
// trait Trait : SuperTrait {
|
||||
// type Y;
|
||||
// fn foo(&self, x: Self) // bad
|
||||
// fn foo(&self) -> Self // bad
|
||||
// fn foo(&self) -> Option<Self> // bad
|
||||
// fn foo(&self) -> Self::Y // OK, desugars to next example
|
||||
// fn foo(&self) -> <Self as Trait>::Y // OK
|
||||
// fn foo(&self) -> Self::X // OK, desugars to next example
|
||||
// fn foo(&self) -> <Self as SuperTrait>::X // OK
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// However, it is not as simple as allowing `Self` in a projected
|
||||
// type, because there are illegal ways to use `Self` as well:
|
||||
//
|
||||
// ```rust
|
||||
// trait Trait : SuperTrait {
|
||||
// ...
|
||||
// fn foo(&self) -> <Self as SomeOtherTrait>::X;
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here we will not have the type of `X` recorded in the
|
||||
// object type, and we cannot resolve `Self as SomeOtherTrait`
|
||||
// without knowing what `Self` is.
|
||||
value
|
||||
.visit_with(&mut IllegalSelfTypeVisitor {
|
||||
tcx,
|
||||
trait_def_id,
|
||||
supertraits: None,
|
||||
allow_self_projections,
|
||||
})
|
||||
.is_break()
|
||||
}
|
||||
|
||||
struct IllegalSelfTypeVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
supertraits: Option<Vec<DefId>>,
|
||||
}
|
||||
struct IllegalSelfTypeVisitor<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
supertraits: Option<Vec<ty::TraitRef<'tcx>>>,
|
||||
allow_self_projections: AllowSelfProjections,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> {
|
||||
type Result = ControlFlow<()>;
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IllegalSelfTypeVisitor<'tcx> {
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||
match t.kind() {
|
||||
ty::Param(_) => {
|
||||
if t == self.tcx.types.self_param {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
ty::Alias(ty::Projection, ref data)
|
||||
if self.tcx.is_impl_trait_in_trait(data.def_id) =>
|
||||
{
|
||||
// We'll deny these later in their own pass
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||
match t.kind() {
|
||||
ty::Param(_) => {
|
||||
if t == self.tcx.types.self_param {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
ty::Alias(ty::Projection, ref data) => {
|
||||
// This is a projected type `<Foo as SomeTrait>::X`.
|
||||
|
||||
// Compute supertraits of current trait lazily.
|
||||
if self.supertraits.is_none() {
|
||||
let trait_ref =
|
||||
ty::Binder::dummy(ty::TraitRef::identity(self.tcx, self.trait_def_id));
|
||||
self.supertraits = Some(
|
||||
traits::supertraits(self.tcx, trait_ref).map(|t| t.def_id()).collect(),
|
||||
);
|
||||
}
|
||||
|
||||
// Determine whether the trait reference `Foo as
|
||||
// SomeTrait` is in fact a supertrait of the
|
||||
// current trait. In that case, this type is
|
||||
// legal, because the type `X` will be specified
|
||||
// in the object type. Note that we can just use
|
||||
// direct equality here because all of these types
|
||||
// are part of the formal parameter listing, and
|
||||
// hence there should be no inference variables.
|
||||
let is_supertrait_of_current_trait = self
|
||||
.supertraits
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.contains(&data.trait_ref(self.tcx).def_id);
|
||||
|
||||
// only walk contained types if it's not a super trait
|
||||
if is_supertrait_of_current_trait {
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
t.super_visit_with(self) // POSSIBLY reporting an error
|
||||
}
|
||||
}
|
||||
_ => t.super_visit_with(self), // walk contained types, if any
|
||||
}
|
||||
}
|
||||
ty::Alias(ty::Projection, ref data) if self.tcx.is_impl_trait_in_trait(data.def_id) => {
|
||||
// We'll deny these later in their own pass
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
ty::Alias(ty::Projection, ref data) => {
|
||||
match self.allow_self_projections {
|
||||
AllowSelfProjections::Yes => {
|
||||
// This is a projected type `<Foo as SomeTrait>::X`.
|
||||
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
|
||||
// Constants can only influence object safety if they are generic and reference `Self`.
|
||||
// This is only possible for unevaluated constants, so we walk these here.
|
||||
self.tcx.expand_abstract_consts(ct).super_visit_with(self)
|
||||
// Compute supertraits of current trait lazily.
|
||||
if self.supertraits.is_none() {
|
||||
self.supertraits = Some(
|
||||
util::supertraits(
|
||||
self.tcx,
|
||||
ty::Binder::dummy(ty::TraitRef::identity(
|
||||
self.tcx,
|
||||
self.trait_def_id,
|
||||
)),
|
||||
)
|
||||
.map(|trait_ref| {
|
||||
self.tcx.erase_regions(
|
||||
self.tcx.instantiate_bound_regions_with_erased(trait_ref),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
);
|
||||
}
|
||||
|
||||
// Determine whether the trait reference `Foo as
|
||||
// SomeTrait` is in fact a supertrait of the
|
||||
// current trait. In that case, this type is
|
||||
// legal, because the type `X` will be specified
|
||||
// in the object type. Note that we can just use
|
||||
// direct equality here because all of these types
|
||||
// are part of the formal parameter listing, and
|
||||
// hence there should be no inference variables.
|
||||
let is_supertrait_of_current_trait =
|
||||
self.supertraits.as_ref().unwrap().contains(
|
||||
&data.trait_ref(self.tcx).fold_with(
|
||||
&mut EraseEscapingBoundRegions {
|
||||
tcx: self.tcx,
|
||||
binder: ty::INNERMOST,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
// only walk contained types if it's not a super trait
|
||||
if is_supertrait_of_current_trait {
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
t.super_visit_with(self) // POSSIBLY reporting an error
|
||||
}
|
||||
}
|
||||
AllowSelfProjections::No => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
|
||||
value
|
||||
.visit_with(&mut IllegalSelfTypeVisitor { tcx, trait_def_id, supertraits: None })
|
||||
.is_break()
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> Self::Result {
|
||||
// Constants can only influence object safety if they are generic and reference `Self`.
|
||||
// This is only possible for unevaluated constants, so we walk these here.
|
||||
self.tcx.expand_abstract_consts(ct).super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
struct EraseEscapingBoundRegions<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
binder: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EraseEscapingBoundRegions<'tcx> {
|
||||
fn cx(&self) -> TyCtxt<'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
self.binder.shift_in(1);
|
||||
let result = t.super_fold_with(self);
|
||||
self.binder.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
if let ty::ReBound(debruijn, _) = *r
|
||||
&& debruijn < self.binder
|
||||
{
|
||||
r
|
||||
} else {
|
||||
self.tcx.lifetimes.re_erased
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_illegal_impl_trait_in_trait<'tcx>(
|
||||
|
|
|
|||
|
|
@ -1202,6 +1202,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
false
|
||||
}
|
||||
}
|
||||
} else if tcx.trait_is_auto(trait_ref.def_id) {
|
||||
tcx.dcx().span_delayed_bug(
|
||||
tcx.def_span(obligation.predicate.def_id),
|
||||
"associated types not allowed on auto traits",
|
||||
);
|
||||
false
|
||||
} else {
|
||||
bug!("unexpected builtin trait with associated type: {trait_ref:?}")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,11 +191,22 @@ fn resolve_associated_item<'tcx>(
|
|||
|
||||
// Any final impl is required to define all associated items.
|
||||
if !leaf_def.item.defaultness(tcx).has_value() {
|
||||
let guard = tcx.dcx().span_delayed_bug(
|
||||
let guar = tcx.dcx().span_delayed_bug(
|
||||
tcx.def_span(leaf_def.item.def_id),
|
||||
"missing value for assoc item in impl",
|
||||
);
|
||||
return Err(guard);
|
||||
return Err(guar);
|
||||
}
|
||||
|
||||
// Make sure that we're projecting to an item that has compatible args.
|
||||
// This may happen if we are resolving an instance before codegen, such
|
||||
// as during inlining. This check is also done in projection.
|
||||
if !tcx.check_args_compatible(leaf_def.item.def_id, args) {
|
||||
let guar = tcx.dcx().span_delayed_bug(
|
||||
tcx.def_span(leaf_def.item.def_id),
|
||||
"missing value for assoc item in impl",
|
||||
);
|
||||
return Err(guar);
|
||||
}
|
||||
|
||||
let args = tcx.erase_regions(args);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
bitflags = "2.4.1"
|
||||
derivative = "2.2.0"
|
||||
derive-where = "1.2.7"
|
||||
indexmap = "2.0.0"
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||
use std::marker::PhantomData;
|
||||
use std::ops::{ControlFlow, Deref};
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
#[cfg(feature = "nightly")]
|
||||
|
|
@ -25,15 +26,12 @@ use crate::{self as ty, Interner};
|
|||
/// e.g., `liberate_late_bound_regions`).
|
||||
///
|
||||
/// `Decodable` and `Encodable` are implemented for `Binder<T>` using the `impl_binder_encode_decode!` macro.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "T: Clone"),
|
||||
Copy(bound = "T: Copy"),
|
||||
Hash(bound = "T: Hash"),
|
||||
PartialEq(bound = "T: PartialEq"),
|
||||
Eq(bound = "T: Eq"),
|
||||
Debug(bound = "T: Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, T: Clone)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive_where(Hash; I: Interner, T: Hash)]
|
||||
#[derive_where(PartialEq; I: Interner, T: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, T: Eq)]
|
||||
#[derive_where(Debug; I: Interner, T: Debug)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct Binder<I: Interner, T> {
|
||||
value: T,
|
||||
|
|
@ -351,21 +349,18 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
|
|||
///
|
||||
/// If you don't have anything to `instantiate`, you may be looking for
|
||||
/// [`instantiate_identity`](EarlyBinder::instantiate_identity) or [`skip_binder`](EarlyBinder::skip_binder).
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "T: Clone"),
|
||||
Copy(bound = "T: Copy"),
|
||||
PartialEq(bound = "T: PartialEq"),
|
||||
Eq(bound = "T: Eq"),
|
||||
Ord(bound = "T: Ord"),
|
||||
PartialOrd(bound = "T: Ord"),
|
||||
Hash(bound = "T: Hash"),
|
||||
Debug(bound = "T: Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, T: Clone)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive_where(PartialEq; I: Interner, T: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, T: Eq)]
|
||||
#[derive_where(Ord; I: Interner, T: Ord)]
|
||||
#[derive_where(PartialOrd; I: Interner, T: Ord)]
|
||||
#[derive_where(Hash; I: Interner, T: Hash)]
|
||||
#[derive_where(Debug; I: Interner, T: Debug)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub struct EarlyBinder<I: Interner, T> {
|
||||
value: T,
|
||||
#[derivative(Debug = "ignore")]
|
||||
#[derive_where(skip(Debug))]
|
||||
_tcx: PhantomData<I>,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#![allow(clippy::derived_hash_with_manual_eq)]
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
|
@ -11,15 +14,12 @@ use crate::{self as ty, Interner, UniverseIndex};
|
|||
/// A "canonicalized" type `V` is one where all free inference
|
||||
/// variables have been rewritten to "canonical vars". These are
|
||||
/// numbered starting from 0 in order of first appearance.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "V: Clone"),
|
||||
Hash(bound = "V: Hash"),
|
||||
PartialEq(bound = "V: PartialEq"),
|
||||
Eq(bound = "V: Eq"),
|
||||
Debug(bound = "V: fmt::Debug"),
|
||||
Copy(bound = "V: Copy")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, V: Clone)]
|
||||
#[derive_where(Hash; I: Interner, V: Hash)]
|
||||
#[derive_where(PartialEq; I: Interner, V: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, V: Eq)]
|
||||
#[derive_where(Debug; I: Interner, V: fmt::Debug)]
|
||||
#[derive_where(Copy; I: Interner, V: Copy)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub struct Canonical<I: Interner, V> {
|
||||
|
|
@ -84,15 +84,7 @@ impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
|
|||
/// canonical value. This is sufficient information for code to create
|
||||
/// a copy of the canonical value in some other inference context,
|
||||
/// with fresh inference variables replacing the canonical values.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Eq(bound = ""),
|
||||
PartialEq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct CanonicalVarInfo<I: Interner> {
|
||||
|
|
@ -149,8 +141,7 @@ impl<I: Interner> CanonicalVarInfo<I> {
|
|||
/// Describes the "kind" of the canonical variable. This is a "kind"
|
||||
/// in the type-theory sense of the term -- i.e., a "meta" type system
|
||||
/// that analyzes type-like values.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Hash, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum CanonicalVarKind<I: Interner> {
|
||||
|
|
@ -178,6 +169,7 @@ pub enum CanonicalVarKind<I: Interner> {
|
|||
PlaceholderConst(I::PlaceholderConst),
|
||||
}
|
||||
|
||||
// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
|
||||
impl<I: Interner> PartialEq for CanonicalVarKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
|
@ -266,15 +258,7 @@ pub enum CanonicalTyVarKind {
|
|||
/// vectors with the original values that were replaced by canonical
|
||||
/// variables. You will need to supply it later to instantiate the
|
||||
/// canonicalized query response.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Hash(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CanonicalVarValues<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#![allow(clippy::derived_hash_with_manual_eq)]
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
|
|
@ -10,8 +13,7 @@ use crate::{self as ty, DebruijnIndex, Interner};
|
|||
use self::ConstKind::*;
|
||||
|
||||
/// Represents a constant in Rust.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub enum ConstKind<I: Interner> {
|
||||
/// A const generic parameter.
|
||||
|
|
@ -43,6 +45,7 @@ pub enum ConstKind<I: Interner> {
|
|||
Expr(I::ExprConst),
|
||||
}
|
||||
|
||||
// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
|
||||
impl<I: Interner> PartialEq for ConstKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
|
@ -77,14 +80,7 @@ impl<I: Interner> fmt::Debug for ConstKind<I> {
|
|||
}
|
||||
|
||||
/// An unevaluated (potentially generic) constant used in the type-system.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct UnevaluatedConst<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::solve::NoSolution;
|
||||
|
|
@ -21,14 +22,7 @@ impl<T> ExpectedFound<T> {
|
|||
}
|
||||
|
||||
// Data structures used in type unification
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", rustc_pass_by_value)]
|
||||
pub enum TypeError<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,16 +1,10 @@
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
|
||||
use crate::Interner;
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Eq(bound = ""),
|
||||
PartialEq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum GenericArgKind<I: Interner> {
|
||||
Lifetime(I::Region),
|
||||
|
|
@ -18,14 +12,7 @@ pub enum GenericArgKind<I: Interner> {
|
|||
Const(I::Const),
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Eq(bound = ""),
|
||||
PartialEq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum TermKind<I: Interner> {
|
||||
Ty(I::Ty),
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
|
@ -5,15 +6,7 @@ use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
|||
use crate::inherent::*;
|
||||
use crate::{self as ty, Interner};
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Copy(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub struct OpaqueTypeKey<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
//! refers to rules defined in RFC 1214 (`OutlivesFooBar`), so see that
|
||||
//! RFC for reference.
|
||||
|
||||
use derive_where::derive_where;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use crate::data_structures::SsoHashSet;
|
||||
|
|
@ -9,8 +10,7 @@ use crate::inherent::*;
|
|||
use crate::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt as _, TypeVisitor};
|
||||
use crate::{self as ty, Interner};
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""))]
|
||||
#[derive_where(Debug; I: Interner)]
|
||||
pub enum Component<I: Interner> {
|
||||
Region(I::Region),
|
||||
Param(I::ParamTy),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
|
@ -12,15 +13,12 @@ use crate::visit::TypeVisitableExt as _;
|
|||
use crate::{self as ty, Interner};
|
||||
|
||||
/// `A: 'region`
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "A: Clone"),
|
||||
Copy(bound = "A: Copy"),
|
||||
Hash(bound = "A: Hash"),
|
||||
PartialEq(bound = "A: PartialEq"),
|
||||
Eq(bound = "A: Eq"),
|
||||
Debug(bound = "A: fmt::Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, A: Clone)]
|
||||
#[derive_where(Copy; I: Interner, A: Copy)]
|
||||
#[derive_where(Hash; I: Interner, A: Hash)]
|
||||
#[derive_where(PartialEq; I: Interner, A: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, A: Eq)]
|
||||
#[derive_where(Debug; I: Interner, A: fmt::Debug)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct OutlivesPredicate<I: Interner, A>(pub A, pub I::Region);
|
||||
|
|
@ -50,14 +48,7 @@ where
|
|||
///
|
||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the generic parameters.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct TraitRef<I: Interner> {
|
||||
|
|
@ -122,14 +113,7 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct TraitPredicate<I: Interner> {
|
||||
|
|
@ -243,15 +227,7 @@ impl fmt::Display for PredicatePolarity {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub enum ExistentialPredicate<I: Interner> {
|
||||
|
|
@ -296,14 +272,7 @@ impl<I: Interner> ty::Binder<I, ExistentialPredicate<I>> {
|
|||
/// ```
|
||||
/// The generic parameters don't include the erased `Self`, only trait
|
||||
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct ExistentialTraitRef<I: Interner> {
|
||||
|
|
@ -349,14 +318,7 @@ impl<I: Interner> ty::Binder<I, ExistentialTraitRef<I>> {
|
|||
}
|
||||
|
||||
/// A `ProjectionPredicate` for an `ExistentialTraitRef`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct ExistentialProjection<I: Interner> {
|
||||
|
|
@ -452,15 +414,7 @@ impl AliasTermKind {
|
|||
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
||||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||
/// * For an opaque type, there is no explicit syntax.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct AliasTerm<I: Interner> {
|
||||
|
|
@ -489,7 +443,7 @@ pub struct AliasTerm<I: Interner> {
|
|||
pub def_id: I::DefId,
|
||||
|
||||
/// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`].
|
||||
#[derivative(Debug = "ignore")]
|
||||
#[derive_where(skip(Debug))]
|
||||
_use_alias_term_new_instead: (),
|
||||
}
|
||||
|
||||
|
|
@ -631,14 +585,7 @@ impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> {
|
|||
/// equality between arbitrary types. Processing an instance of
|
||||
/// Form #2 eventually yields one of these `ProjectionPredicate`
|
||||
/// instances to normalize the LHS.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct ProjectionPredicate<I: Interner> {
|
||||
|
|
@ -706,14 +653,7 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> {
|
|||
|
||||
/// Used by the new solver. Unlike a `ProjectionPredicate` this can only be
|
||||
/// proven by actually normalizing `alias`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct NormalizesTo<I: Interner> {
|
||||
|
|
@ -748,15 +688,7 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
|
|||
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
|
||||
/// whether the `a` type is the type that we should label as "expected" when
|
||||
/// presenting user diagnostics.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct SubtypePredicate<I: Interner> {
|
||||
|
|
@ -766,15 +698,7 @@ pub struct SubtypePredicate<I: Interner> {
|
|||
}
|
||||
|
||||
/// Encodes that we have to coerce *from* the `a` type to the `b` type.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct CoercePredicate<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#![allow(clippy::derived_hash_with_manual_eq)]
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
|
@ -7,8 +10,7 @@ use crate::{self as ty, Interner};
|
|||
|
||||
/// A clause is something that can appear in where bounds or be inferred
|
||||
/// by implied bounds.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub enum ClauseKind<I: Interner> {
|
||||
|
|
@ -38,6 +40,7 @@ pub enum ClauseKind<I: Interner> {
|
|||
ConstEvaluatable(I::Const),
|
||||
}
|
||||
|
||||
// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
|
||||
impl<I: Interner> PartialEq for ClauseKind<I> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
|
|
@ -53,14 +56,7 @@ impl<I: Interner> PartialEq for ClauseKind<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub enum PredicateKind<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
#![allow(clippy::derived_hash_with_manual_eq)]
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
|
|
@ -124,8 +127,7 @@ rustc_index::newtype_index! {
|
|||
/// [1]: https://smallcultfollowing.com/babysteps/blog/2013/10/29/intermingled-parameter-lists/
|
||||
/// [2]: https://smallcultfollowing.com/babysteps/blog/2013/11/04/intermingled-parameter-lists/
|
||||
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
|
||||
pub enum RegionKind<I: Interner> {
|
||||
/// A region parameter; for example `'a` in `impl<'a> Trait for &'a ()`.
|
||||
|
|
@ -193,6 +195,7 @@ const fn regionkind_discriminant<I: Interner>(value: &RegionKind<I>) -> usize {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
|
||||
// This is manually implemented because a derive would require `I: PartialEq`
|
||||
impl<I: Interner> PartialEq for RegionKind<I> {
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::iter;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_ast_ir::Mutability;
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
|
|
@ -17,19 +18,11 @@ pub type RelateResult<I, T> = Result<T, TypeError<I>>;
|
|||
/// a miscompilation or unsoundness.
|
||||
///
|
||||
/// When in doubt, use `VarianceDiagInfo::default()`
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Copy(bound = ""),
|
||||
Clone(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Debug, Default; I: Interner)]
|
||||
pub enum VarianceDiagInfo<I: Interner> {
|
||||
/// No additional information - this is the default.
|
||||
/// We will not add any additional information to error messages.
|
||||
#[derivative(Default)]
|
||||
#[derive_where(default)]
|
||||
None,
|
||||
/// We switched our variance because a generic argument occurs inside
|
||||
/// the invariant generic argument of another type.
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use derive_where::derive_where;
|
||||
use rustc_index::IndexVec;
|
||||
|
||||
use super::{AvailableDepth, Cx, StackDepth, StackEntry};
|
||||
use crate::data_structures::{HashMap, HashSet};
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""), Clone(bound = ""), Copy(bound = ""))]
|
||||
#[derive_where(Debug, Clone, Copy; X: Cx)]
|
||||
struct QueryData<X: Cx> {
|
||||
result: X::Result,
|
||||
proof_tree: X::ProofTree,
|
||||
|
|
@ -20,8 +20,7 @@ struct Success<X: Cx> {
|
|||
/// This contains results whose computation never hit the
|
||||
/// recursion limit in `success`, and all results which hit
|
||||
/// the recursion limit in `with_overflow`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
#[derive_where(Default; X: Cx)]
|
||||
struct CacheEntry<X: Cx> {
|
||||
success: Option<Success<X>>,
|
||||
/// We have to be careful when caching roots of cycles.
|
||||
|
|
@ -32,8 +31,7 @@ struct CacheEntry<X: Cx> {
|
|||
with_overflow: HashMap<usize, X::Tracked<QueryData<X>>>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""))]
|
||||
#[derive_where(Debug; X: Cx)]
|
||||
pub(super) struct CacheData<'a, X: Cx> {
|
||||
pub(super) result: X::Result,
|
||||
pub(super) proof_tree: X::ProofTree,
|
||||
|
|
@ -41,11 +39,10 @@ pub(super) struct CacheData<'a, X: Cx> {
|
|||
pub(super) encountered_overflow: bool,
|
||||
// FIXME: This is currently unused, but impacts the design
|
||||
// by requiring a closure for `Cx::with_global_cache`.
|
||||
#[allow(dead_code)]
|
||||
pub(super) nested_goals: &'a HashSet<X::Input>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
#[derive_where(Default; X: Cx)]
|
||||
pub struct GlobalCache<X: Cx> {
|
||||
map: HashMap<X::Input, CacheEntry<X>>,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ use std::hash::Hash;
|
|||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use tracing::debug;
|
||||
|
||||
|
|
@ -153,8 +154,7 @@ rustc_index::newtype_index! {
|
|||
pub struct StackDepth {}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""))]
|
||||
#[derive_where(Debug; X: Cx)]
|
||||
struct StackEntry<X: Cx> {
|
||||
input: X::Input,
|
||||
|
||||
|
|
@ -226,8 +226,7 @@ struct DetachedEntry<X: Cx> {
|
|||
///
|
||||
/// The provisional cache can theoretically result in changes to the observable behavior,
|
||||
/// see tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Default(bound = ""))]
|
||||
#[derive_where(Default; X: Cx)]
|
||||
struct ProvisionalCacheEntry<X: Cx> {
|
||||
stack_depth: Option<StackDepth>,
|
||||
with_inductive_stack: Option<DetachedEntry<X>>,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use crate::solve::{
|
|||
CandidateSource, CanonicalInput, Certainty, Goal, GoalSource, QueryInput, QueryResult,
|
||||
};
|
||||
use crate::{Canonical, CanonicalVarValues, Interner};
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
|
@ -31,15 +32,12 @@ use std::hash::Hash;
|
|||
/// This is only ever used as [CanonicalState]. Any type information in proof
|
||||
/// trees used mechanically has to be canonicalized as we otherwise leak
|
||||
/// inference variables from a nested `InferCtxt`.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "T: Clone"),
|
||||
Copy(bound = "T: Copy"),
|
||||
PartialEq(bound = "T: PartialEq"),
|
||||
Eq(bound = "T: Eq"),
|
||||
Hash(bound = "T: Hash"),
|
||||
Debug(bound = "T: Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, T: Clone)]
|
||||
#[derive_where(Copy; I: Interner, T: Copy)]
|
||||
#[derive_where(PartialEq; I: Interner, T: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, T: Eq)]
|
||||
#[derive_where(Hash; I: Interner, T: Hash)]
|
||||
#[derive_where(Debug; I: Interner, T: Debug)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub struct State<I: Interner, T> {
|
||||
pub var_values: CanonicalVarValues<I>,
|
||||
|
|
@ -52,24 +50,21 @@ pub type CanonicalState<I, T> = Canonical<I, State<I, T>>;
|
|||
/// for the `CanonicalVarValues` of the canonicalized goal.
|
||||
/// We use this to map any [CanonicalState] from the local `InferCtxt`
|
||||
/// of the solver query to the `InferCtxt` of the caller.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash; I: Interner)]
|
||||
pub struct GoalEvaluation<I: Interner> {
|
||||
pub uncanonicalized_goal: Goal<I, I::Predicate>,
|
||||
pub orig_values: Vec<I::GenericArg>,
|
||||
pub evaluation: CanonicalGoalEvaluation<I>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
pub struct CanonicalGoalEvaluation<I: Interner> {
|
||||
pub goal: CanonicalInput<I>,
|
||||
pub kind: CanonicalGoalEvaluationKind<I>,
|
||||
pub result: QueryResult<I>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
pub enum CanonicalGoalEvaluationKind<I: Interner> {
|
||||
Overflow,
|
||||
CycleInStack,
|
||||
|
|
@ -77,8 +72,7 @@ pub enum CanonicalGoalEvaluationKind<I: Interner> {
|
|||
Evaluation { final_revision: I::CanonicalGoalEvaluationStepRef },
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
pub struct CanonicalGoalEvaluationStep<I: Interner> {
|
||||
pub instantiated_goal: QueryInput<I, I::Predicate>,
|
||||
|
||||
|
|
@ -89,8 +83,7 @@ pub struct CanonicalGoalEvaluationStep<I: Interner> {
|
|||
/// A self-contained computation during trait solving. This either
|
||||
/// corresponds to a `EvalCtxt::probe(_X)` call or the root evaluation
|
||||
/// of a goal.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug(bound = ""), PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
pub struct Probe<I: Interner> {
|
||||
/// What happened inside of this probe in chronological order.
|
||||
pub steps: Vec<ProbeStep<I>>,
|
||||
|
|
@ -98,8 +91,7 @@ pub struct Probe<I: Interner> {
|
|||
pub final_state: CanonicalState<I, ()>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Hash(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
pub enum ProbeStep<I: Interner> {
|
||||
/// We added a goal to the `EvalCtxt` which will get proven
|
||||
/// the next time `EvalCtxt::try_evaluate_added_goals` is called.
|
||||
|
|
@ -121,15 +113,7 @@ pub enum ProbeStep<I: Interner> {
|
|||
/// What kind of probe we're in. In case the probe represents a candidate, or
|
||||
/// the final result of the current goal - via [ProbeKind::Root] - we also
|
||||
/// store the [QueryResult].
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Hash(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub enum ProbeKind<I: Interner> {
|
||||
/// The root inference context while proving a goal.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ pub mod inspect;
|
|||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
|
||||
use derive_where::derive_where;
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
|
@ -89,15 +90,12 @@ pub struct NoSolution;
|
|||
///
|
||||
/// Most of the time the `param_env` contains the `where`-bounds of the function
|
||||
/// we're currently typechecking while the `predicate` is some trait bound.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "P: Clone"),
|
||||
Copy(bound = "P: Copy"),
|
||||
Hash(bound = "P: Hash"),
|
||||
PartialEq(bound = "P: PartialEq"),
|
||||
Eq(bound = "P: Eq"),
|
||||
Debug(bound = "P: fmt::Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, P: Clone)]
|
||||
#[derive_where(Copy; I: Interner, P: Copy)]
|
||||
#[derive_where(Hash; I: Interner, P: Hash)]
|
||||
#[derive_where(PartialEq; I: Interner, P: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, P: Eq)]
|
||||
#[derive_where(Debug; I: Interner, P: fmt::Debug)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct Goal<I: Interner, P> {
|
||||
|
|
@ -140,15 +138,12 @@ pub enum GoalSource {
|
|||
InstantiateHigherRanked,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = "Goal<I, P>: Clone"),
|
||||
Copy(bound = "Goal<I, P>: Copy"),
|
||||
Hash(bound = "Goal<I, P>: Hash"),
|
||||
PartialEq(bound = "Goal<I, P>: PartialEq"),
|
||||
Eq(bound = "Goal<I, P>: Eq"),
|
||||
Debug(bound = "Goal<I, P>: fmt::Debug")
|
||||
)]
|
||||
#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
|
||||
#[derive_where(Copy; I: Interner, Goal<I, P>: Copy)]
|
||||
#[derive_where(Hash; I: Interner, Goal<I, P>: Hash)]
|
||||
#[derive_where(PartialEq; I: Interner, Goal<I, P>: PartialEq)]
|
||||
#[derive_where(Eq; I: Interner, Goal<I, P>: Eq)]
|
||||
#[derive_where(Debug; I: Interner, Goal<I, P>: fmt::Debug)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct QueryInput<I: Interner, P> {
|
||||
|
|
@ -157,15 +152,7 @@ pub struct QueryInput<I: Interner, P> {
|
|||
}
|
||||
|
||||
/// Opaques that are defined in the inference context before a query is called.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct PredefinedOpaquesData<I: Interner> {
|
||||
|
|
@ -173,15 +160,7 @@ pub struct PredefinedOpaquesData<I: Interner> {
|
|||
}
|
||||
|
||||
/// Possible ways the given goal can be proven.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
pub enum CandidateSource<I: Interner> {
|
||||
/// A user written impl.
|
||||
///
|
||||
|
|
@ -265,15 +244,7 @@ pub enum BuiltinImplSource {
|
|||
TupleUnsizing,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct Response<I: Interner> {
|
||||
|
|
@ -284,15 +255,7 @@ pub struct Response<I: Interner> {
|
|||
}
|
||||
|
||||
/// Additional constraints returned on success.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct ExternalConstraintsData<I: Interner> {
|
||||
|
|
@ -301,15 +264,7 @@ pub struct ExternalConstraintsData<I: Interner> {
|
|||
pub normalization_nested_goals: NestedNormalizationGoals<I>,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = ""),
|
||||
Default(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Hash, PartialEq, Eq, Debug, Default; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||
pub struct NestedNormalizationGoals<I: Interner>(pub Vec<(GoalSource, Goal<I, I::Predicate>)>);
|
||||
|
|
@ -386,8 +341,7 @@ impl MaybeCause {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(PartialEq(bound = ""), Eq(bound = ""), Debug(bound = ""))]
|
||||
#[derive_where(PartialEq, Eq, Debug; I: Interner)]
|
||||
pub struct CacheData<I: Interner> {
|
||||
pub result: QueryResult<I>,
|
||||
pub proof_tree: Option<I::CanonicalGoalEvaluationStepRef>,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
#![allow(clippy::derived_hash_with_manual_eq)]
|
||||
|
||||
use derive_where::derive_where;
|
||||
|
||||
#[cfg(feature = "nightly")]
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
#[cfg(feature = "nightly")]
|
||||
|
|
@ -64,8 +68,7 @@ impl AliasTyKind {
|
|||
/// Types written by the user start out as `hir::TyKind` and get
|
||||
/// converted to this representation using `<dyn HirTyLowerer>::lower_ty`.
|
||||
#[cfg_attr(feature = "nightly", rustc_diagnostic_item = "IrTyKind")]
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Clone(bound = ""), Copy(bound = ""), Hash(bound = ""), Eq(bound = ""))]
|
||||
#[derive_where(Clone, Copy, Hash, Eq; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
pub enum TyKind<I: Interner> {
|
||||
/// The primitive boolean type. Written as `bool`.
|
||||
|
|
@ -292,6 +295,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME(GrigorenkoPV): consider not implementing PartialEq manually
|
||||
// This is manually implemented because a derive would require `I: PartialEq`
|
||||
impl<I: Interner> PartialEq for TyKind<I> {
|
||||
#[inline]
|
||||
|
|
@ -414,15 +418,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
|
|||
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
||||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||
/// * For an opaque type, there is no explicit syntax.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||
pub struct AliasTy<I: Interner> {
|
||||
|
|
@ -451,7 +447,7 @@ pub struct AliasTy<I: Interner> {
|
|||
pub def_id: I::DefId,
|
||||
|
||||
/// This field exists to prevent the creation of `AliasTy` without using [`AliasTy::new_from_args`].
|
||||
#[derivative(Debug = "ignore")]
|
||||
#[derive_where(skip(Debug))]
|
||||
pub(crate) _use_alias_ty_new_instead: (),
|
||||
}
|
||||
|
||||
|
|
@ -942,15 +938,7 @@ impl fmt::Debug for InferTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Hash(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub struct TypeAndMut<I: Interner> {
|
||||
|
|
@ -958,14 +946,7 @@ pub struct TypeAndMut<I: Interner> {
|
|||
pub mutbl: Mutability,
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Hash(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash; I: Interner)]
|
||||
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct FnSig<I: Interner> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::ops::ControlFlow;
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
|
||||
use crate::fold::{shift_region, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
|
|
@ -100,15 +101,7 @@ use crate::{self as ty, Interner};
|
|||
/// * `GR`: The "return type", which is the type of value returned upon
|
||||
/// completion of the coroutine.
|
||||
/// * `GW`: The "coroutine witness".
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct ClosureArgs<I: Interner> {
|
||||
/// Lifetime and type parameters from the enclosing function,
|
||||
|
|
@ -210,15 +203,7 @@ impl<I: Interner> ClosureArgs<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CoroutineClosureArgs<I: Interner> {
|
||||
pub args: I::GenericArgs,
|
||||
|
|
@ -370,15 +355,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub struct CoroutineClosureSignature<I: Interner> {
|
||||
pub interior: I::Ty,
|
||||
|
|
@ -552,15 +529,7 @@ impl<I: Interner> TypeFolder<I> for FoldEscapingRegions<I> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||
pub struct GenSig<I: Interner> {
|
||||
pub resume_ty: I::Ty,
|
||||
|
|
@ -569,15 +538,7 @@ pub struct GenSig<I: Interner> {
|
|||
}
|
||||
|
||||
/// Similar to `ClosureArgs`; see the above documentation for more.
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(
|
||||
Clone(bound = ""),
|
||||
Copy(bound = ""),
|
||||
Hash(bound = ""),
|
||||
PartialEq(bound = ""),
|
||||
Eq(bound = ""),
|
||||
Debug(bound = "")
|
||||
)]
|
||||
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
|
||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||
pub struct CoroutineArgs<I: Interner> {
|
||||
pub args: I::GenericArgs,
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
scoped-tls = "1.0"
|
||||
serde = { version = "1.0.125", features = [ "derive" ] }
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ use crate::target::{MachineInfo, MachineSize as Size};
|
|||
use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
|
||||
use crate::Error;
|
||||
use crate::Opaque;
|
||||
use serde::Serialize;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::num::NonZero;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
/// A function ABI definition.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct FnAbi {
|
||||
/// The types of each argument.
|
||||
pub args: Vec<ArgAbi>,
|
||||
|
|
@ -31,7 +32,7 @@ pub struct FnAbi {
|
|||
}
|
||||
|
||||
/// Information about the ABI of a function's argument, or return value.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct ArgAbi {
|
||||
pub ty: Ty,
|
||||
pub layout: Layout,
|
||||
|
|
@ -39,7 +40,7 @@ pub struct ArgAbi {
|
|||
}
|
||||
|
||||
/// How a function argument should be passed in to the target function.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum PassMode {
|
||||
/// Ignore the argument.
|
||||
///
|
||||
|
|
@ -60,14 +61,14 @@ pub enum PassMode {
|
|||
}
|
||||
|
||||
/// The layout of a type, alongside the type itself.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct TyAndLayout {
|
||||
pub ty: Ty,
|
||||
pub layout: Layout,
|
||||
}
|
||||
|
||||
/// The layout of a type in memory.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct LayoutShape {
|
||||
/// The fields location withing the layout
|
||||
pub fields: FieldsShape,
|
||||
|
|
@ -108,7 +109,7 @@ impl LayoutShape {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct Layout(usize);
|
||||
|
||||
impl Layout {
|
||||
|
|
@ -127,7 +128,7 @@ impl IndexedVal for Layout {
|
|||
}
|
||||
|
||||
/// Describes how the fields of a type are shaped in memory.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum FieldsShape {
|
||||
/// Scalar primitives and `!`, which never have fields.
|
||||
Primitive,
|
||||
|
|
@ -177,7 +178,7 @@ impl FieldsShape {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum VariantsShape {
|
||||
/// Single enum variants, structs/tuples, unions, and all non-ADTs.
|
||||
Single { index: VariantIdx },
|
||||
|
|
@ -196,7 +197,7 @@ pub enum VariantsShape {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum TagEncoding {
|
||||
/// The tag directly stores the discriminant, but possibly with a smaller layout
|
||||
/// (so converting the tag to the discriminant can require sign extension).
|
||||
|
|
@ -221,7 +222,7 @@ pub enum TagEncoding {
|
|||
|
||||
/// Describes how values of the type are passed by target ABIs,
|
||||
/// in terms of categories of C types there are ABI rules for.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum ValueAbi {
|
||||
Uninhabited,
|
||||
Scalar(Scalar),
|
||||
|
|
@ -250,7 +251,7 @@ impl ValueAbi {
|
|||
}
|
||||
|
||||
/// Information about one scalar component of a Rust type.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Serialize)]
|
||||
pub enum Scalar {
|
||||
Initialized {
|
||||
/// The primitive type used to represent this value.
|
||||
|
|
@ -280,7 +281,7 @@ impl Scalar {
|
|||
}
|
||||
|
||||
/// Fundamental unit of memory access and layout.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Serialize)]
|
||||
pub enum Primitive {
|
||||
/// The `bool` is the signedness of the `Integer` type.
|
||||
///
|
||||
|
|
@ -310,7 +311,7 @@ impl Primitive {
|
|||
}
|
||||
|
||||
/// Enum representing the existing integer lengths.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
|
||||
pub enum IntegerLength {
|
||||
I8,
|
||||
I16,
|
||||
|
|
@ -320,7 +321,7 @@ pub enum IntegerLength {
|
|||
}
|
||||
|
||||
/// Enum representing the existing float lengths.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
|
||||
pub enum FloatLength {
|
||||
F16,
|
||||
F32,
|
||||
|
|
@ -354,7 +355,7 @@ impl FloatLength {
|
|||
/// An identifier that specifies the address space that some operation
|
||||
/// should operate on. Special address spaces have an effect on code generation,
|
||||
/// depending on the target and the address spaces it implements.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||
pub struct AddressSpace(pub u32);
|
||||
|
||||
impl AddressSpace {
|
||||
|
|
@ -369,7 +370,7 @@ impl AddressSpace {
|
|||
/// sequence:
|
||||
///
|
||||
/// 254 (-2), 255 (-1), 0, 1, 2
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct WrappingRange {
|
||||
pub start: u128,
|
||||
pub end: u128,
|
||||
|
|
@ -420,7 +421,7 @@ impl Debug for WrappingRange {
|
|||
}
|
||||
|
||||
/// General language calling conventions.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum CallConvention {
|
||||
C,
|
||||
Rust,
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
|
||||
use crate::ty::{GenericArgs, Span, Ty};
|
||||
use crate::{with, Crate, Symbol};
|
||||
use serde::Serialize;
|
||||
|
||||
/// A unique identification number for each item accessible for the current compilation unit.
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct DefId(pub(crate) usize);
|
||||
|
||||
/// A trait for retrieving information about a particular definition.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ pub use crate::error::*;
|
|||
use crate::mir::Body;
|
||||
use crate::mir::Mutability;
|
||||
use crate::ty::{ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
|
||||
use serde::Serialize;
|
||||
|
||||
pub mod abi;
|
||||
#[macro_use]
|
||||
|
|
@ -74,7 +75,7 @@ pub type TraitDecls = Vec<TraitDef>;
|
|||
pub type ImplTraitDecls = Vec<ImplDef>;
|
||||
|
||||
/// Holds information about a crate.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
pub struct Crate {
|
||||
pub id: CrateNum,
|
||||
pub name: Symbol,
|
||||
|
|
@ -98,7 +99,7 @@ impl Crate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub enum ItemKind {
|
||||
Fn,
|
||||
Static,
|
||||
|
|
@ -106,7 +107,7 @@ pub enum ItemKind {
|
|||
Ctor(CtorKind),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub enum CtorKind {
|
||||
Const,
|
||||
Fn,
|
||||
|
|
@ -116,6 +117,7 @@ pub type Filename = String;
|
|||
|
||||
crate_def_with_ty! {
|
||||
/// Holds information about an item in a crate.
|
||||
#[derive(Serialize)]
|
||||
pub CrateItem;
|
||||
}
|
||||
|
||||
|
|
@ -188,7 +190,7 @@ pub fn all_trait_impls() -> ImplTraitDecls {
|
|||
}
|
||||
|
||||
/// A type that provides internal information but that can still be used for debug purpose.
|
||||
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct Opaque(String);
|
||||
|
||||
impl std::fmt::Display for Opaque {
|
||||
|
|
|
|||
|
|
@ -4,11 +4,12 @@ use crate::mir::mono::{Instance, StaticDef};
|
|||
use crate::target::{Endian, MachineInfo};
|
||||
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
|
||||
use crate::{with, Error};
|
||||
use serde::Serialize;
|
||||
use std::io::Read;
|
||||
|
||||
/// An allocation in the SMIR global memory can be either a function pointer,
|
||||
/// a static, or a "real" allocation with some data in it.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||
pub enum GlobalAlloc {
|
||||
/// The alloc ID is used as a function pointer.
|
||||
Function(Instance),
|
||||
|
|
@ -41,7 +42,7 @@ impl GlobalAlloc {
|
|||
}
|
||||
|
||||
/// A unique identification number for each provenance
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub struct AllocId(usize);
|
||||
|
||||
impl IndexedVal for AllocId {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ use crate::ty::{
|
|||
TyConst, TyKind, VariantIdx,
|
||||
};
|
||||
use crate::{Error, Opaque, Span, Symbol};
|
||||
use serde::Serialize;
|
||||
use std::io;
|
||||
|
||||
/// The SMIR representation of a single function.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
pub struct Body {
|
||||
pub blocks: Vec<BasicBlock>,
|
||||
|
||||
|
|
@ -104,20 +105,20 @@ impl Body {
|
|||
|
||||
type LocalDecls = Vec<LocalDecl>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct LocalDecl {
|
||||
pub ty: Ty,
|
||||
pub span: Span,
|
||||
pub mutability: Mutability,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
pub struct BasicBlock {
|
||||
pub statements: Vec<Statement>,
|
||||
pub terminator: Terminator,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Terminator {
|
||||
pub kind: TerminatorKind,
|
||||
pub span: Span,
|
||||
|
|
@ -131,7 +132,7 @@ impl Terminator {
|
|||
|
||||
pub type Successors = Vec<BasicBlockIdx>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum TerminatorKind {
|
||||
Goto {
|
||||
target: BasicBlockIdx,
|
||||
|
|
@ -221,7 +222,7 @@ impl TerminatorKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct InlineAsmOperand {
|
||||
pub in_value: Option<Operand>,
|
||||
pub out_place: Option<Place>,
|
||||
|
|
@ -230,7 +231,7 @@ pub struct InlineAsmOperand {
|
|||
pub raw_rpr: String,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum UnwindAction {
|
||||
Continue,
|
||||
Unreachable,
|
||||
|
|
@ -238,7 +239,7 @@ pub enum UnwindAction {
|
|||
Cleanup(BasicBlockIdx),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum AssertMessage {
|
||||
BoundsCheck { len: Operand, index: Operand },
|
||||
Overflow(BinOp, Operand, Operand),
|
||||
|
|
@ -307,7 +308,7 @@ impl AssertMessage {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum BinOp {
|
||||
Add,
|
||||
AddUnchecked,
|
||||
|
|
@ -342,7 +343,7 @@ impl BinOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum UnOp {
|
||||
Not,
|
||||
Neg,
|
||||
|
|
@ -357,20 +358,20 @@ impl UnOp {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum CoroutineKind {
|
||||
Desugared(CoroutineDesugaring, CoroutineSource),
|
||||
Coroutine(Movability),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum CoroutineSource {
|
||||
Block,
|
||||
Closure,
|
||||
Fn,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum CoroutineDesugaring {
|
||||
Async,
|
||||
|
||||
|
|
@ -386,7 +387,7 @@ pub(crate) type LocalDefId = Opaque;
|
|||
pub(crate) type Coverage = Opaque;
|
||||
|
||||
/// The FakeReadCause describes the type of pattern why a FakeRead statement exists.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum FakeReadCause {
|
||||
ForMatchGuard,
|
||||
ForMatchedPlace(LocalDefId),
|
||||
|
|
@ -396,7 +397,7 @@ pub enum FakeReadCause {
|
|||
}
|
||||
|
||||
/// Describes what kind of retag is to be performed
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum RetagKind {
|
||||
FnEntry,
|
||||
TwoPhase,
|
||||
|
|
@ -404,7 +405,7 @@ pub enum RetagKind {
|
|||
Default,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub enum Variance {
|
||||
Covariant,
|
||||
Invariant,
|
||||
|
|
@ -412,26 +413,26 @@ pub enum Variance {
|
|||
Bivariant,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct CopyNonOverlapping {
|
||||
pub src: Operand,
|
||||
pub dst: Operand,
|
||||
pub count: Operand,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum NonDivergingIntrinsic {
|
||||
Assume(Operand),
|
||||
CopyNonOverlapping(CopyNonOverlapping),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Statement {
|
||||
pub kind: StatementKind,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum StatementKind {
|
||||
Assign(Place, Rvalue),
|
||||
FakeRead(FakeReadCause, Place),
|
||||
|
|
@ -448,7 +449,7 @@ pub enum StatementKind {
|
|||
Nop,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum Rvalue {
|
||||
/// Creates a pointer with the indicated mutability to the place.
|
||||
///
|
||||
|
|
@ -622,7 +623,7 @@ impl Rvalue {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum AggregateKind {
|
||||
Array(Ty),
|
||||
Tuple,
|
||||
|
|
@ -633,14 +634,14 @@ pub enum AggregateKind {
|
|||
RawPtr(Ty, Mutability),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum Operand {
|
||||
Copy(Place),
|
||||
Move(Place),
|
||||
Constant(ConstOperand),
|
||||
}
|
||||
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
#[derive(Clone, Eq, PartialEq, Serialize)]
|
||||
pub struct Place {
|
||||
pub local: Local,
|
||||
/// projection out of a place (access a field, deref a pointer, etc)
|
||||
|
|
@ -653,7 +654,7 @@ impl From<Local> for Place {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ConstOperand {
|
||||
pub span: Span,
|
||||
pub user_ty: Option<UserTypeAnnotationIndex>,
|
||||
|
|
@ -661,7 +662,7 @@ pub struct ConstOperand {
|
|||
}
|
||||
|
||||
/// Debug information pertaining to a user variable.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct VarDebugInfo {
|
||||
/// The variable name.
|
||||
pub name: Symbol,
|
||||
|
|
@ -703,19 +704,19 @@ impl VarDebugInfo {
|
|||
|
||||
pub type SourceScope = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct SourceInfo {
|
||||
pub span: Span,
|
||||
pub scope: SourceScope,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct VarDebugInfoFragment {
|
||||
pub ty: Ty,
|
||||
pub projection: Vec<ProjectionElem>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum VarDebugInfoContents {
|
||||
Place(Place),
|
||||
Const(ConstOperand),
|
||||
|
|
@ -726,7 +727,7 @@ pub enum VarDebugInfoContents {
|
|||
// ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements
|
||||
// are of type ProjectionElem<(), ()>). In SMIR we don't need this generality, so we just use
|
||||
// ProjectionElem for Places.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ProjectionElem {
|
||||
/// Dereference projections (e.g. `*_1`) project to the address referenced by the base place.
|
||||
Deref,
|
||||
|
|
@ -800,7 +801,7 @@ pub enum ProjectionElem {
|
|||
Subtype(Ty),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct UserTypeProjection {
|
||||
pub base: UserTypeAnnotationIndex,
|
||||
|
||||
|
|
@ -830,7 +831,7 @@ pub type FieldIdx = usize;
|
|||
type UserTypeAnnotationIndex = usize;
|
||||
|
||||
/// The possible branch sites of a [TerminatorKind::SwitchInt].
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct SwitchTargets {
|
||||
/// The conditional branches where the first element represents the value that guards this
|
||||
/// branch, and the second element is the branch target.
|
||||
|
|
@ -867,7 +868,7 @@ impl SwitchTargets {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum BorrowKind {
|
||||
/// Data must be immutable and is aliasable.
|
||||
Shared,
|
||||
|
|
@ -894,14 +895,14 @@ impl BorrowKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum MutBorrowKind {
|
||||
Default,
|
||||
TwoPhaseBorrow,
|
||||
ClosureCapture,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum FakeBorrowKind {
|
||||
/// A shared (deep) borrow. Data must be immutable and is aliasable.
|
||||
Deep,
|
||||
|
|
@ -912,19 +913,19 @@ pub enum FakeBorrowKind {
|
|||
Shallow,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum Mutability {
|
||||
Not,
|
||||
Mut,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum Safety {
|
||||
Safe,
|
||||
Unsafe,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum PointerCoercion {
|
||||
/// Go from a fn-item type to a fn-pointer type.
|
||||
ReifyFnPointer,
|
||||
|
|
@ -951,7 +952,7 @@ pub enum PointerCoercion {
|
|||
Unsize,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum CastKind {
|
||||
// FIXME(smir-rename): rename this to PointerExposeProvenance
|
||||
PointerExposeAddress,
|
||||
|
|
@ -967,7 +968,7 @@ pub enum CastKind {
|
|||
Transmute,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum NullOp {
|
||||
/// Returns the size of a value of that type.
|
||||
SizeOf,
|
||||
|
|
|
|||
|
|
@ -3,17 +3,18 @@ use crate::crate_def::CrateDef;
|
|||
use crate::mir::Body;
|
||||
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
|
||||
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
|
||||
use serde::Serialize;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::io;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum MonoItem {
|
||||
Fn(Instance),
|
||||
Static(StaticDef),
|
||||
GlobalAsm(Opaque),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct Instance {
|
||||
/// The type of instance.
|
||||
pub kind: InstanceKind,
|
||||
|
|
@ -22,7 +23,7 @@ pub struct Instance {
|
|||
pub def: InstanceDef,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub enum InstanceKind {
|
||||
/// A user defined item.
|
||||
Item,
|
||||
|
|
@ -240,7 +241,7 @@ impl From<StaticDef> for CrateItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct InstanceDef(usize);
|
||||
|
||||
impl CrateDef for InstanceDef {
|
||||
|
|
@ -251,6 +252,7 @@ impl CrateDef for InstanceDef {
|
|||
|
||||
crate_def! {
|
||||
/// Holds information about a static variable definition.
|
||||
#[derive(Serialize)]
|
||||
pub StaticDef;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
//! Provide information about the machine that this is being compiled into.
|
||||
|
||||
use crate::compiler_interface::with;
|
||||
use serde::Serialize;
|
||||
|
||||
/// The properties of the target machine being compiled into.
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
#[derive(Clone, PartialEq, Eq, Serialize)]
|
||||
pub struct MachineInfo {
|
||||
pub endian: Endian,
|
||||
pub pointer_width: MachineSize,
|
||||
|
|
@ -23,14 +24,14 @@ impl MachineInfo {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Serialize)]
|
||||
pub enum Endian {
|
||||
Little,
|
||||
Big,
|
||||
}
|
||||
|
||||
/// Represent the size of a component.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Serialize)]
|
||||
pub struct MachineSize {
|
||||
num_bits: usize,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@ use crate::mir::alloc::{read_target_int, read_target_uint, AllocId};
|
|||
use crate::mir::mono::StaticDef;
|
||||
use crate::target::MachineInfo;
|
||||
use crate::{Filename, Opaque};
|
||||
use serde::Serialize;
|
||||
use std::fmt::{self, Debug, Display, Formatter};
|
||||
use std::ops::Range;
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct Ty(usize);
|
||||
|
||||
impl Debug for Ty {
|
||||
|
|
@ -100,13 +101,13 @@ impl Ty {
|
|||
}
|
||||
|
||||
/// Represents a pattern in the type system
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum Pattern {
|
||||
Range { start: Option<TyConst>, end: Option<TyConst>, include_end: bool },
|
||||
}
|
||||
|
||||
/// Represents a constant in the type system
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TyConst {
|
||||
pub(crate) kind: TyConstKind,
|
||||
pub id: TyConstId,
|
||||
|
|
@ -133,7 +134,7 @@ impl TyConst {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum TyConstKind {
|
||||
Param(ParamConst),
|
||||
Bound(DebruijnIndex, BoundVar),
|
||||
|
|
@ -144,11 +145,11 @@ pub enum TyConstKind {
|
|||
ZSTValue(Ty),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TyConstId(usize);
|
||||
|
||||
/// Represents a constant in MIR
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct MirConst {
|
||||
/// The constant kind.
|
||||
pub(crate) kind: ConstantKind,
|
||||
|
|
@ -205,17 +206,17 @@ impl MirConst {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub struct MirConstId(usize);
|
||||
|
||||
type Ident = Opaque;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Region {
|
||||
pub kind: RegionKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum RegionKind {
|
||||
ReEarlyParam(EarlyParamRegion),
|
||||
ReBound(DebruijnIndex, BoundRegion),
|
||||
|
|
@ -226,7 +227,7 @@ pub enum RegionKind {
|
|||
|
||||
pub(crate) type DebruijnIndex = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct EarlyParamRegion {
|
||||
pub index: u32,
|
||||
pub name: Symbol,
|
||||
|
|
@ -234,7 +235,7 @@ pub struct EarlyParamRegion {
|
|||
|
||||
pub(crate) type BoundVar = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct BoundRegion {
|
||||
pub var: BoundVar,
|
||||
pub kind: BoundRegionKind,
|
||||
|
|
@ -242,13 +243,13 @@ pub struct BoundRegion {
|
|||
|
||||
pub(crate) type UniverseIndex = u32;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Placeholder<T> {
|
||||
pub universe: UniverseIndex,
|
||||
pub bound: T,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Serialize)]
|
||||
pub struct Span(usize);
|
||||
|
||||
impl Debug for Span {
|
||||
|
|
@ -272,7 +273,7 @@ impl Span {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Serialize)]
|
||||
/// Information you get from `Span` in a struct form.
|
||||
/// Line and col start from 1.
|
||||
pub struct LineInfo {
|
||||
|
|
@ -282,7 +283,7 @@ pub struct LineInfo {
|
|||
pub end_col: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum TyKind {
|
||||
RigidTy(RigidTy),
|
||||
Alias(AliasKind, AliasTy),
|
||||
|
|
@ -521,7 +522,7 @@ pub struct TypeAndMut {
|
|||
pub mutability: Mutability,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum RigidTy {
|
||||
Bool,
|
||||
Char,
|
||||
|
|
@ -560,7 +561,7 @@ impl From<RigidTy> for TyKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub enum IntTy {
|
||||
Isize,
|
||||
I8,
|
||||
|
|
@ -583,7 +584,7 @@ impl IntTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub enum UintTy {
|
||||
Usize,
|
||||
U8,
|
||||
|
|
@ -606,7 +607,7 @@ impl UintTy {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub enum FloatTy {
|
||||
F16,
|
||||
F32,
|
||||
|
|
@ -614,13 +615,14 @@ pub enum FloatTy {
|
|||
F128,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub enum Movability {
|
||||
Static,
|
||||
Movable,
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub ForeignModuleDef;
|
||||
}
|
||||
|
||||
|
|
@ -643,6 +645,7 @@ impl ForeignModule {
|
|||
|
||||
crate_def_with_ty! {
|
||||
/// Hold information about a ForeignItem in a crate.
|
||||
#[derive(Serialize)]
|
||||
pub ForeignDef;
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +655,7 @@ impl ForeignDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub enum ForeignItemKind {
|
||||
Fn(FnDef),
|
||||
Static(StaticDef),
|
||||
|
|
@ -661,6 +664,7 @@ pub enum ForeignItemKind {
|
|||
|
||||
crate_def_with_ty! {
|
||||
/// Hold information about a function definition in a crate.
|
||||
#[derive(Serialize)]
|
||||
pub FnDef;
|
||||
}
|
||||
|
||||
|
|
@ -694,6 +698,7 @@ impl FnDef {
|
|||
}
|
||||
|
||||
crate_def_with_ty! {
|
||||
#[derive(Serialize)]
|
||||
pub IntrinsicDef;
|
||||
}
|
||||
|
||||
|
|
@ -718,26 +723,31 @@ impl From<IntrinsicDef> for FnDef {
|
|||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub ClosureDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub CoroutineDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub ParamDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub BrNamedDef;
|
||||
}
|
||||
|
||||
crate_def_with_ty! {
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub AdtDef;
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub enum AdtKind {
|
||||
Enum,
|
||||
Union,
|
||||
|
|
@ -791,7 +801,7 @@ impl AdtDef {
|
|||
}
|
||||
|
||||
/// Definition of a variant, which can be either a struct / union field or an enum variant.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct VariantDef {
|
||||
/// The variant index.
|
||||
///
|
||||
|
|
@ -820,7 +830,7 @@ impl VariantDef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct FieldDef {
|
||||
/// The field definition.
|
||||
///
|
||||
|
|
@ -871,11 +881,13 @@ impl AdtKind {
|
|||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub AliasDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
/// A trait's definition.
|
||||
#[derive(Serialize)]
|
||||
pub TraitDef;
|
||||
}
|
||||
|
||||
|
|
@ -886,15 +898,18 @@ impl TraitDef {
|
|||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub GenericDef;
|
||||
}
|
||||
|
||||
crate_def_with_ty! {
|
||||
#[derive(Serialize)]
|
||||
pub ConstDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
/// A trait impl definition.
|
||||
#[derive(Serialize)]
|
||||
pub ImplDef;
|
||||
}
|
||||
|
||||
|
|
@ -906,15 +921,17 @@ impl ImplDef {
|
|||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub RegionDef;
|
||||
}
|
||||
|
||||
crate_def! {
|
||||
#[derive(Serialize)]
|
||||
pub CoroutineWitnessDef;
|
||||
}
|
||||
|
||||
/// A list of generic arguments.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct GenericArgs(pub Vec<GenericArgKind>);
|
||||
|
||||
impl std::ops::Index<ParamTy> for GenericArgs {
|
||||
|
|
@ -933,7 +950,7 @@ impl std::ops::Index<ParamConst> for GenericArgs {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum GenericArgKind {
|
||||
Lifetime(Region),
|
||||
Type(Ty),
|
||||
|
|
@ -970,13 +987,13 @@ impl GenericArgKind {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum TermKind {
|
||||
Type(Ty),
|
||||
Const(TyConst),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum AliasKind {
|
||||
Projection,
|
||||
Inherent,
|
||||
|
|
@ -984,13 +1001,13 @@ pub enum AliasKind {
|
|||
Weak,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct AliasTy {
|
||||
pub def_id: AliasDef,
|
||||
pub args: GenericArgs,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct AliasTerm {
|
||||
pub def_id: AliasDef,
|
||||
pub args: GenericArgs,
|
||||
|
|
@ -1008,7 +1025,7 @@ impl PolyFnSig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct FnSig {
|
||||
pub inputs_and_output: Vec<Ty>,
|
||||
pub c_variadic: bool,
|
||||
|
|
@ -1026,7 +1043,7 @@ impl FnSig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
pub enum Abi {
|
||||
Rust,
|
||||
C { unwind: bool },
|
||||
|
|
@ -1055,7 +1072,7 @@ pub enum Abi {
|
|||
}
|
||||
|
||||
/// A binder represents a possibly generic type and its bound vars.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Binder<T> {
|
||||
pub value: T,
|
||||
pub bound_vars: Vec<BoundVariableKind>,
|
||||
|
|
@ -1095,38 +1112,38 @@ impl<T> Binder<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct EarlyBinder<T> {
|
||||
pub value: T,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum BoundVariableKind {
|
||||
Ty(BoundTyKind),
|
||||
Region(BoundRegionKind),
|
||||
Const,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
|
||||
pub enum BoundTyKind {
|
||||
Anon,
|
||||
Param(ParamDef, String),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum BoundRegionKind {
|
||||
BrAnon,
|
||||
BrNamed(BrNamedDef, String),
|
||||
BrEnv,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum DynKind {
|
||||
Dyn,
|
||||
DynStar,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ExistentialPredicate {
|
||||
Trait(ExistentialTraitRef),
|
||||
Projection(ExistentialProjection),
|
||||
|
|
@ -1136,7 +1153,7 @@ pub enum ExistentialPredicate {
|
|||
/// An existential reference to a trait where `Self` is not included.
|
||||
///
|
||||
/// The `generic_args` will include any other known argument.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ExistentialTraitRef {
|
||||
pub def_id: TraitDef,
|
||||
pub generic_args: GenericArgs,
|
||||
|
|
@ -1154,20 +1171,20 @@ impl ExistentialTraitRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ExistentialProjection {
|
||||
pub def_id: TraitDef,
|
||||
pub generic_args: GenericArgs,
|
||||
pub term: TermKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ParamTy {
|
||||
pub index: u32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct BoundTy {
|
||||
pub var: usize,
|
||||
pub kind: BoundTyKind,
|
||||
|
|
@ -1178,7 +1195,7 @@ pub type Bytes = Vec<Option<u8>>;
|
|||
/// Size in bytes.
|
||||
pub type Size = usize;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, Serialize)]
|
||||
pub struct Prov(pub AllocId);
|
||||
|
||||
pub type Align = u64;
|
||||
|
|
@ -1186,14 +1203,14 @@ pub type Promoted = u32;
|
|||
pub type InitMaskMaterialized = Vec<u64>;
|
||||
|
||||
/// Stores the provenance information of pointers stored in memory.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct ProvenanceMap {
|
||||
/// Provenance in this map applies from the given offset for an entire pointer-size worth of
|
||||
/// bytes. Two entries in this map are always at least a pointer size apart.
|
||||
pub ptrs: Vec<(Size, Prov)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize)]
|
||||
pub struct Allocation {
|
||||
pub bytes: Bytes,
|
||||
pub provenance: ProvenanceMap,
|
||||
|
|
@ -1269,7 +1286,7 @@ impl Allocation {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ConstantKind {
|
||||
Ty(TyConst),
|
||||
Allocated(Allocation),
|
||||
|
|
@ -1280,27 +1297,27 @@ pub enum ConstantKind {
|
|||
ZeroSized,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ParamConst {
|
||||
pub index: u32,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct UnevaluatedConst {
|
||||
pub def: ConstDef,
|
||||
pub args: GenericArgs,
|
||||
pub promoted: Option<Promoted>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
|
||||
pub enum TraitSpecializationKind {
|
||||
None,
|
||||
Marker,
|
||||
AlwaysApplicable,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TraitDecl {
|
||||
pub def_id: TraitDef,
|
||||
pub safety: Safety,
|
||||
|
|
@ -1333,7 +1350,7 @@ impl TraitDecl {
|
|||
pub type ImplTrait = EarlyBinder<TraitRef>;
|
||||
|
||||
/// A complete reference to a trait, i.e., one where `Self` is known.
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TraitRef {
|
||||
pub def_id: TraitDef,
|
||||
/// The generic arguments for this definition.
|
||||
|
|
@ -1367,7 +1384,7 @@ impl TraitRef {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct Generics {
|
||||
pub parent: Option<GenericDef>,
|
||||
pub parent_count: usize,
|
||||
|
|
@ -1378,14 +1395,14 @@ pub struct Generics {
|
|||
pub host_effect_index: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum GenericParamDefKind {
|
||||
Lifetime,
|
||||
Type { has_default: bool, synthetic: bool },
|
||||
Const { has_default: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct GenericParamDef {
|
||||
pub name: super::Symbol,
|
||||
pub def_id: GenericDef,
|
||||
|
|
@ -1399,7 +1416,7 @@ pub struct GenericPredicates {
|
|||
pub predicates: Vec<(PredicateKind, Span)>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum PredicateKind {
|
||||
Clause(ClauseKind),
|
||||
ObjectSafe(TraitDef),
|
||||
|
|
@ -1410,7 +1427,7 @@ pub enum PredicateKind {
|
|||
AliasRelate(TermKind, TermKind, AliasRelationDirection),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ClauseKind {
|
||||
Trait(TraitPredicate),
|
||||
RegionOutlives(RegionOutlivesPredicate),
|
||||
|
|
@ -1421,57 +1438,57 @@ pub enum ClauseKind {
|
|||
ConstEvaluatable(TyConst),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ClosureKind {
|
||||
Fn,
|
||||
FnMut,
|
||||
FnOnce,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct SubtypePredicate {
|
||||
pub a: Ty,
|
||||
pub b: Ty,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct CoercePredicate {
|
||||
pub a: Ty,
|
||||
pub b: Ty,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum AliasRelationDirection {
|
||||
Equate,
|
||||
Subtype,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct TraitPredicate {
|
||||
pub trait_ref: TraitRef,
|
||||
pub polarity: PredicatePolarity,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct OutlivesPredicate<A, B>(pub A, pub B);
|
||||
|
||||
pub type RegionOutlivesPredicate = OutlivesPredicate<Region, Region>;
|
||||
pub type TypeOutlivesPredicate = OutlivesPredicate<Ty, Region>;
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub struct ProjectionPredicate {
|
||||
pub projection_term: AliasTerm,
|
||||
pub term: TermKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum ImplPolarity {
|
||||
Positive,
|
||||
Negative,
|
||||
Reservation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
|
||||
pub enum PredicatePolarity {
|
||||
Positive,
|
||||
Negative,
|
||||
|
|
@ -1514,7 +1531,7 @@ index_impl!(Span);
|
|||
/// `a` is in the variant with the `VariantIdx` of `0`,
|
||||
/// `c` is in the variant with the `VariantIdx` of `1`, and
|
||||
/// `g` is in the variant with the `VariantIdx` of `0`.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize)]
|
||||
pub struct VariantIdx(usize);
|
||||
|
||||
index_impl!(VariantIdx);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ mod convert;
|
|||
mod decode;
|
||||
mod methods;
|
||||
|
||||
// stable re-exports
|
||||
#[rustfmt::skip]
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
pub use self::convert::CharTryFromError;
|
||||
#[stable(feature = "char_from_str", since = "1.20.0")]
|
||||
|
|
@ -31,11 +33,14 @@ pub use self::convert::ParseCharError;
|
|||
#[stable(feature = "decode_utf16", since = "1.9.0")]
|
||||
pub use self::decode::{DecodeUtf16, DecodeUtf16Error};
|
||||
|
||||
// perma-unstable re-exports
|
||||
#[rustfmt::skip]
|
||||
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
||||
pub use self::methods::encode_utf16_raw; // perma-unstable
|
||||
#[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
|
||||
pub use self::methods::encode_utf8_raw; // perma-unstable
|
||||
|
||||
#[rustfmt::skip]
|
||||
use crate::ascii;
|
||||
use crate::error::Error;
|
||||
use crate::escape;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ use crate::str;
|
|||
/// ```
|
||||
///
|
||||
/// [str]: prim@str "str"
|
||||
#[derive(Hash)]
|
||||
#[derive(PartialEq, Eq, Hash)]
|
||||
#[stable(feature = "core_c_str", since = "1.64.0")]
|
||||
#[rustc_has_incoherent_inherent_impls]
|
||||
#[lang = "CStr"]
|
||||
|
|
@ -104,7 +104,6 @@ use crate::str;
|
|||
// want `repr(transparent)` but we don't want it to show up in rustdoc, so we hide it under
|
||||
// `cfg(doc)`. This is an ad-hoc implementation of attribute privacy.
|
||||
#[repr(transparent)]
|
||||
#[allow(clippy::derived_hash_with_manual_eq)]
|
||||
pub struct CStr {
|
||||
// FIXME: this should not be represented with a DST slice but rather with
|
||||
// just a raw `c_char` along with some form of marker to make
|
||||
|
|
@ -678,15 +677,9 @@ impl CStr {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialEq for CStr {
|
||||
#[inline]
|
||||
fn eq(&self, other: &CStr) -> bool {
|
||||
self.to_bytes().eq(other.to_bytes())
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Eq for CStr {}
|
||||
// `.to_bytes()` representations are compared instead of the inner `[c_char]`s,
|
||||
// because `c_char` is `i8` (not `u8`) on some platforms.
|
||||
// That is why this is implemented manually and not derived.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl PartialOrd for CStr {
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -243,18 +243,6 @@ extern "rust-intrinsic" {
|
|||
#[rustc_nounwind]
|
||||
pub fn simd_shuffle<T, U, V>(x: T, y: T, idx: U) -> V;
|
||||
|
||||
/// Shuffle two vectors by const indices.
|
||||
///
|
||||
/// `T` must be a vector.
|
||||
///
|
||||
/// `U` must be a vector with the same element type as `T` and the same length as `IDX`.
|
||||
///
|
||||
/// Returns a new vector such that element `i` is selected from `xy[IDX[i]]`, where `xy`
|
||||
/// is the concatenation of `x` and `y`. It is a compile-time error if `IDX[i]` is out-of-bounds
|
||||
/// of `xy`.
|
||||
#[rustc_nounwind]
|
||||
pub fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
|
||||
|
||||
/// Read a vector of pointers.
|
||||
///
|
||||
/// `T` must be a vector.
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@
|
|||
#![feature(transparent_unions)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unsized_const_params)]
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(with_negative_coherence)]
|
||||
// tidy-alphabetical-end
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ use crate::hash::Hasher;
|
|||
/// }
|
||||
/// ```
|
||||
#[unstable(feature = "internal_impls_macro", issue = "none")]
|
||||
// Allow implementations of `UnsizedConstParamTy` even though std cannot use that feature.
|
||||
#[allow_internal_unstable(unsized_const_params)]
|
||||
macro marker_impls {
|
||||
( $(#[$($meta:tt)*])* $Trait:ident for $({$($bounds:tt)*})? $T:ty $(, $($rest:tt)*)? ) => {
|
||||
$(#[$($meta)*])* impl< $($($bounds)*)? > $Trait for $T {}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
#![unstable(feature = "unicode_internals", issue = "none")]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
// The `pub use` ones are for use in alloc, and are not re-exported in std.
|
||||
|
||||
pub(crate) use unicode_data::alphabetic::lookup as Alphabetic;
|
||||
// for use in alloc, not re-exported in std.
|
||||
#[rustfmt::skip]
|
||||
pub use unicode_data::case_ignorable::lookup as Case_Ignorable;
|
||||
pub use unicode_data::cased::lookup as Cased;
|
||||
pub(crate) use unicode_data::cc::lookup as Cc;
|
||||
pub use unicode_data::conversions;
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub(crate) use unicode_data::alphabetic::lookup as Alphabetic;
|
||||
pub(crate) use unicode_data::cc::lookup as Cc;
|
||||
pub(crate) use unicode_data::grapheme_extend::lookup as Grapheme_Extend;
|
||||
pub(crate) use unicode_data::lowercase::lookup as Lowercase;
|
||||
pub(crate) use unicode_data::n::lookup as N;
|
||||
|
|
|
|||
1
library/core/tests/ffi.rs
Normal file
1
library/core/tests/ffi.rs
Normal file
|
|
@ -0,0 +1 @@
|
|||
mod cstr;
|
||||
15
library/core/tests/ffi/cstr.rs
Normal file
15
library/core/tests/ffi/cstr.rs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use core::ffi::CStr;
|
||||
|
||||
#[test]
|
||||
fn compares_as_u8s() {
|
||||
let a: &CStr = c"Hello!"; // Starts with ascii
|
||||
let a_bytes: &[u8] = a.to_bytes();
|
||||
assert!((..0b1000_0000).contains(&a_bytes[0]));
|
||||
|
||||
let b: &CStr = c"こんにちは!"; // Starts with non ascii
|
||||
let b_bytes: &[u8] = b.to_bytes();
|
||||
assert!((0b1000_0000..).contains(&b_bytes[0]));
|
||||
|
||||
assert_eq!(Ord::cmp(a, b), Ord::cmp(a_bytes, b_bytes));
|
||||
assert_eq!(PartialOrd::partial_cmp(a, b), PartialOrd::partial_cmp(a_bytes, b_bytes));
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue