From 2bb8956a102cb2efbea35e414a8214fba2efcaf6 Mon Sep 17 00:00:00 2001 From: oxalica Date: Sun, 14 Mar 2021 18:00:11 +0800 Subject: Introduce FunctionQualifier for hir::FunctionData --- crates/hir_ty/src/diagnostics/decl_check.rs | 2 +- crates/hir_ty/src/diagnostics/unsafe_check.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/hir_ty') diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 3605ca581..982ad5b9e 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs @@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> { fn validate_func(&mut self, func: FunctionId) { let data = self.db.function_data(func); - if data.is_extern { + if data.is_in_extern_block { cov_mark::hit!(extern_func_incorrect_case_ignored); return; } diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs index 20bb64827..44a7e5506 100644 --- a/crates/hir_ty/src/diagnostics/unsafe_check.rs +++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs @@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> { let def = self.owner.into(); let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); let is_unsafe = match self.owner { - DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, + DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, }; if is_unsafe @@ -86,7 +86,7 @@ fn walk_unsafe( match expr { &Expr::Call { callee, .. } => { if let Some(func) = infer[callee].as_fn_def(db) { - if db.function_data(func).is_unsafe { + if db.function_data(func).qualifier.is_unsafe { unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); } } @@ -103,7 +103,7 @@ fn walk_unsafe( Expr::MethodCall { .. } => { if infer .method_resolution(current) - .map(|func| db.function_data(func).is_unsafe) + .map(|func| db.function_data(func).qualifier.is_unsafe) .unwrap_or(false) { unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); -- cgit v1.2.3 From ef416e0154767619fcbfa0d1682b28bd338a8ce9 Mon Sep 17 00:00:00 2001 From: oxalica Date: Sun, 14 Mar 2021 20:03:39 +0800 Subject: Impl HirDisplay for function hover message --- crates/hir_ty/src/display.rs | 203 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 195 insertions(+), 8 deletions(-) (limited to 'crates/hir_ty') diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index c1062387e..c572bb114 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -5,7 +5,13 @@ use std::{borrow::Cow, fmt}; use arrayvec::ArrayVec; use chalk_ir::Mutability; use hir_def::{ - db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, + db::DefDatabase, + find_path, + generics::TypeParamProvenance, + item_scope::ItemInNs, + path::{GenericArg, Path, PathKind}, + type_ref::{TypeBound, TypeRef}, + visibility::Visibility, AssocContainerId, Lookup, ModuleId, TraitId, }; use hir_expand::name::Name; @@ -232,7 +238,7 @@ where const TYPE_HINT_TRUNCATION: &str = "…"; -impl HirDisplay for &Ty { +impl HirDisplay for &'_ T { fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { HirDisplay::hir_fmt(*self, f) } @@ -761,12 +767,6 @@ impl HirDisplay for TraitRef { } } -impl HirDisplay for &GenericPredicate { - fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { - HirDisplay::hir_fmt(*self, f) - } -} - impl HirDisplay for GenericPredicate { fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { if f.should_truncate() { @@ -825,3 +825,190 @@ impl HirDisplay for Obligation { } } } + +pub fn write_visibility( + module_id: ModuleId, + vis: Visibility, + f: &mut HirFormatter, +) -> Result<(), HirDisplayError> { + match vis { + Visibility::Public => write!(f, "pub "), + Visibility::Module(vis_id) => { + let def_map = module_id.def_map(f.db.upcast()); + let root_module_id = def_map.module_id(def_map.root()); + if vis_id == module_id { + // pub(self) or omitted + Ok(()) + } else if root_module_id == vis_id { + write!(f, "pub(crate) ") + } else if module_id.containing_module(f.db.upcast()) == Some(vis_id) { + write!(f, "pub(super) ") + } else { + write!(f, "pub(in ...) ") + } + } + } +} + +impl HirDisplay for TypeRef { + fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { + match self { + TypeRef::Never => write!(f, "!")?, + TypeRef::Placeholder => write!(f, "_")?, + TypeRef::Tuple(elems) => { + write!(f, "(")?; + f.write_joined(elems, ", ")?; + if elems.len() == 1 { + write!(f, ",")?; + } + write!(f, ")")?; + } + TypeRef::Path(path) => path.hir_fmt(f)?, + TypeRef::RawPtr(inner, mutability) => { + let mutability = match mutability { + hir_def::type_ref::Mutability::Shared => "*const ", + hir_def::type_ref::Mutability::Mut => "*mut ", + }; + write!(f, "{}", mutability)?; + inner.hir_fmt(f)?; + } + TypeRef::Reference(inner, lifetime, mutability) => { + let mutability = match mutability { + hir_def::type_ref::Mutability::Shared => "", + hir_def::type_ref::Mutability::Mut => "mut ", + }; + write!(f, "&")?; + if let Some(lifetime) = lifetime { + write!(f, "{} ", lifetime.name)?; + } + write!(f, "{}", mutability)?; + inner.hir_fmt(f)?; + } + TypeRef::Array(inner) => { + write!(f, "[")?; + inner.hir_fmt(f)?; + // FIXME: Array length? + write!(f, "; _]")?; + } + TypeRef::Slice(inner) => { + write!(f, "[")?; + inner.hir_fmt(f)?; + write!(f, "]")?; + } + TypeRef::Fn(tys, is_varargs) => { + // FIXME: Function pointer qualifiers. + write!(f, "fn(")?; + f.write_joined(&tys[..tys.len() - 1], ", ")?; + if *is_varargs { + write!(f, "{}...", if tys.len() == 1 { "" } else { ", " })?; + } + write!(f, ")")?; + let ret_ty = tys.last().unwrap(); + match ret_ty { + TypeRef::Tuple(tup) if tup.is_empty() => {} + _ => { + write!(f, " -> ")?; + ret_ty.hir_fmt(f)?; + } + } + } + TypeRef::ImplTrait(bounds) => { + write!(f, "impl ")?; + f.write_joined(bounds, " + ")?; + } + TypeRef::DynTrait(bounds) => { + write!(f, "dyn ")?; + f.write_joined(bounds, " + ")?; + } + TypeRef::Error => write!(f, "{{error}}")?, + } + Ok(()) + } +} + +impl HirDisplay for TypeBound { + fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { + match self { + TypeBound::Path(path) => path.hir_fmt(f), + TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name), + TypeBound::Error => write!(f, "{{error}}"), + } + } +} + +impl HirDisplay for Path { + fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { + match (self.type_anchor(), self.kind()) { + (Some(anchor), _) => { + write!(f, "<")?; + anchor.hir_fmt(f)?; + write!(f, ">")?; + } + (_, PathKind::Plain) => {} + (_, PathKind::Abs) => write!(f, "::")?, + (_, PathKind::Crate) => write!(f, "crate")?, + (_, PathKind::Super(0)) => write!(f, "self")?, + (_, PathKind::Super(n)) => { + write!(f, "super")?; + for _ in 0..*n { + write!(f, "::super")?; + } + } + (_, PathKind::DollarCrate(_)) => write!(f, "{{extern_crate}}")?, + } + + for (seg_idx, segment) in self.segments().iter().enumerate() { + if seg_idx != 0 { + write!(f, "::")?; + } + write!(f, "{}", segment.name)?; + if let Some(generic_args) = segment.args_and_bindings { + // We should be in type context, so format as `Foo` instead of `Foo::`. + // Do we actually format expressions? + write!(f, "<")?; + let mut first = true; + for arg in &generic_args.args { + if first { + first = false; + if generic_args.has_self_type { + // FIXME: Convert to `` form. + write!(f, "Self = ")?; + } + } else { + write!(f, ", ")?; + } + arg.hir_fmt(f)?; + } + for binding in &generic_args.bindings { + if first { + first = false; + } else { + write!(f, ", ")?; + } + write!(f, "{}", binding.name)?; + match &binding.type_ref { + Some(ty) => { + write!(f, " = ")?; + ty.hir_fmt(f)? + } + None => { + write!(f, ": ")?; + f.write_joined(&binding.bounds, " + ")?; + } + } + } + write!(f, ">")?; + } + } + Ok(()) + } +} + +impl HirDisplay for GenericArg { + fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { + match self { + GenericArg::Type(ty) => ty.hir_fmt(f), + GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name), + } + } +} -- cgit v1.2.3 From 87171238c6c528c421f06de8cd7e41ed3b6ff57a Mon Sep 17 00:00:00 2001 From: oxalica Date: Tue, 16 Mar 2021 00:05:03 +0800 Subject: Use hir formatter more --- crates/hir_ty/src/traits/chalk.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/hir_ty') diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs index 232cf9cd0..4bd8ba303 100644 --- a/crates/hir_ty/src/traits/chalk.rs +++ b/crates/hir_ty/src/traits/chalk.rs @@ -429,7 +429,7 @@ pub(crate) fn trait_datum_query( let generic_params = generics(db.upcast(), trait_.into()); let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); let flags = rust_ir::TraitFlags { - auto: trait_data.auto, + auto: trait_data.is_auto, upstream: trait_.lookup(db.upcast()).container.krate() != krate, non_enumerable: true, coinductive: false, // only relevant for Chalk testing -- cgit v1.2.3