Auto merge of #118970 - aliemjay:rollup-or33al2, r=aliemjay
Rollup of 2 pull requests Successful merges: - #118927 (Erase late bound regions from `Instance::fn_sig()` and add a few more details to StableMIR APIs) - #118964 (Opportunistically resolve region var in canonicalizer (instead of resolving root var)) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
d253bf61ad
@ -381,17 +381,13 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
|
||||
self.probe_ty_var(vid).ok()
|
||||
}
|
||||
|
||||
fn root_lt_var(&self, vid: ty::RegionVid) -> ty::RegionVid {
|
||||
self.root_region_var(vid)
|
||||
}
|
||||
|
||||
fn probe_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
|
||||
fn opportunistic_resolve_lt_var(&self, vid: ty::RegionVid) -> Option<ty::Region<'tcx>> {
|
||||
let re = self
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.unwrap_region_constraints()
|
||||
.opportunistic_resolve_var(self.tcx, vid);
|
||||
if re.is_var() { None } else { Some(re) }
|
||||
if *re == ty::ReVar(vid) { None } else { Some(re) }
|
||||
}
|
||||
|
||||
fn root_ct_var(&self, vid: ConstVid) -> ConstVid {
|
||||
@ -1367,10 +1363,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
self.inner.borrow_mut().type_variables().root_var(var)
|
||||
}
|
||||
|
||||
pub fn root_region_var(&self, var: ty::RegionVid) -> ty::RegionVid {
|
||||
self.inner.borrow_mut().unwrap_region_constraints().root_var(var)
|
||||
}
|
||||
|
||||
pub fn root_const_var(&self, var: ty::ConstVid) -> ty::ConstVid {
|
||||
self.inner.borrow_mut().const_unification_table().find(var).vid
|
||||
}
|
||||
|
@ -623,11 +623,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn root_var(&mut self, vid: ty::RegionVid) -> ty::RegionVid {
|
||||
let mut ut = self.unification_table_mut(); // FIXME(rust-lang/ena#42): unnecessary mut
|
||||
ut.find(vid).vid
|
||||
}
|
||||
|
||||
fn combine_map(&mut self, t: CombineMapType) -> &mut CombineMap<'tcx> {
|
||||
match t {
|
||||
Glb => &mut self.glbs,
|
||||
|
@ -242,16 +242,10 @@ impl<Infcx: InferCtxtLike<Interner = I>, I: Interner> TypeFolder<I>
|
||||
|
||||
ty::ReVar(vid) => {
|
||||
assert_eq!(
|
||||
self.infcx.root_lt_var(vid),
|
||||
vid,
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
assert_eq!(
|
||||
self.infcx.probe_lt_var(vid),
|
||||
self.infcx.opportunistic_resolve_lt_var(vid),
|
||||
None,
|
||||
"region vid should have been resolved fully before canonicalization"
|
||||
);
|
||||
|
||||
match self.canonicalize_mode {
|
||||
CanonicalizeMode::Input => CanonicalVarKind::Region(ty::UniverseIndex::ROOT),
|
||||
CanonicalizeMode::Response { .. } => {
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
|
||||
use rustc_middle::ty::{GenericPredicates, Instance, ParamEnv, ScalarInt, ValTree};
|
||||
use rustc_middle::ty::{
|
||||
GenericPredicates, Instance, ParamEnv, ScalarInt, TypeVisitableExt, ValTree,
|
||||
};
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use stable_mir::compiler_interface::Context;
|
||||
use stable_mir::mir::alloc::GlobalAlloc;
|
||||
@ -324,7 +326,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let instance = tables.instances[def];
|
||||
instance.ty(tables.tcx, ParamEnv::empty()).stable(&mut *tables)
|
||||
assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution");
|
||||
instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
||||
|
@ -36,6 +36,7 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
||||
.collect(),
|
||||
self.arg_count,
|
||||
self.var_debug_info.iter().map(|info| info.stable(tables)).collect(),
|
||||
self.spread_arg.stable(tables),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
|
||||
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
|
||||
}
|
||||
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
|
||||
CoroutineKind::AsyncGen(_) => todo!(),
|
||||
CoroutineKind::AsyncGen(source) => {
|
||||
stable_mir::mir::CoroutineKind::AsyncGen(source.stable(tables))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,11 +32,7 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
|
||||
None
|
||||
}
|
||||
|
||||
fn root_lt_var(&self, vid: I::InferRegion) -> I::InferRegion {
|
||||
vid
|
||||
}
|
||||
|
||||
fn probe_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
|
||||
fn opportunistic_resolve_lt_var(&self, _vid: I::InferRegion) -> Option<I::Region> {
|
||||
None
|
||||
}
|
||||
|
||||
|
@ -18,14 +18,14 @@ pub trait InferCtxtLike {
|
||||
lt: <Self::Interner as Interner>::InferRegion,
|
||||
) -> Option<UniverseIndex>;
|
||||
|
||||
/// Resolve `InferRegion` to its root `InferRegion`.
|
||||
fn root_lt_var(
|
||||
&self,
|
||||
vid: <Self::Interner as Interner>::InferRegion,
|
||||
) -> <Self::Interner as Interner>::InferRegion;
|
||||
|
||||
/// Resolve `InferRegion` to its inferred region, if it has been equated with a non-infer region.
|
||||
fn probe_lt_var(
|
||||
/// Resolve `InferRegion` to its inferred region, if it has been equated with
|
||||
/// a non-infer region.
|
||||
///
|
||||
/// FIXME: This has slightly different semantics than `{probe,resolve}_{ty,ct}_var`,
|
||||
/// that has to do with the fact unlike `Ty` or `Const` vars, in rustc, we may
|
||||
/// not always be able to *name* the root region var from the universe of the
|
||||
/// var we're trying to resolve. That's why it's called *opportunistic*.
|
||||
fn opportunistic_resolve_lt_var(
|
||||
&self,
|
||||
vid: <Self::Interner as Interner>::InferRegion,
|
||||
) -> Option<<Self::Interner as Interner>::Region>;
|
||||
|
@ -22,6 +22,11 @@ pub struct Body {
|
||||
|
||||
/// Debug information pertaining to user variables, including captures.
|
||||
pub var_debug_info: Vec<VarDebugInfo>,
|
||||
|
||||
/// Mark an argument (which must be a tuple) as getting passed as its individual components.
|
||||
///
|
||||
/// This is used for the "rust-call" ABI such as closures.
|
||||
pub(super) spread_arg: Option<Local>,
|
||||
}
|
||||
|
||||
pub type BasicBlockIdx = usize;
|
||||
@ -36,6 +41,7 @@ impl Body {
|
||||
locals: LocalDecls,
|
||||
arg_count: usize,
|
||||
var_debug_info: Vec<VarDebugInfo>,
|
||||
spread_arg: Option<Local>,
|
||||
) -> Self {
|
||||
// If locals doesn't contain enough entries, it can lead to panics in
|
||||
// `ret_local`, `arg_locals`, and `inner_locals`.
|
||||
@ -43,7 +49,7 @@ impl Body {
|
||||
locals.len() > arg_count,
|
||||
"A Body must contain at least a local for the return value and each of the function's arguments"
|
||||
);
|
||||
Self { blocks, locals, arg_count, var_debug_info }
|
||||
Self { blocks, locals, arg_count, var_debug_info, spread_arg }
|
||||
}
|
||||
|
||||
/// Return local that holds this function's return value.
|
||||
@ -75,6 +81,11 @@ impl Body {
|
||||
self.locals.get(local)
|
||||
}
|
||||
|
||||
/// Get an iterator for all local declarations.
|
||||
pub fn local_decls(&self) -> impl Iterator<Item = (Local, &LocalDecl)> {
|
||||
self.locals.iter().enumerate()
|
||||
}
|
||||
|
||||
pub fn dump<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
writeln!(w, "{}", function_body(self))?;
|
||||
self.blocks
|
||||
@ -98,6 +109,10 @@ impl Body {
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn spread_arg(&self) -> Option<Local> {
|
||||
self.spread_arg
|
||||
}
|
||||
}
|
||||
|
||||
type LocalDecls = Vec<LocalDecl>;
|
||||
@ -248,6 +263,57 @@ pub enum AssertMessage {
|
||||
MisalignedPointerDereference { required: Operand, found: Operand },
|
||||
}
|
||||
|
||||
impl AssertMessage {
|
||||
pub fn description(&self) -> Result<&'static str, Error> {
|
||||
match self {
|
||||
AssertMessage::Overflow(BinOp::Add, _, _) => Ok("attempt to add with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Sub, _, _) => Ok("attempt to subtract with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Mul, _, _) => Ok("attempt to multiply with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Div, _, _) => Ok("attempt to divide with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Rem, _, _) => {
|
||||
Ok("attempt to calculate the remainder with overflow")
|
||||
}
|
||||
AssertMessage::OverflowNeg(_) => Ok("attempt to negate with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Shr, _, _) => Ok("attempt to shift right with overflow"),
|
||||
AssertMessage::Overflow(BinOp::Shl, _, _) => Ok("attempt to shift left with overflow"),
|
||||
AssertMessage::Overflow(op, _, _) => Err(error!("`{:?}` cannot overflow", op)),
|
||||
AssertMessage::DivisionByZero(_) => Ok("attempt to divide by zero"),
|
||||
AssertMessage::RemainderByZero(_) => {
|
||||
Ok("attempt to calculate the remainder with a divisor of zero")
|
||||
}
|
||||
AssertMessage::ResumedAfterReturn(CoroutineKind::Coroutine) => {
|
||||
Ok("coroutine resumed after completion")
|
||||
}
|
||||
AssertMessage::ResumedAfterReturn(CoroutineKind::Async(_)) => {
|
||||
Ok("`async fn` resumed after completion")
|
||||
}
|
||||
AssertMessage::ResumedAfterReturn(CoroutineKind::Gen(_)) => {
|
||||
Ok("`async gen fn` resumed after completion")
|
||||
}
|
||||
AssertMessage::ResumedAfterReturn(CoroutineKind::AsyncGen(_)) => {
|
||||
Ok("`gen fn` should just keep returning `AssertMessage::None` after completion")
|
||||
}
|
||||
AssertMessage::ResumedAfterPanic(CoroutineKind::Coroutine) => {
|
||||
Ok("coroutine resumed after panicking")
|
||||
}
|
||||
AssertMessage::ResumedAfterPanic(CoroutineKind::Async(_)) => {
|
||||
Ok("`async fn` resumed after panicking")
|
||||
}
|
||||
AssertMessage::ResumedAfterPanic(CoroutineKind::Gen(_)) => {
|
||||
Ok("`async gen fn` resumed after panicking")
|
||||
}
|
||||
AssertMessage::ResumedAfterPanic(CoroutineKind::AsyncGen(_)) => {
|
||||
Ok("`gen fn` should just keep returning `AssertMessage::None` after panicking")
|
||||
}
|
||||
|
||||
AssertMessage::BoundsCheck { .. } => Ok("index out of bounds"),
|
||||
AssertMessage::MisalignedPointerDereference { .. } => {
|
||||
Ok("misaligned pointer dereference")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum BinOp {
|
||||
Add,
|
||||
@ -325,6 +391,7 @@ pub enum CoroutineKind {
|
||||
Async(CoroutineSource),
|
||||
Coroutine,
|
||||
Gen(CoroutineSource),
|
||||
AsyncGen(CoroutineSource),
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::crate_def::CrateDef;
|
||||
use crate::mir::Body;
|
||||
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, FnSig, GenericArgs, IndexedVal, Ty};
|
||||
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
|
||||
use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
@ -115,11 +115,6 @@ impl Instance {
|
||||
})
|
||||
}
|
||||
|
||||
/// Get this function signature with all types already instantiated.
|
||||
pub fn fn_sig(&self) -> FnSig {
|
||||
self.ty().kind().fn_sig().unwrap().skip_binder()
|
||||
}
|
||||
|
||||
/// Check whether this instance is an empty shim.
|
||||
///
|
||||
/// Allow users to check if this shim can be ignored when called directly.
|
||||
|
@ -260,6 +260,7 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
|
||||
);
|
||||
pretty
|
||||
}
|
||||
AssertMessage::Overflow(op, _, _) => unreachable!("`{:?}` cannot overflow", op),
|
||||
AssertMessage::OverflowNeg(op) => {
|
||||
let pretty_op = pretty_operand(op);
|
||||
pretty.push_str(
|
||||
@ -279,17 +280,15 @@ pub fn pretty_assert_message(msg: &AssertMessage) -> String {
|
||||
);
|
||||
pretty
|
||||
}
|
||||
AssertMessage::ResumedAfterReturn(_) => {
|
||||
format!("attempt to resume a generator after completion")
|
||||
}
|
||||
AssertMessage::ResumedAfterPanic(_) => format!("attempt to resume a panicked generator"),
|
||||
AssertMessage::MisalignedPointerDereference { required, found } => {
|
||||
let pretty_required = pretty_operand(required);
|
||||
let pretty_found = pretty_operand(found);
|
||||
pretty.push_str(format!("\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\",{pretty_required}, {pretty_found}").as_str());
|
||||
pretty
|
||||
}
|
||||
_ => todo!(),
|
||||
AssertMessage::ResumedAfterReturn(_) | AssertMessage::ResumedAfterPanic(_) => {
|
||||
msg.description().unwrap().to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ pub trait MirVisitor {
|
||||
}
|
||||
|
||||
fn super_body(&mut self, body: &Body) {
|
||||
let Body { blocks, locals: _, arg_count, var_debug_info } = body;
|
||||
let Body { blocks, locals: _, arg_count, var_debug_info, spread_arg: _ } = body;
|
||||
|
||||
for bb in blocks {
|
||||
self.visit_basic_block(bb);
|
||||
|
@ -22,9 +22,7 @@ impl Debug for Ty {
|
||||
/// Constructors for `Ty`.
|
||||
impl Ty {
|
||||
/// Create a new type from a given kind.
|
||||
///
|
||||
/// Note that not all types may be supported at this point.
|
||||
fn from_rigid_kind(kind: RigidTy) -> Ty {
|
||||
pub fn from_rigid_kind(kind: RigidTy) -> Ty {
|
||||
with(|cx| cx.new_rigid_ty(kind))
|
||||
}
|
||||
|
||||
@ -77,6 +75,16 @@ impl Ty {
|
||||
pub fn bool_ty() -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Bool)
|
||||
}
|
||||
|
||||
/// Create a type representing a signed integer.
|
||||
pub fn signed_ty(inner: IntTy) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Int(inner))
|
||||
}
|
||||
|
||||
/// Create a type representing an unsigned integer.
|
||||
pub fn unsigned_ty(inner: UintTy) -> Ty {
|
||||
Ty::from_rigid_kind(RigidTy::Uint(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ty {
|
||||
|
@ -69,7 +69,7 @@ fn extract_elem_ty(ty: Ty) -> Ty {
|
||||
|
||||
/// Check signature and type of `Vec::<u8>::new` and its generic version.
|
||||
fn test_vec_new(instance: mir::mono::Instance) {
|
||||
let sig = instance.fn_sig();
|
||||
let sig = instance.ty().kind().fn_sig().unwrap().skip_binder();
|
||||
assert_matches!(sig.inputs(), &[]);
|
||||
let elem_ty = extract_elem_ty(sig.output());
|
||||
assert_matches!(elem_ty.kind(), TyKind::RigidTy(RigidTy::Uint(UintTy::U8)));
|
||||
|
22
tests/ui/traits/next-solver/issue-118950-root-region.rs
Normal file
22
tests/ui/traits/next-solver/issue-118950-root-region.rs
Normal file
@ -0,0 +1,22 @@
|
||||
// compile-flags: -Znext-solver
|
||||
//
|
||||
// This is a gnarly test but I don't know how to minimize it, frankly.
|
||||
|
||||
#![feature(lazy_type_alias)]
|
||||
//~^ WARN the feature `lazy_type_alias` is incomplete
|
||||
|
||||
trait ToUnit<'a> {
|
||||
type Unit;
|
||||
}
|
||||
|
||||
trait Overlap<T> {}
|
||||
|
||||
type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
|
||||
|
||||
impl<T> Overlap<T> for T {}
|
||||
|
||||
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
//~^ ERROR conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
|
||||
//~| ERROR cannot find type `Missing` in this scope
|
||||
|
||||
fn main() {}
|
36
tests/ui/traits/next-solver/issue-118950-root-region.stderr
Normal file
36
tests/ui/traits/next-solver/issue-118950-root-region.stderr
Normal file
@ -0,0 +1,36 @@
|
||||
error[E0412]: cannot find type `Missing` in this scope
|
||||
--> $DIR/issue-118950-root-region.rs:18:55
|
||||
|
|
||||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
||||
warning: the feature `lazy_type_alias` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/issue-118950-root-region.rs:5:12
|
||||
|
|
||||
LL | #![feature(lazy_type_alias)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
|
||||
error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
|
||||
--> $DIR/issue-118950-root-region.rs:18:1
|
||||
|
|
||||
LL | impl<T> Overlap<T> for T {}
|
||||
| ------------------------ first implementation here
|
||||
LL |
|
||||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
|
||||
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0119, E0412.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
Loading…
x
Reference in New Issue
Block a user