Skip to content

Commit cb67283

Browse files
authored
Rollup merge of rust-lang#102889 - petrochenkov:partres, r=cjgillot
rustc_hir: Less error-prone methods for accessing `PartialRes` resolution
2 parents ccde95f + 1a8f177 commit cb67283

File tree

12 files changed

+75
-90
lines changed

12 files changed

+75
-90
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -205,13 +205,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
205205
let static_def_id = self
206206
.resolver
207207
.get_partial_res(sym.id)
208-
.filter(|res| res.unresolved_segments() == 0)
209-
.and_then(|res| {
210-
if let Res::Def(DefKind::Static(_), def_id) = res.base_res() {
211-
Some(def_id)
212-
} else {
213-
None
214-
}
208+
.and_then(|res| res.full_res())
209+
.and_then(|res| match res {
210+
Res::Def(DefKind::Static(_), def_id) => Some(def_id),
211+
_ => None,
215212
});
216213

217214
if let Some(def_id) = static_def_id {

compiler/rustc_ast_lowering/src/expr.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1044,9 +1044,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10441044
if let ExprKind::Path(qself, path) = &expr.kind {
10451045
// Does the path resolve to something disallowed in a tuple struct/variant pattern?
10461046
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
1047-
if partial_res.unresolved_segments() == 0
1048-
&& !partial_res.base_res().expected_in_tuple_struct_pat()
1049-
{
1047+
if let Some(res) = partial_res.full_res() && !res.expected_in_tuple_struct_pat() {
10501048
return None;
10511049
}
10521050
}
@@ -1066,9 +1064,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
10661064
if let ExprKind::Path(qself, path) = &expr.kind {
10671065
// Does the path resolve to something disallowed in a unit struct/variant pattern?
10681066
if let Some(partial_res) = self.resolver.get_partial_res(expr.id) {
1069-
if partial_res.unresolved_segments() == 0
1070-
&& !partial_res.base_res().expected_in_unit_struct_pat()
1071-
{
1067+
if let Some(res) = partial_res.full_res() && !res.expected_in_unit_struct_pat() {
10721068
return None;
10731069
}
10741070
}

compiler/rustc_ast_lowering/src/item.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
947947
}
948948
AssocItemKind::MacCall(..) => unimplemented!(),
949949
},
950-
trait_item_def_id: self.resolver.get_partial_res(i.id).map(|r| r.base_res().def_id()),
950+
trait_item_def_id: self
951+
.resolver
952+
.get_partial_res(i.id)
953+
.map(|r| r.expect_full_res().def_id()),
951954
}
952955
}
953956

@@ -1349,9 +1352,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
13491352
match self
13501353
.resolver
13511354
.get_partial_res(bound_pred.bounded_ty.id)
1352-
.map(|d| (d.base_res(), d.unresolved_segments()))
1355+
.and_then(|r| r.full_res())
13531356
{
1354-
Some((Res::Def(DefKind::TyParam, def_id), 0))
1357+
Some(Res::Def(DefKind::TyParam, def_id))
13551358
if bound_pred.bound_generic_params.is_empty() =>
13561359
{
13571360
generics

compiler/rustc_ast_lowering/src/lib.rs

+8-16
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,7 @@ impl ResolverAstLoweringExt for ResolverAstLowering {
175175
return None;
176176
}
177177

178-
let partial_res = self.partial_res_map.get(&expr.id)?;
179-
if partial_res.unresolved_segments() != 0 {
180-
return None;
181-
}
182-
183-
if let Res::Def(DefKind::Fn, def_id) = partial_res.base_res() {
178+
if let Res::Def(DefKind::Fn, def_id) = self.partial_res_map.get(&expr.id)?.full_res()? {
184179
// We only support cross-crate argument rewriting. Uses
185180
// within the same crate should be updated to use the new
186181
// const generics style.
@@ -753,12 +748,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
753748
}
754749

755750
fn expect_full_res(&mut self, id: NodeId) -> Res<NodeId> {
756-
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| {
757-
if pr.unresolved_segments() != 0 {
758-
panic!("path not fully resolved: {:?}", pr);
759-
}
760-
pr.base_res()
761-
})
751+
self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
762752
}
763753

764754
fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
@@ -1138,8 +1128,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
11381128
// type and value namespaces. If we resolved the path in the value namespace, we
11391129
// transform it into a generic const argument.
11401130
TyKind::Path(ref qself, ref path) => {
1141-
if let Some(partial_res) = self.resolver.get_partial_res(ty.id) {
1142-
let res = partial_res.base_res();
1131+
if let Some(res) = self
1132+
.resolver
1133+
.get_partial_res(ty.id)
1134+
.and_then(|partial_res| partial_res.full_res())
1135+
{
11431136
if !res.matches_ns(Namespace::TypeNS) {
11441137
debug!(
11451138
"lower_generic_arg: Lowering type argument as const argument: {:?}",
@@ -1206,8 +1199,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12061199
// by `ty_path`.
12071200
if qself.is_none()
12081201
&& let Some(partial_res) = self.resolver.get_partial_res(t.id)
1209-
&& partial_res.unresolved_segments() == 0
1210-
&& let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res()
1202+
&& let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
12111203
{
12121204
let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| {
12131205
let poly_trait_ref = this.ast_arena.ptr.alloc(PolyTraitRef {

compiler/rustc_ast_lowering/src/pat.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
239239
ident: Ident,
240240
lower_sub: impl FnOnce(&mut Self) -> Option<&'hir hir::Pat<'hir>>,
241241
) -> hir::PatKind<'hir> {
242-
match self.resolver.get_partial_res(p.id).map(|d| d.base_res()) {
242+
match self.resolver.get_partial_res(p.id).map(|d| d.expect_full_res()) {
243243
// `None` can occur in body-less function signatures
244244
res @ (None | Some(Res::Local(_))) => {
245245
let canonical_id = match res {

compiler/rustc_ast_lowering/src/path.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2929

3030
let partial_res =
3131
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
32+
let base_res = partial_res.base_res();
33+
let unresolved_segments = partial_res.unresolved_segments();
3234

3335
let path_span_lo = p.span.shrink_to_lo();
34-
let proj_start = p.segments.len() - partial_res.unresolved_segments();
36+
let proj_start = p.segments.len() - unresolved_segments;
3537
let path = self.arena.alloc(hir::Path {
36-
res: self.lower_res(partial_res.base_res()),
38+
res: self.lower_res(base_res),
3739
segments: self.arena.alloc_from_iter(p.segments[..proj_start].iter().enumerate().map(
3840
|(i, segment)| {
3941
let param_mode = match (qself_position, param_mode) {
@@ -46,7 +48,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
4648
_ => param_mode,
4749
};
4850

49-
let parenthesized_generic_args = match partial_res.base_res() {
51+
let parenthesized_generic_args = match base_res {
5052
// `a::b::Trait(Args)`
5153
Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
5254
ParenthesizedGenericArgs::Ok
@@ -83,7 +85,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
8385

8486
// Simple case, either no projections, or only fully-qualified.
8587
// E.g., `std::mem::size_of` or `<I as Iterator>::Item`.
86-
if partial_res.unresolved_segments() == 0 {
88+
if unresolved_segments == 0 {
8789
return hir::QPath::Resolved(qself, path);
8890
}
8991

compiler/rustc_hir/src/def.rs

+10
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,16 @@ impl PartialRes {
464464
pub fn unresolved_segments(&self) -> usize {
465465
self.unresolved_segments
466466
}
467+
468+
#[inline]
469+
pub fn full_res(&self) -> Option<Res<NodeId>> {
470+
(self.unresolved_segments == 0).then_some(self.base_res)
471+
}
472+
473+
#[inline]
474+
pub fn expect_full_res(&self) -> Res<NodeId> {
475+
self.full_res().expect("unexpected unresolved segments")
476+
}
467477
}
468478

469479
/// Different kinds of symbols can coexist even if they share the same textual name.

compiler/rustc_resolve/src/build_reduced_graph.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
326326
}
327327
PathResult::Module(..) => Err(VisResolutionError::ModuleOnly(path.span)),
328328
PathResult::NonModule(partial_res) => {
329-
expected_found_error(partial_res.base_res())
329+
expected_found_error(partial_res.expect_full_res())
330330
}
331331
PathResult::Failed { span, label, suggestion, .. } => {
332332
Err(VisResolutionError::FailedToResolve(span, label, suggestion))

compiler/rustc_resolve/src/late.rs

+15-13
Original file line numberDiff line numberDiff line change
@@ -641,8 +641,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
641641
// Check whether we should interpret this as a bare trait object.
642642
if qself.is_none()
643643
&& let Some(partial_res) = self.r.partial_res_map.get(&ty.id)
644-
&& partial_res.unresolved_segments() == 0
645-
&& let Res::Def(DefKind::Trait | DefKind::TraitAlias, _) = partial_res.base_res()
644+
&& let Some(Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) = partial_res.full_res()
646645
{
647646
// This path is actually a bare trait object. In case of a bare `Fn`-trait
648647
// object with anonymous lifetimes, we need this rib to correctly place the
@@ -1929,7 +1928,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19291928
match ty.kind {
19301929
TyKind::ImplicitSelf => true,
19311930
TyKind::Path(None, _) => {
1932-
let path_res = self.r.partial_res_map[&ty.id].base_res();
1931+
let path_res = self.r.partial_res_map[&ty.id].expect_full_res();
19331932
if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res {
19341933
return true;
19351934
}
@@ -1970,7 +1969,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
19701969
None
19711970
}
19721971
})
1973-
.map(|res| res.base_res())
1972+
.map(|res| res.expect_full_res())
19741973
.filter(|res| {
19751974
// Permit the types that unambiguously always
19761975
// result in the same type constructor being used
@@ -2530,7 +2529,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
25302529
Finalize::new(trait_ref.ref_id, trait_ref.path.span),
25312530
);
25322531
self.diagnostic_metadata.currently_processing_impl_trait = None;
2533-
if let Some(def_id) = res.base_res().opt_def_id() {
2532+
if let Some(def_id) = res.expect_full_res().opt_def_id() {
25342533
new_id = Some(def_id);
25352534
new_val = Some((self.r.expect_module(def_id), trait_ref.clone()));
25362535
}
@@ -2886,7 +2885,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
28862885
}
28872886

28882887
fn is_base_res_local(&self, nid: NodeId) -> bool {
2889-
matches!(self.r.partial_res_map.get(&nid).map(|res| res.base_res()), Some(Res::Local(..)))
2888+
matches!(
2889+
self.r.partial_res_map.get(&nid).map(|res| res.expect_full_res()),
2890+
Some(Res::Local(..))
2891+
)
28902892
}
28912893

28922894
/// Checks that all of the arms in an or-pattern have exactly the
@@ -3373,12 +3375,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
33733375
source.defer_to_typeck(),
33743376
finalize,
33753377
) {
3376-
Ok(Some(partial_res)) if partial_res.unresolved_segments() == 0 => {
3377-
if source.is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err
3378-
{
3378+
Ok(Some(partial_res)) if let Some(res) = partial_res.full_res() => {
3379+
if source.is_expected(res) || res == Res::Err {
33793380
partial_res
33803381
} else {
3381-
report_errors(self, Some(partial_res.base_res()))
3382+
report_errors(self, Some(res))
33823383
}
33833384
}
33843385

@@ -3586,20 +3587,21 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
35863587
};
35873588

35883589
if path.len() > 1
3589-
&& result.base_res() != Res::Err
3590+
&& let Some(res) = result.full_res()
3591+
&& res != Res::Err
35903592
&& path[0].ident.name != kw::PathRoot
35913593
&& path[0].ident.name != kw::DollarCrate
35923594
{
35933595
let unqualified_result = {
35943596
match self.resolve_path(&[*path.last().unwrap()], Some(ns), None) {
3595-
PathResult::NonModule(path_res) => path_res.base_res(),
3597+
PathResult::NonModule(path_res) => path_res.expect_full_res(),
35963598
PathResult::Module(ModuleOrUniformRoot::Module(module)) => {
35973599
module.res().unwrap()
35983600
}
35993601
_ => return Ok(Some(result)),
36003602
}
36013603
};
3602-
if result.base_res() == unqualified_result {
3604+
if res == unqualified_result {
36033605
let lint = lint::builtin::UNUSED_QUALIFICATIONS;
36043606
self.r.lint_buffer.buffer_lint(
36053607
lint,

compiler/rustc_resolve/src/late/diagnostics.rs

+14-22
Original file line numberDiff line numberDiff line change
@@ -968,11 +968,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
968968
let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else {
969969
return false;
970970
};
971-
if !(matches!(
972-
partial_res.base_res(),
973-
hir::def::Res::Def(hir::def::DefKind::AssocTy, _)
974-
) && partial_res.unresolved_segments() == 0)
975-
{
971+
if !matches!(
972+
partial_res.full_res(),
973+
Some(hir::def::Res::Def(hir::def::DefKind::AssocTy, _))
974+
) {
976975
return false;
977976
}
978977
(ty, position, path)
@@ -986,11 +985,10 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
986985
let Some(partial_res) = self.r.partial_res_map.get(&peeled_ty.id) else {
987986
return false;
988987
};
989-
if !(matches!(
990-
partial_res.base_res(),
991-
hir::def::Res::Def(hir::def::DefKind::TyParam, _)
992-
) && partial_res.unresolved_segments() == 0)
993-
{
988+
if !matches!(
989+
partial_res.full_res(),
990+
Some(hir::def::Res::Def(hir::def::DefKind::TyParam, _))
991+
) {
994992
return false;
995993
}
996994
if let (
@@ -1518,20 +1516,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
15181516
{
15191517
// Look for a field with the same name in the current self_type.
15201518
if let Some(resolution) = self.r.partial_res_map.get(&node_id) {
1521-
match resolution.base_res() {
1522-
Res::Def(DefKind::Struct | DefKind::Union, did)
1523-
if resolution.unresolved_segments() == 0 =>
1524-
{
1525-
if let Some(field_names) = self.r.field_names.get(&did) {
1526-
if field_names
1527-
.iter()
1528-
.any(|&field_name| ident.name == field_name.node)
1529-
{
1530-
return Some(AssocSuggestion::Field);
1531-
}
1519+
if let Some(Res::Def(DefKind::Struct | DefKind::Union, did)) =
1520+
resolution.full_res()
1521+
{
1522+
if let Some(field_names) = self.r.field_names.get(&did) {
1523+
if field_names.iter().any(|&field_name| ident.name == field_name.node) {
1524+
return Some(AssocSuggestion::Field);
15321525
}
15331526
}
1534-
_ => {}
15351527
}
15361528
}
15371529
}

compiler/rustc_resolve/src/lib.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -1883,12 +1883,10 @@ impl<'a> Resolver<'a> {
18831883

18841884
match self.maybe_resolve_path(&segments, Some(ns), &parent_scope) {
18851885
PathResult::Module(ModuleOrUniformRoot::Module(module)) => Some(module.res().unwrap()),
1886-
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
1887-
Some(path_res.base_res())
1886+
PathResult::NonModule(path_res) => path_res.full_res(),
1887+
PathResult::Module(ModuleOrUniformRoot::ExternPrelude) | PathResult::Failed { .. } => {
1888+
None
18881889
}
1889-
PathResult::Module(ModuleOrUniformRoot::ExternPrelude)
1890-
| PathResult::NonModule(..)
1891-
| PathResult::Failed { .. } => None,
18921890
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
18931891
}
18941892
}
@@ -1939,12 +1937,8 @@ impl<'a> Resolver<'a> {
19391937
return None;
19401938
}
19411939

1942-
let partial_res = self.partial_res_map.get(&expr.id)?;
1943-
if partial_res.unresolved_segments() != 0 {
1944-
return None;
1945-
}
1946-
1947-
if let Res::Def(def::DefKind::Fn, def_id) = partial_res.base_res() {
1940+
let res = self.partial_res_map.get(&expr.id)?.full_res()?;
1941+
if let Res::Def(def::DefKind::Fn, def_id) = res {
19481942
// We only support cross-crate argument rewriting. Uses
19491943
// within the same crate should be updated to use the new
19501944
// const generics style.

compiler/rustc_resolve/src/macros.rs

+3-6
Original file line numberDiff line numberDiff line change
@@ -590,9 +590,7 @@ impl<'a> Resolver<'a> {
590590

591591
let res = if path.len() > 1 {
592592
let res = match self.maybe_resolve_path(&path, Some(MacroNS), parent_scope) {
593-
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
594-
Ok(path_res.base_res())
595-
}
593+
PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => Ok(res),
596594
PathResult::Indeterminate if !force => return Err(Determinacy::Undetermined),
597595
PathResult::NonModule(..)
598596
| PathResult::Indeterminate
@@ -692,9 +690,8 @@ impl<'a> Resolver<'a> {
692690
Some(Finalize::new(ast::CRATE_NODE_ID, path_span)),
693691
None,
694692
) {
695-
PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => {
696-
let res = path_res.base_res();
697-
check_consistency(self, &path, path_span, kind, initial_res, res);
693+
PathResult::NonModule(path_res) if let Some(res) = path_res.full_res() => {
694+
check_consistency(self, &path, path_span, kind, initial_res, res)
698695
}
699696
path_res @ PathResult::NonModule(..) | path_res @ PathResult::Failed { .. } => {
700697
let (span, label) = if let PathResult::Failed { span, label, .. } = path_res {

0 commit comments

Comments
 (0)