Add compare-mode=chalk and add a little bit more implementations and fixmes

This commit is contained in:
Jack Huey 2020-05-13 15:18:50 -04:00
parent 72417d84fb
commit 006b482794
10 changed files with 91 additions and 35 deletions

View file

@ -32,12 +32,10 @@ pub enum RustDefId {
RawPtr,
Trait(DefId),
Impl(DefId),
FnDef(DefId),
AssocTy(DefId),
Opaque(DefId),
}
#[derive(Copy, Clone)]

View file

@ -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"),
};

View file

@ -168,7 +168,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> 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<RustInterner<'tcx>> 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<RustInterner<'tcx>> 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<RustInterner<'tcx>> for RustIrDatabase<'t
fn opaque_ty_data(
&self,
_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
) -> Arc<chalk_rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
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<RustInterner<'tcx>> 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<RustInterner<'tcx>> for RustIrDatabase<'t
}
}
}
Trait(_) | Impl(_) | AssocTy(_) => panic!(),
Trait(_) | Impl(_) | AssocTy(_) | Opaque(_) => panic!(),
}
}
_ => None,

View file

@ -352,7 +352,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> 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<RustInterner<'tcx>>> 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<RustInterner<'tcx>>> 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<RustInterner<'tcx>>> 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<RustInterner<'tcx>>> for Region<'t
.intern(interner)
}
ReEmpty(_) => unimplemented!(),
// FIXME(chalk): need to handle ReErased
ReErased => unimplemented!(),
}
}
@ -472,6 +484,39 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
}
}
impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>>>
for Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>
{
fn lower_into(
self,
interner: &RustInterner<'tcx>,
) -> chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>> {
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,

View file

@ -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 <https://github.com/rust-lang/rust/issues/56105>
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
warning: 1 warning emitted

View file

@ -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() {}

View file

@ -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

View file

@ -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),
}
}

View file

@ -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") ||

View file

@ -1985,6 +1985,9 @@ impl<'test> TestCx<'test> {
Some(CompareMode::Polonius) => {
rustc.args(&["-Zpolonius", "-Zborrowck=mir"]);
}
Some(CompareMode::Chalk) => {
rustc.args(&["-Zchalk"]);
}
None => {}
}