Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

simplify rust-ir #251

Merged
merged 5 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions chalk-parse/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ impl fmt::Display for Kind {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct Impl {
pub parameter_kinds: Vec<ParameterKind>,
pub trait_ref: PolarizedTraitRef,
pub trait_ref: TraitRef,
pub polarity: Polarity,
pub where_clauses: Vec<QuantifiedWhereClause>,
pub assoc_ty_values: Vec<AssocTyValue>,
pub impl_type: ImplType,
Expand Down Expand Up @@ -185,17 +186,20 @@ pub struct TraitRef {
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum PolarizedTraitRef {
Positive(TraitRef),
Negative(TraitRef),
pub enum Polarity {
/// `impl Foo for Bar`
Positive,

/// `impl !Foo for Bar`
Negative,
}

impl PolarizedTraitRef {
pub fn from_bool(polarity: bool, trait_ref: TraitRef) -> PolarizedTraitRef {
impl Polarity {
pub fn from_bool(polarity: bool) -> Polarity {
if polarity {
PolarizedTraitRef::Positive(trait_ref)
Polarity::Positive
} else {
PolarizedTraitRef::Negative(trait_ref)
Polarity::Negative
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions chalk-parse/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ Impl: Impl = {
args.extend(a);
Impl {
parameter_kinds: p,
trait_ref: PolarizedTraitRef::from_bool(mark.is_none(), TraitRef {
polarity: Polarity::from_bool(mark.is_none()),
trait_ref: TraitRef {
trait_name: t,
args: args,
}),
},
where_clauses: w,
assoc_ty_values: assoc,
impl_type: external.map(|_| ImplType::External).unwrap_or(ImplType::Local),
Expand Down
50 changes: 22 additions & 28 deletions chalk-rust-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,26 @@ pub enum LangItem {}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImplDatum {
pub polarity: Polarity,
pub binders: Binders<ImplDatumBound>,
pub impl_type: ImplType,
}

impl ImplDatum {
pub fn is_positive(&self) -> bool {
match self.binders.value.trait_ref {
PolarizedTraitRef::Positive(_) => true,
PolarizedTraitRef::Negative(_) => false,
}
self.polarity.is_positive()
}

pub fn trait_id(&self) -> TraitId {
self.binders.value.trait_ref.trait_id
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImplDatumBound {
pub trait_ref: PolarizedTraitRef,
pub trait_ref: TraitRef,
pub where_clauses: Vec<QuantifiedWhereClause>,
pub associated_ty_values: Vec<AssociatedTyValue>,
pub impl_type: ImplType,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -77,15 +79,20 @@ pub struct StructFlags {
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct TraitDatum {
pub binders: Binders<TraitDatumBound>,

/// "Flags" indicate special kinds of traits, like auto traits.
/// In Rust syntax these are represented in different ways, but in
/// chalk we add annotations like `#[auto]`.
pub flags: TraitFlags,
}

impl TraitDatum {
pub fn is_auto_trait(&self) -> bool {
self.binders.value.flags.auto
self.flags.auto
}

pub fn is_non_enumerable_trait(&self) -> bool {
self.binders.value.flags.non_enumerable
self.flags.non_enumerable
}
}

Expand All @@ -110,11 +117,6 @@ pub struct TraitDatumBound {
/// ```
pub where_clauses: Vec<QuantifiedWhereClause>,

/// "Flags" indicate special kinds of traits, like auto traits.
/// In Rust syntax these are represented in different ways, but in
/// chalk we add annotations like `#[auto]`.
pub flags: TraitFlags,

/// The id of each associated type defined in the trait.
pub associated_ty_ids: Vec<TypeId>,
}
Expand Down Expand Up @@ -400,25 +402,17 @@ pub enum TypeSort {
Trait,
}

#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub enum PolarizedTraitRef {
Positive(TraitRef),
Negative(TraitRef),
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub enum Polarity {
Positive,
Negative,
}

enum_fold!(PolarizedTraitRef[] { Positive(a), Negative(a) });

impl PolarizedTraitRef {
impl Polarity {
pub fn is_positive(&self) -> bool {
match *self {
PolarizedTraitRef::Positive(_) => true,
PolarizedTraitRef::Negative(_) => false,
}
}

pub fn trait_ref(&self) -> &TraitRef {
match *self {
PolarizedTraitRef::Positive(ref tr) | PolarizedTraitRef::Negative(ref tr) => tr,
Polarity::Positive => true,
Polarity::Negative => false,
}
}
}
7 changes: 3 additions & 4 deletions chalk-solve/src/clauses/program_clauses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ impl ToProgramClauses for ImplDatum {
clauses.push(
self.binders
.map_ref(|bound| ProgramClauseImplication {
consequence: bound.trait_ref.trait_ref().clone().cast(),
consequence: bound.trait_ref.clone().cast(),
conditions: bound.where_clauses.iter().cloned().casted().collect(),
})
.cast(),
Expand Down Expand Up @@ -94,7 +94,6 @@ impl ToProgramClauses for AssociatedTyValue {
.binders
.value
.trait_ref
.trait_ref()
.shifted_in(self.value.len());

let all_parameters: Vec<_> = self
Expand Down Expand Up @@ -519,7 +518,7 @@ impl ToProgramClauses for TraitDatum {
impl_may_exist
}));

if !self.binders.value.flags.upstream {
if !self.flags.upstream {
let impl_allowed = self
.binders
.map_ref(|bound_datum| ProgramClauseImplication {
Expand Down Expand Up @@ -549,7 +548,7 @@ impl ToProgramClauses for TraitDatum {

// Fundamental traits can be reasoned about negatively without any ambiguity, so no
// need for this rule if the trait is fundamental.
if !self.binders.value.flags.fundamental {
if !self.flags.fundamental {
let impl_may_exist = self
.binders
.map_ref(|bound_datum| ProgramClauseImplication {
Expand Down
4 changes: 2 additions & 2 deletions chalk-solve/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn perform_orphan_check(
.binders
.map_ref(|bound_impl| {
// Ignoring the polarization of the impl's polarized trait ref
DomainGoal::LocalImplAllowed(bound_impl.trait_ref.trait_ref().clone())
DomainGoal::LocalImplAllowed(bound_impl.trait_ref.clone())
})
.cast();

Expand All @@ -38,7 +38,7 @@ pub fn perform_orphan_check(
debug!("overlaps = {:?}", is_allowed);

if !is_allowed {
let trait_id = impl_datum.binders.value.trait_ref.trait_ref().trait_id;
let trait_id = impl_datum.trait_id();
let trait_name = db.type_name(trait_id.into());
Err(CoherenceError::FailedOrphanCheck(trait_name))?;
}
Expand Down
12 changes: 4 additions & 8 deletions chalk-solve/src/coherence/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ where
) -> Result<(), CoherenceError> {
// Ignore impls for marker traits as they are allowed to overlap.
let trait_datum = self.db.trait_datum(self.trait_id);
if trait_datum.binders.value.flags.marker {
if trait_datum.flags.marker {
return Ok(());
}

Expand All @@ -29,9 +29,7 @@ where
let rhs = &self.db.impl_datum(r_id);

// Two negative impls never overlap.
if !lhs.binders.value.trait_ref.is_positive()
&& !rhs.binders.value.trait_ref.is_positive()
{
if !lhs.is_positive() && !rhs.is_positive() {
continue;
}

Expand Down Expand Up @@ -171,9 +169,7 @@ where
);

// Negative impls cannot specialize.
if !less_special.binders.value.trait_ref.is_positive()
|| !more_special.binders.value.trait_ref.is_positive()
{
if !less_special.is_positive() || !more_special.is_positive() {
return false;
}

Expand Down Expand Up @@ -228,5 +224,5 @@ where
}

fn params(impl_datum: &ImplDatum) -> &[Parameter] {
&impl_datum.binders.value.trait_ref.trait_ref().parameters
&impl_datum.binders.value.trait_ref.parameters
}
10 changes: 5 additions & 5 deletions chalk-solve/src/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,9 @@ where
pub fn verify_trait_impl(&self, impl_id: ImplId) -> Result<(), WfError> {
let impl_datum = self.db.impl_datum(impl_id);

let trait_ref = match impl_datum.binders.value.trait_ref {
PolarizedTraitRef::Positive(ref trait_ref) => trait_ref,
_ => return Ok(()),
};
if !impl_datum.is_positive() {
return Ok(());
}

// We retrieve all the input types of the where clauses appearing on the trait impl,
// e.g. in:
Expand Down Expand Up @@ -214,6 +213,7 @@ where
// }
// ```
let mut header_input_types = Vec::new();
let trait_ref = &impl_datum.binders.value.trait_ref;
trait_ref.fold(&mut header_input_types);

// Associated type values are special because they can be parametric (independently of
Expand Down Expand Up @@ -338,7 +338,7 @@ where
if is_legal {
Ok(())
} else {
let trait_ref = impl_datum.binders.value.trait_ref.trait_ref();
let trait_ref = &impl_datum.binders.value.trait_ref;
let name = self.db.type_name(trait_ref.trait_id.into());
Err(WfError::IllFormedTraitImpl(name))
}
Expand Down
8 changes: 3 additions & 5 deletions src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl RustIrDatabase for ChalkDatabase {
.impl_data
.iter()
.filter(|(_, impl_datum)| {
let trait_ref = impl_datum.binders.value.trait_ref.trait_ref();
let trait_ref = &impl_datum.binders.value.trait_ref;
trait_id == trait_ref.trait_id && {
assert_eq!(trait_ref.parameters.len(), parameters.len());
<[_] as CouldMatch<[_]>>::could_match(&parameters, &trait_ref.parameters)
Expand All @@ -109,9 +109,7 @@ impl RustIrDatabase for ChalkDatabase {
.impl_data
.iter()
.filter(|(_, impl_datum)| {
let impl_trait_id = impl_datum.binders.value.trait_ref.trait_ref().trait_id;
let impl_type = impl_datum.binders.value.impl_type;
impl_trait_id == trait_id && impl_type == ImplType::Local
impl_datum.trait_id() == trait_id && impl_datum.impl_type == ImplType::Local
})
.map(|(&impl_id, _)| impl_id)
.collect()
Expand All @@ -126,7 +124,7 @@ impl RustIrDatabase for ChalkDatabase {
.impl_data
.values()
.any(|impl_datum| {
let impl_trait_ref = impl_datum.binders.value.trait_ref.trait_ref();
let impl_trait_ref = &impl_datum.binders.value.trait_ref;
impl_trait_ref.trait_id == auto_trait_id
&& match impl_trait_ref.parameters[0].assert_ty_ref() {
Ty::Apply(apply) => match apply.name {
Expand Down
Loading