Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/source_analyzer.rs')
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 4e85e299a9..c6f2d151f5 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -532,18 +532,12 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, range_pat: &ast::RangePat, ) -> Option<StructId> { - let path: ModPath = match (range_pat.op_kind()?, range_pat.start(), range_pat.end()) { - (RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo], - (RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom], - (RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range], - (RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive], - (RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive], - - (RangeOp::Exclusive, None, None) => return None, - (RangeOp::Inclusive, None, None) => return None, - (RangeOp::Inclusive, Some(_), None) => return None, - }; - self.resolver.resolve_known_struct(db, &path) + self.resolve_range_struct( + db, + range_pat.op_kind()?, + range_pat.start().is_some(), + range_pat.end().is_some(), + ) } pub(crate) fn resolve_range_expr( @@ -551,19 +545,59 @@ impl<'db> SourceAnalyzer<'db> { db: &'db dyn HirDatabase, range_expr: &ast::RangeExpr, ) -> Option<StructId> { - let path: ModPath = match (range_expr.op_kind()?, range_expr.start(), range_expr.end()) { - (RangeOp::Exclusive, None, None) => path![core::ops::RangeFull], - (RangeOp::Exclusive, None, Some(_)) => path![core::ops::RangeTo], - (RangeOp::Exclusive, Some(_), None) => path![core::ops::RangeFrom], - (RangeOp::Exclusive, Some(_), Some(_)) => path![core::ops::Range], - (RangeOp::Inclusive, None, Some(_)) => path![core::ops::RangeToInclusive], - (RangeOp::Inclusive, Some(_), Some(_)) => path![core::ops::RangeInclusive], + self.resolve_range_struct( + db, + range_expr.op_kind()?, + range_expr.start().is_some(), + range_expr.end().is_some(), + ) + } + fn resolve_range_struct( + &self, + db: &'db dyn HirDatabase, + op_kind: RangeOp, + has_start: bool, + has_end: bool, + ) -> Option<StructId> { + let has_new_range = + self.resolver.top_level_def_map().is_unstable_feature_enabled(&sym::new_range); + let lang_items = self.lang_items(db); + match (op_kind, has_start, has_end) { + (RangeOp::Exclusive, false, false) => lang_items.RangeFull, + (RangeOp::Exclusive, false, true) => lang_items.RangeTo, + (RangeOp::Exclusive, true, false) => { + if has_new_range { + lang_items.RangeFromCopy + } else { + lang_items.RangeFrom + } + } + (RangeOp::Exclusive, true, true) => { + if has_new_range { + lang_items.RangeCopy + } else { + lang_items.Range + } + } + (RangeOp::Inclusive, false, true) => { + if has_new_range { + lang_items.RangeToInclusiveCopy + } else { + lang_items.RangeToInclusive + } + } + (RangeOp::Inclusive, true, true) => { + if has_new_range { + lang_items.RangeInclusiveCopy + } else { + lang_items.RangeInclusiveStruct + } + } // [E0586] inclusive ranges must be bounded at the end - (RangeOp::Inclusive, None, None) => return None, - (RangeOp::Inclusive, Some(_), None) => return None, - }; - self.resolver.resolve_known_struct(db, &path) + (RangeOp::Inclusive, false, false) => None, + (RangeOp::Inclusive, true, false) => None, + } } pub(crate) fn resolve_await_to_poll( |