mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +00:00 
			
		
		
		
	Auto merge of #15721 - Veykril:shrink-pat-ptr, r=Veykril
Shrink PatPtr by swapping its AstPtr and Either wrap order Will have neglible perf results I imagine, but it cleans up some code
This commit is contained in:
		
						commit
						ef58843b9f
					
				@ -57,7 +57,7 @@ pub struct Body {
 | 
			
		||||
pub type ExprPtr = AstPtr<ast::Expr>;
 | 
			
		||||
pub type ExprSource = InFile<ExprPtr>;
 | 
			
		||||
 | 
			
		||||
pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
 | 
			
		||||
pub type PatPtr = AstPtr<Either<ast::Pat, ast::SelfParam>>;
 | 
			
		||||
pub type PatSource = InFile<PatPtr>;
 | 
			
		||||
 | 
			
		||||
pub type LabelPtr = AstPtr<ast::Label>;
 | 
			
		||||
@ -356,12 +356,12 @@ impl BodySourceMap {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option<PatId> {
 | 
			
		||||
        let src = node.map(|it| Either::Left(AstPtr::new(it)));
 | 
			
		||||
        let src = node.map(|it| AstPtr::new(it).wrap_left());
 | 
			
		||||
        self.pat_map.get(&src).cloned()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn node_self_param(&self, node: InFile<&ast::SelfParam>) -> Option<PatId> {
 | 
			
		||||
        let src = node.map(|it| Either::Right(AstPtr::new(it)));
 | 
			
		||||
        let src = node.map(|it| AstPtr::new(it).wrap_right());
 | 
			
		||||
        self.pat_map.get(&src).cloned()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -196,16 +196,12 @@ impl ExprCollector<'_> {
 | 
			
		||||
            if let Some(self_param) =
 | 
			
		||||
                param_list.self_param().filter(|_| attr_enabled.next().unwrap_or(false))
 | 
			
		||||
            {
 | 
			
		||||
                let ptr = AstPtr::new(&self_param);
 | 
			
		||||
                let binding_id: la_arena::Idx<Binding> = self.alloc_binding(
 | 
			
		||||
                    name![self],
 | 
			
		||||
                    BindingAnnotation::new(
 | 
			
		||||
                        self_param.mut_token().is_some() && self_param.amp_token().is_none(),
 | 
			
		||||
                        false,
 | 
			
		||||
                    ),
 | 
			
		||||
                );
 | 
			
		||||
                let param_pat =
 | 
			
		||||
                    self.alloc_pat(Pat::Bind { id: binding_id, subpat: None }, Either::Right(ptr));
 | 
			
		||||
                let is_mutable =
 | 
			
		||||
                    self_param.mut_token().is_some() && self_param.amp_token().is_none();
 | 
			
		||||
                let ptr = AstPtr::new(&Either::Right(self_param));
 | 
			
		||||
                let binding_id: la_arena::Idx<Binding> =
 | 
			
		||||
                    self.alloc_binding(name![self], BindingAnnotation::new(is_mutable, false));
 | 
			
		||||
                let param_pat = self.alloc_pat(Pat::Bind { id: binding_id, subpat: None }, ptr);
 | 
			
		||||
                self.add_definition_to_binding(binding_id, param_pat);
 | 
			
		||||
                self.body.params.push(param_pat);
 | 
			
		||||
            }
 | 
			
		||||
@ -1260,8 +1256,8 @@ impl ExprCollector<'_> {
 | 
			
		||||
                    (Some(id), Pat::Bind { id, subpat })
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                let ptr = AstPtr::new(&pat);
 | 
			
		||||
                let pat = self.alloc_pat(pattern, Either::Left(ptr));
 | 
			
		||||
                let ptr = AstPtr::new(&Either::Left(pat));
 | 
			
		||||
                let pat = self.alloc_pat(pattern, ptr);
 | 
			
		||||
                if let Some(binding_id) = binding {
 | 
			
		||||
                    self.add_definition_to_binding(binding_id, pat);
 | 
			
		||||
                }
 | 
			
		||||
@ -1395,7 +1391,7 @@ impl ExprCollector<'_> {
 | 
			
		||||
            ast::Pat::MacroPat(mac) => match mac.macro_call() {
 | 
			
		||||
                Some(call) => {
 | 
			
		||||
                    let macro_ptr = AstPtr::new(&call);
 | 
			
		||||
                    let src = self.expander.to_source(Either::Left(AstPtr::new(&pat)));
 | 
			
		||||
                    let src = self.expander.to_source(AstPtr::new(&Either::Left(pat)));
 | 
			
		||||
                    let pat =
 | 
			
		||||
                        self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| {
 | 
			
		||||
                            this.collect_pat_opt(expanded_pat, binding_list)
 | 
			
		||||
@ -1430,8 +1426,8 @@ impl ExprCollector<'_> {
 | 
			
		||||
                Pat::Range { start, end }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
        let ptr = AstPtr::new(&pat);
 | 
			
		||||
        self.alloc_pat(pattern, Either::Left(ptr))
 | 
			
		||||
        let ptr = AstPtr::new(&Either::Left(pat));
 | 
			
		||||
        self.alloc_pat(pattern, ptr)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn collect_pat_opt(&mut self, pat: Option<ast::Pat>, binding_list: &mut BindingList) -> PatId {
 | 
			
		||||
 | 
			
		||||
@ -475,10 +475,7 @@ fn foo() {
 | 
			
		||||
            .pat_syntax(*body.bindings[resolved.binding()].definitions.first().unwrap())
 | 
			
		||||
            .unwrap();
 | 
			
		||||
 | 
			
		||||
        let local_name = pat_src.value.either(
 | 
			
		||||
            |it| it.syntax_node_ptr().to_node(file.syntax()),
 | 
			
		||||
            |it| it.syntax_node_ptr().to_node(file.syntax()),
 | 
			
		||||
        );
 | 
			
		||||
        let local_name = pat_src.value.syntax_node_ptr().to_node(file.syntax());
 | 
			
		||||
        assert_eq!(local_name.text_range(), expected_name.syntax().text_range());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -336,9 +336,9 @@ impl<'a> DeclValidator<'a> {
 | 
			
		||||
 | 
			
		||||
        for (id, replacement) in pats_replacements {
 | 
			
		||||
            if let Ok(source_ptr) = source_map.pat_syntax(id) {
 | 
			
		||||
                if let Some(expr) = source_ptr.value.as_ref().left() {
 | 
			
		||||
                if let Some(ptr) = source_ptr.value.clone().cast::<ast::IdentPat>() {
 | 
			
		||||
                    let root = source_ptr.file_syntax(self.db.upcast());
 | 
			
		||||
                    if let ast::Pat::IdentPat(ident_pat) = expr.to_node(&root) {
 | 
			
		||||
                    let ident_pat = ptr.to_node(&root);
 | 
			
		||||
                    let parent = match ident_pat.syntax().parent() {
 | 
			
		||||
                        Some(parent) => parent,
 | 
			
		||||
                        None => continue,
 | 
			
		||||
@ -369,10 +369,7 @@ impl<'a> DeclValidator<'a> {
 | 
			
		||||
                        ident_type,
 | 
			
		||||
                        ident: AstPtr::new(&name_ast),
 | 
			
		||||
                        expected_case: replacement.expected_case,
 | 
			
		||||
                            ident_text: replacement
 | 
			
		||||
                                .current_name
 | 
			
		||||
                                .display(self.db.upcast())
 | 
			
		||||
                                .to_string(),
 | 
			
		||||
                        ident_text: replacement.current_name.display(self.db.upcast()).to_string(),
 | 
			
		||||
                        suggested_text: replacement.suggested_text,
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
@ -381,7 +378,6 @@ impl<'a> DeclValidator<'a> {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn validate_struct(&mut self, struct_id: StructId) {
 | 
			
		||||
        let data = self.db.struct_data(struct_id);
 | 
			
		||||
 | 
			
		||||
@ -375,10 +375,7 @@ impl MirEvalError {
 | 
			
		||||
                        Err(_) => continue,
 | 
			
		||||
                    },
 | 
			
		||||
                    MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
 | 
			
		||||
                        Ok(s) => s.map(|it| match it {
 | 
			
		||||
                            Either::Left(e) => e.into(),
 | 
			
		||||
                            Either::Right(e) => e.into(),
 | 
			
		||||
                        }),
 | 
			
		||||
                        Ok(s) => s.map(|it| it.syntax_node_ptr()),
 | 
			
		||||
                        Err(_) => continue,
 | 
			
		||||
                    },
 | 
			
		||||
                    MirSpan::Unknown => continue,
 | 
			
		||||
 | 
			
		||||
@ -269,12 +269,7 @@ fn pat_node(
 | 
			
		||||
    Some(match body_source_map.pat_syntax(pat) {
 | 
			
		||||
        Ok(sp) => {
 | 
			
		||||
            let root = db.parse_or_expand(sp.file_id);
 | 
			
		||||
            sp.map(|ptr| {
 | 
			
		||||
                ptr.either(
 | 
			
		||||
                    |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
                    |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
                )
 | 
			
		||||
            })
 | 
			
		||||
            sp.map(|ptr| ptr.to_node(&root).syntax().clone())
 | 
			
		||||
        }
 | 
			
		||||
        Err(SyntheticSyntax) => return None,
 | 
			
		||||
    })
 | 
			
		||||
@ -303,12 +298,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
 | 
			
		||||
            let syntax_ptr = match body_source_map.pat_syntax(pat) {
 | 
			
		||||
                Ok(sp) => {
 | 
			
		||||
                    let root = db.parse_or_expand(sp.file_id);
 | 
			
		||||
                    sp.map(|ptr| {
 | 
			
		||||
                        ptr.either(
 | 
			
		||||
                            |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
                            |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
                        )
 | 
			
		||||
                    })
 | 
			
		||||
                    sp.map(|ptr| ptr.to_node(&root).syntax().clone())
 | 
			
		||||
                }
 | 
			
		||||
                Err(SyntheticSyntax) => continue,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@ -174,20 +174,19 @@ pub struct MalformedDerive {
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct NoSuchField {
 | 
			
		||||
    pub field: InFile<Either<AstPtr<ast::RecordExprField>, AstPtr<ast::RecordPatField>>>,
 | 
			
		||||
    pub field: InFile<AstPtr<Either<ast::RecordExprField, ast::RecordPatField>>>,
 | 
			
		||||
    pub private: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct PrivateAssocItem {
 | 
			
		||||
    pub expr_or_pat:
 | 
			
		||||
        InFile<Either<AstPtr<ast::Expr>, Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>>>,
 | 
			
		||||
    pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, Either<ast::Pat, ast::SelfParam>>>>,
 | 
			
		||||
    pub item: AssocItem,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct MismatchedTupleStructPatArgCount {
 | 
			
		||||
    pub expr_or_pat: InFile<Either<AstPtr<ast::Expr>, AstPtr<ast::Pat>>>,
 | 
			
		||||
    pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
 | 
			
		||||
    pub expected: usize,
 | 
			
		||||
    pub found: usize,
 | 
			
		||||
}
 | 
			
		||||
@ -228,7 +227,7 @@ pub struct MissingUnsafe {
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct MissingFields {
 | 
			
		||||
    pub file: HirFileId,
 | 
			
		||||
    pub field_list_parent: Either<AstPtr<ast::RecordExpr>, AstPtr<ast::RecordPat>>,
 | 
			
		||||
    pub field_list_parent: AstPtr<Either<ast::RecordExpr, ast::RecordPat>>,
 | 
			
		||||
    pub field_list_parent_path: Option<AstPtr<ast::Path>>,
 | 
			
		||||
    pub missed_fields: Vec<Name>,
 | 
			
		||||
}
 | 
			
		||||
@ -255,7 +254,7 @@ pub struct MissingMatchArms {
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
pub struct TypeMismatch {
 | 
			
		||||
    pub expr_or_pat: Either<InFile<AstPtr<ast::Expr>>, InFile<AstPtr<ast::Pat>>>,
 | 
			
		||||
    pub expr_or_pat: InFile<AstPtr<Either<ast::Expr, ast::Pat>>>,
 | 
			
		||||
    pub expected: Type,
 | 
			
		||||
    pub actual: Type,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1509,10 +1509,10 @@ impl DefWithBody {
 | 
			
		||||
                &hir_ty::InferenceDiagnostic::NoSuchField { field: expr, private } => {
 | 
			
		||||
                    let expr_or_pat = match expr {
 | 
			
		||||
                        ExprOrPatId::ExprId(expr) => {
 | 
			
		||||
                            source_map.field_syntax(expr).map(Either::Left)
 | 
			
		||||
                            source_map.field_syntax(expr).map(AstPtr::wrap_left)
 | 
			
		||||
                        }
 | 
			
		||||
                        ExprOrPatId::PatId(pat) => {
 | 
			
		||||
                            source_map.pat_field_syntax(pat).map(Either::Right)
 | 
			
		||||
                            source_map.pat_field_syntax(pat).map(AstPtr::wrap_right)
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    acc.push(NoSuchField { field: expr_or_pat, private }.into())
 | 
			
		||||
@ -1530,8 +1530,8 @@ impl DefWithBody {
 | 
			
		||||
                }
 | 
			
		||||
                &hir_ty::InferenceDiagnostic::PrivateAssocItem { id, item } => {
 | 
			
		||||
                    let expr_or_pat = match id {
 | 
			
		||||
                        ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(Either::Left),
 | 
			
		||||
                        ExprOrPatId::PatId(pat) => pat_syntax(pat).map(Either::Right),
 | 
			
		||||
                        ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
 | 
			
		||||
                        ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
 | 
			
		||||
                    };
 | 
			
		||||
                    let item = item.into();
 | 
			
		||||
                    acc.push(PrivateAssocItem { expr_or_pat, item }.into())
 | 
			
		||||
@ -1609,12 +1609,17 @@ impl DefWithBody {
 | 
			
		||||
                    found,
 | 
			
		||||
                } => {
 | 
			
		||||
                    let expr_or_pat = match pat {
 | 
			
		||||
                        ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(Either::Left),
 | 
			
		||||
                        ExprOrPatId::PatId(pat) => source_map
 | 
			
		||||
                            .pat_syntax(pat)
 | 
			
		||||
                            .expect("unexpected synthetic")
 | 
			
		||||
                            .map(|it| it.unwrap_left())
 | 
			
		||||
                            .map(Either::Right),
 | 
			
		||||
                        ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
 | 
			
		||||
                        ExprOrPatId::PatId(pat) => {
 | 
			
		||||
                            let InFile { file_id, value } =
 | 
			
		||||
                                source_map.pat_syntax(pat).expect("unexpected synthetic");
 | 
			
		||||
 | 
			
		||||
                            // cast from Either<Pat, SelfParam> -> Either<_, Pat>
 | 
			
		||||
                            let Some(ptr) = AstPtr::try_from_raw(value.syntax_node_ptr()) else {
 | 
			
		||||
                                continue;
 | 
			
		||||
                            };
 | 
			
		||||
                            InFile { file_id, value: ptr }
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    acc.push(
 | 
			
		||||
                        MismatchedTupleStructPatArgCount { expr_or_pat, expected, found }.into(),
 | 
			
		||||
@ -1628,11 +1633,15 @@ impl DefWithBody {
 | 
			
		||||
                ExprOrPatId::PatId(pat) => source_map.pat_syntax(pat).map(Either::Right),
 | 
			
		||||
            };
 | 
			
		||||
            let expr_or_pat = match expr_or_pat {
 | 
			
		||||
                Ok(Either::Left(expr)) => Either::Left(expr),
 | 
			
		||||
                Ok(Either::Right(InFile { file_id, value: Either::Left(pat) })) => {
 | 
			
		||||
                    Either::Right(InFile { file_id, value: pat })
 | 
			
		||||
                Ok(Either::Left(expr)) => expr.map(AstPtr::wrap_left),
 | 
			
		||||
                Ok(Either::Right(InFile { file_id, value: pat })) => {
 | 
			
		||||
                    // cast from Either<Pat, SelfParam> -> Either<_, Pat>
 | 
			
		||||
                    let Some(ptr) = AstPtr::try_from_raw(pat.syntax_node_ptr()) else {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    };
 | 
			
		||||
                    InFile { file_id, value: ptr }
 | 
			
		||||
                }
 | 
			
		||||
                Ok(Either::Right(_)) | Err(SyntheticSyntax) => continue,
 | 
			
		||||
                Err(SyntheticSyntax) => continue,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            acc.push(
 | 
			
		||||
@ -1667,10 +1676,7 @@ impl DefWithBody {
 | 
			
		||||
                            Err(_) => continue,
 | 
			
		||||
                        },
 | 
			
		||||
                        mir::MirSpan::PatId(p) => match source_map.pat_syntax(p) {
 | 
			
		||||
                            Ok(s) => s.map(|it| match it {
 | 
			
		||||
                                Either::Left(e) => e.into(),
 | 
			
		||||
                                Either::Right(e) => e.into(),
 | 
			
		||||
                            }),
 | 
			
		||||
                            Ok(s) => s.map(|it| it.into()),
 | 
			
		||||
                            Err(_) => continue,
 | 
			
		||||
                        },
 | 
			
		||||
                        mir::MirSpan::Unknown => continue,
 | 
			
		||||
@ -1721,10 +1727,7 @@ impl DefWithBody {
 | 
			
		||||
                                        Err(_) => continue,
 | 
			
		||||
                                    },
 | 
			
		||||
                                    mir::MirSpan::PatId(p) => match source_map.pat_syntax(*p) {
 | 
			
		||||
                                        Ok(s) => s.map(|it| match it {
 | 
			
		||||
                                            Either::Left(e) => e.into(),
 | 
			
		||||
                                            Either::Right(e) => e.into(),
 | 
			
		||||
                                        }),
 | 
			
		||||
                                        Ok(s) => s.map(|it| it.into()),
 | 
			
		||||
                                        Err(_) => continue,
 | 
			
		||||
                                    },
 | 
			
		||||
                                    mir::MirSpan::Unknown => continue,
 | 
			
		||||
@ -1763,18 +1766,18 @@ impl DefWithBody {
 | 
			
		||||
                            Ok(source_ptr) => {
 | 
			
		||||
                                let root = source_ptr.file_syntax(db.upcast());
 | 
			
		||||
                                if let ast::Expr::RecordExpr(record_expr) =
 | 
			
		||||
                                    &source_ptr.value.to_node(&root)
 | 
			
		||||
                                    source_ptr.value.to_node(&root)
 | 
			
		||||
                                {
 | 
			
		||||
                                    if record_expr.record_expr_field_list().is_some() {
 | 
			
		||||
                                        let field_list_parent_path =
 | 
			
		||||
                                            record_expr.path().map(|path| AstPtr::new(&path));
 | 
			
		||||
                                        acc.push(
 | 
			
		||||
                                            MissingFields {
 | 
			
		||||
                                                file: source_ptr.file_id,
 | 
			
		||||
                                                field_list_parent: Either::Left(AstPtr::new(
 | 
			
		||||
                                                field_list_parent: AstPtr::new(&Either::Left(
 | 
			
		||||
                                                    record_expr,
 | 
			
		||||
                                                )),
 | 
			
		||||
                                                field_list_parent_path: record_expr
 | 
			
		||||
                                                    .path()
 | 
			
		||||
                                                    .map(|path| AstPtr::new(&path)),
 | 
			
		||||
                                                field_list_parent_path,
 | 
			
		||||
                                                missed_fields,
 | 
			
		||||
                                            }
 | 
			
		||||
                                            .into(),
 | 
			
		||||
@ -1786,19 +1789,20 @@ impl DefWithBody {
 | 
			
		||||
                        },
 | 
			
		||||
                        Either::Right(record_pat) => match source_map.pat_syntax(record_pat) {
 | 
			
		||||
                            Ok(source_ptr) => {
 | 
			
		||||
                                if let Some(expr) = source_ptr.value.as_ref().left() {
 | 
			
		||||
                                if let Some(ptr) = source_ptr.value.clone().cast::<ast::RecordPat>()
 | 
			
		||||
                                {
 | 
			
		||||
                                    let root = source_ptr.file_syntax(db.upcast());
 | 
			
		||||
                                    if let ast::Pat::RecordPat(record_pat) = expr.to_node(&root) {
 | 
			
		||||
                                    let record_pat = ptr.to_node(&root);
 | 
			
		||||
                                    if record_pat.record_pat_field_list().is_some() {
 | 
			
		||||
                                        let field_list_parent_path =
 | 
			
		||||
                                            record_pat.path().map(|path| AstPtr::new(&path));
 | 
			
		||||
                                        acc.push(
 | 
			
		||||
                                            MissingFields {
 | 
			
		||||
                                                file: source_ptr.file_id,
 | 
			
		||||
                                                    field_list_parent: Either::Right(AstPtr::new(
 | 
			
		||||
                                                        &record_pat,
 | 
			
		||||
                                                field_list_parent: AstPtr::new(&Either::Right(
 | 
			
		||||
                                                    record_pat,
 | 
			
		||||
                                                )),
 | 
			
		||||
                                                    field_list_parent_path: record_pat
 | 
			
		||||
                                                        .path()
 | 
			
		||||
                                                        .map(|path| AstPtr::new(&path)),
 | 
			
		||||
                                                field_list_parent_path,
 | 
			
		||||
                                                missed_fields,
 | 
			
		||||
                                            }
 | 
			
		||||
                                            .into(),
 | 
			
		||||
@ -1806,7 +1810,6 @@ impl DefWithBody {
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            }
 | 
			
		||||
                            Err(SyntheticSyntax) => (),
 | 
			
		||||
                        },
 | 
			
		||||
                    }
 | 
			
		||||
@ -2948,10 +2951,10 @@ impl Local {
 | 
			
		||||
            .map(|&definition| {
 | 
			
		||||
                let src = source_map.pat_syntax(definition).unwrap(); // Hmm...
 | 
			
		||||
                let root = src.file_syntax(db.upcast());
 | 
			
		||||
                src.map(|ast| match ast {
 | 
			
		||||
                    // Suspicious unwrap
 | 
			
		||||
                    Either::Left(it) => Either::Left(it.cast().unwrap().to_node(&root)),
 | 
			
		||||
                    Either::Right(it) => Either::Right(it.to_node(&root)),
 | 
			
		||||
                src.map(|ast| match ast.to_node(&root) {
 | 
			
		||||
                    Either::Left(ast::Pat::IdentPat(it)) => Either::Left(it),
 | 
			
		||||
                    Either::Left(_) => unreachable!("local with non ident-pattern"),
 | 
			
		||||
                    Either::Right(it) => Either::Right(it),
 | 
			
		||||
                })
 | 
			
		||||
            })
 | 
			
		||||
            .map(move |source| LocalSource { local: self, source })
 | 
			
		||||
 | 
			
		||||
@ -23,12 +23,7 @@ pub(crate) fn mismatched_tuple_struct_pat_arg_count(
 | 
			
		||||
    Diagnostic::new(
 | 
			
		||||
        DiagnosticCode::RustcHardError("E0023"),
 | 
			
		||||
        message,
 | 
			
		||||
        invalid_args_range(
 | 
			
		||||
            ctx,
 | 
			
		||||
            d.expr_or_pat.clone().map(|it| it.either(Into::into, Into::into)),
 | 
			
		||||
            d.expected,
 | 
			
		||||
            d.found,
 | 
			
		||||
        ),
 | 
			
		||||
        invalid_args_range(ctx, d.expr_or_pat.clone().map(Into::into), d.expected, d.found),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ pub(crate) fn missing_fields(ctx: &DiagnosticsContext<'_>, d: &hir::MissingField
 | 
			
		||||
        d.field_list_parent_path
 | 
			
		||||
            .clone()
 | 
			
		||||
            .map(SyntaxNodePtr::from)
 | 
			
		||||
            .unwrap_or_else(|| d.field_list_parent.clone().either(|it| it.into(), |it| it.into())),
 | 
			
		||||
            .unwrap_or_else(|| d.field_list_parent.clone().into()),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    Diagnostic::new_with_syntax_node_ptr(ctx, DiagnosticCode::RustcHardError("E0063"), message, ptr)
 | 
			
		||||
@ -58,10 +58,8 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
 | 
			
		||||
 | 
			
		||||
    let root = ctx.sema.db.parse_or_expand(d.file);
 | 
			
		||||
 | 
			
		||||
    let current_module = match &d.field_list_parent {
 | 
			
		||||
        Either::Left(ptr) => ctx.sema.scope(ptr.to_node(&root).syntax()).map(|it| it.module()),
 | 
			
		||||
        Either::Right(ptr) => ctx.sema.scope(ptr.to_node(&root).syntax()).map(|it| it.module()),
 | 
			
		||||
    };
 | 
			
		||||
    let current_module =
 | 
			
		||||
        ctx.sema.scope(d.field_list_parent.to_node(&root).syntax()).map(|it| it.module());
 | 
			
		||||
 | 
			
		||||
    let build_text_edit = |parent_syntax, new_syntax: &SyntaxNode, old_syntax| {
 | 
			
		||||
        let edit = {
 | 
			
		||||
@ -87,9 +85,8 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
 | 
			
		||||
        )])
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    match &d.field_list_parent {
 | 
			
		||||
        Either::Left(record_expr) => {
 | 
			
		||||
            let field_list_parent = record_expr.to_node(&root);
 | 
			
		||||
    match &d.field_list_parent.to_node(&root) {
 | 
			
		||||
        Either::Left(field_list_parent) => {
 | 
			
		||||
            let missing_fields = ctx.sema.record_literal_missing_fields(&field_list_parent);
 | 
			
		||||
 | 
			
		||||
            let mut locals = FxHashMap::default();
 | 
			
		||||
@ -152,8 +149,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
 | 
			
		||||
                old_field_list.syntax(),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        Either::Right(record_pat) => {
 | 
			
		||||
            let field_list_parent = record_pat.to_node(&root);
 | 
			
		||||
        Either::Right(field_list_parent) => {
 | 
			
		||||
            let missing_fields = ctx.sema.record_pattern_missing_fields(&field_list_parent);
 | 
			
		||||
 | 
			
		||||
            let old_field_list = field_list_parent.record_pat_field_list()?;
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ use crate::{fix, Assist, Diagnostic, DiagnosticCode, DiagnosticsContext};
 | 
			
		||||
//
 | 
			
		||||
// This diagnostic is triggered if created structure does not have field provided in record.
 | 
			
		||||
pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Diagnostic {
 | 
			
		||||
    let node = d.field.clone().map(|it| it.either(Into::into, Into::into));
 | 
			
		||||
    let node = d.field.clone().map(Into::into);
 | 
			
		||||
    if d.private {
 | 
			
		||||
        // FIXME: quickfix to add required visibility
 | 
			
		||||
        Diagnostic::new_with_syntax_node_ptr(
 | 
			
		||||
@ -35,15 +35,13 @@ pub(crate) fn no_such_field(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField)
 | 
			
		||||
 | 
			
		||||
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::NoSuchField) -> Option<Vec<Assist>> {
 | 
			
		||||
    // FIXME: quickfix for pattern
 | 
			
		||||
    match &d.field.value {
 | 
			
		||||
        Either::Left(ptr) => {
 | 
			
		||||
    let root = ctx.sema.db.parse_or_expand(d.field.file_id);
 | 
			
		||||
            missing_record_expr_field_fixes(
 | 
			
		||||
    match &d.field.value.to_node(&root) {
 | 
			
		||||
        Either::Left(node) => missing_record_expr_field_fixes(
 | 
			
		||||
            &ctx.sema,
 | 
			
		||||
            d.field.file_id.original_file(ctx.sema.db),
 | 
			
		||||
                &ptr.to_node(&root),
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
            node,
 | 
			
		||||
        ),
 | 
			
		||||
        _ => None,
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,3 @@
 | 
			
		||||
use either::Either;
 | 
			
		||||
 | 
			
		||||
use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
 | 
			
		||||
 | 
			
		||||
// Diagnostic: private-assoc-item
 | 
			
		||||
@ -28,13 +26,7 @@ pub(crate) fn private_assoc_item(
 | 
			
		||||
            },
 | 
			
		||||
            name,
 | 
			
		||||
        ),
 | 
			
		||||
        d.expr_or_pat.clone().map(|it| match it {
 | 
			
		||||
            Either::Left(it) => it.into(),
 | 
			
		||||
            Either::Right(it) => match it {
 | 
			
		||||
                Either::Left(it) => it.into(),
 | 
			
		||||
                Either::Right(it) => it.into(),
 | 
			
		||||
            },
 | 
			
		||||
        }),
 | 
			
		||||
        d.expr_or_pat.clone().map(Into::into),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,3 @@
 | 
			
		||||
use either::Either;
 | 
			
		||||
use hir::{db::ExpandDatabase, ClosureStyle, HirDisplay, InFile, Type};
 | 
			
		||||
use ide_db::{famous_defs::FamousDefs, source_change::SourceChange};
 | 
			
		||||
use syntax::{
 | 
			
		||||
@ -14,9 +13,11 @@ use crate::{adjusted_display_range, fix, Assist, Diagnostic, DiagnosticCode, Dia
 | 
			
		||||
// This diagnostic is triggered when the type of an expression or pattern does not match
 | 
			
		||||
// the expected type.
 | 
			
		||||
pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Diagnostic {
 | 
			
		||||
    let display_range = match &d.expr_or_pat {
 | 
			
		||||
        Either::Left(expr) => {
 | 
			
		||||
            adjusted_display_range::<ast::Expr>(ctx, expr.clone().map(|it| it.into()), &|expr| {
 | 
			
		||||
    let display_range = match &d.expr_or_pat.value {
 | 
			
		||||
        expr if ast::Expr::can_cast(expr.kind()) => adjusted_display_range::<ast::Expr>(
 | 
			
		||||
            ctx,
 | 
			
		||||
            InFile { file_id: d.expr_or_pat.file_id, value: expr.syntax_node_ptr() },
 | 
			
		||||
            &|expr| {
 | 
			
		||||
                let salient_token_range = match expr {
 | 
			
		||||
                    ast::Expr::IfExpr(it) => it.if_token()?.text_range(),
 | 
			
		||||
                    ast::Expr::LoopExpr(it) => it.loop_token()?.text_range(),
 | 
			
		||||
@ -32,10 +33,15 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch)
 | 
			
		||||
 | 
			
		||||
                cov_mark::hit!(type_mismatch_range_adjustment);
 | 
			
		||||
                Some(salient_token_range)
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        pat => {
 | 
			
		||||
            ctx.sema
 | 
			
		||||
                .diagnostics_display_range(InFile {
 | 
			
		||||
                    file_id: d.expr_or_pat.file_id,
 | 
			
		||||
                    value: pat.syntax_node_ptr(),
 | 
			
		||||
                })
 | 
			
		||||
        }
 | 
			
		||||
        Either::Right(pat) => {
 | 
			
		||||
            ctx.sema.diagnostics_display_range(pat.clone().map(|it| it.into())).range
 | 
			
		||||
                .range
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    let mut diag = Diagnostic::new(
 | 
			
		||||
@ -57,15 +63,13 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch)
 | 
			
		||||
fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option<Vec<Assist>> {
 | 
			
		||||
    let mut fixes = Vec::new();
 | 
			
		||||
 | 
			
		||||
    match &d.expr_or_pat {
 | 
			
		||||
        Either::Left(expr_ptr) => {
 | 
			
		||||
    if let Some(expr_ptr) = d.expr_or_pat.value.clone().cast::<ast::Expr>() {
 | 
			
		||||
        let expr_ptr = &InFile { file_id: d.expr_or_pat.file_id, value: expr_ptr.clone() };
 | 
			
		||||
        add_reference(ctx, d, expr_ptr, &mut fixes);
 | 
			
		||||
        add_missing_ok_or_some(ctx, d, expr_ptr, &mut fixes);
 | 
			
		||||
        remove_semicolon(ctx, d, expr_ptr, &mut fixes);
 | 
			
		||||
        str_ref_to_owned(ctx, d, expr_ptr, &mut fixes);
 | 
			
		||||
    }
 | 
			
		||||
        Either::Right(_pat_ptr) => {}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if fixes.is_empty() {
 | 
			
		||||
        None
 | 
			
		||||
 | 
			
		||||
@ -846,9 +846,7 @@ fn location_csv_pat(db: &RootDatabase, vfs: &Vfs, sm: &BodySourceMap, pat_id: Pa
 | 
			
		||||
        Err(SyntheticSyntax) => return "synthetic,,".to_string(),
 | 
			
		||||
    };
 | 
			
		||||
    let root = db.parse_or_expand(src.file_id);
 | 
			
		||||
    let node = src.map(|e| {
 | 
			
		||||
        e.either(|it| it.to_node(&root).syntax().clone(), |it| it.to_node(&root).syntax().clone())
 | 
			
		||||
    });
 | 
			
		||||
    let node = src.map(|e| e.to_node(&root).syntax().clone());
 | 
			
		||||
    let original_range = node.as_ref().original_file_range(db);
 | 
			
		||||
    let path = vfs.file_path(original_range.file_id);
 | 
			
		||||
    let line_index = db.line_index(original_range.file_id);
 | 
			
		||||
@ -888,12 +886,7 @@ fn pat_syntax_range(
 | 
			
		||||
    let src = sm.pat_syntax(pat_id);
 | 
			
		||||
    if let Ok(src) = src {
 | 
			
		||||
        let root = db.parse_or_expand(src.file_id);
 | 
			
		||||
        let node = src.map(|e| {
 | 
			
		||||
            e.either(
 | 
			
		||||
                |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
                |it| it.to_node(&root).syntax().clone(),
 | 
			
		||||
            )
 | 
			
		||||
        });
 | 
			
		||||
        let node = src.map(|e| e.to_node(&root).syntax().clone());
 | 
			
		||||
        let original_range = node.as_ref().original_file_range(db);
 | 
			
		||||
        let path = vfs.file_path(original_range.file_id);
 | 
			
		||||
        let line_index = db.line_index(original_range.file_id);
 | 
			
		||||
 | 
			
		||||
@ -73,6 +73,10 @@ impl<N: AstNode> AstPtr<N> {
 | 
			
		||||
        Some(AstPtr { raw: self.raw, _ty: PhantomData })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn kind(&self) -> parser::SyntaxKind {
 | 
			
		||||
        self.raw.kind()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn upcast<M: AstNode>(self) -> AstPtr<M>
 | 
			
		||||
    where
 | 
			
		||||
        N: Into<M>,
 | 
			
		||||
@ -84,6 +88,20 @@ impl<N: AstNode> AstPtr<N> {
 | 
			
		||||
    pub fn try_from_raw(raw: SyntaxNodePtr) -> Option<AstPtr<N>> {
 | 
			
		||||
        N::can_cast(raw.kind()).then_some(AstPtr { raw, _ty: PhantomData })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn wrap_left<R>(self) -> AstPtr<either::Either<N, R>>
 | 
			
		||||
    where
 | 
			
		||||
        either::Either<N, R>: AstNode,
 | 
			
		||||
    {
 | 
			
		||||
        AstPtr { raw: self.raw, _ty: PhantomData }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn wrap_right<L>(self) -> AstPtr<either::Either<L, N>>
 | 
			
		||||
    where
 | 
			
		||||
        either::Either<L, N>: AstNode,
 | 
			
		||||
    {
 | 
			
		||||
        AstPtr { raw: self.raw, _ty: PhantomData }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user