Merge from rustc

This commit is contained in:
The Miri Cronjob Bot 2024-07-26 05:08:10 +00:00
commit 4bd2757b4c
290 changed files with 2907 additions and 2219 deletions

View file

@ -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]]

View file

@ -1,4 +1,4 @@
Version 1.80 (2024-07-25)
Version 1.80.0 (2024-07-25)
==========================
<a id="1.80-Language"></a>

View file

@ -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 },
}

View file

@ -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

View file

@ -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(),
});
}
_ => {}
}

View file

@ -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 {

View file

@ -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();

View file

@ -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.
}
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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)),

View file

@ -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)

View file

@ -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))
);

View file

@ -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))
);

View file

@ -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,

View file

@ -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);

View file

@ -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);

View file

@ -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))
);

View file

@ -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,

View file

@ -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)
}

View file

@ -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;
}

View file

@ -91,7 +91,6 @@ pub enum TypeKind {
Pointer,
Vector,
Metadata,
X86_MMX,
Token,
ScalableVector,
BFloat,

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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:?}",

View file

@ -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:?}",

View file

@ -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,

View file

@ -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);

View file

@ -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::*;

View file

@ -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]

View file

@ -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 {

View file

@ -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 {

View file

@ -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();

View file

@ -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

View file

@ -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,
]
]
);

View file

@ -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)]

View 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(),
},
},
);
}
}
}

View file

@ -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:

View file

@ -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,
);

View file

@ -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"

View file

@ -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,

View file

@ -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);

View file

@ -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 }

View file

@ -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>,

View file

@ -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>,

View file

@ -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,

View file

@ -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.

View file

@ -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>),

View file

@ -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

View file

@ -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,
}

View file

@ -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)]);

View file

@ -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()

View file

@ -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(", "),
});
}

View file

@ -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);

View file

@ -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!(

View file

@ -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" }

View file

@ -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;

View file

@ -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)],
);

View file

@ -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![];

View file

@ -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,

View file

@ -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,
);

View file

@ -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>(

View file

@ -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:?}")
}

View file

@ -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);

View file

@ -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 }

View file

@ -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>,
}

View file

@ -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> {

View file

@ -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> {

View file

@ -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> {

View file

@ -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),

View file

@ -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> {

View file

@ -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),

View file

@ -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> {

View file

@ -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> {

View file

@ -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]

View file

@ -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.

View file

@ -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>>,
}

View file

@ -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>>,

View file

@ -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.

View file

@ -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>,

View file

@ -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> {

View file

@ -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,

View file

@ -5,3 +5,4 @@ edition = "2021"
[dependencies]
scoped-tls = "1.0"
serde = { version = "1.0.125", features = [ "derive" ] }

View file

@ -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,

View file

@ -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.

View file

@ -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 {

View file

@ -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 {

View file

@ -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,

View file

@ -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;
}

View file

@ -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,
}

View file

@ -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);

View file

@ -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;

View file

@ -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]

View file

@ -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.

View file

@ -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

View file

@ -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 {}

View file

@ -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;

View file

@ -0,0 +1 @@
mod cstr;

View 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