diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index e71b51bfa432..b9f2e5a3e997 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -226,9 +226,9 @@ fn resolve_assoc_or_field( resolve_field(db, variant_def, name, ns) } -fn resolve_assoc_item( - db: &dyn HirDatabase, - ty: &Type, +fn resolve_assoc_item<'db>( + db: &'db dyn HirDatabase, + ty: &Type<'db>, name: &Name, ns: Option, ) -> Option { @@ -240,10 +240,10 @@ fn resolve_assoc_item( }) } -fn resolve_impl_trait_item( - db: &dyn HirDatabase, +fn resolve_impl_trait_item<'db>( + db: &'db dyn HirDatabase, resolver: Resolver, - ty: &Type, + ty: &Type<'db>, name: &Name, ns: Option, ) -> Option { diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index 651ec151d40c..3e093de94432 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs @@ -35,15 +35,15 @@ pub use hir_ty::{ }; macro_rules! diagnostics { - ($($diag:ident,)*) => { + ($($diag:ident $(<$lt:lifetime>)?,)*) => { #[derive(Debug)] - pub enum AnyDiagnostic {$( - $diag(Box<$diag>), + pub enum AnyDiagnostic<'db> {$( + $diag(Box<$diag $(<$lt>)?>), )*} $( - impl From<$diag> for AnyDiagnostic { - fn from(d: $diag) -> AnyDiagnostic { + impl<'db> From<$diag $(<$lt>)?> for AnyDiagnostic<'db> { + fn from(d: $diag $(<$lt>)?) -> AnyDiagnostic<'db> { AnyDiagnostic::$diag(Box::new(d)) } } @@ -68,12 +68,12 @@ macro_rules! diagnostics { diagnostics![ AwaitOutsideOfAsync, BreakOutsideOfLoop, - CastToUnsized, - ExpectedFunction, + CastToUnsized<'db>, + ExpectedFunction<'db>, InactiveCode, IncoherentImpl, IncorrectCase, - InvalidCast, + InvalidCast<'db>, InvalidDeriveTarget, MacroDefError, MacroError, @@ -84,7 +84,7 @@ diagnostics![ MissingFields, MissingMatchArms, MissingUnsafe, - MovedOutOfRef, + MovedOutOfRef<'db>, NeedMut, NonExhaustiveLet, NoSuchField, @@ -97,17 +97,17 @@ diagnostics![ TraitImplMissingAssocItems, TraitImplOrphan, TraitImplRedundantAssocItems, - TypedHole, - TypeMismatch, + TypedHole<'db>, + TypeMismatch<'db>, UndeclaredLabel, UnimplementedBuiltinMacro, UnreachableLabel, UnresolvedAssocItem, UnresolvedExternCrate, - UnresolvedField, + UnresolvedField<'db>, UnresolvedImport, UnresolvedMacroCall, - UnresolvedMethodCall, + UnresolvedMethodCall<'db>, UnresolvedModule, UnresolvedIdent, UnusedMut, @@ -125,9 +125,9 @@ pub struct BreakOutsideOfLoop { } #[derive(Debug)] -pub struct TypedHole { +pub struct TypedHole<'db> { pub expr: InFile, - pub expected: Type, + pub expected: Type<'db>, } #[derive(Debug)] @@ -237,25 +237,25 @@ pub struct MismatchedTupleStructPatArgCount { } #[derive(Debug)] -pub struct ExpectedFunction { +pub struct ExpectedFunction<'db> { pub call: InFile, - pub found: Type, + pub found: Type<'db>, } #[derive(Debug)] -pub struct UnresolvedField { +pub struct UnresolvedField<'db> { pub expr: InFile, - pub receiver: Type, + pub receiver: Type<'db>, pub name: Name, pub method_with_same_name_exists: bool, } #[derive(Debug)] -pub struct UnresolvedMethodCall { +pub struct UnresolvedMethodCall<'db> { pub expr: InFile, - pub receiver: Type, + pub receiver: Type<'db>, pub name: Name, - pub field_with_same_name: Option, + pub field_with_same_name: Option>, pub assoc_func_with_same_name: Option, } @@ -324,10 +324,10 @@ pub struct NonExhaustiveLet { } #[derive(Debug)] -pub struct TypeMismatch { +pub struct TypeMismatch<'db> { pub expr_or_pat: InFile, - pub expected: Type, - pub actual: Type, + pub expected: Type<'db>, + pub actual: Type<'db>, } #[derive(Debug)] @@ -347,8 +347,8 @@ pub struct UnusedVariable { } #[derive(Debug)] -pub struct MovedOutOfRef { - pub ty: Type, +pub struct MovedOutOfRef<'db> { + pub ty: Type<'db>, pub span: InFile, } @@ -398,17 +398,17 @@ pub struct RemoveUnnecessaryElse { } #[derive(Debug)] -pub struct CastToUnsized { +pub struct CastToUnsized<'db> { pub expr: InFile, - pub cast_ty: Type, + pub cast_ty: Type<'db>, } #[derive(Debug)] -pub struct InvalidCast { +pub struct InvalidCast<'db> { pub expr: InFile, pub error: CastError, - pub expr_ty: Type, - pub cast_ty: Type, + pub expr_ty: Type<'db>, + pub cast_ty: Type<'db>, } #[derive(Debug)] @@ -427,12 +427,12 @@ pub struct BadRtn { pub rtn: InFile>, } -impl AnyDiagnostic { +impl<'db> AnyDiagnostic<'db> { pub(crate) fn body_validation_diagnostic( - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, diagnostic: BodyValidationDiagnostic, source_map: &hir_def::expr_store::BodySourceMap, - ) -> Option { + ) -> Option> { match diagnostic { BodyValidationDiagnostic::RecordMissingFields { record, variant, missed_fields } => { let variant_data = variant.variant_data(db.upcast()); @@ -563,12 +563,12 @@ impl AnyDiagnostic { } pub(crate) fn inference_diagnostic( - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, def: DefWithBodyId, d: &InferenceDiagnostic, outer_types_source_map: &TypesSourceMap, source_map: &hir_def::expr_store::BodySourceMap, - ) -> Option { + ) -> Option> { let expr_syntax = |expr| { source_map .expr_syntax(expr) @@ -722,7 +722,7 @@ impl AnyDiagnostic { fn path_diagnostic( diag: &PathLoweringDiagnostic, path: InFile, - ) -> Option { + ) -> Option> { Some(match *diag { PathLoweringDiagnostic::GenericArgsProhibited { segment, reason } => { let segment = hir_segment_to_ast_segment(&path.value, segment)?; @@ -758,8 +758,8 @@ impl AnyDiagnostic { pub(crate) fn ty_diagnostic( diag: &TyLoweringDiagnostic, source_map: &TypesSourceMap, - db: &dyn HirDatabase, - ) -> Option { + db: &'db dyn HirDatabase, + ) -> Option> { let source = match diag.source { Either::Left(type_ref_id) => { let Ok(source) = source_map.type_syntax(type_ref_id) else { diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 673c336cc364..dccd10dbd2d6 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -429,7 +429,7 @@ impl HirDisplay for Variant { } } -impl HirDisplay for Type { +impl HirDisplay for Type<'_> { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { self.ty.hir_fmt(f) } @@ -748,7 +748,7 @@ impl HirDisplay for Static { } } -impl HirDisplay for TraitRef { +impl HirDisplay for TraitRef<'_> { fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> { self.trait_ref.hir_fmt(f) } diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 3d9c04d38748..5aafcf60810e 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -234,7 +234,7 @@ impl HasSource for LocalSource { } } -impl HasSource for Param { +impl HasSource for Param<'_> { type Ast = Either; fn source(self, db: &dyn HirDatabase) -> Option> { diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 870967e84aa2..100bc70121db 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -83,7 +83,7 @@ use nameres::diagnostics::DefDiagnosticKind; use rustc_hash::FxHashSet; use smallvec::SmallVec; use span::{Edition, EditionedFileId, FileId, MacroCallId}; -use stdx::{format_to, impl_from, never}; +use stdx::{format_to, impl_from, never, variance::PhantomCovariantLifetime}; use syntax::{ AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, T, TextRange, ToSmolStr, ast::{self, HasAttrs as _, HasGenericParams, HasName}, @@ -401,7 +401,11 @@ impl ModuleDef { Some(name) } - pub fn diagnostics(self, db: &dyn HirDatabase, style_lints: bool) -> Vec { + pub fn diagnostics<'db>( + self, + db: &'db dyn HirDatabase, + style_lints: bool, + ) -> Vec> { let id = match self { ModuleDef::Adt(it) => match it { Adt::Struct(it) => it.id.into(), @@ -614,10 +618,10 @@ impl Module { } /// Fills `acc` with the module's diagnostics. - pub fn diagnostics( + pub fn diagnostics<'db>( self, - db: &dyn HirDatabase, - acc: &mut Vec, + db: &'db dyn HirDatabase, + acc: &mut Vec>, style_lints: bool, ) { let _p = tracing::info_span!("diagnostics", name = ?self.name(db)).entered(); @@ -930,10 +934,10 @@ impl Module { } } -fn macro_call_diagnostics( - db: &dyn HirDatabase, +fn macro_call_diagnostics<'db>( + db: &'db dyn HirDatabase, macro_call_id: MacroCallId, - acc: &mut Vec, + acc: &mut Vec>, ) { let Some(e) = db.parse_macro_expansion_error(macro_call_id) else { return; @@ -969,7 +973,11 @@ fn macro_call_diagnostics( } } -fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec, m: Macro) { +fn emit_macro_def_diagnostics<'db>( + db: &'db dyn HirDatabase, + acc: &mut Vec>, + m: Macro, +) { let id = db.macro_def(m.id); if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) { if let Some(e) = expander.mac.err() { @@ -989,18 +997,18 @@ fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec } } -fn emit_def_diagnostic( - db: &dyn HirDatabase, - acc: &mut Vec, +fn emit_def_diagnostic<'db>( + db: &'db dyn HirDatabase, + acc: &mut Vec>, diag: &DefDiagnostic, edition: Edition, ) { emit_def_diagnostic_(db, acc, &diag.kind, edition) } -fn emit_def_diagnostic_( - db: &dyn HirDatabase, - acc: &mut Vec, +fn emit_def_diagnostic_<'db>( + db: &'db dyn HirDatabase, + acc: &mut Vec>, diag: &DefDiagnosticKind, edition: Edition, ) { @@ -1285,14 +1293,18 @@ impl TupleField { Name::new_tuple_field(self.index as usize) } - pub fn ty(&self, db: &dyn HirDatabase) -> Type { + pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let ty = db.infer(self.owner).tuple_field_access_types[&self.tuple] .as_slice(Interner) .get(self.index as usize) .and_then(|arg| arg.ty(Interner)) .cloned() .unwrap_or_else(|| TyKind::Error.intern(Interner)); - Type { env: db.trait_environment_for_body(self.owner), ty } + Type { + env: db.trait_environment_for_body(self.owner), + ty, + _pd: PhantomCovariantLifetime::new(), + } } } @@ -1343,7 +1355,7 @@ impl Field { /// Returns the type as in the signature of the struct (i.e., with /// placeholder types for type parameters). Only use this in the context of /// the field definition. - pub fn ty(&self, db: &dyn HirDatabase) -> Type { + pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let var_id = self.parent.into(); let generic_def_id: GenericDefId = match self.parent { VariantDef::Struct(it) => it.id.into(), @@ -1356,7 +1368,11 @@ impl Field { } // FIXME: Find better API to also handle const generics - pub fn ty_with_args(&self, db: &dyn HirDatabase, generics: impl Iterator) -> Type { + pub fn ty_with_args<'db>( + &self, + db: &'db dyn HirDatabase, + generics: impl Iterator>, + ) -> Type<'db> { let var_id = self.parent.into(); let def_id: AdtId = match self.parent { VariantDef::Struct(it) => it.id.into(), @@ -1428,15 +1444,15 @@ impl Struct { .collect() } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def(db, self.id) } - pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def_placeholders(db, self.id) } - pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } @@ -1477,15 +1493,15 @@ impl Union { Module { id: self.id.lookup(db.upcast()).container } } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def(db, self.id) } - pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def_placeholders(db, self.id) } - pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } @@ -1538,16 +1554,16 @@ impl Enum { db.enum_data(self.id).repr } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { Type::from_def(db, self.id) } - pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + pub fn ty_placeholders<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { Type::from_def_placeholders(db, self.id) } /// The type of the enum variant bodies. - pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type { + pub fn variant_body_ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { Type::new_for_crate( self.id.lookup(db.upcast()).container.krate(), TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() { @@ -1620,7 +1636,7 @@ impl Variant { self.id.lookup(db.upcast()).parent.into() } - pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type { + pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } @@ -1712,14 +1728,18 @@ impl Adt { /// Turns this ADT into a type. Any type parameters of the ADT will be /// turned into unknown types, which is good for e.g. finding the most /// general set of completions, but will not look very nice when printed. - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let id = AdtId::from(self); Type::from_def(db, 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: impl Iterator) -> Type { + pub fn ty_with_args<'db>( + self, + db: &'db dyn HirDatabase, + args: impl Iterator>, + ) -> Type<'db> { let id = AdtId::from(self); let mut it = args.map(|t| t.ty); let ty = TyBuilder::def_ty(db, id.into(), None) @@ -1863,7 +1883,7 @@ impl DefWithBody { } /// Returns the type this def's body has to evaluate to. - pub fn body_type(self, db: &dyn HirDatabase) -> Type { + pub fn body_type(self, db: &dyn HirDatabase) -> Type<'_> { match self { DefWithBody::Function(it) => it.ret_type(db), DefWithBody::Static(it) => it.ty(db), @@ -1902,10 +1922,10 @@ impl DefWithBody { } } - pub fn diagnostics( + pub fn diagnostics<'db>( self, - db: &dyn HirDatabase, - acc: &mut Vec, + db: &'db dyn HirDatabase, + acc: &mut Vec>, style_lints: bool, ) { let krate = self.module(db).id.krate(); @@ -2207,11 +2227,11 @@ impl Function { db.function_data(self.id).name.clone() } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } - pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type { + pub fn fn_ptr_type(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.resolver(db.upcast()); let substs = TyBuilder::placeholder_subst(db, self.id); let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs); @@ -2220,7 +2240,7 @@ impl Function { } /// Get this function's return type - pub fn ret_type(self, db: &dyn HirDatabase) -> Type { + pub fn ret_type(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.resolver(db.upcast()); let substs = TyBuilder::placeholder_subst(db, self.id); let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs); @@ -2229,11 +2249,11 @@ impl Function { } // FIXME: Find better API to also handle const generics - pub fn ret_type_with_args( + pub fn ret_type_with_args<'db>( self, - db: &dyn HirDatabase, - generics: impl Iterator, - ) -> Type { + db: &'db dyn HirDatabase, + generics: impl Iterator>, + ) -> Type<'db> { let resolver = self.id.resolver(db.upcast()); let parent_id: Option = match self.id.lookup(db.upcast()).container { ItemContainerId::ImplId(it) => Some(it.into()), @@ -2258,7 +2278,7 @@ impl Function { Type::new_with_resolver_inner(db, &resolver, ty) } - pub fn async_ret_type(self, db: &dyn HirDatabase) -> Option { + pub fn async_ret_type<'db>(self, db: &'db dyn HirDatabase) -> Option> { if !self.is_async(db) { return None; } @@ -2282,7 +2302,7 @@ impl Function { self.has_self_param(db).then_some(SelfParam { func: self.id }) } - pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec { + pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec> { let environment = db.trait_environment(self.id.into()); let substs = TyBuilder::placeholder_subst(db, self.id); let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs); @@ -2291,7 +2311,11 @@ impl Function { .iter() .enumerate() .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty: ty.clone() }; + let ty = Type { + env: environment.clone(), + ty: ty.clone(), + _pd: PhantomCovariantLifetime::new(), + }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() @@ -2301,12 +2325,12 @@ impl Function { db.function_data(self.id).params.len() } - pub fn method_params(self, db: &dyn HirDatabase) -> Option> { + pub fn method_params(self, db: &dyn HirDatabase) -> Option>> { self.self_param(db)?; Some(self.params_without_self(db)) } - pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec { + pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec> { let environment = db.trait_environment(self.id.into()); let substs = TyBuilder::placeholder_subst(db, self.id); let callable_sig = db.callable_item_signature(self.id.into()).substitute(Interner, &substs); @@ -2317,18 +2341,22 @@ impl Function { .enumerate() .skip(skip) .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty: ty.clone() }; + let ty = Type { + env: environment.clone(), + ty: ty.clone(), + _pd: PhantomCovariantLifetime::new(), + }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() } // FIXME: Find better API to also handle const generics - pub fn params_without_self_with_args( + pub fn params_without_self_with_args<'db>( self, - db: &dyn HirDatabase, - generics: impl Iterator, - ) -> Vec { + db: &'db dyn HirDatabase, + generics: impl Iterator>, + ) -> Vec> { let environment = db.trait_environment(self.id.into()); let parent_id: Option = match self.id.lookup(db.upcast()).container { ItemContainerId::ImplId(it) => Some(it.into()), @@ -2363,7 +2391,11 @@ impl Function { .enumerate() .skip(skip) .map(|(idx, ty)| { - let ty = Type { env: environment.clone(), ty: ty.clone() }; + let ty = Type { + env: environment.clone(), + ty: ty.clone(), + _pd: PhantomCovariantLifetime::new(), + }; Param { func: Callee::Def(CallableDefId::FunctionId(self.id)), ty, idx } }) .collect() @@ -2393,7 +2425,8 @@ impl Function { return true; } - let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false }; + let ret_type = self.ret_type(db); + let Some(impl_traits) = ret_type.as_impl_traits(db) else { return false }; let Some(future_trait_id) = db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait()) else { @@ -2539,14 +2572,14 @@ impl From for Access { } #[derive(Clone, PartialEq, Eq, Hash, Debug)] -pub struct Param { +pub struct Param<'db> { func: Callee, /// The index in parameter list, including self parameter. idx: usize, - ty: Type, + ty: Type<'db>, } -impl Param { +impl<'db> Param<'db> { pub fn parent_fn(&self) -> Option { match self.func { Callee::Def(CallableDefId::FunctionId(f)) => Some(f.into()), @@ -2562,7 +2595,7 @@ impl Param { self.idx } - pub fn ty(&self) -> &Type { + pub fn ty(&self) -> &Type<'db> { &self.ty } @@ -2629,17 +2662,21 @@ impl SelfParam { Function::from(self.func) } - pub fn ty(&self, db: &dyn HirDatabase) -> Type { + pub fn ty<'db>(&self, db: &'db dyn HirDatabase) -> Type<'db> { let substs = TyBuilder::placeholder_subst(db, self.func); let callable_sig = db.callable_item_signature(self.func.into()).substitute(Interner, &substs); let environment = db.trait_environment(self.func.into()); let ty = callable_sig.params()[0].clone(); - Type { env: environment, ty } + Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() } } // FIXME: Find better API to also handle const generics - pub fn ty_with_args(&self, db: &dyn HirDatabase, generics: impl Iterator) -> Type { + pub fn ty_with_args<'db>( + &self, + db: &'db dyn HirDatabase, + generics: impl Iterator>, + ) -> Type<'db> { let parent_id: GenericDefId = match self.func.lookup(db.upcast()).container { ItemContainerId::ImplId(it) => it.into(), ItemContainerId::TraitId(it) => it.into(), @@ -2664,7 +2701,7 @@ impl SelfParam { db.callable_item_signature(self.func.into()).substitute(Interner, &substs); let environment = db.trait_environment(self.func.into()); let ty = callable_sig.params()[0].clone(); - Type { env: environment, ty } + Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() } } } @@ -2744,7 +2781,7 @@ impl Const { self.source(db)?.value.body() } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } @@ -2821,7 +2858,7 @@ impl Static { self.source(db)?.value.body() } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_value_def(db, self.id) } @@ -2990,11 +3027,11 @@ impl TypeAlias { Module { id: self.id.module(db.upcast()) } } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def(db, self.id) } - pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type { + pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type<'_> { Type::from_def_placeholders(db, self.id) } @@ -3041,7 +3078,7 @@ impl BuiltinType { BuiltinType { inner: hir_def::builtin_type::BuiltinType::Str } } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty<'db>(self, db: &'db dyn HirDatabase) -> Type<'db> { let core = Crate::core(db).map(|core| core.id).unwrap_or_else(|| db.all_crates()[0]); Type::new_for_crate(core, TyBuilder::builtin(self.inner)) } @@ -3485,7 +3522,7 @@ impl AssocItem { } } - pub fn implementing_ty(self, db: &dyn HirDatabase) -> Option { + pub fn implementing_ty(self, db: &dyn HirDatabase) -> Option> { match self.container(db) { AssocItemContainer::Impl(i) => Some(i.self_ty(db)), _ => None, @@ -3513,10 +3550,10 @@ impl AssocItem { } } - pub fn diagnostics( + pub fn diagnostics<'db>( self, - db: &dyn HirDatabase, - acc: &mut Vec, + db: &'db dyn HirDatabase, + acc: &mut Vec>, style_lints: bool, ) { match self { @@ -3639,7 +3676,7 @@ impl GenericDef { } } - pub fn diagnostics(self, db: &dyn HirDatabase, acc: &mut Vec) { + pub fn diagnostics<'db>(self, db: &'db dyn HirDatabase, acc: &mut Vec>) { let def = self.id(); let item_tree_source_maps; @@ -3722,18 +3759,19 @@ impl GenericDef { // We cannot call this `Substitution` unfortunately... #[derive(Debug)] -pub struct GenericSubstitution { +pub struct GenericSubstitution<'db> { def: GenericDefId, subst: Substitution, env: Arc, + _pd: PhantomCovariantLifetime<'db>, } -impl GenericSubstitution { +impl<'db> GenericSubstitution<'db> { fn new(def: GenericDefId, subst: Substitution, env: Arc) -> Self { - Self { def, subst, env } + Self { def, subst, env, _pd: PhantomCovariantLifetime::new() } } - pub fn types(&self, db: &dyn HirDatabase) -> Vec<(Symbol, Type)> { + pub fn types(&self, db: &'db dyn HirDatabase) -> Vec<(Symbol, Type<'db>)> { let container = match self.def { GenericDefId::ConstId(id) => Some(id.lookup(db.upcast()).container), GenericDefId::FunctionId(id) => Some(id.lookup(db.upcast()).container), @@ -3769,7 +3807,10 @@ impl GenericSubstitution { container_params .chain(self_params) .filter_map(|(ty, name)| { - Some((name?.symbol().clone(), Type { ty, env: self.env.clone() })) + Some(( + name?.symbol().clone(), + Type { ty, env: self.env.clone(), _pd: PhantomCovariantLifetime::new() }, + )) }) .collect() } @@ -3872,7 +3913,7 @@ impl Local { self.parent(db).module(db) } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let def = self.parent; let infer = db.infer(def); let ty = infer[self.binding_id].clone(); @@ -4155,7 +4196,7 @@ impl TypeParam { } } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.parent().resolver(db.upcast()); let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id.into())).intern(Interner); @@ -4177,7 +4218,7 @@ impl TypeParam { .collect() } - pub fn default(self, db: &dyn HirDatabase) -> Option { + pub fn default(self, db: &dyn HirDatabase) -> Option> { let ty = generic_arg_from_param(db, self.id.into())?; let resolver = self.id.parent().resolver(db.upcast()); match ty.data(Interner) { @@ -4242,7 +4283,7 @@ impl ConstParam { self.id.parent().into() } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { Type::new(db, self.id.parent(), db.const_param_ty(self.id)) } @@ -4298,7 +4339,7 @@ impl TypeOrConstParam { } } - pub fn ty(self, db: &dyn HirDatabase) -> Type { + pub fn ty(self, db: &dyn HirDatabase) -> Type<'_> { match self.split(db) { Either::Left(it) => it.ty(db), Either::Right(it) => it.ty(db), @@ -4343,7 +4384,10 @@ impl Impl { module.id.def_map(db.upcast())[module.id.local_id].scope.impls().map(Into::into).collect() } - pub fn all_for_type(db: &dyn HirDatabase, Type { ty, env }: Type) -> Vec { + pub fn all_for_type<'db>( + db: &'db dyn HirDatabase, + Type { ty, env, _pd: _ }: Type<'db>, + ) -> Vec { let def_crates = match method_resolution::def_crates(db, &ty, env.krate) { Some(def_crates) => def_crates, None => return Vec::new(), @@ -4429,14 +4473,14 @@ impl Impl { Some(Trait { id }) } - pub fn trait_ref(self, db: &dyn HirDatabase) -> Option { + pub fn trait_ref(self, db: &dyn HirDatabase) -> Option> { let substs = TyBuilder::placeholder_subst(db, self.id); let trait_ref = db.impl_trait(self.id)?.substitute(Interner, &substs); let resolver = self.id.resolver(db.upcast()); Some(TraitRef::new_with_resolver(db, &resolver, trait_ref)) } - pub fn self_ty(self, db: &dyn HirDatabase) -> Type { + pub fn self_ty(self, db: &dyn HirDatabase) -> Type<'_> { let resolver = self.id.resolver(db.upcast()); let substs = TyBuilder::placeholder_subst(db, self.id); let ty = db.impl_self_ty(self.id).substitute(Interner, &substs); @@ -4503,21 +4547,22 @@ impl Impl { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct TraitRef { +pub struct TraitRef<'db> { env: Arc, trait_ref: hir_ty::TraitRef, + _pd: PhantomCovariantLifetime<'db>, } -impl TraitRef { +impl<'db> TraitRef<'db> { pub(crate) fn new_with_resolver( - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, resolver: &Resolver, trait_ref: hir_ty::TraitRef, - ) -> TraitRef { + ) -> Self { let env = resolver .generic_def() .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); - TraitRef { env, trait_ref } + TraitRef { env, trait_ref, _pd: PhantomCovariantLifetime::new() } } pub fn trait_(&self) -> Trait { @@ -4525,21 +4570,21 @@ impl TraitRef { Trait { id } } - pub fn self_ty(&self) -> Type { + pub fn self_ty(&self) -> Type<'_> { let ty = self.trait_ref.self_type_parameter(Interner); - Type { env: self.env.clone(), ty } + Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() } } /// Returns `idx`-th argument of this trait reference if it is a type argument. Note that the /// first argument is the `Self` type. - pub fn get_type_argument(&self, idx: usize) -> Option { + pub fn get_type_argument(&self, idx: usize) -> Option> { self.trait_ref .substitution .as_slice(Interner) .get(idx) .and_then(|arg| arg.ty(Interner)) .cloned() - .map(|ty| Type { env: self.env.clone(), ty }) + .map(|ty| Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() }) } } @@ -4587,7 +4632,7 @@ impl Closure { .collect() } - pub fn capture_types(&self, db: &dyn HirDatabase) -> Vec { + pub fn capture_types<'db>(&self, db: &'db dyn HirDatabase) -> Vec> { let owner = db.lookup_intern_closure((self.id).into()).0; let infer = &db.infer(owner); let (captures, _) = infer.closure_info(&self.id); @@ -4596,6 +4641,7 @@ impl Closure { .map(|capture| Type { env: db.trait_environment_for_body(owner), ty: capture.ty(&self.subst), + _pd: PhantomCovariantLifetime::new(), }) .collect() } @@ -4727,40 +4773,41 @@ impl CaptureUsageSource { } #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct Type { +pub struct Type<'db> { env: Arc, ty: Ty, + _pd: PhantomCovariantLifetime<'db>, } -impl Type { - pub(crate) fn new_with_resolver(db: &dyn HirDatabase, resolver: &Resolver, ty: Ty) -> Type { +impl<'db> Type<'db> { + pub(crate) fn new_with_resolver(db: &'db dyn HirDatabase, resolver: &Resolver, ty: Ty) -> Self { Type::new_with_resolver_inner(db, resolver, ty) } pub(crate) fn new_with_resolver_inner( - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, resolver: &Resolver, ty: Ty, - ) -> Type { + ) -> Self { let environment = resolver .generic_def() .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); - Type { env: environment, ty } + Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() } } - pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty) -> Type { - Type { env: TraitEnvironment::empty(krate), ty } + pub(crate) fn new_for_crate(krate: base_db::Crate, ty: Ty) -> Self { + Type { env: TraitEnvironment::empty(krate), ty, _pd: PhantomCovariantLifetime::new() } } - fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type { + fn new(db: &'db dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Self { let resolver = lexical_env.resolver(db.upcast()); let environment = resolver .generic_def() .map_or_else(|| TraitEnvironment::empty(resolver.krate()), |d| db.trait_environment(d)); - Type { env: environment, ty } + Type { env: environment, ty, _pd: PhantomCovariantLifetime::new() } } - fn from_def(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { + fn from_def(db: &'db dyn HirDatabase, def: impl Into + HasResolver) -> Self { let ty = db.ty(def.into()); let substs = TyBuilder::unknown_subst( db, @@ -4773,7 +4820,10 @@ impl Type { Type::new(db, def, ty.substitute(Interner, &substs)) } - fn from_def_placeholders(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { + fn from_def_placeholders( + db: &'db dyn HirDatabase, + def: impl Into + HasResolver, + ) -> Self { let ty = db.ty(def.into()); let substs = TyBuilder::placeholder_subst( db, @@ -4786,7 +4836,10 @@ impl Type { Type::new(db, def, ty.substitute(Interner, &substs)) } - fn from_value_def(db: &dyn HirDatabase, def: impl Into + HasResolver) -> Type { + fn from_value_def( + db: &'db dyn HirDatabase, + def: impl Into + HasResolver, + ) -> Self { let Some(ty) = db.value_ty(def.into()) else { return Type::new(db, def, TyKind::Error.intern(Interner)); }; @@ -4806,13 +4859,17 @@ impl Type { Type::new(db, def, ty.substitute(Interner, &substs)) } - pub fn new_slice(ty: Type) -> Type { - Type { env: ty.env, ty: TyBuilder::slice(ty.ty) } + pub fn new_slice(ty: Self) -> Self { + Type { env: ty.env, ty: TyBuilder::slice(ty.ty), _pd: PhantomCovariantLifetime::new() } } - pub fn new_tuple(krate: base_db::Crate, tys: &[Type]) -> Type { + pub fn new_tuple(krate: base_db::Crate, tys: &[Self]) -> Self { let tys = tys.iter().map(|it| it.ty.clone()); - Type { env: TraitEnvironment::empty(krate), ty: TyBuilder::tuple_with(tys) } + Type { + env: TraitEnvironment::empty(krate), + ty: TyBuilder::tuple_with(tys), + _pd: PhantomCovariantLifetime::new(), + } } pub fn is_unit(&self) -> bool { @@ -4839,7 +4896,7 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Ref(..)) } - pub fn contains_reference(&self, db: &dyn HirDatabase) -> bool { + pub fn contains_reference(&self, db: &'db dyn HirDatabase) -> bool { return go(db, self.env.krate, &self.ty); fn go(db: &dyn HirDatabase, krate: base_db::Crate, ty: &Ty) -> bool { @@ -4883,13 +4940,13 @@ impl Type { } } - pub fn as_reference(&self) -> Option<(Type, Mutability)> { + pub fn as_reference(&self) -> Option<(Type<'db>, 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 add_reference(&self, mutability: Mutability) -> Type { + pub fn add_reference(&self, mutability: Mutability) -> Self { let ty_mutability = match mutability { Mutability::Shared => hir_ty::Mutability::Not, Mutability::Mut => hir_ty::Mutability::Mut, @@ -4925,25 +4982,25 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Tuple(..)) } - pub fn remove_ref(&self) -> Option { + pub fn remove_ref(&self) -> Option> { match &self.ty.kind(Interner) { TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), _ => None, } } - pub fn as_slice(&self) -> Option { + pub fn as_slice(&self) -> Option> { match &self.ty.kind(Interner) { TyKind::Slice(ty) => Some(self.derived(ty.clone())), _ => None, } } - pub fn strip_references(&self) -> Type { + pub fn strip_references(&self) -> Self { self.derived(self.ty.strip_references().clone()) } - pub fn strip_reference(&self) -> Type { + pub fn strip_reference(&self) -> Self { self.derived(self.ty.strip_reference().clone()) } @@ -4954,7 +5011,7 @@ impl Type { /// Checks that particular type `ty` implements `std::future::IntoFuture` or /// `std::future::Future` and returns the `Output` associated type. /// This function is used in `.await` syntax completion. - pub fn into_future_output(&self, db: &dyn HirDatabase) -> Option { + pub fn into_future_output(&self, db: &'db dyn HirDatabase) -> Option> { let trait_ = db .lang_item(self.env.krate, LangItem::IntoFutureIntoFuture) .and_then(|it| { @@ -4981,14 +5038,14 @@ impl Type { } /// This does **not** resolve `IntoFuture`, only `Future`. - pub fn future_output(self, db: &dyn HirDatabase) -> Option { + pub fn future_output(self, db: &'db dyn HirDatabase) -> Option> { let future_output = db.lang_item(self.env.krate, LangItem::FutureOutput)?.as_type_alias()?; self.normalize_trait_assoc_type(db, &[], future_output.into()) } /// This does **not** resolve `IntoIterator`, only `Iterator`. - pub fn iterator_item(self, db: &dyn HirDatabase) -> Option { + pub fn iterator_item(self, db: &'db dyn HirDatabase) -> Option> { let iterator_trait = db.lang_item(self.env.krate, LangItem::Iterator)?.as_trait()?; let iterator_item = db .trait_items(iterator_trait) @@ -4996,7 +5053,7 @@ impl Type { self.normalize_trait_assoc_type(db, &[], iterator_item.into()) } - pub fn impls_iterator(self, db: &dyn HirDatabase) -> bool { + pub fn impls_iterator(self, db: &'db dyn HirDatabase) -> bool { let Some(iterator_trait) = db.lang_item(self.env.krate, LangItem::Iterator).and_then(|it| it.as_trait()) else { @@ -5008,7 +5065,7 @@ impl Type { } /// Resolves the projection `::IntoIter` and returns the resulting type - pub fn into_iterator_iter(self, db: &dyn HirDatabase) -> Option { + pub fn into_iterator_iter(self, db: &'db dyn HirDatabase) -> Option> { let trait_ = db.lang_item(self.env.krate, LangItem::IntoIterIntoIter).and_then(|it| { let into_iter_fn = it.as_function()?; let assoc_item = as_assoc_item(db, AssocItem::Function, into_iter_fn)?; @@ -5032,7 +5089,7 @@ impl Type { /// /// This function can be used to check if a particular type is callable, since FnOnce is a /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce. - pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool { + pub fn impls_fnonce(&self, db: &'db dyn HirDatabase) -> bool { let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.env.krate) { Some(it) => it, None => return false, @@ -5044,7 +5101,7 @@ impl Type { } // FIXME: Find better API that also handles const generics - pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { + pub fn impls_trait(&self, db: &'db dyn HirDatabase, trait_: Trait, args: &[Type<'db>]) -> bool { let mut it = args.iter().map(|t| t.ty.clone()); let trait_ref = TyBuilder::trait_ref(db, trait_.id) .push(self.ty.clone()) @@ -5072,10 +5129,10 @@ impl Type { pub fn normalize_trait_assoc_type( &self, - db: &dyn HirDatabase, - args: &[Type], + db: &'db dyn HirDatabase, + args: &[Type<'db>], alias: TypeAlias, - ) -> Option { + ) -> Option> { let mut args = args.iter(); let trait_id = match alias.id.lookup(db.upcast()).container { ItemContainerId::TraitId(id) => id, @@ -5099,7 +5156,7 @@ impl Type { if ty.is_unknown() { None } else { Some(self.derived(ty)) } } - pub fn is_copy(&self, db: &dyn HirDatabase) -> bool { + pub fn is_copy(&self, db: &'db dyn HirDatabase) -> bool { let lang_item = db.lang_item(self.env.krate, LangItem::Copy); let copy_trait = match lang_item { Some(LangItemTarget::Trait(it)) => it, @@ -5108,7 +5165,7 @@ impl Type { self.impls_trait(db, copy_trait.into(), &[]) } - pub fn as_callable(&self, db: &dyn HirDatabase) -> Option { + pub fn as_callable(&self, db: &'db dyn HirDatabase) -> Option> { let callee = match self.ty.kind(Interner) { TyKind::Closure(id, subst) => Callee::Closure(*id, subst.clone()), TyKind::Function(_) => Callee::FnPtr, @@ -5162,7 +5219,7 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Array(..)) } - pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { + pub fn is_packed(&self, db: &'db dyn HirDatabase) -> bool { let adt_id = match *self.ty.kind(Interner) { TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, _ => return false, @@ -5179,7 +5236,7 @@ impl Type { matches!(self.ty.kind(Interner), TyKind::Raw(..)) } - pub fn remove_raw_ptr(&self) -> Option { + pub fn remove_raw_ptr(&self) -> Option> { if let TyKind::Raw(_, ty) = self.ty.kind(Interner) { Some(self.derived(ty.clone())) } else { @@ -5227,7 +5284,7 @@ impl Type { } } - pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { + pub fn fields(&self, db: &'db dyn HirDatabase) -> Vec<(Field, Self)> { let (variant_id, substs) = match self.ty.kind(Interner) { TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), substs) => ((*s).into(), substs), TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), substs) => ((*u).into(), substs), @@ -5244,7 +5301,7 @@ impl Type { .collect() } - pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec { + pub fn tuple_fields(&self, _db: &'db dyn HirDatabase) -> Vec { if let TyKind::Tuple(_, substs) = &self.ty.kind(Interner) { substs .iter(Interner) @@ -5255,7 +5312,7 @@ impl Type { } } - pub fn as_array(&self, db: &dyn HirDatabase) -> Option<(Type, usize)> { + pub fn as_array(&self, db: &'db dyn HirDatabase) -> Option<(Self, usize)> { if let TyKind::Array(ty, len) = &self.ty.kind(Interner) { try_const_usize(db, len).map(|it| (self.derived(ty.clone()), it as usize)) } else { @@ -5273,14 +5330,14 @@ impl Type { /// Returns types that this type dereferences to (including this type itself). The returned /// iterator won't yield the same type more than once even if the deref chain contains a cycle. - pub fn autoderef<'db>( + pub fn autoderef( &self, db: &'db dyn HirDatabase, - ) -> impl Iterator + use<'_, 'db> { + ) -> impl Iterator> + use<'_, 'db> { self.autoderef_(db).map(move |ty| self.derived(ty)) } - fn autoderef_(&self, db: &dyn HirDatabase) -> impl Iterator { + fn autoderef_(&self, db: &'db dyn HirDatabase) -> impl Iterator { // There should be no inference vars in types passed here let canonical = hir_ty::replace_errors_with_variables(&self.ty); autoderef(db, self.env.clone(), canonical) @@ -5290,7 +5347,7 @@ impl Type { // lifetime problems, because we need to borrow temp `CrateImplDefs`. pub fn iterate_assoc_items( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, krate: Crate, mut callback: impl FnMut(AssocItem) -> Option, ) -> Option { @@ -5304,7 +5361,7 @@ impl Type { fn iterate_assoc_items_dyn( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, krate: Crate, callback: &mut dyn FnMut(AssocItemId) -> bool, ) { @@ -5343,7 +5400,7 @@ impl Type { /// - "String" /// - "U" /// ``` - pub fn type_arguments(&self) -> impl Iterator + '_ { + pub fn type_arguments(&self) -> impl Iterator> + '_ { self.ty .strip_references() .as_adt() @@ -5413,7 +5470,7 @@ impl Type { pub fn iterate_method_candidates_with_traits( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet, with_local_impls: Option, @@ -5441,7 +5498,7 @@ impl Type { pub fn iterate_method_candidates( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, scope: &SemanticsScope<'_>, with_local_impls: Option, name: Option<&Name>, @@ -5463,7 +5520,7 @@ impl Type { /// are considered inherent methods. pub fn iterate_method_candidates_split_inherent( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet, with_local_impls: Option, @@ -5531,7 +5588,7 @@ impl Type { #[tracing::instrument(skip_all, fields(name = ?name))] pub fn iterate_path_candidates( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet, with_local_impls: Option, @@ -5566,7 +5623,7 @@ impl Type { #[tracing::instrument(skip_all, fields(name = ?name))] pub fn iterate_path_candidates_split_inherent( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, scope: &SemanticsScope<'_>, traits_in_scope: &FxHashSet, with_local_impls: Option, @@ -5629,10 +5686,10 @@ impl Type { /// If a type can be represented as `dyn Trait`, returns all traits accessible via this type, /// or an empty iterator otherwise. - pub fn applicable_inherent_traits<'a>( - &'a self, - db: &'a dyn HirDatabase, - ) -> impl Iterator + 'a { + pub fn applicable_inherent_traits( + &self, + db: &'db dyn HirDatabase, + ) -> impl Iterator { let _p = tracing::info_span!("applicable_inherent_traits").entered(); self.autoderef_(db) .filter_map(|ty| ty.dyn_trait()) @@ -5640,7 +5697,7 @@ impl Type { .map(Trait::from) } - pub fn env_traits<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator + 'a { + pub fn env_traits(&self, db: &'db dyn HirDatabase) -> impl Iterator { let _p = tracing::info_span!("env_traits").entered(); self.autoderef_(db) .filter(|ty| matches!(ty.kind(Interner), TyKind::Placeholder(_))) @@ -5652,10 +5709,7 @@ impl Type { .map(Trait::from) } - pub fn as_impl_traits( - &self, - db: &dyn HirDatabase, - ) -> Option + use<>> { + pub fn as_impl_traits(&self, db: &'db dyn HirDatabase) -> Option> { self.ty.impl_trait_bounds(db).map(|it| { it.into_iter().filter_map(|pred| match pred.skip_binders() { hir_ty::WhereClause::Implemented(trait_ref) => { @@ -5666,33 +5720,33 @@ impl Type { }) } - pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option { + pub fn as_associated_type_parent_trait(&self, db: &'db dyn HirDatabase) -> Option { self.ty.associated_type_parent_trait(db).map(Into::into) } - fn derived(&self, ty: Ty) -> Type { - Type { env: self.env.clone(), ty } + fn derived(&self, ty: Ty) -> Self { + Type { env: self.env.clone(), ty, _pd: PhantomCovariantLifetime::new() } } /// Visits every type, including generic arguments, in this type. `cb` is called with type /// itself first, and then with its generic arguments. - pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { - fn walk_substs( - db: &dyn HirDatabase, - type_: &Type, + pub fn walk(&self, db: &'db dyn HirDatabase, mut cb: impl FnMut(Type<'db>)) { + fn walk_substs<'db>( + db: &'db dyn HirDatabase, + type_: &Type<'db>, substs: &Substitution, - cb: &mut impl FnMut(Type), + cb: &mut impl FnMut(Type<'db>), ) { for ty in substs.iter(Interner).filter_map(|a| a.ty(Interner)) { walk_type(db, &type_.derived(ty.clone()), cb); } } - fn walk_bounds( - db: &dyn HirDatabase, - type_: &Type, + fn walk_bounds<'db>( + db: &'db dyn HirDatabase, + type_: &Type<'db>, bounds: &[QuantifiedWhereClause], - cb: &mut impl FnMut(Type), + cb: &mut impl FnMut(Type<'db>), ) { for pred in bounds { if let WhereClause::Implemented(trait_ref) = pred.skip_binders() { @@ -5709,7 +5763,11 @@ impl Type { } } - fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { + fn walk_type<'db>( + db: &'db dyn HirDatabase, + type_: &Type<'db>, + cb: &mut impl FnMut(Type<'db>), + ) { let ty = type_.ty.strip_references(); match ty.kind(Interner) { TyKind::Adt(_, substs) => { @@ -5777,7 +5835,7 @@ impl Type { /// /// Note that we consider placeholder types to unify with everything. /// For example `Option` and `Option` unify although there is unresolved goal `T = U`. - pub fn could_unify_with(&self, db: &dyn HirDatabase, other: &Type) -> bool { + pub fn could_unify_with(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone())); hir_ty::could_unify(db, self.env.clone(), &tys) } @@ -5786,17 +5844,17 @@ impl Type { /// /// This means that placeholder types are not considered to unify if there are any bounds set on /// them. For example `Option` and `Option` do not unify as we cannot show that `T = U` - pub fn could_unify_with_deeply(&self, db: &dyn HirDatabase, other: &Type) -> bool { + pub fn could_unify_with_deeply(&self, db: &'db dyn HirDatabase, other: &Type<'db>) -> bool { let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), other.ty.clone())); hir_ty::could_unify_deeply(db, self.env.clone(), &tys) } - pub fn could_coerce_to(&self, db: &dyn HirDatabase, to: &Type) -> bool { + pub fn could_coerce_to(&self, db: &'db dyn HirDatabase, to: &Type<'db>) -> bool { let tys = hir_ty::replace_errors_with_variables(&(self.ty.clone(), to.ty.clone())); hir_ty::could_coerce(db, self.env.clone(), &tys) } - pub fn as_type_param(&self, db: &dyn HirDatabase) -> Option { + pub fn as_type_param(&self, db: &'db dyn HirDatabase) -> Option { match self.ty.kind(Interner) { TyKind::Placeholder(p) => Some(TypeParam { id: TypeParamId::from_unchecked(hir_ty::from_placeholder_idx(db, *p)), @@ -5806,19 +5864,19 @@ impl Type { } /// Returns unique `GenericParam`s contained in this type. - pub fn generic_params(&self, db: &dyn HirDatabase) -> FxHashSet { + pub fn generic_params(&self, db: &'db dyn HirDatabase) -> FxHashSet { hir_ty::collect_placeholders(&self.ty, db) .into_iter() .map(|id| TypeOrConstParam { id }.split(db).either_into()) .collect() } - pub fn layout(&self, db: &dyn HirDatabase) -> Result { + pub fn layout(&self, db: &'db dyn HirDatabase) -> Result { db.layout_of_ty(self.ty.clone(), self.env.clone()) .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap())) } - pub fn drop_glue(&self, db: &dyn HirDatabase) -> DropGlue { + pub fn drop_glue(&self, db: &'db dyn HirDatabase) -> DropGlue { db.has_drop_glue(self.ty.clone(), self.env.clone()) } } @@ -5845,8 +5903,8 @@ impl InlineAsmOperand { // FIXME: Document this #[derive(Debug)] -pub struct Callable { - ty: Type, +pub struct Callable<'db> { + ty: Type<'db>, sig: CallableSig, callee: Callee, /// Whether this is a method that was called with method call syntax. @@ -5870,7 +5928,7 @@ pub enum CallableKind { FnImpl(FnTrait), } -impl Callable { +impl<'db> Callable<'db> { pub fn kind(&self) -> CallableKind { match self.callee { Callee::Def(CallableDefId::FunctionId(it)) => CallableKind::Function(it.into()), @@ -5885,7 +5943,7 @@ impl Callable { Callee::FnImpl(fn_) => CallableKind::FnImpl(fn_), } } - pub fn receiver_param(&self, db: &dyn HirDatabase) -> Option<(SelfParam, Type)> { + pub fn receiver_param(&self, db: &'db dyn HirDatabase) -> Option<(SelfParam, Type<'db>)> { let func = match self.callee { Callee::Def(CallableDefId::FunctionId(it)) if self.is_bound_method => it, _ => return None, @@ -5896,7 +5954,7 @@ impl Callable { pub fn n_params(&self) -> usize { self.sig.params().len() - if self.is_bound_method { 1 } else { 0 } } - pub fn params(&self) -> Vec { + pub fn params(&self) -> Vec> { self.sig .params() .iter() @@ -5906,14 +5964,14 @@ impl Callable { .map(|(idx, ty)| Param { func: self.callee.clone(), idx, ty }) .collect() } - pub fn return_type(&self) -> Type { + pub fn return_type(&self) -> Type<'db> { self.ty.derived(self.sig.ret().clone()) } pub fn sig(&self) -> &CallableSig { &self.sig } - pub fn ty(&self) -> &Type { + pub fn ty(&self) -> &Type<'db> { &self.ty } } @@ -6062,9 +6120,9 @@ impl From for ScopeDef { } #[derive(Clone, Debug, PartialEq, Eq)] -pub struct Adjustment { - pub source: Type, - pub target: Type, +pub struct Adjustment<'db> { + pub source: Type<'db>, + pub target: Type<'db>, pub kind: Adjust, } @@ -6163,7 +6221,7 @@ impl HasCrate for TypeAlias { } } -impl HasCrate for Type { +impl HasCrate for Type<'_> { fn krate(&self, _db: &dyn HirDatabase) -> Crate { self.env.krate.into() } @@ -6317,9 +6375,9 @@ pub enum DocLinkDef { SelfType(Trait), } -fn push_ty_diagnostics( - db: &dyn HirDatabase, - acc: &mut Vec, +fn push_ty_diagnostics<'db>( + db: &'db dyn HirDatabase, + acc: &mut Vec>, diagnostics: Option>, source_map: &TypesSourceMap, ) { diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index e5df574199f5..3fff3bf0747b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -107,15 +107,15 @@ impl PathResolution { } #[derive(Debug)] -pub struct TypeInfo { +pub struct TypeInfo<'db> { /// The original type of the expression or pattern. - pub original: Type, + pub original: Type<'db>, /// The adjusted type, if an adjustment happened. - pub adjusted: Option, + pub adjusted: Option>, } -impl TypeInfo { - pub fn original(self) -> Type { +impl<'db> TypeInfo<'db> { + pub fn original(self) -> Type<'db> { self.original } @@ -124,7 +124,7 @@ impl TypeInfo { } /// The adjusted type, or the original in case no adjustments occurred. - pub fn adjusted(self) -> Type { + pub fn adjusted(self) -> Type<'db> { self.adjusted.unwrap_or(self.original) } } @@ -1347,7 +1347,7 @@ impl<'db> SemanticsImpl<'db> { Some(Label { parent, label_id }) } - pub fn resolve_type(&self, ty: &ast::Type) -> Option { + pub fn resolve_type(&self, ty: &ast::Type) -> Option> { let analyze = self.analyze(ty.syntax())?; let (mut types_map, mut types_source_map) = (TypesMap::default(), TypesSourceMap::default()); @@ -1378,7 +1378,7 @@ impl<'db> SemanticsImpl<'db> { } } - pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option> { + pub fn expr_adjustments(&self, expr: &ast::Expr) -> Option>> { let mutability = |m| match m { hir_ty::Mutability::Not => Mutability::Shared, hir_ty::Mutability::Mut => Mutability::Mut, @@ -1421,13 +1421,13 @@ impl<'db> SemanticsImpl<'db> { }) } - pub fn type_of_expr(&self, expr: &ast::Expr) -> Option { + pub fn type_of_expr(&self, expr: &ast::Expr) -> Option> { self.analyze(expr.syntax())? .type_of_expr(self.db, expr) .map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced }) } - pub fn type_of_pat(&self, pat: &ast::Pat) -> Option { + pub fn type_of_pat(&self, pat: &ast::Pat) -> Option> { self.analyze(pat.syntax())? .type_of_pat(self.db, pat) .map(|(ty, coerced)| TypeInfo { original: ty, adjusted: coerced }) @@ -1436,15 +1436,15 @@ impl<'db> SemanticsImpl<'db> { /// It also includes the changes that binding mode makes in the type. For example in /// `let ref x @ Some(_) = None` the result of `type_of_pat` is `Option` but the result /// of this function is `&mut Option` - pub fn type_of_binding_in_pat(&self, pat: &ast::IdentPat) -> Option { + pub fn type_of_binding_in_pat(&self, pat: &ast::IdentPat) -> Option> { self.analyze(pat.syntax())?.type_of_binding_in_pat(self.db, pat) } - pub fn type_of_self(&self, param: &ast::SelfParam) -> Option { + pub fn type_of_self(&self, param: &ast::SelfParam) -> Option> { self.analyze(param.syntax())?.type_of_self(self.db, param) } - pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type; 1]> { + pub fn pattern_adjustments(&self, pat: &ast::Pat) -> SmallVec<[Type<'db>; 1]> { self.analyze(pat.syntax()) .and_then(|it| it.pattern_adjustments(self.db, pat)) .unwrap_or_default() @@ -1454,7 +1454,7 @@ impl<'db> SemanticsImpl<'db> { self.analyze(pat.syntax())?.binding_mode_of_pat(self.db, pat) } - pub fn resolve_expr_as_callable(&self, call: &ast::Expr) -> Option { + pub fn resolve_expr_as_callable(&self, call: &ast::Expr) -> Option> { self.analyze(call.syntax())?.resolve_expr_as_callable(self.db, call) } @@ -1466,7 +1466,7 @@ impl<'db> SemanticsImpl<'db> { pub fn resolve_method_call_fallback( &self, call: &ast::MethodCallExpr, - ) -> Option<(Either, Option)> { + ) -> Option<(Either, Option>)> { self.analyze(call.syntax())?.resolve_method_call_fallback(self.db, call) } @@ -1474,10 +1474,10 @@ impl<'db> SemanticsImpl<'db> { // FIXME: better api for the trait environment pub fn resolve_trait_impl_method( &self, - env: Type, + env: Type<'db>, trait_: Trait, func: Function, - subst: impl IntoIterator, + subst: impl IntoIterator>, ) -> Option { let mut substs = hir_ty::TyBuilder::subst_for_def(self.db, TraitId::from(trait_), None); for s in subst { @@ -1516,7 +1516,10 @@ impl<'db> SemanticsImpl<'db> { // This does not resolve the method call to the correct trait impl! // We should probably fix that. - pub fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option { + pub fn resolve_method_call_as_callable( + &self, + call: &ast::MethodCallExpr, + ) -> Option> { self.analyze(call.syntax())?.resolve_method_call_as_callable(self.db, call) } @@ -1527,14 +1530,15 @@ impl<'db> SemanticsImpl<'db> { pub fn resolve_field_fallback( &self, field: &ast::FieldExpr, - ) -> Option<(Either, Function>, Option)> { + ) -> Option<(Either, Function>, Option>)> + { self.analyze(field.syntax())?.resolve_field_fallback(self.db, field) } pub fn resolve_record_field( &self, field: &ast::RecordExprField, - ) -> Option<(Field, Option, Type)> { + ) -> Option<(Field, Option, Type<'db>)> { self.resolve_record_field_with_substitution(field) .map(|(field, local, ty, _)| (field, local, ty)) } @@ -1542,18 +1546,21 @@ impl<'db> SemanticsImpl<'db> { pub fn resolve_record_field_with_substitution( &self, field: &ast::RecordExprField, - ) -> Option<(Field, Option, Type, GenericSubstitution)> { + ) -> Option<(Field, Option, Type<'db>, GenericSubstitution<'db>)> { self.analyze(field.syntax())?.resolve_record_field(self.db, field) } - pub fn resolve_record_pat_field(&self, field: &ast::RecordPatField) -> Option<(Field, Type)> { + pub fn resolve_record_pat_field( + &self, + field: &ast::RecordPatField, + ) -> Option<(Field, Type<'db>)> { self.resolve_record_pat_field_with_subst(field).map(|(field, ty, _)| (field, ty)) } pub fn resolve_record_pat_field_with_subst( &self, field: &ast::RecordPatField, - ) -> Option<(Field, Type, GenericSubstitution)> { + ) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> { self.analyze(field.syntax())?.resolve_record_pat_field(self.db, field) } @@ -1633,7 +1640,7 @@ impl<'db> SemanticsImpl<'db> { pub fn resolve_path_with_subst( &self, path: &ast::Path, - ) -> Option<(PathResolution, Option)> { + ) -> Option<(PathResolution, Option>)> { self.analyze(path.syntax())?.resolve_path(self.db, path) } @@ -1659,13 +1666,19 @@ impl<'db> SemanticsImpl<'db> { self.analyze(pat.syntax())?.resolve_bind_pat_to_const(self.db, pat) } - pub fn record_literal_missing_fields(&self, literal: &ast::RecordExpr) -> Vec<(Field, Type)> { + pub fn record_literal_missing_fields( + &self, + literal: &ast::RecordExpr, + ) -> Vec<(Field, Type<'db>)> { self.analyze(literal.syntax()) .and_then(|it| it.record_literal_missing_fields(self.db, literal)) .unwrap_or_default() } - pub fn record_pattern_missing_fields(&self, pattern: &ast::RecordPat) -> Vec<(Field, Type)> { + pub fn record_pattern_missing_fields( + &self, + pattern: &ast::RecordPat, + ) -> Vec<(Field, Type<'db>)> { self.analyze(pattern.syntax()) .and_then(|it| it.record_pattern_missing_fields(self.db, pattern)) .unwrap_or_default() diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index ba5ceef00a69..58e621a952da 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -154,11 +154,11 @@ impl SourceAnalyzer { infer.expr_adjustments.get(&expr_id).map(|v| &**v) } - pub(crate) fn type_of_expr( + pub(crate) fn type_of_expr<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, expr: &ast::Expr, - ) -> Option<(Type, Option)> { + ) -> Option<(Type<'db>, Option>)> { let expr_id = self.expr_id(expr.clone())?; let infer = self.infer.as_ref()?; let coerced = expr_id @@ -170,11 +170,11 @@ impl SourceAnalyzer { Some((mk_ty(ty), coerced.map(mk_ty))) } - pub(crate) fn type_of_pat( + pub(crate) fn type_of_pat<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, pat: &ast::Pat, - ) -> Option<(Type, Option)> { + ) -> Option<(Type<'db>, Option>)> { let expr_or_pat_id = self.pat_id(pat)?; let infer = self.infer.as_ref()?; let coerced = match expr_or_pat_id { @@ -193,11 +193,11 @@ impl SourceAnalyzer { Some((mk_ty(ty), coerced.map(mk_ty))) } - pub(crate) fn type_of_binding_in_pat( + pub(crate) fn type_of_binding_in_pat<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, pat: &ast::IdentPat, - ) -> Option { + ) -> Option> { let binding_id = self.binding_id_of_pat(pat)?; let infer = self.infer.as_ref()?; let ty = infer[binding_id].clone(); @@ -205,11 +205,11 @@ impl SourceAnalyzer { Some(mk_ty(ty)) } - pub(crate) fn type_of_self( + pub(crate) fn type_of_self<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, _param: &ast::SelfParam, - ) -> Option { + ) -> Option> { let binding = self.body()?.self_param?; let ty = self.infer.as_ref()?[binding].clone(); Some(Type::new_with_resolver(db, &self.resolver, ty)) @@ -230,11 +230,11 @@ impl SourceAnalyzer { } }) } - pub(crate) fn pattern_adjustments( + pub(crate) fn pattern_adjustments<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, pat: &ast::Pat, - ) -> Option> { + ) -> Option; 1]>> { let pat_id = self.pat_id(pat)?; let infer = self.infer.as_ref()?; Some( @@ -247,11 +247,11 @@ impl SourceAnalyzer { ) } - pub(crate) fn resolve_method_call_as_callable( + pub(crate) fn resolve_method_call_as_callable<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, call: &ast::MethodCallExpr, - ) -> Option { + ) -> Option> { let expr_id = self.expr_id(call.clone().into())?.as_expr()?; let (func, substs) = self.infer.as_ref()?.method_resolution(expr_id)?; let ty = db.value_ty(func.into())?.substitute(Interner, &substs); @@ -272,11 +272,11 @@ impl SourceAnalyzer { Some(self.resolve_impl_method_or_trait_def(db, f_in_trait, substs).into()) } - pub(crate) fn resolve_method_call_fallback( + pub(crate) fn resolve_method_call_fallback<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, call: &ast::MethodCallExpr, - ) -> Option<(Either, Option)> { + ) -> Option<(Either, Option>)> { let expr_id = self.expr_id(call.clone().into())?.as_expr()?; let inference_result = self.infer.as_ref()?; match inference_result.method_resolution(expr_id) { @@ -296,11 +296,11 @@ impl SourceAnalyzer { } } - pub(crate) fn resolve_expr_as_callable( + pub(crate) fn resolve_expr_as_callable<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, call: &ast::Expr, - ) -> Option { + ) -> Option> { let (orig, adjusted) = self.type_of_expr(db, &call.clone())?; adjusted.unwrap_or(orig).as_callable(db) } @@ -316,12 +316,12 @@ impl SourceAnalyzer { }) } - fn field_subst( + fn field_subst<'db>( &self, field_expr: ExprId, infer: &InferenceResult, - db: &dyn HirDatabase, - ) -> Option { + db: &'db dyn HirDatabase, + ) -> Option> { let body = self.body()?; if let Expr::Field { expr: object_expr, name: _ } = body[field_expr] { let (adt, subst) = type_of_expr_including_adjust(infer, object_expr)?.as_adt()?; @@ -334,11 +334,12 @@ impl SourceAnalyzer { None } - pub(crate) fn resolve_field_fallback( + pub(crate) fn resolve_field_fallback<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, field: &ast::FieldExpr, - ) -> Option<(Either, Function>, Option)> { + ) -> Option<(Either, Function>, Option>)> + { let &(def, ..) = self.def.as_ref()?; let expr_id = self.expr_id(field.clone().into())?.as_expr()?; let inference_result = self.infer.as_ref()?; @@ -562,11 +563,11 @@ impl SourceAnalyzer { Some(self.resolve_impl_method_or_trait_def(db, op_fn, substs)) } - pub(crate) fn resolve_record_field( + pub(crate) fn resolve_record_field<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, field: &ast::RecordExprField, - ) -> Option<(Field, Option, Type, GenericSubstitution)> { + ) -> Option<(Field, Option, Type<'db>, GenericSubstitution<'db>)> { let record_expr = ast::RecordExpr::cast(field.syntax().parent().and_then(|p| p.parent())?)?; let expr = ast::Expr::from(record_expr); let expr_id = self.body_source_map()?.node_expr(InFile::new(self.file_id, &expr))?; @@ -606,11 +607,11 @@ impl SourceAnalyzer { )) } - pub(crate) fn resolve_record_pat_field( + pub(crate) fn resolve_record_pat_field<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, field: &ast::RecordPatField, - ) -> Option<(Field, Type, GenericSubstitution)> { + ) -> Option<(Field, Type<'db>, GenericSubstitution<'db>)> { let field_name = field.field_name()?.as_name(); let record_pat = ast::RecordPat::cast(field.syntax().parent().and_then(|p| p.parent())?)?; let pat_id = self.pat_id(&record_pat.into())?; @@ -676,11 +677,11 @@ impl SourceAnalyzer { .map(crate::TypeParam::from) } - pub(crate) fn resolve_path( + pub(crate) fn resolve_path<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, path: &ast::Path, - ) -> Option<(PathResolution, Option)> { + ) -> Option<(PathResolution, Option>)> { let parent = path.syntax().parent(); let parent = || parent.clone(); @@ -1023,11 +1024,11 @@ impl SourceAnalyzer { } } - pub(crate) fn record_literal_missing_fields( + pub(crate) fn record_literal_missing_fields<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, literal: &ast::RecordExpr, - ) -> Option> { + ) -> Option)>> { let body = self.body()?; let infer = self.infer.as_ref()?; @@ -1046,11 +1047,11 @@ impl SourceAnalyzer { Some(res) } - pub(crate) fn record_pattern_missing_fields( + pub(crate) fn record_pattern_missing_fields<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, pattern: &ast::RecordPat, - ) -> Option> { + ) -> Option)>> { let body = self.body()?; let infer = self.infer.as_ref()?; @@ -1063,13 +1064,13 @@ impl SourceAnalyzer { Some(res) } - fn missing_fields( + fn missing_fields<'db>( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, substs: &Substitution, variant: VariantId, missing_fields: Vec, - ) -> Vec<(Field, Type)> { + ) -> Vec<(Field, Type<'db>)> { let field_types = db.field_types(variant); missing_fields diff --git a/crates/hir/src/term_search.rs b/crates/hir/src/term_search.rs index af72179305c8..4b354e640628 100644 --- a/crates/hir/src/term_search.rs +++ b/crates/hir/src/term_search.rs @@ -22,20 +22,20 @@ enum NewTypesKey { /// Helper enum to squash big number of alternative trees into `Many` variant as there is too many /// to take into account. #[derive(Debug)] -enum AlternativeExprs { +enum AlternativeExprs<'db> { /// There are few trees, so we keep track of them all - Few(FxHashSet), + Few(FxHashSet>), /// There are too many trees to keep track of Many, } -impl AlternativeExprs { +impl<'db> AlternativeExprs<'db> { /// Construct alternative trees /// /// # Arguments /// `threshold` - threshold value for many trees (more than that is many) /// `exprs` - expressions iterator - fn new(threshold: usize, exprs: impl Iterator) -> AlternativeExprs { + fn new(threshold: usize, exprs: impl Iterator>) -> AlternativeExprs<'db> { let mut it = AlternativeExprs::Few(Default::default()); it.extend_with_threshold(threshold, exprs); it @@ -45,7 +45,7 @@ impl AlternativeExprs { /// /// # Arguments /// `ty` - Type of expressions queried (this is used to give type to `Expr::Many`) - fn exprs(&self, ty: &Type) -> Vec { + fn exprs(&self, ty: &Type<'db>) -> Vec> { match self { AlternativeExprs::Few(exprs) => exprs.iter().cloned().collect(), AlternativeExprs::Many => vec![Expr::Many(ty.clone())], @@ -57,7 +57,7 @@ impl AlternativeExprs { /// # Arguments /// `threshold` - threshold value for many trees (more than that is many) /// `exprs` - expressions iterator - fn extend_with_threshold(&mut self, threshold: usize, exprs: impl Iterator) { + fn extend_with_threshold(&mut self, threshold: usize, exprs: impl Iterator>) { match self { AlternativeExprs::Few(tts) => { for it in exprs { @@ -88,20 +88,20 @@ impl AlternativeExprs { /// Both of them are to speed up the term search by leaving out types / ScopeDefs that likely do /// not produce any new results. #[derive(Default, Debug)] -struct LookupTable { +struct LookupTable<'db> { /// All the `Expr`s in "value" produce the type of "key" - data: FxHashMap, + data: FxHashMap, AlternativeExprs<'db>>, /// New types reached since last query by the `NewTypesKey` - new_types: FxHashMap>, + new_types: FxHashMap>>, /// Types queried but not present - types_wishlist: FxHashSet, + types_wishlist: FxHashSet>, /// Threshold to squash trees to `Many` many_threshold: usize, } -impl LookupTable { +impl<'db> LookupTable<'db> { /// Initialize lookup table - fn new(many_threshold: usize, goal: Type) -> Self { + fn new(many_threshold: usize, goal: Type<'db>) -> Self { let mut res = Self { many_threshold, ..Default::default() }; res.new_types.insert(NewTypesKey::ImplMethod, Vec::new()); res.new_types.insert(NewTypesKey::StructProjection, Vec::new()); @@ -110,7 +110,7 @@ impl LookupTable { } /// Find all `Expr`s that unify with the `ty` - fn find(&mut self, db: &dyn HirDatabase, ty: &Type) -> Option> { + fn find(&mut self, db: &'db dyn HirDatabase, ty: &Type<'db>) -> Option>> { let res = self .data .iter() @@ -135,7 +135,7 @@ impl LookupTable { /// /// For example if we have type `i32` in data and we query for `&i32` it map all the type /// trees we have for `i32` with `Expr::Reference` and returns them. - fn find_autoref(&mut self, db: &dyn HirDatabase, ty: &Type) -> Option> { + fn find_autoref(&mut self, db: &'db dyn HirDatabase, ty: &Type<'db>) -> Option>> { let res = self .data .iter() @@ -174,7 +174,7 @@ impl LookupTable { /// Note that the types have to be the same, unification is not enough as unification is not /// transitive. For example Vec and FxHashSet both unify with Iterator, /// but they clearly do not unify themselves. - fn insert(&mut self, ty: Type, exprs: impl Iterator) { + fn insert(&mut self, ty: Type<'db>, exprs: impl Iterator>) { match self.data.get_mut(&ty) { Some(it) => { it.extend_with_threshold(self.many_threshold, exprs); @@ -192,14 +192,14 @@ impl LookupTable { } /// Iterate all the reachable types - fn iter_types(&self) -> impl Iterator + '_ { + fn iter_types(&self) -> impl Iterator> + '_ { self.data.keys().cloned() } /// Query new types reached since last query by key /// /// Create new key if you wish to query it to avoid conflicting with existing queries. - fn new_types(&mut self, key: NewTypesKey) -> Vec { + fn new_types(&mut self, key: NewTypesKey) -> Vec> { match self.new_types.get_mut(&key) { Some(it) => std::mem::take(it), None => Vec::new(), @@ -207,20 +207,20 @@ impl LookupTable { } /// Types queried but not found - fn types_wishlist(&mut self) -> &FxHashSet { + fn types_wishlist(&mut self) -> &FxHashSet> { &self.types_wishlist } } /// Context for the `term_search` function #[derive(Debug)] -pub struct TermSearchCtx<'a, DB: HirDatabase> { +pub struct TermSearchCtx<'db, DB: HirDatabase> { /// Semantics for the program - pub sema: &'a Semantics<'a, DB>, + pub sema: &'db Semantics<'db, DB>, /// Semantic scope, captures context for the term search - pub scope: &'a SemanticsScope<'a>, + pub scope: &'db SemanticsScope<'db>, /// Target / expected output type - pub goal: Type, + pub goal: Type<'db>, /// Configuration for term search pub config: TermSearchConfig, } @@ -263,7 +263,7 @@ impl Default for TermSearchConfig { /// Note that there are usually more ways we can get to the `goal` type but some are discarded to /// reduce the memory consumption. It is also unlikely anyone is willing ti browse through /// thousands of possible responses so we currently take first 10 from every tactic. -pub fn term_search(ctx: &TermSearchCtx<'_, DB>) -> Vec { +pub fn term_search<'db, DB: HirDatabase>(ctx: &'db TermSearchCtx<'db, DB>) -> Vec> { let module = ctx.scope.module(); let mut defs = FxHashSet::default(); defs.insert(ScopeDef::ModuleDef(ModuleDef::Module(module))); @@ -285,7 +285,7 @@ pub fn term_search(ctx: &TermSearchCtx<'_, DB>) -> Vec { }; // Try trivial tactic first, also populates lookup table - let mut solutions: Vec = tactics::trivial(ctx, &defs, &mut lookup).collect(); + let mut solutions: Vec> = tactics::trivial(ctx, &defs, &mut lookup).collect(); // Use well known types tactic before iterations as it does not depend on other tactics solutions.extend(tactics::famous_types(ctx, &defs, &mut lookup)); solutions.extend(tactics::assoc_const(ctx, &defs, &mut lookup)); diff --git a/crates/hir/src/term_search/expr.rs b/crates/hir/src/term_search/expr.rs index 0d672dc332f3..c648f704b6f1 100644 --- a/crates/hir/src/term_search/expr.rs +++ b/crates/hir/src/term_search/expr.rs @@ -59,7 +59,7 @@ fn mod_item_path_str( /// So in short it pretty much gives us a way to get type `Option` using the items we have in /// scope. #[derive(Debug, Clone, Eq, Hash, PartialEq)] -pub enum Expr { +pub enum Expr<'db> { /// Constant Const(Const), /// Static variable @@ -69,26 +69,31 @@ pub enum Expr { /// Constant generic parameter ConstParam(ConstParam), /// Well known type (such as `true` for bool) - FamousType { ty: Type, value: &'static str }, + FamousType { ty: Type<'db>, value: &'static str }, /// Function call (does not take self param) - Function { func: Function, generics: Vec, params: Vec }, + Function { func: Function, generics: Vec>, params: Vec> }, /// Method call (has self param) - Method { func: Function, generics: Vec, target: Box, params: Vec }, + Method { + func: Function, + generics: Vec>, + target: Box>, + params: Vec>, + }, /// Enum variant construction - Variant { variant: Variant, generics: Vec, params: Vec }, + Variant { variant: Variant, generics: Vec>, params: Vec> }, /// Struct construction - Struct { strukt: Struct, generics: Vec, params: Vec }, + Struct { strukt: Struct, generics: Vec>, params: Vec> }, /// Tuple construction - Tuple { ty: Type, params: Vec }, + Tuple { ty: Type<'db>, params: Vec> }, /// Struct field access - Field { expr: Box, field: Field }, + Field { expr: Box>, field: Field }, /// Passing type as reference (with `&`) - Reference(Box), + Reference(Box>), /// Indicates possibility of many different options that all evaluate to `ty` - Many(Type), + Many(Type<'db>), } -impl Expr { +impl<'db> Expr<'db> { /// Generate source code for type tree. /// /// Note that trait imports are not added to generated code. @@ -96,8 +101,8 @@ impl Expr { /// by `traits_used` method are also imported. pub fn gen_source_code( &self, - sema_scope: &SemanticsScope<'_>, - many_formatter: &mut dyn FnMut(&Type) -> String, + sema_scope: &SemanticsScope<'db>, + many_formatter: &mut dyn FnMut(&Type<'db>) -> String, cfg: ImportPathConfig, display_target: DisplayTarget, ) -> Result { @@ -298,7 +303,7 @@ impl Expr { /// Get type of the type tree. /// /// Same as getting the type of root node - pub fn ty(&self, db: &dyn HirDatabase) -> Type { + pub fn ty(&self, db: &'db dyn HirDatabase) -> Type<'db> { match self { Expr::Const(it) => it.ty(db), Expr::Static(it) => it.ty(db), diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index bcff44fcd016..9df131f90e40 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -40,11 +40,11 @@ use super::{LookupTable, NewTypesKey, TermSearchCtx}; /// /// _Note that there is no use of calling this tactic in every iteration as the output does not /// depend on the current state of `lookup`_ -pub(super) fn trivial<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn trivial<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, defs: &'a FxHashSet, - lookup: &'a mut LookupTable, -) -> impl Iterator + 'a { + lookup: &'lt mut LookupTable<'db>, +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; defs.iter().filter_map(|def| { let expr = match def { @@ -104,11 +104,11 @@ pub(super) fn trivial<'a, DB: HirDatabase>( /// /// _Note that there is no use of calling this tactic in every iteration as the output does not /// depend on the current state of `lookup`_ -pub(super) fn assoc_const<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn assoc_const<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, defs: &'a FxHashSet, - lookup: &'a mut LookupTable, -) -> impl Iterator + 'a { + lookup: &'lt mut LookupTable<'db>, +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -152,12 +152,12 @@ pub(super) fn assoc_const<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn data_constructor<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn data_constructor<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); lookup @@ -199,14 +199,14 @@ pub(super) fn data_constructor<'a, DB: HirDatabase>( let generics: Vec<_> = ty.type_arguments().collect(); // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = fields + let param_exprs: Vec>> = fields .into_iter() .map(|field| lookup.find(db, &field.ty_with_args(db, generics.iter().cloned()))) .collect::>()?; // Note that we need special case for 0 param constructors because of multi cartesian // product - let exprs: Vec = if param_exprs.is_empty() { + let exprs: Vec> = if param_exprs.is_empty() { vec![Expr::Struct { strukt, generics, params: Vec::new() }] } else { param_exprs @@ -247,7 +247,7 @@ pub(super) fn data_constructor<'a, DB: HirDatabase>( .into_iter() .filter_map(|variant| { // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = variant + let param_exprs: Vec>> = variant .fields(db) .into_iter() .map(|field| { @@ -257,7 +257,7 @@ pub(super) fn data_constructor<'a, DB: HirDatabase>( // Note that we need special case for 0 param constructors because of multi cartesian // product - let variant_exprs: Vec = if param_exprs.is_empty() { + let variant_exprs: Vec> = if param_exprs.is_empty() { vec![Expr::Variant { variant, generics: generics.clone(), @@ -301,12 +301,12 @@ pub(super) fn data_constructor<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn free_function<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn free_function<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); defs.iter() @@ -375,7 +375,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>( } // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = it + let param_exprs: Vec>> = it .params_without_self_with_args(db, generics.iter().cloned()) .into_iter() .map(|field| { @@ -389,7 +389,7 @@ pub(super) fn free_function<'a, DB: HirDatabase>( // Note that we need special case for 0 param constructors because of multi cartesian // product - let fn_exprs: Vec = if param_exprs.is_empty() { + let fn_exprs: Vec> = if param_exprs.is_empty() { vec![Expr::Function { func: *it, generics, params: Vec::new() }] } else { param_exprs @@ -432,12 +432,12 @@ pub(super) fn free_function<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn impl_method<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn impl_method<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); lookup @@ -507,14 +507,14 @@ pub(super) fn impl_method<'a, DB: HirDatabase>( let target_type_exprs = lookup.find(db, &ty).expect("Type not in lookup"); // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = it + let param_exprs: Vec>> = it .params_without_self_with_args(db, ty.type_arguments()) .into_iter() .map(|field| lookup.find_autoref(db, field.ty())) .collect::>()?; let generics: Vec<_> = ty.type_arguments().collect(); - let fn_exprs: Vec = std::iter::once(target_type_exprs) + let fn_exprs: Vec> = std::iter::once(target_type_exprs) .chain(param_exprs) .multi_cartesian_product() .map(|params| { @@ -547,12 +547,12 @@ pub(super) fn impl_method<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn struct_projection<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn struct_projection<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); lookup @@ -589,11 +589,11 @@ pub(super) fn struct_projection<'a, DB: HirDatabase>( /// * `ctx` - Context for the term search /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types -pub(super) fn famous_types<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn famous_types<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, -) -> impl Iterator + 'a { + lookup: &'lt mut LookupTable<'db>, +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); [ @@ -620,12 +620,12 @@ pub(super) fn famous_types<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn impl_static_method<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn impl_static_method<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); lookup @@ -683,7 +683,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( } // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = it + let param_exprs: Vec>> = it .params_without_self_with_args(db, ty.type_arguments()) .into_iter() .map(|field| lookup.find_autoref(db, field.ty())) @@ -692,7 +692,7 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( // Note that we need special case for 0 param constructors because of multi cartesian // product let generics = ty.type_arguments().collect(); - let fn_exprs: Vec = if param_exprs.is_empty() { + let fn_exprs: Vec> = if param_exprs.is_empty() { vec![Expr::Function { func: it, generics, params: Vec::new() }] } else { param_exprs @@ -722,12 +722,12 @@ pub(super) fn impl_static_method<'a, DB: HirDatabase>( /// * `defs` - Set of items in scope at term search target location /// * `lookup` - Lookup table for types /// * `should_continue` - Function that indicates when to stop iterating -pub(super) fn make_tuple<'a, DB: HirDatabase>( - ctx: &'a TermSearchCtx<'a, DB>, +pub(super) fn make_tuple<'a, 'lt, 'db, DB: HirDatabase>( + ctx: &'a TermSearchCtx<'db, DB>, _defs: &'a FxHashSet, - lookup: &'a mut LookupTable, + lookup: &'lt mut LookupTable<'db>, should_continue: &'a dyn std::ops::Fn() -> bool, -) -> impl Iterator + 'a { +) -> impl Iterator> + use<'a, 'db, 'lt, DB> { let db = ctx.sema.db; let module = ctx.scope.module(); @@ -749,15 +749,15 @@ pub(super) fn make_tuple<'a, DB: HirDatabase>( } // Early exit if some param cannot be filled from lookup - let param_exprs: Vec> = + let param_exprs: Vec>> = ty.type_arguments().map(|field| lookup.find(db, &field)).collect::>()?; - let exprs: Vec = param_exprs + let exprs: Vec> = param_exprs .into_iter() .multi_cartesian_product() .filter(|_| should_continue()) .map(|params| { - let tys: Vec = params.iter().map(|it| it.ty(db)).collect(); + let tys: Vec> = params.iter().map(|it| it.ty(db)).collect(); let tuple_ty = Type::new_tuple(module.krate().into(), &tys); let expr = Expr::Tuple { ty: tuple_ty.clone(), params }; diff --git a/crates/ide-assists/src/assist_context.rs b/crates/ide-assists/src/assist_context.rs index afb2229d3e2f..23feb055915d 100644 --- a/crates/ide-assists/src/assist_context.rs +++ b/crates/ide-assists/src/assist_context.rs @@ -100,7 +100,7 @@ impl<'a> AssistContext<'a> { } } - pub(crate) fn db(&self) -> &RootDatabase { + pub(crate) fn db(&self) -> &'a RootDatabase { self.sema.db } diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs index 65bd9141bd23..9e4a9d3827b3 100644 --- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs +++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs @@ -191,7 +191,7 @@ fn add_missing_impl_members_inner( fn try_gen_trait_body( ctx: &AssistContext<'_>, func: &ast::Fn, - trait_ref: hir::TraitRef, + trait_ref: hir::TraitRef<'_>, impl_def: &ast::Impl, edition: Edition, ) -> Option<()> { diff --git a/crates/ide-assists/src/handlers/auto_import.rs b/crates/ide-assists/src/handlers/auto_import.rs index 2c7532d919ad..cb01261cd9c7 100644 --- a/crates/ide-assists/src/handlers/auto_import.rs +++ b/crates/ide-assists/src/handlers/auto_import.rs @@ -178,9 +178,9 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< Some(()) } -pub(super) fn find_importable_node( - ctx: &AssistContext<'_>, -) -> Option<(ImportAssets, SyntaxElement)> { +pub(super) fn find_importable_node<'db>( + ctx: &AssistContext<'db>, +) -> Option<(ImportAssets<'db>, SyntaxElement)> { if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::() { ImportAssets::for_exact_path(&path_under_caret, &ctx.sema) .zip(Some(path_under_caret.syntax().clone().into())) @@ -201,7 +201,7 @@ pub(super) fn find_importable_node( } } -fn group_label(import_candidate: &ImportCandidate) -> GroupLabel { +fn group_label(import_candidate: &ImportCandidate<'_>) -> GroupLabel { let name = match import_candidate { ImportCandidate::Path(candidate) => format!("Import {}", candidate.name.text()), ImportCandidate::TraitAssocItem(candidate) => { diff --git a/crates/ide-assists/src/handlers/extract_function.rs b/crates/ide-assists/src/handlers/extract_function.rs index 5a6a7ede3526..c9f557c90c57 100644 --- a/crates/ide-assists/src/handlers/extract_function.rs +++ b/crates/ide-assists/src/handlers/extract_function.rs @@ -317,23 +317,23 @@ fn extraction_target(node: &SyntaxNode, selection_range: TextRange) -> Option { name: ast::NameRef, self_param: Option, - params: Vec, - control_flow: ControlFlow, - ret_ty: RetType, + params: Vec>, + control_flow: ControlFlow<'db>, + ret_ty: RetType<'db>, body: FunctionBody, outliving_locals: Vec, /// Whether at least one of the container's tail expr is contained in the range we're extracting. contains_tail_expr: bool, - mods: ContainerInfo, + mods: ContainerInfo<'db>, } #[derive(Debug)] -struct Param { +struct Param<'db> { var: Local, - ty: hir::Type, + ty: hir::Type<'db>, move_local: bool, requires_mut: bool, is_copy: bool, @@ -348,10 +348,10 @@ enum ParamKind { } #[derive(Debug)] -enum FunType { +enum FunType<'db> { Unit, - Single(hir::Type), - Tuple(Vec), + Single(hir::Type<'db>), + Tuple(Vec>), } /// Where to put extracted function definition @@ -366,19 +366,19 @@ enum Anchor { // FIXME: ControlFlow and ContainerInfo both track some function modifiers, feels like these two should // probably be merged somehow. #[derive(Debug)] -struct ControlFlow { - kind: Option, +struct ControlFlow<'db> { + kind: Option>, is_async: bool, is_unsafe: bool, } /// The thing whose expression we are extracting from. Can be a function, const, static, const arg, ... #[derive(Clone, Debug)] -struct ContainerInfo { +struct ContainerInfo<'db> { is_const: bool, parent_loop: Option, /// The function's return type, const's type etc. - ret_type: Option, + ret_type: Option>, generic_param_lists: Vec, where_clauses: Vec, edition: Edition, @@ -397,11 +397,11 @@ struct ContainerInfo { /// } /// ``` #[derive(Debug, Clone)] -enum FlowKind { +enum FlowKind<'db> { /// Return with value (`return $expr;`) Return(Option), Try { - kind: TryKind, + kind: TryKind<'db>, }, /// Break with label and value (`break 'label $expr;`) Break(Option, Option), @@ -410,18 +410,18 @@ enum FlowKind { } #[derive(Debug, Clone)] -enum TryKind { +enum TryKind<'db> { Option, - Result { ty: hir::Type }, + Result { ty: hir::Type<'db> }, } #[derive(Debug)] -enum RetType { - Expr(hir::Type), +enum RetType<'db> { + Expr(hir::Type<'db>), Stmt, } -impl RetType { +impl RetType<'_> { fn is_unit(&self) -> bool { match self { RetType::Expr(ty) => ty.is_unit(), @@ -464,8 +464,8 @@ impl LocalUsages { } } -impl Function { - fn return_type(&self, ctx: &AssistContext<'_>) -> FunType { +impl<'db> Function<'db> { + fn return_type(&self, ctx: &AssistContext<'db>) -> FunType<'db> { match &self.ret_ty { RetType::Expr(ty) if ty.is_unit() => FunType::Unit, RetType::Expr(ty) => FunType::Single(ty.clone()), @@ -495,7 +495,7 @@ impl ParamKind { } } -impl Param { +impl<'db> Param<'db> { fn kind(&self) -> ParamKind { match (self.move_local, self.requires_mut, self.is_copy) { (false, true, _) => ParamKind::MutRef, @@ -505,7 +505,7 @@ impl Param { } } - fn to_arg(&self, ctx: &AssistContext<'_>, edition: Edition) -> ast::Expr { + fn to_arg(&self, ctx: &AssistContext<'db>, edition: Edition) -> ast::Expr { let var = path_expr_from_local(ctx, self.var, edition); match self.kind() { ParamKind::Value | ParamKind::MutValue => var, @@ -540,8 +540,12 @@ impl Param { } } -impl TryKind { - fn of_ty(ty: hir::Type, ctx: &AssistContext<'_>, edition: Edition) -> Option { +impl<'db> TryKind<'db> { + fn of_ty( + ty: hir::Type<'db>, + ctx: &AssistContext<'db>, + edition: Edition, + ) -> Option> { if ty.is_unknown() { // We favour Result for `expr?` return Some(TryKind::Result { ty }); @@ -559,7 +563,7 @@ impl TryKind { } } -impl FlowKind { +impl<'db> FlowKind<'db> { fn make_result_handler(&self, expr: Option) -> ast::Expr { match self { FlowKind::Return(_) => make::expr_return(expr), @@ -575,7 +579,7 @@ impl FlowKind { } } - fn expr_ty(&self, ctx: &AssistContext<'_>) -> Option { + fn expr_ty(&self, ctx: &AssistContext<'db>) -> Option> { match self { FlowKind::Return(Some(expr)) | FlowKind::Break(_, Some(expr)) => { ctx.sema.type_of_expr(expr).map(TypeInfo::adjusted) @@ -849,11 +853,11 @@ impl FunctionBody { (res, self_param) } - fn analyze_container( + fn analyze_container<'db>( &self, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, edition: Edition, - ) -> Option<(ContainerInfo, bool)> { + ) -> Option<(ContainerInfo<'db>, bool)> { let mut ancestors = self.parent()?.ancestors(); let infer_expr_opt = |expr| sema.type_of_expr(&expr?).map(TypeInfo::adjusted); let mut parent_loop = None; @@ -958,7 +962,7 @@ impl FunctionBody { )) } - fn return_ty(&self, ctx: &AssistContext<'_>) -> Option { + fn return_ty<'db>(&self, ctx: &AssistContext<'db>) -> Option> { match self.tail_expr() { Some(expr) => ctx.sema.type_of_expr(&expr).map(TypeInfo::original).map(RetType::Expr), None => Some(RetType::Stmt), @@ -979,11 +983,11 @@ impl FunctionBody { } /// Analyses the function body for external control flow. - fn external_control_flow( + fn external_control_flow<'db>( &self, - ctx: &AssistContext<'_>, - container_info: &ContainerInfo, - ) -> Option { + ctx: &AssistContext<'db>, + container_info: &ContainerInfo<'db>, + ) -> Option> { let mut ret_expr = None; let mut try_expr = None; let mut break_expr = None; @@ -1069,12 +1073,12 @@ impl FunctionBody { /// find variables that should be extracted as params /// /// Computes additional info that affects param type and mutability - fn extracted_function_params( + fn extracted_function_params<'db>( &self, - ctx: &AssistContext<'_>, - container_info: &ContainerInfo, + ctx: &AssistContext<'db>, + container_info: &ContainerInfo<'db>, locals: FxIndexSet, - ) -> Vec { + ) -> Vec> { locals .into_iter() .sorted() @@ -1422,7 +1426,7 @@ fn fixup_call_site(builder: &mut SourceChangeBuilder, body: &FunctionBody) { } } -fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> SyntaxNode { +fn make_call(ctx: &AssistContext<'_>, fun: &Function<'_>, indent: IndentLevel) -> SyntaxNode { let ret_ty = fun.return_type(ctx); let args = make::arg_list(fun.params.iter().map(|param| param.to_arg(ctx, fun.mods.edition))); @@ -1481,17 +1485,17 @@ fn make_call(ctx: &AssistContext<'_>, fun: &Function, indent: IndentLevel) -> Sy } } -enum FlowHandler { +enum FlowHandler<'db> { None, - Try { kind: TryKind }, - If { action: FlowKind }, - IfOption { action: FlowKind }, - MatchOption { none: FlowKind }, - MatchResult { err: FlowKind }, + Try { kind: TryKind<'db> }, + If { action: FlowKind<'db> }, + IfOption { action: FlowKind<'db> }, + MatchOption { none: FlowKind<'db> }, + MatchResult { err: FlowKind<'db> }, } -impl FlowHandler { - fn from_ret_ty(fun: &Function, ret_ty: &FunType) -> FlowHandler { +impl<'db> FlowHandler<'db> { + fn from_ret_ty(fun: &Function<'db>, ret_ty: &FunType<'db>) -> FlowHandler<'db> { if fun.contains_tail_expr { return FlowHandler::None; } @@ -1601,7 +1605,7 @@ fn path_expr_from_local(ctx: &AssistContext<'_>, var: Local, edition: Edition) - fn format_function( ctx: &AssistContext<'_>, module: hir::Module, - fun: &Function, + fun: &Function<'_>, old_indent: IndentLevel, ) -> ast::Fn { let fun_name = make::name(&fun.name.text()); @@ -1627,7 +1631,7 @@ fn format_function( fn make_generic_params_and_where_clause( ctx: &AssistContext<'_>, - fun: &Function, + fun: &Function<'_>, ) -> (Option, Option) { let used_type_params = fun.type_params(ctx); @@ -1639,7 +1643,7 @@ fn make_generic_params_and_where_clause( fn make_generic_param_list( ctx: &AssistContext<'_>, - fun: &Function, + fun: &Function<'_>, used_type_params: &[TypeParam], ) -> Option { let mut generic_params = fun @@ -1676,7 +1680,7 @@ fn param_is_required( fn make_where_clause( ctx: &AssistContext<'_>, - fun: &Function, + fun: &Function<'_>, used_type_params: &[TypeParam], ) -> Option { let mut predicates = fun @@ -1716,9 +1720,9 @@ fn resolved_type_param(ctx: &AssistContext<'_>, pred: &ast::WherePred) -> Option } } -impl Function { +impl<'db> Function<'db> { /// Collect all the `TypeParam`s used in the `body` and `params`. - fn type_params(&self, ctx: &AssistContext<'_>) -> Vec { + fn type_params(&self, ctx: &AssistContext<'db>) -> Vec { let type_params_in_descendant_paths = self.body.descendant_paths().filter_map(|it| match ctx.sema.resolve_path(&it) { Some(PathResolution::TypeParam(type_param)) => Some(type_param), @@ -1781,8 +1785,8 @@ impl Function { } } -impl FunType { - fn make_ty(&self, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type { +impl<'db> FunType<'db> { + fn make_ty(&self, ctx: &AssistContext<'db>, module: hir::Module) -> ast::Type { match self { FunType::Unit => make::ty_unit(), FunType::Single(ty) => make_ty(ty, ctx, module), @@ -1804,7 +1808,11 @@ impl FunType { } } -fn make_body(ctx: &AssistContext<'_>, old_indent: IndentLevel, fun: &Function) -> ast::BlockExpr { +fn make_body( + ctx: &AssistContext<'_>, + old_indent: IndentLevel, + fun: &Function<'_>, +) -> ast::BlockExpr { let ret_ty = fun.return_type(ctx); let handler = FlowHandler::from_ret_ty(fun, &ret_ty); @@ -1981,19 +1989,19 @@ fn with_tail_expr(block: ast::BlockExpr, tail_expr: ast::Expr) -> ast::BlockExpr make::hacky_block_expr(elements, Some(tail_expr)) } -fn format_type(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> String { +fn format_type(ty: &hir::Type<'_>, ctx: &AssistContext<'_>, module: hir::Module) -> String { ty.display_source_code(ctx.db(), module.into(), true).ok().unwrap_or_else(|| "_".to_owned()) } -fn make_ty(ty: &hir::Type, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type { +fn make_ty(ty: &hir::Type<'_>, ctx: &AssistContext<'_>, module: hir::Module) -> ast::Type { let ty_str = format_type(ty, ctx, module); make::ty(&ty_str) } fn rewrite_body_segment( ctx: &AssistContext<'_>, - params: &[Param], - handler: &FlowHandler, + params: &[Param<'_>], + handler: &FlowHandler<'_>, syntax: &SyntaxNode, ) -> SyntaxNode { let syntax = fix_param_usages(ctx, params, syntax); @@ -2002,8 +2010,12 @@ fn rewrite_body_segment( } /// change all usages to account for added `&`/`&mut` for some params -fn fix_param_usages(ctx: &AssistContext<'_>, params: &[Param], syntax: &SyntaxNode) -> SyntaxNode { - let mut usages_for_param: Vec<(&Param, Vec)> = Vec::new(); +fn fix_param_usages( + ctx: &AssistContext<'_>, + params: &[Param<'_>], + syntax: &SyntaxNode, +) -> SyntaxNode { + let mut usages_for_param: Vec<(&Param<'_>, Vec)> = Vec::new(); let tm = TreeMutator::new(syntax); @@ -2057,7 +2069,7 @@ fn fix_param_usages(ctx: &AssistContext<'_>, params: &[Param], syntax: &SyntaxNo res } -fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) { +fn update_external_control_flow(handler: &FlowHandler<'_>, syntax: &SyntaxNode) { let mut nested_loop = None; let mut nested_scope = None; for event in syntax.preorder() { @@ -2118,7 +2130,10 @@ fn update_external_control_flow(handler: &FlowHandler, syntax: &SyntaxNode) { } } -fn make_rewritten_flow(handler: &FlowHandler, arg_expr: Option) -> Option { +fn make_rewritten_flow( + handler: &FlowHandler<'_>, + arg_expr: Option, +) -> Option { let value = match handler { FlowHandler::None | FlowHandler::Try { .. } => return None, FlowHandler::If { .. } => make::expr_call( diff --git a/crates/ide-assists/src/handlers/generate_function.rs b/crates/ide-assists/src/handlers/generate_function.rs index 55187c38c171..3f106d24b59c 100644 --- a/crates/ide-assists/src/handlers/generate_function.rs +++ b/crates/ide-assists/src/handlers/generate_function.rs @@ -306,7 +306,7 @@ impl FunctionBuilder { ctx: &AssistContext<'_>, call: &ast::MethodCallExpr, name: &ast::NameRef, - receiver_ty: Type, + receiver_ty: Type<'_>, target_module: Module, target: GeneratedFunctionTarget, ) -> Option { diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs index bb445e572bef..b644b428d490 100644 --- a/crates/ide-assists/src/handlers/inline_call.rs +++ b/crates/ide-assists/src/handlers/inline_call.rs @@ -281,11 +281,11 @@ impl CallInfo { } } -fn get_fn_params( - db: &dyn HirDatabase, +fn get_fn_params<'db>( + db: &'db dyn HirDatabase, function: hir::Function, param_list: &ast::ParamList, -) -> Option, hir::Param)>> { +) -> Option, hir::Param<'db>)>> { let mut assoc_fn_params = function.assoc_fn_params(db).into_iter(); let mut params = Vec::new(); @@ -314,7 +314,7 @@ fn inline( function_def_file_id: EditionedFileId, function: hir::Function, fn_body: &ast::BlockExpr, - params: &[(ast::Pat, Option, hir::Param)], + params: &[(ast::Pat, Option, hir::Param<'_>)], CallInfo { node, arguments, generic_arg_list, krate }: &CallInfo, ) -> ast::Expr { let file_id = sema.hir_file_for(fn_body.syntax()); diff --git a/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/crates/ide-assists/src/handlers/inline_const_as_literal.rs index e5ed04fdc7c9..b11d3792bc4c 100644 --- a/crates/ide-assists/src/handlers/inline_const_as_literal.rs +++ b/crates/ide-assists/src/handlers/inline_const_as_literal.rs @@ -58,7 +58,7 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_> fn validate_type_recursively( ctx: &AssistContext<'_>, - ty_hir: Option<&hir::Type>, + ty_hir: Option<&hir::Type<'_>>, refed: bool, fuel: i32, ) -> Option<()> { diff --git a/crates/ide-assists/src/handlers/merge_match_arms.rs b/crates/ide-assists/src/handlers/merge_match_arms.rs index 42f35210b496..08170f81b283 100644 --- a/crates/ide-assists/src/handlers/merge_match_arms.rs +++ b/crates/ide-assists/src/handlers/merge_match_arms.rs @@ -105,7 +105,7 @@ fn contains_placeholder(a: &ast::MatchArm) -> bool { } fn are_same_types( - current_arm_types: &FxHashMap>, + current_arm_types: &FxHashMap>>, arm: &ast::MatchArm, ctx: &AssistContext<'_>, ) -> bool { @@ -121,15 +121,15 @@ fn are_same_types( true } -fn get_arm_types( - context: &AssistContext<'_>, +fn get_arm_types<'db>( + context: &AssistContext<'db>, arm: &ast::MatchArm, -) -> FxHashMap> { - let mut mapping: FxHashMap> = FxHashMap::default(); +) -> FxHashMap>> { + let mut mapping: FxHashMap>> = FxHashMap::default(); - fn recurse( - map: &mut FxHashMap>, - ctx: &AssistContext<'_>, + fn recurse<'db>( + map: &mut FxHashMap>>, + ctx: &AssistContext<'db>, pat: &Option, ) { if let Some(local_pat) = pat { diff --git a/crates/ide-assists/src/handlers/qualify_path.rs b/crates/ide-assists/src/handlers/qualify_path.rs index 4c213a27f4b8..890eba1b4a46 100644 --- a/crates/ide-assists/src/handlers/qualify_path.rs +++ b/crates/ide-assists/src/handlers/qualify_path.rs @@ -224,7 +224,7 @@ fn item_as_trait(db: &RootDatabase, item: hir::ItemInNs) -> Option { } } -fn group_label(candidate: &ImportCandidate) -> GroupLabel { +fn group_label(candidate: &ImportCandidate<'_>) -> GroupLabel { let name = match candidate { ImportCandidate::Path(it) => &it.name, ImportCandidate::TraitAssocItem(it) | ImportCandidate::TraitMethod(it) => { @@ -237,7 +237,7 @@ fn group_label(candidate: &ImportCandidate) -> GroupLabel { fn label( db: &RootDatabase, - candidate: &ImportCandidate, + candidate: &ImportCandidate<'_>, import: &LocatedImport, edition: Edition, ) -> String { diff --git a/crates/ide-assists/src/handlers/term_search.rs b/crates/ide-assists/src/handlers/term_search.rs index 86121e7fc8c2..8c63ce81e03f 100644 --- a/crates/ide-assists/src/handlers/term_search.rs +++ b/crates/ide-assists/src/handlers/term_search.rs @@ -46,7 +46,7 @@ pub(crate) fn term_search(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option< return None; } - let mut formatter = |_: &hir::Type| String::from("todo!()"); + let mut formatter = |_: &hir::Type<'_>| String::from("todo!()"); let edition = scope.krate().edition(ctx.db()); let paths = paths diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs index 8b81c920ec95..2202d1dbda39 100644 --- a/crates/ide-assists/src/utils.rs +++ b/crates/ide-assists/src/utils.rs @@ -389,7 +389,7 @@ pub(crate) fn does_pat_variant_nested_or_literal(ctx: &AssistContext<'_>, pat: & } fn check_pat_variant_from_enum(ctx: &AssistContext<'_>, pat: &ast::Pat) -> bool { - ctx.sema.type_of_pat(pat).is_none_or(|ty: hir::TypeInfo| { + ctx.sema.type_of_pat(pat).is_none_or(|ty: hir::TypeInfo<'_>| { ty.adjusted().as_adt().is_some_and(|adt| matches!(adt, hir::Adt::Enum(_))) }) } @@ -764,9 +764,9 @@ pub(crate) fn add_method_to_adt( } #[derive(Debug)] -pub(crate) struct ReferenceConversion { +pub(crate) struct ReferenceConversion<'db> { conversion: ReferenceConversionType, - ty: hir::Type, + ty: hir::Type<'db>, impls_deref: bool, } @@ -786,10 +786,10 @@ enum ReferenceConversionType { Result, } -impl ReferenceConversion { +impl<'db> ReferenceConversion<'db> { pub(crate) fn convert_type( &self, - db: &dyn HirDatabase, + db: &'db dyn HirDatabase, display_target: DisplayTarget, ) -> ast::Type { let ty = match self.conversion { @@ -861,11 +861,11 @@ impl ReferenceConversion { // FIXME: It should return a new hir::Type, but currently constructing new types is too cumbersome // and all users of this function operate on string type names, so they can do the conversion // itself themselves. -pub(crate) fn convert_reference_type( - ty: hir::Type, - db: &RootDatabase, - famous_defs: &FamousDefs<'_, '_>, -) -> Option { +pub(crate) fn convert_reference_type<'db>( + ty: hir::Type<'db>, + db: &'db RootDatabase, + famous_defs: &FamousDefs<'_, 'db>, +) -> Option> { handle_copy(&ty, db) .or_else(|| handle_as_ref_str(&ty, db, famous_defs)) .or_else(|| handle_as_ref_slice(&ty, db, famous_defs)) @@ -875,18 +875,21 @@ pub(crate) fn convert_reference_type( .map(|(conversion, impls_deref)| ReferenceConversion { ty, conversion, impls_deref }) } -fn could_deref_to_target(ty: &hir::Type, target: &hir::Type, db: &dyn HirDatabase) -> bool { +fn could_deref_to_target(ty: &hir::Type<'_>, target: &hir::Type<'_>, db: &dyn HirDatabase) -> bool { let ty_ref = ty.add_reference(hir::Mutability::Shared); let target_ref = target.add_reference(hir::Mutability::Shared); ty_ref.could_coerce_to(db, &target_ref) } -fn handle_copy(ty: &hir::Type, db: &dyn HirDatabase) -> Option<(ReferenceConversionType, bool)> { +fn handle_copy( + ty: &hir::Type<'_>, + db: &dyn HirDatabase, +) -> Option<(ReferenceConversionType, bool)> { ty.is_copy(db).then_some((ReferenceConversionType::Copy, true)) } fn handle_as_ref_str( - ty: &hir::Type, + ty: &hir::Type<'_>, db: &dyn HirDatabase, famous_defs: &FamousDefs<'_, '_>, ) -> Option<(ReferenceConversionType, bool)> { @@ -897,7 +900,7 @@ fn handle_as_ref_str( } fn handle_as_ref_slice( - ty: &hir::Type, + ty: &hir::Type<'_>, db: &dyn HirDatabase, famous_defs: &FamousDefs<'_, '_>, ) -> Option<(ReferenceConversionType, bool)> { @@ -911,7 +914,7 @@ fn handle_as_ref_slice( } fn handle_dereferenced( - ty: &hir::Type, + ty: &hir::Type<'_>, db: &dyn HirDatabase, famous_defs: &FamousDefs<'_, '_>, ) -> Option<(ReferenceConversionType, bool)> { @@ -924,7 +927,7 @@ fn handle_dereferenced( } fn handle_option_as_ref( - ty: &hir::Type, + ty: &hir::Type<'_>, db: &dyn HirDatabase, famous_defs: &FamousDefs<'_, '_>, ) -> Option<(ReferenceConversionType, bool)> { @@ -936,7 +939,7 @@ fn handle_option_as_ref( } fn handle_result_as_ref( - ty: &hir::Type, + ty: &hir::Type<'_>, db: &dyn HirDatabase, famous_defs: &FamousDefs<'_, '_>, ) -> Option<(ReferenceConversionType, bool)> { diff --git a/crates/ide-assists/src/utils/gen_trait_fn_body.rs b/crates/ide-assists/src/utils/gen_trait_fn_body.rs index 5c2e27b3430f..b638910538c6 100644 --- a/crates/ide-assists/src/utils/gen_trait_fn_body.rs +++ b/crates/ide-assists/src/utils/gen_trait_fn_body.rs @@ -17,7 +17,7 @@ pub(crate) fn gen_trait_fn_body( func: &ast::Fn, trait_path: &ast::Path, adt: &ast::Adt, - trait_ref: Option, + trait_ref: Option>, ) -> Option<()> { match trait_path.segment()?.name_ref()?.text().as_str() { "Clone" => gen_clone_impl(adt, func), @@ -399,7 +399,7 @@ fn gen_hash_impl(adt: &ast::Adt, func: &ast::Fn) -> Option<()> { } /// Generate a `PartialEq` impl based on the fields and members of the target type. -fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option) -> Option<()> { +fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option>) -> Option<()> { stdx::always!(func.name().is_some_and(|name| name.text() == "eq")); fn gen_eq_chain(expr: Option, cmp: ast::Expr) -> Option { match expr { @@ -591,7 +591,7 @@ fn gen_partial_eq(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option) - Some(()) } -fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option) -> Option<()> { +fn gen_partial_ord(adt: &ast::Adt, func: &ast::Fn, trait_ref: Option>) -> Option<()> { stdx::always!(func.name().is_some_and(|name| name.text() == "partial_cmp")); fn gen_partial_eq_match(match_target: ast::Expr) -> Option { let mut arms = vec![]; diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index c8cdad594978..852bca233a5a 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -161,7 +161,11 @@ impl Completions { item.add_to(self, ctx.db); } - pub(crate) fn add_expr(&mut self, ctx: &CompletionContext<'_>, expr: &hir::term_search::Expr) { + pub(crate) fn add_expr( + &mut self, + ctx: &CompletionContext<'_>, + expr: &hir::term_search::Expr<'_>, + ) { if let Some(item) = render_expr(ctx, expr) { item.add_to(self, ctx.db) } @@ -170,7 +174,7 @@ impl Completions { pub(crate) fn add_crate_roots( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, ) { ctx.process_all_names(&mut |name, res, doc_aliases| match res { ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => { @@ -183,7 +187,7 @@ impl Completions { pub(crate) fn add_path_resolution( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: hir::Name, resolution: hir::ScopeDef, doc_aliases: Vec, @@ -232,7 +236,7 @@ impl Completions { pub(crate) fn add_enum_variants( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, e: hir::Enum, ) { if !ctx.check_stability_and_hidden(e) { @@ -246,7 +250,7 @@ impl Completions { pub(crate) fn add_module( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, module: hir::Module, local_name: hir::Name, doc_aliases: Vec, @@ -263,7 +267,7 @@ impl Completions { pub(crate) fn add_macro( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, mac: hir::Macro, local_name: hir::Name, ) { @@ -286,7 +290,7 @@ impl Completions { pub(crate) fn add_function( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, func: hir::Function, local_name: Option, ) { @@ -312,7 +316,7 @@ impl Completions { pub(crate) fn add_method( &mut self, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, func: hir::Function, receiver: Option, local_name: Option, @@ -340,7 +344,7 @@ impl Completions { pub(crate) fn add_method_with_import( &mut self, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, func: hir::Function, import: LocatedImport, ) { @@ -407,7 +411,7 @@ impl Completions { pub(crate) fn add_qualified_enum_variant( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, variant: hir::Variant, path: hir::ModPath, ) { @@ -424,7 +428,7 @@ impl Completions { pub(crate) fn add_enum_variant( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, variant: hir::Variant, local_name: Option, ) { @@ -447,10 +451,10 @@ impl Completions { pub(crate) fn add_field( &mut self, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, receiver: Option, field: hir::Field, - ty: &hir::Type, + ty: &hir::Type<'_>, ) { let is_private_editable = match ctx.is_visible(&field) { Visible::Yes => false, @@ -471,7 +475,7 @@ impl Completions { pub(crate) fn add_struct_literal( &mut self, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, strukt: hir::Struct, path: Option, local_name: Option, @@ -518,7 +522,7 @@ impl Completions { ctx: &CompletionContext<'_>, receiver: Option, field: usize, - ty: &hir::Type, + ty: &hir::Type<'_>, ) { // Only used for (unnamed) tuples, whose all fields *are* stable. No need to check // stability here. @@ -550,7 +554,7 @@ impl Completions { &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, - path_ctx: Option<&PathCompletionCtx>, + path_ctx: Option<&PathCompletionCtx<'_>>, variant: hir::Variant, local_name: Option, ) { @@ -705,7 +709,7 @@ pub(super) fn complete_name( pub(super) fn complete_name_ref( acc: &mut Completions, ctx: &CompletionContext<'_>, - NameRefContext { nameref, kind }: &NameRefContext, + NameRefContext { nameref, kind }: &NameRefContext<'_>, ) { match kind { NameRefKind::Path(path_ctx) => { diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs index 3c195f80fea4..32b1e7ce10ae 100644 --- a/crates/ide-completion/src/completions/attribute.rs +++ b/crates/ide-completion/src/completions/attribute.rs @@ -85,7 +85,7 @@ pub(crate) fn complete_known_attribute_input( pub(crate) fn complete_attribute_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, &AttrCtx { kind, annotated_item_kind, ref derive_helpers }: &AttrCtx, ) { let is_inner = kind == AttrKind::Inner; diff --git a/crates/ide-completion/src/completions/attribute/derive.rs b/crates/ide-completion/src/completions/attribute/derive.rs index 2fc07e013828..267d92b6c090 100644 --- a/crates/ide-completion/src/completions/attribute/derive.rs +++ b/crates/ide-completion/src/completions/attribute/derive.rs @@ -13,7 +13,7 @@ use crate::{ pub(crate) fn complete_derive_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, existing_derives: &ExistingDerives, ) { let core = ctx.famous_defs().core(); diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index 4f21136d214e..5340d65a142d 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -18,7 +18,7 @@ use crate::{ pub(crate) fn complete_dot( acc: &mut Completions, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, ) { let receiver_ty = match dot_access { DotAccess { receiver_ty: Some(receiver_ty), .. } => &receiver_ty.original, @@ -130,8 +130,8 @@ pub(crate) fn complete_dot( pub(crate) fn complete_undotted_self( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, - expr_ctx: &PathExprCtx, + path_ctx: &PathCompletionCtx<'_>, + expr_ctx: &PathExprCtx<'_>, ) { if !ctx.config.enable_self_on_the_fly { return; @@ -198,9 +198,9 @@ pub(crate) fn complete_undotted_self( fn complete_fields( acc: &mut Completions, ctx: &CompletionContext<'_>, - receiver: &hir::Type, - mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type), - mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type), + receiver: &hir::Type<'_>, + mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type<'_>), + mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type<'_>), is_field_access: bool, is_method_access_with_parens: bool, ) { @@ -230,7 +230,7 @@ fn complete_fields( fn complete_methods( ctx: &CompletionContext<'_>, - receiver: &hir::Type, + receiver: &hir::Type<'_>, traits_in_scope: &FxHashSet, f: impl FnMut(hir::Function), ) { diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs index 0494d4223d18..713d0c3fd9f4 100644 --- a/crates/ide-completion/src/completions/expr.rs +++ b/crates/ide-completion/src/completions/expr.rs @@ -47,8 +47,8 @@ where pub(crate) fn complete_expr_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, - expr_ctx: &PathExprCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, + expr_ctx: &PathExprCtx<'_>, ) { let _p = tracing::info_span!("complete_expr_path").entered(); if !ctx.qualifier_ctx.none() { diff --git a/crates/ide-completion/src/completions/field.rs b/crates/ide-completion/src/completions/field.rs index 1441b0e3a01a..26afa9c8ad96 100644 --- a/crates/ide-completion/src/completions/field.rs +++ b/crates/ide-completion/src/completions/field.rs @@ -8,7 +8,7 @@ use crate::{ pub(crate) fn complete_field_list_tuple_variant( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, ) { if ctx.qualifier_ctx.vis_node.is_some() { } else if let PathCompletionCtx { diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index a74756138090..dad8a76de87d 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -111,7 +111,7 @@ use crate::{ pub(crate) fn import_on_the_fly_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, ) -> Option<()> { if !ctx.config.enable_imports_on_the_fly { return None; @@ -175,7 +175,7 @@ pub(crate) fn import_on_the_fly_pat( pub(crate) fn import_on_the_fly_dot( acc: &mut Completions, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, ) -> Option<()> { if !ctx.config.enable_imports_on_the_fly { return None; @@ -203,8 +203,8 @@ pub(crate) fn import_on_the_fly_dot( fn import_on_the_fly( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { kind, .. }: &PathCompletionCtx, - import_assets: ImportAssets, + path_ctx @ PathCompletionCtx { kind, .. }: &PathCompletionCtx<'_>, + import_assets: ImportAssets<'_>, position: SyntaxNode, potential_import_name: String, ) -> Option<()> { @@ -290,7 +290,7 @@ fn import_on_the_fly_pat_( acc: &mut Completions, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, - import_assets: ImportAssets, + import_assets: ImportAssets<'_>, position: SyntaxNode, potential_import_name: String, ) -> Option<()> { @@ -335,8 +335,8 @@ fn import_on_the_fly_pat_( fn import_on_the_fly_method( acc: &mut Completions, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, - import_assets: ImportAssets, + dot_access: &DotAccess<'_>, + import_assets: ImportAssets<'_>, position: SyntaxNode, potential_import_name: String, ) -> Option<()> { @@ -400,11 +400,11 @@ fn import_name(ctx: &CompletionContext<'_>) -> String { if token_kind.is_any_identifier() { ctx.token.to_string() } else { String::new() } } -fn import_assets_for_path( - ctx: &CompletionContext<'_>, +fn import_assets_for_path<'db>( + ctx: &CompletionContext<'db>, potential_import_name: &str, qualifier: Option, -) -> Option { +) -> Option> { let _p = tracing::info_span!("import_assets_for_path", ?potential_import_name, ?qualifier).entered(); diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs index 58e7f584ed6f..6ac30d24c382 100644 --- a/crates/ide-completion/src/completions/item_list.rs +++ b/crates/ide-completion/src/completions/item_list.rs @@ -10,8 +10,8 @@ pub(crate) mod trait_impl; pub(crate) fn complete_item_list_in_expr( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, - expr_ctx: &PathExprCtx, + path_ctx: &PathCompletionCtx<'_>, + expr_ctx: &PathExprCtx<'_>, ) { if !expr_ctx.in_block_expr { return; @@ -25,7 +25,7 @@ pub(crate) fn complete_item_list_in_expr( pub(crate) fn complete_item_list( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, kind: &ItemListKind, ) { let _p = tracing::info_span!("complete_item_list").entered(); diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index e08271f39a32..8f6e2956c9ea 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -122,7 +122,7 @@ fn complete_trait_impl_name( pub(crate) fn complete_trait_impl_item_by_name( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, name_ref: &Option, impl_: &Option, ) { diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index ea3511d31caf..62fae1cb2374 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -124,7 +124,7 @@ pub(crate) fn complete_pattern( pub(crate) fn complete_pattern_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, ) { match qualified { Qualified::With { resolution: Some(resolution), super_chain_len, .. } => { diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs index 3a55e83026c4..88d80c552f48 100644 --- a/crates/ide-completion/src/completions/postfix.rs +++ b/crates/ide-completion/src/completions/postfix.rs @@ -28,7 +28,7 @@ use crate::{ pub(crate) fn complete_postfix( acc: &mut Completions, ctx: &CompletionContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, ) { if !ctx.config.enable_postfix_completions { return; diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs index c18aab007b2c..36f38a70db63 100644 --- a/crates/ide-completion/src/completions/record.rs +++ b/crates/ide-completion/src/completions/record.rs @@ -88,7 +88,7 @@ pub(crate) fn complete_record_expr_fields( pub(crate) fn add_default_update( acc: &mut Completions, ctx: &CompletionContext<'_>, - ty: Option, + ty: Option>, ) { let default_trait = ctx.famous_defs().core_default_Default(); let impls_default_trait = default_trait @@ -117,7 +117,7 @@ pub(crate) fn add_default_update( fn complete_fields( acc: &mut Completions, ctx: &CompletionContext<'_>, - missing_fields: Vec<(hir::Field, hir::Type)>, + missing_fields: Vec<(hir::Field, hir::Type<'_>)>, ) { for (field, ty) in missing_fields { // This should call something else, we shouldn't be synthesizing a DotAccess here diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs index 31aae1167622..ead9852eff53 100644 --- a/crates/ide-completion/src/completions/snippet.rs +++ b/crates/ide-completion/src/completions/snippet.rs @@ -11,8 +11,8 @@ use crate::{ pub(crate) fn complete_expr_snippet( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, - &PathExprCtx { in_block_expr, .. }: &PathExprCtx, + path_ctx: &PathCompletionCtx<'_>, + &PathExprCtx { in_block_expr, .. }: &PathExprCtx<'_>, ) { if !matches!(path_ctx.qualified, Qualified::No) { return; @@ -51,7 +51,7 @@ macro_rules! $1 { pub(crate) fn complete_item_snippet( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, kind: &ItemListKind, ) { if !matches!(path_ctx.qualified, Qualified::No) { diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs index 79db705af495..7c38c7d8ce44 100644 --- a/crates/ide-completion/src/completions/type.rs +++ b/crates/ide-completion/src/completions/type.rs @@ -12,7 +12,7 @@ use crate::{ pub(crate) fn complete_type_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, location: &TypeLocation, ) { let _p = tracing::info_span!("complete_type_path").entered(); @@ -220,7 +220,7 @@ pub(crate) fn complete_type_path( pub(crate) fn complete_ascribed_type( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, ascription: &TypeAscriptionTarget, ) -> Option<()> { if !path_ctx.is_trivial_path() { diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 4d6d0b758a38..d2ab193ec3df 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -13,7 +13,7 @@ use crate::{ pub(crate) fn complete_use_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, use_tree_parent, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, use_tree_parent, .. }: &PathCompletionCtx<'_>, name_ref: &Option, ) { match qualified { diff --git a/crates/ide-completion/src/completions/vis.rs b/crates/ide-completion/src/completions/vis.rs index d15c35ac8499..38761f77a2c5 100644 --- a/crates/ide-completion/src/completions/vis.rs +++ b/crates/ide-completion/src/completions/vis.rs @@ -8,7 +8,7 @@ use crate::{ pub(crate) fn complete_vis_path( acc: &mut Completions, ctx: &CompletionContext<'_>, - path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx, + path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx<'_>, &has_in_token: &bool, ) { match qualified { diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index fd25ee05e039..ea748a8539e0 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -65,13 +65,13 @@ impl QualifierCtx { /// The state of the path we are currently completing. #[derive(Debug)] -pub(crate) struct PathCompletionCtx { +pub(crate) struct PathCompletionCtx<'db> { /// If this is a call with () already there (or {} in case of record patterns) pub(crate) has_call_parens: bool, /// If this has a macro call bang ! pub(crate) has_macro_bang: bool, /// The qualifier of the current path. - pub(crate) qualified: Qualified, + pub(crate) qualified: Qualified<'db>, /// The parent of the path we are completing. pub(crate) parent: Option, #[allow(dead_code)] @@ -79,14 +79,14 @@ pub(crate) struct PathCompletionCtx { pub(crate) path: ast::Path, /// The path of which we are completing the segment in the original file pub(crate) original_path: Option, - pub(crate) kind: PathKind, + pub(crate) kind: PathKind<'db>, /// Whether the path segment has type args or not. pub(crate) has_type_args: bool, /// Whether the qualifier comes from a use tree parent or not pub(crate) use_tree_parent: bool, } -impl PathCompletionCtx { +impl PathCompletionCtx<'_> { pub(crate) fn is_trivial_path(&self) -> bool { matches!( self, @@ -104,9 +104,9 @@ impl PathCompletionCtx { /// The kind of path we are completing right now. #[derive(Debug, PartialEq, Eq)] -pub(crate) enum PathKind { +pub(crate) enum PathKind<'db> { Expr { - expr_ctx: PathExprCtx, + expr_ctx: PathExprCtx<'db>, }, Type { location: TypeLocation, @@ -140,7 +140,7 @@ pub(crate) struct AttrCtx { } #[derive(Debug, PartialEq, Eq)] -pub(crate) struct PathExprCtx { +pub(crate) struct PathExprCtx<'db> { pub(crate) in_block_expr: bool, pub(crate) in_breakable: BreakableKind, pub(crate) after_if_expr: bool, @@ -152,7 +152,7 @@ pub(crate) struct PathExprCtx { /// The surrounding RecordExpression we are completing a functional update pub(crate) is_func_update: Option, pub(crate) self_param: Option, - pub(crate) innermost_ret_ty: Option, + pub(crate) innermost_ret_ty: Option>, pub(crate) impl_: Option, /// Whether this expression occurs in match arm guard position: before the /// fat arrow token @@ -241,7 +241,7 @@ pub(crate) enum ItemListKind { } #[derive(Debug)] -pub(crate) enum Qualified { +pub(crate) enum Qualified<'db> { No, With { path: ast::Path, @@ -260,7 +260,7 @@ pub(crate) enum Qualified { }, /// <_>:: TypeAnchor { - ty: Option, + ty: Option>, trait_: Option, }, /// Whether the path is an absolute path @@ -341,17 +341,17 @@ pub(crate) enum NameKind { /// The state of the NameRef we are completing. #[derive(Debug)] -pub(crate) struct NameRefContext { +pub(crate) struct NameRefContext<'db> { /// NameRef syntax in the original file pub(crate) nameref: Option, - pub(crate) kind: NameRefKind, + pub(crate) kind: NameRefKind<'db>, } /// The kind of the NameRef we are completing. #[derive(Debug)] -pub(crate) enum NameRefKind { - Path(PathCompletionCtx), - DotAccess(DotAccess), +pub(crate) enum NameRefKind<'db> { + Path(PathCompletionCtx<'db>), + DotAccess(DotAccess<'db>), /// Position where we are only interested in keyword completions Keyword(ast::Item), /// The record expression this nameref is a field of and whether a dot precedes the completion identifier. @@ -365,9 +365,9 @@ pub(crate) enum NameRefKind { /// The identifier we are currently completing. #[derive(Debug)] -pub(crate) enum CompletionAnalysis { +pub(crate) enum CompletionAnalysis<'db> { Name(NameContext), - NameRef(NameRefContext), + NameRef(NameRefContext<'db>), Lifetime(LifetimeContext), /// The string the cursor is currently inside String { @@ -386,9 +386,9 @@ pub(crate) enum CompletionAnalysis { /// Information about the field or method access we are completing. #[derive(Debug)] -pub(crate) struct DotAccess { +pub(crate) struct DotAccess<'db> { pub(crate) receiver: Option, - pub(crate) receiver_ty: Option, + pub(crate) receiver_ty: Option>, pub(crate) kind: DotAccessKind, pub(crate) ctx: DotAccessExprCtx, } @@ -457,7 +457,7 @@ pub(crate) struct CompletionContext<'a> { /// This is usually the parameter name of the function argument we are completing. pub(crate) expected_name: Option, /// The expected type of what we are completing. - pub(crate) expected_type: Option, + pub(crate) expected_type: Option>, pub(crate) qualifier_ctx: QualifierCtx, @@ -608,7 +608,7 @@ impl CompletionContext<'_> { pub(crate) fn iterate_path_candidates( &self, - ty: &hir::Type, + ty: &hir::Type<'_>, mut cb: impl FnMut(hir::AssocItem), ) { let mut seen = FxHashSet::default(); @@ -695,12 +695,12 @@ impl CompletionContext<'_> { } // CompletionContext construction -impl<'a> CompletionContext<'a> { +impl<'db> CompletionContext<'db> { pub(crate) fn new( - db: &'a RootDatabase, + db: &'db RootDatabase, position @ FilePosition { file_id, offset }: FilePosition, - config: &'a CompletionConfig<'a>, - ) -> Option<(CompletionContext<'a>, CompletionAnalysis)> { + config: &'db CompletionConfig<'db>, + ) -> Option<(CompletionContext<'db>, CompletionAnalysis<'db>)> { let _p = tracing::info_span!("CompletionContext::new").entered(); let sema = Semantics::new(db); diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 8f58c2181ef4..de264b776773 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -35,9 +35,9 @@ struct ExpansionResult { derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>, } -pub(super) struct AnalysisResult { - pub(super) analysis: CompletionAnalysis, - pub(super) expected: (Option, Option), +pub(super) struct AnalysisResult<'db> { + pub(super) analysis: CompletionAnalysis<'db>, + pub(super) expected: (Option>, Option), pub(super) qualifier_ctx: QualifierCtx, /// the original token of the expanded file pub(super) token: SyntaxToken, @@ -45,13 +45,13 @@ pub(super) struct AnalysisResult { pub(super) original_offset: TextSize, } -pub(super) fn expand_and_analyze( - sema: &Semantics<'_, RootDatabase>, +pub(super) fn expand_and_analyze<'db>( + sema: &Semantics<'db, RootDatabase>, original_file: SyntaxNode, speculative_file: SyntaxNode, offset: TextSize, original_token: &SyntaxToken, -) -> Option { +) -> Option> { // as we insert after the offset, right biased will *always* pick the identifier no matter // if there is an ident already typed or not let fake_ident_token = speculative_file.token_at_offset(offset).right_biased()?; @@ -434,12 +434,13 @@ fn expand( /// Fill the completion context, this is what does semantic reasoning about the surrounding context /// of the completion location. -fn analyze( - sema: &Semantics<'_, RootDatabase>, +fn analyze<'db>( + sema: &Semantics<'db, RootDatabase>, expansion_result: ExpansionResult, original_token: &SyntaxToken, self_token: &SyntaxToken, -) -> Option<(CompletionAnalysis, (Option, Option), QualifierCtx)> { +) -> Option<(CompletionAnalysis<'db>, (Option>, Option), QualifierCtx)> +{ let _p = tracing::info_span!("CompletionContext::analyze").entered(); let ExpansionResult { original_file, @@ -557,17 +558,17 @@ fn analyze( } /// Calculate the expected type and name of the cursor position. -fn expected_type_and_name( - sema: &Semantics<'_, RootDatabase>, +fn expected_type_and_name<'db>( + sema: &Semantics<'db, RootDatabase>, token: &SyntaxToken, name_like: &ast::NameLike, -) -> (Option, Option) { +) -> (Option>, Option) { let mut node = match token.parent() { Some(it) => it, None => return (None, None), }; - let strip_refs = |mut ty: Type| match name_like { + let strip_refs = |mut ty: Type<'db>| match name_like { ast::NameLike::NameRef(n) => { let p = match n.syntax().parent() { Some(it) => it, @@ -809,13 +810,13 @@ fn classify_name( Some(NameContext { name, kind }) } -fn classify_name_ref( - sema: &Semantics<'_, RootDatabase>, +fn classify_name_ref<'db>( + sema: &Semantics<'db, RootDatabase>, original_file: &SyntaxNode, name_ref: ast::NameRef, original_offset: TextSize, parent: SyntaxNode, -) -> Option<(NameRefContext, QualifierCtx)> { +) -> Option<(NameRefContext<'db>, QualifierCtx)> { let nameref = find_node_at_offset(original_file, original_offset); let make_res = |kind| (NameRefContext { nameref: nameref.clone(), kind }, Default::default()); diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs index e208b9fd41ae..6c0f6cb491ba 100644 --- a/crates/ide-completion/src/item.rs +++ b/crates/ide-completion/src/item.rs @@ -502,7 +502,7 @@ pub(crate) struct Builder { impl Builder { pub(crate) fn from_resolution( ctx: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: hir::Name, resolution: hir::ScopeDef, ) -> Self { diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index b0adbad74ed1..df8da4800a6d 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -122,10 +122,10 @@ impl<'a> RenderContext<'a> { pub(crate) fn render_field( ctx: RenderContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, receiver: Option, field: hir::Field, - ty: &hir::Type, + ty: &hir::Type<'_>, ) -> CompletionItem { let db = ctx.db(); let is_deprecated = ctx.is_deprecated(field); @@ -204,7 +204,7 @@ pub(crate) fn render_tuple_field( ctx: RenderContext<'_>, receiver: Option, field: usize, - ty: &hir::Type, + ty: &hir::Type<'_>, ) -> CompletionItem { let mut item = CompletionItem::new( SymbolKind::Field, @@ -241,7 +241,7 @@ pub(crate) fn render_type_inference( pub(crate) fn render_path_resolution( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: hir::Name, resolution: ScopeDef, ) -> Builder { @@ -259,7 +259,7 @@ pub(crate) fn render_pattern_resolution( pub(crate) fn render_resolution_with_import( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, import_edit: LocatedImport, ) -> Option { let resolution = ScopeDef::from(import_edit.original_item); @@ -282,10 +282,10 @@ pub(crate) fn render_resolution_with_import_pat( pub(crate) fn render_expr( ctx: &CompletionContext<'_>, - expr: &hir::term_search::Expr, + expr: &hir::term_search::Expr<'_>, ) -> Option { let mut i = 1; - let mut snippet_formatter = |ty: &hir::Type| { + let mut snippet_formatter = |ty: &hir::Type<'_>| { let arg_name = ty .as_adt() .map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str())) @@ -295,7 +295,7 @@ pub(crate) fn render_expr( res }; - let mut label_formatter = |ty: &hir::Type| { + let mut label_formatter = |ty: &hir::Type<'_>| { ty.as_adt() .map(|adt| stdx::to_lower_snake_case(adt.name(ctx.db).as_str())) .unwrap_or_else(|| String::from("...")) @@ -391,7 +391,7 @@ fn render_resolution_pat( fn render_resolution_path( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: hir::Name, import_to_add: Option, resolution: ScopeDef, @@ -460,7 +460,7 @@ fn render_resolution_path( } } - let mut set_item_relevance = |ty: Type| { + let mut set_item_relevance = |ty: Type<'_>| { if !ty.is_unknown() { item.detail(ty.display(db, krate).to_string()); } @@ -593,8 +593,8 @@ fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> boo // FIXME: This checks types without possible coercions which some completions might want to do fn match_types( ctx: &CompletionContext<'_>, - ty1: &hir::Type, - ty2: &hir::Type, + ty1: &hir::Type<'_>, + ty2: &hir::Type<'_>, ) -> Option { if ty1 == ty2 { Some(CompletionRelevanceTypeMatch::Exact) @@ -607,7 +607,7 @@ fn match_types( fn compute_type_match( ctx: &CompletionContext<'_>, - completion_ty: &hir::Type, + completion_ty: &hir::Type<'_>, ) -> Option { let expected_type = ctx.expected_type.as_ref()?; @@ -626,7 +626,7 @@ fn compute_exact_name_match(ctx: &CompletionContext<'_>, completion_name: &str) fn compute_ref_match( ctx: &CompletionContext<'_>, - completion_ty: &hir::Type, + completion_ty: &hir::Type<'_>, ) -> Option { let expected_type = ctx.expected_type.as_ref()?; let expected_without_ref = expected_type.remove_ref(); @@ -658,8 +658,8 @@ fn compute_ref_match( fn path_ref_match( completion: &CompletionContext<'_>, - path_ctx: &PathCompletionCtx, - ty: &hir::Type, + path_ctx: &PathCompletionCtx<'_>, + ty: &hir::Type<'_>, item: &mut Builder, ) { if let Some(original_path) = &path_ctx.original_path { diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index 2fe517fa8cd0..7669aec8f535 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -22,13 +22,13 @@ use crate::{ #[derive(Debug)] enum FuncKind<'ctx> { - Function(&'ctx PathCompletionCtx), - Method(&'ctx DotAccess, Option), + Function(&'ctx PathCompletionCtx<'ctx>), + Method(&'ctx DotAccess<'ctx>, Option), } pub(crate) fn render_fn( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: Option, func: hir::Function, ) -> Builder { @@ -38,7 +38,7 @@ pub(crate) fn render_fn( pub(crate) fn render_method( ctx: RenderContext<'_>, - dot_access: &DotAccess, + dot_access: &DotAccess<'_>, receiver: Option, local_name: Option, func: hir::Function, @@ -186,8 +186,8 @@ fn render( fn compute_return_type_match( db: &dyn HirDatabase, ctx: &RenderContext<'_>, - self_type: hir::Type, - ret_type: &hir::Type, + self_type: hir::Type<'_>, + ret_type: &hir::Type<'_>, ) -> CompletionRelevanceReturnType { if match_types(ctx.completion, &self_type, ret_type).is_some() { // fn([..]) -> Self @@ -217,8 +217,8 @@ pub(super) fn add_call_parens<'b>( name: SmolStr, escaped_name: SmolStr, self_param: Option, - params: Vec, - ret_type: &hir::Type, + params: Vec>, + ret_type: &hir::Type<'_>, ) -> &'b mut Builder { cov_mark::hit!(inserts_parens_for_function_calls); @@ -288,7 +288,7 @@ pub(super) fn add_call_parens<'b>( builder.label(SmolStr::from_iter([&name, label_suffix])).insert_snippet(cap, snippet) } -fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type) -> &'static str { +fn ref_of_param(ctx: &CompletionContext<'_>, arg: &str, ty: &hir::Type<'_>) -> &'static str { if let Some(derefed_ty) = ty.remove_ref() { for (name, local) in ctx.locals.iter().sorted_by_key(|&(k, _)| k.clone()) { if name.as_str() == arg { @@ -369,12 +369,12 @@ fn params_display(ctx: &CompletionContext<'_>, detail: &mut String, func: hir::F } } -fn params( - ctx: &CompletionContext<'_>, +fn params<'db>( + ctx: &CompletionContext<'db>, func: hir::Function, func_kind: &FuncKind<'_>, has_dot_receiver: bool, -) -> Option<(Option, Vec)> { +) -> Option<(Option, Vec>)> { ctx.config.callable.as_ref()?; // Don't add parentheses if the expected type is a function reference with the same signature. diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs index 5a9e35a7290b..6c89e49f94e8 100644 --- a/crates/ide-completion/src/render/literal.rs +++ b/crates/ide-completion/src/render/literal.rs @@ -21,7 +21,7 @@ use crate::{ pub(crate) fn render_variant_lit( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, local_name: Option, variant: hir::Variant, path: Option, @@ -35,7 +35,7 @@ pub(crate) fn render_variant_lit( pub(crate) fn render_struct_literal( ctx: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, strukt: hir::Struct, path: Option, local_name: Option, @@ -49,7 +49,7 @@ pub(crate) fn render_struct_literal( fn render( ctx @ RenderContext { completion, .. }: RenderContext<'_>, - path_ctx: &PathCompletionCtx, + path_ctx: &PathCompletionCtx<'_>, thing: Variant, name: hir::Name, path: Option, @@ -194,7 +194,7 @@ impl Variant { } } - fn ty(self, db: &dyn HirDatabase) -> hir::Type { + fn ty(self, db: &dyn HirDatabase) -> hir::Type<'_> { match self { Variant::Struct(it) => it.ty(db), Variant::EnumVariant(it) => it.parent_enum(db).ty(db), diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs index 4674dae03144..35fe407b2e68 100644 --- a/crates/ide-completion/src/render/macro_.rs +++ b/crates/ide-completion/src/render/macro_.rs @@ -12,7 +12,7 @@ use crate::{ pub(crate) fn render_macro( ctx: RenderContext<'_>, - PathCompletionCtx { kind, has_macro_bang, has_call_parens, .. }: &PathCompletionCtx, + PathCompletionCtx { kind, has_macro_bang, has_call_parens, .. }: &PathCompletionCtx<'_>, name: hir::Name, macro_: hir::Macro, diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 8332cd0bcb83..8c5590f960ca 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -46,7 +46,7 @@ pub(crate) fn render_struct_pat( pub(crate) fn render_variant_pat( ctx: RenderContext<'_>, pattern_ctx: &PatternContext, - path_ctx: Option<&PathCompletionCtx>, + path_ctx: Option<&PathCompletionCtx<'_>>, variant: hir::Variant, local_name: Option, path: Option<&hir::ModPath>, @@ -109,7 +109,7 @@ fn build_completion( lookup: SmolStr, pat: String, def: impl HasDocs + Copy, - adt_ty: hir::Type, + adt_ty: hir::Type<'_>, // Missing in context of match statement completions is_variant_missing: bool, ) -> CompletionItem { diff --git a/crates/ide-db/src/active_parameter.rs b/crates/ide-db/src/active_parameter.rs index 06ed4afdf9be..e5caf1b94b8f 100644 --- a/crates/ide-db/src/active_parameter.rs +++ b/crates/ide-db/src/active_parameter.rs @@ -12,14 +12,14 @@ use syntax::{ use crate::RootDatabase; #[derive(Debug)] -pub struct ActiveParameter { - pub ty: Type, +pub struct ActiveParameter<'db> { + pub ty: Type<'db>, pub src: Option>>, } -impl ActiveParameter { +impl<'db> ActiveParameter<'db> { /// Returns information about the call argument this token is part of. - pub fn at_token(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option { + pub fn at_token(sema: &Semantics<'db, RootDatabase>, token: SyntaxToken) -> Option { let (signature, active_parameter) = callable_for_token(sema, token)?; let idx = active_parameter?; @@ -45,10 +45,10 @@ impl ActiveParameter { } /// Returns a [`hir::Callable`] this token is a part of and its argument index of said callable. -pub fn callable_for_token( - sema: &Semantics<'_, RootDatabase>, +pub fn callable_for_token<'db>( + sema: &Semantics<'db, RootDatabase>, token: SyntaxToken, -) -> Option<(hir::Callable, Option)> { +) -> Option<(hir::Callable<'db>, Option)> { // Find the calling expression and its NameRef let parent = token.parent()?; let calling_node = parent.ancestors().filter_map(ast::CallableExpr::cast).find(|it| { @@ -59,11 +59,11 @@ pub fn callable_for_token( callable_for_node(sema, &calling_node, &token) } -pub fn callable_for_node( - sema: &Semantics<'_, RootDatabase>, +pub fn callable_for_node<'db>( + sema: &Semantics<'db, RootDatabase>, calling_node: &ast::CallableExpr, token: &SyntaxToken, -) -> Option<(hir::Callable, Option)> { +) -> Option<(hir::Callable<'db>, Option)> { let callable = match calling_node { ast::CallableExpr::Call(call) => sema.resolve_expr_as_callable(&call.expr()?), ast::CallableExpr::MethodCall(call) => sema.resolve_method_call_as_callable(call), diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 18126f616c9e..bd257ce7279e 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -372,17 +372,17 @@ fn find_std_module( // FIXME: IdentClass as a name no longer fits #[derive(Debug)] -pub enum IdentClass { - NameClass(NameClass), - NameRefClass(NameRefClass), +pub enum IdentClass<'db> { + NameClass(NameClass<'db>), + NameRefClass(NameRefClass<'db>), Operator(OperatorClass), } -impl IdentClass { +impl<'db> IdentClass<'db> { pub fn classify_node( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, node: &SyntaxNode, - ) -> Option { + ) -> Option> { match_ast! { match node { ast::Name(name) => NameClass::classify(sema, &name).map(IdentClass::NameClass), @@ -405,23 +405,23 @@ impl IdentClass { } pub fn classify_token( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, token: &SyntaxToken, - ) -> Option { + ) -> Option> { let parent = token.parent()?; Self::classify_node(sema, &parent) } pub fn classify_lifetime( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, lifetime: &ast::Lifetime, - ) -> Option { + ) -> Option> { NameRefClass::classify_lifetime(sema, lifetime) .map(IdentClass::NameRefClass) .or_else(|| NameClass::classify_lifetime(sema, lifetime).map(IdentClass::NameClass)) } - pub fn definitions(self) -> ArrayVec<(Definition, Option), 2> { + pub fn definitions(self) -> ArrayVec<(Definition, Option>), 2> { let mut res = ArrayVec::new(); match self { IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => { @@ -505,7 +505,7 @@ impl IdentClass { /// /// A model special case is `None` constant in pattern. #[derive(Debug)] -pub enum NameClass { +pub enum NameClass<'db> { Definition(Definition), /// `None` in `if let None = Some(82) {}`. /// Syntactically, it is a name, but semantically it is a reference. @@ -515,11 +515,11 @@ pub enum NameClass { PatFieldShorthand { local_def: Local, field_ref: Field, - adt_subst: GenericSubstitution, + adt_subst: GenericSubstitution<'db>, }, } -impl NameClass { +impl<'db> NameClass<'db> { /// `Definition` defined by this name. pub fn defined(self) -> Option { let res = match self { @@ -532,7 +532,10 @@ impl NameClass { Some(res) } - pub fn classify(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option { + pub fn classify( + sema: &Semantics<'db, RootDatabase>, + name: &ast::Name, + ) -> Option> { let _p = tracing::info_span!("NameClass::classify").entered(); let parent = name.syntax().parent()?; @@ -584,10 +587,10 @@ impl NameClass { Some(definition) } - fn classify_ident_pat( - sema: &Semantics<'_, RootDatabase>, + fn classify_ident_pat<'db>( + sema: &Semantics<'db, RootDatabase>, ident_pat: ast::IdentPat, - ) -> Option { + ) -> Option> { if let Some(def) = sema.resolve_bind_pat_to_const(&ident_pat) { return Some(NameClass::ConstReference(Definition::from(def))); } @@ -625,9 +628,9 @@ impl NameClass { } pub fn classify_lifetime( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, lifetime: &ast::Lifetime, - ) -> Option { + ) -> Option> { let _p = tracing::info_span!("NameClass::classify_lifetime", ?lifetime).entered(); let parent = lifetime.syntax().parent()?; @@ -710,12 +713,12 @@ impl OperatorClass { /// A model special case is field shorthand syntax, which uses a single /// reference to point to two different defs. #[derive(Debug)] -pub enum NameRefClass { - Definition(Definition, Option), +pub enum NameRefClass<'db> { + Definition(Definition, Option>), FieldShorthand { local_ref: Local, field_ref: Field, - adt_subst: GenericSubstitution, + adt_subst: GenericSubstitution<'db>, }, /// The specific situation where we have an extern crate decl without a rename /// Here we have both a declaration and a reference. @@ -728,13 +731,13 @@ pub enum NameRefClass { }, } -impl NameRefClass { +impl<'db> NameRefClass<'db> { // Note: we don't have unit-tests for this rather important function. // It is primarily exercised via goto definition tests in `ide`. pub fn classify( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, name_ref: &ast::NameRef, - ) -> Option { + ) -> Option> { let _p = tracing::info_span!("NameRefClass::classify", ?name_ref).entered(); let parent = name_ref.syntax().parent()?; @@ -845,9 +848,9 @@ impl NameRefClass { } pub fn classify_lifetime( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, lifetime: &ast::Lifetime, - ) -> Option { + ) -> Option> { let _p = tracing::info_span!("NameRefClass::classify_lifetime", ?lifetime).entered(); if lifetime.text() == "'static" { return Some(NameRefClass::Definition( diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs index ac592dfe93cf..9f35988924b9 100644 --- a/crates/ide-db/src/imports/import_assets.rs +++ b/crates/ide-db/src/imports/import_assets.rs @@ -25,26 +25,26 @@ use crate::{ /// * assists /// * etc. #[derive(Debug)] -pub enum ImportCandidate { +pub enum ImportCandidate<'db> { /// A path, qualified (`std::collections::HashMap`) or not (`HashMap`). Path(PathImportCandidate), /// A trait associated function (with no self parameter) or an associated constant. /// For 'test_mod::TestEnum::test_function', `ty` is the `test_mod::TestEnum` expression type /// and `name` is the `test_function` - TraitAssocItem(TraitImportCandidate), + TraitAssocItem(TraitImportCandidate<'db>), /// A trait method with self parameter. /// For 'test_enum.test_method()', `ty` is the `test_enum` expression type /// and `name` is the `test_method` - TraitMethod(TraitImportCandidate), + TraitMethod(TraitImportCandidate<'db>), } /// A trait import needed for a given associated item access. /// For `some::path::SomeStruct::ASSOC_`, contains the /// type of `some::path::SomeStruct` and `ASSOC_` as the item name. #[derive(Debug)] -pub struct TraitImportCandidate { +pub struct TraitImportCandidate<'db> { /// A type of the item that has the associated item accessed at. - pub receiver_ty: Type, + pub receiver_ty: Type<'db>, /// The associated item name that the trait to import should contain. pub assoc_item_name: NameToImport, } @@ -100,16 +100,16 @@ impl NameToImport { /// A struct to find imports in the project, given a certain name (or its part) and the context. #[derive(Debug)] -pub struct ImportAssets { - import_candidate: ImportCandidate, +pub struct ImportAssets<'db> { + import_candidate: ImportCandidate<'db>, candidate_node: SyntaxNode, module_with_candidate: Module, } -impl ImportAssets { +impl<'db> ImportAssets<'db> { pub fn for_method_call( method_call: &ast::MethodCallExpr, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, ) -> Option { let candidate_node = method_call.syntax().clone(); Some(Self { @@ -121,7 +121,7 @@ impl ImportAssets { pub fn for_exact_path( fully_qualified_path: &ast::Path, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, ) -> Option { let candidate_node = fully_qualified_path.syntax().clone(); if let Some(use_tree) = candidate_node.ancestors().find_map(ast::UseTree::cast) { @@ -139,7 +139,7 @@ impl ImportAssets { }) } - pub fn for_ident_pat(sema: &Semantics<'_, RootDatabase>, pat: &ast::IdentPat) -> Option { + pub fn for_ident_pat(sema: &Semantics<'db, RootDatabase>, pat: &ast::IdentPat) -> Option { if !pat.is_simple_ident() { return None; } @@ -156,7 +156,7 @@ impl ImportAssets { module_with_candidate: Module, qualifier: Option, fuzzy_name: String, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, candidate_node: SyntaxNode, ) -> Option { Some(Self { @@ -168,7 +168,7 @@ impl ImportAssets { pub fn for_fuzzy_method_call( module_with_method_call: Module, - receiver_ty: Type, + receiver_ty: Type<'db>, fuzzy_method_name: String, candidate_node: SyntaxNode, ) -> Option { @@ -229,14 +229,14 @@ impl LocatedImport { } } -impl ImportAssets { - pub fn import_candidate(&self) -> &ImportCandidate { +impl<'db> ImportAssets<'db> { + pub fn import_candidate(&self) -> &ImportCandidate<'db> { &self.import_candidate } pub fn search_for_imports( &self, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, cfg: ImportPathConfig, prefix_kind: PrefixKind, ) -> impl Iterator { @@ -247,7 +247,7 @@ impl ImportAssets { /// This may return non-absolute paths if a part of the returned path is already imported into scope. pub fn search_for_relative_paths( &self, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, cfg: ImportPathConfig, ) -> impl Iterator { let _p = tracing::info_span!("ImportAssets::search_for_relative_paths").entered(); @@ -286,7 +286,7 @@ impl ImportAssets { fn search_for( &self, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, prefixed: Option, cfg: ImportPathConfig, ) -> impl Iterator { @@ -533,11 +533,11 @@ fn item_for_path_search_assoc(db: &RootDatabase, assoc_item: AssocItem) -> Optio }) } -fn trait_applicable_items( - db: &RootDatabase, +fn trait_applicable_items<'db>( + db: &'db RootDatabase, current_crate: Crate, - scope: &SemanticsScope<'_>, - trait_candidate: &TraitImportCandidate, + scope: &SemanticsScope<'db>, + trait_candidate: &TraitImportCandidate<'db>, trait_assoc_item: bool, mod_path: impl Fn(ItemInNs) -> Option, scope_filter: impl Fn(hir::Trait) -> bool, @@ -709,9 +709,9 @@ fn get_mod_path( } } -impl ImportCandidate { +impl<'db> ImportCandidate<'db> { fn for_method_call( - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, method_call: &ast::MethodCallExpr, ) -> Option { match sema.resolve_method_call(method_call) { @@ -725,7 +725,7 @@ impl ImportCandidate { } } - fn for_regular_path(sema: &Semantics<'_, RootDatabase>, path: &ast::Path) -> Option { + fn for_regular_path(sema: &Semantics<'db, RootDatabase>, path: &ast::Path) -> Option { if sema.resolve_path(path).is_some() { return None; } @@ -736,7 +736,7 @@ impl ImportCandidate { ) } - fn for_name(sema: &Semantics<'_, RootDatabase>, name: &ast::Name) -> Option { + fn for_name(sema: &Semantics<'db, RootDatabase>, name: &ast::Name) -> Option { if sema .scope(name.syntax())? .speculative_resolve(&make::ext::ident_path(&name.text())) @@ -753,17 +753,17 @@ impl ImportCandidate { fn for_fuzzy_path( qualifier: Option, fuzzy_name: String, - sema: &Semantics<'_, RootDatabase>, + sema: &Semantics<'db, RootDatabase>, ) -> Option { path_import_candidate(sema, qualifier, NameToImport::fuzzy(fuzzy_name)) } } -fn path_import_candidate( - sema: &Semantics<'_, RootDatabase>, +fn path_import_candidate<'db>( + sema: &Semantics<'db, RootDatabase>, qualifier: Option, name: NameToImport, -) -> Option { +) -> Option> { Some(match qualifier { Some(qualifier) => match sema.resolve_path(&qualifier) { Some(PathResolution::Def(ModuleDef::BuiltinType(_))) | None => { diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs index bb4bee91bbe8..63a2ce4e429d 100644 --- a/crates/ide-db/src/search.rs +++ b/crates/ide-db/src/search.rs @@ -430,7 +430,7 @@ pub struct FindUsages<'a> { /// The container of our definition should it be an assoc item assoc_item_container: Option, /// whether to search for the `Self` type of the definition - include_self_kw_refs: Option, + include_self_kw_refs: Option>, /// whether to search for the `self` module search_self_mod: bool, } @@ -1086,12 +1086,12 @@ impl<'a> FindUsages<'a> { fn found_self_ty_name_ref( &self, - self_ty: &hir::Type, + self_ty: &hir::Type<'_>, name_ref: &ast::NameRef, sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool, ) -> bool { // See https://github.com/rust-lang/rust-analyzer/pull/15864/files/e0276dc5ddc38c65240edb408522bb869f15afb4#r1389848845 - let ty_eq = |ty: hir::Type| match (ty.as_adt(), self_ty.as_adt()) { + let ty_eq = |ty: hir::Type<'_>| match (ty.as_adt(), self_ty.as_adt()) { (Some(ty), Some(self_ty)) => ty == self_ty, (None, None) => ty == *self_ty, _ => false, @@ -1314,7 +1314,7 @@ impl<'a> FindUsages<'a> { } } -fn def_to_ty(sema: &Semantics<'_, RootDatabase>, def: &Definition) -> Option { +fn def_to_ty<'db>(sema: &Semantics<'db, RootDatabase>, def: &Definition) -> Option> { match def { Definition::Adt(adt) => Some(adt.ty(sema.db)), Definition::TypeAlias(it) => Some(it.ty(sema.db)), diff --git a/crates/ide-db/src/syntax_helpers/suggest_name.rs b/crates/ide-db/src/syntax_helpers/suggest_name.rs index 51ce9b482935..20146cb5c755 100644 --- a/crates/ide-db/src/syntax_helpers/suggest_name.rs +++ b/crates/ide-db/src/syntax_helpers/suggest_name.rs @@ -151,10 +151,10 @@ impl NameGenerator { /// - If `ty` is an `impl Trait`, it will suggest the name of the first trait. /// /// If the suggested name conflicts with reserved keywords, it will return `None`. - pub fn for_type( + pub fn for_type<'db>( &mut self, - ty: &hir::Type, - db: &RootDatabase, + ty: &hir::Type<'db>, + db: &'db RootDatabase, edition: Edition, ) -> Option { let name = name_of_type(ty, db, edition)?; @@ -373,7 +373,11 @@ fn from_type(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> Option Option { +fn name_of_type<'db>( + ty: &hir::Type<'db>, + db: &'db RootDatabase, + edition: Edition, +) -> Option { let name = if let Some(adt) = ty.as_adt() { let name = adt.name(db).display(db, edition).to_string(); @@ -407,7 +411,11 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option, db: &RootDatabase, edition: Edition) -> SmolStr { +fn sequence_name<'db>( + inner_ty: Option<&hir::Type<'db>>, + db: &'db RootDatabase, + edition: Edition, +) -> SmolStr { let items_str = SmolStr::new_static("items"); let Some(inner_ty) = inner_ty else { return items_str; diff --git a/crates/ide-db/src/ty_filter.rs b/crates/ide-db/src/ty_filter.rs index 63ce0ddbb8fc..e8f2fbc9eb94 100644 --- a/crates/ide-db/src/ty_filter.rs +++ b/crates/ide-db/src/ty_filter.rs @@ -20,7 +20,7 @@ impl TryEnum { const ALL: [TryEnum; 2] = [TryEnum::Option, TryEnum::Result]; /// Returns `Some(..)` if the provided type is an enum that implements `std::ops::Try`. - pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type) -> Option { + pub fn from_ty(sema: &Semantics<'_, RootDatabase>, ty: &hir::Type<'_>) -> Option { let enum_ = match ty.as_adt() { Some(hir::Adt::Enum(it)) => it, _ => return None, diff --git a/crates/ide-db/src/use_trivial_constructor.rs b/crates/ide-db/src/use_trivial_constructor.rs index a4a93e36f0e1..f63cd92694b3 100644 --- a/crates/ide-db/src/use_trivial_constructor.rs +++ b/crates/ide-db/src/use_trivial_constructor.rs @@ -11,7 +11,7 @@ use syntax::{ pub fn use_trivial_constructor( db: &crate::RootDatabase, path: Path, - ty: &hir::Type, + ty: &hir::Type<'_>, edition: Edition, ) -> Option { match ty.as_adt() { diff --git a/crates/ide-diagnostics/src/handlers/expected_function.rs b/crates/ide-diagnostics/src/handlers/expected_function.rs index af25c2b2e332..4811cd7019dc 100644 --- a/crates/ide-diagnostics/src/handlers/expected_function.rs +++ b/crates/ide-diagnostics/src/handlers/expected_function.rs @@ -7,7 +7,7 @@ use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; // This diagnostic is triggered if a call is made on something that is not callable. pub(crate) fn expected_function( ctx: &DiagnosticsContext<'_>, - d: &hir::ExpectedFunction, + d: &hir::ExpectedFunction<'_>, ) -> Diagnostic { Diagnostic::new_with_syntax_node_ptr( ctx, diff --git a/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/crates/ide-diagnostics/src/handlers/invalid_cast.rs index 82cd1f2fde6d..c292d9e7a9fd 100644 --- a/crates/ide-diagnostics/src/handlers/invalid_cast.rs +++ b/crates/ide-diagnostics/src/handlers/invalid_cast.rs @@ -18,7 +18,7 @@ macro_rules! format_ty { // Diagnostic: invalid-cast // // This diagnostic is triggered if the code contains an illegal cast -pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) -> Diagnostic { +pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast<'_>) -> Diagnostic { let display_range = ctx.sema.diagnostics_display_range(d.expr.map(|it| it.into())); let (code, message) = match d.error { CastError::CastToBool => ( @@ -106,7 +106,10 @@ pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) - // Diagnostic: cast-to-unsized // // This diagnostic is triggered when casting to an unsized type -pub(crate) fn cast_to_unsized(ctx: &DiagnosticsContext<'_>, d: &hir::CastToUnsized) -> Diagnostic { +pub(crate) fn cast_to_unsized( + ctx: &DiagnosticsContext<'_>, + d: &hir::CastToUnsized<'_>, +) -> Diagnostic { let display_range = ctx.sema.diagnostics_display_range(d.expr.map(|it| it.into())); Diagnostic::new( DiagnosticCode::RustcHardError("E0620"), diff --git a/crates/ide-diagnostics/src/handlers/missing_fields.rs b/crates/ide-diagnostics/src/handlers/missing_fields.rs index ac68f4186cc5..a9fd7c38620a 100644 --- a/crates/ide-diagnostics/src/handlers/missing_fields.rs +++ b/crates/ide-diagnostics/src/handlers/missing_fields.rs @@ -101,7 +101,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option| match ctx.config.expr_fill_default { crate::ExprFillDefaultMode::Todo => make::ext::expr_todo(), crate::ExprFillDefaultMode::Default => { get_default_constructor(ctx, d, ty).unwrap_or_else(make::ext::expr_todo) @@ -169,7 +169,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option, db: &dyn HirDatabase, module: hir::Module, edition: Edition, @@ -187,7 +187,7 @@ fn make_ty( fn get_default_constructor( ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields, - ty: &Type, + ty: &Type<'_>, ) -> Option { if let Some(builtin_ty) = ty.as_builtin() { if builtin_ty.is_int() || builtin_ty.is_uint() { diff --git a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs index 7d0f10983d73..dd8bd863e0d3 100644 --- a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs +++ b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs @@ -4,7 +4,10 @@ use hir::HirDisplay; // Diagnostic: moved-out-of-ref // // This diagnostic is triggered on moving non copy things out of references. -pub(crate) fn moved_out_of_ref(ctx: &DiagnosticsContext<'_>, d: &hir::MovedOutOfRef) -> Diagnostic { +pub(crate) fn moved_out_of_ref( + ctx: &DiagnosticsContext<'_>, + d: &hir::MovedOutOfRef<'_>, +) -> Diagnostic { Diagnostic::new_with_syntax_node_ptr( ctx, DiagnosticCode::RustcHardError("E0507"), diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 591213d9838c..156b6bedb4d8 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs @@ -20,7 +20,7 @@ use crate::{Assist, Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_dis // // 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 { +pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch<'_>) -> Diagnostic { let display_range = adjusted_display_range(ctx, d.expr_or_pat, &|node| { let Either::Left(expr) = node else { return None }; let salient_token_range = match expr { @@ -59,7 +59,7 @@ pub(crate) fn type_mismatch(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) diag } -fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option> { +fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch<'_>) -> Option> { let mut fixes = Vec::new(); if let Some(expr_ptr) = d.expr_or_pat.value.cast::() { @@ -76,7 +76,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypeMismatch) -> Option, - d: &hir::TypeMismatch, + d: &hir::TypeMismatch<'_>, expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { @@ -98,7 +98,7 @@ fn add_reference( fn add_missing_ok_or_some( ctx: &DiagnosticsContext<'_>, - d: &hir::TypeMismatch, + d: &hir::TypeMismatch<'_>, expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { @@ -186,7 +186,7 @@ fn add_missing_ok_or_some( fn remove_unnecessary_wrapper( ctx: &DiagnosticsContext<'_>, - d: &hir::TypeMismatch, + d: &hir::TypeMismatch<'_>, expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { @@ -269,7 +269,7 @@ fn remove_unnecessary_wrapper( fn remove_semicolon( ctx: &DiagnosticsContext<'_>, - d: &hir::TypeMismatch, + d: &hir::TypeMismatch<'_>, expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { @@ -297,7 +297,7 @@ fn remove_semicolon( fn str_ref_to_owned( ctx: &DiagnosticsContext<'_>, - d: &hir::TypeMismatch, + d: &hir::TypeMismatch<'_>, expr_ptr: &InFile>, acc: &mut Vec, ) -> Option<()> { diff --git a/crates/ide-diagnostics/src/handlers/typed_hole.rs b/crates/ide-diagnostics/src/handlers/typed_hole.rs index 0bef91f3375e..88162738154f 100644 --- a/crates/ide-diagnostics/src/handlers/typed_hole.rs +++ b/crates/ide-diagnostics/src/handlers/typed_hole.rs @@ -18,7 +18,7 @@ use syntax::AstNode; // Diagnostic: typed-hole // // This diagnostic is triggered when an underscore expression is used in an invalid position. -pub(crate) fn typed_hole(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Diagnostic { +pub(crate) fn typed_hole(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole<'_>) -> Diagnostic { let display_range = ctx.sema.diagnostics_display_range(d.expr.map(|it| it.into())); let (message, fixes) = if d.expected.is_unknown() { ("`_` expressions may only appear on the left-hand side of an assignment".to_owned(), None) @@ -38,7 +38,7 @@ pub(crate) fn typed_hole(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Di .with_fixes(fixes) } -fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option> { +fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole<'_>) -> Option> { let db = ctx.sema.db; let root = db.parse_or_expand(d.expr.file_id); let (original_range, _) = @@ -58,7 +58,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::TypedHole) -> Option }; let paths = term_search(&term_search_ctx); - let mut formatter = |_: &hir::Type| String::from("_"); + let mut formatter = |_: &hir::Type<'_>| String::from("_"); let assists: Vec = paths .into_iter() diff --git a/crates/ide-diagnostics/src/handlers/unresolved_field.rs b/crates/ide-diagnostics/src/handlers/unresolved_field.rs index 986ebb8818f4..8a3c6ab80ca2 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_field.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_field.rs @@ -25,7 +25,7 @@ use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_ran // This diagnostic is triggered if a field does not exist on a given type. pub(crate) fn unresolved_field( ctx: &DiagnosticsContext<'_>, - d: &hir::UnresolvedField, + d: &hir::UnresolvedField<'_>, ) -> Diagnostic { let method_suffix = if d.method_with_same_name_exists { ", but a method with a similar name exists" @@ -55,7 +55,7 @@ pub(crate) fn unresolved_field( .experimental() } -fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option> { +fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField<'_>) -> Option> { let mut fixes = Vec::new(); if d.method_with_same_name_exists { fixes.extend(method_fix(ctx, &d.expr)); @@ -65,7 +65,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField) -> Option, d: &hir::UnresolvedField) -> Option { +fn field_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedField<'_>) -> Option { // Get the FileRange of the invalid field access let root = ctx.sema.db.parse_or_expand(d.expr.file_id); let expr = d.expr.value.to_node(&root).left()?; diff --git a/crates/ide-diagnostics/src/handlers/unresolved_method.rs b/crates/ide-diagnostics/src/handlers/unresolved_method.rs index b5d7aa113a10..da35fbba6ca5 100644 --- a/crates/ide-diagnostics/src/handlers/unresolved_method.rs +++ b/crates/ide-diagnostics/src/handlers/unresolved_method.rs @@ -18,7 +18,7 @@ use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext, adjusted_display_ran // This diagnostic is triggered if a method does not exist on a given type. pub(crate) fn unresolved_method( ctx: &DiagnosticsContext<'_>, - d: &hir::UnresolvedMethodCall, + d: &hir::UnresolvedMethodCall<'_>, ) -> Diagnostic { let suffix = if d.field_with_same_name.is_some() { ", but a field with a similar name exists" @@ -50,7 +50,7 @@ pub(crate) fn unresolved_method( .experimental() } -fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) -> Option> { +fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall<'_>) -> Option> { let field_fix = if let Some(ty) = &d.field_with_same_name { field_fix(ctx, d, ty) } else { @@ -73,8 +73,8 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) -> Option< fn field_fix( ctx: &DiagnosticsContext<'_>, - d: &hir::UnresolvedMethodCall, - ty: &hir::Type, + d: &hir::UnresolvedMethodCall<'_>, + ty: &hir::Type<'_>, ) -> Option { if !ty.impls_fnonce(ctx.sema.db) { return None; @@ -108,7 +108,10 @@ fn field_fix( }) } -fn assoc_func_fix(ctx: &DiagnosticsContext<'_>, d: &hir::UnresolvedMethodCall) -> Option { +fn assoc_func_fix( + ctx: &DiagnosticsContext<'_>, + d: &hir::UnresolvedMethodCall<'_>, +) -> Option { if let Some(f) = d.assoc_func_with_same_name { let db = ctx.sema.db; diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs index 757c77b67371..3ff82efddeca 100644 --- a/crates/ide-ssr/src/lib.rs +++ b/crates/ide-ssr/src/lib.rs @@ -113,7 +113,7 @@ pub struct SsrMatches { pub struct MatchFinder<'db> { /// Our source of information about the user's code. sema: Semantics<'db, ide_db::RootDatabase>, - rules: Vec, + rules: Vec>, resolution_scope: resolving::ResolutionScope<'db>, restrict_ranges: Vec, } diff --git a/crates/ide-ssr/src/matching.rs b/crates/ide-ssr/src/matching.rs index 84a5943b1ce2..d59ebdda9a3b 100644 --- a/crates/ide-ssr/src/matching.rs +++ b/crates/ide-ssr/src/matching.rs @@ -84,12 +84,12 @@ pub(crate) struct MatchFailed { /// Checks if `code` matches the search pattern found in `search_scope`, returning information about /// the match, if it does. Since we only do matching in this module and searching is done by the /// parent module, we don't populate nested matches. -pub(crate) fn get_match( +pub(crate) fn get_match<'db>( debug_active: bool, - rule: &ResolvedRule, + rule: &ResolvedRule<'db>, code: &SyntaxNode, restrict_range: &Option, - sema: &Semantics<'_, ide_db::RootDatabase>, + sema: &Semantics<'db, ide_db::RootDatabase>, ) -> Result { record_match_fails_reasons_scope(debug_active, || { Matcher::try_match(rule, code, restrict_range, sema) @@ -102,7 +102,7 @@ struct Matcher<'db, 'sema> { /// If any placeholders come from anywhere outside of this range, then the match will be /// rejected. restrict_range: Option, - rule: &'sema ResolvedRule, + rule: &'sema ResolvedRule<'db>, } /// Which phase of matching we're currently performing. We do two phases because most attempted @@ -117,7 +117,7 @@ enum Phase<'a> { impl<'db, 'sema> Matcher<'db, 'sema> { fn try_match( - rule: &ResolvedRule, + rule: &ResolvedRule<'db>, code: &SyntaxNode, restrict_range: &Option, sema: &'sema Semantics<'db, ide_db::RootDatabase>, @@ -535,7 +535,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> { fn attempt_match_ufcs_to_method_call( &self, phase: &mut Phase<'_>, - pattern_ufcs: &UfcsCallInfo, + pattern_ufcs: &UfcsCallInfo<'db>, code: &ast::MethodCallExpr, ) -> Result<(), MatchFailed> { use ast::HasArgList; @@ -597,7 +597,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> { fn attempt_match_ufcs_to_ufcs( &self, phase: &mut Phase<'_>, - pattern_ufcs: &UfcsCallInfo, + pattern_ufcs: &UfcsCallInfo<'db>, code: &ast::CallExpr, ) -> Result<(), MatchFailed> { use ast::HasArgList; @@ -615,7 +615,7 @@ impl<'db, 'sema> Matcher<'db, 'sema> { /// times. Returns the number of times it needed to be dereferenced. fn check_expr_type( &self, - pattern_type: &hir::Type, + pattern_type: &hir::Type<'db>, expr: &ast::Expr, ) -> Result { use hir::HirDisplay; @@ -656,10 +656,10 @@ impl<'db, 'sema> Matcher<'db, 'sema> { } impl Match { - fn render_template_paths( + fn render_template_paths<'db>( &mut self, - template: &ResolvedPattern, - sema: &Semantics<'_, ide_db::RootDatabase>, + template: &ResolvedPattern<'db>, + sema: &Semantics<'db, ide_db::RootDatabase>, ) -> Result<(), MatchFailed> { let module = sema .scope(&self.matched_node) diff --git a/crates/ide-ssr/src/replacing.rs b/crates/ide-ssr/src/replacing.rs index 2ad562f2427a..8ab3c5136647 100644 --- a/crates/ide-ssr/src/replacing.rs +++ b/crates/ide-ssr/src/replacing.rs @@ -14,21 +14,21 @@ use crate::{Match, SsrMatches, fragments, resolving::ResolvedRule}; /// Returns a text edit that will replace each match in `matches` with its corresponding replacement /// template. Placeholders in the template will have been substituted with whatever they matched to /// in the original code. -pub(crate) fn matches_to_edit( - db: &dyn hir::db::ExpandDatabase, +pub(crate) fn matches_to_edit<'db>( + db: &'db dyn hir::db::ExpandDatabase, matches: &SsrMatches, file_src: &str, - rules: &[ResolvedRule], + rules: &[ResolvedRule<'db>], ) -> TextEdit { matches_to_edit_at_offset(db, matches, file_src, 0.into(), rules) } -fn matches_to_edit_at_offset( - db: &dyn hir::db::ExpandDatabase, +fn matches_to_edit_at_offset<'db>( + db: &'db dyn hir::db::ExpandDatabase, matches: &SsrMatches, file_src: &str, relative_start: TextSize, - rules: &[ResolvedRule], + rules: &[ResolvedRule<'db>], ) -> TextEdit { let mut edit_builder = TextEdit::builder(); for m in &matches.matches { @@ -40,12 +40,12 @@ fn matches_to_edit_at_offset( edit_builder.finish() } -struct ReplacementRenderer<'a> { - db: &'a dyn hir::db::ExpandDatabase, +struct ReplacementRenderer<'a, 'db> { + db: &'db dyn hir::db::ExpandDatabase, match_info: &'a Match, file_src: &'a str, - rules: &'a [ResolvedRule], - rule: &'a ResolvedRule, + rules: &'a [ResolvedRule<'db>], + rule: &'a ResolvedRule<'db>, out: String, // Map from a range within `out` to a token in `template` that represents a placeholder. This is // used to validate that the generated source code doesn't split any placeholder expansions (see @@ -58,11 +58,11 @@ struct ReplacementRenderer<'a> { edition: Edition, } -fn render_replace( - db: &dyn hir::db::ExpandDatabase, +fn render_replace<'db>( + db: &'db dyn hir::db::ExpandDatabase, match_info: &Match, file_src: &str, - rules: &[ResolvedRule], + rules: &[ResolvedRule<'db>], edition: Edition, ) -> String { let rule = &rules[match_info.rule_index]; @@ -89,7 +89,7 @@ fn render_replace( renderer.out } -impl ReplacementRenderer<'_> { +impl<'db> ReplacementRenderer<'_, 'db> { fn render_node_children(&mut self, node: &SyntaxNode) { for node_or_token in node.children_with_tokens() { self.render_node_or_token(&node_or_token); diff --git a/crates/ide-ssr/src/resolving.rs b/crates/ide-ssr/src/resolving.rs index ba6d981b8c15..5ed495b13cab 100644 --- a/crates/ide-ssr/src/resolving.rs +++ b/crates/ide-ssr/src/resolving.rs @@ -15,18 +15,18 @@ pub(crate) struct ResolutionScope<'db> { node: SyntaxNode, } -pub(crate) struct ResolvedRule { - pub(crate) pattern: ResolvedPattern, - pub(crate) template: Option, +pub(crate) struct ResolvedRule<'db> { + pub(crate) pattern: ResolvedPattern<'db>, + pub(crate) template: Option>, pub(crate) index: usize, } -pub(crate) struct ResolvedPattern { +pub(crate) struct ResolvedPattern<'db> { pub(crate) placeholders_by_stand_in: FxHashMap, pub(crate) node: SyntaxNode, // Paths in `node` that we've resolved. pub(crate) resolved_paths: FxHashMap, - pub(crate) ufcs_function_calls: FxHashMap, + pub(crate) ufcs_function_calls: FxHashMap>, pub(crate) contains_self: bool, } @@ -36,18 +36,18 @@ pub(crate) struct ResolvedPath { pub(crate) depth: u32, } -pub(crate) struct UfcsCallInfo { +pub(crate) struct UfcsCallInfo<'db> { pub(crate) call_expr: ast::CallExpr, pub(crate) function: hir::Function, - pub(crate) qualifier_type: Option, + pub(crate) qualifier_type: Option>, } -impl ResolvedRule { +impl<'db> ResolvedRule<'db> { pub(crate) fn new( rule: parsing::ParsedRule, - resolution_scope: &ResolutionScope<'_>, + resolution_scope: &ResolutionScope<'db>, index: usize, - ) -> Result { + ) -> Result, SsrError> { let resolver = Resolver { resolution_scope, placeholders_by_stand_in: rule.placeholders_by_stand_in }; let resolved_template = match rule.template { @@ -74,8 +74,8 @@ struct Resolver<'a, 'db> { placeholders_by_stand_in: FxHashMap, } -impl Resolver<'_, '_> { - fn resolve_pattern_tree(&self, pattern: SyntaxNode) -> Result { +impl<'db> Resolver<'_, 'db> { + fn resolve_pattern_tree(&self, pattern: SyntaxNode) -> Result, SsrError> { use syntax::ast::AstNode; use syntax::{SyntaxElement, T}; let mut resolved_paths = FxHashMap::default(); @@ -255,7 +255,7 @@ impl<'db> ResolutionScope<'db> { } } - fn qualifier_type(&self, path: &SyntaxNode) -> Option { + fn qualifier_type(&self, path: &SyntaxNode) -> Option> { use syntax::ast::AstNode; if let Some(path) = ast::Path::cast(path.clone()) { if let Some(qualifier) = path.qualifier() { diff --git a/crates/ide-ssr/src/search.rs b/crates/ide-ssr/src/search.rs index 73dbefb51b22..18332842ae38 100644 --- a/crates/ide-ssr/src/search.rs +++ b/crates/ide-ssr/src/search.rs @@ -22,13 +22,13 @@ pub(crate) struct UsageCache { usages: Vec<(Definition, UsageSearchResult)>, } -impl MatchFinder<'_> { +impl<'db> MatchFinder<'db> { /// Adds all matches for `rule` to `matches_out`. Matches may overlap in ways that make /// replacement impossible, so further processing is required in order to properly nest matches /// and remove overlapping matches. This is done in the `nesting` module. pub(crate) fn find_matches_for_rule( &self, - rule: &ResolvedRule, + rule: &ResolvedRule<'db>, usage_cache: &mut UsageCache, matches_out: &mut Vec, ) { @@ -50,8 +50,8 @@ impl MatchFinder<'_> { fn find_matches_for_pattern_tree( &self, - rule: &ResolvedRule, - pattern: &ResolvedPattern, + rule: &ResolvedRule<'db>, + pattern: &ResolvedPattern<'db>, usage_cache: &mut UsageCache, matches_out: &mut Vec, ) { @@ -150,7 +150,7 @@ impl MatchFinder<'_> { SearchScope::files(&files) } - fn slow_scan(&self, rule: &ResolvedRule, matches_out: &mut Vec) { + fn slow_scan(&self, rule: &ResolvedRule<'db>, matches_out: &mut Vec) { self.search_files_do(|file_id| { let file = self.sema.parse_guess_edition(file_id); let code = file.syntax(); @@ -183,7 +183,7 @@ impl MatchFinder<'_> { fn slow_scan_node( &self, code: &SyntaxNode, - rule: &ResolvedRule, + rule: &ResolvedRule<'db>, restrict_range: &Option, matches_out: &mut Vec, ) { @@ -212,7 +212,7 @@ impl MatchFinder<'_> { fn try_add_match( &self, - rule: &ResolvedRule, + rule: &ResolvedRule<'db>, code: &SyntaxNode, restrict_range: &Option, matches_out: &mut Vec, @@ -278,7 +278,7 @@ impl UsageCache { /// Returns a path that's suitable for path resolution. We exclude builtin types, since they aren't /// something that we can find references to. We then somewhat arbitrarily pick the path that is the /// longest as this is hopefully more likely to be less common, making it faster to find. -fn pick_path_for_usages(pattern: &ResolvedPattern) -> Option<&ResolvedPath> { +fn pick_path_for_usages<'a>(pattern: &'a ResolvedPattern<'_>) -> Option<&'a ResolvedPath> { // FIXME: Take the scope of the resolved path into account. e.g. if there are any paths that are // private to the current module, then we definitely would want to pick them over say a path // from std. Possibly we should go further than this and intersect the search scopes for all diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index 1bc28f28b6f5..02d96a647328 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs @@ -83,7 +83,7 @@ pub(crate) fn goto_implementation( Some(RangeInfo { range, info: navs }) } -fn impls_for_ty(sema: &Semantics<'_, RootDatabase>, ty: hir::Type) -> Vec { +fn impls_for_ty(sema: &Semantics<'_, RootDatabase>, ty: hir::Type<'_>) -> Vec { Impl::all_for_type(sema.db, ty) .into_iter() .filter_map(|imp| imp.try_to_nav(sema.db)) diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index a3d1679cd374..070eb924233f 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs @@ -38,7 +38,7 @@ pub(crate) fn goto_type_definition( } } }; - let mut process_ty = |ty: hir::Type| { + let mut process_ty = |ty: hir::Type<'_>| { // collect from each `ty` into the `res` result vec let ty = ty.strip_references(); ty.walk(db, |t| { diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 5cab8efa798d..f379cce56b9f 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -425,7 +425,7 @@ pub(crate) fn hover_for_definition( sema: &Semantics<'_, RootDatabase>, file_id: FileId, def: Definition, - subst: Option, + subst: Option>, scope_node: &SyntaxNode, macro_arm: Option, render_extras: bool, @@ -482,10 +482,10 @@ pub(crate) fn hover_for_definition( } } -fn notable_traits( - db: &RootDatabase, - ty: &hir::Type, -) -> Vec<(hir::Trait, Vec<(Option, hir::Name)>)> { +fn notable_traits<'db>( + db: &'db RootDatabase, + ty: &hir::Type<'db>, +) -> Vec<(hir::Trait, Vec<(Option>, hir::Name)>)> { db.notable_traits_in_deps(ty.krate(db).into()) .iter() .flat_map(|it| &**it) @@ -565,8 +565,8 @@ fn runnable_action( fn goto_type_action_for_def( db: &RootDatabase, def: Definition, - notable_traits: &[(hir::Trait, Vec<(Option, hir::Name)>)], - subst_types: Option>, + notable_traits: &[(hir::Trait, Vec<(Option>, hir::Name)>)], + subst_types: Option)>>, edition: Edition, ) -> Option { let mut targets: Vec = Vec::new(); @@ -620,7 +620,7 @@ fn goto_type_action_for_def( fn walk_and_push_ty( db: &RootDatabase, - ty: &hir::Type, + ty: &hir::Type<'_>, push_new_def: &mut dyn FnMut(hir::ModuleDef), ) { ty.walk(db, |t| { diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index a4cb869ac1f6..0895d5575674 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -475,10 +475,10 @@ pub(super) fn definition( db: &RootDatabase, def: Definition, famous_defs: Option<&FamousDefs<'_, '_>>, - notable_traits: &[(Trait, Vec<(Option, Name)>)], + notable_traits: &[(Trait, Vec<(Option>, Name)>)], macro_arm: Option, render_extras: bool, - subst_types: Option<&Vec<(Symbol, Type)>>, + subst_types: Option<&Vec<(Symbol, Type<'_>)>>, config: &HoverConfig, edition: Edition, display_target: DisplayTarget, @@ -899,7 +899,7 @@ pub(super) fn literal( fn render_notable_trait( db: &RootDatabase, - notable_traits: &[(Trait, Vec<(Option, Name)>)], + notable_traits: &[(Trait, Vec<(Option>, Name)>)], edition: Edition, display_target: DisplayTarget, ) -> Option { @@ -935,7 +935,7 @@ fn render_notable_trait( fn type_info( sema: &Semantics<'_, RootDatabase>, config: &HoverConfig, - ty: TypeInfo, + ty: TypeInfo<'_>, edition: Edition, display_target: DisplayTarget, ) -> Option { @@ -1019,7 +1019,7 @@ fn type_info( fn closure_ty( sema: &Semantics<'_, RootDatabase>, config: &HoverConfig, - TypeInfo { original, adjusted }: &TypeInfo, + TypeInfo { original, adjusted }: &TypeInfo<'_>, edition: Edition, display_target: DisplayTarget, ) -> Option { diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index a260944d0553..2499999d49f8 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -712,14 +712,14 @@ impl InlayHintLabelBuilder<'_> { fn label_of_ty( famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>, config: &InlayHintsConfig, - ty: &hir::Type, + ty: &hir::Type<'_>, display_target: DisplayTarget, ) -> Option { fn rec( sema: &Semantics<'_, RootDatabase>, famous_defs: &FamousDefs<'_, '_>, mut max_length: Option, - ty: &hir::Type, + ty: &hir::Type<'_>, label_builder: &mut InlayHintLabelBuilder<'_>, config: &InlayHintsConfig, display_target: DisplayTarget, @@ -778,11 +778,11 @@ fn label_of_ty( } /// Checks if the type is an Iterator from std::iter and returns the iterator trait and the item type of the concrete iterator. -fn hint_iterator( - sema: &Semantics<'_, RootDatabase>, - famous_defs: &FamousDefs<'_, '_>, - ty: &hir::Type, -) -> Option<(hir::Trait, hir::TypeAlias, hir::Type)> { +fn hint_iterator<'db>( + sema: &Semantics<'db, RootDatabase>, + famous_defs: &FamousDefs<'_, 'db>, + ty: &hir::Type<'db>, +) -> Option<(hir::Trait, hir::TypeAlias, hir::Type<'db>)> { let db = sema.db; let strukt = ty.strip_references().as_adt()?; let krate = strukt.module(db).krate(); @@ -816,7 +816,7 @@ fn ty_to_text_edit( sema: &Semantics<'_, RootDatabase>, config: &InlayHintsConfig, node_for_hint: &SyntaxNode, - ty: &hir::Type, + ty: &hir::Type<'_>, offset_to_insert: TextSize, prefix: impl Into, ) -> Option> { diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs index 99c698ce0295..1e806601d3eb 100644 --- a/crates/ide/src/inlay_hints/param_name.rs +++ b/crates/ide/src/inlay_hints/param_name.rs @@ -86,10 +86,10 @@ pub(super) fn hints( Some(()) } -fn get_callable( - sema: &Semantics<'_, RootDatabase>, +fn get_callable<'db>( + sema: &Semantics<'db, RootDatabase>, expr: &ast::Expr, -) -> Option<(hir::Callable, ast::ArgList)> { +) -> Option<(hir::Callable<'db>, ast::ArgList)> { match expr { ast::Expr::CallExpr(expr) => { let descended = sema.descend_node_into_attributes(expr.clone()).pop(); diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index bd14f830dd4d..8c3e3b603bd0 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -255,7 +255,7 @@ fn signature_help_for_call( } res.signature.push(')'); - let mut render = |ret_type: hir::Type| { + let mut render = |ret_type: hir::Type<'_>| { if !ret_type.is_unit() { format_to!(res.signature, " -> {}", ret_type.display(db, display_target)); } @@ -560,11 +560,11 @@ fn signature_help_for_tuple_expr( Some(res) } -fn signature_help_for_record_( - sema: &Semantics<'_, RootDatabase>, +fn signature_help_for_record_<'db>( + sema: &Semantics<'db, RootDatabase>, field_list_children: SyntaxElementChildren, path: &ast::Path, - fields2: impl Iterator, + fields2: impl Iterator)>, token: SyntaxToken, edition: Edition, display_target: DisplayTarget, @@ -652,13 +652,13 @@ fn signature_help_for_record_( Some(res) } -fn signature_help_for_tuple_pat_ish( - db: &RootDatabase, +fn signature_help_for_tuple_pat_ish<'db>( + db: &'db RootDatabase, mut res: SignatureHelp, pat: &SyntaxNode, token: SyntaxToken, mut field_pats: AstChildren, - fields: impl ExactSizeIterator, + fields: impl ExactSizeIterator>, display_target: DisplayTarget, ) -> SignatureHelp { let rest_pat = field_pats.find(|it| matches!(it, ast::Pat::RestPat(_))); diff --git a/crates/ide/src/view_memory_layout.rs b/crates/ide/src/view_memory_layout.rs index 140ae4265be7..63701a4d15e9 100644 --- a/crates/ide/src/view_memory_layout.rs +++ b/crates/ide/src/view_memory_layout.rs @@ -107,7 +107,7 @@ pub(crate) fn view_memory_layout( fn read_layout( nodes: &mut Vec, db: &RootDatabase, - ty: &Type, + ty: &Type<'_>, layout: &Layout, parent_idx: usize, display_target: DisplayTarget, diff --git a/crates/query-group-macro/src/queries.rs b/crates/query-group-macro/src/queries.rs index 06a16cc743ae..193a15b24a96 100644 --- a/crates/query-group-macro/src/queries.rs +++ b/crates/query-group-macro/src/queries.rs @@ -55,8 +55,8 @@ impl ToTokens for TrackedQuery { quote! { #sig { #annotation - fn #shim( - db: &dyn #trait_name, + fn #shim<'db>( + db: &'db dyn #trait_name, _input: #input_struct_name, #(#pat_and_tys),* ) #ret { @@ -70,8 +70,8 @@ impl ToTokens for TrackedQuery { quote! { #sig { #annotation - fn #shim( - db: &dyn #trait_name, + fn #shim<'db>( + db: &'db dyn #trait_name, #(#pat_and_tys),* ) #ret { #invoke(db, #(#params),*) diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 66334e773814..f83f44b86cc9 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs @@ -527,7 +527,7 @@ impl flags::AnalysisStats { } let todo = syntax::ast::make::ext::expr_todo().to_string(); - let mut formatter = |_: &hir::Type| todo.clone(); + let mut formatter = |_: &hir::Type<'_>| todo.clone(); let mut syntax_hit_found = false; for term in found_terms { let generated = term diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 982be40dd425..e2a4efd16df7 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -13,6 +13,7 @@ pub mod panic_context; pub mod process; pub mod rand; pub mod thread; +pub mod variance; pub use itertools; diff --git a/crates/stdx/src/variance.rs b/crates/stdx/src/variance.rs new file mode 100644 index 000000000000..8465d72bf371 --- /dev/null +++ b/crates/stdx/src/variance.rs @@ -0,0 +1,270 @@ +//! This is a copy of [`std::marker::variance`]. + +use std::any::type_name; +use std::cmp::Ordering; +use std::fmt; +use std::hash::{Hash, Hasher}; +use std::marker::PhantomData; + +macro_rules! first_token { + ($first:tt $($rest:tt)*) => { + $first + }; +} +macro_rules! phantom_type { + ($( + $(#[$attr:meta])* + pub struct $name:ident <$t:ident> ($($inner:tt)*); + )*) => {$( + $(#[$attr])* + pub struct $name<$t>($($inner)*) where T: ?Sized; + + impl $name + where T: ?Sized + { + /// Constructs a new instance of the variance marker. + pub const fn new() -> Self { + Self(PhantomData) + } + } + + impl self::sealed::Sealed for $name where T: ?Sized { + const VALUE: Self = Self::new(); + } + + impl Variance for $name where T: ?Sized {} + + impl Default for $name + where T: ?Sized + { + fn default() -> Self { + Self(PhantomData) + } + } + + impl fmt::Debug for $name + where T: ?Sized + { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}<{}>", stringify!($name), type_name::()) + } + } + + impl Clone for $name + where T: ?Sized + { + fn clone(&self) -> Self { + *self + } + } + + impl Copy for $name where T: ?Sized {} + + impl PartialEq for $name + where T: ?Sized + { + fn eq(&self, _: &Self) -> bool { + true + } + } + + impl Eq for $name where T: ?Sized {} + + #[allow(clippy::non_canonical_partial_ord_impl)] + impl PartialOrd for $name + where T: ?Sized + { + fn partial_cmp(&self, _: &Self) -> Option { + Some(Ordering::Equal) + } + } + + impl Ord for $name + where T: ?Sized + { + fn cmp(&self, _: &Self) -> Ordering { + Ordering::Equal + } + } + + impl Hash for $name + where T: ?Sized + { + fn hash(&self, _: &mut H) {} + } + )*}; +} + +macro_rules! phantom_lifetime { + ($( + $(#[$attr:meta])* + pub struct $name:ident <$lt:lifetime> ($($inner:tt)*); + )*) => {$( + $(#[$attr])* + + #[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct $name<$lt>($($inner)*); + + impl $name<'_> { + /// Constructs a new instance of the variance marker. + pub const fn new() -> Self { + Self(first_token!($($inner)*)(PhantomData)) + } + } + + impl self::sealed::Sealed for $name<'_> { + const VALUE: Self = Self::new(); + } + + impl Variance for $name<'_> {} + + impl fmt::Debug for $name<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", stringify!($name)) + } + } + )*}; +} + +phantom_lifetime! { + /// Zero-sized type used to mark a lifetime as covariant. + /// + /// Covariant lifetimes must live at least as long as declared. See [the reference][1] for more + /// information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>); + /// Zero-sized type used to mark a lifetime as contravariant. + /// + /// Contravariant lifetimes must live at most as long as declared. See [the reference][1] for + /// more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>); + /// Zero-sized type used to mark a lifetime as invariant. + /// + /// Invariant lifetimes must be live for the exact length declared, neither shorter nor longer. + /// See [the reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `'a`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>); + +} + +phantom_type! { + /// Zero-sized type used to mark a type parameter as covariant. + /// + /// Types used as part of the return value from a function are covariant. If the type is _also_ + /// passed as a parameter then it is [invariant][PhantomInvariant]. See [the reference][1] for + /// more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomCovariant(PhantomData T>); + /// Zero-sized type used to mark a type parameter as contravariant. + /// + /// Types passed as arguments to a function are contravariant. If the type is _also_ part of the + /// return value from a function then it is [invariant][PhantomInvariant]. See [the + /// reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomContravariant(PhantomData); + /// Zero-sized type used to mark a type parameter as invariant. + /// + /// Types that are both passed as an argument _and_ used as part of the return value from a + /// function are invariant. See [the reference][1] for more information. + /// + /// [1]: https://doc.rust-lang.org/stable/reference/subtyping.html#variance + /// + /// ## Layout + /// + /// For all `T`, the following are guaranteed: + /// * `size_of::>() == 0` + /// * `align_of::>() == 1` + + pub struct PhantomInvariant(PhantomData T>); + +} + +mod sealed { + + pub trait Sealed { + const VALUE: Self; + } +} +/// A marker trait for phantom variance types. +pub trait Variance: sealed::Sealed + Default {} +/// Construct a variance marker; equivalent to [`Default::default`]. +/// +/// This type can be any of the following. You generally should not need to explicitly name the +/// type, however. +/// +/// - [`PhantomCovariant`] +/// - [`PhantomContravariant`] +/// - [`PhantomInvariant`] +/// - [`PhantomCovariantLifetime`] +/// - [`PhantomContravariantLifetime`] +/// - [`PhantomInvariantLifetime`] +/// +/// # Example +/// +/// ```rust +/// #![feature(phantom_variance_markers)] +/// +/// use core::marker::{PhantomCovariant, variance}; +/// +/// struct BoundFn +/// where +/// F: Fn(P) -> R, +/// { +/// function: F, +/// parameter: P, +/// return_value: PhantomCovariant, +/// } +/// +/// let bound_fn = BoundFn { +/// function: core::convert::identity, +/// parameter: 5u8, +/// return_value: variance(), +/// }; +/// ``` +pub const fn variance() -> T +where + T: Variance, +{ + T::VALUE +}