diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs index a165ba85e61..9caa084f2a2 100644 --- a/crates/hir-def/src/body.rs +++ b/crates/hir-def/src/body.rs @@ -13,11 +13,12 @@ use cfg::{CfgExpr, CfgOptions}; use drop_bomb::DropBomb; use either::Either; use hir_expand::{ - attrs::RawAttrs, hygiene::Hygiene, name::Name, ExpandError, ExpandResult, HirFileId, InFile, - MacroCallId, + ast_id_map::AstIdMap, attrs::RawAttrs, hygiene::Hygiene, name::Name, AstId, ExpandError, + ExpandResult, HirFileId, InFile, MacroCallId, }; use la_arena::{Arena, ArenaMap}; use limit::Limit; +use once_cell::unsync::OnceCell; use profile::Count; use rustc_hash::FxHashMap; use syntax::{ast, AstPtr, SyntaxNode, SyntaxNodePtr}; @@ -37,7 +38,43 @@ use crate::{ UnresolvedMacro, }; -pub use lower::LowerCtx; +pub struct LowerCtx<'a> { + pub db: &'a dyn DefDatabase, + hygiene: Hygiene, + ast_id_map: Option<(HirFileId, OnceCell>)>, +} + +impl<'a> LowerCtx<'a> { + pub fn new(db: &'a dyn DefDatabase, hygiene: &Hygiene, file_id: HirFileId) -> Self { + LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: Some((file_id, OnceCell::new())) } + } + + pub fn with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { + LowerCtx { + db, + hygiene: Hygiene::new(db.upcast(), file_id), + ast_id_map: Some((file_id, OnceCell::new())), + } + } + + pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self { + LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: None } + } + + pub(crate) fn hygiene(&self) -> &Hygiene { + &self.hygiene + } + + pub(crate) fn lower_path(&self, ast: ast::Path) -> Option { + Path::from_src(ast, self) + } + + pub(crate) fn ast_id(&self, item: &N) -> Option> { + let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?; + let ast_id_map = ast_id_map.get_or_init(|| self.db.ast_id_map(file_id)); + Some(InFile::new(file_id, ast_id_map.ast_id(item))) + } +} /// A subset of Expander that only deals with cfg attributes. We only need it to /// avoid cyclic queries in crate def map during enum processing. @@ -241,7 +278,7 @@ impl Expander { // The overflow error should have been reported when it occurred (see the next branch), // so don't return overflow error here to avoid diagnostics duplication. cov_mark::hit!(overflow_but_not_me); - return ExpandResult::only_err(ExpandError::RecursionOverflowPosioned); + return ExpandResult::only_err(ExpandError::RecursionOverflowPoisoned); } else if self.recursion_limit(db).check(self.recursion_depth + 1).is_err() { self.recursion_depth = usize::MAX; cov_mark::hit!(your_stack_belongs_to_me); diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs index b87fb94d923..e6bea706d83 100644 --- a/crates/hir-def/src/body/lower.rs +++ b/crates/hir-def/src/body/lower.rs @@ -7,36 +7,30 @@ use base_db::CrateId; use either::Either; use hir_expand::{ ast_id_map::AstIdMap, - hygiene::Hygiene, name::{name, AsName, Name}, - AstId, ExpandError, HirFileId, InFile, + AstId, ExpandError, InFile, }; use intern::Interned; use la_arena::Arena; -use once_cell::unsync::OnceCell; use profile::Count; use rustc_hash::FxHashMap; use smallvec::SmallVec; use syntax::{ ast::{ - self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasLoopBody, HasName, LiteralKind, + self, ArrayExprKind, AstChildren, BlockExpr, HasArgList, HasLoopBody, HasName, SlicePatComponents, }, AstNode, AstPtr, SyntaxNodePtr, }; use crate::{ - body::{ - Body, BodyDiagnostic, BodySourceMap, Expander, ExprPtr, ExprSource, LabelPtr, LabelSource, - PatPtr, PatSource, - }, - builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, + body::{Body, BodyDiagnostic, BodySourceMap, Expander, ExprPtr, LabelPtr, LowerCtx, PatPtr}, data::adt::StructKind, db::DefDatabase, hir::{ dummy_expr_id, Array, Binding, BindingAnnotation, BindingId, ClosureKind, Expr, ExprId, - FloatTypeWrapper, Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, - RecordFieldPat, RecordLitField, Statement, + Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, RecordFieldPat, RecordLitField, + Statement, }, item_scope::BuiltinShadowMode, lang_item::LangItem, @@ -45,44 +39,6 @@ use crate::{ AdtId, BlockId, BlockLoc, ModuleDefId, UnresolvedMacro, }; -pub struct LowerCtx<'a> { - pub db: &'a dyn DefDatabase, - hygiene: Hygiene, - ast_id_map: Option<(HirFileId, OnceCell>)>, -} - -impl<'a> LowerCtx<'a> { - pub fn new(db: &'a dyn DefDatabase, hygiene: &Hygiene, file_id: HirFileId) -> Self { - LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: Some((file_id, OnceCell::new())) } - } - - pub fn with_file_id(db: &'a dyn DefDatabase, file_id: HirFileId) -> Self { - LowerCtx { - db, - hygiene: Hygiene::new(db.upcast(), file_id), - ast_id_map: Some((file_id, OnceCell::new())), - } - } - - pub fn with_hygiene(db: &'a dyn DefDatabase, hygiene: &Hygiene) -> Self { - LowerCtx { db, hygiene: hygiene.clone(), ast_id_map: None } - } - - pub(crate) fn hygiene(&self) -> &Hygiene { - &self.hygiene - } - - pub(crate) fn lower_path(&self, ast: ast::Path) -> Option { - Path::from_src(ast, self) - } - - pub(crate) fn ast_id(&self, item: &N) -> Option> { - let &(file_id, ref ast_id_map) = self.ast_id_map.as_ref()?; - let ast_id_map = ast_id_map.get_or_init(|| self.db.ast_id_map(file_id)); - Some(InFile::new(file_id, ast_id_map.ast_id(item))) - } -} - pub(super) fn lower( db: &dyn DefDatabase, expander: Expander, @@ -119,12 +75,22 @@ struct ExprCollector<'a> { db: &'a dyn DefDatabase, expander: Expander, ast_id_map: Arc, - body: Body, krate: CrateId, + body: Body, source_map: BodySourceMap, - current_try_block_label: Option, + is_lowering_assignee_expr: bool, is_lowering_generator: bool, + + current_try_block_label: Option, + // points to the expression that a try expression will target (replaces current_try_block_label) + // catch_scope: Option, + // points to the expression that an unlabeled control flow will target + // loop_scope: Option, + // needed to diagnose non label control flow in while conditions + // is_in_loop_condition: bool, + + // resolution label_ribs: Vec, } @@ -202,12 +168,9 @@ impl ExprCollector<'_> { self.body.params.push(param_pat); } - for pat in param_list - .params() - .zip(attr_enabled) - .filter_map(|(param, enabled)| param.pat().filter(|_| enabled)) + for (param, _) in param_list.params().zip(attr_enabled).filter(|(_, enabled)| *enabled) { - let param_pat = self.collect_pat(pat); + let param_pat = self.collect_pat_top(param.pat()); self.body.params.push(param_pat); } }; @@ -236,63 +199,6 @@ impl ExprCollector<'_> { self.expander.ctx(self.db) } - fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { - let src = self.expander.to_source(ptr); - let id = self.make_expr(expr, src.clone()); - self.source_map.expr_map.insert(src, id); - id - } - // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed somehow. - fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { - self.body.exprs.alloc(expr) - } - fn missing_expr(&mut self) -> ExprId { - self.alloc_expr_desugared(Expr::Missing) - } - fn make_expr(&mut self, expr: Expr, src: ExprSource) -> ExprId { - let id = self.body.exprs.alloc(expr); - self.source_map.expr_map_back.insert(id, src); - id - } - - fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId { - self.body.bindings.alloc(Binding { name, mode, definitions: SmallVec::new() }) - } - fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { - let src = self.expander.to_source(ptr); - let id = self.make_pat(pat, src.clone()); - self.source_map.pat_map.insert(src, id); - id - } - // FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow. - fn alloc_pat_desugared(&mut self, pat: Pat) -> PatId { - self.body.pats.alloc(pat) - } - fn missing_pat(&mut self) -> PatId { - self.body.pats.alloc(Pat::Missing) - } - fn make_pat(&mut self, pat: Pat, src: PatSource) -> PatId { - let id = self.body.pats.alloc(pat); - self.source_map.pat_map_back.insert(id, src); - id - } - - fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId { - let src = self.expander.to_source(ptr); - let id = self.make_label(label, src.clone()); - self.source_map.label_map.insert(src, id); - id - } - // FIXME: desugared labels don't have ptr, that's wrong and should be fixed somehow. - fn alloc_label_desugared(&mut self, label: Label) -> LabelId { - self.body.labels.alloc(label) - } - fn make_label(&mut self, label: Label, src: LabelSource) -> LabelId { - let id = self.body.labels.alloc(label); - self.source_map.label_map_back.insert(id, src); - id - } - fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr()) } @@ -320,7 +226,7 @@ impl ExprCollector<'_> { self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) } ast::Expr::LetExpr(e) => { - let pat = self.collect_pat_opt(e.pat()); + let pat = self.collect_pat_top(e.pat()); let expr = self.collect_expr_opt(e.expr()); self.alloc_expr(Expr::Let { pat, expr }, syntax_ptr) } @@ -379,7 +285,7 @@ impl ExprCollector<'_> { ast::Expr::ForExpr(e) => { let label = e.label().map(|label| self.collect_label(label)); let iterable = self.collect_expr_opt(e.iterable()); - let pat = self.collect_pat_opt(e.pat()); + let pat = self.collect_pat_top(e.pat()); let body = self.collect_labelled_block_opt(label, e.loop_body()); self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr) } @@ -419,7 +325,7 @@ impl ExprCollector<'_> { .arms() .filter_map(|arm| { self.check_cfg(&arm).map(|()| MatchArm { - pat: self.collect_pat_opt(arm.pat()), + pat: self.collect_pat_top(arm.pat()), expr: self.collect_expr_opt(arm.expr()), guard: arm .guard() @@ -559,7 +465,7 @@ impl ExprCollector<'_> { let mut arg_types = Vec::new(); if let Some(pl) = e.param_list() { for param in pl.params() { - let pat = this.collect_pat_opt(param.pat()); + let pat = this.collect_pat_top(param.pat()); let type_ref = param.ty().map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it))); args.push(pat); @@ -571,8 +477,7 @@ impl ExprCollector<'_> { .and_then(|r| r.ty()) .map(|it| Interned::new(TypeRef::from_ast(&this.ctx(), it))); - let prev_is_lowering_generator = this.is_lowering_generator; - this.is_lowering_generator = false; + let prev_is_lowering_generator = mem::take(&mut this.is_lowering_generator); let body = this.collect_expr_opt(e.body()); @@ -850,7 +755,7 @@ impl ExprCollector<'_> { krate: *krate, }); } - Some(ExpandError::RecursionOverflowPosioned) => { + Some(ExpandError::RecursionOverflowPoisoned) => { // Recursion limit has been reached in the macro expansion tree, but not in // this very macro call. Don't add diagnostics to avoid duplication. } @@ -931,7 +836,7 @@ impl ExprCollector<'_> { if self.check_cfg(&stmt).is_none() { return; } - let pat = self.collect_pat_opt(stmt.pat()); + let pat = self.collect_pat_top(stmt.pat()); let type_ref = stmt.ty().map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it))); let initializer = stmt.initializer().map(|e| self.collect_expr(e)); @@ -1052,32 +957,23 @@ impl ExprCollector<'_> { } } - fn collect_label(&mut self, ast_label: ast::Label) -> LabelId { - let label = Label { - name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime), - }; - self.alloc_label(label, AstPtr::new(&ast_label)) - } + // region: patterns - fn collect_pat(&mut self, pat: ast::Pat) -> PatId { - self.collect_pat_(pat, &mut BindingList::default()) - } - - fn collect_pat_opt(&mut self, pat: Option) -> PatId { + fn collect_pat_top(&mut self, pat: Option) -> PatId { match pat { - Some(pat) => self.collect_pat(pat), + Some(pat) => self.collect_pat(pat, &mut BindingList::default()), None => self.missing_pat(), } } - fn collect_pat_(&mut self, pat: ast::Pat, binding_list: &mut BindingList) -> PatId { + fn collect_pat(&mut self, pat: ast::Pat, binding_list: &mut BindingList) -> PatId { let pattern = match &pat { ast::Pat::IdentPat(bp) => { let name = bp.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); let annotation = BindingAnnotation::new(bp.mut_token().is_some(), bp.ref_token().is_some()); - let subpat = bp.pat().map(|subpat| self.collect_pat_(subpat, binding_list)); + let subpat = bp.pat().map(|subpat| self.collect_pat(subpat, binding_list)); let is_simple_ident_pat = annotation == BindingAnnotation::Unannotated && subpat.is_none(); @@ -1131,7 +1027,7 @@ impl ExprCollector<'_> { Pat::TupleStruct { path, args, ellipsis } } ast::Pat::RefPat(p) => { - let pat = self.collect_pat_opt_(p.pat(), binding_list); + let pat = self.collect_pat_opt(p.pat(), binding_list); let mutability = Mutability::from_mutable(p.mut_token().is_some()); Pat::Ref { pat, mutability } } @@ -1141,10 +1037,10 @@ impl ExprCollector<'_> { path.map(Pat::Path).unwrap_or(Pat::Missing) } ast::Pat::OrPat(p) => { - let pats = p.pats().map(|p| self.collect_pat_(p, binding_list)).collect(); + let pats = p.pats().map(|p| self.collect_pat(p, binding_list)).collect(); Pat::Or(pats) } - ast::Pat::ParenPat(p) => return self.collect_pat_opt_(p.pat(), binding_list), + ast::Pat::ParenPat(p) => return self.collect_pat_opt(p.pat(), binding_list), ast::Pat::TuplePat(p) => { let (args, ellipsis) = self.collect_tuple_pat(p.fields(), binding_list); Pat::Tuple { args, ellipsis } @@ -1159,7 +1055,7 @@ impl ExprCollector<'_> { .fields() .filter_map(|f| { let ast_pat = f.pat()?; - let pat = self.collect_pat_(ast_pat, binding_list); + let pat = self.collect_pat(ast_pat, binding_list); let name = f.field_name()?.as_name(); Some(RecordFieldPat { name, pat }) }) @@ -1178,15 +1074,9 @@ impl ExprCollector<'_> { // FIXME properly handle `RestPat` Pat::Slice { - prefix: prefix - .into_iter() - .map(|p| self.collect_pat_(p, binding_list)) - .collect(), - slice: slice.map(|p| self.collect_pat_(p, binding_list)), - suffix: suffix - .into_iter() - .map(|p| self.collect_pat_(p, binding_list)) - .collect(), + prefix: prefix.into_iter().map(|p| self.collect_pat(p, binding_list)).collect(), + slice: slice.map(|p| self.collect_pat(p, binding_list)), + suffix: suffix.into_iter().map(|p| self.collect_pat(p, binding_list)).collect(), } } #[rustfmt::skip] // https://github.com/rust-lang/rustfmt/issues/5676 @@ -1217,7 +1107,7 @@ impl ExprCollector<'_> { Pat::Missing } ast::Pat::BoxPat(boxpat) => { - let inner = self.collect_pat_opt_(boxpat.pat(), binding_list); + let inner = self.collect_pat_opt(boxpat.pat(), binding_list); Pat::Box { inner } } ast::Pat::ConstBlockPat(const_block_pat) => { @@ -1235,7 +1125,7 @@ impl ExprCollector<'_> { let src = self.expander.to_source(Either::Left(AstPtr::new(&pat))); let pat = self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { - this.collect_pat_opt_(expanded_pat, binding_list) + this.collect_pat_opt(expanded_pat, binding_list) }); self.source_map.pat_map.insert(src, pat); return pat; @@ -1249,9 +1139,9 @@ impl ExprCollector<'_> { self.alloc_pat(pattern, Either::Left(ptr)) } - fn collect_pat_opt_(&mut self, pat: Option, binding_list: &mut BindingList) -> PatId { + fn collect_pat_opt(&mut self, pat: Option, binding_list: &mut BindingList) -> PatId { match pat { - Some(pat) => self.collect_pat_(pat, binding_list), + Some(pat) => self.collect_pat(pat, binding_list), None => self.missing_pat(), } } @@ -1267,12 +1157,14 @@ impl ExprCollector<'_> { // We want to skip the `..` pattern here, since we account for it above. let args = args .filter(|p| !matches!(p, ast::Pat::RestPat(_))) - .map(|p| self.collect_pat_(p, binding_list)) + .map(|p| self.collect_pat(p, binding_list)) .collect(); (args, ellipsis) } + // endregion: patterns + /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when /// not. fn check_cfg(&mut self, owner: &dyn ast::HasAttrs) -> Option<()> { @@ -1301,6 +1193,15 @@ impl ExprCollector<'_> { self.body.bindings[binding_id].definitions.push(pat_id); } + // region: labels + + fn collect_label(&mut self, ast_label: ast::Label) -> LabelId { + let label = Label { + name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime), + }; + self.alloc_label(label, AstPtr::new(&ast_label)) + } + fn resolve_label( &self, lifetime: Option, @@ -1351,42 +1252,53 @@ impl ExprCollector<'_> { self.label_ribs.pop(); res } + // endregion: labels } -impl From for Literal { - fn from(ast_lit_kind: ast::LiteralKind) -> Self { - match ast_lit_kind { - // FIXME: these should have actual values filled in, but unsure on perf impact - LiteralKind::IntNumber(lit) => { - if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { - Literal::Float( - FloatTypeWrapper::new(lit.float_value().unwrap_or(Default::default())), - builtin, - ) - } else if let builtin @ Some(_) = lit.suffix().and_then(BuiltinUint::from_suffix) { - Literal::Uint(lit.value().unwrap_or(0), builtin) - } else { - let builtin = lit.suffix().and_then(BuiltinInt::from_suffix); - Literal::Int(lit.value().unwrap_or(0) as i128, builtin) - } - } - LiteralKind::FloatNumber(lit) => { - let ty = lit.suffix().and_then(BuiltinFloat::from_suffix); - Literal::Float(FloatTypeWrapper::new(lit.value().unwrap_or(Default::default())), ty) - } - LiteralKind::ByteString(bs) => { - let text = bs.value().map(Box::from).unwrap_or_else(Default::default); - Literal::ByteString(text) - } - LiteralKind::String(s) => { - let text = s.value().map(Box::from).unwrap_or_else(Default::default); - Literal::String(text) - } - LiteralKind::Byte(b) => { - Literal::Uint(b.value().unwrap_or_default() as u128, Some(BuiltinUint::U8)) - } - LiteralKind::Char(c) => Literal::Char(c.value().unwrap_or_default()), - LiteralKind::Bool(val) => Literal::Bool(val), - } +impl ExprCollector<'_> { + fn alloc_expr(&mut self, expr: Expr, ptr: ExprPtr) -> ExprId { + let src = self.expander.to_source(ptr); + let id = self.body.exprs.alloc(expr); + self.source_map.expr_map_back.insert(id, src.clone()); + self.source_map.expr_map.insert(src, id); + id + } + // FIXME: desugared exprs don't have ptr, that's wrong and should be fixed somehow. + fn alloc_expr_desugared(&mut self, expr: Expr) -> ExprId { + self.body.exprs.alloc(expr) + } + fn missing_expr(&mut self) -> ExprId { + self.alloc_expr_desugared(Expr::Missing) + } + + fn alloc_binding(&mut self, name: Name, mode: BindingAnnotation) -> BindingId { + self.body.bindings.alloc(Binding { name, mode, definitions: SmallVec::new() }) + } + + fn alloc_pat(&mut self, pat: Pat, ptr: PatPtr) -> PatId { + let src = self.expander.to_source(ptr); + let id = self.body.pats.alloc(pat); + self.source_map.pat_map_back.insert(id, src.clone()); + self.source_map.pat_map.insert(src, id); + id + } + // FIXME: desugared pats don't have ptr, that's wrong and should be fixed somehow. + fn alloc_pat_desugared(&mut self, pat: Pat) -> PatId { + self.body.pats.alloc(pat) + } + fn missing_pat(&mut self) -> PatId { + self.body.pats.alloc(Pat::Missing) + } + + fn alloc_label(&mut self, label: Label, ptr: LabelPtr) -> LabelId { + let src = self.expander.to_source(ptr); + let id = self.body.labels.alloc(label); + self.source_map.label_map_back.insert(id, src.clone()); + self.source_map.label_map.insert(src, id); + id + } + // FIXME: desugared labels don't have ptr, that's wrong and should be fixed somehow. + fn alloc_label_desugared(&mut self, label: Label) -> LabelId { + self.body.labels.alloc(label) } } diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs index 0a5bcb55797..c5392240739 100644 --- a/crates/hir-def/src/body/pretty.rs +++ b/crates/hir-def/src/body/pretty.rs @@ -13,20 +13,16 @@ use crate::{ use super::*; pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBodyId) -> String { - let needs_semi; let header = match owner { DefWithBodyId::FunctionId(it) => { - needs_semi = false; let item_tree_id = it.lookup(db).id; - format!("fn {}(…) ", item_tree_id.item_tree(db)[item_tree_id.value].name) + format!("fn {}", item_tree_id.item_tree(db)[item_tree_id.value].name) } DefWithBodyId::StaticId(it) => { - needs_semi = true; let item_tree_id = it.lookup(db).id; format!("static {} = ", item_tree_id.item_tree(db)[item_tree_id.value].name) } DefWithBodyId::ConstId(it) => { - needs_semi = true; let item_tree_id = it.lookup(db).id; let name = match &item_tree_id.item_tree(db)[item_tree_id.value].name { Some(name) => name.to_string(), @@ -35,7 +31,6 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo format!("const {name} = ") } DefWithBodyId::VariantId(it) => { - needs_semi = false; let src = it.parent.child_source(db); let variant = &src.value[it.local_id]; let name = match &variant.name() { @@ -47,8 +42,18 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo }; let mut p = Printer { body, buf: header, indent_level: 0, needs_indent: false }; + if let DefWithBodyId::FunctionId(it) = owner { + p.buf.push('('); + body.params.iter().zip(&db.function_data(it).params).for_each(|(¶m, ty)| { + p.print_pat(param); + p.buf.push(':'); + p.print_type_ref(ty); + }); + p.buf.push(')'); + p.buf.push(' '); + } p.print_expr(body.body_expr); - if needs_semi { + if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) { p.buf.push(';'); } p.buf diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs index cdd3a93a293..8321ba1da6f 100644 --- a/crates/hir-def/src/hir.rs +++ b/crates/hir-def/src/hir.rs @@ -20,6 +20,7 @@ use hir_expand::name::Name; use intern::Interned; use la_arena::{Idx, RawIdx}; use smallvec::SmallVec; +use syntax::ast; use crate::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint}, @@ -104,6 +105,45 @@ impl Literal { } } +impl From for Literal { + fn from(ast_lit_kind: ast::LiteralKind) -> Self { + use ast::LiteralKind; + match ast_lit_kind { + // FIXME: these should have actual values filled in, but unsure on perf impact + LiteralKind::IntNumber(lit) => { + if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) { + Literal::Float( + FloatTypeWrapper::new(lit.float_value().unwrap_or(Default::default())), + builtin, + ) + } else if let builtin @ Some(_) = lit.suffix().and_then(BuiltinUint::from_suffix) { + Literal::Uint(lit.value().unwrap_or(0), builtin) + } else { + let builtin = lit.suffix().and_then(BuiltinInt::from_suffix); + Literal::Int(lit.value().unwrap_or(0) as i128, builtin) + } + } + LiteralKind::FloatNumber(lit) => { + let ty = lit.suffix().and_then(BuiltinFloat::from_suffix); + Literal::Float(FloatTypeWrapper::new(lit.value().unwrap_or(Default::default())), ty) + } + LiteralKind::ByteString(bs) => { + let text = bs.value().map(Box::from).unwrap_or_else(Default::default); + Literal::ByteString(text) + } + LiteralKind::String(s) => { + let text = s.value().map(Box::from).unwrap_or_else(Default::default); + Literal::String(text) + } + LiteralKind::Byte(b) => { + Literal::Uint(b.value().unwrap_or_default() as u128, Some(BuiltinUint::U8)) + } + LiteralKind::Char(c) => Literal::Char(c.value().unwrap_or_default()), + LiteralKind::Bool(val) => Literal::Bool(val), + } + } +} + #[derive(Debug, Clone, Eq, PartialEq)] pub enum Expr { /// This is produced if the syntax tree does not have a required expression piece. diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 980de3c2685..929dabcaf62 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs @@ -55,7 +55,7 @@ pub type ExpandResult = ValueResult; pub enum ExpandError { UnresolvedProcMacro(CrateId), Mbe(mbe::ExpandError), - RecursionOverflowPosioned, + RecursionOverflowPoisoned, Other(Box), } @@ -70,7 +70,7 @@ impl fmt::Display for ExpandError { match self { ExpandError::UnresolvedProcMacro(_) => f.write_str("unresolved proc-macro"), ExpandError::Mbe(it) => it.fmt(f), - ExpandError::RecursionOverflowPosioned => { + ExpandError::RecursionOverflowPoisoned => { f.write_str("overflow expanding the original macro") } ExpandError::Other(it) => f.write_str(it), diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index fd05e516c26..b37fe1d63d5 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -988,7 +988,7 @@ impl<'a> TyLoweringContext<'a> { // ignore `T: Drop` or `T: Destruct` bounds. // - `T: ~const Drop` has a special meaning in Rust 1.61 that we don't implement. // (So ideally, we'd only ignore `~const Drop` here) - // - `Destruct` impls are built-in in 1.62 (current nightlies as of 08-04-2022), so until + // - `Destruct` impls are built-in in 1.62 (current nightly as of 08-04-2022), so until // the builtin impls are supported by Chalk, we ignore them here. if let Some(lang) = lang_attr(self.db.upcast(), tr.hir_trait_id()) { if matches!(lang, LangItem::Drop | LangItem::Destruct) { @@ -1082,23 +1082,23 @@ impl<'a> TyLoweringContext<'a> { associated_ty_id: to_assoc_type_id(associated_ty), substitution, }; - let mut preds: SmallVec<[_; 1]> = SmallVec::with_capacity( + let mut predicates: SmallVec<[_; 1]> = SmallVec::with_capacity( binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), ); if let Some(type_ref) = &binding.type_ref { let ty = self.lower_ty(type_ref); let alias_eq = AliasEq { alias: AliasTy::Projection(projection_ty.clone()), ty }; - preds.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq))); + predicates.push(crate::wrap_empty_binders(WhereClause::AliasEq(alias_eq))); } for bound in binding.bounds.iter() { - preds.extend(self.lower_type_bound( + predicates.extend(self.lower_type_bound( bound, TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(Interner), false, )); } - preds + predicates }) } @@ -1165,7 +1165,7 @@ impl<'a> TyLoweringContext<'a> { return None; } - // As multiple occurrences of the same auto traits *are* permitted, we dedulicate the + // As multiple occurrences of the same auto traits *are* permitted, we deduplicate the // bounds. We shouldn't have repeated elements besides auto traits at this point. bounds.dedup();