aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs2
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs203
-rw-r--r--crates/hir_ty/src/traits/chalk.rs2
4 files changed, 200 insertions, 13 deletions
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> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_extern { 94 if data.is_in_extern_block {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
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> {
32 let def = self.owner.into(); 32 let def = self.owner.into();
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -86,7 +86,7 @@ fn walk_unsafe(
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def(db) { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).is_unsafe { 89 if db.function_data(func).qualifier.is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,7 +103,7 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).is_unsafe) 106 .map(|func| db.function_data(func).qualifier.is_unsafe)
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
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};
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, 8 db::DefDatabase,
9 find_path,
10 generics::TypeParamProvenance,
11 item_scope::ItemInNs,
12 path::{GenericArg, Path, PathKind},
13 type_ref::{TypeBound, TypeRef},
14 visibility::Visibility,
9 AssocContainerId, Lookup, ModuleId, TraitId, 15 AssocContainerId, Lookup, ModuleId, TraitId,
10}; 16};
11use hir_expand::name::Name; 17use hir_expand::name::Name;
@@ -232,7 +238,7 @@ where
232 238
233const TYPE_HINT_TRUNCATION: &str = "…"; 239const TYPE_HINT_TRUNCATION: &str = "…";
234 240
235impl HirDisplay for &Ty { 241impl<T: HirDisplay> HirDisplay for &'_ T {
236 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 242 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
237 HirDisplay::hir_fmt(*self, f) 243 HirDisplay::hir_fmt(*self, f)
238 } 244 }
@@ -761,12 +767,6 @@ impl HirDisplay for TraitRef {
761 } 767 }
762} 768}
763 769
764impl HirDisplay for &GenericPredicate {
765 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
766 HirDisplay::hir_fmt(*self, f)
767 }
768}
769
770impl HirDisplay for GenericPredicate { 770impl HirDisplay for GenericPredicate {
771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
772 if f.should_truncate() { 772 if f.should_truncate() {
@@ -825,3 +825,190 @@ impl HirDisplay for Obligation {
825 } 825 }
826 } 826 }
827} 827}
828
829pub fn write_visibility(
830 module_id: ModuleId,
831 vis: Visibility,
832 f: &mut HirFormatter,
833) -> Result<(), HirDisplayError> {
834 match vis {
835 Visibility::Public => write!(f, "pub "),
836 Visibility::Module(vis_id) => {
837 let def_map = module_id.def_map(f.db.upcast());
838 let root_module_id = def_map.module_id(def_map.root());
839 if vis_id == module_id {
840 // pub(self) or omitted
841 Ok(())
842 } else if root_module_id == vis_id {
843 write!(f, "pub(crate) ")
844 } else if module_id.containing_module(f.db.upcast()) == Some(vis_id) {
845 write!(f, "pub(super) ")
846 } else {
847 write!(f, "pub(in ...) ")
848 }
849 }
850 }
851}
852
853impl HirDisplay for TypeRef {
854 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
855 match self {
856 TypeRef::Never => write!(f, "!")?,
857 TypeRef::Placeholder => write!(f, "_")?,
858 TypeRef::Tuple(elems) => {
859 write!(f, "(")?;
860 f.write_joined(elems, ", ")?;
861 if elems.len() == 1 {
862 write!(f, ",")?;
863 }
864 write!(f, ")")?;
865 }
866 TypeRef::Path(path) => path.hir_fmt(f)?,
867 TypeRef::RawPtr(inner, mutability) => {
868 let mutability = match mutability {
869 hir_def::type_ref::Mutability::Shared => "*const ",
870 hir_def::type_ref::Mutability::Mut => "*mut ",
871 };
872 write!(f, "{}", mutability)?;
873 inner.hir_fmt(f)?;
874 }
875 TypeRef::Reference(inner, lifetime, mutability) => {
876 let mutability = match mutability {
877 hir_def::type_ref::Mutability::Shared => "",
878 hir_def::type_ref::Mutability::Mut => "mut ",
879 };
880 write!(f, "&")?;
881 if let Some(lifetime) = lifetime {
882 write!(f, "{} ", lifetime.name)?;
883 }
884 write!(f, "{}", mutability)?;
885 inner.hir_fmt(f)?;
886 }
887 TypeRef::Array(inner) => {
888 write!(f, "[")?;
889 inner.hir_fmt(f)?;
890 // FIXME: Array length?
891 write!(f, "; _]")?;
892 }
893 TypeRef::Slice(inner) => {
894 write!(f, "[")?;
895 inner.hir_fmt(f)?;
896 write!(f, "]")?;
897 }
898 TypeRef::Fn(tys, is_varargs) => {
899 // FIXME: Function pointer qualifiers.
900 write!(f, "fn(")?;
901 f.write_joined(&tys[..tys.len() - 1], ", ")?;
902 if *is_varargs {
903 write!(f, "{}...", if tys.len() == 1 { "" } else { ", " })?;
904 }
905 write!(f, ")")?;
906 let ret_ty = tys.last().unwrap();
907 match ret_ty {
908 TypeRef::Tuple(tup) if tup.is_empty() => {}
909 _ => {
910 write!(f, " -> ")?;
911 ret_ty.hir_fmt(f)?;
912 }
913 }
914 }
915 TypeRef::ImplTrait(bounds) => {
916 write!(f, "impl ")?;
917 f.write_joined(bounds, " + ")?;
918 }
919 TypeRef::DynTrait(bounds) => {
920 write!(f, "dyn ")?;
921 f.write_joined(bounds, " + ")?;
922 }
923 TypeRef::Error => write!(f, "{{error}}")?,
924 }
925 Ok(())
926 }
927}
928
929impl HirDisplay for TypeBound {
930 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
931 match self {
932 TypeBound::Path(path) => path.hir_fmt(f),
933 TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
934 TypeBound::Error => write!(f, "{{error}}"),
935 }
936 }
937}
938
939impl HirDisplay for Path {
940 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
941 match (self.type_anchor(), self.kind()) {
942 (Some(anchor), _) => {
943 write!(f, "<")?;
944 anchor.hir_fmt(f)?;
945 write!(f, ">")?;
946 }
947 (_, PathKind::Plain) => {}
948 (_, PathKind::Abs) => write!(f, "::")?,
949 (_, PathKind::Crate) => write!(f, "crate")?,
950 (_, PathKind::Super(0)) => write!(f, "self")?,
951 (_, PathKind::Super(n)) => {
952 write!(f, "super")?;
953 for _ in 0..*n {
954 write!(f, "::super")?;
955 }
956 }
957 (_, PathKind::DollarCrate(_)) => write!(f, "{{extern_crate}}")?,
958 }
959
960 for (seg_idx, segment) in self.segments().iter().enumerate() {
961 if seg_idx != 0 {
962 write!(f, "::")?;
963 }
964 write!(f, "{}", segment.name)?;
965 if let Some(generic_args) = segment.args_and_bindings {
966 // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
967 // Do we actually format expressions?
968 write!(f, "<")?;
969 let mut first = true;
970 for arg in &generic_args.args {
971 if first {
972 first = false;
973 if generic_args.has_self_type {
974 // FIXME: Convert to `<Ty as Trait>` form.
975 write!(f, "Self = ")?;
976 }
977 } else {
978 write!(f, ", ")?;
979 }
980 arg.hir_fmt(f)?;
981 }
982 for binding in &generic_args.bindings {
983 if first {
984 first = false;
985 } else {
986 write!(f, ", ")?;
987 }
988 write!(f, "{}", binding.name)?;
989 match &binding.type_ref {
990 Some(ty) => {
991 write!(f, " = ")?;
992 ty.hir_fmt(f)?
993 }
994 None => {
995 write!(f, ": ")?;
996 f.write_joined(&binding.bounds, " + ")?;
997 }
998 }
999 }
1000 write!(f, ">")?;
1001 }
1002 }
1003 Ok(())
1004 }
1005}
1006
1007impl HirDisplay for GenericArg {
1008 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1009 match self {
1010 GenericArg::Type(ty) => ty.hir_fmt(f),
1011 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1012 }
1013 }
1014}
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(
429 let generic_params = generics(db.upcast(), trait_.into()); 429 let generic_params = generics(db.upcast(), trait_.into());
430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
431 let flags = rust_ir::TraitFlags { 431 let flags = rust_ir::TraitFlags {
432 auto: trait_data.auto, 432 auto: trait_data.is_auto,
433 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 433 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
434 non_enumerable: true, 434 non_enumerable: true,
435 coinductive: false, // only relevant for Chalk testing 435 coinductive: false, // only relevant for Chalk testing