Skip to content

Commit 74fc1cc

Browse files
committed
Add the str primitive type
1 parent adec469 commit 74fc1cc

File tree

10 files changed

+54
-7
lines changed

10 files changed

+54
-7
lines changed

chalk-integration/src/lowering.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,6 +1085,7 @@ impl LowerProjectionTy for ProjectionTy {
10851085
}
10861086

10871087
trait LowerTy {
1088+
/// Lower from the AST to Chalk's Rust IR
10881089
fn lower(&self, env: &Env) -> LowerResult<chalk_ir::Ty<ChalkIr>>;
10891090
}
10901091

@@ -1257,6 +1258,12 @@ impl LowerTy for Ty {
12571258
),
12581259
})
12591260
.intern(interner)),
1261+
1262+
Ty::Str => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1263+
name: chalk_ir::TypeName::Str,
1264+
substitution: chalk_ir::Substitution::empty(interner),
1265+
})
1266+
.intern(interner)),
12601267
}
12611268
}
12621269
}

chalk-ir/src/debug.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ impl<I: Interner> Debug for TypeName<I> {
142142
TypeName::Struct(id) => write!(fmt, "{:?}", id),
143143
TypeName::AssociatedType(assoc_ty) => write!(fmt, "{:?}", assoc_ty),
144144
TypeName::Scalar(scalar) => write!(fmt, "{:?}", scalar),
145+
TypeName::Str => write!(fmt, "Str"),
145146
TypeName::Tuple(arity) => write!(fmt, "{:?}", arity),
146147
TypeName::OpaqueType(opaque_ty) => write!(fmt, "!{:?}", opaque_ty),
147148
TypeName::Slice => write!(fmt, "{{slice}}"),

chalk-ir/src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ pub enum TypeName<I: Interner> {
168168
/// a placeholder for opaque types like `impl Trait`
169169
OpaqueType(OpaqueTyId<I>),
170170

171+
/// the string primitive type
172+
Str,
173+
171174
/// This can be used to represent an error, e.g. during name resolution of a type.
172175
/// Chalk itself will not produce this, just pass it through when given.
173176
Error,
@@ -966,7 +969,7 @@ pub enum WhereClause<I: Interner> {
966969

967970
#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)]
968971
pub enum WellFormed<I: Interner> {
969-
/// A predicate which is true is some trait ref is well-formed.
972+
/// A predicate which is true when some trait ref is well-formed.
970973
/// For example, given the following trait definitions:
971974
///
972975
/// ```notrust
@@ -981,7 +984,7 @@ pub enum WellFormed<I: Interner> {
981984
/// ```
982985
Trait(TraitRef<I>),
983986

984-
/// A predicate which is true is some type is well-formed.
987+
/// A predicate which is true when some type is well-formed.
985988
/// For example, given the following type definition:
986989
///
987990
/// ```notrust

chalk-parse/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ pub enum Ty {
206206
lifetime: Lifetime,
207207
ty: Box<Ty>,
208208
},
209+
Str,
209210
}
210211

211212
#[derive(Copy, Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ pub Ty: Ty = {
196196

197197
TyWithoutFor: Ty = {
198198
<ScalarType> => Ty::Scalar { ty: <> },
199+
"str" => Ty::Str,
199200
<n:Id> => Ty::Id { name: n},
200201
"fn" "(" <t:Ty> ")" => Ty::ForAll {
201202
lifetime_names: vec![],

chalk-solve/src/clauses.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ fn match_ty<I: Interner>(
389389
})
390390
}
391391

392+
/// Lower a Rust IR application type to logic
392393
fn match_type_name<I: Interner>(
393394
builder: &mut ClauseBuilder<'_, I>,
394395
interner: &I,
@@ -408,6 +409,7 @@ fn match_type_name<I: Interner>(
408409
TypeName::Scalar(_) => {
409410
builder.push_fact(WellFormed::Ty(application.clone().intern(interner)))
410411
}
412+
TypeName::Str => builder.push_fact(WellFormed::Ty(application.clone().intern(interner))),
411413
TypeName::Tuple(_) => {
412414
builder.push_fact(WellFormed::Ty(application.clone().intern(interner)))
413415
}

tests/test/coherence.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ fn fundamental_traits() {
264264
lowering_error! {
265265
program {
266266
#[upstream] trait Sized { }
267-
#[upstream] struct str { }
267+
#[upstream] struct str2 { } // str is already known to be !Sized, so make a new str type
268268
trait Bar { }
269-
impl Bar for str { }
269+
impl Bar for str2 { }
270270
impl<T> Bar for T where T: Sized { }
271271
} error_msg {
272272
"overlapping impls of trait `Bar`"
@@ -279,9 +279,9 @@ fn fundamental_traits() {
279279
lowering_success! {
280280
program {
281281
#[upstream] #[fundamental] trait Sized { }
282-
#[upstream] struct str { }
282+
#[upstream] struct str2 { }
283283
trait Bar { }
284-
impl Bar for str { }
284+
impl Bar for str2 { }
285285
impl<T> Bar for T where T: Sized { }
286286
}
287287
}

tests/test/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ mod projection;
318318
mod refs;
319319
mod scalars;
320320
mod slices;
321+
mod string;
321322
mod tuples;
322323
mod unify;
323324
mod wf_goals;

tests/test/string.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use super::*;
2+
3+
#[test]
4+
fn str_trait_impl() {
5+
test! {
6+
program {
7+
trait Foo {}
8+
impl Foo for str {}
9+
}
10+
11+
goal { str: Foo } yields { "Unique" }
12+
}
13+
}
14+
15+
#[test]
16+
fn str_is_well_formed() {
17+
test! {
18+
program {}
19+
goal { WellFormed(str) } yields { "Unique" }
20+
}
21+
}
22+
23+
#[test]
24+
fn str_is_not_sized() {
25+
test! {
26+
program {
27+
#[lang(sized)] trait Sized { }
28+
}
29+
30+
goal { not { str: Sized } } yields { "Unique" }
31+
}
32+
}

tests/test/wf_lowering.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,6 @@ fn assoc_type_recursive_bound() {
576576
}
577577

578578
struct Number { }
579-
struct str { } // not sized
580579

581580
impl Foo for Number {
582581
// Well-formedness checks require that the following

0 commit comments

Comments
 (0)