Skip to content

Commit c3d52b4

Browse files
committed
add Movability to GeneratorDatum
1 parent 0b05a81 commit c3d52b4

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

chalk-integration/src/lowering.rs

+10
Original file line numberDiff line numberDiff line change
@@ -1236,3 +1236,13 @@ impl Lower for Safety {
12361236
}
12371237
}
12381238
}
1239+
1240+
impl Lower for Movability {
1241+
type Lowered = rust_ir::Movability;
1242+
fn lower(&self) -> Self::Lowered {
1243+
match self {
1244+
Movability::Static => rust_ir::Movability::Static,
1245+
Movability::Movable => rust_ir::Movability::Movable,
1246+
}
1247+
}
1248+
}

chalk-integration/src/lowering/program_lowerer.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,10 @@ impl ProgramLowerer {
453453
Ok(GeneratorWitnessExistential { types: witnesses })
454454
})?;
455455

456-
let generator_datum = GeneratorDatum { input_output };
456+
let generator_datum = GeneratorDatum {
457+
movability: defn.movability.lower(),
458+
input_output,
459+
};
457460
let generator_witness = GeneratorWitnessDatum { inner_types };
458461

459462
let id = self.generator_ids[&defn.name.str];

chalk-parse/src/ast.rs

+6
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,16 @@ pub struct Variant {
5050
pub name: Identifier,
5151
pub fields: Vec<Field>,
5252
}
53+
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
54+
pub enum Movability {
55+
Static,
56+
Movable,
57+
}
5358

5459
#[derive(Clone, PartialEq, Eq, Debug)]
5560
pub struct GeneratorDefn {
5661
pub name: Identifier,
62+
pub movability: Movability,
5763
pub variable_kinds: Vec<VariableKind>,
5864
pub upvars: Vec<Ty>,
5965
pub resume_ty: Ty,

chalk-parse/src/parser.lalrpop

+7-1
Original file line numberDiff line numberDiff line change
@@ -192,13 +192,19 @@ FnDefn: FnDefn = {
192192
}
193193
};
194194

195+
Movability: Movability = {
196+
"static" => Movability::Static,
197+
=> Movability::Movable
198+
}
199+
195200
GeneratorDefn: GeneratorDefn = {
196-
"generator" <n:Id> <p:Angle<VariableKind>> "[" "resume" "=" <resume:Ty> "," "yield" "=" <yield_ty:Ty> "]" <ret_ty:FnReturn?>
201+
"generator" <m:Movability> <n:Id> <p:Angle<VariableKind>> "[" "resume" "=" <resume:Ty> "," "yield" "=" <yield_ty:Ty> "]" <ret_ty:FnReturn?>
197202
"{"
198203
"upvars" "[" <upvars:SemiColon<Ty>> "]"
199204
"witnesses" <l:ExistsLifetimes?> "[" <witnesses:SemiColon<Ty>> "]"
200205
"}" => GeneratorDefn {
201206
name: n,
207+
movability: m,
202208
variable_kinds: p,
203209
upvars: upvars,
204210
witness_lifetimes: l.unwrap_or_default(),

chalk-solve/src/clauses.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use self::builder::ClauseBuilder;
22
use self::env_elaborator::elaborate_env_clauses;
33
use self::program_clauses::ToProgramClauses;
44
use crate::goal_builder::GoalBuilder;
5+
use crate::rust_ir::{Movability, WellKnownTrait};
56
use crate::split::Split;
67
use crate::RustIrDatabase;
78
use chalk_ir::cast::{Cast, Caster};
@@ -149,12 +150,7 @@ pub fn push_auto_trait_impls<I: Interner>(
149150
match ty {
150151
// function-types implement auto traits unconditionally
151152
TyKind::Function(_) => {
152-
let auto_trait_ref = TraitRef {
153-
trait_id: auto_trait_id,
154-
substitution: Substitution::from1(interner, ty.clone().intern(interner)),
155-
};
156-
157-
builder.push_fact(auto_trait_ref);
153+
builder.push_fact(consequence);
158154
Ok(())
159155
}
160156
TyKind::InferenceVar(_, _) | TyKind::BoundVar(_) => Err(Floundered),
@@ -173,6 +169,21 @@ pub fn push_auto_trait_impls<I: Interner>(
173169
});
174170
Ok(())
175171
}
172+
TyKind::Generator(generator_id, _) => {
173+
if Some(auto_trait_id) == builder.db.well_known_trait_id(WellKnownTrait::Unpin) {
174+
match builder.db.generator_datum(*generator_id).movability {
175+
// immovable generators are never `Unpin`
176+
Movability::Static => (),
177+
// movable generators are always `Unpin`
178+
Movability::Movable => builder.push_fact(consequence),
179+
}
180+
} else {
181+
// if trait is not `Unpin`, use regular auto trait clause
182+
let conditions = constituent_types(builder.db, ty).into_iter().map(mk_ref);
183+
builder.push_clause(consequence, conditions);
184+
}
185+
Ok(())
186+
}
176187

177188
TyKind::GeneratorWitness(generator_id, _) => {
178189
push_auto_trait_impls_generator_witness(builder, auto_trait_id, *generator_id);

chalk-solve/src/rust_ir.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -638,12 +638,23 @@ pub struct OpaqueTyDatumBound<I: Interner> {
638638
pub where_clauses: Binders<Vec<QuantifiedWhereClause<I>>>,
639639
}
640640

641+
// The movability of a generator: whether a generator contains self-references,
642+
// causing it to be !Unpin
643+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
644+
pub enum Movability {
645+
Static,
646+
Movable,
647+
}
648+
chalk_ir::copy_fold!(Movability);
649+
641650
/// Represents a generator type.
642651
#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, HasInterner)]
643652
pub struct GeneratorDatum<I: Interner> {
653+
// Can the generator be moved (is Unpin or not)
654+
pub movability: Movability,
644655
/// All of the nested types for this generator. The `Binder`
645656
/// represents the types and lifetimes that this generator is generic over -
646-
/// this behaves in the same way as `AdtDatun.binders`
657+
/// this behaves in the same way as `AdtDatum.binders`
647658
pub input_output: Binders<GeneratorInputOutputDatum<I>>,
648659
}
649660

0 commit comments

Comments
 (0)