From 006b48279431cab16d2b5d522151b6eae459e835 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Wed, 13 May 2020 15:18:50 -0400 Subject: [PATCH] Add compare-mode=chalk and add a little bit more implementations and fixmes --- src/librustc_middle/traits/chalk.rs | 4 +- .../traits/chalk_fulfill.rs | 6 ++- src/librustc_traits/chalk/db.rs | 33 +++++++++--- src/librustc_traits/chalk/lowering.rs | 51 +++++++++++++++++-- .../coherence/coherence-subtyping.re.stderr | 16 ------ src/test/ui/coherence/coherence-subtyping.rs | 7 +-- ....old.stderr => coherence-subtyping.stderr} | 2 +- src/tools/compiletest/src/common.rs | 3 ++ src/tools/compiletest/src/header.rs | 1 + src/tools/compiletest/src/runtest.rs | 3 ++ 10 files changed, 91 insertions(+), 35 deletions(-) delete mode 100644 src/test/ui/coherence/coherence-subtyping.re.stderr rename src/test/ui/coherence/{coherence-subtyping.old.stderr => coherence-subtyping.stderr} (95%) diff --git a/src/librustc_middle/traits/chalk.rs b/src/librustc_middle/traits/chalk.rs index b963af96f502..e3ecea69da66 100644 --- a/src/librustc_middle/traits/chalk.rs +++ b/src/librustc_middle/traits/chalk.rs @@ -32,12 +32,10 @@ pub enum RustDefId { RawPtr, Trait(DefId), - Impl(DefId), - FnDef(DefId), - AssocTy(DefId), + Opaque(DefId), } #[derive(Copy, Clone)] diff --git a/src/librustc_trait_selection/traits/chalk_fulfill.rs b/src/librustc_trait_selection/traits/chalk_fulfill.rs index 2d4d582c939b..cbbff82d35f7 100644 --- a/src/librustc_trait_selection/traits/chalk_fulfill.rs +++ b/src/librustc_trait_selection/traits/chalk_fulfill.rs @@ -87,7 +87,9 @@ fn environment<'tcx>( NodeKind::TraitImpl => { let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl"); - inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk())); + // FIXME(chalk): this has problems because of late-bound regions + //inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk())); + inputs.extend(trait_ref.substs.iter()); } // In an inherent impl, we assume that the receiver type and all its @@ -136,6 +138,8 @@ fn in_environment( let environment = match obligation.param_env.def_id { Some(def_id) => environment(infcx.tcx, def_id), None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(), + // FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl + // and ui/generics/generic-static-methods _ => bug!("non-empty `ParamEnv` with no def-id"), }; diff --git a/src/librustc_traits/chalk/db.rs b/src/librustc_traits/chalk/db.rs index a2aee9b6ef74..18c690a2f513 100644 --- a/src/librustc_traits/chalk/db.rs +++ b/src/librustc_traits/chalk/db.rs @@ -168,7 +168,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }); struct_datum } - RustDefId::Ref(_) => Arc::new(chalk_rust_ir::StructDatum { + RustDefId::Ref(_) | RustDefId::RawPtr => Arc::new(chalk_rust_ir::StructDatum { id: struct_id, binders: chalk_ir::Binders::new( chalk_ir::ParameterKinds::from( @@ -204,7 +204,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }) } - _ => bug!("Used not struct variant when expecting struct variant."), + v => bug!("Used not struct variant ({:?}) when expecting struct variant.", v), } } @@ -283,6 +283,17 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t RustDefId::Trait(def_id) => def_id, _ => bug!("Did not use `Trait` variant when expecting trait."), }; + // FIXME(chalk): this match can be removed when builtin types supported + match struct_id.0 { + RustDefId::Adt(_) => {} + RustDefId::Str => return false, + RustDefId::Never => return false, + RustDefId::Slice => return false, + RustDefId::Array => return false, + RustDefId::Ref(_) => return false, + RustDefId::RawPtr => return false, + _ => bug!("Did not use `Adt` variant when expecting adt."), + } let adt_def_id: DefId = match struct_id.0 { RustDefId::Adt(def_id) => def_id, _ => bug!("Did not use `Adt` variant when expecting adt."), @@ -347,9 +358,19 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn opaque_ty_data( &self, - _id: chalk_ir::OpaqueTyId>, + opaque_ty_id: chalk_ir::OpaqueTyId>, ) -> Arc>> { - unimplemented!() + // FIXME(chalk): actually lower opaque ty + let hidden_ty = + self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner); + let value = chalk_rust_ir::OpaqueTyDatumBound { + hidden_ty, + bounds: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), vec![]), + }; + Arc::new(chalk_rust_ir::OpaqueTyDatum { + opaque_ty_id, + bound: chalk_ir::Binders::new(chalk_ir::ParameterKinds::new(&self.interner), value), + }) } /// Since Chalk can't handle all Rust types currently, we have to handle @@ -386,7 +407,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t Str | Slice => Some(false), - Trait(_) | Impl(_) | AssocTy(_) => panic!(), + Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, @@ -416,7 +437,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t } } } - Trait(_) | Impl(_) | AssocTy(_) => panic!(), + Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(), } } _ => None, diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs index c9dd06e9f1ba..8a36ad3b1163 100644 --- a/src/librustc_traits/chalk/lowering.rs +++ b/src/librustc_traits/chalk/lowering.rs @@ -352,7 +352,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }) .intern(interner) } - Dynamic(_, _) => unimplemented!(), + // FIXME(chalk): add region + Dynamic(predicates, _region) => { + TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) }) + .intern(interner) + } Closure(_def_id, _) => unimplemented!(), Generator(_def_id, _substs, _) => unimplemented!(), GeneratorWitness(_) => unimplemented!(), @@ -361,7 +365,13 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { apply(chalk_ir::TypeName::Tuple(substs.len()), substs.lower_into(interner)) } Projection(proj) => TyData::Alias(proj.lower_into(interner)).intern(interner), - Opaque(_def_id, _substs) => unimplemented!(), + Opaque(def_id, substs) => { + TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { + opaque_ty_id: chalk_ir::OpaqueTyId(RustDefId::Opaque(def_id)), + substitution: substs.lower_into(interner), + })) + .intern(interner) + } // This should have been done eagerly prior to this, and all Params // should have been substituted to placeholders Param(_) => panic!("Lowering Param when not expected."), @@ -376,7 +386,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }) .intern(interner), Infer(_infer) => unimplemented!(), - Error(_) => unimplemented!(), + Error(_) => apply(chalk_ir::TypeName::Error, empty()), } } } @@ -401,6 +411,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t ty::BrEnv => unimplemented!(), }, ReFree(_) => unimplemented!(), + // FIXME(chalk): need to handle ReStatic ReStatic => unimplemented!(), ReVar(_) => unimplemented!(), RePlaceholder(placeholder_region) => { @@ -411,6 +422,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t .intern(interner) } ReEmpty(_) => unimplemented!(), + // FIXME(chalk): need to handle ReErased ReErased => unimplemented!(), } } @@ -472,6 +484,39 @@ impl<'tcx> LowerInto<'tcx, Option LowerInto<'tcx, chalk_ir::Binders>>> + for Binder<&'tcx ty::List>> +{ + fn lower_into( + self, + interner: &RustInterner<'tcx>, + ) -> chalk_ir::Binders>> { + let (predicates, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &self); + let where_clauses = predicates.into_iter().map(|predicate| match predicate { + ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { + chalk_ir::Binders::new( + chalk_ir::ParameterKinds::new(interner), + chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { + trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), + substitution: substs.lower_into(interner), + }), + ) + } + ty::ExistentialPredicate::Projection(_predicate) => unimplemented!(), + ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( + chalk_ir::ParameterKinds::new(interner), + chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { + trait_id: chalk_ir::TraitId(RustDefId::Trait(*def_id)), + substitution: chalk_ir::Substitution::empty(interner), + }), + ), + }); + let value = chalk_ir::QuantifiedWhereClauses::from(interner, where_clauses); + chalk_ir::Binders::new(binders, value) + } +} + /// 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, diff --git a/src/test/ui/coherence/coherence-subtyping.re.stderr b/src/test/ui/coherence/coherence-subtyping.re.stderr deleted file mode 100644 index b3c2f4516349..000000000000 --- a/src/test/ui/coherence/coherence-subtyping.re.stderr +++ /dev/null @@ -1,16 +0,0 @@ -warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:16:1 - | -LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} - | ---------------------------------------------------------- first implementation here -LL | -LL | impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8` - | - = note: `#[warn(coherence_leak_check)]` on by default - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #56105 - = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details - -warning: 1 warning emitted - diff --git a/src/test/ui/coherence/coherence-subtyping.rs b/src/test/ui/coherence/coherence-subtyping.rs index f5c1d92411ba..b3ed728a81c0 100644 --- a/src/test/ui/coherence/coherence-subtyping.rs +++ b/src/test/ui/coherence/coherence-subtyping.rs @@ -4,7 +4,6 @@ // Note: This scenario is currently accepted, but as part of the // universe transition (#56105) may eventually become an error. -// revisions: old re // check-pass trait TheTrait { @@ -14,10 +13,8 @@ trait TheTrait { impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} impl TheTrait for for<'a> fn(&'a u8, &'a u8) -> &'a u8 { - //[re]~^ WARNING conflicting implementation - //[re]~^^ WARNING this was previously accepted by the compiler but is being phased out - //[old]~^^^ WARNING conflicting implementation - //[old]~^^^^ WARNING this was previously accepted by the compiler but is being phased out + //~^ WARNING conflicting implementation + //~^^ WARNING this was previously accepted by the compiler but is being phased out } fn main() {} diff --git a/src/test/ui/coherence/coherence-subtyping.old.stderr b/src/test/ui/coherence/coherence-subtyping.stderr similarity index 95% rename from src/test/ui/coherence/coherence-subtyping.old.stderr rename to src/test/ui/coherence/coherence-subtyping.stderr index b3c2f4516349..7f751a24c75c 100644 --- a/src/test/ui/coherence/coherence-subtyping.old.stderr +++ b/src/test/ui/coherence/coherence-subtyping.stderr @@ -1,5 +1,5 @@ warning: conflicting implementations of trait `TheTrait` for type `for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8`: - --> $DIR/coherence-subtyping.rs:16:1 + --> $DIR/coherence-subtyping.rs:15:1 | LL | impl TheTrait for for<'a, 'b> fn(&'a u8, &'b u8) -> &'a u8 {} | ---------------------------------------------------------- first implementation here diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 64c0298c1fa4..703b87634cec 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -123,6 +123,7 @@ pub enum FailMode { pub enum CompareMode { Nll, Polonius, + Chalk, } impl CompareMode { @@ -130,6 +131,7 @@ impl CompareMode { match *self { CompareMode::Nll => "nll", CompareMode::Polonius => "polonius", + CompareMode::Chalk => "chalk", } } @@ -137,6 +139,7 @@ impl CompareMode { match s.as_str() { "nll" => CompareMode::Nll, "polonius" => CompareMode::Polonius, + "chalk" => CompareMode::Chalk, x => panic!("unknown --compare-mode option: {}", x), } } diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 9614707433e1..7d2c83881d13 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -875,6 +875,7 @@ impl Config { match self.compare_mode { Some(CompareMode::Nll) => name == "compare-mode-nll", Some(CompareMode::Polonius) => name == "compare-mode-polonius", + Some(CompareMode::Chalk) => name == "compare-mode-chalk", None => false, } || (cfg!(debug_assertions) && name == "debug") || diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 18f00db3d8e1..95ea4fb07895 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1985,6 +1985,9 @@ impl<'test> TestCx<'test> { Some(CompareMode::Polonius) => { rustc.args(&["-Zpolonius", "-Zborrowck=mir"]); } + Some(CompareMode::Chalk) => { + rustc.args(&["-Zchalk"]); + } None => {} }