Hone logo
Hone
Problems

Implementing Compile-Time Function Evaluation (CTFE) in Rust

This challenge focuses on understanding and implementing the core concepts behind Rust's Compile-Time Function Evaluation (CTFE). CTFE allows certain computations to be performed during compilation, enabling performance optimizations, static assertions, and the creation of complex compile-time data structures. You will build a simplified version of a CTFE engine that can evaluate a subset of Rust-like expressions at compile time.

Problem Description

Your task is to create a simplified CTFE engine that can evaluate a specific subset of arithmetic and logical expressions at compile time. This engine should be able to process expressions represented as Abstract Syntax Trees (ASTs) and produce their evaluated results, also at compile time.

Key Requirements:

  1. AST Representation: You'll need to define an Abstract Syntax Tree (AST) structure that can represent the supported operations and operands.
  2. Evaluation Function: Implement a function that takes an AST node and evaluates it at compile time.
  3. Supported Operations: The engine must support:
    • Integer literals.
    • Basic arithmetic operations: +, -, *, / (integer division).
    • Boolean literals (true, false).
    • Logical operations: && (AND), || (OR).
    • Comparison operations: ==, !=, <, >, <=, >=.
    • Conditional expressions (if/else).
  4. Compile-Time Execution: The evaluation must occur entirely during Rust's compilation phase. This means the result of the evaluation should be a compile-time constant.
  5. Error Handling: Implement basic error handling for invalid operations, type mismatches (within the scope of this simplified engine), and division by zero. These errors should be reported at compile time.

Expected Behavior:

Given an AST representing an expression, your evaluation function, when called within a const context, should produce the correct constant value. For example, if you have an AST for (2 + 3) * 4, the CTFE engine should resolve this to 20.

Important Edge Cases:

  • Division by zero.
  • Type compatibility for operations (e.g., attempting to add an integer to a boolean).
  • Short-circuiting behavior for logical AND (&&) and OR (||).

Examples

Example 1: Simple Arithmetic

// AST representing: (10 + 5) * 2
let expression_ast = ...; // AST node for (10 + 5) * 2

// In a const context:
const RESULT: i32 = evaluate_ctfe(expression_ast);

// Expected Output (during compilation):
// RESULT will be 30

Explanation: The CTFE engine evaluates 10 + 5 to 15, then 15 * 2 to 30.

Example 2: Logical and Comparison Operations

// AST representing: (5 > 3) && (10 == 10)
let expression_ast_logical = ...; // AST node for (5 > 3) && (10 == 10)

// In a const context:
const RESULT_LOGICAL: bool = evaluate_ctfe(expression_ast_logical);

// Expected Output (during compilation):
// RESULT_LOGICAL will be true

Explanation: 5 > 3 evaluates to true, 10 == 10 evaluates to true. true && true evaluates to true.

Example 3: Conditional Expression

// AST representing: if (7 < 4) { 100 } else { 200 }
let expression_ast_conditional = ...; // AST node for if (7 < 4) { 100 } else { 200 }

// In a const context:
const RESULT_CONDITIONAL: i32 = evaluate_ctfe(expression_ast_conditional);

// Expected Output (during compilation):
// RESULT_CONDITIONAL will be 200

Explanation: 7 < 4 evaluates to false, so the else branch is taken, resulting in 200.

Example 4: Division by Zero Error

// AST representing: 10 / 0
let expression_ast_div_zero = ...; // AST node for 10 / 0

// In a const context:
// This should cause a compile-time error.
// const RESULT_DIV_ZERO: i32 = evaluate_ctfe(expression_ast_div_zero);

Explanation: Attempting to divide by zero should trigger a compile-time error, preventing the program from compiling.

Constraints

  • The AST will represent expressions involving signed 32-bit integers (i32) and booleans (bool).
  • All literals will be valid i32 or bool values.
  • The depth of any expression tree will not exceed 50 nodes.
  • The CTFE engine must be implemented using Rust's const fn capabilities wherever possible to ensure compile-time evaluation.
  • For error handling, you can use panic! within const fn to signal compile-time errors.

Notes

  • This challenge is a simplified model. Real CTFE in Rust is significantly more complex, involving a dedicated interpreter and optimizations.
  • You'll need to design your AST nodes carefully to represent the different types of expressions.
  • Consider how to represent different data types within your AST and evaluation logic.
  • The key to achieving compile-time evaluation is to ensure all functions and data used are marked with const and that the evaluation logic itself can be performed within a const context.
  • Think about recursion for traversing the AST.
  • Short-circuiting in && and || is crucial for efficiency and correctness. For example, if the left side of && is false, the right side should not be evaluated.
Loading editor...
rust