Auto merge of #125179 - matthiaskrgr:rollup-wkdwoaj, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #124871 (Don't ICE because recomputing overflow goals during find_best_leaf_obligation causes inference side-effects) - #125018 (Update linker-plugin-lto.md to include LLVM 18) - #125130 (rustdoc-json-types: Document `Id`) - #125170 (Uplift `FnSig` into `rustc_type_ir` (redux)) - #125172 (Fix assertion when attempting to convert `f16` and `f128` with `as`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
97bf25c8cf
@ -247,7 +247,10 @@ pub trait BuilderMethods<'a, 'tcx>:
|
|||||||
} else {
|
} else {
|
||||||
(in_ty, dest_ty)
|
(in_ty, dest_ty)
|
||||||
};
|
};
|
||||||
assert!(matches!(self.cx().type_kind(float_ty), TypeKind::Float | TypeKind::Double));
|
assert!(matches!(
|
||||||
|
self.cx().type_kind(float_ty),
|
||||||
|
TypeKind::Half | TypeKind::Float | TypeKind::Double | TypeKind::FP128
|
||||||
|
));
|
||||||
assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer);
|
assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer);
|
||||||
|
|
||||||
if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts {
|
if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts {
|
||||||
|
@ -112,6 +112,12 @@ impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::FnSig<I> {
|
||||||
|
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
|
||||||
|
format!("{self:?}").into_diag_arg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
||||||
|
|
||||||
impl IntoDiagArg for bool {
|
impl IntoDiagArg for bool {
|
||||||
|
@ -3191,7 +3191,7 @@ pub enum Unsafety {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Unsafety {
|
impl Unsafety {
|
||||||
pub fn prefix_str(&self) -> &'static str {
|
pub fn prefix_str(self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Self::Unsafe => "unsafe ",
|
Self::Unsafe => "unsafe ",
|
||||||
Self::Normal => "",
|
Self::Normal => "",
|
||||||
|
@ -92,7 +92,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
||||||
type AdtDef = ty::AdtDef<'tcx>;
|
type AdtDef = ty::AdtDef<'tcx>;
|
||||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||||
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
|
type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>];
|
||||||
type GenericArg = ty::GenericArg<'tcx>;
|
type GenericArg = ty::GenericArg<'tcx>;
|
||||||
|
|
||||||
type Term = ty::Term<'tcx>;
|
type Term = ty::Term<'tcx>;
|
||||||
@ -103,6 +103,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||||
type Ty = Ty<'tcx>;
|
type Ty = Ty<'tcx>;
|
||||||
type Tys = &'tcx List<Ty<'tcx>>;
|
type Tys = &'tcx List<Ty<'tcx>>;
|
||||||
|
type FnInputTys = &'tcx [Ty<'tcx>];
|
||||||
type ParamTy = ParamTy;
|
type ParamTy = ParamTy;
|
||||||
type BoundTy = ty::BoundTy;
|
type BoundTy = ty::BoundTy;
|
||||||
type PlaceholderTy = ty::PlaceholderType;
|
type PlaceholderTy = ty::PlaceholderType;
|
||||||
@ -113,21 +114,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type AllocId = crate::mir::interpret::AllocId;
|
type AllocId = crate::mir::interpret::AllocId;
|
||||||
|
|
||||||
type Pat = Pattern<'tcx>;
|
type Pat = Pattern<'tcx>;
|
||||||
|
type Unsafety = hir::Unsafety;
|
||||||
|
type Abi = abi::Abi;
|
||||||
|
|
||||||
type Const = ty::Const<'tcx>;
|
type Const = ty::Const<'tcx>;
|
||||||
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
||||||
type PlaceholderConst = ty::PlaceholderConst;
|
type PlaceholderConst = ty::PlaceholderConst;
|
||||||
type ParamConst = ty::ParamConst;
|
type ParamConst = ty::ParamConst;
|
||||||
type BoundConst = ty::BoundVar;
|
type BoundConst = ty::BoundVar;
|
||||||
type ValueConst = ty::ValTree<'tcx>;
|
type ValueConst = ty::ValTree<'tcx>;
|
||||||
|
|
||||||
type ExprConst = ty::Expr<'tcx>;
|
type ExprConst = ty::Expr<'tcx>;
|
||||||
|
|
||||||
type Region = Region<'tcx>;
|
type Region = Region<'tcx>;
|
||||||
type EarlyParamRegion = ty::EarlyParamRegion;
|
type EarlyParamRegion = ty::EarlyParamRegion;
|
||||||
type LateParamRegion = ty::LateParamRegion;
|
type LateParamRegion = ty::LateParamRegion;
|
||||||
type BoundRegion = ty::BoundRegion;
|
type BoundRegion = ty::BoundRegion;
|
||||||
type InferRegion = ty::RegionVid;
|
type InferRegion = ty::RegionVid;
|
||||||
|
|
||||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||||
|
|
||||||
type Predicate = Predicate<'tcx>;
|
type Predicate = Predicate<'tcx>;
|
||||||
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
||||||
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
||||||
@ -135,10 +139,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
||||||
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
||||||
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
||||||
|
|
||||||
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
||||||
type ClosureKind = ty::ClosureKind;
|
type ClosureKind = ty::ClosureKind;
|
||||||
|
|
||||||
type Clauses = ty::Clauses<'tcx>;
|
type Clauses = ty::Clauses<'tcx>;
|
||||||
|
|
||||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
||||||
self.mk_canonical_var_infos(infos)
|
self.mk_canonical_var_infos(infos)
|
||||||
}
|
}
|
||||||
@ -191,7 +197,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
args: Self::GenericArgs,
|
args: Self::GenericArgs,
|
||||||
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
|
) -> (rustc_type_ir::TraitRef<Self>, Self::OwnItemArgs) {
|
||||||
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
|
assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
|
||||||
let trait_def_id = self.parent(def_id);
|
let trait_def_id = self.parent(def_id);
|
||||||
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
|
assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
|
||||||
@ -223,6 +229,18 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
|
||||||
|
fn is_rust(self) -> bool {
|
||||||
|
matches!(self, abi::Abi::Rust)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::inherent::Unsafety<TyCtxt<'tcx>> for hir::Unsafety {
|
||||||
|
fn prefix_str(self) -> &'static str {
|
||||||
|
self.prefix_str()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||||
|
|
||||||
pub struct CtxtInterners<'tcx> {
|
pub struct CtxtInterners<'tcx> {
|
||||||
|
@ -3034,6 +3034,16 @@ forward_display_to_print! {
|
|||||||
define_print! {
|
define_print! {
|
||||||
(self, cx):
|
(self, cx):
|
||||||
|
|
||||||
|
ty::FnSig<'tcx> {
|
||||||
|
p!(write("{}", self.unsafety.prefix_str()));
|
||||||
|
|
||||||
|
if self.abi != Abi::Rust {
|
||||||
|
p!(write("extern {} ", self.abi));
|
||||||
|
}
|
||||||
|
|
||||||
|
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||||
|
}
|
||||||
|
|
||||||
ty::TraitRef<'tcx> {
|
ty::TraitRef<'tcx> {
|
||||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||||
}
|
}
|
||||||
@ -3169,16 +3179,6 @@ define_print_and_forward_display! {
|
|||||||
p!("{{", comma_sep(self.iter()), "}}")
|
p!("{{", comma_sep(self.iter()), "}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnSig<'tcx> {
|
|
||||||
p!(write("{}", self.unsafety.prefix_str()));
|
|
||||||
|
|
||||||
if self.abi != Abi::Rust {
|
|
||||||
p!(write("extern {} ", self.abi));
|
|
||||||
}
|
|
||||||
|
|
||||||
p!("fn", pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
|
||||||
}
|
|
||||||
|
|
||||||
TraitRefPrintOnlyTraitPath<'tcx> {
|
TraitRefPrintOnlyTraitPath<'tcx> {
|
||||||
p!(print_def_path(self.0.def_id, self.0.args));
|
p!(print_def_path(self.0.def_id, self.0.args));
|
||||||
}
|
}
|
||||||
|
@ -83,49 +83,6 @@ impl fmt::Debug for ty::LateParamRegion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for ty::FnSig<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
WithInfcx::with_no_infcx(self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::FnSig<'tcx> {
|
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
|
||||||
) -> core::fmt::Result {
|
|
||||||
let sig = this.data;
|
|
||||||
let ty::FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = sig;
|
|
||||||
|
|
||||||
write!(f, "{}", unsafety.prefix_str())?;
|
|
||||||
match abi {
|
|
||||||
rustc_target::spec::abi::Abi::Rust => (),
|
|
||||||
abi => write!(f, "extern \"{abi:?}\" ")?,
|
|
||||||
};
|
|
||||||
|
|
||||||
write!(f, "fn(")?;
|
|
||||||
let inputs = sig.inputs();
|
|
||||||
match inputs.len() {
|
|
||||||
0 if *c_variadic => write!(f, "...)")?,
|
|
||||||
0 => write!(f, ")")?,
|
|
||||||
_ => {
|
|
||||||
for ty in &sig.inputs()[0..(sig.inputs().len() - 1)] {
|
|
||||||
write!(f, "{:?}, ", &this.wrap(ty))?;
|
|
||||||
}
|
|
||||||
write!(f, "{:?}", &this.wrap(sig.inputs().last().unwrap()))?;
|
|
||||||
if *c_variadic {
|
|
||||||
write!(f, "...")?;
|
|
||||||
}
|
|
||||||
write!(f, ")")?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match sig.output().kind() {
|
|
||||||
ty::Tuple(list) if list.is_empty() => Ok(()),
|
|
||||||
_ => write!(f, " -> {:?}", &this.wrap(sig.output())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
|
impl<'tcx> ty::DebugWithInfcx<TyCtxt<'tcx>> for Ty<'tcx> {
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
|
@ -39,6 +39,7 @@ use super::GenericParamDefKind;
|
|||||||
pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>;
|
pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>;
|
||||||
pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
|
pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
|
||||||
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||||
|
pub type FnSig<'tcx> = ir::FnSig<TyCtxt<'tcx>>;
|
||||||
|
|
||||||
pub trait Article {
|
pub trait Article {
|
||||||
fn article(&self) -> &'static str;
|
fn article(&self) -> &'static str;
|
||||||
@ -985,14 +986,6 @@ impl<'tcx, T> Binder<'tcx, T> {
|
|||||||
Binder { value: &self.value, bound_vars: self.bound_vars }
|
Binder { value: &self.value, bound_vars: self.bound_vars }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_bound_ref_unchecked<F, U>(&self, f: F) -> Binder<'tcx, U>
|
|
||||||
where
|
|
||||||
F: FnOnce(&T) -> U,
|
|
||||||
{
|
|
||||||
let value = f(&self.value);
|
|
||||||
Binder { value, bound_vars: self.bound_vars }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
|
pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U>
|
||||||
where
|
where
|
||||||
F: FnOnce(&T) -> U,
|
F: FnOnce(&T) -> U,
|
||||||
@ -1109,73 +1102,37 @@ pub struct GenSig<'tcx> {
|
|||||||
pub return_ty: Ty<'tcx>,
|
pub return_ty: Ty<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signature of a function type, which we have arbitrarily
|
|
||||||
/// decided to use to refer to the input/output types.
|
|
||||||
///
|
|
||||||
/// - `inputs`: is the list of arguments and their modes.
|
|
||||||
/// - `output`: is the return type.
|
|
||||||
/// - `c_variadic`: indicates whether this is a C-variadic function.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
|
||||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
|
||||||
pub struct FnSig<'tcx> {
|
|
||||||
pub inputs_and_output: &'tcx List<Ty<'tcx>>,
|
|
||||||
pub c_variadic: bool,
|
|
||||||
pub unsafety: hir::Unsafety,
|
|
||||||
pub abi: abi::Abi,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> FnSig<'tcx> {
|
|
||||||
pub fn inputs(&self) -> &'tcx [Ty<'tcx>] {
|
|
||||||
&self.inputs_and_output[..self.inputs_and_output.len() - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn output(&self) -> Ty<'tcx> {
|
|
||||||
self.inputs_and_output[self.inputs_and_output.len() - 1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
|
|
||||||
// method.
|
|
||||||
fn fake() -> FnSig<'tcx> {
|
|
||||||
FnSig {
|
|
||||||
inputs_and_output: List::empty(),
|
|
||||||
c_variadic: false,
|
|
||||||
unsafety: hir::Unsafety::Normal,
|
|
||||||
abi: abi::Abi::Rust,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> IntoDiagArg for FnSig<'tcx> {
|
|
||||||
fn into_diag_arg(self) -> DiagArgValue {
|
|
||||||
self.to_string().into_diag_arg()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
|
pub type PolyFnSig<'tcx> = Binder<'tcx, FnSig<'tcx>>;
|
||||||
|
|
||||||
impl<'tcx> PolyFnSig<'tcx> {
|
impl<'tcx> PolyFnSig<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> {
|
pub fn inputs(&self) -> Binder<'tcx, &'tcx [Ty<'tcx>]> {
|
||||||
self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs())
|
self.map_bound_ref(|fn_sig| fn_sig.inputs())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
|
pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||||
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
|
self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> {
|
pub fn inputs_and_output(&self) -> ty::Binder<'tcx, &'tcx List<Ty<'tcx>>> {
|
||||||
self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
|
self.map_bound_ref(|fn_sig| fn_sig.inputs_and_output)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
pub fn output(&self) -> ty::Binder<'tcx, Ty<'tcx>> {
|
||||||
self.map_bound_ref(|fn_sig| fn_sig.output())
|
self.map_bound_ref(|fn_sig| fn_sig.output())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn c_variadic(&self) -> bool {
|
pub fn c_variadic(&self) -> bool {
|
||||||
self.skip_binder().c_variadic
|
self.skip_binder().c_variadic
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unsafety(&self) -> hir::Unsafety {
|
pub fn unsafety(&self) -> hir::Unsafety {
|
||||||
self.skip_binder().unsafety
|
self.skip_binder().unsafety
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn abi(&self) -> abi::Abi {
|
pub fn abi(&self) -> abi::Abi {
|
||||||
self.skip_binder().abi
|
self.skip_binder().abi
|
||||||
}
|
}
|
||||||
@ -2031,7 +1988,12 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
FnPtr(f) => *f,
|
FnPtr(f) => *f,
|
||||||
Error(_) => {
|
Error(_) => {
|
||||||
// ignore errors (#54954)
|
// ignore errors (#54954)
|
||||||
ty::Binder::dummy(FnSig::fake())
|
ty::Binder::dummy(ty::FnSig {
|
||||||
|
inputs_and_output: ty::List::empty(),
|
||||||
|
c_variadic: false,
|
||||||
|
unsafety: hir::Unsafety::Normal,
|
||||||
|
abi: abi::Abi::Rust,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Closure(..) => bug!(
|
Closure(..) => bug!(
|
||||||
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
|
"to get the signature of a closure, use `args.as_closure().sig()` not `fn_sig()`",
|
||||||
@ -2624,6 +2586,13 @@ impl<'tcx> Ty<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx> rustc_type_ir::inherent::Tys<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> {
|
||||||
|
fn split_inputs_and_output(self) -> (&'tcx [Ty<'tcx>], Ty<'tcx>) {
|
||||||
|
let (output, inputs) = self.split_last().unwrap();
|
||||||
|
(inputs, *output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Extra information about why we ended up with a particular variance.
|
/// Extra information about why we ended up with a particular variance.
|
||||||
/// This is only used to add more information to error messages, and
|
/// This is only used to add more information to error messages, and
|
||||||
/// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo`
|
/// has no effect on soundness. While choosing the 'wrong' `VarianceDiagInfo`
|
||||||
|
@ -244,16 +244,23 @@ fn fulfillment_error_for_no_solution<'tcx>(
|
|||||||
|
|
||||||
fn fulfillment_error_for_stalled<'tcx>(
|
fn fulfillment_error_for_stalled<'tcx>(
|
||||||
infcx: &InferCtxt<'tcx>,
|
infcx: &InferCtxt<'tcx>,
|
||||||
obligation: PredicateObligation<'tcx>,
|
root_obligation: PredicateObligation<'tcx>,
|
||||||
) -> FulfillmentError<'tcx> {
|
) -> FulfillmentError<'tcx> {
|
||||||
let code = infcx.probe(|_| {
|
let (code, refine_obligation) = infcx.probe(|_| {
|
||||||
match infcx.evaluate_root_goal(obligation.clone().into(), GenerateProofTree::Never).0 {
|
match infcx.evaluate_root_goal(root_obligation.clone().into(), GenerateProofTree::Never).0 {
|
||||||
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
|
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
|
||||||
FulfillmentErrorCode::Ambiguity { overflow: None }
|
(FulfillmentErrorCode::Ambiguity { overflow: None }, true)
|
||||||
}
|
|
||||||
Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => {
|
|
||||||
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) }
|
|
||||||
}
|
}
|
||||||
|
Ok((_, Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }))) => (
|
||||||
|
FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) },
|
||||||
|
// Don't look into overflows because we treat overflows weirdly anyways.
|
||||||
|
// In `instantiate_response_discarding_overflow` we set `has_changed = false`,
|
||||||
|
// recomputing the goal again during `find_best_leaf_obligation` may apply
|
||||||
|
// inference guidance that makes other goals go from ambig -> pass, for example.
|
||||||
|
//
|
||||||
|
// FIXME: We should probably just look into overflows here.
|
||||||
|
false,
|
||||||
|
),
|
||||||
Ok((_, Certainty::Yes)) => {
|
Ok((_, Certainty::Yes)) => {
|
||||||
bug!("did not expect successful goal when collecting ambiguity errors")
|
bug!("did not expect successful goal when collecting ambiguity errors")
|
||||||
}
|
}
|
||||||
@ -264,9 +271,13 @@ fn fulfillment_error_for_stalled<'tcx>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
FulfillmentError {
|
FulfillmentError {
|
||||||
obligation: find_best_leaf_obligation(infcx, &obligation, true),
|
obligation: if refine_obligation {
|
||||||
|
find_best_leaf_obligation(infcx, &root_obligation, true)
|
||||||
|
} else {
|
||||||
|
root_obligation.clone()
|
||||||
|
},
|
||||||
code,
|
code,
|
||||||
root_obligation: obligation,
|
root_obligation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,41 +313,50 @@ impl<'tcx> BestObligation<'tcx> {
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Filter out the candidates that aren't either error or ambiguous (depending
|
/// Filter out the candidates that aren't interesting to visit for the
|
||||||
/// on what we are looking for), and also throw out candidates that have no
|
/// purposes of reporting errors. For ambiguities, we only consider
|
||||||
/// failing WC (or higher-ranked obligations, for which there should only be
|
/// candidates that may hold. For errors, we only consider candidates that
|
||||||
/// one candidate anyways -- but I digress). This most likely means that the
|
/// *don't* hold and which have impl-where clauses that also don't hold.
|
||||||
/// goal just didn't unify at all, e.g. a param candidate with an alias in it.
|
|
||||||
fn non_trivial_candidates<'a>(
|
fn non_trivial_candidates<'a>(
|
||||||
&self,
|
&self,
|
||||||
goal: &'a InspectGoal<'a, 'tcx>,
|
goal: &'a InspectGoal<'a, 'tcx>,
|
||||||
) -> Vec<InspectCandidate<'a, 'tcx>> {
|
) -> Vec<InspectCandidate<'a, 'tcx>> {
|
||||||
let mut candidates = goal
|
let mut candidates = goal.candidates();
|
||||||
.candidates()
|
match self.consider_ambiguities {
|
||||||
.into_iter()
|
true => {
|
||||||
.filter(|candidate| match self.consider_ambiguities {
|
// If we have an ambiguous obligation, we must consider *all* candidates
|
||||||
true => matches!(candidate.result(), Ok(Certainty::Maybe(_))),
|
// that hold, or else we may guide inference causing other goals to go
|
||||||
false => matches!(candidate.result(), Err(_)),
|
// from ambig -> pass/fail.
|
||||||
})
|
candidates.retain(|candidate| candidate.result().is_ok());
|
||||||
.collect::<Vec<_>>();
|
}
|
||||||
|
false => {
|
||||||
// If we have >1 candidate, one may still be due to "boring" reasons, like
|
// If we have >1 candidate, one may still be due to "boring" reasons, like
|
||||||
// an alias-relate that failed to hold when deeply evaluated. We really
|
// an alias-relate that failed to hold when deeply evaluated. We really
|
||||||
// don't care about reasons like this.
|
// don't care about reasons like this.
|
||||||
if candidates.len() > 1 {
|
if candidates.len() > 1 {
|
||||||
candidates.retain(|candidate| {
|
candidates.retain(|candidate| {
|
||||||
goal.infcx().probe(|_| {
|
goal.infcx().probe(|_| {
|
||||||
candidate.instantiate_nested_goals(self.span()).iter().any(|nested_goal| {
|
candidate.instantiate_nested_goals(self.span()).iter().any(
|
||||||
matches!(
|
|nested_goal| {
|
||||||
nested_goal.source(),
|
matches!(
|
||||||
GoalSource::ImplWhereBound | GoalSource::InstantiateHigherRanked
|
nested_goal.source(),
|
||||||
) && match self.consider_ambiguities {
|
GoalSource::ImplWhereBound
|
||||||
true => matches!(nested_goal.result(), Ok(Certainty::Maybe(_))),
|
| GoalSource::InstantiateHigherRanked
|
||||||
false => matches!(nested_goal.result(), Err(_)),
|
) && match self.consider_ambiguities {
|
||||||
}
|
true => {
|
||||||
})
|
matches!(
|
||||||
})
|
nested_goal.result(),
|
||||||
});
|
Ok(Certainty::Maybe(MaybeCause::Ambiguity))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
false => matches!(nested_goal.result(), Err(_)),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates
|
candidates
|
||||||
@ -401,7 +421,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||||||
|
|
||||||
// Skip nested goals that aren't the *reason* for our goal's failure.
|
// Skip nested goals that aren't the *reason* for our goal's failure.
|
||||||
match self.consider_ambiguities {
|
match self.consider_ambiguities {
|
||||||
true if matches!(nested_goal.result(), Ok(Certainty::Maybe(_))) => {}
|
true if matches!(
|
||||||
|
nested_goal.result(),
|
||||||
|
Ok(Certainty::Maybe(MaybeCause::Ambiguity))
|
||||||
|
) => {}
|
||||||
false if matches!(nested_goal.result(), Err(_)) => {}
|
false if matches!(nested_goal.result(), Err(_)) => {}
|
||||||
_ => continue,
|
_ => continue,
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,21 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||||||
fn new_alias(interner: I, kind: AliasTyKind, alias_ty: AliasTy<I>) -> Self;
|
fn new_alias(interner: I, kind: AliasTyKind, alias_ty: AliasTy<I>) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Tys<I: Interner<Tys = Self>>:
|
||||||
|
Copy + Debug + Hash + Eq + IntoIterator<Item = I::Ty> + Deref<Target: Deref<Target = [I::Ty]>>
|
||||||
|
{
|
||||||
|
fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Abi<I: Interner<Abi = Self>>: Copy + Debug + Hash + Eq {
|
||||||
|
/// Whether this ABI is `extern "Rust"`.
|
||||||
|
fn is_rust(self) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Unsafety<I: Interner<Unsafety = Self>>: Copy + Debug + Hash + Eq {
|
||||||
|
fn prefix_str(self) -> &'static str;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Region<I: Interner<Region = Self>>:
|
pub trait Region<I: Interner<Region = Self>>:
|
||||||
Copy + DebugWithInfcx<I> + Hash + Eq + Into<I::GenericArg> + IntoKind<Kind = RegionKind<I>> + Flags
|
Copy + DebugWithInfcx<I> + Hash + Eq + Into<I::GenericArg> + IntoKind<Kind = RegionKind<I>> + Flags
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::inherent::*;
|
use crate::inherent::*;
|
||||||
use crate::ir_print::IrPrint;
|
use crate::ir_print::IrPrint;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
||||||
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, NormalizesTo, ProjectionPredicate,
|
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, FnSig, NormalizesTo,
|
||||||
SubtypePredicate, TraitPredicate, TraitRef,
|
ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Interner:
|
pub trait Interner:
|
||||||
@ -24,13 +25,16 @@ pub trait Interner:
|
|||||||
+ IrPrint<NormalizesTo<Self>>
|
+ IrPrint<NormalizesTo<Self>>
|
||||||
+ IrPrint<SubtypePredicate<Self>>
|
+ IrPrint<SubtypePredicate<Self>>
|
||||||
+ IrPrint<CoercePredicate<Self>>
|
+ IrPrint<CoercePredicate<Self>>
|
||||||
|
+ IrPrint<FnSig<Self>>
|
||||||
{
|
{
|
||||||
type DefId: Copy + Debug + Hash + Eq;
|
type DefId: Copy + Debug + Hash + Eq;
|
||||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||||
type AdtDef: Copy + Debug + Hash + Eq;
|
type AdtDef: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
type GenericArgs: GenericArgs<Self>;
|
type GenericArgs: GenericArgs<Self>;
|
||||||
type GenericArgsSlice: Copy + Debug + Hash + Eq;
|
/// The slice of args for a specific item. For a GAT like `type Foo<'a>`, it will be `['a]`,
|
||||||
|
/// not including the args from the parent item (trait or impl).
|
||||||
|
type OwnItemArgs: Copy + Debug + Hash + Eq;
|
||||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||||
type Term: Copy + Debug + Hash + Eq;
|
type Term: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
@ -42,7 +46,8 @@ pub trait Interner:
|
|||||||
|
|
||||||
// Kinds of tys
|
// Kinds of tys
|
||||||
type Ty: Ty<Self>;
|
type Ty: Ty<Self>;
|
||||||
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
type Tys: Tys<Self>;
|
||||||
|
type FnInputTys: Copy + Debug + Hash + Eq + Deref<Target = [Self::Ty]>;
|
||||||
type ParamTy: Copy + Debug + Hash + Eq;
|
type ParamTy: Copy + Debug + Hash + Eq;
|
||||||
type BoundTy: Copy + Debug + Hash + Eq;
|
type BoundTy: Copy + Debug + Hash + Eq;
|
||||||
type PlaceholderTy: PlaceholderLike;
|
type PlaceholderTy: PlaceholderLike;
|
||||||
@ -53,6 +58,8 @@ pub trait Interner:
|
|||||||
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
type PolyFnSig: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||||
type AllocId: Copy + Debug + Hash + Eq;
|
type AllocId: Copy + Debug + Hash + Eq;
|
||||||
type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx<Self>;
|
type Pat: Copy + Debug + Hash + Eq + DebugWithInfcx<Self>;
|
||||||
|
type Unsafety: Unsafety<Self>;
|
||||||
|
type Abi: Abi<Self>;
|
||||||
|
|
||||||
// Kinds of consts
|
// Kinds of consts
|
||||||
type Const: Const<Self>;
|
type Const: Const<Self>;
|
||||||
@ -99,7 +106,7 @@ pub trait Interner:
|
|||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
args: Self::GenericArgs,
|
args: Self::GenericArgs,
|
||||||
) -> (TraitRef<Self>, Self::GenericArgsSlice);
|
) -> (TraitRef<Self>, Self::OwnItemArgs);
|
||||||
|
|
||||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AliasTerm, AliasTy, CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner,
|
AliasTerm, AliasTy, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
|
||||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
Interner, NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IrPrint<T> {
|
pub trait IrPrint<T> {
|
||||||
@ -45,6 +45,7 @@ define_display_via_print!(
|
|||||||
CoercePredicate,
|
CoercePredicate,
|
||||||
AliasTy,
|
AliasTy,
|
||||||
AliasTerm,
|
AliasTerm,
|
||||||
|
FnSig,
|
||||||
);
|
);
|
||||||
|
|
||||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
||||||
|
@ -497,7 +497,7 @@ impl<I: Interner> AliasTerm<I> {
|
|||||||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||||
/// then this function would return a `T: StreamingIterator` trait reference and
|
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||||
/// `['a]` as the own args.
|
/// `['a]` as the own args.
|
||||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::OwnItemArgs) {
|
||||||
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +342,7 @@ impl<I: Interner> PartialEq for TyKind<I> {
|
|||||||
impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
|
impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
) -> fmt::Result {
|
) -> fmt::Result {
|
||||||
match this.data {
|
match this.data {
|
||||||
Bool => write!(f, "bool"),
|
Bool => write!(f, "bool"),
|
||||||
@ -514,7 +514,7 @@ impl<I: Interner> AliasTy<I> {
|
|||||||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||||
/// then this function would return a `T: StreamingIterator` trait reference and
|
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||||
/// `['a]` as the own args.
|
/// `['a]` as the own args.
|
||||||
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::OwnItemArgs) {
|
||||||
debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
|
debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
|
||||||
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||||
}
|
}
|
||||||
@ -561,8 +561,8 @@ impl<I: Interner> fmt::Debug for AliasTy<I> {
|
|||||||
impl<I: Interner> DebugWithInfcx<I> for AliasTy<I> {
|
impl<I: Interner> DebugWithInfcx<I> for AliasTy<I> {
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
f: &mut fmt::Formatter<'_>,
|
||||||
) -> core::fmt::Result {
|
) -> fmt::Result {
|
||||||
f.debug_struct("AliasTy")
|
f.debug_struct("AliasTy")
|
||||||
.field("args", &this.map(|data| data.args))
|
.field("args", &this.map(|data| data.args))
|
||||||
.field("def_id", &this.data.def_id)
|
.field("def_id", &this.data.def_id)
|
||||||
@ -952,3 +952,76 @@ pub struct TypeAndMut<I: Interner> {
|
|||||||
pub ty: I::Ty,
|
pub ty: I::Ty,
|
||||||
pub mutbl: Mutability,
|
pub mutbl: Mutability,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
Clone(bound = ""),
|
||||||
|
Copy(bound = ""),
|
||||||
|
PartialEq(bound = ""),
|
||||||
|
Eq(bound = ""),
|
||||||
|
Hash(bound = "")
|
||||||
|
)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
|
pub struct FnSig<I: Interner> {
|
||||||
|
pub inputs_and_output: I::Tys,
|
||||||
|
pub c_variadic: bool,
|
||||||
|
pub unsafety: I::Unsafety,
|
||||||
|
pub abi: I::Abi,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> FnSig<I> {
|
||||||
|
pub fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty) {
|
||||||
|
self.inputs_and_output.split_inputs_and_output()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn inputs(self) -> I::FnInputTys {
|
||||||
|
self.split_inputs_and_output().0
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn output(self) -> I::Ty {
|
||||||
|
self.split_inputs_and_output().1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> fmt::Debug for FnSig<I> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
WithInfcx::with_no_infcx(self).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I: Interner> DebugWithInfcx<I> for FnSig<I> {
|
||||||
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
|
f: &mut fmt::Formatter<'_>,
|
||||||
|
) -> fmt::Result {
|
||||||
|
let sig = this.data;
|
||||||
|
let FnSig { inputs_and_output: _, c_variadic, unsafety, abi } = sig;
|
||||||
|
|
||||||
|
write!(f, "{}", unsafety.prefix_str())?;
|
||||||
|
if !abi.is_rust() {
|
||||||
|
write!(f, "extern \"{abi:?}\" ")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "fn(")?;
|
||||||
|
let (inputs, output) = sig.split_inputs_and_output();
|
||||||
|
for (i, ty) in inputs.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
write!(f, ", ")?;
|
||||||
|
}
|
||||||
|
write!(f, "{:?}", &this.wrap(ty))?;
|
||||||
|
}
|
||||||
|
if *c_variadic {
|
||||||
|
if inputs.is_empty() {
|
||||||
|
write!(f, "...")?;
|
||||||
|
} else {
|
||||||
|
write!(f, ", ...")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
write!(f, ")")?;
|
||||||
|
|
||||||
|
match output.kind() {
|
||||||
|
Tuple(list) if list.is_empty() => Ok(()),
|
||||||
|
_ => write!(f, " -> {:?}", &this.wrap(sig.output())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -200,6 +200,7 @@ The following table shows known good combinations of toolchain versions.
|
|||||||
| 1.60 - 1.64 | 14 |
|
| 1.60 - 1.64 | 14 |
|
||||||
| 1.65 - 1.69 | 15 |
|
| 1.65 - 1.69 | 15 |
|
||||||
| 1.70 - 1.72 | 16 |
|
| 1.70 - 1.72 | 16 |
|
||||||
| 1.73 - 1.74 | 17 |
|
| 1.73 - 1.77 | 17 |
|
||||||
|
| 1.78 | 18 |
|
||||||
|
|
||||||
Note that the compatibility policy for this feature might change in the future.
|
Note that the compatibility policy for this feature might change in the future.
|
||||||
|
@ -188,7 +188,19 @@ pub enum TypeBindingKind {
|
|||||||
Constraint(Vec<GenericBound>),
|
Constraint(Vec<GenericBound>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An opaque identifier for an item.
|
||||||
|
///
|
||||||
|
/// It can be used to lookup in [Crate::index] or [Crate::paths] to resolve it
|
||||||
|
/// to an [Item].
|
||||||
|
///
|
||||||
|
/// Id's are only valid within a single JSON blob. They cannot be used to
|
||||||
|
/// resolve references between the JSON output's for different crates.
|
||||||
|
///
|
||||||
|
/// Rustdoc makes no guarantees about the inner value of Id's. Applications
|
||||||
|
/// should treat them as opaque keys to lookup items, and avoid attempting
|
||||||
|
/// to parse them, or otherwise depend on any implementation details.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
// FIXME(aDotInTheVoid): Consider making this non-public in rustdoc-types.
|
||||||
pub struct Id(pub String);
|
pub struct Id(pub String);
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
#![feature(f128)]
|
#![feature(f128)]
|
||||||
|
#![feature(f16)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
// CHECK-LABEL: i1 @f128_eq(
|
// CHECK-LABEL: i1 @f128_eq(
|
||||||
@ -127,3 +128,196 @@ pub fn f128_rem_assign(a: &mut f128, b: f128) {
|
|||||||
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
// CHECK-NEXT: store fp128 %{{.+}}, ptr %{{.+}}
|
||||||
*a %= b
|
*a %= b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* float to float conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @f128_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_f16(a: f128) -> f16 {
|
||||||
|
// CHECK: fptrunc fp128 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: float @f128_as_f32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_f32(a: f128) -> f32 {
|
||||||
|
// CHECK: fptrunc fp128 %{{.+}} to float
|
||||||
|
a as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: double @f128_as_f64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_f64(a: f128) -> f64 {
|
||||||
|
// CHECK: fptrunc fp128 %{{.+}} to double
|
||||||
|
a as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @f128_as_self(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_self(a: f128) -> f128 {
|
||||||
|
// CHECK: ret fp128 %{{.+}}
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @f16_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_f128(a: f16) -> f128 {
|
||||||
|
// CHECK: fpext half %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @f32_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f32_as_f128(a: f32) -> f128 {
|
||||||
|
// CHECK: fpext float %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @f64_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f64_as_f128(a: f64) -> f128 {
|
||||||
|
// CHECK: fpext double %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float to int conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: i8 @f128_as_u8(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_u8(a: f128) -> u8 {
|
||||||
|
// CHECK: call i8 @llvm.fptoui.sat.i8.f128(fp128 %{{.+}})
|
||||||
|
a as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_u16(a: f128) -> u16 {
|
||||||
|
// CHECK: call i16 @llvm.fptoui.sat.i16.f128(fp128 %{{.+}})
|
||||||
|
a as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i32 @f128_as_u32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_u32(a: f128) -> u32 {
|
||||||
|
// CHECK: call i32 @llvm.fptoui.sat.i32.f128(fp128 %{{.+}})
|
||||||
|
a as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i64 @f128_as_u64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_u64(a: f128) -> u64 {
|
||||||
|
// CHECK: call i64 @llvm.fptoui.sat.i64.f128(fp128 %{{.+}})
|
||||||
|
a as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i128 @f128_as_u128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_u128(a: f128) -> u128 {
|
||||||
|
// CHECK: call i128 @llvm.fptoui.sat.i128.f128(fp128 %{{.+}})
|
||||||
|
a as u128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i8 @f128_as_i8(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_i8(a: f128) -> i8 {
|
||||||
|
// CHECK: call i8 @llvm.fptosi.sat.i8.f128(fp128 %{{.+}})
|
||||||
|
a as i8
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i16 @f128_as_i16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_i16(a: f128) -> i16 {
|
||||||
|
// CHECK: call i16 @llvm.fptosi.sat.i16.f128(fp128 %{{.+}})
|
||||||
|
a as i16
|
||||||
|
}
|
||||||
|
// CHECK-LABEL: i32 @f128_as_i32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_i32(a: f128) -> i32 {
|
||||||
|
// CHECK: call i32 @llvm.fptosi.sat.i32.f128(fp128 %{{.+}})
|
||||||
|
a as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i64 @f128_as_i64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_i64(a: f128) -> i64 {
|
||||||
|
// CHECK: call i64 @llvm.fptosi.sat.i64.f128(fp128 %{{.+}})
|
||||||
|
a as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i128 @f128_as_i128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_i128(a: f128) -> i128 {
|
||||||
|
// CHECK: call i128 @llvm.fptosi.sat.i128.f128(fp128 %{{.+}})
|
||||||
|
a as i128
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int to float conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @u8_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u8_as_f128(a: u8) -> f128 {
|
||||||
|
// CHECK: uitofp i8 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @u16_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u16_as_f128(a: u16) -> f128 {
|
||||||
|
// CHECK: uitofp i16 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @u32_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u32_as_f128(a: u32) -> f128 {
|
||||||
|
// CHECK: uitofp i32 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @u64_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u64_as_f128(a: u64) -> f128 {
|
||||||
|
// CHECK: uitofp i64 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @u128_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u128_as_f128(a: u128) -> f128 {
|
||||||
|
// CHECK: uitofp i128 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @i8_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i8_as_f128(a: i8) -> f128 {
|
||||||
|
// CHECK: sitofp i8 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @i16_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i16_as_f128(a: i16) -> f128 {
|
||||||
|
// CHECK: sitofp i16 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @i32_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i32_as_f128(a: i32) -> f128 {
|
||||||
|
// CHECK: sitofp i32 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @i64_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i64_as_f128(a: i64) -> f128 {
|
||||||
|
// CHECK: sitofp i64 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @i128_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i128_as_f128(a: i128) -> f128 {
|
||||||
|
// CHECK: sitofp i128 %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
// Verify that our intrinsics generate the correct LLVM calls for f16
|
// Verify that our intrinsics generate the correct LLVM calls for f16
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
#![feature(f128)]
|
||||||
#![feature(f16)]
|
#![feature(f16)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
|
|
||||||
|
/* arithmetic */
|
||||||
|
|
||||||
// CHECK-LABEL: i1 @f16_eq(
|
// CHECK-LABEL: i1 @f16_eq(
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn f16_eq(a: f16, b: f16) -> bool {
|
pub fn f16_eq(a: f16, b: f16) -> bool {
|
||||||
@ -109,7 +112,7 @@ pub fn f16_sub_assign(a: &mut f16, b: f16) {
|
|||||||
pub fn f16_mul_assign(a: &mut f16, b: f16) {
|
pub fn f16_mul_assign(a: &mut f16, b: f16) {
|
||||||
// CHECK: fmul half %{{.+}}, %{{.+}}
|
// CHECK: fmul half %{{.+}}, %{{.+}}
|
||||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||||
*a *= b
|
*a *= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: void @f16_div_assign(
|
// CHECK-LABEL: void @f16_div_assign(
|
||||||
@ -117,7 +120,7 @@ pub fn f16_mul_assign(a: &mut f16, b: f16) {
|
|||||||
pub fn f16_div_assign(a: &mut f16, b: f16) {
|
pub fn f16_div_assign(a: &mut f16, b: f16) {
|
||||||
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
// CHECK: fdiv half %{{.+}}, %{{.+}}
|
||||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||||
*a /= b
|
*a /= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: void @f16_rem_assign(
|
// CHECK-LABEL: void @f16_rem_assign(
|
||||||
@ -125,5 +128,198 @@ pub fn f16_div_assign(a: &mut f16, b: f16) {
|
|||||||
pub fn f16_rem_assign(a: &mut f16, b: f16) {
|
pub fn f16_rem_assign(a: &mut f16, b: f16) {
|
||||||
// CHECK: frem half %{{.+}}, %{{.+}}
|
// CHECK: frem half %{{.+}}, %{{.+}}
|
||||||
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
// CHECK-NEXT: store half %{{.+}}, ptr %{{.+}}
|
||||||
*a %= b
|
*a %= b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float to float conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @f16_as_self(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_self(a: f16) -> f16 {
|
||||||
|
// CHECK: ret half %{{.+}}
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: float @f16_as_f32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_f32(a: f16) -> f32 {
|
||||||
|
// CHECK: fpext half %{{.+}} to float
|
||||||
|
a as f32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: double @f16_as_f64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_f64(a: f16) -> f64 {
|
||||||
|
// CHECK: fpext half %{{.+}} to double
|
||||||
|
a as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: fp128 @f16_as_f128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_f128(a: f16) -> f128 {
|
||||||
|
// CHECK: fpext half %{{.+}} to fp128
|
||||||
|
a as f128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @f32_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f32_as_f16(a: f32) -> f16 {
|
||||||
|
// CHECK: fptrunc float %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @f64_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f64_as_f16(a: f64) -> f16 {
|
||||||
|
// CHECK: fptrunc double %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @f128_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f128_as_f16(a: f128) -> f16 {
|
||||||
|
// CHECK: fptrunc fp128 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
/* float to int conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: i8 @f16_as_u8(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_u8(a: f16) -> u8 {
|
||||||
|
// CHECK: call i8 @llvm.fptoui.sat.i8.f16(half %{{.+}})
|
||||||
|
a as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_u16(a: f16) -> u16 {
|
||||||
|
// CHECK: call i16 @llvm.fptoui.sat.i16.f16(half %{{.+}})
|
||||||
|
a as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i32 @f16_as_u32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_u32(a: f16) -> u32 {
|
||||||
|
// CHECK: call i32 @llvm.fptoui.sat.i32.f16(half %{{.+}})
|
||||||
|
a as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i64 @f16_as_u64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_u64(a: f16) -> u64 {
|
||||||
|
// CHECK: call i64 @llvm.fptoui.sat.i64.f16(half %{{.+}})
|
||||||
|
a as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i128 @f16_as_u128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_u128(a: f16) -> u128 {
|
||||||
|
// CHECK: call i128 @llvm.fptoui.sat.i128.f16(half %{{.+}})
|
||||||
|
a as u128
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i8 @f16_as_i8(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_i8(a: f16) -> i8 {
|
||||||
|
// CHECK: call i8 @llvm.fptosi.sat.i8.f16(half %{{.+}})
|
||||||
|
a as i8
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i16 @f16_as_i16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_i16(a: f16) -> i16 {
|
||||||
|
// CHECK: call i16 @llvm.fptosi.sat.i16.f16(half %{{.+}})
|
||||||
|
a as i16
|
||||||
|
}
|
||||||
|
// CHECK-LABEL: i32 @f16_as_i32(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_i32(a: f16) -> i32 {
|
||||||
|
// CHECK: call i32 @llvm.fptosi.sat.i32.f16(half %{{.+}})
|
||||||
|
a as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i64 @f16_as_i64(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_i64(a: f16) -> i64 {
|
||||||
|
// CHECK: call i64 @llvm.fptosi.sat.i64.f16(half %{{.+}})
|
||||||
|
a as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: i128 @f16_as_i128(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn f16_as_i128(a: f16) -> i128 {
|
||||||
|
// CHECK: call i128 @llvm.fptosi.sat.i128.f16(half %{{.+}})
|
||||||
|
a as i128
|
||||||
|
}
|
||||||
|
|
||||||
|
/* int to float conversions */
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @u8_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u8_as_f16(a: u8) -> f16 {
|
||||||
|
// CHECK: uitofp i8 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @u16_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u16_as_f16(a: u16) -> f16 {
|
||||||
|
// CHECK: uitofp i16 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @u32_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u32_as_f16(a: u32) -> f16 {
|
||||||
|
// CHECK: uitofp i32 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @u64_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u64_as_f16(a: u64) -> f16 {
|
||||||
|
// CHECK: uitofp i64 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @u128_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn u128_as_f16(a: u128) -> f16 {
|
||||||
|
// CHECK: uitofp i128 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @i8_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i8_as_f16(a: i8) -> f16 {
|
||||||
|
// CHECK: sitofp i8 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @i16_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i16_as_f16(a: i16) -> f16 {
|
||||||
|
// CHECK: sitofp i16 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @i32_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i32_as_f16(a: i32) -> f16 {
|
||||||
|
// CHECK: sitofp i32 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @i64_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i64_as_f16(a: i64) -> f16 {
|
||||||
|
// CHECK: sitofp i64 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: half @i128_as_f16(
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn i128_as_f16(a: i128) -> f16 {
|
||||||
|
// CHECK: sitofp i128 %{{.+}} to half
|
||||||
|
a as f16
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
|
error[E0119]: conflicting implementations of trait `Trait` for type `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
|
||||||
--> $DIR/coherence-fulfill-overflow.rs:12:1
|
--> $DIR/coherence-fulfill-overflow.rs:12:1
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
|
LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
|
||||||
| ------------------------------------- first implementation here
|
| ------------------------------------- first implementation here
|
||||||
LL | impl<T: ?Sized + TwoW> Trait for T {}
|
LL | impl<T: ?Sized + TwoW> Trait for T {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>`
|
||||||
|
|
|
|
||||||
= note: overflow evaluating the requirement `W<W<W<W<_>>>>: TwoW`
|
= note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>: TwoW`
|
||||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `_: Sized`
|
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
||||||
--> $DIR/fixpoint-exponential-growth.rs:33:13
|
--> $DIR/fixpoint-exponential-growth.rs:33:13
|
||||||
|
|
|
|
||||||
LL | impls::<W<_>>();
|
LL | impls::<W<_>>();
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: required for `W<(W<_>, W<_>)>` to implement `Trait`
|
|
||||||
--> $DIR/fixpoint-exponential-growth.rs:23:12
|
|
||||||
|
|
|
||||||
LL | impl<T, U> Trait for W<(W<T>, W<U>)>
|
|
||||||
| - ^^^^^ ^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required by a bound in `impls`
|
note: required by a bound in `impls`
|
||||||
--> $DIR/fixpoint-exponential-growth.rs:30:13
|
--> $DIR/fixpoint-exponential-growth.rs:30:13
|
||||||
|
|
|
|
||||||
|
@ -1,53 +1,21 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `(): Inductive`
|
error[E0275]: overflow evaluating the requirement `(): Trait`
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:32:19
|
--> $DIR/double-cycle-inductive-coinductive.rs:32:19
|
||||||
|
|
|
|
||||||
LL | impls_trait::<()>();
|
LL | impls_trait::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `Trait`
|
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:9:34
|
|
||||||
|
|
|
||||||
LL | impl<T: Inductive + Coinductive> Trait for T {}
|
|
||||||
| --------- ^^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `Inductive`
|
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:12:16
|
|
||||||
|
|
|
||||||
LL | impl<T: Trait> Inductive for T {}
|
|
||||||
| ----- ^^^^^^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 7 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `Trait`
|
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
|
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
|
||||||
|
|
|
|
||||||
LL | fn impls_trait<T: Trait>() {}
|
LL | fn impls_trait<T: Trait>() {}
|
||||||
| ^^^^^ required by this bound in `impls_trait`
|
| ^^^^^ required by this bound in `impls_trait`
|
||||||
|
|
||||||
error[E0275]: overflow evaluating the requirement `(): CoinductiveRev`
|
error[E0275]: overflow evaluating the requirement `(): TraitRev`
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:35:23
|
--> $DIR/double-cycle-inductive-coinductive.rs:35:23
|
||||||
|
|
|
|
||||||
LL | impls_trait_rev::<()>();
|
LL | impls_trait_rev::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `TraitRev`
|
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:21:40
|
|
||||||
|
|
|
||||||
LL | impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
|
|
||||||
| -------------- ^^^^^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `CoinductiveRev`
|
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:27:19
|
|
||||||
|
|
|
||||||
LL | impl<T: TraitRev> CoinductiveRev for T {}
|
|
||||||
| -------- ^^^^^^^^^^^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 7 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `TraitRev`
|
|
||||||
note: required by a bound in `impls_trait_rev`
|
note: required by a bound in `impls_trait_rev`
|
||||||
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
|
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
|
||||||
|
|
|
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `W<W<_>>: Trait`
|
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
||||||
--> $DIR/inductive-fixpoint-hang.rs:31:19
|
--> $DIR/inductive-fixpoint-hang.rs:31:19
|
||||||
|
|
|
|
||||||
LL | impls_trait::<W<_>>();
|
LL | impls_trait::<W<_>>();
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: required for `W<W<W<_>>>` to implement `Trait`
|
|
||||||
--> $DIR/inductive-fixpoint-hang.rs:22:17
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized> Trait for W<W<T>>
|
|
||||||
| ^^^^^ ^^^^^^^
|
|
||||||
LL | where
|
|
||||||
LL | W<T>: Trait,
|
|
||||||
| ----- unsatisfied trait bound introduced here
|
|
||||||
= note: 8 redundant requirements hidden
|
|
||||||
= note: required for `W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>` to implement `Trait`
|
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/inductive-fixpoint-hang.rs:28:19
|
--> $DIR/inductive-fixpoint-hang.rs:28:19
|
||||||
|
|
|
|
||||||
|
@ -39,7 +39,7 @@ fn impls_ar<T: AR>() {}
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
impls_a::<()>();
|
impls_a::<()>();
|
||||||
//~^ ERROR overflow evaluating the requirement `(): B`
|
//~^ ERROR overflow evaluating the requirement `(): A`
|
||||||
|
|
||||||
impls_ar::<()>();
|
impls_ar::<()>();
|
||||||
//~^ ERROR overflow evaluating the requirement `(): AR`
|
//~^ ERROR overflow evaluating the requirement `(): AR`
|
||||||
|
@ -1,25 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `(): B`
|
error[E0275]: overflow evaluating the requirement `(): A`
|
||||||
--> $DIR/inductive-not-on-stack.rs:41:15
|
--> $DIR/inductive-not-on-stack.rs:41:15
|
||||||
|
|
|
|
||||||
LL | impls_a::<()>();
|
LL | impls_a::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `A`
|
|
||||||
--> $DIR/inductive-not-on-stack.rs:21:16
|
|
||||||
|
|
|
||||||
LL | impl<T: B + C> A for T {}
|
|
||||||
| - ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `B`
|
|
||||||
--> $DIR/inductive-not-on-stack.rs:22:12
|
|
||||||
|
|
|
||||||
LL | impl<T: A> B for T {}
|
|
||||||
| - ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 7 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `A`
|
|
||||||
note: required by a bound in `impls_a`
|
note: required by a bound in `impls_a`
|
||||||
--> $DIR/inductive-not-on-stack.rs:25:15
|
--> $DIR/inductive-not-on-stack.rs:25:15
|
||||||
|
|
|
|
||||||
@ -32,29 +16,6 @@ error[E0275]: overflow evaluating the requirement `(): AR`
|
|||||||
LL | impls_ar::<()>();
|
LL | impls_ar::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `BR`
|
|
||||||
--> $DIR/inductive-not-on-stack.rs:35:13
|
|
||||||
|
|
|
||||||
LL | impl<T: AR> BR for T {}
|
|
||||||
| -- ^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `CR`
|
|
||||||
--> $DIR/inductive-not-on-stack.rs:36:13
|
|
||||||
|
|
|
||||||
LL | impl<T: BR> CR for T {}
|
|
||||||
| -- ^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `AR`
|
|
||||||
--> $DIR/inductive-not-on-stack.rs:34:18
|
|
||||||
|
|
|
||||||
LL | impl<T: CR + BR> AR for T {}
|
|
||||||
| -- ^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 6 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `AR`
|
|
||||||
note: required by a bound in `impls_ar`
|
note: required by a bound in `impls_ar`
|
||||||
--> $DIR/inductive-not-on-stack.rs:38:16
|
--> $DIR/inductive-not-on-stack.rs:38:16
|
||||||
|
|
|
|
||||||
|
@ -35,5 +35,5 @@ fn impls_a<T: A>() {}
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
impls_a::<()>();
|
impls_a::<()>();
|
||||||
//~^ ERROR overflow evaluating the requirement `(): CInd`
|
//~^ ERROR overflow evaluating the requirement `(): A`
|
||||||
}
|
}
|
||||||
|
@ -1,46 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `(): CInd`
|
error[E0275]: overflow evaluating the requirement `(): A`
|
||||||
--> $DIR/mixed-cycles-1.rs:37:15
|
--> $DIR/mixed-cycles-1.rs:37:15
|
||||||
|
|
|
|
||||||
LL | impls_a::<()>();
|
LL | impls_a::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `B`
|
|
||||||
--> $DIR/mixed-cycles-1.rs:31:28
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + CInd + C> B for T {}
|
|
||||||
| ---- ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `C`
|
|
||||||
--> $DIR/mixed-cycles-1.rs:32:25
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + B + A> C for T {}
|
|
||||||
| - ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `CInd`
|
|
||||||
--> $DIR/mixed-cycles-1.rs:28:21
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + C> CInd for T {}
|
|
||||||
| - ^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 4 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `B`
|
|
||||||
note: required for `()` to implement `BInd`
|
|
||||||
--> $DIR/mixed-cycles-1.rs:23:21
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + B> BInd for T {}
|
|
||||||
| - ^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `A`
|
|
||||||
--> $DIR/mixed-cycles-1.rs:30:28
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + BInd + C> A for T {}
|
|
||||||
| ---- ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required by a bound in `impls_a`
|
note: required by a bound in `impls_a`
|
||||||
--> $DIR/mixed-cycles-1.rs:34:15
|
--> $DIR/mixed-cycles-1.rs:34:15
|
||||||
|
|
|
|
||||||
|
@ -28,5 +28,5 @@ fn impls_a<T: A>() {}
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
impls_a::<()>();
|
impls_a::<()>();
|
||||||
//~^ ERROR overflow evaluating the requirement `(): BInd`
|
//~^ ERROR overflow evaluating the requirement `(): A`
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `(): BInd`
|
error[E0275]: overflow evaluating the requirement `(): A`
|
||||||
--> $DIR/mixed-cycles-2.rs:30:15
|
--> $DIR/mixed-cycles-2.rs:30:15
|
||||||
|
|
|
|
||||||
LL | impls_a::<()>();
|
LL | impls_a::<()>();
|
||||||
| ^^
|
| ^^
|
||||||
|
|
|
|
||||||
note: required for `()` to implement `B`
|
|
||||||
--> $DIR/mixed-cycles-2.rs:25:24
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + BInd> B for T {}
|
|
||||||
| ---- ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required for `()` to implement `BInd`
|
|
||||||
--> $DIR/mixed-cycles-2.rs:22:21
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + B> BInd for T {}
|
|
||||||
| - ^^^^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 6 redundant requirements hidden
|
|
||||||
= note: required for `()` to implement `BInd`
|
|
||||||
note: required for `()` to implement `A`
|
|
||||||
--> $DIR/mixed-cycles-2.rs:24:28
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + BInd + B> A for T {}
|
|
||||||
| ---- ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required by a bound in `impls_a`
|
note: required by a bound in `impls_a`
|
||||||
--> $DIR/mixed-cycles-2.rs:27:15
|
--> $DIR/mixed-cycles-2.rs:27:15
|
||||||
|
|
|
|
||||||
|
21
tests/ui/traits/next-solver/diagnostics/ambiguous-fail.rs
Normal file
21
tests/ui/traits/next-solver/diagnostics/ambiguous-fail.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct W<T>(*mut T);
|
||||||
|
impl<T> Trait for W<W<T>>
|
||||||
|
where
|
||||||
|
W<T>: Trait,
|
||||||
|
{
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait NoOverlap {}
|
||||||
|
impl<T: Trait> NoOverlap for T {}
|
||||||
|
|
||||||
|
impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
|
||||||
|
//~^ ERROR conflicting implementations of trait `NoOverlap` for type `W<_>`
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0119]: conflicting implementations of trait `NoOverlap` for type `W<_>`
|
||||||
|
--> $DIR/ambiguous-fail.rs:18:1
|
||||||
|
|
|
||||||
|
LL | impl<T: Trait> NoOverlap for T {}
|
||||||
|
| ------------------------------ first implementation here
|
||||||
|
LL |
|
||||||
|
LL | impl<T: Trait<Assoc = u32>> NoOverlap for W<T> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
21
tests/ui/traits/next-solver/diagnostics/ambiguous-pass.rs
Normal file
21
tests/ui/traits/next-solver/diagnostics/ambiguous-pass.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct W<T>(*mut T);
|
||||||
|
impl<T> Trait for W<W<T>>
|
||||||
|
where
|
||||||
|
W<T>: Trait,
|
||||||
|
{
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait NoOverlap {}
|
||||||
|
impl<T: Trait> NoOverlap for T {}
|
||||||
|
|
||||||
|
impl<T: Trait<Assoc = ()>> NoOverlap for W<T> {}
|
||||||
|
//~^ ERROR conflicting implementations of trait `NoOverlap` for type `W<_>`
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,12 @@
|
|||||||
|
error[E0119]: conflicting implementations of trait `NoOverlap` for type `W<_>`
|
||||||
|
--> $DIR/ambiguous-pass.rs:18:1
|
||||||
|
|
|
||||||
|
LL | impl<T: Trait> NoOverlap for T {}
|
||||||
|
| ------------------------------ first implementation here
|
||||||
|
LL |
|
||||||
|
LL | impl<T: Trait<Assoc = ()>> NoOverlap for W<T> {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<_>`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0119`.
|
@ -15,5 +15,5 @@ fn impls<T: Trait>() {}
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
impls::<W<_>>();
|
impls::<W<_>>();
|
||||||
//~^ ERROR overflow evaluating the requirement `_: Sized`
|
//~^ ERROR overflow evaluating the requirement `W<_>: Trait`
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,9 @@
|
|||||||
error[E0275]: overflow evaluating the requirement `_: Sized`
|
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
||||||
--> $DIR/exponential-trait-goals.rs:17:13
|
--> $DIR/exponential-trait-goals.rs:17:13
|
||||||
|
|
|
|
||||||
LL | impls::<W<_>>();
|
LL | impls::<W<_>>();
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
|
|
||||||
note: required for `W<(W<_>, W<_>)>` to implement `Trait`
|
|
||||||
--> $DIR/exponential-trait-goals.rs:7:12
|
|
||||||
|
|
|
||||||
LL | impl<T, U> Trait for W<(W<T>, W<U>)>
|
|
||||||
| - ^^^^^ ^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
note: required by a bound in `impls`
|
note: required by a bound in `impls`
|
||||||
--> $DIR/exponential-trait-goals.rs:14:13
|
--> $DIR/exponential-trait-goals.rs:14:13
|
||||||
|
|
|
|
||||||
|
@ -5,15 +5,6 @@ LL | impls_trait::<Four<Four<Four<Four<()>>>>>();
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
|
||||||
note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>` to implement `Trait`
|
|
||||||
--> $DIR/global-cache.rs:12:16
|
|
||||||
|
|
|
||||||
LL | impl<T: Trait> Trait for Inc<T> {}
|
|
||||||
| ----- ^^^^^ ^^^^^^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
= note: 5 redundant requirements hidden
|
|
||||||
= note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>>>>>>` to implement `Trait`
|
|
||||||
note: required by a bound in `impls_trait`
|
note: required by a bound in `impls_trait`
|
||||||
--> $DIR/global-cache.rs:15:19
|
--> $DIR/global-cache.rs:15:19
|
||||||
|
|
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user