mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Auto merge of #113577 - matthiaskrgr:rollup-vaa83ip, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #112717 (Implement a few more rvalue translation to smir) - #113310 (Don't suggest `impl Trait` in path position) - #113497 (Support explicit 32-bit MIPS ABI for the synthetic object) - #113560 (Lint against misplaced where-clauses on associated types in traits) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e571544f44
@ -4233,6 +4233,7 @@ dependencies = [
|
|||||||
"rustc_hir",
|
"rustc_hir",
|
||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
|
"rustc_target",
|
||||||
"scoped-tls",
|
"scoped-tls",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
@ -1300,14 +1300,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssocItemKind::Type(box TyAlias {
|
AssocItemKind::Type(box TyAlias { bounds, ty, .. }) => {
|
||||||
generics,
|
|
||||||
where_clauses,
|
|
||||||
where_predicates_split,
|
|
||||||
bounds,
|
|
||||||
ty,
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
if ty.is_none() {
|
if ty.is_none() {
|
||||||
self.session.emit_err(errors::AssocTypeWithoutBody {
|
self.session.emit_err(errors::AssocTypeWithoutBody {
|
||||||
span: item.span,
|
span: item.span,
|
||||||
@ -1315,17 +1308,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
self.check_type_no_bounds(bounds, "`impl`s");
|
self.check_type_no_bounds(bounds, "`impl`s");
|
||||||
if ty.is_some() {
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let AssocItemKind::Type(box TyAlias {
|
||||||
|
generics,
|
||||||
|
where_clauses,
|
||||||
|
where_predicates_split,
|
||||||
|
ty: Some(_),
|
||||||
|
..
|
||||||
|
}) = &item.kind
|
||||||
|
{
|
||||||
self.check_gat_where(
|
self.check_gat_where(
|
||||||
item.id,
|
item.id,
|
||||||
generics.where_clause.predicates.split_at(*where_predicates_split).0,
|
generics.where_clause.predicates.split_at(*where_predicates_split).0,
|
||||||
*where_clauses,
|
*where_clauses,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
|
if ctxt == AssocCtxt::Trait || self.in_trait_impl {
|
||||||
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
|
self.visibility_not_permitted(&item.vis, errors::VisibilityNotPermittedNote::TraitImpl);
|
||||||
|
@ -243,8 +243,16 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
|
|||||||
s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
|
s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
|
||||||
_ => elf::EF_MIPS_ARCH_32R2,
|
_ => elf::EF_MIPS_ARCH_32R2,
|
||||||
};
|
};
|
||||||
// The only ABI LLVM supports for 32-bit MIPS CPUs is o32.
|
|
||||||
let mut e_flags = elf::EF_MIPS_CPIC | elf::EF_MIPS_ABI_O32 | arch;
|
let mut e_flags = elf::EF_MIPS_CPIC | arch;
|
||||||
|
|
||||||
|
// If the ABI is explicitly given, use it or default to O32.
|
||||||
|
match sess.target.options.llvm_abiname.to_lowercase().as_str() {
|
||||||
|
"n32" => e_flags |= elf::EF_MIPS_ABI2,
|
||||||
|
"o32" => e_flags |= elf::EF_MIPS_ABI_O32,
|
||||||
|
_ => e_flags |= elf::EF_MIPS_ABI_O32,
|
||||||
|
};
|
||||||
|
|
||||||
if sess.target.options.relocation_model != RelocModel::Static {
|
if sess.target.options.relocation_model != RelocModel::Static {
|
||||||
e_flags |= elf::EF_MIPS_PIC;
|
e_flags |= elf::EF_MIPS_PIC;
|
||||||
}
|
}
|
||||||
|
@ -162,10 +162,18 @@ fn fmt_printer<'a, 'tcx>(infcx: &'a InferCtxt<'tcx>, ns: Namespace) -> FmtPrinte
|
|||||||
let mut infcx_inner = infcx.inner.borrow_mut();
|
let mut infcx_inner = infcx.inner.borrow_mut();
|
||||||
let ty_vars = infcx_inner.type_variables();
|
let ty_vars = infcx_inner.type_variables();
|
||||||
let var_origin = ty_vars.var_origin(ty_vid);
|
let var_origin = ty_vars.var_origin(ty_vid);
|
||||||
if let TypeVariableOriginKind::TypeParameterDefinition(name, _) = var_origin.kind
|
if let TypeVariableOriginKind::TypeParameterDefinition(name, def_id) = var_origin.kind
|
||||||
&& !var_origin.span.from_expansion()
|
&& !var_origin.span.from_expansion()
|
||||||
{
|
{
|
||||||
|
let generics = infcx.tcx.generics_of(infcx.tcx.parent(def_id));
|
||||||
|
let idx = generics.param_def_id_to_index(infcx.tcx, def_id).unwrap();
|
||||||
|
let generic_param_def = generics.param_at(idx as usize, infcx.tcx);
|
||||||
|
if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param_def.kind
|
||||||
|
{
|
||||||
|
None
|
||||||
|
} else {
|
||||||
Some(name)
|
Some(name)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -4084,7 +4084,7 @@ declare_lint! {
|
|||||||
///
|
///
|
||||||
/// ### Explanation
|
/// ### Explanation
|
||||||
///
|
///
|
||||||
/// The preferred location for where clauses on associated types in impls
|
/// The preferred location for where clauses on associated types
|
||||||
/// is after the type. However, for most of generic associated types development,
|
/// is after the type. However, for most of generic associated types development,
|
||||||
/// it was only accepted before the equals. To provide a transition period and
|
/// it was only accepted before the equals. To provide a transition period and
|
||||||
/// further evaluate this change, both are currently accepted. At some point in
|
/// further evaluate this change, both are currently accepted. At some point in
|
||||||
|
@ -4,14 +4,18 @@ version = "0.0.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rustc_hir = { path = "../rustc_hir" }
|
# Use optional dependencies for rustc_* in order to support building this crate separately.
|
||||||
|
rustc_hir = { path = "../rustc_hir", optional = true }
|
||||||
rustc_middle = { path = "../rustc_middle", optional = true }
|
rustc_middle = { path = "../rustc_middle", optional = true }
|
||||||
rustc_span = { path = "../rustc_span", optional = true }
|
rustc_span = { path = "../rustc_span", optional = true }
|
||||||
|
rustc_target = { path = "../rustc_target", optional = true }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
scoped-tls = "1.0"
|
scoped-tls = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [
|
default = [
|
||||||
|
"rustc_hir",
|
||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
|
"rustc_target",
|
||||||
]
|
]
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "nightly-2023-02-28"
|
channel = "nightly-2023-06-14"
|
||||||
components = [ "rustfmt", "rustc-dev" ]
|
components = [ "rustfmt", "rustc-dev" ]
|
||||||
|
@ -13,6 +13,17 @@
|
|||||||
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
|
#![cfg_attr(not(feature = "default"), feature(rustc_private))]
|
||||||
#![feature(local_key_cell_methods)]
|
#![feature(local_key_cell_methods)]
|
||||||
#![feature(ptr_metadata)]
|
#![feature(ptr_metadata)]
|
||||||
|
#![feature(type_alias_impl_trait)] // Used to define opaque types.
|
||||||
|
|
||||||
|
// Declare extern rustc_* crates to enable building this crate separately from the compiler.
|
||||||
|
#[cfg(not(feature = "default"))]
|
||||||
|
extern crate rustc_hir;
|
||||||
|
#[cfg(not(feature = "default"))]
|
||||||
|
extern crate rustc_middle;
|
||||||
|
#[cfg(not(feature = "default"))]
|
||||||
|
extern crate rustc_span;
|
||||||
|
#[cfg(not(feature = "default"))]
|
||||||
|
extern crate rustc_target;
|
||||||
|
|
||||||
pub mod rustc_internal;
|
pub mod rustc_internal;
|
||||||
pub mod stable_mir;
|
pub mod stable_mir;
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
||||||
//! until stable MIR is complete.
|
//! until stable MIR is complete.
|
||||||
|
|
||||||
|
use std::fmt::Debug;
|
||||||
|
use std::string::ToString;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
rustc_smir::Tables,
|
rustc_smir::Tables,
|
||||||
stable_mir::{self, with},
|
stable_mir::{self, with},
|
||||||
@ -49,3 +52,10 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
|||||||
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
||||||
crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
|
crate::stable_mir::run(Tables { tcx, def_ids: vec![], types: vec![] }, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A type that provides internal information but that can still be used for debug purpose.
|
||||||
|
pub type Opaque = impl Debug + ToString + Clone;
|
||||||
|
|
||||||
|
pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
|
||||||
|
format!("{value:?}")
|
||||||
|
}
|
||||||
|
@ -7,11 +7,13 @@
|
|||||||
//!
|
//!
|
||||||
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
|
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
|
||||||
|
|
||||||
|
use crate::rustc_internal::{self, opaque};
|
||||||
use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy};
|
use crate::stable_mir::ty::{FloatTy, IntTy, RigidTy, TyKind, UintTy};
|
||||||
use crate::stable_mir::{self, Context};
|
use crate::stable_mir::{self, Context};
|
||||||
use rustc_middle::mir;
|
use rustc_middle::mir;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
|
use rustc_target::abi::FieldIdx;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
impl<'tcx> Context for Tables<'tcx> {
|
impl<'tcx> Context for Tables<'tcx> {
|
||||||
@ -137,11 +139,21 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
|
|||||||
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
|
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Stable {
|
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
||||||
|
pub(crate) trait Stable {
|
||||||
|
/// The stable representation of the type implementing Stable.
|
||||||
type T;
|
type T;
|
||||||
|
/// Converts an object to the equivalent Stable MIR representation.
|
||||||
fn stable(&self) -> Self::T;
|
fn stable(&self) -> Self::T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Stable for DefId {
|
||||||
|
type T = stable_mir::CrateItem;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
rustc_internal::crate_item(*self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Stable for mir::Statement<'tcx> {
|
impl<'tcx> Stable for mir::Statement<'tcx> {
|
||||||
type T = stable_mir::mir::Statement;
|
type T = stable_mir::mir::Statement;
|
||||||
fn stable(&self) -> Self::T {
|
fn stable(&self) -> Self::T {
|
||||||
@ -173,12 +185,18 @@ impl<'tcx> Stable for mir::Rvalue<'tcx> {
|
|||||||
match self {
|
match self {
|
||||||
Use(op) => stable_mir::mir::Rvalue::Use(op.stable()),
|
Use(op) => stable_mir::mir::Rvalue::Use(op.stable()),
|
||||||
Repeat(_, _) => todo!(),
|
Repeat(_, _) => todo!(),
|
||||||
Ref(_, _, _) => todo!(),
|
Ref(region, kind, place) => {
|
||||||
ThreadLocalRef(_) => todo!(),
|
stable_mir::mir::Rvalue::Ref(opaque(region), kind.stable(), place.stable())
|
||||||
AddressOf(_, _) => todo!(),
|
}
|
||||||
Len(_) => todo!(),
|
ThreadLocalRef(def_id) => stable_mir::mir::Rvalue::ThreadLocalRef(def_id.stable()),
|
||||||
|
AddressOf(mutability, place) => {
|
||||||
|
stable_mir::mir::Rvalue::AddressOf(mutability.stable(), place.stable())
|
||||||
|
}
|
||||||
|
Len(place) => stable_mir::mir::Rvalue::Len(place.stable()),
|
||||||
Cast(_, _, _) => todo!(),
|
Cast(_, _, _) => todo!(),
|
||||||
BinaryOp(_, _) => todo!(),
|
BinaryOp(bin_op, ops) => {
|
||||||
|
stable_mir::mir::Rvalue::BinaryOp(bin_op.stable(), ops.0.stable(), ops.1.stable())
|
||||||
|
}
|
||||||
CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
|
CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
|
||||||
bin_op.stable(),
|
bin_op.stable(),
|
||||||
ops.0.stable(),
|
ops.0.stable(),
|
||||||
@ -186,14 +204,119 @@ impl<'tcx> Stable for mir::Rvalue<'tcx> {
|
|||||||
),
|
),
|
||||||
NullaryOp(_, _) => todo!(),
|
NullaryOp(_, _) => todo!(),
|
||||||
UnaryOp(un_op, op) => stable_mir::mir::Rvalue::UnaryOp(un_op.stable(), op.stable()),
|
UnaryOp(un_op, op) => stable_mir::mir::Rvalue::UnaryOp(un_op.stable(), op.stable()),
|
||||||
Discriminant(_) => todo!(),
|
Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable()),
|
||||||
Aggregate(_, _) => todo!(),
|
Aggregate(_, _) => todo!(),
|
||||||
ShallowInitBox(_, _) => todo!(),
|
ShallowInitBox(_, _) => todo!(),
|
||||||
CopyForDeref(_) => todo!(),
|
CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Stable for mir::Mutability {
|
||||||
|
type T = stable_mir::mir::Mutability;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use mir::Mutability::*;
|
||||||
|
match *self {
|
||||||
|
Not => stable_mir::mir::Mutability::Not,
|
||||||
|
Mut => stable_mir::mir::Mutability::Mut,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for mir::BorrowKind {
|
||||||
|
type T = stable_mir::mir::BorrowKind;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use mir::BorrowKind::*;
|
||||||
|
match *self {
|
||||||
|
Shared => stable_mir::mir::BorrowKind::Shared,
|
||||||
|
Shallow => stable_mir::mir::BorrowKind::Shallow,
|
||||||
|
Mut { kind } => stable_mir::mir::BorrowKind::Mut { kind: kind.stable() },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for mir::MutBorrowKind {
|
||||||
|
type T = stable_mir::mir::MutBorrowKind;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use mir::MutBorrowKind::*;
|
||||||
|
match *self {
|
||||||
|
Default => stable_mir::mir::MutBorrowKind::Default,
|
||||||
|
TwoPhaseBorrow => stable_mir::mir::MutBorrowKind::TwoPhaseBorrow,
|
||||||
|
ClosureCapture => stable_mir::mir::MutBorrowKind::ClosureCapture,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> Stable for mir::NullOp<'tcx> {
|
||||||
|
type T = stable_mir::mir::NullOp;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use mir::NullOp::*;
|
||||||
|
match self {
|
||||||
|
SizeOf => stable_mir::mir::NullOp::SizeOf,
|
||||||
|
AlignOf => stable_mir::mir::NullOp::AlignOf,
|
||||||
|
OffsetOf(indices) => {
|
||||||
|
stable_mir::mir::NullOp::OffsetOf(indices.iter().map(|idx| idx.stable()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for mir::CastKind {
|
||||||
|
type T = stable_mir::mir::CastKind;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use mir::CastKind::*;
|
||||||
|
match self {
|
||||||
|
PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
|
||||||
|
PointerFromExposedAddress => stable_mir::mir::CastKind::PointerFromExposedAddress,
|
||||||
|
PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable()),
|
||||||
|
DynStar => stable_mir::mir::CastKind::DynStar,
|
||||||
|
IntToInt => stable_mir::mir::CastKind::IntToInt,
|
||||||
|
FloatToInt => stable_mir::mir::CastKind::FloatToInt,
|
||||||
|
FloatToFloat => stable_mir::mir::CastKind::FloatToFloat,
|
||||||
|
IntToFloat => stable_mir::mir::CastKind::IntToFloat,
|
||||||
|
PtrToPtr => stable_mir::mir::CastKind::PtrToPtr,
|
||||||
|
FnPtrToPtr => stable_mir::mir::CastKind::FnPtrToPtr,
|
||||||
|
Transmute => stable_mir::mir::CastKind::Transmute,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for ty::adjustment::PointerCoercion {
|
||||||
|
type T = stable_mir::mir::PointerCoercion;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
use ty::adjustment::PointerCoercion;
|
||||||
|
match self {
|
||||||
|
PointerCoercion::ReifyFnPointer => stable_mir::mir::PointerCoercion::ReifyFnPointer,
|
||||||
|
PointerCoercion::UnsafeFnPointer => stable_mir::mir::PointerCoercion::UnsafeFnPointer,
|
||||||
|
PointerCoercion::ClosureFnPointer(unsafety) => {
|
||||||
|
stable_mir::mir::PointerCoercion::ClosureFnPointer(unsafety.stable())
|
||||||
|
}
|
||||||
|
PointerCoercion::MutToConstPointer => {
|
||||||
|
stable_mir::mir::PointerCoercion::MutToConstPointer
|
||||||
|
}
|
||||||
|
PointerCoercion::ArrayToPointer => stable_mir::mir::PointerCoercion::ArrayToPointer,
|
||||||
|
PointerCoercion::Unsize => stable_mir::mir::PointerCoercion::Unsize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for rustc_hir::Unsafety {
|
||||||
|
type T = stable_mir::mir::Safety;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
match self {
|
||||||
|
rustc_hir::Unsafety::Unsafe => stable_mir::mir::Safety::Unsafe,
|
||||||
|
rustc_hir::Unsafety::Normal => stable_mir::mir::Safety::Normal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Stable for FieldIdx {
|
||||||
|
type T = usize;
|
||||||
|
fn stable(&self) -> Self::T {
|
||||||
|
self.as_usize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Stable for mir::Operand<'tcx> {
|
impl<'tcx> Stable for mir::Operand<'tcx> {
|
||||||
type T = stable_mir::mir::Operand;
|
type T = stable_mir::mir::Operand;
|
||||||
fn stable(&self) -> Self::T {
|
fn stable(&self) -> Self::T {
|
||||||
@ -229,17 +352,20 @@ impl Stable for mir::UnwindAction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rustc_assert_msg_to_msg<'tcx>(
|
impl<'tcx> Stable for mir::AssertMessage<'tcx> {
|
||||||
assert_message: &rustc_middle::mir::AssertMessage<'tcx>,
|
type T = stable_mir::mir::AssertMessage;
|
||||||
) -> stable_mir::mir::AssertMessage {
|
fn stable(&self) -> Self::T {
|
||||||
use rustc_middle::mir::AssertKind;
|
use rustc_middle::mir::AssertKind;
|
||||||
match assert_message {
|
match self {
|
||||||
AssertKind::BoundsCheck { len, index } => {
|
AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
|
||||||
stable_mir::mir::AssertMessage::BoundsCheck { len: len.stable(), index: index.stable() }
|
len: len.stable(),
|
||||||
}
|
index: index.stable(),
|
||||||
AssertKind::Overflow(bin_op, op1, op2) => {
|
},
|
||||||
stable_mir::mir::AssertMessage::Overflow(bin_op.stable(), op1.stable(), op2.stable())
|
AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
|
||||||
}
|
bin_op.stable(),
|
||||||
|
op1.stable(),
|
||||||
|
op2.stable(),
|
||||||
|
),
|
||||||
AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()),
|
AssertKind::OverflowNeg(op) => stable_mir::mir::AssertMessage::OverflowNeg(op.stable()),
|
||||||
AssertKind::DivisionByZero(op) => {
|
AssertKind::DivisionByZero(op) => {
|
||||||
stable_mir::mir::AssertMessage::DivisionByZero(op.stable())
|
stable_mir::mir::AssertMessage::DivisionByZero(op.stable())
|
||||||
@ -260,6 +386,7 @@ fn rustc_assert_msg_to_msg<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stable for mir::BinOp {
|
impl Stable for mir::BinOp {
|
||||||
@ -381,7 +508,7 @@ impl<'tcx> Stable for mir::Terminator<'tcx> {
|
|||||||
Assert { cond, expected, msg, target, unwind } => Terminator::Assert {
|
Assert { cond, expected, msg, target, unwind } => Terminator::Assert {
|
||||||
cond: cond.stable(),
|
cond: cond.stable(),
|
||||||
expected: *expected,
|
expected: *expected,
|
||||||
msg: rustc_assert_msg_to_msg(msg),
|
msg: msg.stable(),
|
||||||
target: target.as_usize(),
|
target: target.as_usize(),
|
||||||
unwind: unwind.stable(),
|
unwind: unwind.stable(),
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::stable_mir::ty::Ty;
|
use crate::rustc_internal::Opaque;
|
||||||
|
use crate::stable_mir::{self, ty::Ty};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Body {
|
pub struct Body {
|
||||||
@ -136,12 +137,98 @@ pub enum Statement {
|
|||||||
Nop,
|
Nop,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Region = Opaque;
|
||||||
|
|
||||||
// FIXME this is incomplete
|
// FIXME this is incomplete
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Rvalue {
|
pub enum Rvalue {
|
||||||
Use(Operand),
|
/// Creates a pointer with the indicated mutability to the place.
|
||||||
|
///
|
||||||
|
/// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
|
||||||
|
/// `&raw v` or `addr_of!(v)`.
|
||||||
|
AddressOf(Mutability, Place),
|
||||||
|
|
||||||
|
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
|
||||||
|
/// parameter may be a `usize` as well.
|
||||||
|
/// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
|
||||||
|
/// raw pointers, or function pointers and return a `bool`. The types of the operands must be
|
||||||
|
/// matching, up to the usual caveat of the lifetimes in function pointers.
|
||||||
|
/// * Left and right shift operations accept signed or unsigned integers not necessarily of the
|
||||||
|
/// same type and return a value of the same type as their LHS. Like in Rust, the RHS is
|
||||||
|
/// truncated as needed.
|
||||||
|
/// * The `Bit*` operations accept signed integers, unsigned integers, or bools with matching
|
||||||
|
/// types and return a value of that type.
|
||||||
|
/// * The remaining operations accept signed integers, unsigned integers, or floats with
|
||||||
|
/// matching types and return a value of that type.
|
||||||
|
BinaryOp(BinOp, Operand, Operand),
|
||||||
|
|
||||||
|
/// Performs essentially all of the casts that can be performed via `as`.
|
||||||
|
///
|
||||||
|
/// This allows for casts from/to a variety of types.
|
||||||
|
Cast(CastKind, Operand, Ty),
|
||||||
|
|
||||||
|
/// Same as `BinaryOp`, but yields `(T, bool)` with a `bool` indicating an error condition.
|
||||||
|
///
|
||||||
|
/// For addition, subtraction, and multiplication on integers the error condition is set when
|
||||||
|
/// the infinite precision result would not be equal to the actual result.
|
||||||
CheckedBinaryOp(BinOp, Operand, Operand),
|
CheckedBinaryOp(BinOp, Operand, Operand),
|
||||||
|
|
||||||
|
/// A CopyForDeref is equivalent to a read from a place.
|
||||||
|
/// When such a read happens, it is guaranteed that the only use of the returned value is a
|
||||||
|
/// deref operation, immediately followed by one or more projections.
|
||||||
|
CopyForDeref(Place),
|
||||||
|
|
||||||
|
/// Computes the discriminant of the place, returning it as an integer of type
|
||||||
|
/// [`discriminant_ty`]. Returns zero for types without discriminant.
|
||||||
|
///
|
||||||
|
/// The validity requirements for the underlying value are undecided for this rvalue, see
|
||||||
|
/// [#91095]. Note too that the value of the discriminant is not the same thing as the
|
||||||
|
/// variant index; use [`discriminant_for_variant`] to convert.
|
||||||
|
///
|
||||||
|
/// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
|
||||||
|
/// [#91095]: https://github.com/rust-lang/rust/issues/91095
|
||||||
|
/// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
|
||||||
|
Discriminant(Place),
|
||||||
|
|
||||||
|
/// Yields the length of the place, as a `usize`.
|
||||||
|
///
|
||||||
|
/// If the type of the place is an array, this is the array length. For slices (`[T]`, not
|
||||||
|
/// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
|
||||||
|
/// ill-formed for places of other types.
|
||||||
|
Len(Place),
|
||||||
|
|
||||||
|
/// Creates a reference to the place.
|
||||||
|
Ref(Region, BorrowKind, Place),
|
||||||
|
|
||||||
|
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
|
||||||
|
///
|
||||||
|
/// This is different from a normal transmute because dataflow analysis will treat the box as
|
||||||
|
/// initialized but its content as uninitialized. Like other pointer casts, this in general
|
||||||
|
/// affects alias analysis.
|
||||||
|
ShallowInitBox(Operand, Ty),
|
||||||
|
|
||||||
|
/// Creates a pointer/reference to the given thread local.
|
||||||
|
///
|
||||||
|
/// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
|
||||||
|
/// `*const T`, and if neither of those apply a `&T`.
|
||||||
|
///
|
||||||
|
/// **Note:** This is a runtime operation that actually executes code and is in this sense more
|
||||||
|
/// like a function call. Also, eliminating dead stores of this rvalue causes `fn main() {}` to
|
||||||
|
/// SIGILL for some reason that I (JakobDegen) never got a chance to look into.
|
||||||
|
///
|
||||||
|
/// **Needs clarification**: Are there weird additional semantics here related to the runtime
|
||||||
|
/// nature of this operation?
|
||||||
|
ThreadLocalRef(stable_mir::CrateItem),
|
||||||
|
|
||||||
|
/// Exactly like `BinaryOp`, but less operands.
|
||||||
|
///
|
||||||
|
/// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
|
||||||
|
/// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
|
||||||
|
/// return a value with the same type as their operand.
|
||||||
UnaryOp(UnOp, Operand),
|
UnaryOp(UnOp, Operand),
|
||||||
|
|
||||||
|
/// Yields the operand unchanged
|
||||||
|
Use(Operand),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -157,8 +244,98 @@ pub struct Place {
|
|||||||
pub projection: String,
|
pub projection: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FieldIdx = usize;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SwitchTarget {
|
pub struct SwitchTarget {
|
||||||
pub value: u128,
|
pub value: u128,
|
||||||
pub target: usize,
|
pub target: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum BorrowKind {
|
||||||
|
/// Data must be immutable and is aliasable.
|
||||||
|
Shared,
|
||||||
|
|
||||||
|
/// The immediately borrowed place must be immutable, but projections from
|
||||||
|
/// it don't need to be. For example, a shallow borrow of `a.b` doesn't
|
||||||
|
/// conflict with a mutable borrow of `a.b.c`.
|
||||||
|
Shallow,
|
||||||
|
|
||||||
|
/// Data is mutable and not aliasable.
|
||||||
|
Mut {
|
||||||
|
/// `true` if this borrow arose from method-call auto-ref
|
||||||
|
kind: MutBorrowKind,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum MutBorrowKind {
|
||||||
|
Default,
|
||||||
|
TwoPhaseBorrow,
|
||||||
|
ClosureCapture,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum Mutability {
|
||||||
|
Not,
|
||||||
|
Mut,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum Safety {
|
||||||
|
Unsafe,
|
||||||
|
Normal,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum PointerCoercion {
|
||||||
|
/// Go from a fn-item type to a fn-pointer type.
|
||||||
|
ReifyFnPointer,
|
||||||
|
|
||||||
|
/// Go from a safe fn pointer to an unsafe fn pointer.
|
||||||
|
UnsafeFnPointer,
|
||||||
|
|
||||||
|
/// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
|
||||||
|
/// It cannot convert a closure that requires unsafe.
|
||||||
|
ClosureFnPointer(Safety),
|
||||||
|
|
||||||
|
/// Go from a mut raw pointer to a const raw pointer.
|
||||||
|
MutToConstPointer,
|
||||||
|
|
||||||
|
/// Go from `*const [T; N]` to `*const T`
|
||||||
|
ArrayToPointer,
|
||||||
|
|
||||||
|
/// Unsize a pointer/reference value, e.g., `&[T; n]` to
|
||||||
|
/// `&[T]`. Note that the source could be a thin or fat pointer.
|
||||||
|
/// This will do things like convert thin pointers to fat
|
||||||
|
/// pointers, or convert structs containing thin pointers to
|
||||||
|
/// structs containing fat pointers, or convert between fat
|
||||||
|
/// pointers.
|
||||||
|
Unsize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum CastKind {
|
||||||
|
PointerExposeAddress,
|
||||||
|
PointerFromExposedAddress,
|
||||||
|
PointerCoercion(PointerCoercion),
|
||||||
|
DynStar,
|
||||||
|
IntToInt,
|
||||||
|
FloatToInt,
|
||||||
|
FloatToFloat,
|
||||||
|
IntToFloat,
|
||||||
|
PtrToPtr,
|
||||||
|
FnPtrToPtr,
|
||||||
|
Transmute,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum NullOp {
|
||||||
|
/// Returns the size of a value of that type.
|
||||||
|
SizeOf,
|
||||||
|
/// Returns the minimum alignment of a type.
|
||||||
|
AlignOf,
|
||||||
|
/// Returns the offset of a field.
|
||||||
|
OffsetOf(Vec<FieldIdx>),
|
||||||
|
}
|
||||||
|
@ -0,0 +1,12 @@
|
|||||||
|
trait T {}
|
||||||
|
|
||||||
|
struct S {}
|
||||||
|
|
||||||
|
impl S {
|
||||||
|
fn owo(&self, _: Option<&impl T>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
(S {}).owo(None)
|
||||||
|
//~^ ERROR type annotations needed
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/issue-113264-incorrect-impl-trait-in-path-suggestion.rs:10:16
|
||||||
|
|
|
||||||
|
LL | (S {}).owo(None)
|
||||||
|
| ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
|
||||||
|
|
|
||||||
|
help: consider specifying the generic argument
|
||||||
|
|
|
||||||
|
LL | (S {}).owo(None::<&_>)
|
||||||
|
| ++++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
@ -1,5 +1,5 @@
|
|||||||
warning: where clause not allowed here
|
warning: where clause not allowed here
|
||||||
--> $DIR/type-alias-where-fixable.rs:13:16
|
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:13:16
|
||||||
|
|
|
|
||||||
LL | type Assoc where u32: Copy = ();
|
LL | type Assoc where u32: Copy = ();
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
@ -13,7 +13,7 @@ LL + type Assoc = () where u32: Copy;
|
|||||||
|
|
|
|
||||||
|
|
||||||
warning: where clause not allowed here
|
warning: where clause not allowed here
|
||||||
--> $DIR/type-alias-where-fixable.rs:16:17
|
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:16:17
|
||||||
|
|
|
|
||||||
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
@ -26,7 +26,7 @@ LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
|||||||
|
|
|
|
||||||
|
|
||||||
warning: where clause not allowed here
|
warning: where clause not allowed here
|
||||||
--> $DIR/type-alias-where-fixable.rs:24:17
|
--> $DIR/where-clause-placement-assoc-type-in-impl.rs:24:17
|
||||||
|
|
|
|
||||||
LL | type Assoc2 where u32: Copy, i32: Copy = ();
|
LL | type Assoc2 where u32: Copy, i32: Copy = ();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -0,0 +1,15 @@
|
|||||||
|
// check-pass
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
// Not fine, suggests moving.
|
||||||
|
type Assoc = () where u32: Copy;
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
// Not fine, suggests moving `u32: Copy`
|
||||||
|
type Assoc2 = () where i32: Copy, u32: Copy;
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,15 @@
|
|||||||
|
// check-pass
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
#![feature(associated_type_defaults)]
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
// Not fine, suggests moving.
|
||||||
|
type Assoc where u32: Copy = ();
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
// Not fine, suggests moving `u32: Copy`
|
||||||
|
type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
|
//~^ WARNING where clause not allowed here
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,29 @@
|
|||||||
|
warning: where clause not allowed here
|
||||||
|
--> $DIR/where-clause-placement-assoc-type-in-trait.rs:8:16
|
||||||
|
|
|
||||||
|
LL | type Assoc where u32: Copy = ();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
= note: `#[warn(deprecated_where_clause_location)]` on by default
|
||||||
|
help: move it to the end of the type declaration
|
||||||
|
|
|
||||||
|
LL - type Assoc where u32: Copy = ();
|
||||||
|
LL + type Assoc = () where u32: Copy;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: where clause not allowed here
|
||||||
|
--> $DIR/where-clause-placement-assoc-type-in-trait.rs:11:17
|
||||||
|
|
|
||||||
|
LL | type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
help: move it to the end of the type declaration
|
||||||
|
|
|
||||||
|
LL - type Assoc2 where u32: Copy = () where i32: Copy;
|
||||||
|
LL + type Assoc2 = () where i32: Copy, u32: Copy;
|
||||||
|
|
|
||||||
|
|
||||||
|
warning: 2 warnings emitted
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
error: where clauses are not allowed after the type for type aliases
|
error: where clauses are not allowed after the type for type aliases
|
||||||
--> $DIR/type-alias-where.rs:6:15
|
--> $DIR/where-clause-placement-type-alias.rs:6:15
|
||||||
|
|
|
|
||||||
LL | type Bar = () where u32: Copy;
|
LL | type Bar = () where u32: Copy;
|
||||||
| ^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^
|
||||||
@ -7,7 +7,7 @@ LL | type Bar = () where u32: Copy;
|
|||||||
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
= note: see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
|
||||||
|
|
||||||
error: where clauses are not allowed after the type for type aliases
|
error: where clauses are not allowed after the type for type aliases
|
||||||
--> $DIR/type-alias-where.rs:8:15
|
--> $DIR/where-clause-placement-type-alias.rs:8:15
|
||||||
|
|
|
|
||||||
LL | type Baz = () where;
|
LL | type Baz = () where;
|
||||||
| ^^^^^
|
| ^^^^^
|
Loading…
Reference in New Issue
Block a user