Update Chalk

This commit is contained in:
Jack Huey 2020-05-27 01:05:09 -04:00
parent 0c04344d86
commit ecb8b9f9f7
15 changed files with 311 additions and 107 deletions

View File

@ -434,9 +434,9 @@ dependencies = [
[[package]]
name = "chalk-derive"
version = "0.11.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b9bd01eab87277d973183a1d2e56bace1c11f8242c52c20636fb7dddf343ac9"
checksum = "d463e01905d607e181de72e8608721d3269f29176c9a14ce037011316ae7131d"
dependencies = [
"proc-macro2 1.0.3",
"quote 1.0.2",
@ -446,20 +446,21 @@ dependencies = [
[[package]]
name = "chalk-engine"
version = "0.11.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c7a637c3d17ed555aef16e16952a5d1e127bd55178cc30be22afeb92da90c7d"
checksum = "efaf428f5398d36284f79690cf988762b7c091249f50a6c11db613a46c057000"
dependencies = [
"chalk-derive",
"chalk-ir",
"rustc-hash",
"tracing",
]
[[package]]
name = "chalk-ir"
version = "0.11.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "595e5735ded16c3f3dc348f7b15bbb2521a0080b1863cac38ad5271589944670"
checksum = "fd3fdc1e9f68498ffe80f4a23b0b95f1ca6fb21d5a4c9b0c085fab3ca712bdbe"
dependencies = [
"chalk-derive",
"lazy_static",
@ -467,9 +468,9 @@ dependencies = [
[[package]]
name = "chalk-solve"
version = "0.11.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d9d938139db425867a30cc0cfec0269406d8238d0571d829041eaa7a8455d11"
checksum = "5b9fd4102807b7ebe8fb034fa0f488c5656e1966d3261b558b81a08d519cdb29"
dependencies = [
"chalk-derive",
"chalk-engine",
@ -478,6 +479,7 @@ dependencies = [
"itertools 0.9.0",
"petgraph",
"rustc-hash",
"tracing",
]
[[package]]
@ -5332,6 +5334,37 @@ dependencies = [
"syn 0.15.35",
]
[[package]]
name = "tracing"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41f40ed0e162c911ac6fcb53ecdc8134c46905fdbbae8c50add462a538b495f"
dependencies = [
"cfg-if",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-attributes"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99bbad0de3fd923c9c3232ead88510b783e5a4d16a6154adffa3d53308de984c"
dependencies = [
"proc-macro2 1.0.3",
"quote 1.0.2",
"syn 1.0.11",
]
[[package]]
name = "tracing-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aa83a9a47081cd522c09c81b31aec2c9273424976f922ad61c053b58350b715"
dependencies = [
"lazy_static",
]
[[package]]
name = "try-lock"
version = "0.2.2"

View File

@ -30,7 +30,7 @@ rustc_serialize = { path = "../librustc_serialize" }
rustc_ast = { path = "../librustc_ast" }
rustc_span = { path = "../librustc_span" }
byteorder = { version = "1.3" }
chalk-ir = "0.11.0"
chalk-ir = "0.14.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
measureme = "0.7.1"
rustc_session = { path = "../librustc_session" }

View File

@ -10,6 +10,7 @@ use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
use rustc_hir::def_id::DefId;
use rustc_target::spec::abi::Abi;
use smallvec::SmallVec;
@ -77,6 +78,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> {
type DefId = DefId;
type InternedAdtId = &'tcx AdtDef;
type Identifier = ();
type FnAbi = Abi;
fn debug_program_clause_implication(
pci: &chalk_ir::ProgramClauseImplication<Self>,

View File

@ -7,17 +7,17 @@ use crate::traits::{
ChalkEnvironmentAndGoal, ChalkEnvironmentClause, FulfillmentError, FulfillmentErrorCode,
ObligationCause, PredicateObligation, SelectionError, TraitEngine,
};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct FulfillmentContext<'tcx> {
obligations: FxHashSet<PredicateObligation<'tcx>>,
obligations: FxIndexSet<PredicateObligation<'tcx>>,
}
impl FulfillmentContext<'tcx> {
crate fn new() -> Self {
FulfillmentContext { obligations: FxHashSet::default() }
FulfillmentContext { obligations: FxIndexSet::default() }
}
}
@ -79,7 +79,7 @@ fn environment<'tcx>(
};
// FIXME(eddyb) isn't the unordered nature of this a hazard?
let mut inputs = FxHashSet::default();
let mut inputs = FxIndexSet::default();
match node_kind {
// In a trait impl, we assume that the header trait ref and all its
@ -140,7 +140,8 @@ fn in_environment(
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"),
//_ => bug!("non-empty `ParamEnv` with no def-id"),
_ => ty::List::empty(),
};
ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }
@ -195,7 +196,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
infcx: &InferCtxt<'_, 'tcx>,
) -> Result<(), Vec<FulfillmentError<'tcx>>> {
let mut errors = Vec::new();
let mut next_round = FxHashSet::default();
let mut next_round = FxIndexSet::default();
let mut making_progress;
loop {
@ -203,7 +204,7 @@ impl TraitEngine<'tcx> for FulfillmentContext<'tcx> {
// We iterate over all obligations, and record if we are able
// to unambiguously prove at least one obligation.
for obligation in self.obligations.drain() {
for obligation in self.obligations.drain(..) {
let goal_in_environment = in_environment(infcx, &obligation);
let mut orig_values = OriginalQueryValues::default();
let canonical_goal =

View File

@ -16,8 +16,8 @@ rustc_hir = { path = "../librustc_hir" }
rustc_index = { path = "../librustc_index" }
rustc_ast = { path = "../librustc_ast" }
rustc_span = { path = "../librustc_span" }
chalk-ir = "0.11.0"
chalk-solve = "0.11.0"
chalk-ir = "0.14.0"
chalk-solve = "0.14.0"
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
rustc_infer = { path = "../librustc_infer" }
rustc_trait_selection = { path = "../librustc_trait_selection" }

View File

@ -8,7 +8,7 @@
use rustc_middle::traits::ChalkRustInterner as RustInterner;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, Binder, TyCtxt};
use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt};
use rustc_hir::def_id::DefId;
@ -85,14 +85,29 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
.iter()
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
let associated_ty_ids: Vec<_> = self
.tcx
.associated_items(def_id)
.in_definition_order()
.filter(|i| i.kind == AssocKind::Type)
.map(|i| chalk_ir::AssocTypeId(i.def_id))
.collect();
let well_known =
if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::SizedTrait)
Some(chalk_solve::rust_ir::WellKnownTrait::Sized)
} else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::CopyTrait)
Some(chalk_solve::rust_ir::WellKnownTrait::Copy)
} else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::CloneTrait)
Some(chalk_solve::rust_ir::WellKnownTrait::Clone)
} else if self.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::Drop)
} else if self.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::Fn)
} else if self.tcx.lang_items().fn_once_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce)
} else if self.tcx.lang_items().fn_mut_trait().map(|t| def_id == t).unwrap_or(false) {
Some(chalk_solve::rust_ir::WellKnownTrait::FnMut)
} else {
None
};
@ -110,7 +125,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
non_enumerable: true,
coinductive: false,
},
associated_ty_ids: vec![],
associated_ty_ids,
well_known,
})
}
@ -156,6 +171,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
flags: chalk_solve::rust_ir::AdtFlags {
upstream: !adt_def.did.is_local(),
fundamental: adt_def.is_fundamental(),
phantom_data: adt_def.is_phantom_data(),
},
});
return struct_datum;
@ -176,28 +192,32 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
let sig = self.tcx.fn_sig(def_id);
// FIXME(chalk): collect into an intermediate SmallVec here since
// we need `TypeFoldable` for `no_bound_vars`
let argument_types: Binder<Vec<_>> =
sig.map_bound(|i| i.inputs().iter().copied().collect());
let argument_types = argument_types
.no_bound_vars()
.expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
let inputs_and_output = sig.inputs_and_output();
let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars(
&self.interner,
self.tcx,
&inputs_and_output,
);
let argument_types = inputs_and_output[..inputs_and_output.len() - 1]
.iter()
.map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner))
.collect();
let return_type = sig
.output()
.no_bound_vars()
.expect("FIXME(chalk): late-bound fn parameters not supported in chalk")
let return_type = inputs_and_output[inputs_and_output.len() - 1]
.subst(self.tcx, &bound_vars)
.lower_into(&self.interner);
let bound =
chalk_solve::rust_ir::FnDefDatumBound { argument_types, where_clauses, return_type };
let bound = chalk_solve::rust_ir::FnDefDatumBound {
inputs_and_output: chalk_ir::Binders::new(
iobinders,
chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
),
where_clauses,
};
Arc::new(chalk_solve::rust_ir::FnDefDatum {
id: fn_def_id,
abi: sig.abi(),
binders: chalk_ir::Binders::new(binders, bound),
})
}
@ -326,9 +346,16 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
&self,
opaque_ty_id: chalk_ir::OpaqueTyId<RustInterner<'tcx>>,
) -> Arc<chalk_solve::rust_ir::OpaqueTyDatum<RustInterner<'tcx>>> {
// FIXME(chalk): actually lower opaque ty
let bound_vars = bound_vars_for_item(self.tcx, opaque_ty_id.0);
let binders = binders_for(&self.interner, bound_vars);
let predicates = self.tcx.predicates_defined_on(opaque_ty_id.0).predicates;
let where_clauses: Vec<_> = predicates
.iter()
.map(|(wc, _)| wc.subst(self.tcx, &bound_vars))
.filter_map(|wc| LowerInto::<Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>>::lower_into(wc, &self.interner)).collect();
let value = chalk_solve::rust_ir::OpaqueTyDatumBound {
bounds: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), vec![]),
bounds: chalk_ir::Binders::new(binders, where_clauses),
};
Arc::new(chalk_solve::rust_ir::OpaqueTyDatum {
opaque_ty_id,
@ -346,7 +373,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
) -> Option<bool> {
use chalk_ir::TyData::*;
match well_known {
chalk_solve::rust_ir::WellKnownTrait::SizedTrait => match ty {
chalk_solve::rust_ir::WellKnownTrait::Sized => match ty {
Apply(apply) => match apply.name {
chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
ty::AdtKind::Struct | ty::AdtKind::Union => None,
@ -364,8 +391,8 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
| InferenceVar(_, _)
| BoundVar(_) => None,
},
chalk_solve::rust_ir::WellKnownTrait::CopyTrait
| chalk_solve::rust_ir::WellKnownTrait::CloneTrait => match ty {
chalk_solve::rust_ir::WellKnownTrait::Copy
| chalk_solve::rust_ir::WellKnownTrait::Clone => match ty {
Apply(apply) => match apply.name {
chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() {
ty::AdtKind::Struct | ty::AdtKind::Union => None,
@ -383,7 +410,11 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
| InferenceVar(_, _)
| BoundVar(_) => None,
},
chalk_solve::rust_ir::WellKnownTrait::DropTrait => None,
chalk_solve::rust_ir::WellKnownTrait::Drop => None,
chalk_solve::rust_ir::WellKnownTrait::Fn => None,
chalk_solve::rust_ir::WellKnownTrait::FnMut => None,
chalk_solve::rust_ir::WellKnownTrait::FnOnce => None,
chalk_solve::rust_ir::WellKnownTrait::Unsize => None,
}
}
@ -399,17 +430,17 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
well_known_trait: chalk_solve::rust_ir::WellKnownTrait,
) -> Option<chalk_ir::TraitId<RustInterner<'tcx>>> {
use chalk_solve::rust_ir::WellKnownTrait::*;
let t = match well_known_trait {
SizedTrait => {
self.tcx.lang_items().sized_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
}
CopyTrait => self.tcx.lang_items().copy_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
CloneTrait => {
self.tcx.lang_items().clone_trait().map(|t| chalk_ir::TraitId(t)).unwrap()
}
DropTrait => self.tcx.lang_items().drop_trait().map(|t| chalk_ir::TraitId(t)).unwrap(),
let def_id = match well_known_trait {
Sized => self.tcx.lang_items().sized_trait(),
Copy => self.tcx.lang_items().copy_trait(),
Clone => self.tcx.lang_items().clone_trait(),
Drop => self.tcx.lang_items().drop_trait(),
Fn => self.tcx.lang_items().fn_trait(),
FnMut => self.tcx.lang_items().fn_mut_trait(),
FnOnce => self.tcx.lang_items().fn_once_trait(),
Unsize => self.tcx.lang_items().unsize_trait(),
};
Some(t)
def_id.map(|t| chalk_ir::TraitId(t))
}
fn is_object_safe(&self, trait_id: chalk_ir::TraitId<RustInterner<'tcx>>) -> bool {
@ -423,6 +454,87 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
// FIXME(chalk): actually get hidden ty
self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner)
}
fn closure_kind(
&self,
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
) -> chalk_solve::rust_ir::ClosureKind {
let kind = &substs.parameters(&self.interner)[substs.len(&self.interner) - 3];
match kind.assert_ty_ref(&self.interner).data(&self.interner) {
chalk_ir::TyData::Apply(apply) => match apply.name {
chalk_ir::TypeName::Scalar(scalar) => match scalar {
chalk_ir::Scalar::Int(int_ty) => match int_ty {
chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn,
chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut,
chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce,
_ => bug!("bad closure kind"),
},
_ => bug!("bad closure kind"),
},
_ => bug!("bad closure kind"),
},
_ => bug!("bad closure kind"),
}
}
fn closure_inputs_and_output(
&self,
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
) -> chalk_ir::Binders<chalk_solve::rust_ir::FnDefInputsAndOutputDatum<RustInterner<'tcx>>>
{
let sig = &substs.parameters(&self.interner)[substs.len(&self.interner) - 2];
match sig.assert_ty_ref(&self.interner).data(&self.interner) {
chalk_ir::TyData::Function(f) => {
let substitution = f.substitution.parameters(&self.interner);
let return_type =
substitution.last().unwrap().assert_ty_ref(&self.interner).clone();
// Closure arguments are tupled
let argument_tuple = substitution[0].assert_ty_ref(&self.interner);
let argument_types = match argument_tuple.data(&self.interner) {
chalk_ir::TyData::Apply(apply) => match apply.name {
chalk_ir::TypeName::Tuple(_) => apply
.substitution
.iter(&self.interner)
.map(|arg| arg.assert_ty_ref(&self.interner))
.cloned()
.collect(),
_ => bug!("Expecting closure FnSig args to be tupled."),
},
_ => bug!("Expecting closure FnSig args to be tupled."),
};
chalk_ir::Binders::new(
chalk_ir::VariableKinds::from(
&self.interner,
(0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime),
),
chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type },
)
}
_ => panic!("Invalid sig."),
}
}
fn closure_upvars(
&self,
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
) -> chalk_ir::Binders<chalk_ir::Ty<RustInterner<'tcx>>> {
let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs);
let tuple = substs.parameters(&self.interner).last().unwrap().assert_ty_ref(&self.interner);
inputs_and_output.map_ref(|_| tuple.clone())
}
fn closure_fn_substitution(
&self,
_closure_id: chalk_ir::ClosureId<RustInterner<'tcx>>,
substs: &chalk_ir::Substitution<RustInterner<'tcx>>,
) -> chalk_ir::Substitution<RustInterner<'tcx>> {
let substitution = &substs.parameters(&self.interner)[0..substs.len(&self.interner) - 3];
chalk_ir::Substitution::from(&self.interner, substitution)
}
}
/// Creates a `InternalSubsts` that maps each generic parameter to a higher-ranked

View File

@ -43,6 +43,8 @@ use rustc_span::def_id::DefId;
use std::collections::btree_map::{BTreeMap, Entry};
use chalk_ir::fold::shift::Shift;
/// Essentially an `Into` with a `&RustInterner` parameter
crate trait LowerInto<'tcx, T> {
/// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`.
@ -82,7 +84,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
collect_bound_vars(interner, interner.tcx, predicate);
Some(
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
binders,
chalk_ir::ProgramClauseImplication {
consequence: chalk_ir::DomainGoal::FromEnv(
@ -102,7 +104,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
collect_bound_vars(interner, interner.tcx, predicate);
Some(
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
binders,
chalk_ir::ProgramClauseImplication {
consequence: chalk_ir::DomainGoal::Holds(
@ -127,7 +129,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
collect_bound_vars(interner, interner.tcx, predicate);
Some(
chalk_ir::ProgramClauseData::ForAll(chalk_ir::Binders::new(
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
binders,
chalk_ir::ProgramClauseImplication {
consequence: chalk_ir::DomainGoal::Holds(
@ -153,13 +155,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
}
}
ChalkEnvironmentClause::TypeFromEnv(ty) => Some(
chalk_ir::ProgramClauseData::Implies(chalk_ir::ProgramClauseImplication {
consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
ty.lower_into(interner),
)),
conditions: chalk_ir::Goals::new(interner),
priority: chalk_ir::ClausePriority::High,
})
chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
chalk_ir::VariableKinds::new(interner),
chalk_ir::ProgramClauseImplication {
consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(
ty.lower_into(interner).shifted_in(interner),
)),
conditions: chalk_ir::Goals::new(interner),
priority: chalk_ir::ClausePriority::High,
},
))
.intern(interner),
),
});
@ -416,12 +421,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty<RustInterner<'tcx>>> for Ty<'tcx> {
})
.intern(interner)
}
// FIXME(chalk): add region
Dynamic(predicates, _region) => {
TyData::Dyn(chalk_ir::DynTy { bounds: predicates.lower_into(interner) })
.intern(interner)
}
Closure(_def_id, _) => unimplemented!(),
Dynamic(predicates, region) => TyData::Dyn(chalk_ir::DynTy {
bounds: predicates.lower_into(interner),
lifetime: region.lower_into(interner),
})
.intern(interner),
Closure(def_id, substs) => apply(
chalk_ir::TypeName::Closure(chalk_ir::ClosureId(def_id)),
substs.lower_into(interner),
),
Generator(_def_id, _substs, _) => unimplemented!(),
GeneratorWitness(_) => unimplemented!(),
Never => apply(chalk_ir::TypeName::Never, empty()),
@ -624,7 +632,7 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>(
}
(0..parameters.len()).for_each(|i| {
parameters.get(&(i as u32)).expect("Skipped bound var index.");
parameters.get(&(i as u32)).expect(&format!("Skipped bound var index `{:?}`.", i));
});
let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v));

View File

@ -133,6 +133,7 @@ crate fn evaluate_goal<'tcx>(
},
chalk_ir::TypeName::Array => unimplemented!(),
chalk_ir::TypeName::FnDef(_) => unimplemented!(),
chalk_ir::TypeName::Closure(_) => unimplemented!(),
chalk_ir::TypeName::Never => unimplemented!(),
chalk_ir::TypeName::Tuple(_size) => unimplemented!(),
chalk_ir::TypeName::Slice => unimplemented!(),

View File

@ -0,0 +1,39 @@
// check-fail
// compile-flags: -Z chalk
fn main() -> () {
let t = || {};
t();
let mut a = 0;
let mut b = move || {
a = 1;
};
b();
let mut c = b;
c();
b();
let mut a = 0;
let mut b = || {
a = 1;
};
b();
let mut c = b;
c();
b(); //~ ERROR
// FIXME(chalk): this doesn't quite work
/*
let b = |c| {
c
};
let a = &32;
b(a);
*/
}

View File

@ -0,0 +1,18 @@
error[E0382]: borrow of moved value: `b`
--> $DIR/closure.rs:28:5
|
LL | let mut c = b;
| - value moved here
...
LL | b();
| ^ value borrowed here after move
|
note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment
--> $DIR/closure.rs:21:9
|
LL | a = 1;
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.

View File

@ -23,15 +23,10 @@ impl<T> Bar for Option<T> {
type Item = Option<T>;
}
// FIXME(chalk): the ordering of these two errors differs between CI and local
// We need to figure out why its non-deterministic
/*
impl Bar for f32 {
//^ ERROR the trait bound `f32: Foo` is not satisfied
type Item = f32;
//^ ERROR the trait bound `f32: Foo` is not satisfied
//~^ ERROR the trait bound `f32: Foo` is not satisfied
}
*/
trait Baz<U: ?Sized> where U: Foo { }

View File

@ -11,7 +11,18 @@ LL | impl Foo for str { }
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:40:6
--> $DIR/impl_wf.rs:27:17
|
LL | trait Bar {
| --- required by a bound in this
LL | type Item: Foo;
| --- required by this bound in `Bar`
...
LL | type Item = f32;
| ^^^ the trait `Foo` is not implemented for `f32`
error[E0277]: the trait bound `f32: Foo` is not satisfied
--> $DIR/impl_wf.rs:35:6
|
LL | trait Baz<U: ?Sized> where U: Foo { }
| --- required by this bound in `Baz`
@ -19,6 +30,6 @@ LL | trait Baz<U: ?Sized> where U: Foo { }
LL | impl Baz<f32> for f32 { }
| ^^^^^^^^ the trait `Foo` is not implemented for `f32`
error: aborting due to 2 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -1,7 +1,5 @@
// run-pass
// compile-flags: -Z chalk
// FIXME(chalk): remove when uncommented
#![allow(dead_code, unused_variables)]
trait Foo { }
@ -11,8 +9,6 @@ struct S<T: Foo> {
x: T,
}
// FIXME(chalk): need late-bound regions on FnDefs
/*
fn only_foo<T: Foo>(_x: &T) { }
impl<T> S<T> {
@ -21,7 +17,6 @@ impl<T> S<T> {
only_foo(&self.x)
}
}
*/
trait Bar { }
impl Bar for u32 { }
@ -31,16 +26,10 @@ fn only_bar<T: Bar>() { }
impl<T> S<T> {
// Test that the environment of `dummy_bar` adds up with the environment
// of the inherent impl.
// FIXME(chalk): need late-bound regions on FnDefs
/*
fn dummy_bar<U: Bar>(&self) {
only_foo(&self.x);
only_bar::<U>();
}
*/
fn dummy_bar<U: Bar>() {
only_bar::<U>();
}
}
fn main() {
@ -48,10 +37,6 @@ fn main() {
x: 5,
};
// FIXME(chalk): need late-bound regions on FnDefs
/*
s.dummy_foo();
s.dummy_bar::<u32>();
*/
S::<i32>::dummy_bar::<u32>();
s.dummy_foo();
}

View File

@ -1,5 +1,5 @@
// FIXME(chalk): should fail, see comments
// check-pass
// check-fail
// compile-flags: -Z chalk
#![feature(trivial_bounds)]
@ -10,7 +10,6 @@ trait Bar {
trait Foo: Bar { }
struct S where S: Foo;
//~^ WARN Trait bound S: Foo does not depend on any type or lifetime parameters
impl Foo for S {
}
@ -26,10 +25,6 @@ fn foo<T: Foo>() {
fn main() {
// For some reason, the error is duplicated...
// FIXME(chalk): this order of this duplicate error seems non-determistic
// and causes test to fail
/*
foo::<S>() // ERROR the type `S` is not well-formed (chalk)
//^ ERROR the type `S` is not well-formed (chalk)
*/
foo::<S>() //~ ERROR the type `S` is not well-formed (chalk)
//~^ ERROR the type `S` is not well-formed (chalk)
}

View File

@ -1,10 +1,14 @@
warning: Trait bound S: Foo does not depend on any type or lifetime parameters
--> $DIR/recursive_where_clause_on_type.rs:12:19
error: the type `S` is not well-formed (chalk)
--> $DIR/recursive_where_clause_on_type.rs:28:11
|
LL | struct S where S: Foo;
| ^^^
LL | foo::<S>()
| ^
error: the type `S` is not well-formed (chalk)
--> $DIR/recursive_where_clause_on_type.rs:28:5
|
= note: `#[warn(trivial_bounds)]` on by default
LL | foo::<S>()
| ^^^^^^^^
warning: 1 warning emitted
error: aborting due to 2 previous errors