From a1127d92d814aa72e132186f21c5584645f72ac0 Mon Sep 17 00:00:00 2001 From: memoryleak47 Date: Sun, 6 Sep 2020 12:29:58 +0200 Subject: [PATCH] Add WellKnownTrait::Unpin --- chalk-integration/src/lowering.rs | 1 + chalk-parse/src/ast.rs | 1 + chalk-parse/src/parser.lalrpop | 1 + chalk-solve/src/clauses/builtin_traits.rs | 4 ++ chalk-solve/src/display/items.rs | 1 + chalk-solve/src/rust_ir.rs | 1 + chalk-solve/src/wf.rs | 5 +- tests/test/mod.rs | 1 + tests/test/unpin.rs | 86 +++++++++++++++++++++++ 9 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 tests/test/unpin.rs diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index c803ee5ee97..d8a15ab2db7 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -2124,6 +2124,7 @@ impl LowerWellKnownTrait for WellKnownTrait { Self::FnMut => rust_ir::WellKnownTrait::FnMut, Self::Fn => rust_ir::WellKnownTrait::Fn, Self::Unsize => rust_ir::WellKnownTrait::Unsize, + Self::Unpin => rust_ir::WellKnownTrait::Unpin, } } } diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index aee71042791..e83f0b7816b 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -126,6 +126,7 @@ pub enum WellKnownTrait { FnMut, Fn, Unsize, + Unpin, } #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index f24d98b11a3..705846392a5 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -62,6 +62,7 @@ WellKnownTrait: WellKnownTrait = { "#" "[" "lang" "(" "fn_mut" ")" "]" => WellKnownTrait::FnMut, "#" "[" "lang" "(" "fn" ")" "]" => WellKnownTrait::Fn, "#" "[" "lang" "(" "unsize" ")" "]" => WellKnownTrait::Unsize, + "#" "[" "lang" "(" "unpin" ")" "]" => WellKnownTrait::Unpin, }; AdtRepr: Atom = "#" "[" "repr" "(" ")" "]" => name.str; diff --git a/chalk-solve/src/clauses/builtin_traits.rs b/chalk-solve/src/clauses/builtin_traits.rs index d21a4b602b6..9a50e5f29f8 100644 --- a/chalk-solve/src/clauses/builtin_traits.rs +++ b/chalk-solve/src/clauses/builtin_traits.rs @@ -41,8 +41,12 @@ pub fn add_builtin_program_clauses( WellKnownTrait::Unsize => { unsize::add_unsize_program_clauses(db, builder, &trait_ref, ty) } + // Drop impls are provided explicitly WellKnownTrait::Drop => (), + + // There are no special rules for Unpin + WellKnownTrait::Unpin => (), } Ok(()) }) diff --git a/chalk-solve/src/display/items.rs b/chalk-solve/src/display/items.rs index 13da1a01b28..585c4eab467 100644 --- a/chalk-solve/src/display/items.rs +++ b/chalk-solve/src/display/items.rs @@ -193,6 +193,7 @@ impl RenderAsRust for TraitDatum { WellKnownTrait::FnMut => "fn_mut", WellKnownTrait::Fn => "fn", WellKnownTrait::Unsize => "unsize", + WellKnownTrait::Unpin => "unpin", }; writeln!(f, "#[lang({})]", name)?; } diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index b87d1a8270c..ec300d1721a 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -269,6 +269,7 @@ pub enum WellKnownTrait { FnMut, Fn, Unsize, + Unpin, } chalk_ir::const_visit!(WellKnownTrait); diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index bd2179e9539..80912736ed5 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -562,7 +562,8 @@ impl WfWellKnownGoals { | WellKnownTrait::FnOnce | WellKnownTrait::FnMut | WellKnownTrait::Fn - | WellKnownTrait::Unsize => None, + | WellKnownTrait::Unsize + | WellKnownTrait::Unpin => None, } } @@ -577,7 +578,7 @@ impl WfWellKnownGoals { match db.trait_datum(impl_datum.trait_id()).well_known? { WellKnownTrait::Drop => Self::drop_impl_constraint(db, impl_datum), - WellKnownTrait::Copy | WellKnownTrait::Clone => None, + WellKnownTrait::Copy | WellKnownTrait::Clone | WellKnownTrait::Unpin => None, // You can't add a manual implementation for following traits: WellKnownTrait::Sized | WellKnownTrait::FnOnce diff --git a/tests/test/mod.rs b/tests/test/mod.rs index b25dd98fea0..9930a70ee39 100644 --- a/tests/test/mod.rs +++ b/tests/test/mod.rs @@ -345,5 +345,6 @@ mod slices; mod string; mod tuples; mod unify; +mod unpin; mod unsize; mod wf_goals; diff --git a/tests/test/unpin.rs b/tests/test/unpin.rs new file mode 100644 index 00000000000..cb9347456d8 --- /dev/null +++ b/tests/test/unpin.rs @@ -0,0 +1,86 @@ +//! Tests targeting the Unpin trait + +use super::*; + +#[test] +fn unpin_lowering() { + lowering_success! { + program { + #[auto] #[lang(unpin)] trait Unpin { } + enum A { Variant } + struct B { } + impl !Unpin for A {} + impl Unpin for B {} + } + } +} + +#[test] +fn unpin_auto_trait() { + test! { + program { + #[auto] #[lang(unpin)] trait Unpin { } + struct A { } + } + + goal { + A: Unpin + } yields { + "Unique" + } + } +} + +#[test] +fn unpin_negative() { + test! { + program { + #[auto] #[lang(unpin)] trait Unpin { } + struct A { } + impl !Unpin for A {} + } + + goal { + A: Unpin + } yields { + "No possible solution" + } + } +} + +#[test] +fn unpin_inherit_negative() { + test! { + program { + #[auto] #[lang(unpin)] trait Unpin { } + struct A { } + impl !Unpin for A {} + struct B { a: A } + } + + goal { + B: Unpin + } yields { + "No possible solution" + } + } +} + +#[test] +fn unpin_overwrite() { + test! { + program { + #[auto] #[lang(unpin)] trait Unpin { } + struct A { } + impl !Unpin for A {} + struct B { a: A } + impl Unpin for B {} + } + + goal { + B: Unpin + } yields { + "Unique" + } + } +}