Auto merge of #105350 - compiler-errors:faster-binder-relate, r=oli-obk
Fast-path some binder relations A simpler approach than #104598 Fixes #104583 r? types
This commit is contained in:
commit
109cccbe4f
9 changed files with 63 additions and 5 deletions
|
@ -178,6 +178,11 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
|
|||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
// A binder is equal to itself if it's structually equal to itself
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
|
||||
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
|
||||
self.fields.higher_ranked_sub(b, a, self.a_is_expected)?;
|
||||
|
|
|
@ -103,6 +103,11 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
|
|||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
// GLB of a binder and itself is just itself
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
debug!("binders(a={:?}, b={:?})", a, b);
|
||||
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
|
||||
// When higher-ranked types are involved, computing the GLB is
|
||||
|
|
|
@ -103,6 +103,11 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
|
|||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
// LUB of a binder and itself is just itself
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
debug!("binders(a={:?}, b={:?})", a, b);
|
||||
if a.skip_binder().has_escaping_bound_vars() || b.skip_binder().has_escaping_bound_vars() {
|
||||
// When higher-ranked types are involved, computing the LUB is
|
||||
|
|
|
@ -213,6 +213,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
|||
where
|
||||
T: Relate<'tcx>,
|
||||
{
|
||||
// A binder is always a subtype of itself if it's structually equal to itself
|
||||
if a == b {
|
||||
return Ok(a);
|
||||
}
|
||||
|
||||
self.fields.higher_ranked_sub(a, b, self.a_is_expected)?;
|
||||
Ok(a)
|
||||
}
|
||||
|
|
|
@ -235,7 +235,7 @@ pub struct ImplHeader<'tcx> {
|
|||
pub predicates: Vec<Predicate<'tcx>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable)]
|
||||
pub enum ImplSubject<'tcx> {
|
||||
Trait(TraitRef<'tcx>),
|
||||
Inherent(Ty<'tcx>),
|
||||
|
|
|
@ -106,7 +106,7 @@ pub trait TypeRelation<'tcx>: Sized {
|
|||
T: Relate<'tcx>;
|
||||
}
|
||||
|
||||
pub trait Relate<'tcx>: TypeFoldable<'tcx> + Copy {
|
||||
pub trait Relate<'tcx>: TypeFoldable<'tcx> + PartialEq + Copy {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
a: Self,
|
||||
|
@ -351,7 +351,7 @@ impl<'tcx> Relate<'tcx> for ty::ExistentialTraitRef<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
|
||||
#[derive(PartialEq, Copy, Debug, Clone, TypeFoldable, TypeVisitable)]
|
||||
struct GeneratorWitness<'tcx>(&'tcx ty::List<Ty<'tcx>>);
|
||||
|
||||
impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> {
|
||||
|
|
|
@ -217,7 +217,7 @@ static_assert_size!(TyKind<'_>, 32);
|
|||
/// * `GR`: The "return type", which is the type of value returned upon
|
||||
/// completion of the generator.
|
||||
/// * `GW`: The "generator witness".
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct ClosureSubsts<'tcx> {
|
||||
/// Lifetime and type parameters from the enclosing function,
|
||||
/// concatenated with a tuple containing the types of the upvars.
|
||||
|
@ -348,7 +348,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
|
|||
}
|
||||
|
||||
/// Similar to `ClosureSubsts`; see the above documentation for more.
|
||||
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, Lift)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct GeneratorSubsts<'tcx> {
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
|
||||
|
||||
fn id(
|
||||
f: &dyn Fn(u32),
|
||||
) -> &dyn Fn(
|
||||
&dyn Fn(
|
||||
&dyn Fn(
|
||||
&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))),
|
||||
),
|
||||
),
|
||||
) {
|
||||
f
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
|
@ -0,0 +1,22 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/hang-on-deeply-nested-dyn.rs:12:5
|
||||
|
|
||||
LL | ) -> &dyn Fn(
|
||||
| ______-
|
||||
LL | | &dyn Fn(
|
||||
LL | | &dyn Fn(
|
||||
LL | | &dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(&dyn Fn(u32))))))))),
|
||||
LL | | ),
|
||||
LL | | ),
|
||||
LL | | ) {
|
||||
| |_- expected `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn Fn(u32) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a)) + 'a))` because of return type
|
||||
LL | f
|
||||
| ^ expected reference, found `u32`
|
||||
|
|
||||
= note: expected reference `&dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a (dyn for<'a> Fn(&'a ...) + 'a)) + 'a)) + 'a))`
|
||||
the full type name has been written to '$TEST_BUILD_DIR/higher-rank-trait-bounds/hang-on-deeply-nested-dyn/hang-on-deeply-nested-dyn.long-type-hash.txt'
|
||||
found reference `&dyn Fn(u32)`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Add table
Add a link
Reference in a new issue