|
1 | 1 | use std::iter::zip; |
2 | 2 |
|
3 | | -use formality_core::{Fallible, Map, Upcast}; |
4 | | -use formality_prove::Env; |
| 3 | +use formality_core::{judgment_fn, Fallible, Map, Upcast}; |
| 4 | +use formality_prove::{prove_normalize, Constraints, Decls, Env}; |
5 | 5 | use formality_rust::grammar::minirust::ArgumentExpression::{ByValue, InPlace}; |
6 | 6 | use formality_rust::grammar::minirust::PlaceExpression::Local; |
7 | 7 | use formality_rust::grammar::minirust::ValueExpression::{Constant, Fn, Load}; |
8 | 8 | use formality_rust::grammar::minirust::{ |
9 | 9 | self, ArgumentExpression, BasicBlock, BbId, LocalId, PlaceExpression, ValueExpression, |
10 | 10 | }; |
11 | 11 | use formality_rust::grammar::FnBoundData; |
12 | | -use formality_types::grammar::{CrateId, FnId}; |
| 12 | +use formality_types::grammar::{CrateId, FnId, Parameter, RigidName, RigidTy}; |
13 | 13 | use formality_types::grammar::{Relation, Ty, Wcs}; |
14 | 14 |
|
15 | 15 | use crate::{Check, CrateItem}; |
@@ -228,7 +228,7 @@ impl Check<'_> { |
228 | 228 | // Check if the value is well-formed. |
229 | 229 | let value_ty = self.check_value(typeck_env, switch_value).unwrap(); |
230 | 230 |
|
231 | | - self.prove_goal(&typeck_env.env, Wcs::default(), value_ty.is_int())?; |
| 231 | + self.prove_judgment(&typeck_env.env, &fn_assumptions, value_ty, ty_is_int)?; |
232 | 232 |
|
233 | 233 | // Ensure all bbid are valid. |
234 | 234 | for switch_target in switch_targets { |
@@ -371,3 +371,34 @@ struct TypeckEnv { |
371 | 371 | /// declared in the current crate. |
372 | 372 | crate_id: CrateId, |
373 | 373 | } |
| 374 | + |
| 375 | +judgment_fn! { |
| 376 | + fn ty_is_int( |
| 377 | + _decls: Decls, |
| 378 | + env: Env, |
| 379 | + assumptions: Wcs, |
| 380 | + ty: Parameter, |
| 381 | + ) => Constraints { |
| 382 | + debug(assumptions, ty, env) |
| 383 | + // If the type that we are currently checking is rigid, check if it is an int. |
| 384 | + // If the type can be normalized, normalize until rigid then check if it is an int. |
| 385 | + // For the rest of the case, it should fail. |
| 386 | + |
| 387 | + ( |
| 388 | + (prove_normalize(&decl, &env, &assumptions, ty) => (c1, p)) |
| 389 | + (let assumptions = c1.substitution().apply(&assumptions)) |
| 390 | + (ty_is_int(&decl, &env, assumptions, p) => c2) |
| 391 | + ----------------------------- ("alias_ty is int") |
| 392 | + (ty_is_int(decl, env, assumptions, ty) => c2) |
| 393 | + ) |
| 394 | + |
| 395 | + ( |
| 396 | + (if id.is_int()) |
| 397 | + ----------------------------- ("rigid_ty is int") |
| 398 | + (ty_is_int(_decls, _env, _assumptions, RigidTy {name: RigidName::ScalarId(id), parameters: _}) => Constraints::none(env)) |
| 399 | + ) |
| 400 | + |
| 401 | + } |
| 402 | +} |
| 403 | + |
| 404 | +mod test; |
0 commit comments