1use std::collections::VecDeque;
2use std::ops::{Deref, DerefMut};
3
4use cairo_lang_defs::ids::{
5 EnumId, ExternFunctionId, ExternTypeId, FreeFunctionId, GenericParamId, ImplAliasId, ImplDefId,
6 ImplFunctionId, ImplImplDefId, LocalVarId, MemberId, ParamId, StructId, TraitConstantId,
7 TraitFunctionId, TraitId, TraitImplId, TraitTypeId, VariantId,
8};
9use cairo_lang_diagnostics::{DiagnosticAdded, Maybe};
10use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
11use cairo_lang_utils::{LookupIntern, extract_matches};
12use itertools::zip_eq;
13
14use crate::db::SemanticGroup;
15use crate::expr::inference::canonic::CanonicalTrait;
16use crate::expr::inference::{
17 ConstVar, ImplVar, ImplVarId, ImplVarTraitItemMappings, InferenceId, InferenceVar,
18 LocalConstVarId, LocalImplVarId, LocalTypeVarId, TypeVar,
19};
20use crate::items::constant::{ConstValue, ConstValueId, ImplConstantId};
21use crate::items::functions::{
22 ConcreteFunctionWithBody, ConcreteFunctionWithBodyId, GenericFunctionId,
23 GenericFunctionWithBodyId, ImplFunctionBodyId, ImplGenericFunctionId,
24 ImplGenericFunctionWithBodyId,
25};
26use crate::items::generics::{GenericParamConst, GenericParamImpl, GenericParamType};
27use crate::items::imp::{
28 GeneratedImplId, GeneratedImplItems, GeneratedImplLongId, ImplId, ImplImplId, ImplLongId,
29 UninferredGeneratedImplId, UninferredGeneratedImplLongId, UninferredImpl,
30};
31use crate::items::trt::{ConcreteTraitGenericFunctionId, ConcreteTraitGenericFunctionLongId};
32use crate::types::{
33 ClosureTypeLongId, ConcreteEnumLongId, ConcreteExternTypeLongId, ConcreteStructLongId,
34 ImplTypeId,
35};
36use crate::{
37 ConcreteEnumId, ConcreteExternTypeId, ConcreteFunction, ConcreteImplId, ConcreteImplLongId,
38 ConcreteStructId, ConcreteTraitId, ConcreteTraitLongId, ConcreteTypeId, ConcreteVariant,
39 ExprId, ExprVar, ExprVarMemberPath, FunctionId, FunctionLongId, GenericArgumentId,
40 GenericParam, MatchArmSelector, Parameter, Signature, TypeId, TypeLongId, ValueSelectorArm,
41 VarId,
42};
43
44pub enum RewriteResult {
45 Modified,
46 NoChange,
47}
48
49#[derive(Clone, Debug, Default, PartialEq, Eq)]
52pub struct GenericSubstitution {
53 param_to_arg: OrderedHashMap<GenericParamId, GenericArgumentId>,
54 self_impl: Option<ImplId>,
55}
56impl GenericSubstitution {
57 pub fn from_impl(self_impl: ImplId) -> Self {
58 GenericSubstitution { param_to_arg: OrderedHashMap::default(), self_impl: Some(self_impl) }
59 }
60 pub fn new(generic_params: &[GenericParam], generic_args: &[GenericArgumentId]) -> Self {
61 GenericSubstitution {
62 param_to_arg: zip_eq(generic_params, generic_args)
63 .map(|(param, arg)| (param.id(), *arg))
64 .collect(),
65 self_impl: None,
66 }
67 }
68 pub fn concat(mut self, other: GenericSubstitution) -> Self {
69 for (key, value) in other.param_to_arg.into_iter() {
70 self.param_to_arg.insert(key, value);
71 }
72 if let Some(self_impl) = other.self_impl {
73 self.self_impl = Some(self_impl);
74 }
75 self
76 }
77}
78impl Deref for GenericSubstitution {
79 type Target = OrderedHashMap<GenericParamId, GenericArgumentId>;
80
81 fn deref(&self) -> &Self::Target {
82 &self.param_to_arg
83 }
84}
85impl DerefMut for GenericSubstitution {
86 fn deref_mut(&mut self) -> &mut Self::Target {
87 &mut self.param_to_arg
88 }
89}
90#[allow(clippy::derived_hash_with_manual_eq)]
91impl std::hash::Hash for GenericSubstitution {
92 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
93 self.param_to_arg.len().hash(state);
94 for e in self.param_to_arg.iter() {
95 e.hash(state);
96 }
97 }
98}
99
100#[macro_export]
101macro_rules! semantic_object_for_id {
102 ($name:ident, $lookup:ident, $intern:ident, $long_ty:ident) => {
103 impl<
104 'a,
105 Error,
106 TRewriter: $crate::substitution::HasDb<&'a dyn $crate::db::SemanticGroup>
107 + $crate::substitution::SemanticRewriter<$long_ty, Error>,
108 > $crate::substitution::SemanticObject<TRewriter, Error> for $name
109 {
110 fn default_rewrite(
111 &mut self,
112 rewriter: &mut TRewriter,
113 ) -> Result<$crate::substitution::RewriteResult, Error> where {
114 let db = $crate::substitution::HasDb::get_db(rewriter);
115 let mut val = db.$lookup(*self);
116 Ok(
117 match $crate::substitution::SemanticRewriter::internal_rewrite(
118 rewriter, &mut val,
119 )? {
120 $crate::substitution::RewriteResult::Modified => {
121 *self = db.$intern(val);
122 $crate::substitution::RewriteResult::Modified
123 }
124 $crate::substitution::RewriteResult::NoChange => {
125 $crate::substitution::RewriteResult::NoChange
126 }
127 },
128 )
129 }
130 }
131 };
132}
133
134#[macro_export]
135macro_rules! add_rewrite {
136 (<$($generics:lifetime),*>, $self_ty:ty, $err_ty:ty, $ty:ident) => {
137 impl <$($generics),*> SemanticRewriter<$ty, $err_ty> for $self_ty {
138 fn internal_rewrite(
139 &mut self,
140 value: &mut $ty
141 ) -> Result<$crate::substitution::RewriteResult, $err_ty> {
142 $crate::substitution::SemanticObject::default_rewrite(value, self)
143 }
144 }
145 };
146}
147
148#[macro_export]
149macro_rules! add_rewrite_identity {
150 (<$($generics:lifetime),*>, $self_ty:ty, $err_ty:ty, $ty:ident) => {
151 impl <$($generics),*> SemanticRewriter<$ty, $err_ty> for $self_ty {
152 fn internal_rewrite(
153 &mut self,
154 _value: &mut $ty
155 ) -> Result<$crate::substitution::RewriteResult, $err_ty> {
156 Ok(RewriteResult::NoChange)
157 }
158 }
159 };
160}
161
162pub trait SemanticObject<TRewriter, Error>: Sized {
163 fn default_rewrite(&mut self, rewriter: &mut TRewriter) -> Result<RewriteResult, Error>;
164}
165impl<T: Clone, E, TRewriter: SemanticRewriter<T, E>> SemanticRewriter<Vec<T>, E> for TRewriter {
166 fn internal_rewrite(&mut self, value: &mut Vec<T>) -> Result<RewriteResult, E> {
167 let mut result = RewriteResult::NoChange;
168 for el in value.iter_mut() {
169 match self.internal_rewrite(el)? {
170 RewriteResult::Modified => {
171 result = RewriteResult::Modified;
172 }
173 RewriteResult::NoChange => {}
174 }
175 }
176
177 Ok(result)
178 }
179}
180impl<T, E, TRewriter: SemanticRewriter<T, E>> SemanticRewriter<VecDeque<T>, E> for TRewriter {
181 fn internal_rewrite(&mut self, value: &mut VecDeque<T>) -> Result<RewriteResult, E> {
182 let mut result = RewriteResult::NoChange;
183 for el in value.iter_mut() {
184 match self.internal_rewrite(el)? {
185 RewriteResult::Modified => {
186 result = RewriteResult::Modified;
187 }
188 RewriteResult::NoChange => {}
189 }
190 }
191
192 Ok(result)
193 }
194}
195impl<T, E, TRewriter: SemanticRewriter<T, E>> SemanticRewriter<Box<T>, E> for TRewriter {
196 fn internal_rewrite(&mut self, value: &mut Box<T>) -> Result<RewriteResult, E> {
197 self.internal_rewrite(value.as_mut())
198 }
199}
200
201impl<T: Clone, V: Clone, E, TRewriter: SemanticRewriter<V, E>>
202 SemanticRewriter<OrderedHashMap<T, V>, E> for TRewriter
203{
204 fn internal_rewrite(&mut self, value: &mut OrderedHashMap<T, V>) -> Result<RewriteResult, E> {
205 let mut result = RewriteResult::NoChange;
206 for el in value.iter_mut() {
207 match self.internal_rewrite(el.1)? {
208 RewriteResult::Modified => {
209 result = RewriteResult::Modified;
210 }
211 RewriteResult::NoChange => {}
212 }
213 }
214
215 Ok(result)
216 }
217}
218impl<T0, T1, E, TRewriter: SemanticRewriter<T0, E> + SemanticRewriter<T1, E>>
219 SemanticRewriter<(T0, T1), E> for TRewriter
220{
221 fn internal_rewrite(&mut self, value: &mut (T0, T1)) -> Result<RewriteResult, E> {
222 match (self.internal_rewrite(&mut value.0)?, self.internal_rewrite(&mut value.1)?) {
223 (RewriteResult::NoChange, RewriteResult::NoChange) => Ok(RewriteResult::NoChange),
224 _ => Ok(RewriteResult::Modified),
225 }
226 }
227}
228impl<T, E, TRewriter: SemanticRewriter<T, E>> SemanticRewriter<Option<T>, E> for TRewriter {
229 fn internal_rewrite(&mut self, value: &mut Option<T>) -> Result<RewriteResult, E> {
230 Ok(match value {
231 Some(val) => self.internal_rewrite(val)?,
232 None => RewriteResult::NoChange,
233 })
234 }
235}
236impl<T, E, TRewriter: SemanticRewriter<T, E>, E2> SemanticRewriter<Result<T, E2>, E> for TRewriter {
237 fn internal_rewrite(&mut self, value: &mut Result<T, E2>) -> Result<RewriteResult, E> {
238 Ok(match value {
239 Ok(val) => self.internal_rewrite(val)?,
240 Err(_) => RewriteResult::NoChange,
241 })
242 }
243}
244pub trait HasDb<T> {
245 fn get_db(&self) -> T;
246}
247pub trait SemanticRewriter<T, Error> {
248 fn rewrite(&mut self, mut value: T) -> Result<T, Error> {
249 self.internal_rewrite(&mut value)?;
250 Ok(value)
251 }
252
253 fn internal_rewrite(&mut self, value: &mut T) -> Result<RewriteResult, Error>;
254}
255
256#[macro_export]
257macro_rules! prune_single {
258 ($macro:ident, $item:ident, ) => {$macro!($item);};
259 ($macro:ident, $item:ident, $item0:ident $($item_rest:ident)*) => {
260 macro_rules! __inner_helper {
261 ($item $item) => { };
263 ($item $item0) => { $crate::prune_single!($macro, $item, $($item_rest)*); };
265 }
266 __inner_helper!($item $item0);
267 }
268}
269
270#[macro_export]
271macro_rules! add_basic_rewrites {
272 (<$($generics:lifetime),*>, $self_ty:ty, $err_ty:ty, @exclude $($exclude:ident)*) => {
273 macro_rules! __identity_helper {
274 ($item:ident) => {
275 $crate::add_rewrite_identity!(<$($generics),*>, $self_ty, $err_ty, $item);
276 }
277 }
278 macro_rules! __regular_helper {
279 ($item:ident) => { $crate::add_rewrite!(<$($generics),*>, $self_ty, $err_ty, $item); }
280 }
281
282 $crate::prune_single!(__identity_helper, InferenceId, $($exclude)*);
283 $crate::prune_single!(__identity_helper, ParamId, $($exclude)*);
284 $crate::prune_single!(__identity_helper, FreeFunctionId, $($exclude)*);
285 $crate::prune_single!(__identity_helper, ExternFunctionId, $($exclude)*);
286 $crate::prune_single!(__identity_helper, ExternTypeId, $($exclude)*);
287 $crate::prune_single!(__identity_helper, ImplDefId, $($exclude)*);
288 $crate::prune_single!(__identity_helper, ImplImplDefId, $($exclude)*);
289 $crate::prune_single!(__identity_helper, ImplAliasId, $($exclude)*);
290 $crate::prune_single!(__identity_helper, TraitId, $($exclude)*);
291 $crate::prune_single!(__identity_helper, TraitFunctionId, $($exclude)*);
292 $crate::prune_single!(__identity_helper, VariantId, $($exclude)*);
293 $crate::prune_single!(__identity_helper, ImplFunctionId, $($exclude)*);
294 $crate::prune_single!(__identity_helper, EnumId, $($exclude)*);
295 $crate::prune_single!(__identity_helper, StructId, $($exclude)*);
296 $crate::prune_single!(__identity_helper, GenericParamId, $($exclude)*);
297 $crate::prune_single!(__identity_helper, TraitTypeId, $($exclude)*);
298 $crate::prune_single!(__identity_helper, TraitImplId, $($exclude)*);
299 $crate::prune_single!(__identity_helper, TraitConstantId, $($exclude)*);
300 $crate::prune_single!(__identity_helper, TypeVar, $($exclude)*);
301 $crate::prune_single!(__identity_helper, ConstVar, $($exclude)*);
302 $crate::prune_single!(__identity_helper, VarId, $($exclude)*);
303 $crate::prune_single!(__identity_helper, MemberId, $($exclude)*);
304 $crate::prune_single!(__identity_helper, LocalVarId, $($exclude)*);
305 $crate::prune_single!(__identity_helper, LocalImplVarId, $($exclude)*);
306 $crate::prune_single!(__identity_helper, LocalTypeVarId, $($exclude)*);
307 $crate::prune_single!(__identity_helper, LocalConstVarId, $($exclude)*);
308 $crate::prune_single!(__identity_helper, InferenceVar, $($exclude)*);
309 $crate::prune_single!(__identity_helper, ImplFunctionBodyId, $($exclude)*);
310 $crate::prune_single!(__identity_helper, ExprId, $($exclude)*);
311
312 $crate::prune_single!(__regular_helper, Signature, $($exclude)*);
313 $crate::prune_single!(__regular_helper, GenericFunctionId, $($exclude)*);
314 $crate::prune_single!(__regular_helper, GenericFunctionWithBodyId, $($exclude)*);
315 $crate::prune_single!(__regular_helper, ConcreteFunction, $($exclude)*);
316 $crate::prune_single!(__regular_helper, ConcreteFunctionWithBody, $($exclude)*);
317 $crate::prune_single!(__regular_helper, ConcreteFunctionWithBodyId, $($exclude)*);
318 $crate::prune_single!(__regular_helper, ImplGenericFunctionId, $($exclude)*);
319 $crate::prune_single!(__regular_helper, ImplGenericFunctionWithBodyId, $($exclude)*);
320 $crate::prune_single!(__regular_helper, ImplVar, $($exclude)*);
321 $crate::prune_single!(__regular_helper, ImplVarId, $($exclude)*);
322 $crate::prune_single!(__regular_helper, Parameter, $($exclude)*);
323 $crate::prune_single!(__regular_helper, GenericParam, $($exclude)*);
324 $crate::prune_single!(__regular_helper, GenericParamType, $($exclude)*);
325 $crate::prune_single!(__regular_helper, GenericParamConst, $($exclude)*);
326 $crate::prune_single!(__regular_helper, GenericParamImpl, $($exclude)*);
327 $crate::prune_single!(__regular_helper, GenericArgumentId, $($exclude)*);
328 $crate::prune_single!(__regular_helper, FunctionId, $($exclude)*);
329 $crate::prune_single!(__regular_helper, FunctionLongId, $($exclude)*);
330 $crate::prune_single!(__regular_helper, TypeId, $($exclude)*);
331 $crate::prune_single!(__regular_helper, TypeLongId, $($exclude)*);
332 $crate::prune_single!(__regular_helper, ConstValueId, $($exclude)*);
333 $crate::prune_single!(__regular_helper, ConstValue, $($exclude)*);
334 $crate::prune_single!(__regular_helper, ConcreteVariant, $($exclude)*);
335 $crate::prune_single!(__regular_helper, ValueSelectorArm, $($exclude)*);
336 $crate::prune_single!(__regular_helper, MatchArmSelector, $($exclude)*);
337 $crate::prune_single!(__regular_helper, ClosureTypeLongId, $($exclude)*);
338 $crate::prune_single!(__regular_helper, ConcreteTypeId, $($exclude)*);
339 $crate::prune_single!(__regular_helper, ConcreteStructId, $($exclude)*);
340 $crate::prune_single!(__regular_helper, ConcreteStructLongId, $($exclude)*);
341 $crate::prune_single!(__regular_helper, ConcreteEnumId, $($exclude)*);
342 $crate::prune_single!(__regular_helper, ConcreteEnumLongId, $($exclude)*);
343 $crate::prune_single!(__regular_helper, ConcreteExternTypeId, $($exclude)*);
344 $crate::prune_single!(__regular_helper, ConcreteExternTypeLongId, $($exclude)*);
345 $crate::prune_single!(__regular_helper, ConcreteTraitId, $($exclude)*);
346 $crate::prune_single!(__regular_helper, ConcreteTraitLongId, $($exclude)*);
347 $crate::prune_single!(__regular_helper, ConcreteImplId, $($exclude)*);
348 $crate::prune_single!(__regular_helper, ConcreteImplLongId, $($exclude)*);
349 $crate::prune_single!(__regular_helper, ConcreteTraitGenericFunctionLongId, $($exclude)*);
350 $crate::prune_single!(__regular_helper, ConcreteTraitGenericFunctionId, $($exclude)*);
351 $crate::prune_single!(__regular_helper, GeneratedImplId, $($exclude)*);
352 $crate::prune_single!(__regular_helper, GeneratedImplLongId, $($exclude)*);
353 $crate::prune_single!(__regular_helper, GeneratedImplItems, $($exclude)*);
354 $crate::prune_single!(__regular_helper, ImplLongId, $($exclude)*);
355 $crate::prune_single!(__regular_helper, ImplId, $($exclude)*);
356 $crate::prune_single!(__regular_helper, ImplTypeId, $($exclude)*);
357 $crate::prune_single!(__regular_helper, ImplConstantId, $($exclude)*);
358 $crate::prune_single!(__regular_helper, ImplImplId, $($exclude)*);
359 $crate::prune_single!(__regular_helper, UninferredGeneratedImplId, $($exclude)*);
360 $crate::prune_single!(__regular_helper, UninferredGeneratedImplLongId, $($exclude)*);
361 $crate::prune_single!(__regular_helper, UninferredImpl, $($exclude)*);
362 $crate::prune_single!(__regular_helper, ExprVarMemberPath, $($exclude)*);
363 $crate::prune_single!(__regular_helper, ExprVar, $($exclude)*);
364 $crate::prune_single!(__regular_helper, ImplVarTraitItemMappings, $($exclude)*);
365 $crate::prune_single!(__regular_helper, CanonicalTrait, $($exclude)*);
366 };
367}
368
369#[macro_export]
370macro_rules! add_expr_rewrites {
371 (<$($generics:lifetime),*>, $self_ty:ty, $err_ty:ty, @exclude $($exclude:ident)*) => {
372 macro_rules! __identity_helper {
373 ($item:ident) => {
374 $crate::add_rewrite_identity!(<$($generics),*>, $self_ty, $err_ty, $item);
375 }
376 }
377 macro_rules! __regular_helper {
378 ($item:ident) => { $crate::add_rewrite!(<$($generics),*>, $self_ty, $err_ty, $item); }
379 }
380
381 $crate::prune_single!(__identity_helper, PatternId, $($exclude)*);
382 $crate::prune_single!(__identity_helper, StatementId, $($exclude)*);
383 $crate::prune_single!(__identity_helper, ConstantId, $($exclude)*);
384
385 $crate::prune_single!(__regular_helper, Expr, $($exclude)*);
386 $crate::prune_single!(__regular_helper, ExprTuple, $($exclude)*);
387 $crate::prune_single!(__regular_helper, ExprSnapshot, $($exclude)*);
388 $crate::prune_single!(__regular_helper, ExprDesnap, $($exclude)*);
389 $crate::prune_single!(__regular_helper, ExprAssignment, $($exclude)*);
390 $crate::prune_single!(__regular_helper, ExprLogicalOperator, $($exclude)*);
391 $crate::prune_single!(__regular_helper, ExprBlock, $($exclude)*);
392 $crate::prune_single!(__regular_helper, ExprFunctionCall, $($exclude)*);
393 $crate::prune_single!(__regular_helper, ExprMatch, $($exclude)*);
394 $crate::prune_single!(__regular_helper, ExprIf, $($exclude)*);
395 $crate::prune_single!(__regular_helper, Condition, $($exclude)*);
396 $crate::prune_single!(__regular_helper, ExprLoop, $($exclude)*);
397 $crate::prune_single!(__regular_helper, ExprWhile, $($exclude)*);
398 $crate::prune_single!(__regular_helper, ExprFor, $($exclude)*);
399 $crate::prune_single!(__regular_helper, ExprLiteral, $($exclude)*);
400 $crate::prune_single!(__regular_helper, ExprStringLiteral, $($exclude)*);
401 $crate::prune_single!(__regular_helper, ExprMemberAccess, $($exclude)*);
402 $crate::prune_single!(__regular_helper, ExprStructCtor, $($exclude)*);
403 $crate::prune_single!(__regular_helper, ExprEnumVariantCtor, $($exclude)*);
404 $crate::prune_single!(__regular_helper, ExprPropagateError, $($exclude)*);
405 $crate::prune_single!(__regular_helper, ExprConstant, $($exclude)*);
406 $crate::prune_single!(__regular_helper, ExprFixedSizeArray, $($exclude)*);
407 $crate::prune_single!(__regular_helper, ExprClosure, $($exclude)*);
408 $crate::prune_single!(__regular_helper, ExprMissing, $($exclude)*);
409 $crate::prune_single!(__regular_helper, ExprFunctionCallArg, $($exclude)*);
410 $crate::prune_single!(__regular_helper, FixedSizeArrayItems, $($exclude)*);
411 $crate::prune_single!(__regular_helper, MatchArm, $($exclude)*);
412 $crate::prune_single!(__regular_helper, Statement, $($exclude)*);
413 $crate::prune_single!(__regular_helper, StatementExpr, $($exclude)*);
414 $crate::prune_single!(__regular_helper, StatementLet, $($exclude)*);
415 $crate::prune_single!(__regular_helper, StatementReturn, $($exclude)*);
416 $crate::prune_single!(__regular_helper, StatementContinue, $($exclude)*);
417 $crate::prune_single!(__regular_helper, StatementBreak, $($exclude)*);
418 $crate::prune_single!(__regular_helper, StatementItem, $($exclude)*);
419 $crate::prune_single!(__regular_helper, Pattern, $($exclude)*);
420 $crate::prune_single!(__regular_helper, PatternLiteral, $($exclude)*);
421 $crate::prune_single!(__regular_helper, PatternStringLiteral, $($exclude)*);
422 $crate::prune_single!(__regular_helper, PatternVariable, $($exclude)*);
423 $crate::prune_single!(__regular_helper, PatternStruct, $($exclude)*);
424 $crate::prune_single!(__regular_helper, PatternTuple, $($exclude)*);
425 $crate::prune_single!(__regular_helper, PatternFixedSizeArray, $($exclude)*);
426 $crate::prune_single!(__regular_helper, PatternEnumVariant, $($exclude)*);
427 $crate::prune_single!(__regular_helper, PatternOtherwise, $($exclude)*);
428 $crate::prune_single!(__regular_helper, PatternMissing, $($exclude)*);
429 $crate::prune_single!(__regular_helper, LocalVariable, $($exclude)*);
430 $crate::prune_single!(__regular_helper, Member, $($exclude)*);
431 };
432}
433
434pub struct SubstitutionRewriter<'a> {
435 pub db: &'a dyn SemanticGroup,
436 pub substitution: &'a GenericSubstitution,
437}
438impl<'a> HasDb<&'a dyn SemanticGroup> for SubstitutionRewriter<'a> {
439 fn get_db(&self) -> &'a dyn SemanticGroup {
440 self.db
441 }
442}
443
444add_basic_rewrites!(
445 <'a>,
446 SubstitutionRewriter<'a>,
447 DiagnosticAdded,
448 @exclude TypeId TypeLongId ImplId ImplLongId ConstValue GenericFunctionId
449);
450
451impl SemanticRewriter<TypeId, DiagnosticAdded> for SubstitutionRewriter<'_> {
452 fn internal_rewrite(&mut self, value: &mut TypeId) -> Maybe<RewriteResult> {
453 if value.is_fully_concrete(self.db) {
454 return Ok(RewriteResult::NoChange);
455 }
456 value.default_rewrite(self)
457 }
458}
459
460impl SemanticRewriter<ImplId, DiagnosticAdded> for SubstitutionRewriter<'_> {
461 fn internal_rewrite(&mut self, value: &mut ImplId) -> Maybe<RewriteResult> {
462 if value.is_fully_concrete(self.db) {
463 return Ok(RewriteResult::NoChange);
464 }
465 value.default_rewrite(self)
466 }
467}
468
469impl SemanticRewriter<TypeLongId, DiagnosticAdded> for SubstitutionRewriter<'_> {
470 fn internal_rewrite(&mut self, value: &mut TypeLongId) -> Maybe<RewriteResult> {
471 match value {
472 TypeLongId::GenericParameter(generic_param) => {
473 if let Some(generic_arg) = self.substitution.get(generic_param) {
474 let type_id = *extract_matches!(generic_arg, GenericArgumentId::Type);
475 *value = type_id.lookup_intern(self.db);
477 return Ok(RewriteResult::Modified);
478 }
479 }
480 TypeLongId::ImplType(impl_type_id) => {
481 let impl_type_id_rewrite_result = self.internal_rewrite(impl_type_id)?;
482 let new_value =
483 self.db.impl_type_concrete_implized(*impl_type_id)?.lookup_intern(self.db);
484 if new_value != *value {
485 *value = new_value;
486 return Ok(RewriteResult::Modified);
487 } else {
488 return Ok(impl_type_id_rewrite_result);
489 }
490 }
491 TypeLongId::TraitType(trait_type_id) => {
492 if let Some(self_impl) = &self.substitution.self_impl {
493 assert_eq!(
494 trait_type_id.trait_id(self.db.upcast()),
495 self_impl.concrete_trait(self.db)?.trait_id(self.db)
496 );
497 let impl_type_id = ImplTypeId::new(*self_impl, *trait_type_id, self.db);
498 *value =
499 self.db.impl_type_concrete_implized(impl_type_id)?.lookup_intern(self.db);
500 return Ok(RewriteResult::Modified);
501 }
502 }
503 _ => {}
504 }
505 value.default_rewrite(self)
506 }
507}
508impl SemanticRewriter<ConstValue, DiagnosticAdded> for SubstitutionRewriter<'_> {
509 fn internal_rewrite(&mut self, value: &mut ConstValue) -> Maybe<RewriteResult> {
510 match value {
511 ConstValue::Generic(param_id) => {
512 if let Some(generic_arg) = self.substitution.get(param_id) {
513 let const_value_id = extract_matches!(generic_arg, GenericArgumentId::Constant);
514
515 *value = const_value_id.lookup_intern(self.db);
516 return Ok(RewriteResult::Modified);
517 }
518 }
519 ConstValue::ImplConstant(impl_constant_id) => {
520 let impl_const_id_rewrite_result = self.internal_rewrite(impl_constant_id)?;
521 let new_value = self
522 .db
523 .impl_constant_concrete_implized_value(*impl_constant_id)?
524 .lookup_intern(self.db);
525 if new_value != *value {
526 *value = new_value;
527 return Ok(RewriteResult::Modified);
528 } else {
529 return Ok(impl_const_id_rewrite_result);
530 }
531 }
532 ConstValue::TraitConstant(trait_constant_id) => {
533 if let Some(self_impl) = &self.substitution.self_impl {
534 assert_eq!(
535 trait_constant_id.trait_id(self.db.upcast()),
536 self_impl.concrete_trait(self.db)?.trait_id(self.db)
537 );
538 let impl_const_id =
539 ImplConstantId::new(*self_impl, *trait_constant_id, self.db);
540 *value = self
541 .db
542 .impl_constant_concrete_implized_value(impl_const_id)?
543 .lookup_intern(self.db);
544
545 return Ok(RewriteResult::Modified);
546 }
547 }
548 _ => {}
549 }
550
551 value.default_rewrite(self)
552 }
553}
554impl SemanticRewriter<ImplLongId, DiagnosticAdded> for SubstitutionRewriter<'_> {
555 fn internal_rewrite(&mut self, value: &mut ImplLongId) -> Maybe<RewriteResult> {
556 match value {
557 ImplLongId::GenericParameter(generic_param) => {
558 if let Some(generic_arg) = self.substitution.get(generic_param) {
559 *value = extract_matches!(generic_arg, GenericArgumentId::Impl)
560 .lookup_intern(self.db);
561 return Ok(RewriteResult::Modified);
564 }
565 }
566 ImplLongId::ImplImpl(impl_impl_id) => {
567 let impl_impl_id_rewrite_result = self.internal_rewrite(impl_impl_id)?;
568 let new_value =
569 self.db.impl_impl_concrete_implized(*impl_impl_id)?.lookup_intern(self.db);
570 if new_value != *value {
571 *value = new_value;
572 return Ok(RewriteResult::Modified);
573 } else {
574 return Ok(impl_impl_id_rewrite_result);
575 }
576 }
577 ImplLongId::TraitImpl(trait_impl_id) => {
578 if let Some(self_impl) = &self.substitution.self_impl {
579 assert_eq!(
580 trait_impl_id.trait_id(self.db.upcast()),
581 self_impl.concrete_trait(self.db)?.trait_id(self.db)
582 );
583 let impl_impl_id = ImplImplId::new(*self_impl, *trait_impl_id, self.db);
584 *value =
585 self.db.impl_impl_concrete_implized(impl_impl_id)?.lookup_intern(self.db);
586
587 return Ok(RewriteResult::Modified);
588 }
589 }
590 _ => {}
591 }
592 value.default_rewrite(self)
593 }
594}
595impl SemanticRewriter<GenericFunctionId, DiagnosticAdded> for SubstitutionRewriter<'_> {
596 fn internal_rewrite(&mut self, value: &mut GenericFunctionId) -> Maybe<RewriteResult> {
597 if let GenericFunctionId::Trait(id) = value {
598 if let Some(self_impl) = &self.substitution.self_impl {
599 let id_rewritten = self.internal_rewrite(id)?;
600 if id.concrete_trait(self.db.upcast()) == self_impl.concrete_trait(self.db)? {
601 *value = GenericFunctionId::Impl(ImplGenericFunctionId {
602 impl_id: *self_impl,
603 function: id.trait_function(self.db),
604 });
605 return Ok(RewriteResult::Modified);
606 }
607 return Ok(id_rewritten);
608 }
609 }
610 value.default_rewrite(self)
611 }
612}