Auto merge of #112080 - matthiaskrgr:rollup-pmpbe49, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #111558 (Move tests) - #111827 (Add build instructions for cranelift backend as part of Rust repo) - #111988 (Make `TyKind: Debug` have less verbose output) - #112022 (Check nested obligations during coercion unify in new solver) - #112057 (Suggest correct `self_ty`) - #112063 (Add a test for issue 110457/incremental ICE with closures with the same span) Failed merges: - #112068 (Move tests from `ui/discrim` dir) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d9a4d5eca3
@ -42,6 +42,32 @@ This will build your project with rustc_codegen_cranelift instead of the usual L
|
||||
|
||||
For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.md](docs/usage.md).
|
||||
|
||||
## Building and testing with changes in rustc code
|
||||
|
||||
This is useful when changing code in `rustc_codegen_cranelift` as part of changing [main Rust repository](https://github.com/rust-lang/rust/).
|
||||
This can happen, for example, when you are implementing a new compiler intrinsic.
|
||||
|
||||
Instruction below uses `$RustCheckoutDir` as substitute for any folder where you cloned Rust repository.
|
||||
|
||||
You need to do this steps to successfully compile and use the cranelift backend with your changes in rustc code:
|
||||
|
||||
1. `cd $RustCheckoutDir`
|
||||
2. Run `python x.py setup` and choose option for compiler (`b`).
|
||||
3. Build compiler and necessary tools: `python x.py build --stage=2 compiler library/std src/tools/rustdoc src/tools/rustfmt`
|
||||
* (Optional) You can also build cargo by adding `src/tools/cargo` to previous command.
|
||||
4. Copy exectutable files from `./build/host/stage2-tools/<your hostname triple>/release`
|
||||
to `./build/host/stage2/bin/`. Note that you would need to do this every time you rebuilt `rust` repository.
|
||||
5. Copy cargo from another toolchain: `cp $(rustup which cargo) .build/<your hostname triple>/stage2/bin/cargo`
|
||||
* Another option is to build it at step 3 and copy with other executables at step 4.
|
||||
6. Link your new `rustc` to toolchain: `rustup toolchain link stage2 ./build/host/stage2/`.
|
||||
7. (Windows only) compile y.rs: `rustc +stage2 -O y.rs`.
|
||||
8. You need to prefix every `./y.rs` (or `y` if you built `y.rs`) command by `rustup run stage2` to make cg_clif use your local changes in rustc.
|
||||
|
||||
* `rustup run stage2 ./y.rs prepare`
|
||||
* `rustup run stage2 ./y.rs build`
|
||||
* (Optional) run tests: `rustup run stage2 ./y.rs test`
|
||||
9. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.
|
||||
|
||||
## Configuration
|
||||
|
||||
See the documentation on the `BackendConfig` struct in [config.rs](src/config.rs) for all
|
||||
|
@ -902,7 +902,7 @@ fn report_trait_method_mismatch<'tcx>(
|
||||
if trait_m.fn_has_self_parameter =>
|
||||
{
|
||||
let ty = trait_sig.inputs()[0];
|
||||
let sugg = match ExplicitSelf::determine(ty, |_| ty == impl_trait_ref.self_ty()) {
|
||||
let sugg = match ExplicitSelf::determine(ty, |ty| ty == impl_trait_ref.self_ty()) {
|
||||
ExplicitSelf::ByValue => "self".to_owned(),
|
||||
ExplicitSelf::ByReference(_, hir::Mutability::Not) => "&self".to_owned(),
|
||||
ExplicitSelf::ByReference(_, hir::Mutability::Mut) => "&mut self".to_owned(),
|
||||
|
@ -62,6 +62,7 @@
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use rustc_trait_selection::infer::InferCtxtExt as _;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||
};
|
||||
@ -144,12 +145,28 @@ fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> {
|
||||
debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub);
|
||||
self.commit_if_ok(|_| {
|
||||
let at = self.at(&self.cause, self.fcx.param_env);
|
||||
if self.use_lub {
|
||||
|
||||
let res = if self.use_lub {
|
||||
at.lub(DefineOpaqueTypes::Yes, b, a)
|
||||
} else {
|
||||
at.sup(DefineOpaqueTypes::Yes, b, a)
|
||||
.map(|InferOk { value: (), obligations }| InferOk { value: a, obligations })
|
||||
};
|
||||
|
||||
// In the new solver, lazy norm may allow us to shallowly equate
|
||||
// more types, but we emit possibly impossible-to-satisfy obligations.
|
||||
// Filter these cases out to make sure our coercion is more accurate.
|
||||
if self.tcx.trait_solver_next() {
|
||||
if let Ok(res) = &res {
|
||||
for obligation in &res.obligations {
|
||||
if !self.predicate_may_hold(&obligation) {
|
||||
return Err(TypeError::Mismatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,16 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type FreeRegion = ty::FreeRegion;
|
||||
type RegionVid = ty::RegionVid;
|
||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||
|
||||
fn ty_and_mut_to_parts(
|
||||
TypeAndMut { ty, mutbl }: TypeAndMut<'tcx>,
|
||||
) -> (Self::Ty, Self::Mutability) {
|
||||
(ty, mutbl)
|
||||
}
|
||||
|
||||
fn mutability_is_mut(mutbl: Self::Mutability) -> bool {
|
||||
mutbl.is_mut()
|
||||
}
|
||||
}
|
||||
|
||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||
|
@ -1496,7 +1496,7 @@ pub fn remap_generic_params_to_declaration_params(
|
||||
/// identified by both a universe, as well as a name residing within that universe. Distinct bound
|
||||
/// regions/types/consts within the same universe simply have an unknown relationship to one
|
||||
/// another.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
#[derive(HashStable, TyEncodable, TyDecodable)]
|
||||
pub struct Placeholder<T> {
|
||||
pub universe: UniverseIndex,
|
||||
|
@ -685,29 +685,30 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
||||
}
|
||||
ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
|
||||
ty::Infer(infer_ty) => {
|
||||
let verbose = self.should_print_verbose();
|
||||
if self.should_print_verbose() {
|
||||
p!(write("{:?}", ty.kind()));
|
||||
return Ok(self);
|
||||
}
|
||||
|
||||
if let ty::TyVar(ty_vid) = infer_ty {
|
||||
if let Some(name) = self.ty_infer_name(ty_vid) {
|
||||
p!(write("{}", name))
|
||||
} else {
|
||||
if verbose {
|
||||
p!(write("{:?}", infer_ty))
|
||||
} else {
|
||||
p!(write("{}", infer_ty))
|
||||
}
|
||||
p!(write("{}", infer_ty))
|
||||
}
|
||||
} else {
|
||||
if verbose { p!(write("{:?}", infer_ty)) } else { p!(write("{}", infer_ty)) }
|
||||
p!(write("{}", infer_ty))
|
||||
}
|
||||
}
|
||||
ty::Error(_) => p!("{{type error}}"),
|
||||
ty::Param(ref param_ty) => p!(print(param_ty)),
|
||||
ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
|
||||
ty::BoundTyKind::Anon => debug_bound_var(&mut self, debruijn, bound_ty.var)?,
|
||||
ty::BoundTyKind::Anon => {
|
||||
rustc_type_ir::debug_bound_var(&mut self, debruijn, bound_ty.var)?
|
||||
}
|
||||
ty::BoundTyKind::Param(_, s) => match self.should_print_verbose() {
|
||||
true if debruijn == ty::INNERMOST => p!(write("^{}", s)),
|
||||
true => p!(write("^{}_{}", debruijn.index(), s)),
|
||||
false => p!(write("{}", s)),
|
||||
true => p!(write("{:?}", ty.kind())),
|
||||
false => p!(write("{s}")),
|
||||
},
|
||||
},
|
||||
ty::Adt(def, substs) => {
|
||||
@ -740,10 +741,11 @@ fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error>
|
||||
}
|
||||
}
|
||||
ty::Placeholder(placeholder) => match placeholder.bound.kind {
|
||||
ty::BoundTyKind::Anon => {
|
||||
debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound.var)?;
|
||||
}
|
||||
ty::BoundTyKind::Param(_, name) => p!(write("{}", name)),
|
||||
ty::BoundTyKind::Anon => p!(write("{placeholder:?}")),
|
||||
ty::BoundTyKind::Param(_, name) => match self.should_print_verbose() {
|
||||
true => p!(write("{:?}", ty.kind())),
|
||||
false => p!(write("{name}")),
|
||||
},
|
||||
},
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
||||
// We use verbose printing in 'NO_QUERIES' mode, to
|
||||
@ -1372,11 +1374,9 @@ macro_rules! print_underscore {
|
||||
}
|
||||
|
||||
ty::ConstKind::Bound(debruijn, bound_var) => {
|
||||
debug_bound_var(&mut self, debruijn, bound_var)?
|
||||
rustc_type_ir::debug_bound_var(&mut self, debruijn, bound_var)?
|
||||
}
|
||||
ty::ConstKind::Placeholder(placeholder) => {
|
||||
debug_placeholder_var(&mut self, placeholder.universe, placeholder.bound)?;
|
||||
},
|
||||
ty::ConstKind::Placeholder(placeholder) => p!(write("{placeholder:?}")),
|
||||
// FIXME(generic_const_exprs):
|
||||
// write out some legible representation of an abstract const?
|
||||
ty::ConstKind::Expr(_) => p!("{{const expr}}"),
|
||||
@ -3065,27 +3065,3 @@ pub struct OpaqueFnEntry<'tcx> {
|
||||
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
|
||||
return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
|
||||
}
|
||||
|
||||
pub fn debug_bound_var<T: std::fmt::Write>(
|
||||
fmt: &mut T,
|
||||
debruijn: ty::DebruijnIndex,
|
||||
var: ty::BoundVar,
|
||||
) -> Result<(), std::fmt::Error> {
|
||||
if debruijn == ty::INNERMOST {
|
||||
write!(fmt, "^{}", var.index())
|
||||
} else {
|
||||
write!(fmt, "^{}_{}", debruijn.index(), var.index())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn debug_placeholder_var<T: std::fmt::Write>(
|
||||
fmt: &mut T,
|
||||
universe: ty::UniverseIndex,
|
||||
bound: ty::BoundVar,
|
||||
) -> Result<(), std::fmt::Error> {
|
||||
if universe == ty::UniverseIndex::ROOT {
|
||||
write!(fmt, "!{}", bound.index())
|
||||
} else {
|
||||
write!(fmt, "!{}_{}", universe.index(), bound.index())
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,35 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "({:?}; c_variadic: {})->{:?}", self.inputs(), self.c_variadic, self.output())
|
||||
let ty::FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = self;
|
||||
|
||||
write!(f, "{}", unsafety.prefix_str())?;
|
||||
match abi {
|
||||
rustc_target::spec::abi::Abi::Rust => (),
|
||||
abi => write!(f, "extern \"{abi:?}\" ")?,
|
||||
};
|
||||
|
||||
write!(f, "fn(")?;
|
||||
let inputs = self.inputs();
|
||||
match inputs.len() {
|
||||
0 if *c_variadic => write!(f, "...)")?,
|
||||
0 => write!(f, ")")?,
|
||||
_ => {
|
||||
for ty in &self.inputs()[0..(self.inputs().len() - 1)] {
|
||||
write!(f, "{ty:?}, ")?;
|
||||
}
|
||||
write!(f, "{:?}", self.inputs().last().unwrap())?;
|
||||
if *c_variadic {
|
||||
write!(f, "...")?;
|
||||
}
|
||||
write!(f, ")")?;
|
||||
}
|
||||
}
|
||||
|
||||
match self.output().kind() {
|
||||
ty::Tuple(list) if list.is_empty() => Ok(()),
|
||||
_ => write!(f, " -> {:?}", self.output()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -216,20 +244,37 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Param(param) => write!(f, "{param:?}"),
|
||||
Infer(var) => write!(f, "{var:?}"),
|
||||
Bound(debruijn, var) => ty::print::debug_bound_var(f, *debruijn, *var),
|
||||
Placeholder(placeholder) => {
|
||||
ty::print::debug_placeholder_var(f, placeholder.universe, placeholder.bound)
|
||||
}
|
||||
Bound(debruijn, var) => rustc_type_ir::debug_bound_var(f, *debruijn, *var),
|
||||
Placeholder(placeholder) => write!(f, "{placeholder:?}"),
|
||||
Unevaluated(uv) => {
|
||||
f.debug_tuple("Unevaluated").field(&uv.substs).field(&uv.def).finish()
|
||||
}
|
||||
Value(valtree) => write!(f, "{valtree:?}"),
|
||||
Error(_) => write!(f, "[const error]"),
|
||||
Error(_) => write!(f, "{{const error}}"),
|
||||
Expr(expr) => write!(f, "{expr:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ty::BoundTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.kind {
|
||||
ty::BoundTyKind::Anon => write!(f, "{:?}", self.var),
|
||||
ty::BoundTyKind::Param(_, sym) => write!(f, "{sym:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug> fmt::Debug for ty::Placeholder<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if self.universe == ty::UniverseIndex::ROOT {
|
||||
write!(f, "!{:?}", self.bound)
|
||||
} else {
|
||||
write!(f, "!{}_{:?}", self.universe.index(), self.bound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Atomic structs
|
||||
//
|
||||
@ -294,6 +339,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::ty::AliasRelationDirection,
|
||||
crate::ty::Placeholder<crate::ty::BoundRegion>,
|
||||
crate::ty::Placeholder<crate::ty::BoundTy>,
|
||||
crate::ty::Placeholder<ty::BoundVar>,
|
||||
crate::ty::ClosureKind,
|
||||
crate::ty::FreeRegion,
|
||||
crate::ty::InferTy,
|
||||
@ -310,7 +356,6 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
interpret::Scalar,
|
||||
rustc_target::abi::Size,
|
||||
ty::BoundVar,
|
||||
ty::Placeholder<ty::BoundVar>,
|
||||
}
|
||||
|
||||
TrivialTypeTraversalAndLiftImpls! {
|
||||
|
@ -1511,10 +1511,11 @@ fn index(self) -> usize {
|
||||
|
||||
rustc_index::newtype_index! {
|
||||
#[derive(HashStable)]
|
||||
#[debug_format = "{}"]
|
||||
pub struct BoundVar {}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable)]
|
||||
pub struct BoundTy {
|
||||
pub var: BoundVar,
|
||||
|
@ -52,7 +52,7 @@ pub trait Interner: Sized {
|
||||
type PolyFnSig: Clone + Debug + Hash + Ord;
|
||||
type ListBinderExistentialPredicate: Clone + Debug + Hash + Ord;
|
||||
type BinderListTy: Clone + Debug + Hash + Ord;
|
||||
type ListTy: Clone + Debug + Hash + Ord;
|
||||
type ListTy: Clone + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
||||
type AliasTy: Clone + Debug + Hash + Ord;
|
||||
type ParamTy: Clone + Debug + Hash + Ord;
|
||||
type BoundTy: Clone + Debug + Hash + Ord;
|
||||
@ -67,6 +67,9 @@ pub trait Interner: Sized {
|
||||
type FreeRegion: Clone + Debug + Hash + Ord;
|
||||
type RegionVid: Clone + Debug + Hash + Ord;
|
||||
type PlaceholderRegion: Clone + Debug + Hash + Ord;
|
||||
|
||||
fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Self::Mutability);
|
||||
fn mutability_is_mut(mutbl: Self::Mutability) -> bool;
|
||||
}
|
||||
|
||||
/// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter`
|
||||
@ -390,7 +393,19 @@ pub fn shifted_out_to_binder(self, to_binder: DebruijnIndex) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
pub fn debug_bound_var<T: std::fmt::Write>(
|
||||
fmt: &mut T,
|
||||
debruijn: DebruijnIndex,
|
||||
var: impl std::fmt::Debug,
|
||||
) -> Result<(), std::fmt::Error> {
|
||||
if debruijn == INNERMOST {
|
||||
write!(fmt, "^{:?}", var)
|
||||
} else {
|
||||
write!(fmt, "^{}_{:?}", debruijn.index(), var)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum IntTy {
|
||||
Isize,
|
||||
@ -448,7 +463,7 @@ pub fn to_unsigned(self) -> UintTy {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Debug)]
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum UintTy {
|
||||
Usize,
|
||||
@ -506,7 +521,7 @@ pub fn to_signed(self) -> IntTy {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum FloatTy {
|
||||
F32,
|
||||
|
@ -4,11 +4,12 @@
|
||||
|
||||
use crate::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::Interner;
|
||||
use crate::{FloatTy, IntTy, Interner, UintTy};
|
||||
use rustc_data_structures::functor::IdFunctor;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
|
||||
use core::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
@ -163,3 +164,21 @@ fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::Break
|
||||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for IntTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.name_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for UintTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.name_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for FloatTy {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.name_str())
|
||||
}
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ fn clone(&self) -> Self {
|
||||
Str => Str,
|
||||
Array(t, c) => Array(t.clone(), c.clone()),
|
||||
Slice(t) => Slice(t.clone()),
|
||||
RawPtr(t) => RawPtr(t.clone()),
|
||||
RawPtr(p) => RawPtr(p.clone()),
|
||||
Ref(r, t, m) => Ref(r.clone(), t.clone(), m.clone()),
|
||||
FnDef(d, s) => FnDef(d.clone(), s.clone()),
|
||||
FnPtr(s) => FnPtr(s.clone()),
|
||||
@ -499,33 +499,65 @@ fn hash<__H: hash::Hasher>(&self, state: &mut __H) -> () {
|
||||
impl<I: Interner> fmt::Debug for TyKind<I> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Bool => f.write_str("Bool"),
|
||||
Char => f.write_str("Char"),
|
||||
Int(i) => f.debug_tuple_field1_finish("Int", i),
|
||||
Uint(u) => f.debug_tuple_field1_finish("Uint", u),
|
||||
Float(float) => f.debug_tuple_field1_finish("Float", float),
|
||||
Bool => write!(f, "bool"),
|
||||
Char => write!(f, "char"),
|
||||
Int(i) => write!(f, "{i:?}"),
|
||||
Uint(u) => write!(f, "{u:?}"),
|
||||
Float(float) => write!(f, "{float:?}"),
|
||||
Adt(d, s) => f.debug_tuple_field2_finish("Adt", d, s),
|
||||
Foreign(d) => f.debug_tuple_field1_finish("Foreign", d),
|
||||
Str => f.write_str("Str"),
|
||||
Array(t, c) => f.debug_tuple_field2_finish("Array", t, c),
|
||||
Slice(t) => f.debug_tuple_field1_finish("Slice", t),
|
||||
RawPtr(t) => f.debug_tuple_field1_finish("RawPtr", t),
|
||||
Ref(r, t, m) => f.debug_tuple_field3_finish("Ref", r, t, m),
|
||||
Str => write!(f, "str"),
|
||||
Array(t, c) => write!(f, "[{t:?}; {c:?}]"),
|
||||
Slice(t) => write!(f, "[{t:?}]"),
|
||||
RawPtr(p) => {
|
||||
let (ty, mutbl) = I::ty_and_mut_to_parts(p.clone());
|
||||
match I::mutability_is_mut(mutbl) {
|
||||
true => write!(f, "*mut "),
|
||||
false => write!(f, "*const "),
|
||||
}?;
|
||||
write!(f, "{ty:?}")
|
||||
}
|
||||
Ref(r, t, m) => match I::mutability_is_mut(m.clone()) {
|
||||
true => write!(f, "&{r:?} mut {t:?}"),
|
||||
false => write!(f, "&{r:?} {t:?}"),
|
||||
},
|
||||
FnDef(d, s) => f.debug_tuple_field2_finish("FnDef", d, s),
|
||||
FnPtr(s) => f.debug_tuple_field1_finish("FnPtr", s),
|
||||
Dynamic(p, r, repr) => f.debug_tuple_field3_finish("Dynamic", p, r, repr),
|
||||
FnPtr(s) => write!(f, "{s:?}"),
|
||||
Dynamic(p, r, repr) => match repr {
|
||||
DynKind::Dyn => write!(f, "dyn {p:?} + {r:?}"),
|
||||
DynKind::DynStar => write!(f, "dyn* {p:?} + {r:?}"),
|
||||
},
|
||||
Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, s),
|
||||
Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, s, m),
|
||||
GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", g),
|
||||
GeneratorWitnessMIR(d, s) => f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, s),
|
||||
Never => f.write_str("Never"),
|
||||
Tuple(t) => f.debug_tuple_field1_finish("Tuple", t),
|
||||
Never => write!(f, "!"),
|
||||
Tuple(t) => {
|
||||
let mut iter = t.clone().into_iter();
|
||||
|
||||
write!(f, "(")?;
|
||||
|
||||
match iter.next() {
|
||||
None => return write!(f, ")"),
|
||||
Some(ty) => write!(f, "{ty:?}")?,
|
||||
};
|
||||
|
||||
match iter.next() {
|
||||
None => return write!(f, ",)"),
|
||||
Some(ty) => write!(f, "{ty:?})")?,
|
||||
}
|
||||
|
||||
for ty in iter {
|
||||
write!(f, ", {ty:?}")?;
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
Alias(i, a) => f.debug_tuple_field2_finish("Alias", i, a),
|
||||
Param(p) => f.debug_tuple_field1_finish("Param", p),
|
||||
Bound(d, b) => f.debug_tuple_field2_finish("Bound", d, b),
|
||||
Placeholder(p) => f.debug_tuple_field1_finish("Placeholder", p),
|
||||
Infer(t) => f.debug_tuple_field1_finish("Infer", t),
|
||||
TyKind::Error(e) => f.debug_tuple_field1_finish("Error", e),
|
||||
Param(p) => write!(f, "{p:?}"),
|
||||
Bound(d, b) => crate::debug_bound_var(f, *d, b),
|
||||
Placeholder(p) => write!(f, "{p:?}"),
|
||||
Infer(t) => write!(f, "{t:?}"),
|
||||
TyKind::Error(_) => write!(f, "{{type error}}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,8 +10,8 @@
|
||||
|
||||
const ENTRY_LIMIT: usize = 900;
|
||||
// FIXME: The following limits should be reduced eventually.
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1920;
|
||||
const ROOT_ENTRY_LIMIT: usize = 896;
|
||||
const ISSUES_ENTRY_LIMIT: usize = 1898;
|
||||
const ROOT_ENTRY_LIMIT: usize = 894;
|
||||
|
||||
const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
|
||||
"rs", // test source files
|
||||
|
@ -0,0 +1,90 @@
|
||||
// force-host
|
||||
// no-prefer-dynamic
|
||||
#![crate_type = "proc-macro"]
|
||||
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
|
||||
|
||||
#[proc_macro]
|
||||
pub fn expand(_: TokenStream) -> TokenStream {
|
||||
// Hand expansion/rewriting of
|
||||
// ```
|
||||
// quote! {
|
||||
// output_mut(|o| o.copied_text = "".into());
|
||||
// output_mut(|o| o.copied_text = format!("{:?}", self.tile_db));
|
||||
// }.into()
|
||||
// ```
|
||||
stream([
|
||||
ident("output_mut"),
|
||||
group(
|
||||
Delimiter::Parenthesis,
|
||||
[
|
||||
or(),
|
||||
ident("o"),
|
||||
or(),
|
||||
ident("o"),
|
||||
dot(),
|
||||
ident("copied_text"),
|
||||
eq(),
|
||||
string(""),
|
||||
dot(),
|
||||
ident("into"),
|
||||
group(Delimiter::Parenthesis, []),
|
||||
],
|
||||
),
|
||||
semi(),
|
||||
ident("output_mut"),
|
||||
group(
|
||||
Delimiter::Parenthesis,
|
||||
[
|
||||
or(),
|
||||
ident("o"),
|
||||
or(),
|
||||
ident("o"),
|
||||
dot(),
|
||||
ident("copied_text"),
|
||||
eq(),
|
||||
ident("format"),
|
||||
bang(),
|
||||
group(
|
||||
Delimiter::Parenthesis,
|
||||
[string("{:?}"), comma(), ident("self"), dot(), ident("tile_db")],
|
||||
),
|
||||
],
|
||||
),
|
||||
semi(),
|
||||
])
|
||||
}
|
||||
|
||||
fn stream(s: impl IntoIterator<Item = TokenTree>) -> TokenStream {
|
||||
s.into_iter().collect()
|
||||
}
|
||||
|
||||
fn ident(i: &str) -> TokenTree {
|
||||
TokenTree::Ident(Ident::new(i, Span::call_site()))
|
||||
}
|
||||
fn group(d: Delimiter, s: impl IntoIterator<Item = TokenTree>) -> TokenTree {
|
||||
TokenTree::Group(Group::new(d, s.into_iter().collect()))
|
||||
}
|
||||
fn semi() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new(';', Spacing::Alone))
|
||||
}
|
||||
fn or() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new('|', Spacing::Alone))
|
||||
}
|
||||
fn dot() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new('.', Spacing::Alone))
|
||||
}
|
||||
fn eq() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new('=', Spacing::Alone))
|
||||
}
|
||||
fn bang() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new('!', Spacing::Alone))
|
||||
}
|
||||
fn comma() -> TokenTree {
|
||||
TokenTree::Punct(Punct::new(',', Spacing::Alone))
|
||||
}
|
||||
fn string(s: &str) -> TokenTree {
|
||||
TokenTree::Literal(Literal::string(s))
|
||||
}
|
47
tests/incremental/issue-110457-same-span-closures/main.rs
Normal file
47
tests/incremental/issue-110457-same-span-closures/main.rs
Normal file
@ -0,0 +1,47 @@
|
||||
// aux-build: egui_inspect_derive.rs
|
||||
// revisions: cpass1 cpass2
|
||||
|
||||
extern crate egui_inspect_derive;
|
||||
|
||||
pub struct TileDef {
|
||||
pub layer: (),
|
||||
#[cfg(cpass2)]
|
||||
pub blend_graphic: String,
|
||||
}
|
||||
|
||||
pub(crate) struct GameState {
|
||||
pub(crate) tile_db: TileDb,
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
fn inspect_mut(&mut self) {
|
||||
egui_inspect_derive::expand! {}
|
||||
}
|
||||
}
|
||||
|
||||
fn new() -> GameState {
|
||||
loop {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut app = new();
|
||||
app.inspect_mut();
|
||||
}
|
||||
// this is actually used
|
||||
pub struct TileDb {
|
||||
unknown_bg: TileDef,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for TileDb {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PlatformOutput {
|
||||
pub copied_text: String,
|
||||
}
|
||||
|
||||
pub fn output_mut<R>(writer: impl FnOnce(&mut PlatformOutput) -> R) -> R {
|
||||
loop {}
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// revisions: current next
|
||||
//[next] compile-flag: -Ztrait-solver=next
|
||||
// check-pass
|
||||
|
||||
use std::path::Path;
|
||||
|
@ -22,7 +22,7 @@ LL | fn bar(&mut self) { }
|
||||
| ^^^^^^^^^
|
||||
| |
|
||||
| types differ in mutability
|
||||
| help: change the self-receiver type to match the trait: `self: &Bar`
|
||||
| help: change the self-receiver type to match the trait: `&self`
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/E0053.rs:3:12
|
||||
|
7
tests/ui/mismatched_types/issue-112036.rs
Normal file
7
tests/ui/mismatched_types/issue-112036.rs
Normal file
@ -0,0 +1,7 @@
|
||||
struct Foo;
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(self) {} //~ ERROR method `drop` has an incompatible type for trait
|
||||
}
|
||||
|
||||
fn main() {}
|
15
tests/ui/mismatched_types/issue-112036.stderr
Normal file
15
tests/ui/mismatched_types/issue-112036.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0053]: method `drop` has an incompatible type for trait
|
||||
--> $DIR/issue-112036.rs:4:13
|
||||
|
|
||||
LL | fn drop(self) {}
|
||||
| ^^^^
|
||||
| |
|
||||
| expected `&mut Foo`, found `Foo`
|
||||
| help: change the self-receiver type to match the trait: `&mut self`
|
||||
|
|
||||
= note: expected signature `fn(&mut Foo)`
|
||||
found signature `fn(Foo)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -1,7 +1,7 @@
|
||||
DefId(0:3 ~ thir_flat[7b97]::main):
|
||||
Thir {
|
||||
body_type: Fn(
|
||||
([]; c_variadic: false)->(),
|
||||
fn(),
|
||||
),
|
||||
arms: [],
|
||||
blocks: [
|
||||
|
Loading…
Reference in New Issue
Block a user