Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 113 |
1 files changed, 79 insertions, 34 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 3c12907b82..f4e58d88ed 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -58,7 +58,6 @@ use hir_ty::{ consteval::{ eval_const, unknown_const_as_generic, ComputedExpr, ConstEvalCtx, ConstEvalError, ConstExt, }, - could_unify, diagnostics::BodyValidationDiagnostic, method_resolution::{self, TyFingerprint}, primitive::UintTy, @@ -85,12 +84,11 @@ use crate::db::{DefDatabase, HirDatabase}; pub use crate::{ attrs::{HasAttrs, Namespace}, diagnostics::{ - AddReferenceHere, AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, - InvalidDeriveTarget, MacroError, MalformedDerive, MismatchedArgCount, MissingFields, - MissingMatchArms, MissingOkOrSomeInTailExpr, MissingUnsafe, NoSuchField, - RemoveThisSemicolon, ReplaceFilterMapNextWithFindMap, UnimplementedBuiltinMacro, - UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, UnresolvedModule, - UnresolvedProcMacro, + AnyDiagnostic, BreakOutsideOfLoop, InactiveCode, IncorrectCase, InvalidDeriveTarget, + MacroError, MalformedDerive, MismatchedArgCount, MissingFields, MissingMatchArms, + MissingUnsafe, NoSuchField, ReplaceFilterMapNextWithFindMap, TypeMismatch, + UnimplementedBuiltinMacro, UnresolvedExternCrate, UnresolvedImport, UnresolvedMacroCall, + UnresolvedModule, UnresolvedProcMacro, }, has_source::HasSource, semantics::{PathResolution, Semantics, SemanticsScope, TypeInfo}, @@ -1005,6 +1003,24 @@ impl Adt { Type::from_def(db, id.module(db.upcast()).krate(), id) } + /// Turns this ADT into a type with the given type parameters. This isn't + /// the greatest API, FIXME find a better one. + pub fn ty_with_args(self, db: &dyn HirDatabase, args: &[Type]) -> Type { + let id = AdtId::from(self); + let mut it = args.iter().map(|t| t.ty.clone()); + let ty = TyBuilder::def_ty(db, id.into()) + .fill(|x| { + let r = it.next().unwrap_or_else(|| TyKind::Error.intern(Interner)); + match x { + ParamKind::Type => GenericArgData::Ty(r).intern(Interner), + ParamKind::Const(ty) => unknown_const_as_generic(ty.clone()), + } + }) + .build(); + let krate = id.module(db.upcast()).krate(); + Type::new(db, krate, id, ty) + } + pub fn module(self, db: &dyn HirDatabase) -> Module { match self { Adt::Struct(s) => s.module(db), @@ -1020,6 +1036,14 @@ impl Adt { Adt::Enum(e) => e.name(db), } } + + pub fn as_enum(&self) -> Option<Enum> { + if let Self::Enum(v) = self { + Some(*v) + } else { + None + } + } } impl HasVisibility for Adt { @@ -1163,6 +1187,30 @@ impl DefWithBody { } } } + for (expr, mismatch) in infer.expr_type_mismatches() { + let expr = match source_map.expr_syntax(expr) { + Ok(expr) => expr, + Err(SyntheticSyntax) => continue, + }; + acc.push( + TypeMismatch { + expr, + expected: Type::new( + db, + krate, + DefWithBodyId::from(self), + mismatch.expected.clone(), + ), + actual: Type::new( + db, + krate, + DefWithBodyId::from(self), + mismatch.actual.clone(), + ), + } + .into(), + ); + } for expr in hir_ty::diagnostics::missing_unsafe(db, self.into()) { match source_map.expr_syntax(expr) { @@ -1259,25 +1307,6 @@ impl DefWithBody { Err(SyntheticSyntax) => (), } } - BodyValidationDiagnostic::RemoveThisSemicolon { expr } => { - match source_map.expr_syntax(expr) { - Ok(expr) => acc.push(RemoveThisSemicolon { expr }.into()), - Err(SyntheticSyntax) => (), - } - } - BodyValidationDiagnostic::MissingOkOrSomeInTailExpr { expr, required } => { - match source_map.expr_syntax(expr) { - Ok(expr) => acc.push( - MissingOkOrSomeInTailExpr { - expr, - required, - expected: self.body_type(db), - } - .into(), - ), - Err(SyntheticSyntax) => (), - } - } BodyValidationDiagnostic::MissingMatchArms { match_expr } => { match source_map.expr_syntax(match_expr) { Ok(source_ptr) => { @@ -1299,12 +1328,6 @@ impl DefWithBody { Err(SyntheticSyntax) => (), } } - BodyValidationDiagnostic::AddReferenceHere { arg_expr, mutability } => { - match source_map.expr_syntax(arg_expr) { - Ok(expr) => acc.push(AddReferenceHere { expr, mutability }.into()), - Err(SyntheticSyntax) => (), - } - } } } @@ -2618,6 +2641,17 @@ impl Type { Type { krate, env: environment, ty } } + pub fn reference(inner: &Type, m: Mutability) -> Type { + inner.derived( + TyKind::Ref( + if m.is_mut() { hir_ty::Mutability::Mut } else { hir_ty::Mutability::Not }, + hir_ty::static_lifetime(), + inner.ty.clone(), + ) + .intern(Interner), + ) + } + fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { let resolver = lexical_env.resolver(db.upcast()); let environment = resolver @@ -2659,6 +2693,12 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Ref(..)) } + pub fn as_reference(&self) -> Option<(Type, Mutability)> { + let (ty, _lt, m) = self.ty.as_reference()?; + let m = Mutability::from_mutable(matches!(m, hir_ty::Mutability::Mut)); + Some((self.derived(ty.clone()), m)) + } + pub fn is_slice(&self) -> bool { matches!(self.ty.kind(Interner), TyKind::Slice(..)) } @@ -2900,7 +2940,7 @@ impl Type { self.autoderef_(db).map(move |ty| self.derived(ty)) } - pub fn autoderef_<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Ty> + 'a { + fn autoderef_<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Ty> + 'a { // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(&self.ty); let environment = self.env.clone(); @@ -3238,7 +3278,12 @@ impl Type { pub fn could_unify_with(&self, db: &dyn HirDatabase, other: &Type) -> bool { let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone())); - could_unify(db, self.env.clone(), &tys) + hir_ty::could_unify(db, self.env.clone(), &tys) + } + + pub fn could_coerce_to(&self, db: &dyn HirDatabase, to: &Type) -> bool { + let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), to.ty.clone())); + hir_ty::could_coerce(db, self.env.clone(), &tys) } } |