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.

`