Skip to content

Commit 0681eeb

Browse files
authored
Unrolled build for rust-lang#125978
Rollup merge of rust-lang#125978 - fmease:cleanup-hir-ty-lowering-consolidate-assoc-item-access-checking, r=davidtwco Cleanup: HIR ty lowering: Consolidate the places that do assoc item probing & access checking Use `probe_assoc_item` (for hygienically probing an assoc item and checking if it's accessible wrt. visibility and stability) for assoc item constraints, too, not just for assoc type paths and make the privacy error translatable.
2 parents 02c7a59 + c59a2b2 commit 0681eeb

File tree

6 files changed

+98
-70
lines changed

6 files changed

+98
-70
lines changed

compiler/rustc_hir_analysis/messages.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ hir_analysis_assoc_item_constraints_not_allowed_here =
88
associated item constraints are not allowed here
99
.label = associated item constraint not allowed here
1010
11+
hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
12+
.label = private {$kind}
13+
.defined_here_label = the {$kind} is defined here
14+
1115
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_name}` not found for `{$ty_param_name}`
1216
1317
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->

compiler/rustc_hir_analysis/src/errors.rs

+12
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ pub struct AssocKindMismatchWrapInBracesSugg {
5555
pub hi: Span,
5656
}
5757

58+
#[derive(Diagnostic)]
59+
#[diag(hir_analysis_assoc_item_is_private, code = E0624)]
60+
pub struct AssocItemIsPrivate {
61+
#[primary_span]
62+
#[label]
63+
pub span: Span,
64+
pub kind: &'static str,
65+
pub name: Ident,
66+
#[label(hir_analysis_defined_here_label)]
67+
pub defined_here_label: Span,
68+
}
69+
5870
#[derive(Diagnostic)]
5971
#[diag(hir_analysis_assoc_item_not_found, code = E0220)]
6072
pub struct AssocItemNotFound<'a> {

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+17-33
Original file line numberDiff line numberDiff line change
@@ -294,30 +294,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
294294
)?
295295
};
296296

297-
let (assoc_ident, def_scope) =
298-
tcx.adjust_ident_and_get_scope(constraint.ident, candidate.def_id(), hir_ref_id);
299-
300-
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
301-
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
302-
// `assoc_ident` again and again.
303-
let assoc_item = tcx
304-
.associated_items(candidate.def_id())
305-
.filter_by_name_unhygienic(assoc_ident.name)
306-
.find(|i| i.kind == assoc_kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
307-
.expect("missing associated item");
308-
309-
if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
310-
let reported = tcx
311-
.dcx()
312-
.struct_span_err(
313-
constraint.span,
314-
format!("{} `{}` is private", assoc_item.kind, constraint.ident),
315-
)
316-
.with_span_label(constraint.span, format!("private {}", assoc_item.kind))
317-
.emit();
318-
self.set_tainted_by_errors(reported);
319-
}
320-
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), constraint.span, None);
297+
let assoc_item = self
298+
.probe_assoc_item(
299+
constraint.ident,
300+
assoc_kind,
301+
hir_ref_id,
302+
constraint.span,
303+
candidate.def_id(),
304+
)
305+
.expect("failed to find associated item");
321306

322307
duplicates
323308
.entry(assoc_item.def_id)
@@ -404,10 +389,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
404389
// Create the generic arguments for the associated type or constant by joining the
405390
// parent arguments (the arguments of the trait) and the own arguments (the ones of
406391
// the associated item itself) and construct an alias type using them.
407-
let alias_ty = candidate.map_bound(|trait_ref| {
408-
let ident = Ident::new(assoc_item.name, constraint.ident.span);
392+
let alias_term = candidate.map_bound(|trait_ref| {
409393
let item_segment = hir::PathSegment {
410-
ident,
394+
ident: constraint.ident,
411395
hir_id: constraint.hir_id,
412396
res: Res::Err,
413397
args: Some(constraint.gen_args),
@@ -426,15 +410,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
426410
});
427411

428412
// Provide the resolved type of the associated constant to `type_of(AnonConst)`.
429-
if let hir::AssocItemConstraintKind::Equality { term: hir::Term::Const(anon_const) } =
430-
constraint.kind
431-
{
432-
let ty = alias_ty.map_bound(|ty| tcx.type_of(ty.def_id).instantiate(tcx, ty.args));
433-
let ty = check_assoc_const_binding_type(tcx, assoc_ident, ty, constraint.hir_id);
413+
if let Some(anon_const) = constraint.ct() {
414+
let ty = alias_term
415+
.map_bound(|alias| tcx.type_of(alias.def_id).instantiate(tcx, alias.args));
416+
let ty =
417+
check_assoc_const_binding_type(tcx, constraint.ident, ty, constraint.hir_id);
434418
tcx.feed_anon_const_type(anon_const.def_id, ty::EarlyBinder::bind(ty));
435419
}
436420

437-
alias_ty
421+
alias_term
438422
};
439423

440424
match constraint.kind {

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+58-33
Original file line numberDiff line numberDiff line change
@@ -1151,8 +1151,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11511151
};
11521152

11531153
let trait_did = bound.def_id();
1154-
let assoc_ty_did = self.probe_assoc_ty(assoc_ident, hir_ref_id, span, trait_did).unwrap();
1155-
let ty = self.lower_assoc_ty(span, assoc_ty_did, assoc_segment, bound);
1154+
let assoc_ty = self
1155+
.probe_assoc_item(assoc_ident, ty::AssocKind::Type, hir_ref_id, span, trait_did)
1156+
.expect("failed to find associated type");
1157+
let ty = self.lower_assoc_ty(span, assoc_ty.def_id, assoc_segment, bound);
11561158

11571159
if let Some(variant_def_id) = variant_resolution {
11581160
tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
@@ -1168,7 +1170,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11681170
};
11691171

11701172
could_refer_to(DefKind::Variant, variant_def_id, "");
1171-
could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
1173+
could_refer_to(DefKind::AssocTy, assoc_ty.def_id, " also");
11721174

11731175
lint.span_suggestion(
11741176
span,
@@ -1178,7 +1180,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
11781180
);
11791181
});
11801182
}
1181-
Ok((ty, DefKind::AssocTy, assoc_ty_did))
1183+
Ok((ty, DefKind::AssocTy, assoc_ty.def_id))
11821184
}
11831185

11841186
fn probe_inherent_assoc_ty(
@@ -1205,7 +1207,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12051207
let candidates: Vec<_> = tcx
12061208
.inherent_impls(adt_did)?
12071209
.iter()
1208-
.filter_map(|&impl_| Some((impl_, self.probe_assoc_ty_unchecked(name, block, impl_)?)))
1210+
.filter_map(|&impl_| {
1211+
let (item, scope) =
1212+
self.probe_assoc_item_unchecked(name, ty::AssocKind::Type, block, impl_)?;
1213+
Some((impl_, (item.def_id, scope)))
1214+
})
12091215
.collect();
12101216

12111217
if candidates.is_empty() {
@@ -1249,7 +1255,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
12491255
},
12501256
)?;
12511257

1252-
self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1258+
self.check_assoc_item(assoc_item, name, def_scope, block, span);
12531259

12541260
// FIXME(fmease): Currently creating throwaway `parent_args` to please
12551261
// `lower_generic_args_of_assoc_item`. Modify the latter instead (or sth. similar) to
@@ -1336,50 +1342,69 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
13361342
}
13371343
}
13381344

1339-
fn probe_assoc_ty(&self, name: Ident, block: HirId, span: Span, scope: DefId) -> Option<DefId> {
1340-
let (item, def_scope) = self.probe_assoc_ty_unchecked(name, block, scope)?;
1341-
self.check_assoc_ty(item, name, def_scope, block, span);
1345+
/// Given name and kind search for the assoc item in the provided scope and check if it's accessible[^1].
1346+
///
1347+
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
1348+
fn probe_assoc_item(
1349+
&self,
1350+
ident: Ident,
1351+
kind: ty::AssocKind,
1352+
block: HirId,
1353+
span: Span,
1354+
scope: DefId,
1355+
) -> Option<ty::AssocItem> {
1356+
let (item, scope) = self.probe_assoc_item_unchecked(ident, kind, block, scope)?;
1357+
self.check_assoc_item(item.def_id, ident, scope, block, span);
13421358
Some(item)
13431359
}
13441360

1345-
fn probe_assoc_ty_unchecked(
1361+
/// Given name and kind search for the assoc item in the provided scope
1362+
/// *without* checking if it's accessible[^1].
1363+
///
1364+
/// [^1]: I.e., accessible in the provided scope wrt. visibility and stability.
1365+
fn probe_assoc_item_unchecked(
13461366
&self,
1347-
name: Ident,
1367+
ident: Ident,
1368+
kind: ty::AssocKind,
13481369
block: HirId,
13491370
scope: DefId,
1350-
) -> Option<(DefId, DefId)> {
1371+
) -> Option<(ty::AssocItem, /*scope*/ DefId)> {
13511372
let tcx = self.tcx();
1352-
let (ident, def_scope) = tcx.adjust_ident_and_get_scope(name, scope, block);
13531373

1374+
let (ident, def_scope) = tcx.adjust_ident_and_get_scope(ident, scope, block);
13541375
// We have already adjusted the item name above, so compare with `.normalize_to_macros_2_0()`
13551376
// instead of calling `filter_by_name_and_kind` which would needlessly normalize the
13561377
// `ident` again and again.
1357-
let item = tcx.associated_items(scope).in_definition_order().find(|i| {
1358-
i.kind.namespace() == Namespace::TypeNS
1359-
&& i.ident(tcx).normalize_to_macros_2_0() == ident
1360-
})?;
1378+
let item = tcx
1379+
.associated_items(scope)
1380+
.filter_by_name_unhygienic(ident.name)
1381+
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == ident)?;
13611382

1362-
Some((item.def_id, def_scope))
1383+
Some((*item, def_scope))
13631384
}
13641385

1365-
fn check_assoc_ty(&self, item: DefId, name: Ident, def_scope: DefId, block: HirId, span: Span) {
1386+
/// Check if the given assoc item is accessible in the provided scope wrt. visibility and stability.
1387+
fn check_assoc_item(
1388+
&self,
1389+
item_def_id: DefId,
1390+
ident: Ident,
1391+
scope: DefId,
1392+
block: HirId,
1393+
span: Span,
1394+
) {
13661395
let tcx = self.tcx();
1367-
let kind = DefKind::AssocTy;
1368-
1369-
if !tcx.visibility(item).is_accessible_from(def_scope, tcx) {
1370-
let kind = tcx.def_kind_descr(kind, item);
1371-
let msg = format!("{kind} `{name}` is private");
1372-
let def_span = tcx.def_span(item);
1373-
let reported = tcx
1374-
.dcx()
1375-
.struct_span_err(span, msg)
1376-
.with_code(E0624)
1377-
.with_span_label(span, format!("private {kind}"))
1378-
.with_span_label(def_span, format!("{kind} defined here"))
1379-
.emit();
1396+
1397+
if !tcx.visibility(item_def_id).is_accessible_from(scope, tcx) {
1398+
let reported = tcx.dcx().emit_err(crate::errors::AssocItemIsPrivate {
1399+
span,
1400+
kind: tcx.def_descr(item_def_id),
1401+
name: ident,
1402+
defined_here_label: tcx.def_span(item_def_id),
1403+
});
13801404
self.set_tainted_by_errors(reported);
13811405
}
1382-
tcx.check_stability(item, Some(block), span, None);
1406+
1407+
tcx.check_stability(item_def_id, Some(block), span, None);
13831408
}
13841409

13851410
fn probe_traits_that_match_assoc_ty(

tests/ui/associated-inherent-types/assoc-inherent-private.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0624]: associated type `P` is private
22
--> $DIR/assoc-inherent-private.rs:10:10
33
|
44
LL | type P = ();
5-
| ------ associated type defined here
5+
| ------ the associated type is defined here
66
...
77
LL | type U = m::T::P;
88
| ^^^^^^^ private associated type
@@ -11,7 +11,7 @@ error[E0624]: associated type `P` is private
1111
--> $DIR/assoc-inherent-private.rs:21:10
1212
|
1313
LL | pub(super) type P = bool;
14-
| ----------------- associated type defined here
14+
| ----------------- the associated type is defined here
1515
...
1616
LL | type V = n::n::T::P;
1717
| ^^^^^^^^^^ private associated type

tests/ui/traits/item-privacy.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,17 @@ error[E0624]: associated type `A` is private
196196
--> $DIR/item-privacy.rs:119:12
197197
|
198198
LL | type A = u8;
199-
| ------ associated type defined here
199+
| ------ the associated type is defined here
200200
...
201201
LL | let _: T::A;
202202
| ^^^^ private associated type
203203

204-
error: associated type `A` is private
204+
error[E0624]: associated type `A` is private
205205
--> $DIR/item-privacy.rs:128:9
206206
|
207+
LL | type A = u8;
208+
| ------ the associated type is defined here
209+
...
207210
LL | A = u8,
208211
| ^^^^^^ private associated type
209212

0 commit comments

Comments
 (0)