Auto merge of #102509 - matthiaskrgr:rollup-gtenet8, r=matthiaskrgr

Rollup of 5 pull requests

Successful merges:

 - #101075 (Migrate rustc_codegen_gcc to SessionDiagnostics )
 - #102350 (Improve errors for incomplete functions in struct definitions)
 - #102481 (rustdoc: remove unneeded CSS `.rust-example-rendered { position }`)
 - #102491 (rustdoc: remove no-op source sidebar `opacity`)
 - #102499 (Adjust the s390x data layout for LLVM 16)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-09-30 10:39:09 +00:00
commit f914b82a75
22 changed files with 482 additions and 205 deletions

View File

@ -1,6 +1,8 @@
use std::fs::File;
use std::path::{Path, PathBuf};
use crate::errors::RanlibFailure;
use rustc_codegen_ssa::back::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use rustc_session::Session;
@ -181,7 +183,7 @@ impl<'a> ArchiveBuilder<'a> for ArArchiveBuilder<'a> {
std::process::Command::new("ranlib").arg(output).status().expect("Couldn't run ranlib");
if !status.success() {
self.config.sess.fatal(&format!("Ranlib exited with code {:?}", status.code()));
self.config.sess.emit_fatal(RanlibFailure::new(status.code()));
}
any_members

View File

@ -12,6 +12,7 @@ use std::borrow::Cow;
use crate::builder::Builder;
use crate::context::CodegenCx;
use crate::errors::UnwindingInlineAsm;
use crate::type_of::LayoutGccExt;
use crate::callee::get_fn;
@ -109,7 +110,7 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
fn codegen_inline_asm(&mut self, template: &[InlineAsmTemplatePiece], rust_operands: &[InlineAsmOperandRef<'tcx, Self>], options: InlineAsmOptions, span: &[Span], _instance: Instance<'_>, _dest_catch_funclet: Option<(Self::BasicBlock, Self::BasicBlock, Option<&Self::Funclet>)>) {
if options.contains(InlineAsmOptions::MAY_UNWIND) {
self.sess()
.struct_span_err(span[0], "GCC backend does not support unwinding from inline asm")
.create_err(UnwindingInlineAsm { span: span[0] })
.emit();
return;
}

View File

@ -14,6 +14,7 @@ use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size, WrappingRan
use crate::base;
use crate::context::CodegenCx;
use crate::errors::LinkageConstOrMutType;
use crate::type_of::LayoutGccExt;
impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
@ -368,10 +369,7 @@ fn check_and_apply_linkage<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, attrs: &Codeg
cx.layout_of(mt.ty).gcc_type(cx, true)
}
else {
cx.sess().span_fatal(
span,
"must have type `*const T` or `*mut T` due to `#[linkage]` attribute",
)
cx.sess().emit_fatal(LinkageConstOrMutType { span: span })
};
// Declare a symbol `foo` with the desired linkage.
let global1 = cx.declare_global_with_linkage(&sym, llty2, base::global_linkage_to_gcc(linkage));

View File

@ -13,7 +13,7 @@ use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_middle::ty::layout::{FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, TyAndLayout, LayoutOfHelpers};
use rustc_session::Session;
use rustc_span::Span;
use rustc_span::{Span, source_map::respan};
use rustc_target::abi::{call::FnAbi, HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_target::spec::{HasTargetSpec, Target, TlsModel};
@ -293,7 +293,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
self.is_native_int_type(typ) || self.is_non_native_int_type(typ) || typ.is_compatible_with(self.bool_type)
}
pub fn sess(&self) -> &Session {
pub fn sess(&self) -> &'tcx Session {
&self.tcx.sess
}
@ -477,7 +477,7 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
#[inline]
fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) = err {
self.sess().span_fatal(span, &err.to_string())
self.sess().emit_fatal(respan(span, err))
} else {
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
}
@ -495,7 +495,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
fn_abi_request: FnAbiRequest<'tcx>,
) -> ! {
if let FnAbiError::Layout(LayoutError::SizeOverflow(_)) = err {
self.sess().span_fatal(span, &err.to_string())
self.sess().emit_fatal(respan(span, err))
} else {
match fn_abi_request {
FnAbiRequest::OfFnPtr { sig, extra_args } => {

View File

@ -0,0 +1,242 @@
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
use rustc_macros::Diagnostic;
use rustc_middle::ty::Ty;
use rustc_span::{Span, Symbol};
use std::borrow::Cow;
struct ExitCode(Option<i32>);
impl IntoDiagnosticArg for ExitCode {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
let ExitCode(exit_code) = self;
match exit_code {
Some(t) => t.into_diagnostic_arg(),
None => DiagnosticArgValue::Str(Cow::Borrowed("<signal>")),
}
}
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::ranlib_failure)]
pub(crate) struct RanlibFailure {
exit_code: ExitCode,
}
impl RanlibFailure {
pub fn new(exit_code: Option<i32>) -> Self {
RanlibFailure { exit_code: ExitCode(exit_code) }
}
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_basic_integer, code = "E0511")]
pub(crate) struct InvalidMonomorphizationBasicInteger<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_invalid_float_vector, code = "E0511")]
pub(crate) struct InvalidMonomorphizationInvalidFloatVector<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub elem_ty: &'a str,
pub vec_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_not_float, code = "E0511")]
pub(crate) struct InvalidMonomorphizationNotFloat<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_unrecognized, code = "E0511")]
pub(crate) struct InvalidMonomorphizationUnrecognized {
#[primary_span]
pub span: Span,
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_expected_signed_unsigned, code = "E0511")]
pub(crate) struct InvalidMonomorphizationExpectedSignedUnsigned<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub elem_ty: Ty<'a>,
pub vec_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_unsupported_element, code = "E0511")]
pub(crate) struct InvalidMonomorphizationUnsupportedElement<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_ty: Ty<'a>,
pub elem_ty: Ty<'a>,
pub ret_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_invalid_bitmask, code = "E0511")]
pub(crate) struct InvalidMonomorphizationInvalidBitmask<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ty: Ty<'a>,
pub expected_int_bits: u64,
pub expected_bytes: u64,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_simd_shuffle, code = "E0511")]
pub(crate) struct InvalidMonomorphizationSimdShuffle<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_expected_simd, code = "E0511")]
pub(crate) struct InvalidMonomorphizationExpectedSimd<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub position: &'a str,
pub found_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_mask_type, code = "E0511")]
pub(crate) struct InvalidMonomorphizationMaskType<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_return_length, code = "E0511")]
pub(crate) struct InvalidMonomorphizationReturnLength<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_len: u64,
pub ret_ty: Ty<'a>,
pub out_len: u64,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_return_length_input_type, code = "E0511")]
pub(crate) struct InvalidMonomorphizationReturnLengthInputType<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_len: u64,
pub in_ty: Ty<'a>,
pub ret_ty: Ty<'a>,
pub out_len: u64,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_return_element, code = "E0511")]
pub(crate) struct InvalidMonomorphizationReturnElement<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_elem: Ty<'a>,
pub in_ty: Ty<'a>,
pub ret_ty: Ty<'a>,
pub out_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_return_type, code = "E0511")]
pub(crate) struct InvalidMonomorphizationReturnType<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_elem: Ty<'a>,
pub in_ty: Ty<'a>,
pub ret_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_inserted_type, code = "E0511")]
pub(crate) struct InvalidMonomorphizationInsertedType<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_elem: Ty<'a>,
pub in_ty: Ty<'a>,
pub out_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_return_integer_type, code = "E0511")]
pub(crate) struct InvalidMonomorphizationReturnIntegerType<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub ret_ty: Ty<'a>,
pub out_ty: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_mismatched_lengths, code = "E0511")]
pub(crate) struct InvalidMonomorphizationMismatchedLengths {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub m_len: u64,
pub v_len: u64,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_unsupported_cast, code = "E0511")]
pub(crate) struct InvalidMonomorphizationUnsupportedCast<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_ty: Ty<'a>,
pub in_elem: Ty<'a>,
pub ret_ty: Ty<'a>,
pub out_elem: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::invalid_monomorphization_unsupported_operation, code = "E0511")]
pub(crate) struct InvalidMonomorphizationUnsupportedOperation<'a> {
#[primary_span]
pub span: Span,
pub name: Symbol,
pub in_ty: Ty<'a>,
pub in_elem: Ty<'a>,
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::linkage_const_or_mut_type)]
pub(crate) struct LinkageConstOrMutType {
#[primary_span]
pub span: Span
}
#[derive(Diagnostic)]
#[diag(codegen_gcc::lto_not_supported)]
pub(crate) struct LTONotSupported;
#[derive(Diagnostic)]
#[diag(codegen_gcc::unwinding_inline_asm)]
pub(crate) struct UnwindingInlineAsm {
#[primary_span]
pub span: Span
}

View File

@ -4,7 +4,7 @@ mod simd;
use gccjit::{ComparisonOp, Function, RValue, ToRValue, Type, UnaryOp, FunctionType};
use rustc_codegen_ssa::MemFlags;
use rustc_codegen_ssa::base::wants_msvc_seh;
use rustc_codegen_ssa::common::{IntPredicate, span_invalid_monomorphization_error};
use rustc_codegen_ssa::common::IntPredicate;
use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{ArgAbiMethods, BaseTypeMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods};
@ -20,6 +20,7 @@ use crate::abi::GccType;
use crate::builder::Builder;
use crate::common::{SignType, TypeReflection};
use crate::context::CodegenCx;
use crate::errors::InvalidMonomorphizationBasicInteger;
use crate::type_of::LayoutGccExt;
use crate::intrinsic::simd::generic_simd_intrinsic;
@ -242,15 +243,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
_ => bug!(),
},
None => {
span_invalid_monomorphization_error(
tcx.sess,
span,
&format!(
"invalid monomorphization of `{}` intrinsic: \
expected basic integer type, found `{}`",
name, ty
),
);
tcx.sess.emit_err(InvalidMonomorphizationBasicInteger { span, name, ty });
return;
}
}

View File

@ -2,7 +2,7 @@ use std::cmp::Ordering;
use gccjit::{BinaryOp, RValue, Type, ToRValue};
use rustc_codegen_ssa::base::compare_simd_types;
use rustc_codegen_ssa::common::{TypeKind, span_invalid_monomorphization_error};
use rustc_codegen_ssa::common::TypeKind;
use rustc_codegen_ssa::mir::operand::OperandRef;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
@ -14,43 +14,48 @@ use rustc_span::{Span, Symbol, sym};
use rustc_target::abi::Align;
use crate::builder::Builder;
use crate::errors::{
InvalidMonomorphizationInvalidFloatVector,
InvalidMonomorphizationNotFloat,
InvalidMonomorphizationUnrecognized,
InvalidMonomorphizationExpectedSignedUnsigned,
InvalidMonomorphizationUnsupportedElement,
InvalidMonomorphizationInvalidBitmask,
InvalidMonomorphizationSimdShuffle,
InvalidMonomorphizationExpectedSimd,
InvalidMonomorphizationMaskType,
InvalidMonomorphizationReturnLength,
InvalidMonomorphizationReturnLengthInputType,
InvalidMonomorphizationReturnElement,
InvalidMonomorphizationReturnType,
InvalidMonomorphizationInsertedType,
InvalidMonomorphizationReturnIntegerType,
InvalidMonomorphizationMismatchedLengths,
InvalidMonomorphizationUnsupportedCast,
InvalidMonomorphizationUnsupportedOperation
};
use crate::intrinsic;
pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>, name: Symbol, callee_ty: Ty<'tcx>, args: &[OperandRef<'tcx, RValue<'gcc>>], ret_ty: Ty<'tcx>, llret_ty: Type<'gcc>, span: Span) -> Result<RValue<'gcc>, ()> {
// macros for error handling:
#[allow(unused_macro_rules)]
macro_rules! emit_error {
($msg: tt) => {
emit_error!($msg, )
};
($msg: tt, $($fmt: tt)*) => {
span_invalid_monomorphization_error(
bx.sess(), span,
&format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
name, $($fmt)*));
}
}
macro_rules! return_error {
($($fmt: tt)*) => {
($err:expr) => {
{
emit_error!($($fmt)*);
bx.sess().emit_err($err);
return Err(());
}
}
}
macro_rules! require {
($cond: expr, $($fmt: tt)*) => {
($cond:expr, $err:expr) => {
if !$cond {
return_error!($($fmt)*);
return_error!($err);
}
};
}
}
macro_rules! require_simd {
($ty: expr, $position: expr) => {
require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty)
require!($ty.is_simd(), InvalidMonomorphizationExpectedSimd { span, name, position: $position, found_ty: $ty })
};
}
@ -82,10 +87,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
bx.load(int_ty, ptr, Align::ONE)
}
_ => return_error!(
"invalid bitmask `{}`, expected `u{}` or `[u8; {}]`",
mask_ty,
expected_int_bits,
expected_bytes
InvalidMonomorphizationInvalidBitmask { span, name, ty: mask_ty, expected_int_bits, expected_bytes }
),
};
@ -127,18 +129,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
require!(
in_len == out_len,
"expected return type with length {} (same as input type `{}`), \
found `{}` with length {}",
in_len,
in_ty,
ret_ty,
out_len
InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len }
);
require!(
bx.type_kind(bx.element_type(llret_ty)) == TypeKind::Integer,
"expected return type with integer elements, found `{}` with non-integer `{}`",
ret_ty,
out_ty
InvalidMonomorphizationReturnIntegerType {span, name, ret_ty, out_ty}
);
return Ok(compare_simd_types(
@ -163,8 +158,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
})
}
_ => return_error!(
"simd_shuffle index must be an array of `u32`, got `{}`",
args[2].layout.ty
InvalidMonomorphizationSimdShuffle { span, name, ty: args[2].layout.ty }
),
}
}
@ -179,19 +173,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
require!(
out_len == n,
"expected return type of length {}, found `{}` with length {}",
n,
ret_ty,
out_len
InvalidMonomorphizationReturnLength { span, name, in_len: n, ret_ty, out_len }
);
require!(
in_elem == out_ty,
"expected return element type `{}` (element of input `{}`), \
found `{}` with element type `{}`",
in_elem,
in_ty,
ret_ty,
out_ty
InvalidMonomorphizationReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
);
let vector = args[2].immediate();
@ -207,10 +193,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
if name == sym::simd_insert {
require!(
in_elem == arg_tys[2],
"expected inserted type `{}` (element of input `{}`), found `{}`",
in_elem,
in_ty,
arg_tys[2]
InvalidMonomorphizationInsertedType { span, name, in_elem, in_ty, out_ty: arg_tys[2] }
);
let vector = args[0].immediate();
let index = args[1].immediate();
@ -263,10 +246,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
if name == sym::simd_extract {
require!(
ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`",
in_elem,
in_ty,
ret_ty
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
);
let vector = args[0].immediate();
return Ok(bx.context.new_vector_access(None, vector, args[1].immediate()).to_rvalue());
@ -279,13 +259,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let (v_len, _) = arg_tys[1].simd_size_and_type(bx.tcx());
require!(
m_len == v_len,
"mismatched lengths: mask length `{}` != other vector length `{}`",
m_len,
v_len
InvalidMonomorphizationMismatchedLengths { span, name, m_len, v_len }
);
match m_elem_ty.kind() {
ty::Int(_) => {}
_ => return_error!("mask element type is `{}`, expected `i_`", m_elem_ty),
_ => return_error!(InvalidMonomorphizationMaskType { span, name, ty: m_elem_ty }),
}
return Ok(bx.vector_select(args[0].immediate(), args[1].immediate(), args[2].immediate()));
}
@ -295,12 +273,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let (out_len, out_elem) = ret_ty.simd_size_and_type(bx.tcx());
require!(
in_len == out_len,
"expected return type with length {} (same as input type `{}`), \
found `{}` with length {}",
in_len,
in_ty,
ret_ty,
out_len
InvalidMonomorphizationReturnLengthInputType { span, name, in_len, in_ty, ret_ty, out_len }
);
// casting cares about nominal type, not just structural type
if in_elem == out_elem {
@ -412,13 +385,8 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
}
_ => { /* Unsupported. Fallthrough. */ }
}
require!(
false,
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
in_ty,
in_elem,
ret_ty,
out_elem
return_error!(
InvalidMonomorphizationUnsupportedCast { span, name, in_ty, in_elem, ret_ty, out_elem }
);
}
@ -431,10 +399,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
})*
_ => {},
}
require!(false,
"unsupported operation on `{}` with element `{}`",
in_ty,
in_elem)
return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
})*
}
}
@ -448,23 +413,14 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
span: Span,
args: &[OperandRef<'tcx, RValue<'gcc>>],
) -> Result<RValue<'gcc>, ()> {
macro_rules! emit_error {
($msg: tt, $($fmt: tt)*) => {
span_invalid_monomorphization_error(
bx.sess(), span,
&format!(concat!("invalid monomorphization of `{}` intrinsic: ", $msg),
name, $($fmt)*));
}
}
macro_rules! return_error {
($($fmt: tt)*) => {
($err:expr) => {
{
emit_error!($($fmt)*);
bx.sess().emit_err($err);
return Err(());
}
}
}
let (elem_ty_str, elem_ty) =
if let ty::Float(f) = in_elem.kind() {
let elem_ty = bx.cx.type_float_from_ty(*f);
@ -472,16 +428,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
32 => ("f32", elem_ty),
64 => ("f64", elem_ty),
_ => {
return_error!(
"unsupported element type `{}` of floating-point vector `{}`",
f.name_str(),
in_ty
);
return_error!(InvalidMonomorphizationInvalidFloatVector { span, name, elem_ty: f.name_str(), vec_ty: in_ty });
}
}
}
else {
return_error!("`{}` is not a floating-point type", in_ty);
return_error!(InvalidMonomorphizationNotFloat { span, name, ty: in_ty });
};
let vec_ty = bx.cx.type_vector(elem_ty, in_len);
@ -504,7 +456,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
sym::simd_fsqrt => ("sqrt", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_round => ("round", bx.type_func(&[vec_ty], vec_ty)),
sym::simd_trunc => ("trunc", bx.type_func(&[vec_ty], vec_ty)),
_ => return_error!("unrecognized intrinsic `{}`", name),
_ => return_error!(InvalidMonomorphizationUnrecognized { span, name })
};
let llvm_name = &format!("llvm.{0}.v{1}{2}", intr_name, in_len, elem_ty_str);
let function = intrinsic::llvm::intrinsic(llvm_name, &bx.cx);
@ -557,10 +509,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
})*
_ => {},
}
require!(false,
"unsupported operation on `{}` with element `{}`",
in_ty,
in_elem)
return_error!(InvalidMonomorphizationUnsupportedOperation { span, name, in_ty, in_elem })
})*
}
}
@ -579,12 +528,12 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
ty::Int(i) => (true, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_int_from_ty(i)),
ty::Uint(i) => (false, i.bit_width().unwrap_or(ptr_bits), bx.cx.type_uint_from_ty(i)),
_ => {
return_error!(
"expected element type `{}` of vector type `{}` \
to be a signed or unsigned integer type",
arg_tys[0].simd_size_and_type(bx.tcx()).1,
arg_tys[0]
);
return_error!(InvalidMonomorphizationExpectedSignedUnsigned {
span,
name,
elem_ty: arg_tys[0].simd_size_and_type(bx.tcx()).1,
vec_ty: arg_tys[0],
});
}
};
let builtin_name =
@ -617,10 +566,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
if name == sym::$name {
require!(
ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`",
in_elem,
in_ty,
ret_ty
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
);
return match in_elem.kind() {
ty::Int(_) | ty::Uint(_) => {
@ -644,13 +590,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
Ok(bx.vector_reduce_op(args[0].immediate(), $vec_op))
}
}
_ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`",
sym::$name,
in_ty,
in_elem,
ret_ty
),
_ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
};
}
};
@ -676,20 +616,11 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
if name == sym::$name {
require!(
ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`",
in_elem,
in_ty,
ret_ty
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
);
return match in_elem.kind() {
ty::Int(_) | ty::Uint(_) | ty::Float(_) => Ok(bx.$reduction(args[0].immediate())),
_ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`",
sym::$name,
in_ty,
in_elem,
ret_ty
),
_ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
};
}
};
@ -704,22 +635,13 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
let input = if !$boolean {
require!(
ret_ty == in_elem,
"expected return type `{}` (element of input `{}`), found `{}`",
in_elem,
in_ty,
ret_ty
InvalidMonomorphizationReturnType { span, name, in_elem, in_ty, ret_ty }
);
args[0].immediate()
} else {
match in_elem.kind() {
ty::Int(_) | ty::Uint(_) => {}
_ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`",
sym::$name,
in_ty,
in_elem,
ret_ty
),
_ => return_error!(InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }),
}
// boolean reductions operate on vectors of i1s:
@ -733,11 +655,7 @@ pub fn generic_simd_intrinsic<'a, 'gcc, 'tcx>(bx: &mut Builder<'a, 'gcc, 'tcx>,
Ok(if !$boolean { r } else { bx.zext(r, bx.type_bool()) })
}
_ => return_error!(
"unsupported {} from `{}` with element `{}` to `{}`",
sym::$name,
in_ty,
in_elem,
ret_ty
InvalidMonomorphizationUnsupportedElement { span, name, in_ty, elem_ty: in_elem, ret_ty }
),
};
}

View File

@ -18,6 +18,8 @@
#![recursion_limit="256"]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
extern crate rustc_apfloat;
extern crate rustc_ast;
@ -25,6 +27,7 @@ extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_hir;
extern crate rustc_macros;
extern crate rustc_metadata;
extern crate rustc_middle;
extern crate rustc_session;
@ -50,6 +53,7 @@ mod context;
mod coverageinfo;
mod debuginfo;
mod declare;
mod errors;
mod int;
mod intrinsic;
mod mono_item;
@ -59,6 +63,7 @@ mod type_of;
use std::any::Any;
use std::sync::{Arc, Mutex};
use crate::errors::LTONotSupported;
use gccjit::{Context, OptimizationLevel, CType};
use rustc_ast::expand::allocator::AllocatorKind;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
@ -97,7 +102,7 @@ pub struct GccCodegenBackend {
impl CodegenBackend for GccCodegenBackend {
fn init(&self, sess: &Session) {
if sess.lto() != Lto::No {
sess.warn("LTO is not supported. You may get a linker error.");
sess.emit_warning(LTONotSupported {});
}
let temp_dir = TempDir::new().expect("cannot create temporary directory");

View File

@ -154,6 +154,11 @@ pub unsafe fn create_module<'ll>(
target_data_layout = target_data_layout.replace("-p10:8:8-p20:8:8", "");
}
}
if llvm_version < (16, 0, 0) {
if sess.target.arch == "s390x" {
target_data_layout = target_data_layout.replace("-v128:64", "");
}
}
// Ensure the data-layout values hardcoded remain the defaults.
if sess.target.is_builtin {

View File

@ -0,0 +1,68 @@
codegen_gcc_ranlib_failure =
Ranlib exited with code {$exit_code}
codegen_gcc_linkage_const_or_mut_type =
must have type `*const T` or `*mut T` due to `#[linkage]` attribute
codegen_gcc_unwinding_inline_asm =
GCC backend does not support unwinding from inline asm
codegen_gcc_lto_not_supported =
LTO is not supported. You may get a linker error.
codegen_gcc_invalid_monomorphization_basic_integer =
invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
codegen_gcc_invalid_monomorphization_invalid_float_vector =
invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$elem_ty}` of floating-point vector `{$vec_ty}`
codegen_gcc_invalid_monomorphization_not_float =
invalid monomorphization of `{$name}` intrinsic: `{$ty}` is not a floating-point type
codegen_gcc_invalid_monomorphization_unrecognized =
invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
codegen_gcc_invalid_monomorphization_expected_signed_unsigned =
invalid monomorphization of `{$name}` intrinsic: expected element type `{$elem_ty}` of vector type `{$vec_ty}` to be a signed or unsigned integer type
codegen_gcc_invalid_monomorphization_unsupported_element =
invalid monomorphization of `{$name}` intrinsic: unsupported {$name} from `{$in_ty}` with element `{$elem_ty}` to `{$ret_ty}`
codegen_gcc_invalid_monomorphization_invalid_bitmask =
invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_gcc_invalid_monomorphization_simd_shuffle =
invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be an array of `u32`, got `{$ty}`
codegen_gcc_invalid_monomorphization_expected_simd =
invalid monomorphization of `{$name}` intrinsic: expected SIMD {$expected_ty} type, found non-SIMD `{$found_ty}`
codegen_gcc_invalid_monomorphization_mask_type =
invalid monomorphization of `{$name}` intrinsic: mask element type is `{$ty}`, expected `i_`
codegen_gcc_invalid_monomorphization_return_length =
invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
codegen_gcc_invalid_monomorphization_return_length_input_type =
invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
codegen_gcc_invalid_monomorphization_return_element =
invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
codegen_gcc_invalid_monomorphization_return_type =
invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
codegen_gcc_invalid_monomorphization_inserted_type =
invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
codegen_gcc_invalid_monomorphization_return_integer_type =
invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
codegen_gcc_invalid_monomorphization_mismatched_lengths =
invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
codegen_gcc_invalid_monomorphization_unsupported_cast =
invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
codegen_gcc_invalid_monomorphization_unsupported_operation =
invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`

View File

@ -41,6 +41,7 @@ fluent_messages! {
borrowck => "../locales/en-US/borrowck.ftl",
builtin_macros => "../locales/en-US/builtin_macros.ftl",
const_eval => "../locales/en-US/const_eval.ftl",
codegen_gcc => "../locales/en-US/codegen_gcc.ftl",
driver => "../locales/en-US/driver.ftl",
expand => "../locales/en-US/expand.ftl",
session => "../locales/en-US/session.ftl",

View File

@ -5,6 +5,7 @@ use crate::{
};
use crate::{Handler, Level, MultiSpan, StashKey};
use rustc_lint_defs::Applicability;
use rustc_span::source_map::Spanned;
use rustc_span::Span;
use std::borrow::Cow;
@ -23,6 +24,18 @@ pub trait IntoDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> {
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>;
}
impl<'a, T, E> IntoDiagnostic<'a, E> for Spanned<T>
where
T: IntoDiagnostic<'a, E>,
E: EmissionGuarantee,
{
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, E> {
let mut diag = self.node.into_diagnostic(handler);
diag.set_span(self.span);
diag
}
}
/// Used for emitting structured error messages and other diagnostic information.
///
/// If there is some state in a downstream crate you would like to

View File

@ -7,6 +7,7 @@ use crate::ty::{
};
use rustc_ast as ast;
use rustc_attr as attr;
use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
@ -206,6 +207,12 @@ pub enum LayoutError<'tcx> {
NormalizationFailure(Ty<'tcx>, NormalizationError<'tcx>),
}
impl<'a> IntoDiagnostic<'a, !> for LayoutError<'a> {
fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, !> {
handler.struct_fatal(self.to_string())
}
}
impl<'tcx> fmt::Display for LayoutError<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
@ -3065,6 +3072,12 @@ impl<'tcx> fmt::Display for FnAbiError<'tcx> {
}
}
impl<'tcx> IntoDiagnostic<'tcx, !> for FnAbiError<'tcx> {
fn into_diagnostic(self, handler: &'tcx Handler) -> DiagnosticBuilder<'tcx, !> {
handler.struct_fatal(self.to_string())
}
}
// FIXME(eddyb) maybe use something like this for an unified `fn_abi_of`, not
// just for error handling.
#[derive(Debug)]

View File

@ -1753,18 +1753,24 @@ impl<'a> Parser<'a> {
};
// We use `parse_fn` to get a span for the function
let fn_parse_mode = FnParseMode { req_name: |_| true, req_body: true };
if let Err(mut db) =
self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis)
{
db.delay_as_bug();
match self.parse_fn(&mut AttrVec::new(), fn_parse_mode, lo, &inherited_vis) {
Ok(_) => {
let mut err = self.struct_span_err(
lo.to(self.prev_token.span),
&format!("functions are not allowed in {adt_ty} definitions"),
);
err.help(
"unlike in C++, Java, and C#, functions are declared in `impl` blocks",
);
err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
err
}
Err(err) => {
err.cancel();
self.restore_snapshot(snapshot);
self.expected_ident_found()
}
}
let mut err = self.struct_span_err(
lo.to(self.prev_token.span),
&format!("functions are not allowed in {adt_ty} definitions"),
);
err.help("unlike in C++, Java, and C#, functions are declared in `impl` blocks");
err.help("see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information");
err
} else if self.eat_keyword(kw::Struct) {
match self.parse_item_struct() {
Ok((ident, _)) => {

View File

@ -6,9 +6,9 @@ pub fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The data_layout string below and the ABI implementation in
// cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
// Pass the -vector feature string to LLVM to respect this assumption.
// FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
// also strip v128 from the data_layout below to match the older LLVM's expectation.
base.features = "-vector".into();
base.max_atomic_width = Some(64);
base.min_global_align = Some(16);
@ -17,7 +17,7 @@ pub fn target() -> Target {
Target {
llvm_target: "s390x-unknown-linux-gnu".into(),
pointer_width: 64,
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(),
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(),
arch: "s390x".into(),
options: base,
}

View File

@ -6,9 +6,9 @@ pub fn target() -> Target {
base.endian = Endian::Big;
// z10 is the oldest CPU supported by LLVM
base.cpu = "z10".into();
// FIXME: The data_layout string below and the ABI implementation in
// cabi_s390x.rs are for now hard-coded to assume the no-vector ABI.
// Pass the -vector feature string to LLVM to respect this assumption.
// FIXME: The ABI implementation in cabi_s390x.rs is for now hard-coded to assume the no-vector
// ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
// also strip v128 from the data_layout below to match the older LLVM's expectation.
base.features = "-vector".into();
base.max_atomic_width = Some(64);
base.min_global_align = Some(16);
@ -18,7 +18,7 @@ pub fn target() -> Target {
Target {
llvm_target: "s390x-unknown-linux-musl".into(),
pointer_width: 64,
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64".into(),
data_layout: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64".into(),
arch: "s390x".into(),
options: base,
}

View File

@ -448,7 +448,6 @@ img {
}
.source .sidebar > *:not(#sidebar-toggle) {
opacity: 0;
visibility: hidden;
}
@ -457,7 +456,6 @@ img {
}
.source-sidebar-expanded .source .sidebar > *:not(#sidebar-toggle) {
opacity: 1;
visibility: visible;
}
@ -1322,11 +1320,6 @@ h3.variant {
font-size: 1.25rem;
}
/* Example code has the "Run" button that needs to be positioned relative to the pre */
pre.rust.rust-example-rendered {
position: relative;
}
pre.rust {
tab-size: 4;
-moz-tab-size: 4;

View File

@ -3,20 +3,17 @@ javascript: false
goto: file://|DOC_PATH|/src/test_docs/lib.rs.html
// Since the javascript is disabled, there shouldn't be a toggle.
assert-false: "#sidebar-toggle"
// For some reason, we need to wait a bit here because it seems like the transition on opacity
// is being applied whereas it can't be reproduced in a browser...
wait-for-css: (".sidebar > *", {"visibility": "hidden", "opacity": 0})
wait-for-css: (".sidebar > *", {"visibility": "hidden"})
// Let's retry with javascript enabled.
javascript: true
reload:
wait-for: "#sidebar-toggle"
assert-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden", "opacity": 0})
assert-css: ("#sidebar-toggle", {"visibility": "visible"})
assert-css: (".sidebar > *:not(#sidebar-toggle)", {"visibility": "hidden"})
// Let's expand the sidebar now.
click: "#sidebar-toggle"
// Because of the transition CSS, we check by using `wait-for-css` instead of `assert-css`.
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
// We now check that opening the sidebar and clicking a link will leave it open.
// The behavior here on desktop is different than the behavior on mobile,
@ -36,7 +33,7 @@ show-text: true
local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
reload:
// Waiting for the sidebar to be displayed...
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
assert-css: (
"#source-sidebar details[open] > .files a.selected",
{"color": "rgb(0, 0, 0)", "background-color": "rgb(255, 255, 255)"},
@ -91,7 +88,7 @@ assert-css: (
local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
reload:
// Waiting for the sidebar to be displayed...
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
assert-css: (
"#source-sidebar details[open] > .files > a.selected",
{"color": "rgb(221, 221, 221)", "background-color": "rgb(51, 51, 51)"},
@ -146,7 +143,7 @@ assert-css: (
local-storage: {"rustdoc-theme": "ayu", "rustdoc-use-system-theme": "false"}
reload:
// Waiting for the sidebar to be displayed...
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
assert-css: (
"#source-sidebar details[open] > .files a.selected",
{"color": "rgb(255, 180, 76)", "background-color": "rgb(20, 25, 31)"},
@ -201,7 +198,7 @@ assert-css: (
size: (500, 700)
reload:
// Waiting for the sidebar to be displayed...
wait-for-css: ("#sidebar-toggle", {"visibility": "visible", "opacity": 1})
wait-for-css: ("#sidebar-toggle", {"visibility": "visible"})
// We now check it takes the full size of the display.
assert-property: ("body", {"clientWidth": "500", "clientHeight": "700"})

View File

@ -3,7 +3,7 @@
struct Baz {
inner : dyn fn ()
//~^ ERROR expected `,`, or `}`, found keyword `fn`
//~| ERROR functions are not allowed in struct definitions
//~| ERROR expected identifier, found keyword `fn`
//~| ERROR cannot find type `dyn` in this scope
}

View File

@ -4,16 +4,18 @@ error: expected `,`, or `}`, found keyword `fn`
LL | inner : dyn fn ()
| ^ help: try adding a comma: `,`
error: functions are not allowed in struct definitions
error: expected identifier, found keyword `fn`
--> $DIR/fn-field-parse-error-ice.rs:4:17
|
LL | struct Baz {
| --- while parsing this struct
LL | inner : dyn fn ()
| ^^
| ^^ expected identifier, found keyword
|
= help: unlike in C++, Java, and C#, functions are declared in `impl` blocks
= help: see https://doc.rust-lang.org/book/ch05-03-method-syntax.html for more information
help: escape `fn` to use it as an identifier
|
LL | inner : dyn r#fn ()
| ++
error[E0412]: cannot find type `dyn` in this scope
--> $DIR/fn-field-parse-error-ice.rs:4:13

View File

@ -0,0 +1,5 @@
fn main() {}
struct S {
fn: u8 //~ ERROR expected identifier, found keyword `fn`
}

View File

@ -0,0 +1,15 @@
error: expected identifier, found keyword `fn`
--> $DIR/incomplete-fn-in-struct-definition.rs:4:5
|
LL | struct S {
| - while parsing this struct
LL | fn: u8
| ^^ expected identifier, found keyword
|
help: escape `fn` to use it as an identifier
|
LL | r#fn: u8
| ++
error: aborting due to previous error