Attempt to resolve all polymorphic types to a single "key" type. For `target_for_param_type` to be useful, this must have already been called.
(&mut self, ecx: &ExprContext)
| 1461 | /// `target_for_param_type` to be useful, this must have already been |
| 1462 | /// called. |
| 1463 | fn determine_key(&mut self, ecx: &ExprContext) -> bool { |
| 1464 | self.key = if !self.seen.iter().any(|v| v.is_coerced()) { |
| 1465 | match &self.compat { |
| 1466 | // No encountered param was polymorphic |
| 1467 | None => None, |
| 1468 | // Params were polymorphic, but we never received a known type. |
| 1469 | // This cannot be delegated to `guess_best_common_type`, which |
| 1470 | // will incorrectly guess string, which is incompatible with |
| 1471 | // `BestCommonList`, `BestCommonMap`. |
| 1472 | Some(t) => match t { |
| 1473 | PolymorphicCompatClass::BestCommonAny => Some(SqlScalarType::String), |
| 1474 | PolymorphicCompatClass::BestCommonList => Some(SqlScalarType::List { |
| 1475 | custom_id: None, |
| 1476 | element_type: Box::new(SqlScalarType::String), |
| 1477 | }), |
| 1478 | PolymorphicCompatClass::BestCommonMap => Some(SqlScalarType::Map { |
| 1479 | value_type: Box::new(SqlScalarType::String), |
| 1480 | custom_id: None, |
| 1481 | }), |
| 1482 | // Do not infer type. |
| 1483 | PolymorphicCompatClass::StructuralEq | PolymorphicCompatClass::Any => None, |
| 1484 | }, |
| 1485 | } |
| 1486 | } else { |
| 1487 | // If we saw any polymorphic parameters, we must have determined the |
| 1488 | // compatibility type. |
| 1489 | let compat = self.compat.as_ref().unwrap(); |
| 1490 | |
| 1491 | let r = match compat { |
| 1492 | PolymorphicCompatClass::Any => { |
| 1493 | let mut s = self |
| 1494 | .seen |
| 1495 | .iter() |
| 1496 | .filter_map(|f| f.as_coerced().cloned()) |
| 1497 | .collect::<Vec<_>>(); |
| 1498 | let (candiate, remaining) = |
| 1499 | s.split_first().expect("have at least one non-None element"); |
| 1500 | if remaining.iter().all(|r| r.base_eq(candiate)) { |
| 1501 | s.remove(0) |
| 1502 | } else { |
| 1503 | return false; |
| 1504 | } |
| 1505 | } |
| 1506 | _ => match typeconv::guess_best_common_type(ecx, &self.seen) { |
| 1507 | Ok(r) => r, |
| 1508 | Err(_) => return false, |
| 1509 | }, |
| 1510 | }; |
| 1511 | |
| 1512 | // Ensure the best common type is compatible. |
| 1513 | for t in self.seen.iter() { |
| 1514 | if let CoercibleScalarType::Coerced(t) = t { |
| 1515 | if !compat.compatible(ecx, t, &r) { |
| 1516 | return false; |
| 1517 | } |
| 1518 | } |
| 1519 | } |
| 1520 | Some(r) |
no test coverage detected