Factor out resolve_type_relative_path
· rust-lang/rust@695fcf5 (original) (raw)
`@@ -38,8 +38,8 @@ use rustc_middle::middle::stability::AllowUnstable;
`
38
38
`use rustc_middle::mir::interpret::LitToConstInput;
`
39
39
`use rustc_middle::ty::print::PrintPolyTraitRefExt as _;
`
40
40
`use rustc_middle::ty::{
`
41
``
`-
self, AssocTag, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty,
`
42
``
`-
TyCtxt, TypeVisitableExt, TypingMode, Upcast, fold_regions,
`
``
41
`+
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
`
``
42
`+
TypeVisitableExt, TypingMode, Upcast, fold_regions,
`
43
43
`};
`
44
44
`use rustc_middle::{bug, span_bug};
`
45
45
`use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
`
`@@ -937,7 +937,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
937
937
`fn probe_trait_that_defines_assoc_item(
`
938
938
`&self,
`
939
939
`trait_def_id: DefId,
`
940
``
`-
assoc_tag: AssocTag,
`
``
940
`+
assoc_tag: ty::AssocTag,
`
941
941
`assoc_ident: Ident,
`
942
942
`) -> bool {
`
943
943
`self.tcx()
`
`@@ -980,7 +980,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
980
980
`&self,
`
981
981
`ty_param_def_id: LocalDefId,
`
982
982
`ty_param_span: Span,
`
983
``
`-
assoc_tag: AssocTag,
`
``
983
`+
assoc_tag: ty::AssocTag,
`
984
984
`assoc_ident: Ident,
`
985
985
`span: Span,
`
986
986
`) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
`
`@@ -1015,7 +1015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1015
1015
`&self,
`
1016
1016
`all_candidates: impl Fn() -> I,
`
1017
1017
`qself: AssocItemQSelf,
`
1018
``
`-
assoc_tag: AssocTag,
`
``
1018
`+
assoc_tag: ty::AssocTag,
`
1019
1019
`assoc_ident: Ident,
`
1020
1020
`span: Span,
`
1021
1021
`constraint: Option<&hir::AssocItemConstraint<'tcx>>,
`
`@@ -1238,7 +1238,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1238
1238
`) -> Result<TypeRelativePath<'tcx>, ErrorGuaranteed> {
`
1239
1239
`debug!(%self_ty, ?segment.ident);
`
1240
1240
`let tcx = self.tcx();
`
1241
``
`-
let ident = segment.ident;
`
1242
1241
``
1243
1242
`// Check if we have an enum variant or an inherent associated type.
`
1244
1243
`let mut variant_def_id = None;
`
`@@ -1247,7 +1246,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1247
1246
`let variant_def = adt_def
`
1248
1247
`.variants()
`
1249
1248
`.iter()
`
1250
``
`-
.find(|vd| tcx.hygienic_eq(ident, vd.ident(tcx), adt_def.did()));
`
``
1249
`+
.find(|vd| tcx.hygienic_eq(segment.ident, vd.ident(tcx), adt_def.did()));
`
1251
1250
`if let Some(variant_def) = variant_def {
`
1252
1251
`if let PermitVariants::Yes = mode.permit_variants() {
`
1253
1252
` tcx.check_stability(variant_def.def_id, Some(qpath_hir_id), span, None);
`
`@@ -1282,13 +1281,70 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1282
1281
`}
`
1283
1282
`}
`
1284
1283
``
``
1284
`+
let (item_def_id, bound) = self.resolve_type_relative_path(
`
``
1285
`+
self_ty,
`
``
1286
`+
hir_self_ty,
`
``
1287
`+
mode.assoc_tag(),
`
``
1288
`+
segment,
`
``
1289
`+
qpath_hir_id,
`
``
1290
`+
span,
`
``
1291
`+
variant_def_id,
`
``
1292
`+
)?;
`
``
1293
+
``
1294
`+
let (item_def_id, args) = self.lower_assoc_item_path(span, item_def_id, segment, bound)?;
`
``
1295
+
``
1296
`+
if let Some(variant_def_id) = variant_def_id {
`
``
1297
`+
tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
`
``
1298
`+
lint.primary_message("ambiguous associated item");
`
``
1299
`+
let mut could_refer_to = |kind: DefKind, def_id, also| {
`
``
1300
`+
let note_msg = format!(
`
``
1301
`` +
"{}
could{} refer to the {} defined here",
``
``
1302
`+
segment.ident,
`
``
1303
`+
also,
`
``
1304
`+
tcx.def_kind_descr(kind, def_id)
`
``
1305
`+
);
`
``
1306
`+
lint.span_note(tcx.def_span(def_id), note_msg);
`
``
1307
`+
};
`
``
1308
+
``
1309
`+
could_refer_to(DefKind::Variant, variant_def_id, "");
`
``
1310
`+
could_refer_to(mode.def_kind(), item_def_id, " also");
`
``
1311
+
``
1312
`+
lint.span_suggestion(
`
``
1313
`+
span,
`
``
1314
`+
"use fully-qualified syntax",
`
``
1315
`+
format!(
`
``
1316
`+
"<{} as {}>::{}",
`
``
1317
`+
self_ty,
`
``
1318
`+
tcx.item_name(bound.def_id()),
`
``
1319
`+
segment.ident
`
``
1320
`+
),
`
``
1321
`+
Applicability::MachineApplicable,
`
``
1322
`+
);
`
``
1323
`+
});
`
``
1324
`+
}
`
``
1325
+
``
1326
`+
Ok(TypeRelativePath::AssocItem(item_def_id, args))
`
``
1327
`+
}
`
``
1328
+
``
1329
`+
/// Resolve a type-relative (and type-level) path.
`
``
1330
`+
fn resolve_type_relative_path(
`
``
1331
`+
&self,
`
``
1332
`+
self_ty: Ty<'tcx>,
`
``
1333
`+
hir_self_ty: &'tcx hir::Ty<'tcx>,
`
``
1334
`+
assoc_tag: ty::AssocTag,
`
``
1335
`+
segment: &'tcx hir::PathSegment<'tcx>,
`
``
1336
`+
qpath_hir_id: HirId,
`
``
1337
`+
span: Span,
`
``
1338
`+
variant_def_id: Option,
`
``
1339
`+
) -> Result<(DefId, ty::PolyTraitRef<'tcx>), ErrorGuaranteed> {
`
``
1340
`+
let tcx = self.tcx();
`
``
1341
+
1285
1342
`let self_ty_res = match hir_self_ty.kind {
`
1286
1343
` hir::TyKind::Path(hir::QPath::Resolved(_, path)) => path.res,
`
1287
1344
` _ => Res::Err,
`
1288
1345
`};
`
1289
1346
``
1290
``
`-
// Find the type of the associated item, and the trait where the associated
`
1291
``
`-
// item is declared.
`
``
1347
`+
// Find the type of the assoc item, and the trait where the associated item is declared.
`
1292
1348
`let bound = match (self_ty.kind(), self_ty_res) {
`
1293
1349
`(_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
`
1294
1350
`` // Self
in an impl of a trait -- we have a concrete self type and a
``
`@@ -1300,14 +1356,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1300
1356
``
1301
1357
`self.probe_single_bound_for_assoc_item(
`
1302
1358
` || {
`
1303
``
`-
traits::supertraits(
`
1304
``
`-
tcx,
`
1305
``
`-
ty::Binder::dummy(trait_ref.instantiate_identity()),
`
1306
``
`-
)
`
``
1359
`+
let trait_ref = ty::Binder::dummy(trait_ref.instantiate_identity());
`
``
1360
`+
traits::supertraits(tcx, trait_ref)
`
1307
1361
`},
`
1308
1362
`AssocItemQSelf::SelfTyAlias,
`
1309
``
`-
mode.assoc_tag(),
`
1310
``
`-
ident,
`
``
1363
`+
assoc_tag,
`
``
1364
`+
segment.ident,
`
1311
1365
` span,
`
1312
1366
`None,
`
1313
1367
`)?
`
`@@ -1318,55 +1372,28 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
`
1318
1372
`) => self.probe_single_ty_param_bound_for_assoc_item(
`
1319
1373
` param_did.expect_local(),
`
1320
1374
` hir_self_ty.span,
`
1321
``
`-
mode.assoc_tag(),
`
1322
``
`-
ident,
`
``
1375
`+
assoc_tag,
`
``
1376
`+
segment.ident,
`
1323
1377
` span,
`
1324
1378
`)?,
`
1325
1379
` _ => {
`
1326
1380
`return Err(self.report_unresolved_type_relative_path(
`
1327
1381
` self_ty,
`
1328
1382
` hir_self_ty,
`
1329
``
`-
mode.assoc_tag(),
`
1330
``
`-
ident,
`
``
1383
`+
assoc_tag,
`
``
1384
`+
segment.ident,
`
1331
1385
` qpath_hir_id,
`
1332
1386
` span,
`
1333
1387
` variant_def_id,
`
1334
1388
`));
`
1335
1389
`}
`
1336
1390
`};
`
1337
1391
``
1338
``
`-
let trait_def_id = bound.def_id();
`
1339
1392
`let assoc_item = self
`
1340
``
`-
.probe_assoc_item(ident, mode.assoc_tag(), qpath_hir_id, span, trait_def_id)
`
``
1393
`+
.probe_assoc_item(segment.ident, assoc_tag, qpath_hir_id, span, bound.def_id())
`
1341
1394
`.expect("failed to find associated item");
`
1342
``
`-
let (def_id, args) = self.lower_assoc_item_path(span, assoc_item.def_id, segment, bound)?;
`
1343
``
`-
let result = TypeRelativePath::AssocItem(def_id, args);
`
1344
``
-
1345
``
`-
if let Some(variant_def_id) = variant_def_id {
`
1346
``
`-
tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, qpath_hir_id, span, |lint| {
`
1347
``
`-
lint.primary_message("ambiguous associated item");
`
1348
``
`-
let mut could_refer_to = |kind: DefKind, def_id, also| {
`
1349
``
`-
let note_msg = format!(
`
1350
``
`` -
"{}
could{} refer to the {} defined here",
``
1351
``
`-
ident,
`
1352
``
`-
also,
`
1353
``
`-
tcx.def_kind_descr(kind, def_id)
`
1354
``
`-
);
`
1355
``
`-
lint.span_note(tcx.def_span(def_id), note_msg);
`
1356
``
`-
};
`
1357
1395
``
1358
``
`-
could_refer_to(DefKind::Variant, variant_def_id, "");
`
1359
``
`-
could_refer_to(mode.def_kind(), assoc_item.def_id, " also");
`
1360
``
-
1361
``
`-
lint.span_suggestion(
`
1362
``
`-
span,
`
1363
``
`-
"use fully-qualified syntax",
`
1364
``
`-
format!("<{} as {}>::{}", self_ty, tcx.item_name(trait_def_id), ident),
`
1365
``
`-
Applicability::MachineApplicable,
`
1366
``
`-
);
`
1367
``
`-
});
`
1368
``
`-
}
`
1369
``
`-
Ok(result)
`
``
1396
`+
Ok((assoc_item.def_id, bound))
`
1370
1397
`}
`
1371
1398
``
1372
1399
`/// Search for inherent associated items for use at the type level.
`