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

Implement unsafe trait support (continued) #155

Merged
merged 11 commits into from
Nov 12, 2023
14 changes: 6 additions & 8 deletions crates/formality-check/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ use formality_types::{
};

impl super::Check<'_> {
#[context("check_trait_impl({v:?})")]
pub(super) fn check_trait_impl(&self, v: &TraitImpl) -> Fallible<()> {
let TraitImpl { binder, safety } = v;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JFYI I use struct patterns a lot as a deliberate style choice -- I want compilation errors when/if add'l fields are added to the struct -- but in this case it doesn't seem very critical.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's more for the result when opening binder

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense. I would add this back in this PR but it's already merged :) I'll open another PR.

Copy link
Member Author

@lqd lqd Nov 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if it's not critical per se, I've re-introduced it in #156 here for consistency and easier evolvability, as well as to the negative impl counterpart.


#[context("check_trait_impl({trait_impl:?})")]
pub(super) fn check_trait_impl(&self, trait_impl: &TraitImpl) -> Fallible<()> {
let mut env = Env::default();

let TraitImplBoundData {
Expand All @@ -29,7 +27,7 @@ impl super::Check<'_> {
trait_parameters,
where_clauses,
impl_items,
} = env.instantiate_universally(binder);
} = env.instantiate_universally(&trait_impl.binder);

let trait_ref = trait_id.with(self_ty, trait_parameters);

Expand All @@ -45,7 +43,7 @@ impl super::Check<'_> {
trait_items,
} = trait_decl.binder.instantiate_with(&trait_ref.parameters)?;

self.check_safety_matches(&trait_decl, safety)?;
self.check_safety_matches(&trait_decl, &trait_impl)?;

for impl_item in &impl_items {
self.check_trait_impl_item(&env, &where_clauses, &trait_items, impl_item)?;
Expand Down Expand Up @@ -74,8 +72,8 @@ impl super::Check<'_> {
}

/// Validate that the declared safety of an impl matches the one from the trait declaration.
fn check_safety_matches(&self, trait_decl: &Trait, trait_impl: &Safety) -> Fallible<()> {
if trait_decl.safety != *trait_impl {
fn check_safety_matches(&self, trait_decl: &Trait, trait_impl: &TraitImpl) -> Fallible<()> {
Copy link
Contributor

@nikomatsakis nikomatsakis Nov 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and I like this version of the fn better

if trait_decl.safety != trait_impl.safety {
match trait_decl.safety {
Safety::Safe => bail!("implementing the trait `{:?}` is not unsafe", trait_decl.id),
Safety::Unsafe => bail!(
Expand Down