Skip to content

Commit 3118532

Browse files
committed
Extend parser and IR to support impl/dyn Trait
1 parent df09cc6 commit 3118532

File tree

7 files changed

+57
-1
lines changed

7 files changed

+57
-1
lines changed

chalk-ir/src/debug.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ impl Debug for Ty {
8585
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
8686
match self {
8787
Ty::BoundVar(depth) => write!(fmt, "^{}", depth),
88+
Ty::Dyn(clauses) => write!(fmt, "{:?}", clauses),
89+
Ty::Opaque(clauses) => write!(fmt, "{:?}", clauses),
8890
Ty::InferenceVar(var) => write!(fmt, "{:?}", var),
8991
Ty::Apply(apply) => write!(fmt, "{:?}", apply),
9092
Ty::Projection(proj) => write!(fmt, "{:?}", proj),

chalk-ir/src/fold.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,8 @@ pub fn super_fold_ty(folder: &mut dyn Folder, ty: &Ty, binders: usize) -> Fallib
341341
Ok(Ty::BoundVar(depth))
342342
}
343343
}
344+
Ty::Dyn(ref clauses) => Ok(Ty::Dyn(clauses.fold_with(folder, binders)?)),
345+
Ty::Opaque(ref clauses) => Ok(Ty::Opaque(clauses.fold_with(folder, binders)?)),
344346
Ty::InferenceVar(var) => folder.fold_inference_ty(var, binders),
345347
Ty::Apply(ref apply) => {
346348
let ApplicationTy {

chalk-ir/src/lib.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,19 @@ pub enum Ty {
235235
/// an empty list).
236236
Apply(ApplicationTy),
237237

238+
/// A "dyn" type is a trait object type created via the "dyn Trait" syntax.
239+
/// In the chalk parser, the traits that the object represents is parsed as
240+
/// a QuantifiedInlineBound, and is then changed to a list of where clauses
241+
/// during lowering.
242+
Dyn(Binders<Vec<QuantifiedWhereClause>>),
243+
244+
/// An "opaque" type is one that is created via the "impl Trait" syntax.
245+
/// They are named so because the concrete type implementing the trait
246+
/// is unknown, and hence the type is opaque to us. The only information
247+
/// that we know of is that this type implements the traits listed by the
248+
/// user.
249+
Opaque(Binders<Vec<QuantifiedWhereClause>>),
250+
238251
/// A "projection" type corresponds to an (unnormalized)
239252
/// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
240253
/// trait and all its parameters are fully known.

chalk-parse/src/ast.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ pub enum Ty {
153153
Id {
154154
name: Identifier,
155155
},
156+
Dyn {
157+
bounds: Vec<QuantifiedInlineBound>,
158+
},
159+
Opaque {
160+
bounds: Vec<QuantifiedInlineBound>,
161+
},
156162
Apply {
157163
name: Identifier,
158164
args: Vec<Parameter>,

chalk-parse/src/parser.lalrpop

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ pub Ty: Ty = {
171171

172172
TyWithoutFor: Ty = {
173173
<n:Id> => Ty::Id { name: n},
174+
"dyn" <b:Plus<QuantifiedInlineBound>> => Ty::Dyn {
175+
bounds: b,
176+
},
177+
"impl" <b:Plus<QuantifiedInlineBound>> => Ty::Opaque {
178+
bounds: b,
179+
},
174180
<n:Id> "<" <a:Comma<Parameter>> ">" => Ty::Apply { name: n, args: a },
175181
<p:ProjectionTy> => Ty::Projection { proj: p },
176182
"(" <Ty> ")",

chalk-solve/src/solve/slg.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,11 @@ impl MayInvalidate {
447447
}
448448

449449
// For everything else, be conservative here and just say we may invalidate.
450-
(Ty::ForAll(_), _) | (Ty::Apply(_), _) | (Ty::Projection(_), _) => true,
450+
(Ty::ForAll(_), _)
451+
| (Ty::Dyn(_), _)
452+
| (Ty::Opaque(_), _)
453+
| (Ty::Apply(_), _)
454+
| (Ty::Projection(_), _) => true,
451455
}
452456
}
453457

src/lowering.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ enum LifetimeLookup {
6464
}
6565

6666
const SELF: &str = "Self";
67+
const FIXME_SELF: &str = "__FIXME_SELF__";
6768

6869
impl<'k> Env<'k> {
6970
fn lookup(&self, name: Identifier) -> Fallible<NameLookup> {
@@ -857,6 +858,28 @@ impl LowerTy for Ty {
857858
NameLookup::Parameter(d) => Ok(chalk_ir::Ty::BoundVar(d)),
858859
},
859860

861+
Ty::Dyn { bounds } => Ok(chalk_ir::Ty::Dyn(env.in_binders(
862+
// FIXME: Figure out a proper name for this type parameter
863+
Some(chalk_ir::ParameterKind::Ty(intern(FIXME_SELF))),
864+
|env| {
865+
bounds
866+
.lower()?
867+
.flat_map(|qil| qil.into_where_clauses(chalk_ir::Ty::BoundVar(0)))
868+
.collect()
869+
},
870+
))),
871+
872+
Ty::Opaque { bounds } => Ok(chalk_ir::Ty::Opaque(env.in_binders(
873+
// FIXME: Figure out a proper name for this type parameter
874+
Some(chalk_ir::ParameterKind::Ty(intern(FIXME_SELF))),
875+
|env| {
876+
bounds
877+
.lower()?
878+
.flat_map(|qil| qil.into_where_clauses(chalk_ir::Ty::BoundVar(0)))
879+
.collect()
880+
},
881+
))),
882+
860883
Ty::Apply { name, ref args } => {
861884
let id = match env.lookup(name)? {
862885
NameLookup::Type(id) => id,

0 commit comments

Comments
 (0)