diff --git a/Cargo.lock b/Cargo.lock index 26a9e64b85af..daaa4ae44bac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,9 +427,9 @@ dependencies = [ [[package]] name = "chalk-derive" -version = "0.21.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1df0dbb57d74b4acd20f20fa66ab2acd09776b79eaeb9d8f947b2f3e01c40bf" +checksum = "8c85b013e2dc1b46ac4a279f54e62e55556a8c4d859f7b7c4e340a9b1d013640" dependencies = [ "proc-macro2", "quote", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.21.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb7c65a13f32f02aba8f1d9a37f206af615f77ac564624b81a4c593c6c1735b9" +checksum = "2a499f81860f6eadfe0c76c5bb606cd2df701939d5a596ed3724c7db04aec14b" dependencies = [ "chalk-derive", "chalk-ir", @@ -452,9 +452,9 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.21.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44361a25dbdb1dc428f56ad7a3c21ba9ca12f3225c26a47919ff6fcb10a583d4" +checksum = "2135d844688dc920e3ece3012c5d3d4f06e26986fe38bc041bc98f0e7a9f4e2b" dependencies = [ "chalk-derive", "lazy_static", @@ -462,9 +462,9 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.21.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a886da37a0dc457057d86f78f026f7a09c6d8088aa13f4f4127fdb8dc80119a3" +checksum = "bc69e4e94ffd4b39f1a865824b431bb82a7b4c8f14a0ba3d461cd86e56a590ac" dependencies = [ "chalk-derive", "chalk-ir", diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index a5a860a38b3e..5136e2743cdb 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,7 +26,7 @@ rustc_index = { path = "../rustc_index" } rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.21.0" +chalk-ir = "0.28.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 3571ff17f31b..369d003eb22f 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -12,9 +12,9 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.21.0" -chalk-solve = "0.21.0" -chalk-engine = "0.21.0" +chalk-ir = "0.28.0" +chalk-solve = "0.28.0" +chalk-engine = "0.28.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 2fad54013ad5..828ee6dea625 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -11,7 +11,6 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable}; use rustc_hir::def_id::DefId; -use rustc_hir::Unsafety; use rustc_span::symbol::sym; @@ -19,6 +18,7 @@ use std::fmt; use std::sync::Arc; use crate::chalk::lowering::{self, LowerInto}; +use rustc_ast::ast; pub struct RustIrDatabase<'tcx> { pub(crate) interner: RustInterner<'tcx>, @@ -247,12 +247,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }; Arc::new(chalk_solve::rust_ir::FnDefDatum { id: fn_def_id, - abi: sig.abi(), - safety: match sig.unsafety() { - Unsafety::Normal => chalk_ir::Safety::Safe, - Unsafety::Unsafe => chalk_ir::Safety::Unsafe, - }, - variadic: sig.c_variadic(), + sig: sig.lower_into(&self.interner), binders: chalk_ir::Binders::new(binders, bound), }) } @@ -327,21 +322,75 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn impl_provided_for( &self, auto_trait_id: chalk_ir::TraitId>, - adt_id: chalk_ir::AdtId>, + app_ty: &chalk_ir::ApplicationTy>, ) -> bool { + use chalk_ir::Scalar::*; + use chalk_ir::TypeName::*; + let trait_def_id = auto_trait_id.0; - let adt_def = adt_id.0; let all_impls = self.interner.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap(); let self_ty = trait_ref.self_ty(); - match *self_ty.kind() { - ty::Adt(impl_adt_def, _) => { - if impl_adt_def == adt_def { - return true; + let provides = match (self_ty.kind(), app_ty.name) { + (&ty::Adt(impl_adt_def, ..), Adt(id)) => impl_adt_def.did == id.0.did, + (_, AssociatedType(_ty_id)) => { + // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774 + false + } + (ty::Bool, Scalar(Bool)) => true, + (ty::Char, Scalar(Char)) => true, + (ty::Int(ty1), Scalar(Int(ty2))) => match (ty1, ty2) { + (ast::IntTy::Isize, chalk_ir::IntTy::Isize) + | (ast::IntTy::I8, chalk_ir::IntTy::I8) + | (ast::IntTy::I16, chalk_ir::IntTy::I16) + | (ast::IntTy::I32, chalk_ir::IntTy::I32) + | (ast::IntTy::I64, chalk_ir::IntTy::I64) + | (ast::IntTy::I128, chalk_ir::IntTy::I128) => true, + _ => false, + }, + (ty::Uint(ty1), Scalar(Uint(ty2))) => match (ty1, ty2) { + (ast::UintTy::Usize, chalk_ir::UintTy::Usize) + | (ast::UintTy::U8, chalk_ir::UintTy::U8) + | (ast::UintTy::U16, chalk_ir::UintTy::U16) + | (ast::UintTy::U32, chalk_ir::UintTy::U32) + | (ast::UintTy::U64, chalk_ir::UintTy::U64) + | (ast::UintTy::U128, chalk_ir::UintTy::U128) => true, + _ => false, + }, + (ty::Float(ty1), Scalar(Float(ty2))) => match (ty1, ty2) { + (ast::FloatTy::F32, chalk_ir::FloatTy::F32) + | (ast::FloatTy::F64, chalk_ir::FloatTy::F64) => true, + _ => false, + }, + (&ty::Tuple(..), Tuple(..)) => true, + (&ty::Array(..), Array) => true, + (&ty::Slice(..), Slice) => true, + (&ty::RawPtr(type_and_mut), Raw(mutability)) => { + match (type_and_mut.mutbl, mutability) { + (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, + (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, } } - _ => {} + (&ty::Ref(.., mutability1), Ref(mutability2)) => match (mutability1, mutability2) { + (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, + (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, + (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, + }, + (&ty::Opaque(def_id, ..), OpaqueType(opaque_ty_id)) => def_id == opaque_ty_id.0, + (&ty::FnDef(def_id, ..), FnDef(fn_def_id)) => def_id == fn_def_id.0, + (&ty::Str, Str) => true, + (&ty::Never, Never) => true, + (&ty::Closure(def_id, ..), Closure(closure_id)) => def_id == closure_id.0, + (&ty::Foreign(def_id), Foreign(foreign_def_id)) => def_id == foreign_def_id.0, + (&ty::Error(..), Error) => false, + _ => false, + }; + if provides { + return true; } } false @@ -416,15 +465,18 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t well_known_trait: chalk_solve::rust_ir::WellKnownTrait, ) -> Option>> { use chalk_solve::rust_ir::WellKnownTrait::*; + let lang_items = self.interner.tcx.lang_items(); let def_id = match well_known_trait { - Sized => self.interner.tcx.lang_items().sized_trait(), - Copy => self.interner.tcx.lang_items().copy_trait(), - Clone => self.interner.tcx.lang_items().clone_trait(), - Drop => self.interner.tcx.lang_items().drop_trait(), - Fn => self.interner.tcx.lang_items().fn_trait(), - FnMut => self.interner.tcx.lang_items().fn_mut_trait(), - FnOnce => self.interner.tcx.lang_items().fn_once_trait(), - Unsize => self.interner.tcx.lang_items().unsize_trait(), + Sized => lang_items.sized_trait(), + Copy => lang_items.copy_trait(), + Clone => lang_items.clone_trait(), + Drop => lang_items.drop_trait(), + Fn => lang_items.fn_trait(), + FnMut => lang_items.fn_mut_trait(), + FnOnce => lang_items.fn_once_trait(), + Unsize => lang_items.unsize_trait(), + Unpin => lang_items.unpin_trait(), + CoerceUnsized => lang_items.coerce_unsized_trait(), }; def_id.map(chalk_ir::TraitId) } diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 650404e8ca6d..1e1841a57f81 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -39,6 +39,8 @@ use rustc_middle::ty::{ }; use rustc_span::def_id::DefId; +use chalk_ir::{FnSig, ForeignDefId}; +use rustc_hir::Unsafety; use std::collections::btree_map::{BTreeMap, Entry}; /// Essentially an `Into` with a `&RustInterner` parameter @@ -269,8 +271,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64), }, Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)), - // FIXME(chalk): lower Foreign - Foreign(def_id) => apply(chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)), empty()), + Foreign(def_id) => apply(chalk_ir::TypeName::Foreign(ForeignDefId(def_id)), empty()), Str => apply(chalk_ir::TypeName::Str, empty()), Array(ty, len) => { let value = match len.val { @@ -340,18 +341,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output()); TyData::Function(chalk_ir::FnPointer { num_binders: binders.len(interner), + sig: sig.lower_into(interner), substitution: chalk_ir::Substitution::from_iter( interner, inputs_and_outputs.iter().map(|ty| { chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner) }), ), - abi: sig.abi(), - safety: match sig.unsafety() { - rustc_hir::Unsafety::Normal => chalk_ir::Safety::Safe, - rustc_hir::Unsafety::Unsafe => chalk_ir::Safety::Unsafe, - }, - variadic: sig.c_variadic(), }) .intern(interner) } @@ -480,6 +476,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty> { substs: application_ty.substitution.lower_into(interner), item_def_id: assoc_ty.0, }), + chalk_ir::TypeName::Foreign(def_id) => ty::Foreign(def_id.0), chalk_ir::TypeName::Error => unimplemented!(), }, TyData::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { @@ -718,6 +715,19 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders LowerInto<'tcx, chalk_ir::FnSig>> for ty::Binder> { + fn lower_into(self, _interner: &RustInterner<'_>) -> FnSig> { + chalk_ir::FnSig { + abi: self.abi(), + safety: match self.unsafety() { + Unsafety::Normal => chalk_ir::Safety::Safe, + Unsafety::Unsafe => chalk_ir::Safety::Unsafe, + }, + variadic: self.c_variadic(), + } + } +} + /// To collect bound vars, we have to do two passes. In the first pass, we /// collect all `BoundRegion`s and `ty::Bound`s. In the second pass, we then /// replace `BrNamed` into `BrAnon`. The two separate passes are important,