Auto merge of #101228 - nnethercote:simplify-hir-PathSegment, r=petrochenkov

Simplify `hir::PathSegment`

r? `@petrochenkov`
This commit is contained in:
bors 2022-09-05 13:36:54 +00:00
commit 2dc703fd6e
28 changed files with 172 additions and 194 deletions

View file

@ -1776,12 +1776,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
binding: hir::HirId, binding: hir::HirId,
attrs: AttrVec, attrs: AttrVec,
) -> hir::Expr<'hir> { ) -> hir::Expr<'hir> {
let hir_id = self.next_id();
let res = Res::Local(binding);
let expr_path = hir::ExprKind::Path(hir::QPath::Resolved( let expr_path = hir::ExprKind::Path(hir::QPath::Resolved(
None, None,
self.arena.alloc(hir::Path { self.arena.alloc(hir::Path {
span: self.lower_span(span), span: self.lower_span(span),
res: Res::Local(binding), res,
segments: arena_vec![self; hir::PathSegment::from_ident(ident)], segments: arena_vec![self; hir::PathSegment::new(ident, hir_id, res)],
}), }),
)); ));

View file

@ -246,9 +246,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
} }
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) { fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment<'hir>) {
if let Some(hir_id) = path_segment.hir_id { self.insert(path_span, path_segment.hir_id, Node::PathSegment(path_segment));
self.insert(path_span, hir_id, Node::PathSegment(path_segment));
}
intravisit::walk_path_segment(self, path_span, path_segment); intravisit::walk_path_segment(self, path_span, path_segment);
} }

View file

@ -1439,10 +1439,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
GenericParamKind::Const { .. } => None, GenericParamKind::Const { .. } => None,
GenericParamKind::Type { .. } => { GenericParamKind::Type { .. } => {
let def_id = self.local_def_id(id).to_def_id(); let def_id = self.local_def_id(id).to_def_id();
let hir_id = self.next_id();
let res = Res::Def(DefKind::TyParam, def_id);
let ty_path = self.arena.alloc(hir::Path { let ty_path = self.arena.alloc(hir::Path {
span: param_span, span: param_span,
res: Res::Def(DefKind::TyParam, def_id), res,
segments: self.arena.alloc_from_iter([hir::PathSegment::from_ident(ident)]), segments: self
.arena
.alloc_from_iter([hir::PathSegment::new(ident, hir_id, res)]),
}); });
let ty_id = self.next_id(); let ty_id = self.next_id();
let bounded_ty = let bounded_ty =

View file

@ -1260,14 +1260,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx); return self.lower_path_ty(t, qself, path, ParamMode::Explicit, itctx);
} }
TyKind::ImplicitSelf => { TyKind::ImplicitSelf => {
let hir_id = self.lower_node_id(t.id);
let res = self.expect_full_res(t.id); let res = self.expect_full_res(t.id);
let res = self.lower_res(res); let res = self.lower_res(res);
hir::TyKind::Path(hir::QPath::Resolved( hir::TyKind::Path(hir::QPath::Resolved(
None, None,
self.arena.alloc(hir::Path { self.arena.alloc(hir::Path {
res, res,
segments: arena_vec![self; hir::PathSegment::from_ident( segments: arena_vec![self; hir::PathSegment::new(
Ident::with_dummy_span(kw::SelfUpper) Ident::with_dummy_span(kw::SelfUpper),
hir_id,
res
)], )],
span: self.lower_span(t.span), span: self.lower_span(t.span),
}), }),
@ -2193,12 +2196,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::PredicateOrigin::ImplTrait, hir::PredicateOrigin::ImplTrait,
); );
let hir_id = self.next_id();
let res = Res::Def(DefKind::TyParam, def_id.to_def_id());
let ty = hir::TyKind::Path(hir::QPath::Resolved( let ty = hir::TyKind::Path(hir::QPath::Resolved(
None, None,
self.arena.alloc(hir::Path { self.arena.alloc(hir::Path {
span: self.lower_span(span), span: self.lower_span(span),
res: Res::Def(DefKind::TyParam, def_id.to_def_id()), res,
segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))], segments:
arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
}), }),
)); ));

View file

@ -254,14 +254,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lower_sub(self), lower_sub(self),
) )
} }
Some(res) => hir::PatKind::Path(hir::QPath::Resolved( Some(res) => {
None, let hir_id = self.next_id();
self.arena.alloc(hir::Path { let res = self.lower_res(res);
span: self.lower_span(ident.span), hir::PatKind::Path(hir::QPath::Resolved(
res: self.lower_res(res), None,
segments: arena_vec![self; hir::PathSegment::from_ident(self.lower_ident(ident))], self.arena.alloc(hir::Path {
}), span: self.lower_span(ident.span),
)), res,
segments: arena_vec![self; hir::PathSegment::new(self.lower_ident(ident), hir_id, res)],
}),
))
}
} }
} }

View file

@ -250,16 +250,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
} }
let res = self.expect_full_res(segment.id); let res = self.expect_full_res(segment.id);
let id = self.lower_node_id(segment.id); let hir_id = self.lower_node_id(segment.id);
debug!( debug!(
"lower_path_segment: ident={:?} original-id={:?} new-id={:?}", "lower_path_segment: ident={:?} original-id={:?} new-id={:?}",
segment.ident, segment.id, id, segment.ident, segment.id, hir_id,
); );
hir::PathSegment { hir::PathSegment {
ident: self.lower_ident(segment.ident), ident: self.lower_ident(segment.ident),
hir_id: Some(id), hir_id,
res: Some(self.lower_res(res)), res: self.lower_res(res),
infer_args, infer_args,
args: if generic_args.is_empty() && generic_args.span.is_empty() { args: if generic_args.is_empty() && generic_args.span.is_empty() {
None None

View file

@ -935,10 +935,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
_, _,
) = hir_map.body(fn_body_id).value.kind ) = hir_map.body(fn_body_id).value.kind
{ {
let opt_suggestions = path_segment let opt_suggestions = self
.hir_id .infcx
.map(|path_hir_id| self.infcx.tcx.typeck(path_hir_id.owner)) .tcx
.and_then(|typeck| typeck.type_dependent_def_id(*hir_id)) .typeck(path_segment.hir_id.owner)
.type_dependent_def_id(*hir_id)
.and_then(|def_id| self.infcx.tcx.impl_of_method(def_id)) .and_then(|def_id| self.infcx.tcx.impl_of_method(def_id))
.map(|def_id| self.infcx.tcx.associated_items(def_id)) .map(|def_id| self.infcx.tcx.associated_items(def_id))
.map(|assoc_items| { .map(|assoc_items| {

View file

@ -308,6 +308,7 @@ pub enum Res<Id = hir::HirId> {
/// ///
/// **Belongs to the type namespace.** /// **Belongs to the type namespace.**
PrimTy(hir::PrimTy), PrimTy(hir::PrimTy),
/// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and /// The `Self` type, optionally with the [`DefId`] of the trait it belongs to and
/// optionally with the [`DefId`] of the item introducing the `Self` type alias. /// optionally with the [`DefId`] of the item introducing the `Self` type alias.
/// ///
@ -355,7 +356,8 @@ pub enum Res<Id = hir::HirId> {
/// const fn baz<T>() -> usize { 10 } /// const fn baz<T>() -> usize { 10 }
/// ``` /// ```
/// We do however allow `Self` in repeat expression even if it is generic to not break code /// We do however allow `Self` in repeat expression even if it is generic to not break code
/// which already works on stable while causing the `const_evaluatable_unchecked` future compat lint: /// which already works on stable while causing the `const_evaluatable_unchecked` future compat
/// lint:
/// ``` /// ```
/// fn foo<T>() { /// fn foo<T>() {
/// let _bar = [1_u8; std::mem::size_of::<*mut T>()]; /// let _bar = [1_u8; std::mem::size_of::<*mut T>()];
@ -370,6 +372,7 @@ pub enum Res<Id = hir::HirId> {
/// from mentioning generics (i.e. when used in an anonymous constant). /// from mentioning generics (i.e. when used in an anonymous constant).
alias_to: Option<(DefId, bool)>, alias_to: Option<(DefId, bool)>,
}, },
/// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`. /// A tool attribute module; e.g., the `rustfmt` in `#[rustfmt::skip]`.
/// ///
/// **Belongs to the type namespace.** /// **Belongs to the type namespace.**
@ -383,6 +386,7 @@ pub enum Res<Id = hir::HirId> {
/// ///
/// *See also [`Res::SelfTy`].* /// *See also [`Res::SelfTy`].*
SelfCtor(DefId), SelfCtor(DefId),
/// A local variable or function parameter. /// A local variable or function parameter.
/// ///
/// **Belongs to the value namespace.** /// **Belongs to the value namespace.**

View file

@ -202,13 +202,8 @@ impl Path<'_> {
pub struct PathSegment<'hir> { pub struct PathSegment<'hir> {
/// The identifier portion of this path segment. /// The identifier portion of this path segment.
pub ident: Ident, pub ident: Ident,
// `id` and `res` are optional. We currently only use these in save-analysis, pub hir_id: HirId,
// any path segments without these will not have save-analysis info and pub res: Res,
// therefore will not have 'jump to def' in IDEs, but otherwise will not be
// affected. (In general, we don't bother to get the defs for synthesized
// segments, only for segments which have come from the AST).
pub hir_id: Option<HirId>,
pub res: Option<Res>,
/// Type/lifetime parameters attached to this path. They come in /// Type/lifetime parameters attached to this path. They come in
/// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that /// two flavors: `Path<A,B,C>` and `Path(A,B) -> C`. Note that
@ -226,12 +221,12 @@ pub struct PathSegment<'hir> {
impl<'hir> PathSegment<'hir> { impl<'hir> PathSegment<'hir> {
/// Converts an identifier to the corresponding segment. /// Converts an identifier to the corresponding segment.
pub fn from_ident(ident: Ident) -> PathSegment<'hir> { pub fn new(ident: Ident, hir_id: HirId, res: Res) -> PathSegment<'hir> {
PathSegment { ident, hir_id: None, res: None, infer_args: true, args: None } PathSegment { ident, hir_id, res, infer_args: true, args: None }
} }
pub fn invalid() -> Self { pub fn invalid() -> Self {
Self::from_ident(Ident::empty()) Self::new(Ident::empty(), HirId::INVALID, Res::Err)
} }
pub fn args(&self) -> &GenericArgs<'hir> { pub fn args(&self) -> &GenericArgs<'hir> {

View file

@ -20,6 +20,9 @@ pub struct HirId {
} }
impl HirId { impl HirId {
/// Signal local id which should never be used.
pub const INVALID: HirId = HirId { owner: CRATE_DEF_ID, local_id: ItemLocalId::INVALID };
#[inline] #[inline]
pub fn expect_owner(self) -> LocalDefId { pub fn expect_owner(self) -> LocalDefId {
assert_eq!(self.local_id.index(), 0); assert_eq!(self.local_id.index(), 0);

View file

@ -724,7 +724,7 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(
segment: &'v PathSegment<'v>, segment: &'v PathSegment<'v>,
) { ) {
visitor.visit_ident(segment.ident); visitor.visit_ident(segment.ident);
walk_list!(visitor, visit_id, segment.hir_id); visitor.visit_id(segment.hir_id);
if let Some(ref args) = segment.args { if let Some(ref args) = segment.args {
visitor.visit_generic_args(path_span, args); visitor.visit_generic_args(path_span, args);
} }

View file

@ -1189,7 +1189,7 @@ impl<'a> State<'a> {
let generic_args = segment.args(); let generic_args = segment.args();
if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() { if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
self.print_generic_args(generic_args, segment.infer_args, true); self.print_generic_args(generic_args, true);
} }
self.print_call_post(base_args) self.print_call_post(base_args)
@ -1592,7 +1592,7 @@ impl<'a> State<'a> {
} }
if segment.ident.name != kw::PathRoot { if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident); self.print_ident(segment.ident);
self.print_generic_args(segment.args(), segment.infer_args, colons_before_params); self.print_generic_args(segment.args(), colons_before_params);
} }
} }
} }
@ -1600,7 +1600,7 @@ impl<'a> State<'a> {
pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) { pub fn print_path_segment(&mut self, segment: &hir::PathSegment<'_>) {
if segment.ident.name != kw::PathRoot { if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident); self.print_ident(segment.ident);
self.print_generic_args(segment.args(), segment.infer_args, false); self.print_generic_args(segment.args(), false);
} }
} }
@ -1619,11 +1619,7 @@ impl<'a> State<'a> {
} }
if segment.ident.name != kw::PathRoot { if segment.ident.name != kw::PathRoot {
self.print_ident(segment.ident); self.print_ident(segment.ident);
self.print_generic_args( self.print_generic_args(segment.args(), colons_before_params);
segment.args(),
segment.infer_args,
colons_before_params,
);
} }
} }
@ -1631,11 +1627,7 @@ impl<'a> State<'a> {
self.word("::"); self.word("::");
let item_segment = path.segments.last().unwrap(); let item_segment = path.segments.last().unwrap();
self.print_ident(item_segment.ident); self.print_ident(item_segment.ident);
self.print_generic_args( self.print_generic_args(item_segment.args(), colons_before_params)
item_segment.args(),
item_segment.infer_args,
colons_before_params,
)
} }
hir::QPath::TypeRelative(qself, item_segment) => { hir::QPath::TypeRelative(qself, item_segment) => {
// If we've got a compound-qualified-path, let's push an additional pair of angle // If we've got a compound-qualified-path, let's push an additional pair of angle
@ -1651,11 +1643,7 @@ impl<'a> State<'a> {
self.word("::"); self.word("::");
self.print_ident(item_segment.ident); self.print_ident(item_segment.ident);
self.print_generic_args( self.print_generic_args(item_segment.args(), colons_before_params)
item_segment.args(),
item_segment.infer_args,
colons_before_params,
)
} }
hir::QPath::LangItem(lang_item, span, _) => { hir::QPath::LangItem(lang_item, span, _) => {
self.word("#[lang = \""); self.word("#[lang = \"");
@ -1668,7 +1656,6 @@ impl<'a> State<'a> {
fn print_generic_args( fn print_generic_args(
&mut self, &mut self,
generic_args: &hir::GenericArgs<'_>, generic_args: &hir::GenericArgs<'_>,
infer_args: bool,
colons_before_params: bool, colons_before_params: bool,
) { ) {
if generic_args.parenthesized { if generic_args.parenthesized {
@ -1715,13 +1702,6 @@ impl<'a> State<'a> {
); );
} }
// FIXME(eddyb): this would leak into error messages (e.g.,
// "non-exhaustive patterns: `Some::<..>(_)` not covered").
if infer_args && false {
start_or_comma(self);
self.word("..");
}
for binding in generic_args.bindings { for binding in generic_args.bindings {
start_or_comma(self); start_or_comma(self);
self.print_type_binding(binding); self.print_type_binding(binding);
@ -1735,7 +1715,7 @@ impl<'a> State<'a> {
pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) { pub fn print_type_binding(&mut self, binding: &hir::TypeBinding<'_>) {
self.print_ident(binding.ident); self.print_ident(binding.ident);
self.print_generic_args(binding.gen_args, false, false); self.print_generic_args(binding.gen_args, false);
self.space(); self.space();
match binding.kind { match binding.kind {
hir::TypeBindingKind::Equality { ref term } => { hir::TypeBindingKind::Equality { ref term } => {

View file

@ -909,7 +909,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
None? None?
} }
let substs = self.node_substs_opt(expr.hir_id)?; let substs = self.node_substs_opt(expr.hir_id)?;
let span = tcx.hir().span(segment.hir_id?); let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
InsertableGenericArgs { InsertableGenericArgs {
insert_span, insert_span,
@ -957,13 +957,13 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
path.segments path.segments
.iter() .iter()
.filter_map(move |segment| { .filter_map(move |segment| {
let res = segment.res?; let res = segment.res;
let generics_def_id = tcx.res_generics_def_id(res)?; let generics_def_id = tcx.res_generics_def_id(res)?;
let generics = tcx.generics_of(generics_def_id); let generics = tcx.generics_of(generics_def_id);
if generics.has_impl_trait() { if generics.has_impl_trait() {
return None; return None;
} }
let span = tcx.hir().span(segment.hir_id?); let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
Some(InsertableGenericArgs { Some(InsertableGenericArgs {
insert_span, insert_span,
@ -996,7 +996,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
if !segment.infer_args || generics.has_impl_trait() { if !segment.infer_args || generics.has_impl_trait() {
None?; None?;
} }
let span = tcx.hir().span(segment.hir_id?); let span = tcx.hir().span(segment.hir_id);
let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi()); let insert_span = segment.ident.span.shrink_to_hi().with_hi(span.hi());
InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id } InsertableGenericArgs { insert_span, substs, generics_def_id: def_id, def_id }
}; };

View file

@ -154,16 +154,11 @@ impl<'tcx> Visitor<'tcx> for TypeParamSpanVisitor<'tcx> {
} }
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[segment] [segment]
if segment if matches!(
.res segment.res,
.map(|res| { Res::SelfTy { trait_: _, alias_to: _ }
matches!( | Res::Def(hir::def::DefKind::TyParam, _)
res, ) =>
Res::SelfTy { trait_: _, alias_to: _ }
| Res::Def(hir::def::DefKind::TyParam, _)
)
})
.unwrap_or(false) =>
{ {
self.types.push(path.span); self.types.push(path.span);
} }

View file

@ -118,8 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
_: rustc_hir::HirId, _: rustc_hir::HirId,
) { ) {
if let Some(segment) = path.segments.iter().nth_back(1) if let Some(segment) = path.segments.iter().nth_back(1)
&& let Some(res) = &segment.res && lint_ty_kind_usage(cx, &segment.res)
&& lint_ty_kind_usage(cx, res)
{ {
let span = path.span.with_hi( let span = path.span.with_hi(
segment.args.map_or(segment.ident.span, |a| a.span_ext).hi() segment.args.map_or(segment.ident.span, |a| a.span_ext).hi()

View file

@ -832,7 +832,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
// added, such as `core::intrinsics::transmute` // added, such as `core::intrinsics::transmute`
let parents = path.segments.iter().rev().skip(1); let parents = path.segments.iter().rev().skip(1);
for path_segment in parents { for path_segment in parents {
if let Some(def_id) = path_segment.res.as_ref().and_then(Res::opt_def_id) { if let Some(def_id) = path_segment.res.opt_def_id() {
// use `None` for id to prevent deprecation check // use `None` for id to prevent deprecation check
self.tcx.check_stability_allow_unstable( self.tcx.check_stability_allow_unstable(
def_id, def_id,

View file

@ -912,7 +912,10 @@ impl<'tcx> DumpVisitor<'tcx> {
_, _,
) )
| Res::SelfTy { .. } => { | Res::SelfTy { .. } => {
self.dump_path_segment_ref(id, &hir::PathSegment::from_ident(ident)); self.dump_path_segment_ref(
id,
&hir::PathSegment::new(ident, hir::HirId::INVALID, Res::Err),
);
} }
def => { def => {
error!("unexpected definition kind when processing collected idents: {:?}", def) error!("unexpected definition kind when processing collected idents: {:?}", def)

View file

@ -596,13 +596,14 @@ impl<'tcx> SaveContext<'tcx> {
Node::TraitRef(tr) => tr.path.res, Node::TraitRef(tr) => tr.path.res,
Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res, Node::Item(&hir::Item { kind: hir::ItemKind::Use(path, _), .. }) => path.res,
Node::PathSegment(seg) => match seg.res { Node::PathSegment(seg) => {
Some(res) if res != Res::Err => res, if seg.res != Res::Err {
_ => { seg.res
} else {
let parent_node = self.tcx.hir().get_parent_node(hir_id); let parent_node = self.tcx.hir().get_parent_node(hir_id);
self.get_path_res(parent_node) self.get_path_res(parent_node)
} }
}, }
Node::Expr(&hir::Expr { kind: hir::ExprKind::Struct(ref qpath, ..), .. }) => { Node::Expr(&hir::Expr { kind: hir::ExprKind::Struct(ref qpath, ..), .. }) => {
self.typeck_results().qpath_res(qpath, hir_id) self.typeck_results().qpath_res(qpath, hir_id)
@ -648,7 +649,7 @@ impl<'tcx> SaveContext<'tcx> {
} }
pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option<Ref> { pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option<Ref> {
self.get_path_segment_data_with_id(path_seg, path_seg.hir_id?) self.get_path_segment_data_with_id(path_seg, path_seg.hir_id)
} }
pub fn get_path_segment_data_with_id( pub fn get_path_segment_data_with_id(

View file

@ -2210,12 +2210,12 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
&& let [ && let [
.., ..,
trait_path_segment @ hir::PathSegment { trait_path_segment @ hir::PathSegment {
res: Some(rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, trait_id)), res: rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, trait_id),
.. ..
}, },
hir::PathSegment { hir::PathSegment {
ident: assoc_item_name, ident: assoc_item_name,
res: Some(rustc_hir::def::Res::Def(_, item_id)), res: rustc_hir::def::Res::Def(_, item_id),
.. ..
} }
] = path.segments ] = path.segments

View file

@ -1113,8 +1113,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let ident = Ident::new(assoc_item.name, binding.item_name.span); let ident = Ident::new(assoc_item.name, binding.item_name.span);
let item_segment = hir::PathSegment { let item_segment = hir::PathSegment {
ident, ident,
hir_id: Some(binding.hir_id), hir_id: binding.hir_id,
res: None, res: Res::Err,
args: Some(binding.gen_args), args: Some(binding.gen_args),
infer_args: false, infer_args: false,
}; };
@ -1845,7 +1845,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
[.., hir::PathSegment { [.., hir::PathSegment {
ident, ident,
args, args,
res: Some(Res::Def(DefKind::Enum, _)), res: Res::Def(DefKind::Enum, _),
.. ..
}, _] => ( }, _] => (
// We need to include the `::` in `Type::Variant::<Args>` // We need to include the `::` in `Type::Variant::<Args>`
@ -2127,24 +2127,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let types_and_spans: Vec<_> = segments let types_and_spans: Vec<_> = segments
.clone() .clone()
.flat_map(|segment| { .flat_map(|segment| {
segment.res.and_then(|res| { if segment.args().args.is_empty() {
if segment.args().args.is_empty() { None
None } else {
} else { Some((
Some(( match segment.res {
match res { Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()),
Res::PrimTy(ty) => format!("{} `{}`", res.descr(), ty.name()),
Res::Def(_, def_id) Res::Def(_, def_id)
if let Some(name) = self.tcx().opt_item_name(def_id) => { if let Some(name) = self.tcx().opt_item_name(def_id) => {
format!("{} `{name}`", res.descr()) format!("{} `{name}`", segment.res.descr())
} }
Res::Err => "this type".to_string(), Res::Err => "this type".to_string(),
_ => res.descr().to_string(), _ => segment.res.descr().to_string(),
}, },
segment.ident.span, segment.ident.span,
)) ))
} }
})
}) })
.collect(); .collect();
let this_type = match &types_and_spans[..] { let this_type = match &types_and_spans[..] {

View file

@ -610,12 +610,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>(
fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) { fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
match arg.kind { match arg.kind {
hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments { hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
[ [PathSegment { res: Res::SelfTy { trait_: _, alias_to: impl_ref }, .. }] => {
PathSegment {
res: Some(Res::SelfTy { trait_: _, alias_to: impl_ref }),
..
},
] => {
let impl_ty_name = let impl_ty_name =
impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id)); impl_ref.map(|(def_id, _)| self.tcx.def_path_str(def_id));
self.selftys.push((path.span, impl_ty_name)); self.selftys.push((path.span, impl_ty_name));

View file

@ -768,7 +768,7 @@ impl<'tcx> TypeVisitor<'tcx> for GATSubstCollector<'tcx> {
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool { fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
match ty.kind { match ty.kind {
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments { hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
[s] => s.res.and_then(|r| r.opt_def_id()) == Some(trait_def_id.to_def_id()), [s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
_ => false, _ => false,
}, },
_ => false, _ => false,

View file

@ -1,6 +1,5 @@
use rustc_errors::{Applicability, StashKey}; use rustc_errors::{Applicability, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit; use rustc_hir::intravisit;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -179,15 +178,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
return None; return None;
}; };
// Try to use the segment resolution if it is valid, otherwise we let generics = match tcx.res_generics_def_id(segment.res) {
// default to the path resolution.
let res = segment.res.filter(|&r| r != Res::Err).unwrap_or(path.res);
let generics = match tcx.res_generics_def_id(res) {
Some(def_id) => tcx.generics_of(def_id), Some(def_id) => tcx.generics_of(def_id),
None => { None => {
tcx.sess.delay_span_bug( tcx.sess.delay_span_bug(
tcx.def_span(def_id), tcx.def_span(def_id),
&format!("unexpected anon const res {:?} in path: {:?}", res, path), &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
); );
return None; return None;
} }

View file

@ -291,62 +291,60 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
// Creates lifetime name suggestions from the lifetime parameter names // Creates lifetime name suggestions from the lifetime parameter names
fn get_lifetime_args_suggestions_from_param_names( fn get_lifetime_args_suggestions_from_param_names(
&self, &self,
path_hir_id: Option<hir::HirId>, path_hir_id: hir::HirId,
num_params_to_take: usize, num_params_to_take: usize,
) -> String { ) -> String {
debug!(?path_hir_id); debug!(?path_hir_id);
if let Some(path_hir_id) = path_hir_id { let mut ret = Vec::new();
let mut ret = Vec::new(); for (id, node) in self.tcx.hir().parent_iter(path_hir_id) {
for (id, node) in self.tcx.hir().parent_iter(path_hir_id) { debug!(?id);
debug!(?id); let params = if let Some(generics) = node.generics() {
let params = if let Some(generics) = node.generics() { generics.params
generics.params } else if let hir::Node::Ty(ty) = node
} else if let hir::Node::Ty(ty) = node && let hir::TyKind::BareFn(bare_fn) = ty.kind
&& let hir::TyKind::BareFn(bare_fn) = ty.kind {
{ bare_fn.generic_params
bare_fn.generic_params } else {
} else { &[]
&[] };
}; ret.extend(params.iter().filter_map(|p| {
ret.extend(params.iter().filter_map(|p| { let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }
let hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit } = p.kind
= p.kind else { return None };
else { return None }; let hir::ParamName::Plain(name) = p.name else { return None };
let hir::ParamName::Plain(name) = p.name else { return None }; Some(name.to_string())
Some(name.to_string()) }));
})); // Suggest `'static` when in const/static item-like.
// Suggest `'static` when in const/static item-like. if let hir::Node::Item(hir::Item {
if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. },
kind: hir::ItemKind::Static { .. } | hir::ItemKind::Const { .. }, ..
.. })
}) | hir::Node::TraitItem(hir::TraitItem {
| hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const { .. },
kind: hir::TraitItemKind::Const { .. }, ..
.. })
}) | hir::Node::ImplItem(hir::ImplItem {
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const { .. },
kind: hir::ImplItemKind::Const { .. }, ..
.. })
}) | hir::Node::ForeignItem(hir::ForeignItem {
| hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Static { .. },
kind: hir::ForeignItemKind::Static { .. }, ..
.. })
}) | hir::Node::AnonConst(..) = node
| hir::Node::AnonConst(..) = node {
{ ret.extend(
ret.extend( std::iter::repeat("'static".to_owned())
std::iter::repeat("'static".to_owned()) .take(num_params_to_take.saturating_sub(ret.len())),
.take(num_params_to_take.saturating_sub(ret.len())), );
); }
} if ret.len() >= num_params_to_take {
if ret.len() >= num_params_to_take { return ret[..num_params_to_take].join(", ");
return ret[..num_params_to_take].join(", "); }
} // We cannot refer to lifetimes defined in an outer function.
// We cannot refer to lifetimes defined in an outer function. if let hir::Node::Item(_) = node {
if let hir::Node::Item(_) = node { break;
break;
}
} }
} }
@ -690,8 +688,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
num = num_trait_generics_except_self, num = num_trait_generics_except_self,
); );
if let Some(hir_id) = self.path_segment.hir_id if let Some(parent_node) = self.tcx.hir().find_parent_node(self.path_segment.hir_id)
&& let Some(parent_node) = self.tcx.hir().find_parent_node(hir_id)
&& let Some(parent_node) = self.tcx.hir().find(parent_node) && let Some(parent_node) = self.tcx.hir().find(parent_node)
&& let hir::Node::Expr(expr) = parent_node { && let hir::Node::Expr(expr) = parent_node {
match expr.kind { match expr.kind {

View file

@ -166,25 +166,23 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) { fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
if let ExprKind::MethodCall(segment, ..) = expr.kind { if let ExprKind::MethodCall(segment, ..) = expr.kind {
if let Some(hir_id) = segment.hir_id { let hir = self.tcx.hir();
let hir = self.tcx.hir(); let body_id = hir.enclosing_body_owner(segment.hir_id);
let body_id = hir.enclosing_body_owner(hir_id); // FIXME: this is showing error messages for parts of the code that are not
// FIXME: this is showing error messages for parts of the code that are not // compiled (because of cfg)!
// compiled (because of cfg)! //
// // See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352
// See discussion in https://github.com/rust-lang/rust/issues/69426#issuecomment-1019412352 let typeck_results = self
let typeck_results = self.tcx.typeck_body( .tcx
hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"), .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body"));
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
self.matches.insert(
segment.ident.span,
match hir.span_if_local(def_id) {
Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
None => LinkFromSrc::External(def_id),
},
); );
if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) {
self.matches.insert(
segment.ident.span,
match hir.span_if_local(def_id) {
Some(span) => LinkFromSrc::Local(clean::Span::new(span)),
None => LinkFromSrc::External(def_id),
},
);
}
} }
} else if self.handle_macro(expr.span) { } else if self.handle_macro(expr.span) {
// We don't want to go deeper into the macro. // We don't want to go deeper into the macro.

View file

@ -185,7 +185,7 @@ fn in_impl<'tcx>(
if let ItemKind::Impl(item) = &item.kind; if let ItemKind::Impl(item) = &item.kind;
if let Some(of_trait) = &item.of_trait; if let Some(of_trait) = &item.of_trait;
if let Some(seg) = of_trait.path.segments.last(); if let Some(seg) = of_trait.path.segments.last();
if let Some(Res::Def(_, trait_id)) = seg.res; if let Res::Def(_, trait_id) = seg.res;
if trait_id == bin_op; if trait_id == bin_op;
if let Some(generic_args) = seg.args; if let Some(generic_args) = seg.args;
if let Some(GenericArg::Type(other_ty)) = generic_args.args.last(); if let Some(GenericArg::Type(other_ty)) = generic_args.args.last();

View file

@ -43,8 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef {
if mut_ty.mutbl == Mutability::Not; if mut_ty.mutbl == Mutability::Not;
if let TyKind::Path(ref qpath) = &mut_ty.ty.kind; if let TyKind::Path(ref qpath) = &mut_ty.ty.kind;
let last = last_path_segment(qpath); let last = last_path_segment(qpath);
if let Some(res) = last.res; if let Some(def_id) = last.res.opt_def_id();
if let Some(def_id) = res.opt_def_id();
if cx.tcx.is_diagnostic_item(sym::Option, def_id); if cx.tcx.is_diagnostic_item(sym::Option, def_id);
if let Some(params) = last_path_segment(qpath).args ; if let Some(params) = last_path_segment(qpath).args ;

View file

@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
if !bound_predicate.span.from_expansion(); if !bound_predicate.span.from_expansion();
if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind; if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind;
if let Some(PathSegment { if let Some(PathSegment {
res: Some(Res::SelfTy{ trait_: Some(def_id), alias_to: _ }), .. res: Res::SelfTy{ trait_: Some(def_id), alias_to: _ }, ..
}) = segments.first(); }) = segments.first();
if let Some( if let Some(
Node::Item( Node::Item(