]> git.lizzy.rs Git - rust.git/commitdiff
Merge #5331
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Sun, 12 Jul 2020 20:31:51 +0000 (20:31 +0000)
committerGitHub <noreply@github.com>
Sun, 12 Jul 2020 20:31:51 +0000 (20:31 +0000)
5331: Fix #4966 r=flodiebold a=flodiebold

We add a level of binders when converting our function pointer to Chalk's; we need to remove it again on the way back.

Fixes #4966.

Co-authored-by: Florian Diebold <florian.diebold@freiheit.com>
1  2 
crates/ra_hir_ty/src/traits/chalk/mapping.rs

index 7dc9ee7598d762370fd1039995bcdb61df87d25c,cb354d586bb3838670277298cdc436d1c72005e9..06453ef820810eba1520232df03f10d6a8476c7a
@@@ -29,7 -29,6 +29,7 @@@ impl ToChalk for Ty 
          match self {
              Ty::Apply(apply_ty) => match apply_ty.ctor {
                  TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters),
 +                TypeCtor::Array => array_to_chalk(db, apply_ty.parameters),
                  TypeCtor::FnPtr { num_args: _ } => {
                      let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner);
                      chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution })
              Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner),
              Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
              Ty::Dyn(predicates) => {
 -                let where_clauses = chalk_ir::QuantifiedWhereClauses::from(
 +                let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
                      &Interner,
                      predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
                  );
                  let bounded_ty = chalk_ir::DynTy {
                      bounds: make_binders(where_clauses, 1),
 -                    lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner),
 +                    lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
                  };
                  chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
              }
@@@ -93,7 -92,6 +93,7 @@@
              chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
                  TypeName::Error => Ty::Unknown,
                  TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution),
 +                TypeName::Array => array_from_chalk(db, apply_ty.substitution),
                  _ => {
                      let ctor = from_chalk(db, apply_ty.name);
                      let parameters = from_chalk(db, apply_ty.substitution);
                  let parameters = from_chalk(db, opaque_ty.substitution);
                  Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
              }
-             chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => {
-                 let parameters: Substs = from_chalk(db, substitution);
+             chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => {
+                 assert_eq!(num_binders, 0);
+                 let parameters: Substs = from_chalk(
+                     db,
+                     substitution.shifted_out(&Interner).expect("fn ptr should have no binders"),
+                 );
                  Ty::Apply(ApplicationTy {
                      ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 },
                      parameters,
      }
  }
  
 -const LIFETIME_PLACEHOLDER: PlaceholderIndex =
 +const FAKE_PLACEHOLDER: PlaceholderIndex =
      PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
  
  /// We currently don't model lifetimes, but Chalk does. So, we have to insert a
@@@ -151,10 -153,10 +155,10 @@@ fn ref_to_chalk
      subst: Substs,
  ) -> chalk_ir::Ty<Interner> {
      let arg = subst[0].clone().to_chalk(db);
 -    let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner);
 +    let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
      chalk_ir::ApplicationTy {
          name: TypeName::Ref(mutability.to_chalk(db)),
 -        substitution: chalk_ir::Substitution::from(
 +        substitution: chalk_ir::Substitution::from_iter(
              &Interner,
              vec![lifetime.cast(&Interner), arg.cast(&Interner)],
          ),
@@@ -175,40 -177,11 +179,40 @@@ fn ref_from_chalk
      Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
  }
  
 +/// We currently don't model constants, but Chalk does. So, we have to insert a
 +/// fake constant here, because Chalks built-in logic may expect it to be there.
 +fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
 +    let arg = subst[0].clone().to_chalk(db);
 +    let usize_ty = chalk_ir::ApplicationTy {
 +        name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)),
 +        substitution: chalk_ir::Substitution::empty(&Interner),
 +    }
 +    .intern(&Interner);
 +    let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty);
 +    chalk_ir::ApplicationTy {
 +        name: TypeName::Array,
 +        substitution: chalk_ir::Substitution::from_iter(
 +            &Interner,
 +            vec![arg.cast(&Interner), const_.cast(&Interner)],
 +        ),
 +    }
 +    .intern(&Interner)
 +}
 +
 +/// Here we remove the const from the type we got from Chalk.
 +fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty {
 +    let tys = subst
 +        .iter(&Interner)
 +        .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone())))
 +        .collect();
 +    Ty::apply(TypeCtor::Array, Substs(tys))
 +}
 +
  impl ToChalk for Substs {
      type Chalk = chalk_ir::Substitution<Interner>;
  
      fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
 -        chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
 +        chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
      }
  
      fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs {
@@@ -294,7 -267,6 +298,7 @@@ impl ToChalk for TypeCtor 
              TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
              TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
              TypeCtor::Slice => TypeName::Slice,
 +            TypeCtor::Array => TypeName::Array,
              TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
              TypeCtor::Str => TypeName::Str,
              TypeCtor::FnDef(callable_def) => {
              }
              TypeCtor::Never => TypeName::Never,
  
 -            TypeCtor::Adt(_)
 -            | TypeCtor::Array
 -            | TypeCtor::FnPtr { .. }
 -            | TypeCtor::Closure { .. } => {
 +            // FIXME convert these
 +            TypeCtor::Adt(_) | TypeCtor::FnPtr { .. } | TypeCtor::Closure { .. } => {
                  // other TypeCtors get interned and turned into a chalk StructId
                  let struct_id = db.intern_type_ctor(self).into();
                  TypeName::Adt(struct_id)
@@@ -522,11 -496,6 +526,11 @@@ impl ToChalk for GenericPredicate 
                  // we shouldn't get these from Chalk
                  panic!("encountered LifetimeOutlives from Chalk")
              }
 +
 +            chalk_ir::WhereClause::TypeOutlives(_) => {
 +                // we shouldn't get these from Chalk
 +                panic!("encountered TypeOutlives from Chalk")
 +            }
          }
      }
  }
@@@ -605,10 -574,7 +609,10 @@@ wher
                  )
              });
          let value = self.value.to_chalk(db);
 -        chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) }
 +        chalk_ir::Canonical {
 +            value,
 +            binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
 +        }
      }
  
      fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
@@@ -729,7 -695,7 +733,7 @@@ wher
      T: HasInterner<Interner = Interner>,
  {
      chalk_ir::Binders::new(
 -        chalk_ir::VariableKinds::from(
 +        chalk_ir::VariableKinds::from_iter(
              &Interner,
              std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars),
          ),