diff --git a/crates/hir-def/src/expr_store/lower.rs b/crates/hir-def/src/expr_store/lower.rs index 1e5d9c2a626e..10bbfbbe988b 100644 --- a/crates/hir-def/src/expr_store/lower.rs +++ b/crates/hir-def/src/expr_store/lower.rs @@ -19,6 +19,7 @@ use hir_expand::{ }; use intern::{Symbol, sym}; use itertools::Itertools; +use la_arena::Arena; use rustc_abi::ExternAbi; use rustc_hash::FxHashMap; use smallvec::SmallVec; @@ -35,9 +36,9 @@ use thin_vec::ThinVec; use tt::TextRange; use crate::{ - AdtId, BlockId, BlockIdLt, ConstId, DefWithBodyId, FunctionId, GenericDefId, ImplId, - ItemContainerId, LoweringMode, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, - UnresolvedMacro, + AdtId, BlockId, BlockIdLt, ConstId, DefWithBodyId, FunctionId, GenericDefId, + HrtbLifetimeParamId, ImplId, ItemContainerId, LifetimeParamId, LoweringMode, MacroId, + ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, attrs::AttrFlags, expr_store::{ Body, BodySourceMap, ExprPtr, ExprRoot, ExpressionStore, ExpressionStoreBuilder, @@ -52,7 +53,8 @@ use crate::{ Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind, CoroutineKind, CoroutineSource, Expr, ExprId, Item, Label, LabelId, Literal, LoopSource, MatchArm, Movability, OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, - Statement, generics::GenericParams, + Statement, + generics::{GenericParams, LifetimeBoundType, LifetimeParamData}, }, item_scope::BuiltinShadowMode, item_tree::FieldsShape, @@ -205,7 +207,8 @@ pub(crate) fn lower_type_ref( type_ref: InFile>, ) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId) { let mut expr_collector = - ExprCollector::new(db, module, type_ref.file_id, LoweringMode::Analysis); + ExprCollector::new(db, module, type_ref.file_id, LoweringMode::Analysis) + .elide_static_lifetime(); let type_ref = expr_collector.lower_type_ref_opt(type_ref.value, &mut ExprCollector::impl_trait_allocator); let (store, source_map) = expr_collector.store.finish(); @@ -237,6 +240,18 @@ pub(crate) fn lower_impl( ) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId, Option, GenericParams) { let mut expr_collector = ExprCollector::new(db, module, impl_syntax.file_id, LoweringMode::Analysis); + let mut collector = generics::GenericParamsCollector::new(impl_id.into()); + collector.lower( + &mut expr_collector, + impl_syntax.value.generic_param_list(), + impl_syntax.value.where_clause(), + ); + + expr_collector.elide_create_lifetime( + collector.lifetimes_mut(), + impl_id.into(), + LifetimeBoundType::EarlyBound, + ); let self_ty = expr_collector.lower_type_ref_opt_disallow_impl_trait(impl_syntax.value.self_ty()); let trait_ = impl_syntax.value.trait_().and_then(|it| match &it { @@ -247,14 +262,8 @@ pub(crate) fn lower_impl( } _ => None, }); - let mut collector = generics::GenericParamsCollector::new(impl_id.into()); - collector.lower( - &mut expr_collector, - impl_syntax.value.generic_param_list(), - impl_syntax.value.where_clause(), - ); - let params = collector.finish(); let (store, source_map) = expr_collector.store.finish(); + let params = collector.finish(); (store, source_map, self_ty, trait_, params) } @@ -344,14 +353,25 @@ pub(crate) fn lower_function( if enabled { has_self_param = true; params.push(match param.ty() { - Some(ty) => collector.lower_type_ref(ty, &mut impl_trait_lower_fn), + Some(ty) => collector.with_self_param(|this| { + this.lower_type_ref(ty, &mut impl_trait_lower_fn) + }), None => { let self_type = collector.alloc_type_ref_desugared(TypeRef::Path( Name::new_symbol_root(sym::Self_).into(), )); - let lifetime = param - .lifetime() - .map(|lifetime| collector.lower_lifetime_ref(lifetime)); + let lifetime = collector.with_self_param(|this| { + param + .lifetime() + .map(|lifetime| this.lower_lifetime_ref(lifetime)) + .or_else(|| match param.kind() { + ast::SelfParamKind::Ref + | ast::SelfParamKind::MutRef => { + Some(this.lower_elided_lifetime()) + } + ast::SelfParamKind::Owned => None, + }) + }); match param.kind() { ast::SelfParamKind::Owned => self_type, ast::SelfParamKind::Ref => collector.alloc_type_ref_desugared( @@ -386,18 +406,20 @@ pub(crate) fn lower_function( // FIXME .collect::>(); for p in p { - params.push(collector.lower_type_ref_opt(p, &mut impl_trait_lower_fn)); + collector.with_param(|this| { + params.push(this.lower_type_ref_opt(p, &mut impl_trait_lower_fn)); + }) } } }) }); + expr_collector.elide_return_lifetime(); let return_type = fn_.value.ret_type().map(|ret_type| { expr_collector.with_lifetime_bound_scope(LifetimeBoundScope::Return, |this| { this.lower_type_ref_opt(ret_type.ty(), &mut ExprCollector::impl_trait_allocator) }) }); - collector.update_to_late_bound_lifetimes(&expr_collector.named_lifetime_store); - let generics = collector.finish(); + expr_collector.update_to_late_bound_lifetimes(); let return_type = if fn_.value.async_token().is_some() || fn_.value.gen_token().is_some() { let (path, assoc_name) = @@ -436,6 +458,7 @@ pub(crate) fn lower_function( return_type }; let (store, source_map) = expr_collector.store.finish(); + let generics = collector.finish(); ( store, source_map, @@ -447,7 +470,7 @@ pub(crate) fn lower_function( ) } -pub struct ExprCollector<'db> { +pub struct ExprCollector<'db, 'a> { db: &'db dyn SourceDatabase, cfg_options: &'db CfgOptions, expander: Expander<'db>, @@ -465,6 +488,10 @@ pub struct ExprCollector<'db> { is_lowering_coroutine: bool, + lifetime_arena: Option<&'a mut Arena>, + lifetime_elision_kind: LifetimeElisionKind, + elision_candidates: Option>, + for_type_binder: Option>, /// Legacy (`macro_rules!`) macros can have multiple definitions and shadow each other, @@ -534,7 +561,7 @@ struct BindingList { impl BindingList { fn find( &mut self, - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, name: Name, hygiene: HygieneId, mode: BindingAnnotation, @@ -550,7 +577,7 @@ impl BindingList { id } - fn check_is_used(&mut self, ec: &mut ExprCollector<'_>, id: BindingId) { + fn check_is_used(&mut self, ec: &mut ExprCollector<'_, '_>, id: BindingId) { match self.is_used.get(&id) { None => { if self.reject_new { @@ -608,13 +635,68 @@ impl NamedLifetimeStore { } } -impl<'db> ExprCollector<'db> { +#[derive(Clone, PartialEq, Eq, Debug, Hash)] +pub enum ReturnLifetimeElision { + Self_(LifetimeRef), + Param(LifetimeRef), + Error, + None, +} + +#[derive(Debug)] +pub enum LifetimeElisionKind { + NewGenericLifetime { + bound_type: LifetimeBoundType, + parent: Option, + return_lt: ReturnLifetimeElision, + }, + NewHrtbLifetime { + binder: ThinVec, + return_lt: ReturnLifetimeElision, + }, + Lifetime(LifetimeRef), + Static, + Error, +} + +impl LifetimeElisionKind { + fn can_elide(&self) -> bool { + matches!( + self, + LifetimeElisionKind::NewGenericLifetime { .. } + | LifetimeElisionKind::NewHrtbLifetime { .. } + | LifetimeElisionKind::Lifetime(_) + ) + } + + fn get_return_lt_mut(&mut self) -> Option<&mut ReturnLifetimeElision> { + match self { + LifetimeElisionKind::NewGenericLifetime { return_lt, .. } + | LifetimeElisionKind::NewHrtbLifetime { return_lt, .. } => Some(return_lt), + LifetimeElisionKind::Lifetime(_) + | LifetimeElisionKind::Static + | LifetimeElisionKind::Error => None, + } + } +} + +impl ReturnLifetimeElision { + fn get_lifetime_ref(self) -> LifetimeRef { + match self { + ReturnLifetimeElision::Self_(lifetime_ref) + | ReturnLifetimeElision::Param(lifetime_ref) => lifetime_ref, + ReturnLifetimeElision::Error | ReturnLifetimeElision::None => LifetimeRef::Error, + } + } +} + +impl<'db, 'a> ExprCollector<'db, 'a> { pub fn new( - db: &dyn SourceDatabase, + db: &'db dyn SourceDatabase, module: ModuleId, current_file_id: HirFileId, lowering_mode: LoweringMode, - ) -> ExprCollector<'_> { + ) -> ExprCollector<'db, 'a> { let (def_map, local_def_map) = module.local_def_map(db); let expander = Expander::new(db, current_file_id, def_map); let krate = module.krate(db); @@ -639,6 +721,9 @@ impl<'db> ExprCollector<'db> { name_generator_index: 0, named_lifetime_store: NamedLifetimeStore::default(), for_type_binder: None, + lifetime_arena: None, + lifetime_elision_kind: LifetimeElisionKind::Error, + elision_candidates: None, }; result.store.inference_roots = Some(SmallVec::new()); result @@ -650,6 +735,78 @@ impl<'db> ExprCollector<'db> { Name::generate_new_name(index) } + fn elide_static_lifetime(mut self) -> Self { + self.lifetime_elision_kind = LifetimeElisionKind::Static; + self + } + + fn elide_lifetime_for_binder(&mut self) -> LifetimeElisionKind { + let binder = self.for_type_binder.take().unwrap_or_default(); + mem::replace( + &mut self.lifetime_elision_kind, + LifetimeElisionKind::NewHrtbLifetime { binder, return_lt: ReturnLifetimeElision::None }, + ) + } + + fn elide_create_lifetime( + &mut self, + lifetimes: &'a mut Arena, + parent: GenericDefId, + bound_type: LifetimeBoundType, + ) { + self.lifetime_arena = Some(lifetimes); + self.lifetime_elision_kind = LifetimeElisionKind::NewGenericLifetime { + bound_type, + parent: Some(parent), + return_lt: ReturnLifetimeElision::None, + }; + } + + fn elide_return_lifetime(&mut self) { + let old_elision_kind = + mem::replace(&mut self.lifetime_elision_kind, LifetimeElisionKind::Error); + + let new_elision_kind = + if let LifetimeElisionKind::NewGenericLifetime { return_lt, .. } = old_elision_kind { + LifetimeElisionKind::Lifetime(return_lt.get_lifetime_ref()) + } else { + unreachable!("Method called with non LifetimeElisionKind::NewGenericLifetime"); + }; + self.lifetime_elision_kind = new_elision_kind; + } + + fn elide_return_lifetime_for_binder(&mut self) -> ThinVec { + let old_elision_kind = + mem::replace(&mut self.lifetime_elision_kind, LifetimeElisionKind::Error); + + let (binder, new_elision_kind) = + if let LifetimeElisionKind::NewHrtbLifetime { binder, return_lt } = old_elision_kind { + (binder, LifetimeElisionKind::Lifetime(return_lt.get_lifetime_ref())) + } else { + unreachable!("Method called with non LifetimeElisionKind::NewHrtbLifetime"); + }; + self.lifetime_elision_kind = new_elision_kind; + binder + } + + pub(crate) fn update_to_late_bound_lifetimes(&mut self) { + let lifetimes = self.lifetime_arena.as_mut().unwrap(); // Should never call with None + for (_param_id, lifetime) in lifetimes.iter_mut() { + let lifetime_name = &lifetime.name; + if self.named_lifetime_store.lifetimes_in_where_clause.contains(lifetime_name) { + continue; + } + + if !self.named_lifetime_store.lifetimes_constrained_by_input.contains(lifetime_name) + && self.named_lifetime_store.lifetimes_in_output.contains(lifetime_name) + { + continue; + } + + lifetime.bound_type = LifetimeBoundType::LateBound + } + } + #[inline] pub(crate) fn lang_items(&self) -> &'db LangItems { self.lang_items.get_or_init(|| crate::lang_item::lang_items(self.db, self.def_map.krate())) @@ -668,7 +825,7 @@ impl<'db> ExprCollector<'db> { let lifetime_ref = match lifetime.text() { "" | "'" => LifetimeRef::Error, "'static" => LifetimeRef::Static, - "'_" => LifetimeRef::Placeholder, + "'_" => return self.lower_elided_lifetime_opt(Some(lifetime)), text => LifetimeRef::Named(Name::new_lifetime(text)), }; self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime)) @@ -720,17 +877,19 @@ impl<'db> ExprCollector<'db> { } ast::Type::RefType(inner) => { let inner_ty = self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn); - let lifetime = inner.lifetime().map(|lt| self.lower_lifetime_ref(lt)); + let lifetime = if let Some(lt) = inner.lifetime() { + Some(self.lower_lifetime_ref(lt)) + } else { + Some(self.lower_elided_lifetime()) + }; let mutability = Mutability::from_mutable(inner.mut_token().is_some()); TypeRef::Reference(Box::new(RefType { ty: inner_ty, lifetime, mutability })) } ast::Type::InferType(_inner) => TypeRef::Placeholder, ast::Type::FnPtrType(inner) => { - let ret_ty = inner - .ret_type() - .and_then(|rt| rt.ty()) - .map(|it| self.lower_type_ref(it, impl_trait_lower_fn)) - .unwrap_or_else(|| self.alloc_type_ref_desugared(TypeRef::unit())); + let old_elision_kind = self.elide_lifetime_for_binder(); + let old_candidates = self.elision_candidates.take(); + let mut is_varargs = false; let mut params = if let Some(pl) = inner.param_list() { if let Some(param) = pl.params().last() { @@ -740,7 +899,9 @@ impl<'db> ExprCollector<'db> { pl.params() .filter(|it| it.dotdotdot_token().is_none()) .map(|it| { - let type_ref = self.lower_type_ref_opt(it.ty(), impl_trait_lower_fn); + let type_ref = self.with_param(|this| { + this.lower_type_ref_opt(it.ty(), impl_trait_lower_fn) + }); let name = match it.pat() { Some(ast::Pat::IdentPat(it)) => Some( it.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing), @@ -753,6 +914,14 @@ impl<'db> ExprCollector<'db> { } else { Vec::with_capacity(1) }; + let elided_for_binder = self.elide_return_lifetime_for_binder(); + let ret_ty = inner + .ret_type() + .and_then(|rt| rt.ty()) + .map(|it| self.lower_type_ref(it, impl_trait_lower_fn)) + .unwrap_or_else(|| self.alloc_type_ref_desugared(TypeRef::unit())); + params.push((None, ret_ty)); + fn lower_abi(abi: ast::Abi) -> ExternAbi { abi.abi_string() .and_then(|abi| abi.text_without_quotes().parse().ok()) @@ -760,9 +929,11 @@ impl<'db> ExprCollector<'db> { } let abi = inner.abi().map(lower_abi).unwrap_or(ExternAbi::Rust); - params.push((None, ret_ty)); - let binder = self.for_type_binder.take().map(|b| b.into()); + let binder = (!elided_for_binder.is_empty()).then_some(elided_for_binder.into()); + + self.lifetime_elision_kind = old_elision_kind; + self.elision_candidates = old_candidates; TypeRef::Fn(Box::new(FnType { is_varargs, is_unsafe: inner.unsafe_token().is_some(), @@ -774,9 +945,9 @@ impl<'db> ExprCollector<'db> { // for types are close enough for our purposes to the inner type for now... ast::Type::ForType(inner) => { let binder = self.lower_for_binder_opt(inner.for_binder()); - let old_for_binder = self.for_type_binder.replace(binder); - let ty = self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn); - self.for_type_binder = old_for_binder; + let ty = self.with_for_binder(binder, |ec| { + ec.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn) + }); return ty; } ast::Type::ImplTraitType(inner) => { @@ -784,7 +955,10 @@ impl<'db> ExprCollector<'db> { // Disallow nested impl traits TypeRef::Error } else { - return self.with_outer_impl_trait_scope(true, |this| { + let old_elision_kind = + mem::replace(&mut self.lifetime_elision_kind, LifetimeElisionKind::Error); + let old_elision_candidates = self.elision_candidates.take(); + let result = self.with_outer_impl_trait_scope(true, |this| { let is_argument_scope = this.is_argument_lt_bound_scope(); let type_bounds = this.with_lifetime_bound_scope( LifetimeBoundScope::ImplTrait { is_argument_scope }, @@ -797,6 +971,9 @@ impl<'db> ExprCollector<'db> { ); impl_trait_lower_fn(this, AstPtr::new(&node), type_bounds) }); + self.elision_candidates = old_elision_candidates; + self.lifetime_elision_kind = old_elision_kind; + return result; } } ast::Type::DynTraitType(inner) => TypeRef::DynTrait( @@ -865,6 +1042,7 @@ impl<'db> ExprCollector<'db> { let ptr = self.expander.in_file(node); self.store.lifetime_map_back.insert(id, ptr); self.store.lifetime_map.insert(ptr, id); + self.record_lifetime_usage(id); id } @@ -873,13 +1051,21 @@ impl<'db> ExprCollector<'db> { } fn alloc_lifetime_ref_desugared(&mut self, lifetime_ref: LifetimeRef) -> LifetimeRefId { - self.store.lifetimes.alloc(lifetime_ref) + let id = self.store.lifetimes.alloc(lifetime_ref); + self.record_lifetime_usage(id); + id } fn alloc_error_type(&mut self) -> TypeRefId { self.store.types.alloc(TypeRef::Error) } + fn record_lifetime_usage(&mut self, id: LifetimeRefId) { + if let Some(elision_candidates) = &mut self.elision_candidates { + elision_candidates.push(id); + } + } + pub fn lower_path( &mut self, ast: ast::Path, @@ -899,8 +1085,106 @@ impl<'db> ExprCollector<'db> { result } + fn with_self_param(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { + self.with_param_inner(true, f) + } + + fn with_param(&mut self, f: impl FnOnce(&mut Self) -> R) -> R { + self.with_param_inner(false, f) + } + + fn with_param_inner(&mut self, is_self: bool, f: impl FnOnce(&mut Self) -> R) -> R { + let old = self.elision_candidates.replace(ThinVec::new()); + let result = f(self); + + let return_lt = self.lifetime_elision_kind.get_return_lt_mut(); + + if let Some(candidates) = self.elision_candidates.take() + && let Some(return_lt) = return_lt + { + let distinct: FxIndexSet<_> = + candidates.iter().map(|id| &self.store.lifetimes[*id]).collect(); + + let get_only = || { + if distinct.len() == 1 { distinct.first() } else { None } + }; + + if is_self { + if distinct.is_empty() { + *return_lt = ReturnLifetimeElision::None; + } else if let Some(<_ref) = get_only() { + *return_lt = ReturnLifetimeElision::Self_(lt_ref.clone()); + } else { + *return_lt = ReturnLifetimeElision::Error; + }; + } else { + match return_lt { + ReturnLifetimeElision::None => { + if let Some(<_ref) = get_only() { + *return_lt = ReturnLifetimeElision::Param(lt_ref.clone()) + } else { + *return_lt = ReturnLifetimeElision::Error; + } + } + ReturnLifetimeElision::Param(_) => *return_lt = ReturnLifetimeElision::Error, + ReturnLifetimeElision::Self_(_) | ReturnLifetimeElision::Error => (), + } + } + } + + self.elision_candidates = old; + result + } + + fn with_for_binder( + &mut self, + binder: Option>, + f: impl FnOnce(&mut Self) -> R, + ) -> R { + let old = match binder { + Some(binder) => self.for_type_binder.replace(binder), + None => return f(self), + }; + let result = f(self); + self.for_type_binder = old; + result + } + + fn lower_elided_lifetime(&mut self) -> LifetimeRefId { + self.lower_elided_lifetime_opt(None) + } + + fn lower_elided_lifetime_opt(&mut self, lifetime: Option) -> LifetimeRefId { + let lifetime_ref = match &mut self.lifetime_elision_kind { + &mut LifetimeElisionKind::NewGenericLifetime { bound_type, parent, .. } => { + let name = Name::anon_lifetime(); + let lifetimes = self.lifetime_arena.as_mut().unwrap(); + let parent = parent.unwrap(); + let lifetime = LifetimeParamData { name, bound_type }; + let param_id = LifetimeParamId { parent, local_id: lifetimes.alloc(lifetime) }; + LifetimeRef::Param(param_id) + } + LifetimeElisionKind::NewHrtbLifetime { binder, .. } => { + let name = Name::anon_lifetime(); + let local_id = binder.len(); + binder.push(name); + let param_id = HrtbLifetimeParamId(local_id as u32); + LifetimeRef::HrtbParam(param_id) + } + LifetimeElisionKind::Lifetime(lifetime_ref) => lifetime_ref.clone(), + LifetimeElisionKind::Static => LifetimeRef::Static, + LifetimeElisionKind::Error => LifetimeRef::Error, + }; + + if let Some(lifetime) = lifetime { + self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime)) + } else { + self.alloc_lifetime_ref_desugared(lifetime_ref) + } + } + pub fn impl_trait_error_allocator( - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, ptr: TypePtr, _: ThinVec, ) -> TypeRefId { @@ -908,7 +1192,7 @@ impl<'db> ExprCollector<'db> { } fn impl_trait_allocator( - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, ptr: TypePtr, bounds: ThinVec, ) -> TypeRefId { @@ -928,6 +1212,9 @@ impl<'db> ExprCollector<'db> { impl_trait_lower_fn: ImplTraitLowerFn<'_>, ) -> Option { let params = args?; + let old_elision_kind = self.elide_lifetime_for_binder(); + let old_candidates = self.elision_candidates.take(); + let mut param_types = Vec::new(); for param in params.type_args() { let type_ref = self.lower_type_ref_opt(param.ty(), impl_trait_lower_fn); @@ -936,6 +1223,10 @@ impl<'db> ExprCollector<'db> { let args = Box::new([GenericArg::Type( self.alloc_type_ref_desugared(TypeRef::Tuple(ThinVec::from_iter(param_types))), )]); + + let elided_for_binder = self.elide_return_lifetime_for_binder(); + self.for_type_binder = Some(elided_for_binder); + let bindings = if let Some(ret_type) = ret_type { let type_ref = self.lower_type_ref_opt(ret_type.ty(), impl_trait_lower_fn); Box::new([AssociatedTypeBinding { @@ -954,6 +1245,9 @@ impl<'db> ExprCollector<'db> { bounds: Box::default(), }]) }; + + self.lifetime_elision_kind = old_elision_kind; + self.elision_candidates = old_candidates; Some(GenericArgs { args, has_self_type: false, @@ -1260,16 +1554,21 @@ impl<'db> ExprCollector<'db> { Some(_) => TraitBoundModifier::Maybe, None => TraitBoundModifier::None, }; - self.lower_path_type(&path_type, impl_trait_lower_fn) - .map(|p| { - let path = self.alloc_path(p, AstPtr::new(&path_type).upcast()); - if binder.is_empty() { - TypeBound::Path(path, m) - } else { - TypeBound::ForLifetime(binder, path) - } - }) - .unwrap_or(TypeBound::Error) + self.with_for_binder(binder, |ec| { + ec.lower_path_type(&path_type, impl_trait_lower_fn) + .map(|p| { + let path = ec.alloc_path(p, AstPtr::new(&path_type).upcast()); + let binder = ec.for_type_binder.take(); + if let Some(binder) = binder + && !binder.is_empty() + { + TypeBound::ForLifetime(binder, path) + } else { + TypeBound::Path(path, m) + } + }) + .unwrap_or(TypeBound::Error) + }) } ast::TypeBoundKind::Use(gal) => TypeBound::Use( gal.use_bound_generic_args() @@ -1287,8 +1586,8 @@ impl<'db> ExprCollector<'db> { } } - fn lower_for_binder_opt(&mut self, binder: Option) -> ThinVec { - binder.map(|b| self.lower_for_binder(b)).unwrap_or_default() + fn lower_for_binder_opt(&mut self, binder: Option) -> Option> { + binder.map(|b| self.lower_for_binder(b)) } fn lower_for_binder(&mut self, binder: ForBinder) -> ThinVec { @@ -1651,6 +1950,7 @@ impl<'db> ExprCollector<'db> { let mut arg_types = Vec::new(); // For coroutine closures, the body, aka. the coroutine is the bindings owner, and not the closure. if let Some(pl) = e.param_list() { + // Should we elide in closure? let num_params = pl.params().count(); args.reserve_exact(num_params); arg_types.reserve_exact(num_params); @@ -1661,6 +1961,7 @@ impl<'db> ExprCollector<'db> { let pat = this.collect_pat_top(param.pat()); let type_ref = + // FIXME: should closures elide if so how? param.ty().map(|it| this.lower_type_ref_disallow_impl_trait(it)); args.push(pat); arg_types.push(type_ref); @@ -2026,7 +2327,10 @@ impl<'db> ExprCollector<'db> { }; return Some(result); - fn collect_path(this: &mut ExprCollector<'_>, expr: ast::Expr) -> Option { + fn collect_path( + this: &mut ExprCollector<'_, '_>, + expr: ast::Expr, + ) -> Option { match expr { ast::Expr::PathExpr(e) => Some(e), ast::Expr::MacroExpr(mac) => { @@ -2043,7 +2347,7 @@ impl<'db> ExprCollector<'db> { } fn collect_possibly_rest( - this: &mut ExprCollector<'_>, + this: &mut ExprCollector<'_, '_>, expr: ast::Expr, ) -> Either { match &expr { @@ -2076,7 +2380,7 @@ impl<'db> ExprCollector<'db> { } fn collect_tuple( - this: &mut ExprCollector<'_>, + this: &mut ExprCollector<'_, '_>, fields: ast::AstChildren, ) -> (Option, Box<[la_arena::Idx]>) { let mut ellipsis = None; @@ -3331,7 +3635,7 @@ fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> Some((hir_lit, ast_lit)) } -impl<'db> ExprCollector<'db> { +impl<'db, 'a> ExprCollector<'db, 'a> { fn with_fresh_binding_expr_root(&mut self, f: impl FnOnce(&mut Self) -> ExprId) -> ExprId { self.with_expr_root(|this| this.with_binding_owner(f)) } @@ -3486,21 +3790,13 @@ impl<'db> ExprCollector<'db> { matches!(self.named_lifetime_store.lifetime_bound_scope, Some(LifetimeBoundScope::Argument)) } - fn get_constrained_lifetimes_if_type_alias<'a>( + fn get_constrained_lifetimes_if_type_alias<'g>( &mut self, - mod_path: &'a ModPath, - generic_args: Option<&'a GenericArgs>, - ) -> Option + use<'a, 'db>> { + module_def_id: Option, + generic_args: Option<&'g GenericArgs>, + ) -> Option + use<'g, 'db>> { let generic_args = generic_args?; - let r_path = self.def_map.resolve_path( - self.local_def_map, - self.db, - self.module, - mod_path, - BuiltinShadowMode::Module, - None, - ); - let ModuleDefId::TypeAliasId(id) = r_path.0.take_types()? else { return None }; + let ModuleDefId::TypeAliasId(id) = module_def_id? else { return None }; let constrained_lt_indices = get_constrained_lifetimes(self.db, id); let res = constrained_lt_indices.iter().filter_map(|&idx| { @@ -3568,6 +3864,54 @@ impl<'db> ExprCollector<'db> { Default::default() } } + + pub(crate) fn collect_path_elided_lifetimes( + &mut self, + module_def_id: Option, + args: Option<&GenericArgs>, + ) -> Option { + let num_lifetime_args = args + .as_ref() + .map(|args| { + args.args.iter().filter(|arg| matches!(arg, GenericArg::Lifetime(..))).count() + }) + .unwrap_or_default(); + + let def = module_def_id.and_then(|def| def.as_generic_def_id()); + + let num_lifetime_params = + def.map(|def| GenericParams::of(self.db, def).len_lifetimes()).unwrap_or_default(); + + let mut elided_args = Vec::new(); + if num_lifetime_args == 0 { + // lifetime args does not exist in source + // call elided function for all lifetime params + for _ in 0..num_lifetime_params { + let lt_id = self.lower_elided_lifetime(); + elided_args.push(GenericArg::Lifetime(lt_id)); + } + } + if !elided_args.is_empty() { + if let Some(prev_generic_args) = args { + elided_args.extend_from_slice(prev_generic_args.args.as_ref()); + Some(GenericArgs { + args: elided_args.into_boxed_slice(), + has_self_type: prev_generic_args.has_self_type, + bindings: prev_generic_args.bindings.clone(), + parenthesized: prev_generic_args.parenthesized, + }) + } else { + Some(GenericArgs { + args: elided_args.into_boxed_slice(), + has_self_type: false, + bindings: Box::default(), + parenthesized: GenericArgsParentheses::No, + }) + } + } else { + None + } + } } fn comma_follows_token(t: Option) -> bool { diff --git a/crates/hir-def/src/expr_store/lower/asm.rs b/crates/hir-def/src/expr_store/lower/asm.rs index fb0a5b0bf7a7..b4813cbf5192 100644 --- a/crates/hir-def/src/expr_store/lower/asm.rs +++ b/crates/hir-def/src/expr_store/lower/asm.rs @@ -13,7 +13,7 @@ use crate::{ hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmKind, InlineAsmRegOrRegClass}, }; -impl ExprCollector<'_> { +impl ExprCollector<'_, '_> { pub(super) fn lower_inline_asm( &mut self, asm: ast::AsmExpr, diff --git a/crates/hir-def/src/expr_store/lower/format_args.rs b/crates/hir-def/src/expr_store/lower/format_args.rs index 5552213aba55..69da5a092ba8 100644 --- a/crates/hir-def/src/expr_store/lower/format_args.rs +++ b/crates/hir-def/src/expr_store/lower/format_args.rs @@ -19,7 +19,7 @@ use crate::{ type_ref::{Mutability, Rawness}, }; -impl<'db> ExprCollector<'db> { +impl<'db> ExprCollector<'db, '_> { pub(super) fn collect_format_args( &mut self, f: ast::FormatArgsExpr, diff --git a/crates/hir-def/src/expr_store/lower/generics.rs b/crates/hir-def/src/expr_store/lower/generics.rs index 65877fb627f2..5bff54610f22 100644 --- a/crates/hir-def/src/expr_store/lower/generics.rs +++ b/crates/hir-def/src/expr_store/lower/generics.rs @@ -14,7 +14,7 @@ use crate::{ GenericDefId, TypeOrConstParamId, TypeParamId, expr_store::{ TypePtr, - lower::{ExprCollector, LifetimeBoundScope, NamedLifetimeStore}, + lower::{ExprCollector, LifetimeBoundScope}, }, hir::generics::{ ConstParamData, GenericParams, LifetimeBoundType, LifetimeParamData, TypeOrConstParamData, @@ -23,8 +23,8 @@ use crate::{ type_ref::{LifetimeRef, LifetimeRefId, TypeBound, TypeRef, TypeRefId}, }; -pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db> FnMut( - &'ec mut ExprCollector<'db>, +pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db, 'a> FnMut( + &'ec mut ExprCollector<'db, 'a>, TypePtr, ThinVec, ) -> TypeRefId; @@ -46,7 +46,7 @@ impl GenericParamsCollector { } } pub(crate) fn with_self_param( - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, parent: GenericDefId, bounds: Option, ) -> Self { @@ -57,7 +57,7 @@ impl GenericParamsCollector { pub(crate) fn lower( &mut self, - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, generic_param_list: Option, where_clause: Option, ) { @@ -69,11 +69,12 @@ impl GenericParamsCollector { } } - pub(crate) fn collect_impl_trait( - &mut self, - ec: &mut ExprCollector<'_>, - cb: impl FnOnce(&mut ExprCollector<'_>, ImplTraitLowerFn<'_>) -> R, + pub(crate) fn collect_impl_trait<'a, R>( + &'a mut self, + ec: &mut ExprCollector<'_, 'a>, + cb: impl FnOnce(&mut ExprCollector<'_, '_>, ImplTraitLowerFn<'_>) -> R, ) -> R { + ec.elide_create_lifetime(&mut self.lifetimes, self.parent, LifetimeBoundType::LateBound); cb( ec, &mut Self::lower_argument_impl_trait( @@ -96,7 +97,11 @@ impl GenericParamsCollector { } } - fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericParamList) { + pub(crate) fn lifetimes_mut(&mut self) -> &mut Arena { + &mut self.lifetimes + } + + fn lower_param_list(&mut self, ec: &mut ExprCollector<'_, '_>, params: ast::GenericParamList) { for generic_param in params.generic_params() { let enabled = ec.check_cfg(&generic_param); if !enabled { @@ -158,7 +163,7 @@ impl GenericParamsCollector { fn lower_where_predicates( &mut self, - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, where_clause: ast::WhereClause, ) { ec.with_lifetime_bound_scope(LifetimeBoundScope::WhereClause, |ec| { @@ -185,6 +190,7 @@ impl GenericParamsCollector { }) .collect() }); + for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) { self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target); } @@ -194,7 +200,7 @@ impl GenericParamsCollector { fn lower_bounds( &mut self, - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, type_bounds: Option, target: Either, ) { @@ -205,7 +211,7 @@ impl GenericParamsCollector { fn lower_type_bound_as_predicate( &mut self, - ec: &mut ExprCollector<'_>, + ec: &mut ExprCollector<'_, '_>, bound: ast::TypeBound, hrtb_lifetimes: Option<&[Name]>, target: Either, @@ -240,8 +246,11 @@ impl GenericParamsCollector { type_or_consts: &mut Arena, where_predicates: &mut Vec, parent: GenericDefId, - ) -> impl for<'ec, 'db> FnMut(&'ec mut ExprCollector<'db>, TypePtr, ThinVec) -> TypeRefId - { + ) -> impl for<'ec, 'db, 'a> FnMut( + &'ec mut ExprCollector<'db, 'a>, + TypePtr, + ThinVec, + ) -> TypeRefId { move |ec, ptr, impl_trait_bounds| { let param = TypeParamData { name: None, @@ -264,7 +273,11 @@ impl GenericParamsCollector { } } - fn fill_self_param(&mut self, ec: &mut ExprCollector<'_>, bounds: Option) { + fn fill_self_param( + &mut self, + ec: &mut ExprCollector<'_, '_>, + bounds: Option, + ) { let self_ = Name::new_symbol_root(sym::Self_); let idx = self.type_or_consts.alloc( TypeParamData { @@ -284,24 +297,4 @@ impl GenericParamsCollector { self.lower_bounds(ec, Some(bounds), Either::Left(self_)); } } - - pub(crate) fn update_to_late_bound_lifetimes( - &mut self, - named_lifetime_store: &NamedLifetimeStore, - ) { - for (_param_id, lifetime) in self.lifetimes.iter_mut() { - let lifetime_name = &lifetime.name; - if named_lifetime_store.lifetimes_in_where_clause.contains(lifetime_name) { - continue; - } - - if !named_lifetime_store.lifetimes_constrained_by_input.contains(lifetime_name) - && named_lifetime_store.lifetimes_in_output.contains(lifetime_name) - { - continue; - } - - lifetime.bound_type = LifetimeBoundType::LateBound - } - } } diff --git a/crates/hir-def/src/expr_store/lower/path.rs b/crates/hir-def/src/expr_store/lower/path.rs index 8f71ea867dd5..63cca00ec20f 100644 --- a/crates/hir-def/src/expr_store/lower/path.rs +++ b/crates/hir-def/src/expr_store/lower/path.rs @@ -6,10 +6,12 @@ mod tests; use std::iter; use crate::{ + ModuleDefId, expr_store::{ lower::{ExprCollector, generics::ImplTraitLowerFn}, path::NormalPath, }, + item_scope::BuiltinShadowMode, type_ref::LifetimeRef, }; @@ -39,7 +41,7 @@ thread_local! { // If you modify the logic of the lowering, make sure to check if `hir_segment_to_ast_segment()` // also needs an update. pub(super) fn lower_path( - collector: &mut ExprCollector<'_>, + collector: &mut ExprCollector<'_, '_>, mut path: ast::Path, impl_trait_lower_fn: ImplTraitLowerFn<'_>, ) -> Option { @@ -256,11 +258,46 @@ pub(super) fn lower_path( *last_segment_args = None; } + let segments_len = segments.len(); let mod_path = Interned::new(ModPath::from_segments(kind, segments)); + let (resolved_module_def_id, is_trait_assoc_item) = { + let (per_ns, remaining_idx) = collector.def_map.resolve_path( + collector.local_def_map, + collector.db, + collector.module, + &mod_path, + BuiltinShadowMode::Module, + None, + ); + let def = per_ns.types.map(|item| item.def); + + let is_trait_assoc_item = matches!(def, Some(ModuleDefId::TraitId(..))) + && remaining_idx.is_some_and(|idx| idx > 0); + (def, is_trait_assoc_item) + }; + + if collector.lifetime_elision_kind.can_elide() && !is_trait_assoc_item { + let args_in_source = generic_args.last().and_then(|g| g.as_ref()); + let merged_args_with_elided = + collector.collect_path_elided_lifetimes(resolved_module_def_id, args_in_source); + match &merged_args_with_elided { + // there are elided args + Some(_) => { + if args_in_source.is_none() { + generic_args.resize(segments_len, None); + } + if let Some(args) = generic_args.last_mut() { + *args = merged_args_with_elided + } + } + _ => {} // there are no elided args + } + } + if let Some(old_lifetimes_constrained_by_input) = old_lifetimes_constrained_by_input { let type_alias_constrained_lifetimes = collector.get_constrained_lifetimes_if_type_alias( - &mod_path, + resolved_module_def_id, generic_args.last().and_then(|g| g.as_ref()), ); if let Some(lifetimes) = type_alias_constrained_lifetimes { diff --git a/crates/hir-def/src/expr_store/pretty.rs b/crates/hir-def/src/expr_store/pretty.rs index 1c70922467e1..7406845fe3a1 100644 --- a/crates/hir-def/src/expr_store/pretty.rs +++ b/crates/hir-def/src/expr_store/pretty.rs @@ -374,6 +374,10 @@ fn print_generic_params( w!(p, "<"); let mut first = true; for (_i, param) in generic_params.iter_lt() { + if param.is_elided() { + continue; + } + if !first { w!(p, ", "); } @@ -1267,6 +1271,7 @@ impl Printer<'_> { } LifetimeRef::Placeholder => w!(self, "'_"), LifetimeRef::Error => w!(self, "'{{error}}"), + LifetimeRef::HrtbParam(_) => w!(self, "'_"), // FIXME: properly handle it, currently do not have enough data to handle &LifetimeRef::Param(p) => self.print_lifetime_param(p), } } @@ -1302,7 +1307,9 @@ impl Printer<'_> { Mutability::Mut => "mut ", }; w!(self, "&"); - if let Some(lt) = &ref_.lifetime { + if let Some(lt) = &ref_.lifetime + && !self.store[*lt].is_elided(self.db) + { self.print_lifetime_ref(*lt); w!(self, " "); } diff --git a/crates/hir-def/src/expr_store/tests/signatures.rs b/crates/hir-def/src/expr_store/tests/signatures.rs index 460ab6418d92..29bda53461cb 100644 --- a/crates/hir-def/src/expr_store/tests/signatures.rs +++ b/crates/hir-def/src/expr_store/tests/signatures.rs @@ -169,7 +169,7 @@ fn allowed3(baz: impl Baz>) {} {...} fn not_allowed2(Param[0]) where - Param[0]: Fn::<(&{error}), Output = ()> + Param[0]: for<'_> Fn::<(&{error}), Output = ()> {...} fn not_allowed3(Param[0]) where @@ -177,7 +177,7 @@ fn allowed3(baz: impl Baz>) {} {...} fn not_allowed4(Param[0]) where - Param[0]: Bar::<&{error}> + Param[0]: Bar::<&'{error} {error}> {...} fn allowed1(Param[1]) where @@ -207,7 +207,7 @@ type Alias<'a, 'b, T> = &'b T; fn f(_: Alias) {} "#, expect![[r#" - fn f(Alias::) {...} + fn f(Alias::<'_, '_, T>) {...} "#]], ); } @@ -237,3 +237,41 @@ extern "C" { "#]], ); } + +#[test] +fn return_elided_test() { + lower_and_print( + r#" +#[lang = "owned_box"] +pub struct Box(T); + +fn with_self<'a, 'b>(&'a self, foo: &'b str) -> &str {} +fn with_self<'b>(&'static self, foo: &'b str) -> &str {} +fn with_self(&self, foo: &str) -> &str {} + +fn with_self_error(self: &Box<&Self>) -> &str {} + +fn foo<'a>(value: &'a str) -> &str {} +fn foo(value: &'static str) -> &str {} +fn foo(value: &str) -> &str {} + +fn foo<'a, 'b>(value: &'a str, v2: &'b str) -> &str {} +fn foo(value: &'static str, v2: &'static str) -> &str {} +fn foo(value: &str, v2: &str) -> &str {} +"#, + expect![[r#" + struct Box(...) + ; + fn with_self<'a, 'b>(&'a Self, &'b str) -> &'a str {...} + fn with_self<'b>(&'static Self, &'b str) -> &'static str {...} + fn with_self<>(&Self, &str) -> &str {...} + fn with_self_error<>(&Box::<&Self>) -> &'{error} str {...} + fn foo<'a>(&'a str) -> &'a str {...} + fn foo(&'static str) -> &'static str {...} + fn foo<>(&str) -> &str {...} + fn foo<'a, 'b>(&'a str, &'b str) -> &'{error} str {...} + fn foo(&'static str, &'static str) -> &'{error} str {...} + fn foo<>(&str, &str) -> &'{error} str {...} + "#]], + ); +} diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs index 2e0b6f1ae1cd..4b5102ab863b 100644 --- a/crates/hir-def/src/hir/generics.rs +++ b/crates/hir-def/src/hir/generics.rs @@ -37,13 +37,17 @@ pub struct LifetimeParamData { pub bound_type: LifetimeBoundType, } -#[derive(Clone, PartialEq, Eq, Debug, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum LifetimeBoundType { EarlyBound, LateBound, } impl LifetimeParamData { + pub fn is_elided(&self) -> bool { + self.name.is_anon_lifetime() + } + pub fn is_late_bound(&self) -> bool { self.bound_type == LifetimeBoundType::LateBound } diff --git a/crates/hir-def/src/hir/type_ref.rs b/crates/hir-def/src/hir/type_ref.rs index 8e29268c1c21..edfabc5bda14 100644 --- a/crates/hir-def/src/hir/type_ref.rs +++ b/crates/hir-def/src/hir/type_ref.rs @@ -1,15 +1,16 @@ //! HIR for references to types. Paths in these are not yet resolved. They can //! be directly created from an ast::TypeRef, without further queries. +use base_db::SourceDatabase; use hir_expand::name::Name; use la_arena::Idx; use rustc_abi::ExternAbi; use thin_vec::ThinVec; use crate::{ - LifetimeParamId, TypeParamId, + HrtbLifetimeParamId, LifetimeParamId, TypeParamId, expr_store::{ExpressionStore, path::Path}, - hir::{ExprId, PatId}, + hir::{ExprId, PatId, generics::GenericParams}, }; #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] @@ -157,6 +158,7 @@ pub enum LifetimeRef { Static, Placeholder, Param(LifetimeParamId), + HrtbParam(HrtbLifetimeParamId), Error, } @@ -202,6 +204,22 @@ impl TypeBound { } } +impl LifetimeRef { + pub fn is_elided(&self, db: &dyn SourceDatabase) -> bool { + match self { + LifetimeRef::HrtbParam(_) | LifetimeRef::Placeholder => true, + LifetimeRef::Named(name) => name.is_anon_lifetime(), // Ideally, should not be true if it's Named variant + LifetimeRef::Param(lifetime_param_id) => { + let generics = GenericParams::of(db, lifetime_param_id.parent); + let lt_param = &generics.lifetimes[lifetime_param_id.local_id]; + lt_param.name.is_anon_lifetime() + } + + LifetimeRef::Static | LifetimeRef::Error => false, + } + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct ConstRef { pub expr: ExprId, diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs index d35a4617fb72..1cdc05f1a597 100644 --- a/crates/hir-def/src/lib.rs +++ b/crates/hir-def/src/lib.rs @@ -718,10 +718,7 @@ pub struct LifetimeParamId { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct HrtbLifetimeParamId { - pub scope: GenericDefId, - pub local_id: usize, -} +pub struct HrtbLifetimeParamId(pub u32); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)] pub enum ItemContainerId { @@ -1419,6 +1416,24 @@ impl ModuleDefId { ModuleDefId::BuiltinType(_) => return None, }) } + + /// Converts this `ModuleDefId` into a `GenericDefId` if possible. + /// + /// Returns `None` for variants, modules, builtin types, and macros. + pub fn as_generic_def_id(self) -> Option { + match self { + ModuleDefId::FunctionId(id) => Some(id.into()), + ModuleDefId::AdtId(id) => Some(id.into()), + ModuleDefId::ConstId(id) => Some(id.into()), + ModuleDefId::StaticId(id) => Some(id.into()), + ModuleDefId::TraitId(id) => Some(id.into()), + ModuleDefId::TypeAliasId(id) => Some(id.into()), + ModuleDefId::ModuleId(_) => None, + ModuleDefId::EnumVariantId(_) => None, + ModuleDefId::BuiltinType(_) => None, + ModuleDefId::MacroId(_) => None, + } + } } /// Helper wrapper for `AstId` with `ModPath` #[derive(Clone, Debug, Eq, PartialEq)] diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 5b11f5ff8bbb..28e0149a5cf8 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -571,6 +571,10 @@ impl<'db> Resolver<'db> { LifetimeRef::Param(lifetime_param_id) => { Some(LifetimeNs::LifetimeParam(*lifetime_param_id)) } + LifetimeRef::HrtbParam(_) => { + stdx::never!(); + None + } } } diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs index 7968adabbccf..5922830b7d8c 100644 --- a/crates/hir-expand/src/name.rs +++ b/crates/hir-expand/src/name.rs @@ -112,6 +112,11 @@ impl Name { } } + #[inline] + pub fn anon_lifetime() -> Name { + Self::new_symbol_root(sym::tick_underscore) + } + #[inline] pub fn new_symbol(symbol: Symbol, ctx: SyntaxContext) -> Self { debug_assert!(!symbol.as_str().starts_with("r#")); @@ -204,6 +209,11 @@ impl Name { pub fn is_generated(&self) -> bool { is_generated(self.as_str()) } + + #[inline] + pub fn is_anon_lifetime(&self) -> bool { + *self == sym::tick_underscore + } } #[inline] diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index dc20eb930e81..7ae0b319ba7a 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs @@ -2337,7 +2337,7 @@ impl<'db> HirDisplay<'db> for Region<'db> { write!(f, "'_") } } - RegionKind::ReErased => write!(f, "'"), + RegionKind::ReErased => write!(f, "'_"), RegionKind::RePlaceholder(_) => write!(f, "'"), RegionKind::ReLateParam(_) => write!(f, "'_"), } @@ -2429,6 +2429,7 @@ impl<'db> HirDisplayWithExpressionStore<'db> for LifetimeRefId { LifetimeRef::Static => write!(f, "'static"), LifetimeRef::Placeholder => write!(f, "'_"), LifetimeRef::Error => write!(f, "'{{error}}"), + LifetimeRef::HrtbParam(_) => write!(f, "'_"), // FIXME: find a way to display HRTB param as well &LifetimeRef::Param(lifetime_param_id) => { let generic_params = GenericParams::of(f.db, lifetime_param_id.parent); write!( @@ -2501,7 +2502,9 @@ impl<'db> HirDisplayWithExpressionStore<'db> for TypeRefId { hir_def::type_ref::Mutability::Mut => "mut ", }; write!(f, "&")?; - if let Some(lifetime) = &ref_.lifetime { + if let Some(lifetime) = &ref_.lifetime + && !store[*lifetime].is_elided(f.db) + { lifetime.hir_fmt(f, owner, store)?; write!(f, " ")?; } diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 7b28689912e5..80eef815bd77 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -46,8 +46,8 @@ use rustc_hash::FxHashSet; use rustc_type_ir::{ AliasTyKind, BoundRegion, BoundRegionKind, BoundTyKind, BoundVar, BoundVariableKind, DebruijnIndex, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, - Interner, OutlivesPredicate, TermKind, TyKind, TypeFoldable, TypeVisitableExt, Upcast, - UpcastFrom, elaborate, + INNERMOST, Interner, OutlivesPredicate, TermKind, TyKind, TypeFoldable, TypeVisitableExt, + Upcast, UpcastFrom, elaborate, inherent::{Clause as _, GenericArgs as _, IntoKind as _, Region as _, Ty as _}, }; use salsa::SalsaValue; @@ -1352,20 +1352,24 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } fn find_and_lower_hrtb_lifetime(&mut self, lifetime: LifetimeRefId) -> Option> { - if let LifetimeRef::Named(lt_name) = &self.store[lifetime] { - self.bound_vars.iter().rev().enumerate().find_map(|(debruijn, (binder, _))| { - binder.iter().enumerate().find_map(|(index, l)| { - (l == lt_name).then(|| { - self.hrtb_region_param( - index as u32, - DebruijnIndex::from_usize(debruijn), - self.generic_def, - ) + match &self.store[lifetime] { + LifetimeRef::Named(lt_name) => { + self.bound_vars.iter().rev().enumerate().find_map(|(debruijn, (binder, _))| { + binder.iter().enumerate().find_map(|(index, l)| { + (l == lt_name).then(|| { + self.hrtb_region_param( + index as u32, + DebruijnIndex::from_usize(debruijn), + self.generic_def, + ) + }) }) }) - }) - } else { - None + } + LifetimeRef::HrtbParam(hrtb_param_id) => { + Some(self.hrtb_region_param(hrtb_param_id.0, INNERMOST, self.generic_def)) + } + _ => None, } } } diff --git a/crates/hir-ty/src/tests/closure_captures.rs b/crates/hir-ty/src/tests/closure_captures.rs index c951a5481c46..29604e0ce5b9 100644 --- a/crates/hir-ty/src/tests/closure_captures.rs +++ b/crates/hir-ty/src/tests/closure_captures.rs @@ -175,7 +175,7 @@ fn main() { let closure = || { let b = *a; }; } "#, - expect!["53..71;20..21;66..68 ByRef(Immutable) *a &' bool"], + expect!["53..71;20..21;66..68 ByRef(Immutable) *a &'_ bool"], ); } @@ -189,7 +189,7 @@ fn main() { let closure = || { let &mut ref b = a; }; } "#, - expect!["53..79;20..21;62..72 ByRef(Immutable) *a &' bool"], + expect!["53..79;20..21;62..72 ByRef(Immutable) *a &'_ bool"], ); check_closure_captures( r#" @@ -199,7 +199,7 @@ fn main() { let closure = || { let &mut ref mut b = a; }; } "#, - expect!["53..83;20..21;62..76 ByRef(Mutable) *a &' mut bool"], + expect!["53..83;20..21;62..76 ByRef(Mutable) *a &'_ mut bool"], ); } @@ -213,7 +213,7 @@ fn main() { let closure = || { *a = false; }; } "#, - expect!["53..71;20..21;58..60 ByRef(Mutable) *a &' mut bool"], + expect!["53..71;20..21;58..60 ByRef(Mutable) *a &'_ mut bool"], ); } @@ -227,7 +227,7 @@ fn main() { let closure = || { let ref mut b = *a; }; } "#, - expect!["53..79;20..21;74..76 ByRef(Mutable) *a &' mut bool"], + expect!["53..79;20..21;74..76 ByRef(Mutable) *a &'_ mut bool"], ); } @@ -273,8 +273,8 @@ fn main() { } "#, expect![[r#" - 71..89;36..41;85..86 ByRef(Immutable) a &' NonCopy - 109..131;36..41;127..128 ByRef(Mutable) a &' mut NonCopy"#]], + 71..89;36..41;85..86 ByRef(Immutable) a &'_ NonCopy + 109..131;36..41;127..128 ByRef(Mutable) a &'_ mut NonCopy"#]], ); } @@ -289,7 +289,7 @@ fn main() { let closure = || { let b = a.a; }; } "#, - expect!["92..111;50..51;105..108 ByRef(Immutable) a.a &' i32"], + expect!["92..111;50..51;105..108 ByRef(Immutable) a.a &'_ i32"], ); } @@ -310,8 +310,8 @@ fn main() { } "#, expect![[r#" - 133..212;87..92;155..158 ByRef(Immutable) a.a &' i32 - 133..212;87..92;181..184 ByRef(Mutable) a.b &' mut i32 + 133..212;87..92;155..158 ByRef(Immutable) a.a &'_ i32 + 133..212;87..92;181..184 ByRef(Mutable) a.b &'_ mut i32 133..212;87..92;202..205 ByValue a.c NonCopy"#]], ); } @@ -333,8 +333,8 @@ fn main() { } "#, expect![[r#" - 123..133;92..97;126..127 ByRef(Immutable) a &' Foo - 153..164;92..97;156..157 ByRef(Mutable) a &' mut Foo"#]], + 123..133;92..97;126..127 ByRef(Immutable) a &'_ Foo + 153..164;92..97;156..157 ByRef(Mutable) a &'_ mut Foo"#]], ); } @@ -361,7 +361,7 @@ fn main() { } "#, expect![[r#" - 113..167;36..41;127..128,159..160 ByRef(Mutable) a &' mut &'? mut bool + 113..167;36..41;127..128,159..160 ByRef(Mutable) a &'_ mut &'? mut bool 231..304;196..201;252..253,276..277,296..297 ByValue a NonCopy"#]], ); } @@ -400,8 +400,8 @@ fn main() { } "#, expect![[r#" - 125..163;36..41;134..135 ByRef(Immutable) a &' NonCopy - 183..225;36..41;192..193 ByRef(Mutable) a &' mut NonCopy"#]], + 125..163;36..41;134..135 ByRef(Immutable) a &'_ NonCopy + 183..225;36..41;192..193 ByRef(Mutable) a &'_ mut NonCopy"#]], ); } @@ -415,7 +415,7 @@ fn main() { let mut closure = || { let (b | b) = a; }; } "#, - expect!["57..80;20..25;76..77 ByRef(Immutable) a &' bool"], + expect!["57..80;20..25;76..77 ByRef(Immutable) a &'_ bool"], ); } @@ -434,9 +434,7 @@ fn main() { }; } "#, - expect![ - "57..149;20..25;79..80,99..100,123..124,134..135 ByRef(Mutable) a &' mut bool" - ], + expect!["57..149;20..25;79..80,99..100,123..124,134..135 ByRef(Mutable) a &'_ mut bool"], ); } @@ -450,7 +448,7 @@ fn main() { let mut closure = || { let b = *&mut a; }; } "#, - expect!["57..80;20..25;76..77 ByRef(Mutable) a &' mut bool"], + expect!["57..80;20..25;76..77 ByRef(Mutable) a &'_ mut bool"], ); } @@ -469,10 +467,10 @@ fn main() { } "#, expect![[r#" - 54..72;20..25;68..69 ByRef(Immutable) a &' &'? bool - 92..114;20..25;110..111 ByRef(Mutable) a &' mut &'? bool - 158..176;124..125;172..173 ByRef(Immutable) a &' &'? mut bool - 196..218;124..125;214..215 ByRef(Mutable) a &' mut &'? mut bool"#]], + 54..72;20..25;68..69 ByRef(Immutable) a &'_ &'? bool + 92..114;20..25;110..111 ByRef(Mutable) a &'_ mut &'? bool + 158..176;124..125;172..173 ByRef(Immutable) a &'_ &'? mut bool + 196..218;124..125;214..215 ByRef(Mutable) a &'_ mut &'? mut bool"#]], ); } @@ -491,7 +489,7 @@ fn main() { closure(); } "#, - expect!["99..165;49..54;120..121,133..134 ByRef(Mutable) a &' mut A"], + expect!["99..165;49..54;120..121,133..134 ByRef(Mutable) a &'_ mut A"], ); } @@ -514,8 +512,8 @@ fn main() { } "#, expect![[r#" - 129..225;49..54;158..163 ByRef(Immutable) s_ref &' &'? mut S - 129..225;93..99;201..207 ByRef(Mutable) s_ref2 &' mut &'? mut S"#]], + 129..225;49..54;158..163 ByRef(Immutable) s_ref &'_ &'? mut S + 129..225;93..99;201..207 ByRef(Mutable) s_ref2 &'_ mut &'? mut S"#]], ); } @@ -559,7 +557,7 @@ fn main() { }; } "#, - expect!["220..257;174..175;245..250 ByRef(Immutable) c.b.x &' i32"], + expect!["220..257;174..175;245..250 ByRef(Immutable) c.b.x &'_ i32"], ); } @@ -578,8 +576,8 @@ fn f() { } "#, expect![[r#" - 44..113;17..18;92..93 ByRef(Immutable) a &' i32 - 73..106;17..18;92..93 ByRef(Immutable) a &' i32"#]], + 44..113;17..18;92..93 ByRef(Immutable) a &'_ i32 + 73..106;17..18;92..93 ByRef(Immutable) a &'_ i32"#]], ); } @@ -597,7 +595,7 @@ fn f() { }; } "#, - expect!["77..110;46..47;96..97 ByRef(Immutable) b &' i32"], + expect!["77..110;46..47;96..97 ByRef(Immutable) b &'_ i32"], ); } @@ -614,7 +612,7 @@ fn foo(foo: &Foo) { || { return foo.arr[0] }; } "#, - expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &' Foo"], + expect!["102..126;85..88;114..117 ByRef(Immutable) *foo &'_ Foo"], ); } diff --git a/crates/hir-ty/src/tests/macros.rs b/crates/hir-ty/src/tests/macros.rs index c0da6cfd307d..d14bb1f2bf13 100644 --- a/crates/hir-ty/src/tests/macros.rs +++ b/crates/hir-ty/src/tests/macros.rs @@ -199,7 +199,7 @@ fn expr_macro_def_expanded_in_various_places() { 100..119 'for _ ...!() {}': ! 100..119 'for _ ...!() {}': {unknown} 100..119 'for _ ...!() {}': &'? mut {unknown} - 100..119 'for _ ...!() {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 100..119 'for _ ...!() {}': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 100..119 'for _ ...!() {}': Option<<{unknown} as Iterator>::Item> 100..119 'for _ ...!() {}': () 100..119 'for _ ...!() {}': () @@ -293,7 +293,7 @@ fn expr_macro_rules_expanded_in_various_places() { 114..133 'for _ ...!() {}': ! 114..133 'for _ ...!() {}': {unknown} 114..133 'for _ ...!() {}': &'? mut {unknown} - 114..133 'for _ ...!() {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 114..133 'for _ ...!() {}': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 114..133 'for _ ...!() {}': Option<<{unknown} as Iterator>::Item> 114..133 'for _ ...!() {}': () 114..133 'for _ ...!() {}': () diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs index 985ecb6c5d3b..4204057960ff 100644 --- a/crates/hir-ty/src/tests/method_resolution.rs +++ b/crates/hir-ty/src/tests/method_resolution.rs @@ -660,7 +660,7 @@ fn infer_call_trait_method_on_generic_param_1() { } "#, expect![[r#" - 29..33 'self': &'? Self + 29..33 'self': &'_ Self 63..64 't': T 69..88 '{ ...d(); }': () 75..76 't': T @@ -681,7 +681,7 @@ fn infer_call_trait_method_on_generic_param_2() { } "#, expect![[r#" - 32..36 'self': &'? Self + 32..36 'self': &'_ Self 70..71 't': T 76..95 '{ ...d(); }': () 82..83 't': T @@ -1155,12 +1155,12 @@ fn dyn_trait_super_trait_not_in_scope() { } "#, expect![[r#" - 51..55 'self': &'? Self + 51..55 'self': &'_ Self 64..69 '{ 0 }': u32 66..67 '0': u32 - 176..177 'd': &'? (dyn Trait + 'static) + 176..177 'd': &'_ (dyn Trait + 'static) 191..207 '{ ...o(); }': () - 197..198 'd': &'? (dyn Trait + 'static) + 197..198 'd': &'_ (dyn Trait + 'static) 197..204 'd.foo()': u32 "#]], ); @@ -1187,7 +1187,7 @@ fn test() { } "#, expect![[r#" - 75..79 'self': &'? S + 75..79 'self': &'_ S 89..109 '{ ... }': bool 99..103 'true': bool 123..167 '{ ...o(); }': () diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs index 5cc4156e2a4c..361f02db313b 100644 --- a/crates/hir-ty/src/tests/never_type.rs +++ b/crates/hir-ty/src/tests/never_type.rs @@ -364,7 +364,7 @@ fn diverging_expression_3_break() { 151..172 'for a ...eak; }': ! 151..172 'for a ...eak; }': {unknown} 151..172 'for a ...eak; }': &'? mut {unknown} - 151..172 'for a ...eak; }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 151..172 'for a ...eak; }': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 151..172 'for a ...eak; }': Option<<{unknown} as Iterator>::Item> 151..172 'for a ...eak; }': () 151..172 'for a ...eak; }': () @@ -381,7 +381,7 @@ fn diverging_expression_3_break() { 237..250 'for a in b {}': ! 237..250 'for a in b {}': {unknown} 237..250 'for a in b {}': &'? mut {unknown} - 237..250 'for a in b {}': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 237..250 'for a in b {}': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 237..250 'for a in b {}': Option<<{unknown} as Iterator>::Item> 237..250 'for a in b {}': () 237..250 'for a in b {}': () @@ -397,7 +397,7 @@ fn diverging_expression_3_break() { 315..337 'for a ...urn; }': ! 315..337 'for a ...urn; }': {unknown} 315..337 'for a ...urn; }': &'? mut {unknown} - 315..337 'for a ...urn; }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 315..337 'for a ...urn; }': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 315..337 'for a ...urn; }': Option<<{unknown} as Iterator>::Item> 315..337 'for a ...urn; }': () 315..337 'for a ...urn; }': () diff --git a/crates/hir-ty/src/tests/opaque_types.rs b/crates/hir-ty/src/tests/opaque_types.rs index 21d830ed51e3..0503287c2023 100644 --- a/crates/hir-ty/src/tests/opaque_types.rs +++ b/crates/hir-ty/src/tests/opaque_types.rs @@ -204,7 +204,7 @@ impl Miku { 61..72 '{ loop {} }': Vec 63..70 'loop {}': ! 68..70 '{}': () - 133..137 'self': &'? Miku + 133..137 'self': &'_ Miku 152..220 '{ ... }': Miku 162..214 'Miku {... }': Miku 193..201 'Vec::new': fn new<{unknown}>() -> Vec<{unknown}> diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs index a6e864916f40..f728f6af4e20 100644 --- a/crates/hir-ty/src/tests/patterns.rs +++ b/crates/hir-ty/src/tests/patterns.rs @@ -32,13 +32,13 @@ fn infer_pattern() { } "#, expect![[r#" - 8..9 'x': &'? i32 + 8..9 'x': &'_ i32 17..399 '{ ...o_x; }': () 27..28 'y': &'? i32 - 31..32 'x': &'? i32 + 31..32 'x': &'_ i32 42..44 '&z': &'? i32 43..44 'z': i32 - 47..48 'x': &'? i32 + 47..48 'x': &'_ i32 58..59 'a': i32 62..63 'z': i32 73..79 '(c, d)': (i32, &'? str) @@ -50,7 +50,7 @@ fn infer_pattern() { 101..150 'for (e... }': ! 101..150 'for (e... }': IntoIter<(i32, i32), 1> 101..150 'for (e... }': &'? mut IntoIter<(i32, i32), 1> - 101..150 'for (e... }': fn next>(&'? mut IntoIter<(i32, i32), 1>) -> Option< as Iterator>::Item> + 101..150 'for (e... }': fn next>(&'?0.0 mut IntoIter<(i32, i32), 1>) -> Option< as Iterator>::Item> 101..150 'for (e... }': Option<(i32, i32)> 101..150 'for (e... }': () 101..150 'for (e... }': () @@ -95,14 +95,14 @@ fn infer_pattern() { 276..281 'a + b': u64 280..281 'b': u64 283..284 'c': i32 - 297..309 'ref ref_to_x': &'? &'? i32 - 312..313 'x': &'? i32 + 297..309 'ref ref_to_x': &'? &'_ i32 + 312..313 'x': &'_ i32 323..332 'mut mut_x': &'? i32 - 335..336 'x': &'? i32 - 346..366 'ref mu...f_to_x': &'? mut &'? i32 - 369..370 'x': &'? i32 - 380..381 'k': &'? mut &'? i32 - 384..396 'mut_ref_to_x': &'? mut &'? i32 + 335..336 'x': &'_ i32 + 346..366 'ref mu...f_to_x': &'? mut &'_ i32 + 369..370 'x': &'_ i32 + 380..381 'k': &'? mut &'_ i32 + 384..396 'mut_ref_to_x': &'? mut &'_ i32 "#]], ); } @@ -127,7 +127,7 @@ fn infer_literal_pattern() { 17..28 '{ loop {} }': T 19..26 'loop {}': ! 24..26 '{}': () - 37..38 'x': &'? i32 + 37..38 'x': &'_ i32 46..263 '{ ...) {} }': () 52..75 'if let...y() {}': () 55..72 'let "f... any()': bool @@ -394,9 +394,9 @@ fn infer_pattern_match_byte_string_literal() { } "#, expect![[r#" - 105..109 'self': &'? [T; N] + 105..109 'self': &'_ [T; N] 111..116 'index': RangeFull - 157..180 '{ ... }': &'? [u8] + 157..180 '{ ... }': &'_ [u8] 167..174 'loop {}': ! 172..174 '{}': () 191..192 'v': [u8; 3] @@ -705,7 +705,7 @@ fn main() { } "#, expect![[r#" - 27..31 'self': &'? S + 27..31 'self': &'_ S 41..50 '{ false }': bool 43..48 'false': bool 64..115 '{ ... } }': () @@ -777,10 +777,10 @@ fn slice_tail_pattern() { } "#, expect![[r#" - 7..13 'params': &'? [i32] + 7..13 'params': &'_ [i32] 23..92 '{ ... } }': () 29..90 'match ... }': () - 35..41 'params': &'? [i32] + 35..41 'params': &'_ [i32] 52..69 '[head,... @ ..]': [i32] 53..57 'head': &'? i32 59..68 'tail @ ..': &'? [i32] @@ -1338,23 +1338,23 @@ fn foo(v: &Box>) { } "#, expect![[r#" - 142..146 'self': &'? Box - 165..188 '{ ... }': &'? T + 142..146 'self': &'_ Box + 165..188 '{ ... }': &'_ T 175..182 'loop {}': ! 180..182 '{}': () - 310..314 'self': &'? Foo - 333..356 '{ ... }': &'? [T] + 310..314 'self': &'_ Foo + 333..356 '{ ... }': &'_ [T] 343..350 'loop {}': ! 348..350 '{}': () !0..20 'builti...inner)': Foo !0..28 'builti...nner))': Box> !14..19 'inner': &'? [i32] - 399..400 'v': &'? Box> + 399..400 'v': &'_ Box> 418..493 '{ ... } }': () 424..491 'match ... }': () - 430..431 'v': &'? Box> + 430..431 'v': &'_ Box> 467..469 '{}': () - 478..479 '_': &'? Box> + 478..479 '_': &'_ Box> 483..485 '{}': () "#]], ); diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs index e4a08aab9d1f..08450535154b 100644 --- a/crates/hir-ty/src/tests/regression.rs +++ b/crates/hir-ty/src/tests/regression.rs @@ -303,7 +303,7 @@ fn infer_std_crash_5() { 32..320 'for co... }': ! 32..320 'for co... }': {unknown} 32..320 'for co... }': &'? mut {unknown} - 32..320 'for co... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 32..320 'for co... }': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 32..320 'for co... }': Option<<{unknown} as Iterator>::Item> 32..320 'for co... }': () 32..320 'for co... }': () @@ -501,10 +501,10 @@ fn issue_3999_slice() { } "#, expect![[r#" - 7..13 'params': &'? [usize] + 7..13 'params': &'_ [usize] 25..80 '{ ... } }': () 31..78 'match ... }': () - 37..43 'params': &'? [usize] + 37..43 'params': &'_ [usize] 54..66 '[ps @ .., _]': [usize] 55..62 'ps @ ..': &'? [usize] 60..62 '..': [usize] @@ -559,7 +559,7 @@ fn issue_4235_name_conflicts() { "#, expect![[r#" 31..37 'FOO {}': FOO - 63..67 'self': &'? FOO + 63..67 'self': &'_ FOO 69..71 '{}': () 85..119 '{ ...o(); }': () 95..96 'a': &'? FOO @@ -751,12 +751,12 @@ fn issue_4885() { } "#, expect![[r#" - 70..73 'key': &'? K + 70..73 'key': &'_ K 132..148 '{ ...key) }': impl Future>::Bar> - 138..141 'bar': fn bar(&'? K) -> impl Future>::Bar> + 138..141 'bar': fn bar(&'?0.0 K) -> impl Future>::Bar> 138..146 'bar(key)': impl Future>::Bar> - 142..145 'key': &'? K - 162..165 'key': &'? K + 142..145 'key': &'_ K + 162..165 'key': &'_ K 224..227 '{ }': () "#]], ); @@ -807,11 +807,11 @@ fn issue_4800() { } "#, expect![[r#" - 379..383 'self': &'? mut PeerSet + 379..383 'self': &'_ mut PeerSet 401..424 '{ ... }': dyn Future + 'static 411..418 'loop {}': ! 416..418 '{}': () - 575..579 'self': &'? mut Self + 575..579 'self': &'_ mut Self "#]], ); } @@ -891,10 +891,10 @@ fn main() { } "#, expect![[r#" - 86..90 'self': &'? S + 86..90 'self': &'_ S 92..94 '_t': T 99..101 '{}': () - 127..131 'self': &'? S + 127..131 'self': &'_ S 133..135 '_f': F 140..142 '{}': () 155..217 '{ ...10); }': () @@ -904,8 +904,8 @@ fn main() { 171..182 'PhantomData': PhantomData 189..190 's': S 189..201 's.g(|_x| {})': () - 193..200 '|_x| {}': impl FnOnce(&'? i32) - 194..196 '_x': &'? i32 + 193..200 '|_x| {}': impl FnOnce(&'?0.0 i32) + 194..196 '_x': &'_ i32 198..200 '{}': () 207..208 's': S 207..214 's.f(10)': () @@ -938,13 +938,13 @@ fn flush(&self) { } "#, expect![[r#" - 129..133 'self': &'? Mutex + 129..133 'self': &'_ Mutex 156..158 '{}': MutexGuard<'?, T> - 242..246 'self': &'? MutexGuard<'a, T> - 265..276 '{ loop {} }': &'? T + 242..246 'self': &'_ MutexGuard<'a, T> + 265..276 '{ loop {} }': &'_ T 267..274 'loop {}': ! 272..274 '{}': () - 289..293 'self': &'? {unknown} + 289..293 'self': &'_ {unknown} 295..345 '{ ...()); }': () 305..306 'w': &'? Mutex 331..342 '*(w.lock())': BufWriter @@ -1294,7 +1294,7 @@ fn test() { 16..66 'for _ ... }': ! 16..66 'for _ ... }': {unknown} 16..66 'for _ ... }': &'? mut {unknown} - 16..66 'for _ ... }': fn next<{unknown}>(&'? mut {unknown}) -> Option<<{unknown} as Iterator>::Item> + 16..66 'for _ ... }': fn next<{unknown}>(&'?0.0 mut {unknown}) -> Option<<{unknown} as Iterator>::Item> 16..66 'for _ ... }': Option<<{unknown} as Iterator>::Item> 16..66 'for _ ... }': () 16..66 'for _ ... }': () @@ -1689,7 +1689,7 @@ fn dyn_with_unresolved_trait() { r#" fn foo(a: &dyn DoesNotExist) { a.bar(); - //^&'? {unknown} + //^&'_ {unknown} } "#, ); @@ -2229,13 +2229,13 @@ impl<'a, T: Deref> Struct<'a, T> { } "#, expect![[r#" - 137..141 'self': &'? Struct<'a, T> - 152..160 '{ self }': &'? Struct<'a, T> - 154..158 'self': &'? Struct<'a, T> - 174..178 'self': &'? Struct<'a, T> + 137..141 'self': &'_ Struct<'a, T> + 152..160 '{ self }': &'_ Struct<'a, T> + 154..158 'self': &'_ Struct<'a, T> + 174..178 'self': &'_ Struct<'a, T> 180..215 '{ ... }': () 194..195 '_': &'? Struct<'?, T> - 198..202 'self': &'? Struct<'a, T> + 198..202 'self': &'_ Struct<'a, T> 198..208 'self.foo()': &'? Struct<'?, T> "#]], ); @@ -2301,9 +2301,9 @@ fn test(x: bool) { 69..80 '{ loop {} }': Map 71..78 'loop {}': ! 76..78 '{}': () - 93..97 'self': &'? Map - 99..100 '_': &'? T - 120..131 '{ loop {} }': Option<&'? U> + 93..97 'self': &'_ Map + 99..100 '_': &'_ T + 120..131 '{ loop {} }': Option<&'_ U> 122..129 'loop {}': ! 127..129 '{}': () 143..144 'x': bool @@ -2768,24 +2768,24 @@ where } "#, expect![[r#" - 214..223 'filter_fn': dyn Fn(&'? T) -> bool + 'static + 214..223 'filter_fn': dyn Fn(&'_ T) -> bool + 'static 253..360 '{ ... }': Filter<'a, 'b, T> 263..354 'Self {... }': Filter<'a, 'b, T> - 293..302 'filter_fn': dyn Fn(&'? T) -> bool + 'static + 293..302 'filter_fn': dyn Fn(&'_ T) -> bool + 'static 319..323 'None': Option 340..343 '&()': &'? () 341..343 '()': () - 421..425 'self': &'? Self - 427..433 'filter': &'? Filter<'?, '?, T> - 580..584 'self': &'? [T; N] - 586..592 'filter': &'? Filter<'?, '?, T> + 421..425 'self': &'_ Self + 427..433 'filter': &'_ Filter<'_, '_, T> + 580..584 'self': &'_ [T; N] + 586..592 'filter': &'_ Filter<'_, '_, T> 622..704 '{ ... }': T - 636..637 '_': Filter, dyn Fn(&'? T) -> bool + '?> - 640..644 'self': &'? [T; N] + 636..637 '_': Filter, dyn Fn(&'_ T) -> bool + '?> + 640..644 'self': &'_ [T; N] 640..656 'self.i...iter()': Iter<'?, T> - 640..681 'self.i...er_fn)': Filter, dyn Fn(&'? T) -> bool + '?> - 664..670 'filter': &'? Filter<'?, '?, T> - 664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static + 640..681 'self.i...er_fn)': Filter, dyn Fn(&'_ T) -> bool + '?> + 664..670 'filter': &'_ Filter<'_, '_, T> + 664..680 'filter...ter_fn': dyn Fn(&'_ T) -> bool + 'static 691..698 'loop {}': ! 696..698 '{}': () "#]], diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs index 97f83ca0362e..790ae4fdc3b6 100644 --- a/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/crates/hir-ty/src/tests/regression/new_solver.rs @@ -140,7 +140,7 @@ fn test() -> i32 { 155..170 '{ loop {} }': *const T 161..168 'loop {}': ! 166..168 '{}': () - 195..199 'self': &'? Self + 195..199 'self': &'_ Self 208..231 '{ ... }': i32 218..225 'loop {}': ! 223..225 '{}': () @@ -543,7 +543,7 @@ fn test_at_most() { expect![[r#" 48..49 '0': usize 182..186 'self': Between - 188..192 '_sep': &'? str + 188..192 '_sep': &'_ str 200..206 '_other': Between 222..242 '{ ... }': Between 232..236 'self': Between @@ -705,10 +705,10 @@ where } "#, expect![[r#" - 43..47 'self': &'? Self - 168..172 'self': &'? F + 43..47 'self': &'_ Self + 168..172 'self': &'_ F 205..227 '{ ... }': >::CallRefFuture<'?> - 215..219 'self': &'? F + 215..219 'self': &'_ F 215..221 'self()': >::CallRefFuture<'?> "#]], ); @@ -825,12 +825,12 @@ fn main() { } "#, expect![[r#" - 164..168 'self': &'? mut Foo + 164..168 'self': &'_ mut Foo 192..224 '{ ... }': Option - 202..206 'self': &'? mut Foo + 202..206 'self': &'_ mut Foo 202..218 'self.n...spec()': Option - 278..282 'self': &'? mut Self - 380..384 'self': &'? mut Foo + 278..282 'self': &'_ mut Self + 380..384 'self': &'_ mut Foo 408..428 '{ ... }': Option 418..422 'None': Option 501..505 'iter': I @@ -889,10 +889,10 @@ fn test2(factory: T) { } "#, expect![[r#" - 39..43 'self': &'? Self - 101..105 'self': &'? Self - 198..202 'self': &'? Self - 239..243 'self': &'? Self + 39..43 'self': &'_ Self + 101..105 'self': &'_ Self + 198..202 'self': &'_ Self + 239..243 'self': &'_ Self 290..293 'foo': impl Foo + ?Sized 325..359 '{ ...z(); }': () 335..338 'baz': u8 diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs index 3cdfe4edcb90..0872d2bb5884 100644 --- a/crates/hir-ty/src/tests/simple.rs +++ b/crates/hir-ty/src/tests/simple.rs @@ -134,12 +134,12 @@ fn test(a: u32, b: isize, c: !, d: &str) { 8..9 'a': u32 16..17 'b': isize 26..27 'c': ! - 32..33 'd': &'? str + 32..33 'd': &'_ str 41..120 '{ ...f32; }': ! 47..48 'a': u32 54..55 'b': isize 61..62 'c': ! - 68..69 'd': &'? str + 68..69 'd': &'_ str 75..81 '1usize': usize 87..93 '1isize': isize 99..105 '"test"': &'static str @@ -363,23 +363,23 @@ fn test(a: &u32, b: &mut u32, c: *const u32, d: *mut u32) { } "#, expect![[r#" - 8..9 'a': &'? u32 - 17..18 'b': &'? mut u32 + 8..9 'a': &'_ u32 + 17..18 'b': &'_ mut u32 30..31 'c': *const u32 45..46 'd': *mut u32 58..149 '{ ... *d; }': () - 64..65 'a': &'? u32 + 64..65 'a': &'_ u32 71..73 '*a': u32 - 72..73 'a': &'? u32 - 79..81 '&a': &'? &'? u32 - 80..81 'a': &'? u32 - 87..93 '&mut a': &'? mut &'? u32 - 92..93 'a': &'? u32 - 99..100 'b': &'? mut u32 + 72..73 'a': &'_ u32 + 79..81 '&a': &'? &'_ u32 + 80..81 'a': &'_ u32 + 87..93 '&mut a': &'? mut &'_ u32 + 92..93 'a': &'_ u32 + 99..100 'b': &'_ mut u32 106..108 '*b': u32 - 107..108 'b': &'? mut u32 - 114..116 '&b': &'? &'? mut u32 - 115..116 'b': &'? mut u32 + 107..108 'b': &'_ mut u32 + 114..116 '&b': &'? &'_ mut u32 + 115..116 'b': &'_ mut u32 122..123 'c': *const u32 129..131 '*c': u32 130..131 'c': *const u32 @@ -602,12 +602,12 @@ impl S { } "#, expect![[r#" - 33..37 'self': &'? S + 33..37 'self': &'_ S 39..60 '{ ... }': () - 49..53 'self': &'? S - 74..78 'self': &'? S + 49..53 'self': &'_ S + 74..78 'self': &'_ S 87..108 '{ ... }': () - 97..101 'self': &'? S + 97..101 'self': &'_ S 132..152 '{ ... }': S 142..146 'S {}': S 176..199 '{ ... }': S @@ -870,19 +870,19 @@ fn test() { } "#, expect![[r#" - 66..70 'self': &'? A - 78..101 '{ ... }': &'? T + 66..70 'self': &'_ A + 78..101 '{ ... }': &'_ T 88..95 '&self.0': &'? T - 89..93 'self': &'? A + 89..93 'self': &'_ A 89..95 'self.0': T - 182..186 'self': &'? B - 205..228 '{ ... }': &'? T + 182..186 'self': &'_ B + 205..228 '{ ... }': &'_ T 215..222 '&self.0': &'? T - 216..220 'self': &'? B + 216..220 'self': &'_ B 216..222 'self.0': T 242..280 '{ ...))); }': () 252..253 't': &'? i32 - 256..262 'A::foo': fn foo(&'? A) -> &'? i32 + 256..262 'A::foo': fn foo(&'?0.0 A) -> &'?0.0 i32 256..277 'A::foo...42))))': &'? i32 263..276 '&&B(B(A(42)))': &'? &'? B>> 264..276 '&B(B(A(42)))': &'? B>> @@ -925,17 +925,17 @@ fn test(a: A) { } "#, expect![[r#" - 71..75 'self': &'? A - 77..78 'x': &'? A - 93..114 '{ ... }': &'? T + 71..75 'self': &'_ A + 77..78 'x': &'_ A + 93..114 '{ ... }': &'_ T 103..108 '&*x.0': &'? T 104..108 '*x.0': T - 105..106 'x': &'? A + 105..106 'x': &'_ A 105..108 'x.0': *mut T - 195..199 'self': &'? B - 218..241 '{ ... }': &'? T + 195..199 'self': &'_ B + 218..241 '{ ... }': &'_ T 228..235 '&self.0': &'? T - 229..233 'self': &'? B + 229..233 'self': &'_ B 229..235 'self.0': T 253..254 'a': A 264..310 '{ ...))); }': () @@ -1074,7 +1074,7 @@ fn infer_inherent_method() { 31..35 'self': A 37..38 'x': u32 52..54 '{}': i32 - 106..110 'self': &'? A + 106..110 'self': &'_ A 112..113 'x': u64 127..129 '{}': i64 147..148 'a': A @@ -1109,7 +1109,7 @@ fn test() { } "#, expect![[r#" - 67..71 'self': &'? str + 67..71 'self': &'_ str 80..82 '{}': i32 96..116 '{ ...o(); }': () 102..107 '"foo"': &'static str @@ -1132,7 +1132,7 @@ fn infer_tuple() { } "#, expect![[r#" - 8..9 'x': &'? str + 8..9 'x': &'_ str 17..18 'y': isize 27..169 '{ ...d"); }': () 37..38 'a': (u32, &'? str) @@ -1142,15 +1142,15 @@ fn infer_tuple() { 72..73 'b': ((u32, &'? str), &'? str) 76..82 '(a, x)': ((u32, &'? str), &'? str) 77..78 'a': (u32, &'? str) - 80..81 'x': &'? str + 80..81 'x': &'_ str 92..93 'c': (isize, &'? str) 96..102 '(y, x)': (isize, &'? str) 97..98 'y': isize - 100..101 'x': &'? str + 100..101 'x': &'_ str 112..113 'd': ((isize, &'? str), &'? str) 116..122 '(c, x)': ((isize, &'? str), &'? str) 117..118 'c': (isize, &'? str) - 120..121 'x': &'? str + 120..121 'x': &'_ str 132..133 'e': (i32, &'? str) 136..144 '(1, "e")': (i32, &'? str) 137..138 '1': i32 @@ -1187,12 +1187,12 @@ fn infer_array() { } "#, expect![[r#" - 8..9 'x': &'? str + 8..9 'x': &'_ str 17..18 'y': isize 27..326 '{ ...,4]; }': () 37..38 'a': [&'? str; 1] 41..44 '[x]': [&'? str; 1] - 42..43 'x': &'? str + 42..43 'x': &'_ str 54..55 'b': [[&'? str; 1]; 2] 58..64 '[a, a]': [[&'? str; 1]; 2] 59..60 'a': [&'? str; 1] @@ -1439,7 +1439,7 @@ fn infer_impl_generics_with_autoderef() { } "#, expect![[r#" - 77..81 'self': &'? Option + 77..81 'self': &'_ Option 97..99 '{}': Option<&'? T> 110..111 'o': Option 126..164 '{ ...f(); }': () @@ -1585,16 +1585,16 @@ fn infer_type_alias() { "#, expect![[r#" 115..116 'x': A - 123..124 'y': A<&'? str, u128> + 123..124 'y': A<&'_ str, u128> 137..138 'z': A 153..210 '{ ...z.y; }': () 159..160 'x': A 159..162 'x.x': u32 168..169 'x': A 168..171 'x.y': i128 - 177..178 'y': A<&'? str, u128> - 177..180 'y.x': &'? str - 186..187 'y': A<&'? str, u128> + 177..178 'y': A<&'_ str, u128> + 177..180 'y.x': &'_ str + 186..187 'y': A<&'_ str, u128> 186..189 'y.y': u128 195..196 'z': A 195..198 'z.x': u8 @@ -1652,10 +1652,10 @@ fn infer_type_param() { 9..10 'x': T 20..29 '{ x }': T 26..27 'x': T - 43..44 'x': &'? T + 43..44 'x': &'_ T 55..65 '{ *x }': T 61..63 '*x': T - 62..63 'x': &'? T + 62..63 'x': &'_ T 77..157 '{ ...(1); }': () 87..88 'y': u32 91..96 '10u32': u32 @@ -1663,7 +1663,7 @@ fn infer_type_param() { 102..107 'id(y)': u32 105..106 'y': u32 117..118 'x': bool - 127..132 'clone': fn clone(&'? bool) -> bool + 127..132 'clone': fn clone(&'?0.0 bool) -> bool 127..135 'clone(z)': bool 133..134 'z': &'? bool 141..151 'id::': fn id(i128) -> i128 @@ -2110,7 +2110,7 @@ fn test(mut cx: Context<'_>) { } "#, expect![[r#" - 91..97 'mut cx': Context<'?> + 91..97 'mut cx': Context<'_> 112..239 '{ ...cx); }': () 122..135 'mut generator': impl AsyncIterator 138..174 'async ... }': impl AsyncIterator @@ -2122,8 +2122,8 @@ fn test(mut cx: Context<'_>) { 193..236 'Pin::n...ut cx)': Poll> 202..216 '&mut generator': &'? mut impl AsyncIterator 207..216 'generator': impl AsyncIterator - 228..235 '&mut cx': &'? mut Context<'?> - 233..235 'cx': Context<'?> + 228..235 '&mut cx': &'? mut Context<'_> + 233..235 'cx': Context<'_> "#]], ); } @@ -2181,7 +2181,7 @@ fn test(mut cx: Context<'_>) { 103..120 '{ ... (); }': () 109..117 'yield ()': () 115..117 '()': () - 130..136 'mut cx': Context<'?> + 130..136 'mut cx': Context<'_> 151..248 '{ ...cx); }': () 161..174 'mut generator': impl AsyncIterator 177..181 'html': fn html() -> impl AsyncIterator @@ -2192,8 +2192,8 @@ fn test(mut cx: Context<'_>) { 202..245 'Pin::n...ut cx)': Poll> 211..225 '&mut generator': &'? mut impl AsyncIterator 216..225 'generator': impl AsyncIterator - 237..244 '&mut cx': &'? mut Context<'?> - 242..244 'cx': Context<'?> + 237..244 '&mut cx': &'? mut Context<'_> + 242..244 'cx': Context<'_> "#]], ); } @@ -3260,7 +3260,7 @@ fn main() { } "#, expect![[r#" - 104..108 'self': &'? Box + 104..108 'self': &'_ Box 188..192 'self': &'_ Box> 218..220 '{}': &'? T 242..246 'self': &'_ Box> @@ -3732,14 +3732,14 @@ fn f(t: Ark) { } "#, expect![[r#" - 47..51 'self': &'? Ark + 47..51 'self': &'_ Ark 65..88 '{ ... }': *const T 75..82 '&self.0': &'? T - 76..80 'self': &'? Ark + 76..80 'self': &'_ Ark 76..82 'self.0': T 99..100 't': Ark 110..144 '{ ... (); }': () - 116..124 'Ark::foo': fn foo(&'? Ark) -> *const T + 116..124 'Ark::foo': fn foo(&'?0.0 Ark) -> *const T 116..128 'Ark::foo(&t)': *const T 116..141 'Ark::f...nst ()': *const () 125..127 '&t': &'? Ark @@ -4099,13 +4099,13 @@ fn foo() { expect![[r#" 22..29 '{ 123 }': i32 24..27 '123': i32 - 37..38 's': &'? str + 37..38 's': &'_ str 46..48 '{}': () !0..68 'builti...");},)': () !40..43 'bar': fn bar() -> i32 !40..45 'bar()': i32 !51..66 '{baz("hello");}': () - !52..55 'baz': fn baz(&'? str) + !52..55 'baz': fn baz(&'?0.0 str) !52..64 'baz("hello")': () !56..63 '"hello"': &'static str 59..257 '{ ... } }': () @@ -4189,15 +4189,15 @@ fn foo() { 73..96 '{ ... }': LazyLock 83..90 'loop {}': ! 88..90 '{}': () - 111..115 'this': &'? LazyLock - 130..153 '{ ... }': &'? T + 111..115 'this': &'_ LazyLock + 130..153 '{ ... }': &'_ T 140..147 'loop {}': ! 145..147 '{}': () 207..220 'LazyLock::new': fn new<[u32; 0]>() -> LazyLock<[u32; 0]> 207..222 'LazyLock::new()': LazyLock<[u32; 0]> 234..285 '{ ...CK); }': () 244..245 '_': &'? [u32; 0] - 248..263 'LazyLock::force': fn force<[u32; 0]>(&'? LazyLock<[u32; 0]>) -> &'? [u32; 0] + 248..263 'LazyLock::force': fn force<[u32; 0]>(&'?0.0 LazyLock<[u32; 0]>) -> &'?0.0 [u32; 0] 248..282 'LazyLo..._LOCK)': &'? [u32; 0] 264..281 '&VALUE...Y_LOCK': &'? LazyLock<[u32; 0]> 265..281 'VALUES...Y_LOCK': LazyLock<[u32; 0]> diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs index fad944589dab..6f124bfa7fbb 100644 --- a/crates/hir-ty/src/tests/traits.rs +++ b/crates/hir-ty/src/tests/traits.rs @@ -1022,15 +1022,15 @@ fn test(x: impl Trait, y: &impl Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &'? Self - 54..58 'self': &'? Self + 29..33 'self': &'_ Self + 54..58 'self': &'_ Self 77..78 'x': impl Trait 97..99 '{}': () 154..155 'x': impl Trait - 174..175 'y': &'? impl Trait + 174..175 'y': &'_ impl Trait 195..323 '{ ...2(); }': () 201..202 'x': impl Trait - 208..209 'y': &'? impl Trait + 208..209 'y': &'_ impl Trait 219..220 'z': S 223..224 'S': fn S(u16) -> S 223..227 'S(1)': S @@ -1040,13 +1040,13 @@ fn test(x: impl Trait, y: &impl Trait) { 237..238 'z': S 245..246 'x': impl Trait 245..252 'x.foo()': u64 - 258..259 'y': &'? impl Trait + 258..259 'y': &'_ impl Trait 258..265 'y.foo()': u32 271..272 'z': S 271..278 'z.foo()': u16 284..285 'x': impl Trait 284..292 'x.foo2()': i64 - 298..299 'y': &'? impl Trait + 298..299 'y': &'_ impl Trait 298..306 'y.foo2()': i64 312..313 'z': S 312..320 'z.foo2()': i64 @@ -1220,26 +1220,26 @@ fn test(x: impl Trait, y: &impl Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &'? Self - 54..58 'self': &'? Self + 29..33 'self': &'_ Self + 54..58 'self': &'_ Self 98..100 '{}': () 110..111 'x': impl Trait - 130..131 'y': &'? impl Trait + 130..131 'y': &'_ impl Trait 151..268 '{ ...2(); }': () 157..158 'x': impl Trait - 164..165 'y': &'? impl Trait + 164..165 'y': &'_ impl Trait 175..176 'z': impl Trait 179..182 'bar': fn bar() -> impl Trait 179..184 'bar()': impl Trait 190..191 'x': impl Trait 190..197 'x.foo()': u64 - 203..204 'y': &'? impl Trait + 203..204 'y': &'_ impl Trait 203..210 'y.foo()': u64 216..217 'z': impl Trait 216..223 'z.foo()': u64 229..230 'x': impl Trait 229..237 'x.foo2()': i64 - 243..244 'y': &'? impl Trait + 243..244 'y': &'_ impl Trait 243..251 'y.foo2()': i64 257..258 'z': impl Trait 257..265 'z.foo2()': i64 @@ -1344,7 +1344,7 @@ fn test() { a.foo(); }"#, expect![[r#" - 29..33 'self': &'? Self + 29..33 'self': &'_ Self 71..82 '{ loop {} }': ! 73..80 'loop {}': ! 78..80 '{}': () @@ -1382,8 +1382,8 @@ fn test() { d.foo(); }"#, expect![[r#" - 49..53 'self': &'? mut Self - 101..105 'self': &'? Self + 49..53 'self': &'_ mut Self + 101..105 'self': &'_ Self 184..195 '{ loop {} }': (impl Iterator>, impl Trait) 186..193 'loop {}': ! 191..193 '{}': () @@ -1430,10 +1430,10 @@ fn foo() -> (impl FnOnce(&str, T), impl Trait) { } "#, expect![[r#" - 134..165 '{ ...(C)) }': (impl FnOnce(&'? str, T), impl Trait) - 140..163 '(|inpu...ar(C))': (impl FnOnce(&'? str, T), Bar) - 141..154 '|input, t| {}': impl FnOnce(&'? str, T) - 142..147 'input': &'? str + 134..165 '{ ...(C)) }': (impl FnOnce(&'?0.0 str, T), impl Trait) + 140..163 '(|inpu...ar(C))': (impl FnOnce(&'?0.0 str, T), Bar) + 141..154 '|input, t| {}': impl FnOnce(&'?0.0 str, T) + 142..147 'input': &'_ str 149..150 't': T 152..154 '{}': () 156..159 'Bar': fn Bar(u8) -> Bar @@ -1488,26 +1488,26 @@ fn test(x: Box>, y: &dyn Trait) { z.foo2(); }"#, expect![[r#" - 29..33 'self': &'? Self - 54..58 'self': &'? Self + 29..33 'self': &'_ Self + 54..58 'self': &'_ Self 206..208 '{}': Box + '?> 218..219 'x': Box + 'static> - 242..243 'y': &'? (dyn Trait + 'static) + 242..243 'y': &'_ (dyn Trait + 'static) 262..379 '{ ...2(); }': () 268..269 'x': Box + 'static> - 275..276 'y': &'? (dyn Trait + 'static) + 275..276 'y': &'_ (dyn Trait + 'static) 286..287 'z': Box + '?> 290..293 'bar': fn bar() -> Box + 'static> 290..295 'bar()': Box + 'static> 301..302 'x': Box + 'static> 301..308 'x.foo()': u64 - 314..315 'y': &'? (dyn Trait + 'static) + 314..315 'y': &'_ (dyn Trait + 'static) 314..321 'y.foo()': u64 327..328 'z': Box + '?> 327..334 'z.foo()': u64 340..341 'x': Box + 'static> 340..348 'x.foo2()': i64 - 354..355 'y': &'? (dyn Trait + 'static) + 354..355 'y': &'_ (dyn Trait + 'static) 354..362 'y.foo2()': i64 368..369 'z': Box + '?> 368..376 'z.foo2()': i64 @@ -1536,12 +1536,12 @@ fn test(s: S) { s.bar().baz(); }"#, expect![[r#" - 32..36 'self': &'? Self - 106..110 'self': &'? S - 132..143 '{ loop {} }': &'? (dyn Trait + 'static) + 32..36 'self': &'_ Self + 106..110 'self': &'_ S + 132..143 '{ loop {} }': &'_ (dyn Trait + 'static) 134..141 'loop {}': ! 139..141 '{}': () - 179..183 'self': &'? Self + 179..183 'self': &'_ Self 255..256 's': S 271..293 '{ ...z(); }': () 277..278 's': S @@ -1570,19 +1570,19 @@ fn test(x: Trait, y: &Trait) -> u64 { z.foo(); }"#, expect![[r#" - 26..30 'self': &'? Self + 26..30 'self': &'_ Self 60..62 '{}': dyn Trait + '? 72..73 'x': dyn Trait + 'static - 82..83 'y': &'? (dyn Trait + 'static) + 82..83 'y': &'_ (dyn Trait + 'static) 100..175 '{ ...o(); }': u64 106..107 'x': dyn Trait + 'static - 113..114 'y': &'? (dyn Trait + 'static) + 113..114 'y': &'_ (dyn Trait + 'static) 124..125 'z': dyn Trait + '? 128..131 'bar': fn bar() -> dyn Trait + 'static 128..133 'bar()': dyn Trait + 'static 139..140 'x': dyn Trait + 'static 139..146 'x.foo()': u64 - 152..153 'y': &'? (dyn Trait + 'static) + 152..153 'y': &'_ (dyn Trait + 'static) 152..159 'y.foo()': u64 165..166 'z': dyn Trait + '? 165..172 'z.foo()': u64 @@ -1602,12 +1602,12 @@ fn main() { } "#, expect![[r#" - 31..35 'self': &'? S + 31..35 'self': &'_ S 37..39 '{}': () - 47..48 '_': &'? (dyn Fn(S) + 'static) + 47..48 '_': &'_ (dyn Fn(S) + 'static) 58..60 '{}': () 71..105 '{ ...()); }': () - 77..78 'f': fn f(&'? (dyn Fn(S) + 'static)) + 77..78 'f': fn f(&'?0.0 (dyn Fn(S) + 'static)) 77..102 'f(&|nu...foo())': () 79..101 '&|numb....foo()': &'? impl Fn(S) 80..101 '|numbe....foo()': impl Fn(S) @@ -1843,7 +1843,7 @@ fn test(x: T, y: U) { y.foo(); }"#, expect![[r#" - 53..57 'self': &'? Self + 53..57 'self': &'_ Self 66..68 '{}': u32 185..186 'x': T 191..192 'y': U @@ -1872,11 +1872,11 @@ fn test(x: &impl Trait1) { x.foo(); }"#, expect![[r#" - 53..57 'self': &'? Self + 53..57 'self': &'_ Self 66..68 '{}': u32 - 119..120 'x': &'? impl Trait1 + 119..120 'x': &'_ impl Trait1 136..152 '{ ...o(); }': () - 142..143 'x': &'? impl Trait1 + 142..143 'x': &'_ impl Trait1 142..149 'x.foo()': u32 "#]], ); @@ -1992,8 +1992,8 @@ fn test() { opt.map(f); }"#, expect![[r#" - 28..32 'self': &'? Self - 132..136 'self': &'? Bar + 28..32 'self': &'_ Self + 132..136 'self': &'_ Bar 149..160 '{ loop {} }': (A1, R) 151..158 'loop {}': ! 156..158 '{}': () @@ -2046,7 +2046,7 @@ fn make_foo_fn() -> Foo {} let r2 = lazy2.foo(); }"#, expect![[r#" - 36..40 'self': &'? Foo + 36..40 'self': &'_ Foo 51..53 '{}': usize 134..135 'f': F 154..156 '{}': Lazy @@ -2354,14 +2354,14 @@ impl Trait for S2 { fn f(&self, x: ::Item) { let y = x; } }"#, expect![[r#" - 40..44 'self': &'? Self + 40..44 'self': &'_ Self 46..47 'x': ::Item - 126..130 'self': &'? S + 126..130 'self': &'_ S 132..133 'x': u32 147..161 '{ let y = x; }': () 153..154 'y': u32 157..158 'x': u32 - 228..232 'self': &'? S2 + 228..232 'self': &'_ S2 234..235 'x': i32 251..265 '{ let y = x; }': () 257..258 'y': i32 @@ -2738,12 +2738,12 @@ fn main() { 72..74 '_v': F 117..120 '{ }': () 132..163 '{ ... }); }': () - 138..148 'f::<(), _>': fn f<(), impl FnOnce(&'? ())>(impl FnOnce(&'? ())) + 138..148 'f::<(), _>': fn f<(), impl FnOnce(&'?0.0 ())>(impl FnOnce(&'?0.0 ())) 138..160 'f::<()... z; })': () - 149..159 '|z| { z; }': impl FnOnce(&'? ()) - 150..151 'z': &'? () + 149..159 '|z| { z; }': impl FnOnce(&'?0.0 ()) + 150..151 'z': &'_ () 153..159 '{ z; }': () - 155..156 'z': &'? () + 155..156 'z': &'_ () "#]], ); } @@ -2992,13 +2992,13 @@ fn test(x: &dyn Foo) { foo(x); }"#, expect![[r#" - 21..22 'x': &'? (dyn Foo + 'static) + 21..22 'x': &'_ (dyn Foo + 'static) 34..36 '{}': () - 46..47 'x': &'? (dyn Foo + 'static) + 46..47 'x': &'_ (dyn Foo + 'static) 59..74 '{ foo(x); }': () - 65..68 'foo': fn foo(&'? (dyn Foo + 'static)) + 65..68 'foo': fn foo(&'?0.0 (dyn Foo + 'static)) 65..71 'foo(x)': () - 69..70 'x': &'? (dyn Foo + 'static) + 69..70 'x': &'_ (dyn Foo + 'static) "#]], ); } @@ -3022,7 +3022,7 @@ fn test() { (IsCopy, NotCopy).test(); }"#, expect![[r#" - 78..82 'self': &'? Self + 78..82 'self': &'_ Self 134..235 '{ ...t(); }': () 140..146 'IsCopy': IsCopy 140..153 'IsCopy.test()': bool @@ -3064,7 +3064,7 @@ fn test() { 28..29 'T': {unknown} 36..38 '{}': T 36..38: expected T, got () - 113..117 'self': &'? Self + 113..117 'self': &'_ Self 169..249 '{ ...t(); }': () 175..178 'foo': fn foo() 175..185 'foo.test()': bool @@ -3092,7 +3092,7 @@ fn test(f1: fn(), f2: fn(usize) -> u8, f3: fn(u8, u8) -> &u8) { f3.test(); }"#, expect![[r#" - 22..26 'self': &'? Self + 22..26 'self': &'_ Self 76..78 'f1': fn() 86..88 'f2': fn(usize) -> u8 107..109 'f3': fn(u8, u8) -> &'? u8 @@ -3122,7 +3122,7 @@ fn test() { (1u8, *"foo").test(); // not Sized }"#, expect![[r#" - 22..26 'self': &'? Self + 22..26 'self': &'_ Self 79..194 '{ ...ized }': () 85..88 '1u8': u8 85..95 '1u8.test()': bool @@ -3265,23 +3265,23 @@ fn foo() { f(&s); }"#, expect![[r#" - 154..158 'self': &'? Box - 166..205 '{ ... }': &'? T - 176..199 'unsafe...nner }': &'? T + 154..158 'self': &'_ Box + 166..205 '{ ... }': &'_ T + 176..199 'unsafe...nner }': &'_ T 185..197 '&*self.inner': &'? T 186..197 '*self.inner': T - 187..191 'self': &'? Box + 187..191 'self': &'_ Box 187..197 'self.inner': *mut T 218..324 '{ ...&s); }': () 228..229 's': Option 232..236 'None': Option - 246..247 'f': Box) + 'static> - 281..310 'Box { ... {}) }': Box) + 'static> - 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'? Option) - 300..307 '|ps| {}': impl FnOnce(&'? Option) - 301..303 'ps': &'? Option + 246..247 'f': Box) + 'static> + 281..310 'Box { ... {}) }': Box) + 'static> + 294..308 '&mut (|ps| {})': &'? mut impl FnOnce(&'_ Option) + 300..307 '|ps| {}': impl FnOnce(&'_ Option) + 301..303 'ps': &'_ Option 305..307 '{}': () - 316..317 'f': Box) + 'static> + 316..317 'f': Box) + 'static> 316..321 'f(&s)': () 318..320 '&s': &'? Option 319..320 's': Option @@ -3415,7 +3415,7 @@ fn f() { } }"#, expect![[r#" - 46..50 'self': &'? Self + 46..50 'self': &'_ Self 58..63 '{ 0 }': u8 60..61 '0': u8 115..185 '{ ... } }': () @@ -3779,11 +3779,11 @@ fn main() { } "#, expect![[r#" - 44..48 'self': &'? Self - 133..137 'self': &'? [u8; 4] + 44..48 'self': &'_ Self + 133..137 'self': &'_ [u8; 4] 155..172 '{ ... }': usize 165..166 '2': usize - 236..240 'self': &'? [u8; 2] + 236..240 'self': &'_ [u8; 2] 258..275 '{ ... }': u8 268..269 '2': u8 289..392 '{ ...g(); }': () @@ -3827,11 +3827,11 @@ fn main() { } "#, expect![[r#" - 44..48 'self': &'? Self - 151..155 'self': &'? [u8; L] + 44..48 'self': &'_ Self + 151..155 'self': &'_ [u8; L] 173..194 '{ ... }': [u8; L] 183..188 '*self': [u8; L] - 184..188 'self': &'? [u8; L] + 184..188 'self': &'_ [u8; L] 208..260 '{ ...g(); }': () 218..219 'v': [u8; 2] 222..230 '[0u8; 2]': [u8; 2] @@ -4151,13 +4151,13 @@ fn g(t: &(dyn Sync + T2 + T1 + Send)) { } "#, expect![[r#" - 68..69 't': &'? {unknown} + 68..69 't': &'_ {unknown} 101..103 '{}': () - 109..110 't': &'? {unknown} + 109..110 't': &'_ {unknown} 142..155 '{ f(t); }': () - 148..149 'f': fn f(&'? {unknown}) + 148..149 'f': fn f(&'?0.0 {unknown}) 148..152 'f(t)': () - 150..151 't': &'? {unknown} + 150..151 't': &'_ {unknown} "#]], ); @@ -4200,7 +4200,7 @@ trait Trait { } fn f(t: &dyn Trait) {} - //^&'? (dyn Trait + 'static) + //^&'_ (dyn Trait + 'static) "#, ); } @@ -4316,10 +4316,10 @@ fn f<'a>(v: &dyn Trait = &'a i32>) { } "#, expect![[r#" - 90..94 'self': &'? Self - 127..128 'v': &'? (dyn Trait = &'_ i32> + 'static) + 90..94 'self': &'_ Self + 127..128 'v': &'_ (dyn Trait = &'_ i32> + 'static) 164..195 '{ ...f(); }': () - 170..171 'v': &'? (dyn Trait = &'_ i32> + 'static) + 170..171 'v': &'_ (dyn Trait = &'_ i32> + 'static) 170..184 'v.get::()': <{unknown} as Trait>::Assoc 170..192 'v.get:...eref()': {unknown} "#]], @@ -4861,11 +4861,11 @@ fn allowed3(baz: impl Baz>) {} 184..185 'f': impl Fn({unknown}) 184..190 'f(foo)': () 186..189 'foo': S - 251..252 'f': impl Fn(&'? {unknown}) + 251..252 'f': impl Fn(&'?0.0 {unknown}) 274..307 '{ ...oo); }': () 284..287 'foo': S 290..291 'S': S - 297..298 'f': impl Fn(&'? {unknown}) + 297..298 'f': impl Fn(&'?0.0 {unknown}) 297..304 'f(&foo)': () 299..303 '&foo': &'? S 300..303 'foo': S @@ -5068,8 +5068,8 @@ fn main() { } "#, expect![[r#" - 147..151 'self': &'? AnyhowError - 170..181 '{ loop {} }': &'? (dyn Error + Send + Sync + 'static) + 147..151 'self': &'_ AnyhowError + 170..181 '{ loop {} }': &'_ (dyn Error + Send + Sync + 'static) 172..179 'loop {}': ! 177..179 '{}': () 223..227 'self': AnyhowError @@ -5107,7 +5107,7 @@ fn main() { 290..291 '_': Box + '?> 294..298 'iter': Box + 'static> 294..310 'iter.i...iter()': Box + '?> - 152..156 'self': &'? mut Box + 152..156 'self': &'_ mut Box 177..208 '{ ... }': Option<::Item> 191..198 'loop {}': ! 196..198 '{}': () @@ -5372,7 +5372,7 @@ impl<'a, 'b> Trait<'a, 'b> for Foo {} fn run_dyn<'b>(val: &dyn for<'a> Trait<'a, 'b>) {} "#, expect![[r#" - 91..94 'val': &'? (dyn Trait<'_, '_> + 'static) + 91..94 'val': &'_ (dyn Trait<'_, '_> + 'static) 124..126 '{}': () "#]], ); diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index 269029728398..2efdaa03cc60 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -592,8 +592,8 @@ struct TestBox+Setter> { //~ ERROR [U: *, T: +] } "#, expect![[r#" - get[Self: contravariant, T: covariant] - get[Self: contravariant, T: contravariant] + get[Self: contravariant, T: covariant, '_: invariant] + get[Self: contravariant, T: contravariant, '_: invariant] TestStruct[U: covariant, T: covariant] TestEnum[U: bivariant, T: covariant] TestContraStruct[U: bivariant, T: covariant] @@ -628,10 +628,10 @@ fn pick<'b, G>(get: &'b G, if_odd: &'b i32) -> i32 {} "#, expect![[r#" - get[Self: contravariant, T: covariant] + get[Self: contravariant, T: covariant, '_: invariant] Cloner[T: covariant] - get[T: invariant] - get['a: invariant, G: contravariant] + get[T: invariant, '_: invariant] + get['a: invariant, G: contravariant, '_: invariant] pick['b: contravariant, G: contravariant] "#]], ); @@ -653,7 +653,7 @@ struct TOption<'a> { //~ ERROR ['a: +] "#, expect![[r#" Option[T: covariant] - foo[Self: contravariant] + foo[Self: contravariant, '_: invariant] TOption['a: covariant] "#]], ); @@ -701,8 +701,8 @@ struct TestObject { //~ ERROR [A: o, R: o] TestMut[A: covariant, B: invariant] TestIndirect[A: covariant, B: invariant] TestIndirect2[A: invariant, B: invariant] - get[Self: contravariant, A: covariant] - set[Self: invariant, A: contravariant] + get[Self: contravariant, A: covariant, '_: invariant] + set[Self: invariant, A: contravariant, '_: invariant] TestObject[A: invariant, R: invariant] "#]], ); @@ -719,7 +719,7 @@ trait SomeTrait<'a> { fn foo(&self); } // OK on traits. expect![[r#" SomeStruct['a: bivariant] SomeEnum['a: bivariant] - foo[Self: contravariant, 'a: invariant] + foo[Self: contravariant, 'a: invariant, '_: invariant] "#]], ); } @@ -948,7 +948,7 @@ struct FixedPoint(&'static FixedPoint<(), T, U>, V); res, "{name}[{}]\n", generics(&db, def) - .iter(false) + .iter(true) .map(|(_, param)| match param { GenericParamDataRef::TypeParamData(type_param_data) => { type_param_data.name.as_ref().unwrap() diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 61eda80fb487..c76b42caec79 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -327,7 +327,9 @@ impl<'db> HirDisplay<'db> for SelfParam { TypeRef::Reference(ref_) if matches!(&data.store[ref_.ty], TypeRef::Path(p) if p.is_self_type()) => { f.write_char('&')?; - if let Some(lifetime) = &ref_.lifetime { + if let Some(lifetime) = &ref_.lifetime + && !data.store[*lifetime].is_elided(f.db) + { lifetime.hir_fmt(f, owner, &data.store)?; f.write_char(' ')?; } @@ -704,7 +706,7 @@ fn write_generic_params_or_args<'db>( ) -> Result { let (params, store) = GenericParams::with_store(f.db, def); let owner = def.into(); - if params.iter_lt().next().is_none() + if params.iter_lt().all(|it| it.1.is_elided()) && params.iter_type_or_consts().all(|it| it.1.const_param().is_none()) && params .iter_type_or_consts() @@ -725,6 +727,9 @@ fn write_generic_params_or_args<'db>( } }; for (_, lifetime) in params.iter_lt() { + if lifetime.is_elided() { + continue; + } delim(f)?; write!(f, "{}", lifetime.name.display(f.db, f.edition()))?; } diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 70e2d3faf160..ea35b6886c0e 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2927,11 +2927,8 @@ impl Const { pub fn eval(self, db: &dyn HirDatabase) -> Result, ConstEvalError<'_>> { let interner = DbInterner::new_no_crate(db); let ty = db.value_ty(self.id.into()).unwrap().instantiate_identity().skip_norm_wip(); - db.const_eval(self.id, GenericArgs::empty(interner), None).map(|it| EvaluatedConst { - allocation: it, - def: self.id.into(), - ty, - }) + db.const_eval(self.id, GenericArgs::identity_for_item(interner, self.id.into()), None) + .map(|it| EvaluatedConst { allocation: it, def: self.id.into(), ty }) } } @@ -4534,6 +4531,10 @@ impl LifetimeParam { params[self.id.local_id].name.clone() } + pub fn is_elided(self, db: &dyn HirDatabase) -> bool { + self.name(db).is_anon_lifetime() + } + pub fn module(self, db: &dyn HirDatabase) -> Module { self.id.parent.module(db).into() } diff --git a/crates/hir/src/term_search/tactics.rs b/crates/hir/src/term_search/tactics.rs index d6d432ab7816..c7ec1388066e 100644 --- a/crates/hir/src/term_search/tactics.rs +++ b/crates/hir/src/term_search/tactics.rs @@ -325,11 +325,6 @@ pub(super) fn free_function<'a, 'lt, 'db, DB: HirDatabase>( .map(|it| it.as_type_param(db)) .collect::>>()?; - // Ignore lifetimes as we do not check them - if !generics.lifetime_params(db).is_empty() { - return None; - } - // Only account for stable type parameters for now, unstable params can be default // tho, for example in `Box` if type_params.iter().any(|it| it.is_unstable(db) && it.default(db).is_none()) { @@ -464,16 +459,8 @@ pub(super) fn impl_method<'a, 'lt, 'db, DB: HirDatabase>( _ => None, }) .filter(|_| should_continue()) - .filter_map(move |(imp, ty, it)| { + .filter_map(move |(_, ty, it)| { let fn_generics = GenericDef::from(it); - let imp_generics = GenericDef::from(imp); - - // Ignore all functions that have something to do with lifetimes as we don't check them - if !fn_generics.lifetime_params(db).is_empty() - || !imp_generics.lifetime_params(db).is_empty() - { - return None; - } // Ignore functions without self param if !it.has_self_param(db) { diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 43b2a53a7f7e..fe18f5042ccd 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -1207,7 +1207,7 @@ fn main() { "#, expect![[r#" - me Function fn(&self, i32) -> bool [] + me Function(…) fn(&self, i32) -> bool [] "#]], ); } @@ -2672,8 +2672,8 @@ struct WorldSnapshot { _f: () }; fn go(world: &WorldSnapshot) { go(w$0) } "#, expect![[r#" - lc world &WorldSnapshot [type+name+local] - ex world [type] + lc world &WorldSnapshot [type_could_unify+name+local] + ex world [type_could_unify] st WorldSnapshot {…} WorldSnapshot { _f: () } [] st &WorldSnapshot {…} [type] st WorldSnapshot WorldSnapshot [] diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs index 0e558cf6a2b5..04331d48eaa8 100644 --- a/crates/ide-completion/src/tests/expression.rs +++ b/crates/ide-completion/src/tests/expression.rs @@ -3168,10 +3168,10 @@ fn foo() { } "#, expect![[r#" - me bar(…) (as ExcludedTrait) fn(&self) - me baz(…) (as ExcludedTrait) fn(&self) - me foo(…) (as ExcludedTrait) fn(&self) - "#]], + me bar(…) (as ExcludedTrait) fn(&self) + me baz(…) (as ExcludedTrait) fn(&self) + me foo(…) (as ExcludedTrait) fn(&self) + "#]], ); check_with_config( CompletionConfig { @@ -3197,10 +3197,10 @@ fn foo() { } "#, expect![[r#" - me bar(…) (as ExcludedTrait) fn(&self) - me baz(…) (as ExcludedTrait) fn(&self) - me foo(…) (as ExcludedTrait) fn(&self) - "#]], + me bar(…) (as ExcludedTrait) fn(&self) + me baz(…) (as ExcludedTrait) fn(&self) + me foo(…) (as ExcludedTrait) fn(&self) + "#]], ); } diff --git a/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs b/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs index 8df99598590f..d98b2c7186ed 100644 --- a/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs +++ b/crates/ide-diagnostics/src/handlers/elided_lifetimes_in_path.rs @@ -30,6 +30,7 @@ mod tests { use crate::tests::check_diagnostics; #[test] + #[ignore = "lifetime elision shows the elided lifetimes being non-elided currently"] fn fn_() { check_diagnostics( r#" @@ -54,6 +55,7 @@ fn foo(_: Foo<'_>) -> Foo { loop {} } } #[test] + #[ignore = "lifetime elision shows the elided lifetimes being non-elided currently"] fn async_fn() { check_diagnostics( r#" @@ -93,6 +95,7 @@ impl Trait<'_> for Foo<'_> {} } #[test] + #[ignore] fn impl_() { check_diagnostics( r#" diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 9dbf1136dcfc..ad2084d93caa 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -5911,7 +5911,7 @@ const FOO$0: &str = "bar"; ``` ```rust - const FOO: &str = "bar" + const FOO: &'static str = "bar" ``` --- @@ -6065,7 +6065,7 @@ const FOO$0: &i32 = &2; ``` ```rust - const FOO: &i32 = &2 + const FOO: &'static i32 = &2 ``` --- @@ -6240,7 +6240,7 @@ const FOO$0: Option<&i32> = Some(2).as_ref(); ``` ```rust - const FOO: Option<&i32> = Some(&2) + const FOO: Option<&'static i32> = Some(&2) ``` "#]], ); @@ -6263,7 +6263,7 @@ const FOO$0: &dyn Debug = &2i32; ``` ```rust - const FOO: &dyn Debug = &2 + const FOO: &'static dyn Debug = &2 ``` "#]], ); @@ -6284,7 +6284,7 @@ const FOO$0: &[i32] = &[1, 2, 3 + 4]; ``` ```rust - const FOO: &[i32] = &[1, 2, 7] + const FOO: &'static [i32] = &[1, 2, 7] ``` "#]], ); @@ -6301,7 +6301,7 @@ const FOO$0: &[i32; 5] = &[12; 5]; ``` ```rust - const FOO: &[i32; {const}] = &[12, 12, 12, 12, 12] + const FOO: &'static [i32; {const}] = &[12, 12, 12, 12, 12] ``` "#]], ); @@ -6322,7 +6322,7 @@ const FOO$0: (&i32, &[i32], &i32) = { ``` ```rust - const FOO: (&i32, &[i32], &i32) = (&1, &[1, 2, 3], &1) + const FOO: (&'static i32, &'static [i32], &'static i32) = (&1, &[1, 2, 3], &1) ``` "#]], ); @@ -6365,7 +6365,7 @@ const FOO$0: &S<[u8]> = core::mem::transmute::<&[u8], _>(&[1, 2, 3]); ``` ```rust - const FOO: &S<[u8]> = &S + const FOO: &'static S<[u8]> = &S ``` "#]], ); @@ -6385,7 +6385,7 @@ const FOO$0: &str = "foo"; ``` ```rust - const FOO: &str = "foo" + const FOO: &'static str = "foo" ``` "#]], ); @@ -6427,7 +6427,7 @@ const FOO$0: (&str, &str) = { ``` ```rust - const FOO: (&str, &str) = ("foo", "foo") + const FOO: (&'static str, &'static str) = ("foo", "foo") ``` "#]], ); diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs index 4a2cc5f551b6..b2229cfa044d 100644 --- a/crates/ide/src/rename.rs +++ b/crates/ide/src/rename.rs @@ -543,7 +543,10 @@ fn rename_to_self<'db>( }) }; - if ty != impl_ty { + let rebased_impl_ty = impl_ty.try_rebase_into(sema.db, &ty); + if let Some(impl_ty) = rebased_impl_ty + && !ty.could_unify_with(sema.db, &impl_ty) + { bail!("Parameter type differs from impl block type"); } diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs index 0022c1148a14..ce2da39e8ae4 100644 --- a/crates/ide/src/signature_help.rs +++ b/crates/ide/src/signature_help.rs @@ -190,7 +190,8 @@ fn signature_help_for_call( .iter() .filter(|param| match param { GenericParam::TypeParam(type_param) => !type_param.is_implicit(db), - GenericParam::ConstParam(_) | GenericParam::LifetimeParam(_) => true, + GenericParam::LifetimeParam(lt_param) => !lt_param.is_elided(db), + GenericParam::ConstParam(_) => true, }) .map(|param| param.display(db, display_target)) .join(", "); @@ -1809,8 +1810,8 @@ fn f() { } "#, expect![[r#" - fn f - ^ + fn f<'_, T> + ^^ - "#]], ); } diff --git a/crates/rust-analyzer/tests/slow-tests/cli.rs b/crates/rust-analyzer/tests/slow-tests/cli.rs index 4ef930e9854e..4ad7320e8454 100644 --- a/crates/rust-analyzer/tests/slow-tests/cli.rs +++ b/crates/rust-analyzer/tests/slow-tests/cli.rs @@ -98,7 +98,7 @@ mod tests { {"id":56,"type":"edge","label":"textDocument/references","inV":55,"outV":11} {"id":57,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[10],"outV":55} {"id":58,"type":"edge","label":"item","document":1,"property":"references","inVs":[13,23],"outV":55} - {"id":59,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &str = \"encoded_data\"\n```"}}} + {"id":59,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo\n```\n\n```rust\nconst REQ_001: &'static str = \"encoded_data\"\n```"}}} {"id":60,"type":"edge","label":"textDocument/hover","inV":59,"outV":16} {"id":61,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::REQ_001","unique":"scheme","kind":"export"} {"id":62,"type":"edge","label":"packageInformation","inV":31,"outV":61} @@ -120,7 +120,7 @@ mod tests { {"id":78,"type":"vertex","label":"referenceResult"} {"id":79,"type":"edge","label":"textDocument/references","inV":78,"outV":19} {"id":80,"type":"edge","label":"item","document":1,"property":"definitions","inVs":[18],"outV":78} - {"id":81,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &str = \"encoded_data\"\n```"}}} + {"id":81,"type":"vertex","label":"hoverResult","result":{"contents":{"kind":"markdown","value":"\n```rust\nfoo::tests\n```\n\n```rust\nconst REQ_002: &'static str = \"encoded_data\"\n```"}}} {"id":82,"type":"edge","label":"textDocument/hover","inV":81,"outV":26} {"id":83,"type":"vertex","label":"moniker","scheme":"rust-analyzer","identifier":"foo::tests::REQ_002","unique":"scheme","kind":"export"} {"id":84,"type":"edge","label":"packageInformation","inV":31,"outV":83}