• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Conversion from AST representation of types to the `ty.rs` representation.
2 //! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
3 //! instance of `AstConv`.
4 
5 mod bounds;
6 mod errors;
7 pub mod generics;
8 mod lint;
9 mod object_safety;
10 
11 use crate::astconv::errors::prohibit_assoc_ty_binding;
12 use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
13 use crate::bounds::Bounds;
14 use crate::collect::HirPlaceholderCollector;
15 use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
16 use crate::middle::resolve_bound_vars as rbv;
17 use crate::require_c_abi_if_c_variadic;
18 use rustc_ast::TraitObjectSyntax;
19 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
20 use rustc_errors::{
21     struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
22     MultiSpan,
23 };
24 use rustc_hir as hir;
25 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
26 use rustc_hir::def_id::{DefId, LocalDefId};
27 use rustc_hir::intravisit::{walk_generics, Visitor as _};
28 use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
29 use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
30 use rustc_infer::traits::ObligationCause;
31 use rustc_middle::middle::stability::AllowUnstable;
32 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
33 use rustc_middle::ty::GenericParamDefKind;
34 use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
35 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
36 use rustc_span::edit_distance::find_best_match_for_name;
37 use rustc_span::symbol::{kw, Ident, Symbol};
38 use rustc_span::{sym, Span, DUMMY_SP};
39 use rustc_target::spec::abi;
40 use rustc_trait_selection::traits::wf::object_region_bounds;
41 use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCtxt};
42 use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
43 
44 use std::fmt::Display;
45 use std::slice;
46 
47 #[derive(Debug)]
48 pub struct PathSeg(pub DefId, pub usize);
49 
50 #[derive(Copy, Clone, Debug)]
51 pub struct OnlySelfBounds(pub bool);
52 
53 #[derive(Copy, Clone, Debug)]
54 pub enum PredicateFilter {
55     /// All predicates may be implied by the trait.
56     All,
57 
58     /// Only traits that reference `Self: ..` are implied by the trait.
59     SelfOnly,
60 
61     /// Only traits that reference `Self: ..` and define an associated type
62     /// with the given ident are implied by the trait.
63     SelfThatDefines(Ident),
64 
65     /// Only traits that reference `Self: ..` and their associated type bounds.
66     /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
67     /// and `<Self as Tr>::A: B`.
68     SelfAndAssociatedTypeBounds,
69 }
70 
71 pub trait AstConv<'tcx> {
tcx(&self) -> TyCtxt<'tcx>72     fn tcx(&self) -> TyCtxt<'tcx>;
73 
item_def_id(&self) -> DefId74     fn item_def_id(&self) -> DefId;
75 
76     /// Returns predicates in scope of the form `X: Foo<T>`, where `X`
77     /// is a type parameter `X` with the given id `def_id` and T
78     /// matches `assoc_name`. This is a subset of the full set of
79     /// predicates.
80     ///
81     /// This is used for one specific purpose: resolving "short-hand"
82     /// associated type references like `T::Item`. In principle, we
83     /// would do that by first getting the full set of predicates in
84     /// scope and then filtering down to find those that apply to `T`,
85     /// but this can lead to cycle errors. The problem is that we have
86     /// to do this resolution *in order to create the predicates in
87     /// the first place*. Hence, we have this "special pass".
get_type_parameter_bounds( &self, span: Span, def_id: LocalDefId, assoc_name: Ident, ) -> ty::GenericPredicates<'tcx>88     fn get_type_parameter_bounds(
89         &self,
90         span: Span,
91         def_id: LocalDefId,
92         assoc_name: Ident,
93     ) -> ty::GenericPredicates<'tcx>;
94 
95     /// Returns the lifetime to use when a lifetime is omitted (and not elided).
re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Option<ty::Region<'tcx>>96     fn re_infer(&self, param: Option<&ty::GenericParamDef>, span: Span)
97     -> Option<ty::Region<'tcx>>;
98 
99     /// Returns the type to use when a type is omitted.
ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>100     fn ty_infer(&self, param: Option<&ty::GenericParamDef>, span: Span) -> Ty<'tcx>;
101 
102     /// Returns `true` if `_` is allowed in type signatures in the current context.
allow_ty_infer(&self) -> bool103     fn allow_ty_infer(&self) -> bool;
104 
105     /// Returns the const to use when a const is omitted.
ct_infer( &self, ty: Ty<'tcx>, param: Option<&ty::GenericParamDef>, span: Span, ) -> Const<'tcx>106     fn ct_infer(
107         &self,
108         ty: Ty<'tcx>,
109         param: Option<&ty::GenericParamDef>,
110         span: Span,
111     ) -> Const<'tcx>;
112 
113     /// Projecting an associated type from a (potentially)
114     /// higher-ranked trait reference is more complicated, because of
115     /// the possibility of late-bound regions appearing in the
116     /// associated type binding. This is not legal in function
117     /// signatures for that reason. In a function body, we can always
118     /// handle it because we can use inference variables to remove the
119     /// late-bound regions.
projected_ty_from_poly_trait_ref( &self, span: Span, item_def_id: DefId, item_segment: &hir::PathSegment<'_>, poly_trait_ref: ty::PolyTraitRef<'tcx>, ) -> Ty<'tcx>120     fn projected_ty_from_poly_trait_ref(
121         &self,
122         span: Span,
123         item_def_id: DefId,
124         item_segment: &hir::PathSegment<'_>,
125         poly_trait_ref: ty::PolyTraitRef<'tcx>,
126     ) -> Ty<'tcx>;
127 
128     /// Returns `AdtDef` if `ty` is an ADT.
129     /// Note that `ty` might be a projection type that needs normalization.
130     /// This used to get the enum variants in scope of the type.
131     /// For example, `Self::A` could refer to an associated type
132     /// or to an enum variant depending on the result of this function.
probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>133     fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>>;
134 
135     /// Invoked when we encounter an error from some prior pass
136     /// (e.g., resolve) that is translated into a ty-error. This is
137     /// used to help suppress derived errors typeck might otherwise
138     /// report.
set_tainted_by_errors(&self, e: ErrorGuaranteed)139     fn set_tainted_by_errors(&self, e: ErrorGuaranteed);
140 
record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span)141     fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
142 
astconv(&self) -> &dyn AstConv<'tcx> where Self: Sized,143     fn astconv(&self) -> &dyn AstConv<'tcx>
144     where
145         Self: Sized,
146     {
147         self
148     }
149 
infcx(&self) -> Option<&InferCtxt<'tcx>>150     fn infcx(&self) -> Option<&InferCtxt<'tcx>>;
151 }
152 
153 #[derive(Debug)]
154 struct ConvertedBinding<'a, 'tcx> {
155     hir_id: hir::HirId,
156     item_name: Ident,
157     kind: ConvertedBindingKind<'a, 'tcx>,
158     gen_args: &'a GenericArgs<'a>,
159     span: Span,
160 }
161 
162 #[derive(Debug)]
163 enum ConvertedBindingKind<'a, 'tcx> {
164     Equality(ty::Term<'tcx>),
165     Constraint(&'a [hir::GenericBound<'a>]),
166 }
167 
168 /// New-typed boolean indicating whether explicit late-bound lifetimes
169 /// are present in a set of generic arguments.
170 ///
171 /// For example if we have some method `fn f<'a>(&'a self)` implemented
172 /// for some type `T`, although `f` is generic in the lifetime `'a`, `'a`
173 /// is late-bound so should not be provided explicitly. Thus, if `f` is
174 /// instantiated with some generic arguments providing `'a` explicitly,
175 /// we taint those arguments with `ExplicitLateBound::Yes` so that we
176 /// can provide an appropriate diagnostic later.
177 #[derive(Copy, Clone, PartialEq, Debug)]
178 pub enum ExplicitLateBound {
179     Yes,
180     No,
181 }
182 
183 #[derive(Copy, Clone, PartialEq)]
184 pub enum IsMethodCall {
185     Yes,
186     No,
187 }
188 
189 /// Denotes the "position" of a generic argument, indicating if it is a generic type,
190 /// generic function or generic method call.
191 #[derive(Copy, Clone, PartialEq)]
192 pub(crate) enum GenericArgPosition {
193     Type,
194     Value, // e.g., functions
195     MethodCall,
196 }
197 
198 /// A marker denoting that the generic arguments that were
199 /// provided did not match the respective generic parameters.
200 #[derive(Clone, Default, Debug)]
201 pub struct GenericArgCountMismatch {
202     /// Indicates whether a fatal error was reported (`Some`), or just a lint (`None`).
203     pub reported: Option<ErrorGuaranteed>,
204     /// A list of spans of arguments provided that were not valid.
205     pub invalid_args: Vec<Span>,
206 }
207 
208 /// Decorates the result of a generic argument count mismatch
209 /// check with whether explicit late bounds were provided.
210 #[derive(Clone, Debug)]
211 pub struct GenericArgCountResult {
212     pub explicit_late_bound: ExplicitLateBound,
213     pub correct: Result<(), GenericArgCountMismatch>,
214 }
215 
216 pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'a>>, bool)217     fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'a>>, bool);
218 
provided_kind( &mut self, param: &ty::GenericParamDef, arg: &GenericArg<'_>, ) -> subst::GenericArg<'tcx>219     fn provided_kind(
220         &mut self,
221         param: &ty::GenericParamDef,
222         arg: &GenericArg<'_>,
223     ) -> subst::GenericArg<'tcx>;
224 
inferred_kind( &mut self, substs: Option<&[subst::GenericArg<'tcx>]>, param: &ty::GenericParamDef, infer_args: bool, ) -> subst::GenericArg<'tcx>225     fn inferred_kind(
226         &mut self,
227         substs: Option<&[subst::GenericArg<'tcx>]>,
228         param: &ty::GenericParamDef,
229         infer_args: bool,
230     ) -> subst::GenericArg<'tcx>;
231 }
232 
233 impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
234     #[instrument(level = "debug", skip(self), ret)]
ast_region_to_region( &self, lifetime: &hir::Lifetime, def: Option<&ty::GenericParamDef>, ) -> ty::Region<'tcx>235     pub fn ast_region_to_region(
236         &self,
237         lifetime: &hir::Lifetime,
238         def: Option<&ty::GenericParamDef>,
239     ) -> ty::Region<'tcx> {
240         let tcx = self.tcx();
241         let lifetime_name = |def_id| tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id));
242 
243         match tcx.named_bound_var(lifetime.hir_id) {
244             Some(rbv::ResolvedArg::StaticLifetime) => tcx.lifetimes.re_static,
245 
246             Some(rbv::ResolvedArg::LateBound(debruijn, index, def_id)) => {
247                 let name = lifetime_name(def_id.expect_local());
248                 let br = ty::BoundRegion {
249                     var: ty::BoundVar::from_u32(index),
250                     kind: ty::BrNamed(def_id, name),
251                 };
252                 ty::Region::new_late_bound(tcx, debruijn, br)
253             }
254 
255             Some(rbv::ResolvedArg::EarlyBound(def_id)) => {
256                 let name = tcx.hir().ty_param_name(def_id.expect_local());
257                 let item_def_id = tcx.hir().ty_param_owner(def_id.expect_local());
258                 let generics = tcx.generics_of(item_def_id);
259                 let index = generics.param_def_id_to_index[&def_id];
260                 ty::Region::new_early_bound(tcx, ty::EarlyBoundRegion { def_id, index, name })
261             }
262 
263             Some(rbv::ResolvedArg::Free(scope, id)) => {
264                 let name = lifetime_name(id.expect_local());
265                 ty::Region::new_free(tcx, scope, ty::BrNamed(id, name))
266 
267                 // (*) -- not late-bound, won't change
268             }
269 
270             Some(rbv::ResolvedArg::Error(_)) => {
271                 bug!("only ty/ct should resolve as ResolvedArg::Error")
272             }
273 
274             None => {
275                 self.re_infer(def, lifetime.ident.span).unwrap_or_else(|| {
276                     debug!(?lifetime, "unelided lifetime in signature");
277 
278                     // This indicates an illegal lifetime
279                     // elision. `resolve_lifetime` should have
280                     // reported an error in this case -- but if
281                     // not, let's error out.
282                     ty::Region::new_error_with_message(
283                         tcx,
284                         lifetime.ident.span,
285                         "unelided lifetime in signature",
286                     )
287                 })
288             }
289         }
290     }
291 
292     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
293     /// returns an appropriate set of substitutions for this particular reference to `I`.
ast_path_substs_for_ty( &self, span: Span, def_id: DefId, item_segment: &hir::PathSegment<'_>, ) -> SubstsRef<'tcx>294     pub fn ast_path_substs_for_ty(
295         &self,
296         span: Span,
297         def_id: DefId,
298         item_segment: &hir::PathSegment<'_>,
299     ) -> SubstsRef<'tcx> {
300         let (substs, _) = self.create_substs_for_ast_path(
301             span,
302             def_id,
303             &[],
304             item_segment,
305             item_segment.args(),
306             item_segment.infer_args,
307             None,
308             ty::BoundConstness::NotConst,
309         );
310         if let Some(b) = item_segment.args().bindings.first() {
311             prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
312         }
313 
314         substs
315     }
316 
317     /// Given the type/lifetime/const arguments provided to some path (along with
318     /// an implicit `Self`, if this is a trait reference), returns the complete
319     /// set of substitutions. This may involve applying defaulted type parameters.
320     /// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`.
321     ///
322     /// Example:
323     ///
324     /// ```ignore (illustrative)
325     ///    T: std::ops::Index<usize, Output = u32>
326     /// // ^1 ^^^^^^^^^^^^^^2 ^^^^3  ^^^^^^^^^^^4
327     /// ```
328     ///
329     /// 1. The `self_ty` here would refer to the type `T`.
330     /// 2. The path in question is the path to the trait `std::ops::Index`,
331     ///    which will have been resolved to a `def_id`
332     /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type
333     ///    parameters are returned in the `SubstsRef`, the associated type bindings like
334     ///    `Output = u32` are returned from `create_assoc_bindings_for_generic_args`.
335     ///
336     /// Note that the type listing given here is *exactly* what the user provided.
337     ///
338     /// For (generic) associated types
339     ///
340     /// ```ignore (illustrative)
341     /// <Vec<u8> as Iterable<u8>>::Iter::<'a>
342     /// ```
343     ///
344     /// We have the parent substs are the substs for the parent trait:
345     /// `[Vec<u8>, u8]` and `generic_args` are the arguments for the associated
346     /// type itself: `['a]`. The returned `SubstsRef` concatenates these two
347     /// lists: `[Vec<u8>, u8, 'a]`.
348     #[instrument(level = "debug", skip(self, span), ret)]
create_substs_for_ast_path<'a>( &self, span: Span, def_id: DefId, parent_substs: &[subst::GenericArg<'tcx>], seg: &hir::PathSegment<'_>, generic_args: &'a hir::GenericArgs<'_>, infer_args: bool, self_ty: Option<Ty<'tcx>>, constness: ty::BoundConstness, ) -> (SubstsRef<'tcx>, GenericArgCountResult)349     fn create_substs_for_ast_path<'a>(
350         &self,
351         span: Span,
352         def_id: DefId,
353         parent_substs: &[subst::GenericArg<'tcx>],
354         seg: &hir::PathSegment<'_>,
355         generic_args: &'a hir::GenericArgs<'_>,
356         infer_args: bool,
357         self_ty: Option<Ty<'tcx>>,
358         constness: ty::BoundConstness,
359     ) -> (SubstsRef<'tcx>, GenericArgCountResult) {
360         // If the type is parameterized by this region, then replace this
361         // region with the current anon region binding (in other words,
362         // whatever & would get replaced with).
363 
364         let tcx = self.tcx();
365         let generics = tcx.generics_of(def_id);
366         debug!("generics: {:?}", generics);
367 
368         if generics.has_self {
369             if generics.parent.is_some() {
370                 // The parent is a trait so it should have at least one subst
371                 // for the `Self` type.
372                 assert!(!parent_substs.is_empty())
373             } else {
374                 // This item (presumably a trait) needs a self-type.
375                 assert!(self_ty.is_some());
376             }
377         } else {
378             assert!(self_ty.is_none());
379         }
380 
381         let arg_count = check_generic_arg_count(
382             tcx,
383             span,
384             def_id,
385             seg,
386             generics,
387             generic_args,
388             GenericArgPosition::Type,
389             self_ty.is_some(),
390             infer_args,
391         );
392 
393         // Skip processing if type has no generic parameters.
394         // Traits always have `Self` as a generic parameter, which means they will not return early
395         // here and so associated type bindings will be handled regardless of whether there are any
396         // non-`Self` generic parameters.
397         if generics.params.is_empty() {
398             return (tcx.mk_substs(parent_substs), arg_count);
399         }
400 
401         struct SubstsForAstPathCtxt<'a, 'tcx> {
402             astconv: &'a (dyn AstConv<'tcx> + 'a),
403             def_id: DefId,
404             generic_args: &'a GenericArgs<'a>,
405             span: Span,
406             inferred_params: Vec<Span>,
407             infer_args: bool,
408         }
409 
410         impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
411             fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'a>>, bool) {
412                 if did == self.def_id {
413                     (Some(self.generic_args), self.infer_args)
414                 } else {
415                     // The last component of this tuple is unimportant.
416                     (None, false)
417                 }
418             }
419 
420             fn provided_kind(
421                 &mut self,
422                 param: &ty::GenericParamDef,
423                 arg: &GenericArg<'_>,
424             ) -> subst::GenericArg<'tcx> {
425                 let tcx = self.astconv.tcx();
426 
427                 let mut handle_ty_args = |has_default, ty: &hir::Ty<'_>| {
428                     if has_default {
429                         tcx.check_optional_stability(
430                             param.def_id,
431                             Some(arg.hir_id()),
432                             arg.span(),
433                             None,
434                             AllowUnstable::No,
435                             |_, _| {
436                                 // Default generic parameters may not be marked
437                                 // with stability attributes, i.e. when the
438                                 // default parameter was defined at the same time
439                                 // as the rest of the type. As such, we ignore missing
440                                 // stability attributes.
441                             },
442                         );
443                     }
444                     if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) {
445                         self.inferred_params.push(ty.span);
446                         Ty::new_misc_error(tcx).into()
447                     } else {
448                         self.astconv.ast_ty_to_ty(ty).into()
449                     }
450                 };
451 
452                 match (&param.kind, arg) {
453                     (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
454                         self.astconv.ast_region_to_region(lt, Some(param)).into()
455                     }
456                     (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Type(ty)) => {
457                         handle_ty_args(has_default, ty)
458                     }
459                     (&GenericParamDefKind::Type { has_default, .. }, GenericArg::Infer(inf)) => {
460                         handle_ty_args(has_default, &inf.to_ty())
461                     }
462                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
463                         let did = ct.value.def_id;
464                         tcx.feed_anon_const_type(did, tcx.type_of(param.def_id));
465                         ty::Const::from_anon_const(tcx, did).into()
466                     }
467                     (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
468                         let ty = tcx
469                             .at(self.span)
470                             .type_of(param.def_id)
471                             .no_bound_vars()
472                             .expect("const parameter types cannot be generic");
473                         if self.astconv.allow_ty_infer() {
474                             self.astconv.ct_infer(ty, Some(param), inf.span).into()
475                         } else {
476                             self.inferred_params.push(inf.span);
477                             ty::Const::new_misc_error(tcx, ty).into()
478                         }
479                     }
480                     _ => unreachable!(),
481                 }
482             }
483 
484             fn inferred_kind(
485                 &mut self,
486                 substs: Option<&[subst::GenericArg<'tcx>]>,
487                 param: &ty::GenericParamDef,
488                 infer_args: bool,
489             ) -> subst::GenericArg<'tcx> {
490                 let tcx = self.astconv.tcx();
491                 match param.kind {
492                     GenericParamDefKind::Lifetime => self
493                         .astconv
494                         .re_infer(Some(param), self.span)
495                         .unwrap_or_else(|| {
496                             debug!(?param, "unelided lifetime in signature");
497 
498                             // This indicates an illegal lifetime in a non-assoc-trait position
499                             ty::Region::new_error_with_message(
500                                 tcx,
501                                 self.span,
502                                 "unelided lifetime in signature",
503                             )
504                         })
505                         .into(),
506                     GenericParamDefKind::Type { has_default, .. } => {
507                         if !infer_args && has_default {
508                             // No type parameter provided, but a default exists.
509                             let substs = substs.unwrap();
510                             if substs.iter().any(|arg| match arg.unpack() {
511                                 GenericArgKind::Type(ty) => ty.references_error(),
512                                 _ => false,
513                             }) {
514                                 // Avoid ICE #86756 when type error recovery goes awry.
515                                 return Ty::new_misc_error(tcx).into();
516                             }
517                             tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into()
518                         } else if infer_args {
519                             self.astconv.ty_infer(Some(param), self.span).into()
520                         } else {
521                             // We've already errored above about the mismatch.
522                             Ty::new_misc_error(tcx).into()
523                         }
524                     }
525                     GenericParamDefKind::Const { has_default } => {
526                         let ty = tcx
527                             .at(self.span)
528                             .type_of(param.def_id)
529                             .no_bound_vars()
530                             .expect("const parameter types cannot be generic");
531                         if let Err(guar) = ty.error_reported() {
532                             return ty::Const::new_error(tcx, guar, ty).into();
533                         }
534                         if !infer_args && has_default {
535                             tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
536                         } else {
537                             if infer_args {
538                                 self.astconv.ct_infer(ty, Some(param), self.span).into()
539                             } else {
540                                 // We've already errored above about the mismatch.
541                                 ty::Const::new_misc_error(tcx, ty).into()
542                             }
543                         }
544                     }
545                 }
546             }
547         }
548 
549         let mut substs_ctx = SubstsForAstPathCtxt {
550             astconv: self,
551             def_id,
552             span,
553             generic_args,
554             inferred_params: vec![],
555             infer_args,
556         };
557         let substs = create_substs_for_generic_args(
558             tcx,
559             def_id,
560             parent_substs,
561             self_ty.is_some(),
562             self_ty,
563             &arg_count,
564             &mut substs_ctx,
565         );
566 
567         if let ty::BoundConstness::ConstIfConst = constness
568             && generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
569         {
570             tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
571         }
572 
573         (substs, arg_count)
574     }
575 
create_assoc_bindings_for_generic_args<'a>( &self, generic_args: &'a hir::GenericArgs<'_>, ) -> Vec<ConvertedBinding<'a, 'tcx>>576     fn create_assoc_bindings_for_generic_args<'a>(
577         &self,
578         generic_args: &'a hir::GenericArgs<'_>,
579     ) -> Vec<ConvertedBinding<'a, 'tcx>> {
580         // Convert associated-type bindings or constraints into a separate vector.
581         // Example: Given this:
582         //
583         //     T: Iterator<Item = u32>
584         //
585         // The `T` is passed in as a self-type; the `Item = u32` is
586         // not a "type parameter" of the `Iterator` trait, but rather
587         // a restriction on `<T as Iterator>::Item`, so it is passed
588         // back separately.
589         let assoc_bindings = generic_args
590             .bindings
591             .iter()
592             .map(|binding| {
593                 let kind = match &binding.kind {
594                     hir::TypeBindingKind::Equality { term } => match term {
595                         hir::Term::Ty(ty) => {
596                             ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty).into())
597                         }
598                         hir::Term::Const(c) => {
599                             let c = Const::from_anon_const(self.tcx(), c.def_id);
600                             ConvertedBindingKind::Equality(c.into())
601                         }
602                     },
603                     hir::TypeBindingKind::Constraint { bounds } => {
604                         ConvertedBindingKind::Constraint(bounds)
605                     }
606                 };
607                 ConvertedBinding {
608                     hir_id: binding.hir_id,
609                     item_name: binding.ident,
610                     kind,
611                     gen_args: binding.gen_args,
612                     span: binding.span,
613                 }
614             })
615             .collect();
616 
617         assoc_bindings
618     }
619 
create_substs_for_associated_item( &self, span: Span, item_def_id: DefId, item_segment: &hir::PathSegment<'_>, parent_substs: SubstsRef<'tcx>, ) -> SubstsRef<'tcx>620     pub fn create_substs_for_associated_item(
621         &self,
622         span: Span,
623         item_def_id: DefId,
624         item_segment: &hir::PathSegment<'_>,
625         parent_substs: SubstsRef<'tcx>,
626     ) -> SubstsRef<'tcx> {
627         debug!(
628             "create_substs_for_associated_item(span: {:?}, item_def_id: {:?}, item_segment: {:?}",
629             span, item_def_id, item_segment
630         );
631         let (args, _) = self.create_substs_for_ast_path(
632             span,
633             item_def_id,
634             parent_substs,
635             item_segment,
636             item_segment.args(),
637             item_segment.infer_args,
638             None,
639             ty::BoundConstness::NotConst,
640         );
641 
642         if let Some(b) = item_segment.args().bindings.first() {
643             prohibit_assoc_ty_binding(self.tcx(), b.span, Some((item_segment, span)));
644         }
645 
646         args
647     }
648 
649     /// Instantiates the path for the given trait reference, assuming that it's
650     /// bound to a valid trait type. Returns the `DefId` of the defining trait.
651     /// The type _cannot_ be a type other than a trait type.
652     ///
653     /// If the `projections` argument is `None`, then assoc type bindings like `Foo<T = X>`
654     /// are disallowed. Otherwise, they are pushed onto the vector given.
instantiate_mono_trait_ref( &self, trait_ref: &hir::TraitRef<'_>, self_ty: Ty<'tcx>, constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx>655     pub fn instantiate_mono_trait_ref(
656         &self,
657         trait_ref: &hir::TraitRef<'_>,
658         self_ty: Ty<'tcx>,
659         constness: ty::BoundConstness,
660     ) -> ty::TraitRef<'tcx> {
661         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
662 
663         self.ast_path_to_mono_trait_ref(
664             trait_ref.path.span,
665             trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()),
666             self_ty,
667             trait_ref.path.segments.last().unwrap(),
668             true,
669             constness,
670         )
671     }
672 
instantiate_poly_trait_ref_inner( &self, hir_id: hir::HirId, span: Span, binding_span: Option<Span>, constness: ty::BoundConstness, polarity: ty::ImplPolarity, bounds: &mut Bounds<'tcx>, speculative: bool, trait_ref_span: Span, trait_def_id: DefId, trait_segment: &hir::PathSegment<'_>, args: &GenericArgs<'_>, infer_args: bool, self_ty: Ty<'tcx>, only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult673     fn instantiate_poly_trait_ref_inner(
674         &self,
675         hir_id: hir::HirId,
676         span: Span,
677         binding_span: Option<Span>,
678         constness: ty::BoundConstness,
679         polarity: ty::ImplPolarity,
680         bounds: &mut Bounds<'tcx>,
681         speculative: bool,
682         trait_ref_span: Span,
683         trait_def_id: DefId,
684         trait_segment: &hir::PathSegment<'_>,
685         args: &GenericArgs<'_>,
686         infer_args: bool,
687         self_ty: Ty<'tcx>,
688         only_self_bounds: OnlySelfBounds,
689     ) -> GenericArgCountResult {
690         let (substs, arg_count) = self.create_substs_for_ast_path(
691             trait_ref_span,
692             trait_def_id,
693             &[],
694             trait_segment,
695             args,
696             infer_args,
697             Some(self_ty),
698             constness,
699         );
700 
701         let tcx = self.tcx();
702         let bound_vars = tcx.late_bound_vars(hir_id);
703         debug!(?bound_vars);
704 
705         let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
706 
707         let poly_trait_ref =
708             ty::Binder::bind_with_vars(ty::TraitRef::new(tcx, trait_def_id, substs), bound_vars);
709 
710         debug!(?poly_trait_ref, ?assoc_bindings);
711         bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
712 
713         let mut dup_bindings = FxHashMap::default();
714         for binding in &assoc_bindings {
715             // Don't register additional associated type bounds for negative bounds,
716             // since we should have emitten an error for them earlier, and they will
717             // not be well-formed!
718             if polarity == ty::ImplPolarity::Negative {
719                 self.tcx()
720                     .sess
721                     .delay_span_bug(binding.span, "negative trait bounds should not have bindings");
722                 continue;
723             }
724 
725             // Specify type to assert that error was already reported in `Err` case.
726             let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
727                 hir_id,
728                 poly_trait_ref,
729                 binding,
730                 bounds,
731                 speculative,
732                 &mut dup_bindings,
733                 binding_span.unwrap_or(binding.span),
734                 constness,
735                 only_self_bounds,
736                 polarity,
737             );
738             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
739         }
740 
741         arg_count
742     }
743 
744     /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
745     /// a full trait reference. The resulting trait reference is returned. This may also generate
746     /// auxiliary bounds, which are added to `bounds`.
747     ///
748     /// Example:
749     ///
750     /// ```ignore (illustrative)
751     /// poly_trait_ref = Iterator<Item = u32>
752     /// self_ty = Foo
753     /// ```
754     ///
755     /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
756     ///
757     /// **A note on binders:** against our usual convention, there is an implied bounder around
758     /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
759     /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
760     /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
761     /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
762     /// however.
763     #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
instantiate_poly_trait_ref( &self, trait_ref: &hir::TraitRef<'_>, span: Span, constness: ty::BoundConstness, polarity: ty::ImplPolarity, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, speculative: bool, only_self_bounds: OnlySelfBounds, ) -> GenericArgCountResult764     pub(crate) fn instantiate_poly_trait_ref(
765         &self,
766         trait_ref: &hir::TraitRef<'_>,
767         span: Span,
768         constness: ty::BoundConstness,
769         polarity: ty::ImplPolarity,
770         self_ty: Ty<'tcx>,
771         bounds: &mut Bounds<'tcx>,
772         speculative: bool,
773         only_self_bounds: OnlySelfBounds,
774     ) -> GenericArgCountResult {
775         let hir_id = trait_ref.hir_ref_id;
776         let binding_span = None;
777         let trait_ref_span = trait_ref.path.span;
778         let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
779         let trait_segment = trait_ref.path.segments.last().unwrap();
780         let args = trait_segment.args();
781         let infer_args = trait_segment.infer_args;
782 
783         self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
784         self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
785 
786         self.instantiate_poly_trait_ref_inner(
787             hir_id,
788             span,
789             binding_span,
790             constness,
791             polarity,
792             bounds,
793             speculative,
794             trait_ref_span,
795             trait_def_id,
796             trait_segment,
797             args,
798             infer_args,
799             self_ty,
800             only_self_bounds,
801         )
802     }
803 
instantiate_lang_item_trait_ref( &self, lang_item: hir::LangItem, span: Span, hir_id: hir::HirId, args: &GenericArgs<'_>, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, only_self_bounds: OnlySelfBounds, )804     pub(crate) fn instantiate_lang_item_trait_ref(
805         &self,
806         lang_item: hir::LangItem,
807         span: Span,
808         hir_id: hir::HirId,
809         args: &GenericArgs<'_>,
810         self_ty: Ty<'tcx>,
811         bounds: &mut Bounds<'tcx>,
812         only_self_bounds: OnlySelfBounds,
813     ) {
814         let binding_span = Some(span);
815         let constness = ty::BoundConstness::NotConst;
816         let speculative = false;
817         let trait_ref_span = span;
818         let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
819         let trait_segment = &hir::PathSegment::invalid();
820         let infer_args = false;
821 
822         self.instantiate_poly_trait_ref_inner(
823             hir_id,
824             span,
825             binding_span,
826             constness,
827             ty::ImplPolarity::Positive,
828             bounds,
829             speculative,
830             trait_ref_span,
831             trait_def_id,
832             trait_segment,
833             args,
834             infer_args,
835             self_ty,
836             only_self_bounds,
837         );
838     }
839 
ast_path_to_mono_trait_ref( &self, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, trait_segment: &hir::PathSegment<'_>, is_impl: bool, constness: ty::BoundConstness, ) -> ty::TraitRef<'tcx>840     fn ast_path_to_mono_trait_ref(
841         &self,
842         span: Span,
843         trait_def_id: DefId,
844         self_ty: Ty<'tcx>,
845         trait_segment: &hir::PathSegment<'_>,
846         is_impl: bool,
847         constness: ty::BoundConstness,
848     ) -> ty::TraitRef<'tcx> {
849         let (substs, _) = self.create_substs_for_ast_trait_ref(
850             span,
851             trait_def_id,
852             self_ty,
853             trait_segment,
854             is_impl,
855             constness,
856         );
857         if let Some(b) = trait_segment.args().bindings.first() {
858             prohibit_assoc_ty_binding(self.tcx(), b.span, Some((trait_segment, span)));
859         }
860         ty::TraitRef::new(self.tcx(), trait_def_id, substs)
861     }
862 
863     #[instrument(level = "debug", skip(self, span))]
create_substs_for_ast_trait_ref<'a>( &self, span: Span, trait_def_id: DefId, self_ty: Ty<'tcx>, trait_segment: &'a hir::PathSegment<'a>, is_impl: bool, constness: ty::BoundConstness, ) -> (SubstsRef<'tcx>, GenericArgCountResult)864     fn create_substs_for_ast_trait_ref<'a>(
865         &self,
866         span: Span,
867         trait_def_id: DefId,
868         self_ty: Ty<'tcx>,
869         trait_segment: &'a hir::PathSegment<'a>,
870         is_impl: bool,
871         constness: ty::BoundConstness,
872     ) -> (SubstsRef<'tcx>, GenericArgCountResult) {
873         self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, is_impl);
874 
875         self.create_substs_for_ast_path(
876             span,
877             trait_def_id,
878             &[],
879             trait_segment,
880             trait_segment.args(),
881             trait_segment.infer_args,
882             Some(self_ty),
883             constness,
884         )
885     }
886 
trait_defines_associated_item_named( &self, trait_def_id: DefId, assoc_kind: ty::AssocKind, assoc_name: Ident, ) -> bool887     fn trait_defines_associated_item_named(
888         &self,
889         trait_def_id: DefId,
890         assoc_kind: ty::AssocKind,
891         assoc_name: Ident,
892     ) -> bool {
893         self.tcx()
894             .associated_items(trait_def_id)
895             .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id)
896             .is_some()
897     }
898 
ast_path_to_ty( &self, span: Span, did: DefId, item_segment: &hir::PathSegment<'_>, ) -> Ty<'tcx>899     fn ast_path_to_ty(
900         &self,
901         span: Span,
902         did: DefId,
903         item_segment: &hir::PathSegment<'_>,
904     ) -> Ty<'tcx> {
905         let substs = self.ast_path_substs_for_ty(span, did, item_segment);
906         let ty = self.tcx().at(span).type_of(did);
907 
908         if matches!(self.tcx().def_kind(did), DefKind::TyAlias)
909             && (ty.skip_binder().has_opaque_types() || self.tcx().features().lazy_type_alias)
910         {
911             // Type aliases referring to types that contain opaque types (but aren't just directly
912             // referencing a single opaque type) get encoded as a type alias that normalization will
913             // then actually instantiate the where bounds of.
914             let alias_ty = self.tcx().mk_alias_ty(did, substs);
915             Ty::new_alias(self.tcx(), ty::Weak, alias_ty)
916         } else {
917             ty.subst(self.tcx(), substs)
918         }
919     }
920 
report_ambiguous_associated_type( &self, span: Span, types: &[String], traits: &[String], name: Symbol, ) -> ErrorGuaranteed921     fn report_ambiguous_associated_type(
922         &self,
923         span: Span,
924         types: &[String],
925         traits: &[String],
926         name: Symbol,
927     ) -> ErrorGuaranteed {
928         let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
929         if self
930             .tcx()
931             .resolutions(())
932             .confused_type_with_std_module
933             .keys()
934             .any(|full_span| full_span.contains(span))
935         {
936             err.span_suggestion_verbose(
937                 span.shrink_to_lo(),
938                 "you are looking for the module in `std`, not the primitive type",
939                 "std::",
940                 Applicability::MachineApplicable,
941             );
942         } else {
943             match (types, traits) {
944                 ([], []) => {
945                     err.span_suggestion_verbose(
946                         span,
947                         format!(
948                             "if there were a type named `Type` that implements a trait named \
949                              `Trait` with associated type `{name}`, you could use the \
950                              fully-qualified path",
951                         ),
952                         format!("<Type as Trait>::{name}"),
953                         Applicability::HasPlaceholders,
954                     );
955                 }
956                 ([], [trait_str]) => {
957                     err.span_suggestion_verbose(
958                         span,
959                         format!(
960                             "if there were a type named `Example` that implemented `{trait_str}`, \
961                              you could use the fully-qualified path",
962                         ),
963                         format!("<Example as {trait_str}>::{name}"),
964                         Applicability::HasPlaceholders,
965                     );
966                 }
967                 ([], traits) => {
968                     err.span_suggestions(
969                         span,
970                         format!(
971                             "if there were a type named `Example` that implemented one of the \
972                              traits with associated type `{name}`, you could use the \
973                              fully-qualified path",
974                         ),
975                         traits
976                             .iter()
977                             .map(|trait_str| format!("<Example as {trait_str}>::{name}"))
978                             .collect::<Vec<_>>(),
979                         Applicability::HasPlaceholders,
980                     );
981                 }
982                 ([type_str], []) => {
983                     err.span_suggestion_verbose(
984                         span,
985                         format!(
986                             "if there were a trait named `Example` with associated type `{name}` \
987                              implemented for `{type_str}`, you could use the fully-qualified path",
988                         ),
989                         format!("<{type_str} as Example>::{name}"),
990                         Applicability::HasPlaceholders,
991                     );
992                 }
993                 (types, []) => {
994                     err.span_suggestions(
995                         span,
996                         format!(
997                             "if there were a trait named `Example` with associated type `{name}` \
998                              implemented for one of the types, you could use the fully-qualified \
999                              path",
1000                         ),
1001                         types
1002                             .into_iter()
1003                             .map(|type_str| format!("<{type_str} as Example>::{name}")),
1004                         Applicability::HasPlaceholders,
1005                     );
1006                 }
1007                 (types, traits) => {
1008                     let mut suggestions = vec![];
1009                     for type_str in types {
1010                         for trait_str in traits {
1011                             suggestions.push(format!("<{type_str} as {trait_str}>::{name}"));
1012                         }
1013                     }
1014                     err.span_suggestions(
1015                         span,
1016                         "use the fully-qualified path",
1017                         suggestions,
1018                         Applicability::MachineApplicable,
1019                     );
1020                 }
1021             }
1022         }
1023         err.emit()
1024     }
1025 
1026     // Search for a bound on a type parameter which includes the associated item
1027     // given by `assoc_name`. `ty_param_def_id` is the `DefId` of the type parameter
1028     // This function will fail if there are no suitable bounds or there is
1029     // any ambiguity.
find_bound_for_assoc_item( &self, ty_param_def_id: LocalDefId, assoc_name: Ident, span: Span, ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>1030     fn find_bound_for_assoc_item(
1031         &self,
1032         ty_param_def_id: LocalDefId,
1033         assoc_name: Ident,
1034         span: Span,
1035     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
1036         let tcx = self.tcx();
1037 
1038         debug!(
1039             "find_bound_for_assoc_item(ty_param_def_id={:?}, assoc_name={:?}, span={:?})",
1040             ty_param_def_id, assoc_name, span,
1041         );
1042 
1043         let predicates =
1044             &self.get_type_parameter_bounds(span, ty_param_def_id, assoc_name).predicates;
1045 
1046         debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
1047 
1048         let param_name = tcx.hir().ty_param_name(ty_param_def_id);
1049         self.one_bound_for_assoc_type(
1050             || {
1051                 traits::transitive_bounds_that_define_assoc_item(
1052                     tcx,
1053                     predicates
1054                         .iter()
1055                         .filter_map(|(p, _)| Some(p.as_trait_clause()?.map_bound(|t| t.trait_ref))),
1056                     assoc_name,
1057                 )
1058             },
1059             param_name,
1060             assoc_name,
1061             span,
1062             None,
1063         )
1064     }
1065 
1066     // Checks that `bounds` contains exactly one element and reports appropriate
1067     // errors otherwise.
1068     #[instrument(level = "debug", skip(self, all_candidates, ty_param_name, is_equality), ret)]
one_bound_for_assoc_type<I>( &self, all_candidates: impl Fn() -> I, ty_param_name: impl Display, assoc_name: Ident, span: Span, is_equality: Option<ty::Term<'tcx>>, ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> where I: Iterator<Item = ty::PolyTraitRef<'tcx>>,1069     fn one_bound_for_assoc_type<I>(
1070         &self,
1071         all_candidates: impl Fn() -> I,
1072         ty_param_name: impl Display,
1073         assoc_name: Ident,
1074         span: Span,
1075         is_equality: Option<ty::Term<'tcx>>,
1076     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>
1077     where
1078         I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
1079     {
1080         let mut matching_candidates = all_candidates().filter(|r| {
1081             self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Type, assoc_name)
1082         });
1083         let mut const_candidates = all_candidates().filter(|r| {
1084             self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Const, assoc_name)
1085         });
1086 
1087         let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) {
1088             (Some(bound), _) => (bound, matching_candidates.next()),
1089             (None, Some(bound)) => (bound, const_candidates.next()),
1090             (None, None) => {
1091                 let reported = self.complain_about_assoc_type_not_found(
1092                     all_candidates,
1093                     &ty_param_name.to_string(),
1094                     assoc_name,
1095                     span,
1096                 );
1097                 return Err(reported);
1098             }
1099         };
1100         debug!(?bound);
1101 
1102         if let Some(bound2) = next_cand {
1103             debug!(?bound2);
1104 
1105             let bounds = IntoIterator::into_iter([bound, bound2]).chain(matching_candidates);
1106             let mut err = if is_equality.is_some() {
1107                 // More specific Error Index entry.
1108                 struct_span_err!(
1109                     self.tcx().sess,
1110                     span,
1111                     E0222,
1112                     "ambiguous associated type `{}` in bounds of `{}`",
1113                     assoc_name,
1114                     ty_param_name
1115                 )
1116             } else {
1117                 struct_span_err!(
1118                     self.tcx().sess,
1119                     span,
1120                     E0221,
1121                     "ambiguous associated type `{}` in bounds of `{}`",
1122                     assoc_name,
1123                     ty_param_name
1124                 )
1125             };
1126             err.span_label(span, format!("ambiguous associated type `{}`", assoc_name));
1127 
1128             let mut where_bounds = vec![];
1129             for bound in bounds {
1130                 let bound_id = bound.def_id();
1131                 let bound_span = self
1132                     .tcx()
1133                     .associated_items(bound_id)
1134                     .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, bound_id)
1135                     .and_then(|item| self.tcx().hir().span_if_local(item.def_id));
1136 
1137                 if let Some(bound_span) = bound_span {
1138                     err.span_label(
1139                         bound_span,
1140                         format!(
1141                             "ambiguous `{}` from `{}`",
1142                             assoc_name,
1143                             bound.print_only_trait_path(),
1144                         ),
1145                     );
1146                     if let Some(constraint) = &is_equality {
1147                         where_bounds.push(format!(
1148                             "        T: {trait}::{assoc} = {constraint}",
1149                             trait=bound.print_only_trait_path(),
1150                             assoc=assoc_name,
1151                             constraint=constraint,
1152                         ));
1153                     } else {
1154                         err.span_suggestion_verbose(
1155                             span.with_hi(assoc_name.span.lo()),
1156                             "use fully qualified syntax to disambiguate",
1157                             format!("<{} as {}>::", ty_param_name, bound.print_only_trait_path()),
1158                             Applicability::MaybeIncorrect,
1159                         );
1160                     }
1161                 } else {
1162                     err.note(format!(
1163                         "associated type `{}` could derive from `{}`",
1164                         ty_param_name,
1165                         bound.print_only_trait_path(),
1166                     ));
1167                 }
1168             }
1169             if !where_bounds.is_empty() {
1170                 err.help(format!(
1171                     "consider introducing a new type parameter `T` and adding `where` constraints:\
1172                      \n    where\n        T: {},\n{}",
1173                     ty_param_name,
1174                     where_bounds.join(",\n"),
1175                 ));
1176             }
1177             let reported = err.emit();
1178             if !where_bounds.is_empty() {
1179                 return Err(reported);
1180             }
1181         }
1182 
1183         Ok(bound)
1184     }
1185 
1186     #[instrument(level = "debug", skip(self, all_candidates, ty_name), ret)]
one_bound_for_assoc_method( &self, all_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>, ty_name: impl Display, assoc_name: Ident, span: Span, ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed>1187     fn one_bound_for_assoc_method(
1188         &self,
1189         all_candidates: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
1190         ty_name: impl Display,
1191         assoc_name: Ident,
1192         span: Span,
1193     ) -> Result<ty::PolyTraitRef<'tcx>, ErrorGuaranteed> {
1194         let mut matching_candidates = all_candidates.filter(|r| {
1195             self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Fn, assoc_name)
1196         });
1197 
1198         let candidate = match matching_candidates.next() {
1199             Some(candidate) => candidate,
1200             None => {
1201                 return Err(self.tcx().sess.emit_err(
1202                     crate::errors::ReturnTypeNotationMissingMethod {
1203                         span,
1204                         ty_name: ty_name.to_string(),
1205                         assoc_name: assoc_name.name,
1206                     },
1207                 ));
1208             }
1209         };
1210 
1211         if let Some(conflicting_candidate) = matching_candidates.next() {
1212             return Err(self.tcx().sess.emit_err(
1213                 crate::errors::ReturnTypeNotationConflictingBound {
1214                     span,
1215                     ty_name: ty_name.to_string(),
1216                     assoc_name: assoc_name.name,
1217                     first_bound: candidate.print_only_trait_path(),
1218                     second_bound: conflicting_candidate.print_only_trait_path(),
1219                 },
1220             ));
1221         }
1222 
1223         Ok(candidate)
1224     }
1225 
1226     // Create a type from a path to an associated type or to an enum variant.
1227     // For a path `A::B::C::D`, `qself_ty` and `qself_def` are the type and def for `A::B::C`
1228     // and item_segment is the path segment for `D`. We return a type and a def for
1229     // the whole path.
1230     // Will fail except for `T::A` and `Self::A`; i.e., if `qself_ty`/`qself_def` are not a type
1231     // parameter or `Self`.
1232     // NOTE: When this function starts resolving `Trait::AssocTy` successfully
1233     // it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
1234     #[instrument(level = "debug", skip(self, hir_ref_id, span, qself, assoc_segment), fields(assoc_ident=?assoc_segment.ident), ret)]
associated_path_to_ty( &self, hir_ref_id: hir::HirId, span: Span, qself_ty: Ty<'tcx>, qself: &hir::Ty<'_>, assoc_segment: &hir::PathSegment<'_>, permit_variants: bool, ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed>1235     pub fn associated_path_to_ty(
1236         &self,
1237         hir_ref_id: hir::HirId,
1238         span: Span,
1239         qself_ty: Ty<'tcx>,
1240         qself: &hir::Ty<'_>,
1241         assoc_segment: &hir::PathSegment<'_>,
1242         permit_variants: bool,
1243     ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
1244         let tcx = self.tcx();
1245         let assoc_ident = assoc_segment.ident;
1246         let qself_res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = &qself.kind {
1247             path.res
1248         } else {
1249             Res::Err
1250         };
1251 
1252         // Check if we have an enum variant or an inherent associated type.
1253         let mut variant_resolution = None;
1254         if let Some(adt_def) = self.probe_adt(span, qself_ty) {
1255             if adt_def.is_enum() {
1256                 let variant_def = adt_def
1257                     .variants()
1258                     .iter()
1259                     .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
1260                 if let Some(variant_def) = variant_def {
1261                     if permit_variants {
1262                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
1263                         self.prohibit_generics(slice::from_ref(assoc_segment).iter(), |err| {
1264                             err.note("enum variants can't have type parameters");
1265                             let type_name = tcx.item_name(adt_def.did());
1266                             let msg = format!(
1267                                 "you might have meant to specify type parameters on enum \
1268                                  `{type_name}`"
1269                             );
1270                             let Some(args) = assoc_segment.args else { return; };
1271                             // Get the span of the generics args *including* the leading `::`.
1272                             let args_span = assoc_segment.ident.span.shrink_to_hi().to(args.span_ext);
1273                             if tcx.generics_of(adt_def.did()).count() == 0 {
1274                                 // FIXME(estebank): we could also verify that the arguments being
1275                                 // work for the `enum`, instead of just looking if it takes *any*.
1276                                 err.span_suggestion_verbose(
1277                                     args_span,
1278                                     format!("{type_name} doesn't have generic parameters"),
1279                                     "",
1280                                     Applicability::MachineApplicable,
1281                                 );
1282                                 return;
1283                             }
1284                             let Ok(snippet) = tcx.sess.source_map().span_to_snippet(args_span) else {
1285                                 err.note(msg);
1286                                 return;
1287                             };
1288                             let (qself_sugg_span, is_self) = if let hir::TyKind::Path(
1289                                 hir::QPath::Resolved(_, path)
1290                             ) = &qself.kind {
1291                                 // If the path segment already has type params, we want to overwrite
1292                                 // them.
1293                                 match &path.segments {
1294                                     // `segment` is the previous to last element on the path,
1295                                     // which would normally be the `enum` itself, while the last
1296                                     // `_` `PathSegment` corresponds to the variant.
1297                                     [.., hir::PathSegment {
1298                                         ident,
1299                                         args,
1300                                         res: Res::Def(DefKind::Enum, _),
1301                                         ..
1302                                     }, _] => (
1303                                         // We need to include the `::` in `Type::Variant::<Args>`
1304                                         // to point the span to `::<Args>`, not just `<Args>`.
1305                                         ident.span.shrink_to_hi().to(args.map_or(
1306                                             ident.span.shrink_to_hi(),
1307                                             |a| a.span_ext)),
1308                                         false,
1309                                     ),
1310                                     [segment] => (
1311                                         // We need to include the `::` in `Type::Variant::<Args>`
1312                                         // to point the span to `::<Args>`, not just `<Args>`.
1313                                         segment.ident.span.shrink_to_hi().to(segment.args.map_or(
1314                                             segment.ident.span.shrink_to_hi(),
1315                                             |a| a.span_ext)),
1316                                         kw::SelfUpper == segment.ident.name,
1317                                     ),
1318                                     _ => {
1319                                         err.note(msg);
1320                                         return;
1321                                     }
1322                                 }
1323                             } else {
1324                                 err.note(msg);
1325                                 return;
1326                             };
1327                             let suggestion = vec![
1328                                 if is_self {
1329                                     // Account for people writing `Self::Variant::<Args>`, where
1330                                     // `Self` is the enum, and suggest replacing `Self` with the
1331                                     // appropriate type: `Type::<Args>::Variant`.
1332                                     (qself.span, format!("{type_name}{snippet}"))
1333                                 } else {
1334                                     (qself_sugg_span, snippet)
1335                                 },
1336                                 (args_span, String::new()),
1337                             ];
1338                             err.multipart_suggestion_verbose(
1339                                 msg,
1340                                 suggestion,
1341                                 Applicability::MaybeIncorrect,
1342                             );
1343                         });
1344                         return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
1345                     } else {
1346                         variant_resolution = Some(variant_def.def_id);
1347                     }
1348                 }
1349             }
1350 
1351             if let Some((ty, did)) = self.lookup_inherent_assoc_ty(
1352                 assoc_ident,
1353                 assoc_segment,
1354                 adt_def.did(),
1355                 qself_ty,
1356                 hir_ref_id,
1357                 span,
1358             )? {
1359                 return Ok((ty, DefKind::AssocTy, did));
1360             }
1361         }
1362 
1363         // Find the type of the associated item, and the trait where the associated
1364         // item is declared.
1365         let bound = match (&qself_ty.kind(), qself_res) {
1366             (_, Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. }) => {
1367                 // `Self` in an impl of a trait -- we have a concrete self type and a
1368                 // trait reference.
1369                 let Some(trait_ref) = tcx.impl_trait_ref(impl_def_id) else {
1370                     // A cycle error occurred, most likely.
1371                     let guar = tcx.sess.delay_span_bug(span, "expected cycle error");
1372                     return Err(guar);
1373                 };
1374 
1375                 self.one_bound_for_assoc_type(
1376                     || traits::supertraits(tcx, ty::Binder::dummy(trait_ref.subst_identity())),
1377                     kw::SelfUpper,
1378                     assoc_ident,
1379                     span,
1380                     None,
1381                 )?
1382             }
1383             (
1384                 &ty::Param(_),
1385                 Res::SelfTyParam { trait_: param_did } | Res::Def(DefKind::TyParam, param_did),
1386             ) => self.find_bound_for_assoc_item(param_did.expect_local(), assoc_ident, span)?,
1387             _ => {
1388                 let reported = if variant_resolution.is_some() {
1389                     // Variant in type position
1390                     let msg = format!("expected type, found variant `{}`", assoc_ident);
1391                     tcx.sess.span_err(span, msg)
1392                 } else if qself_ty.is_enum() {
1393                     let mut err = struct_span_err!(
1394                         tcx.sess,
1395                         assoc_ident.span,
1396                         E0599,
1397                         "no variant named `{}` found for enum `{}`",
1398                         assoc_ident,
1399                         qself_ty,
1400                     );
1401 
1402                     let adt_def = qself_ty.ty_adt_def().expect("enum is not an ADT");
1403                     if let Some(suggested_name) = find_best_match_for_name(
1404                         &adt_def
1405                             .variants()
1406                             .iter()
1407                             .map(|variant| variant.name)
1408                             .collect::<Vec<Symbol>>(),
1409                         assoc_ident.name,
1410                         None,
1411                     ) {
1412                         err.span_suggestion(
1413                             assoc_ident.span,
1414                             "there is a variant with a similar name",
1415                             suggested_name,
1416                             Applicability::MaybeIncorrect,
1417                         );
1418                     } else {
1419                         err.span_label(
1420                             assoc_ident.span,
1421                             format!("variant not found in `{}`", qself_ty),
1422                         );
1423                     }
1424 
1425                     if let Some(sp) = tcx.hir().span_if_local(adt_def.did()) {
1426                         err.span_label(sp, format!("variant `{}` not found here", assoc_ident));
1427                     }
1428 
1429                     err.emit()
1430                 } else if let Err(reported) = qself_ty.error_reported() {
1431                     reported
1432                 } else if let ty::Alias(ty::Opaque, alias_ty) = qself_ty.kind() {
1433                     // `<impl Trait as OtherTrait>::Assoc` makes no sense.
1434                     struct_span_err!(
1435                         tcx.sess,
1436                         tcx.def_span(alias_ty.def_id),
1437                         E0667,
1438                         "`impl Trait` is not allowed in path parameters"
1439                     )
1440                     .emit() // Already reported in an earlier stage.
1441                 } else {
1442                     let traits: Vec<_> =
1443                         self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
1444 
1445                     // Don't print `TyErr` to the user.
1446                     self.report_ambiguous_associated_type(
1447                         span,
1448                         &[qself_ty.to_string()],
1449                         &traits,
1450                         assoc_ident.name,
1451                     )
1452                 };
1453                 return Err(reported);
1454             }
1455         };
1456 
1457         let trait_did = bound.def_id();
1458         let Some(assoc_ty_did) = self.lookup_assoc_ty(assoc_ident, hir_ref_id, span, trait_did) else {
1459             // Assume that if it's not matched, there must be a const defined with the same name
1460             // but it was used in a type position.
1461             let msg = format!("found associated const `{assoc_ident}` when type was expected");
1462             let guar = tcx.sess.struct_span_err(span, msg).emit();
1463             return Err(guar);
1464         };
1465 
1466         let ty = self.projected_ty_from_poly_trait_ref(span, assoc_ty_did, assoc_segment, bound);
1467 
1468         if let Some(variant_def_id) = variant_resolution {
1469             tcx.struct_span_lint_hir(
1470                 AMBIGUOUS_ASSOCIATED_ITEMS,
1471                 hir_ref_id,
1472                 span,
1473                 "ambiguous associated item",
1474                 |lint| {
1475                     let mut could_refer_to = |kind: DefKind, def_id, also| {
1476                         let note_msg = format!(
1477                             "`{}` could{} refer to the {} defined here",
1478                             assoc_ident,
1479                             also,
1480                             tcx.def_kind_descr(kind, def_id)
1481                         );
1482                         lint.span_note(tcx.def_span(def_id), note_msg);
1483                     };
1484 
1485                     could_refer_to(DefKind::Variant, variant_def_id, "");
1486                     could_refer_to(DefKind::AssocTy, assoc_ty_did, " also");
1487 
1488                     lint.span_suggestion(
1489                         span,
1490                         "use fully-qualified syntax",
1491                         format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
1492                         Applicability::MachineApplicable,
1493                     );
1494 
1495                     lint
1496                 },
1497             );
1498         }
1499         Ok((ty, DefKind::AssocTy, assoc_ty_did))
1500     }
1501 
lookup_inherent_assoc_ty( &self, name: Ident, segment: &hir::PathSegment<'_>, adt_did: DefId, self_ty: Ty<'tcx>, block: hir::HirId, span: Span, ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed>1502     fn lookup_inherent_assoc_ty(
1503         &self,
1504         name: Ident,
1505         segment: &hir::PathSegment<'_>,
1506         adt_did: DefId,
1507         self_ty: Ty<'tcx>,
1508         block: hir::HirId,
1509         span: Span,
1510     ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> {
1511         let tcx = self.tcx();
1512 
1513         // Don't attempt to look up inherent associated types when the feature is not enabled.
1514         // Theoretically it'd be fine to do so since we feature-gate their definition site.
1515         // However, due to current limitations of the implementation (caused by us performing
1516         // selection in AstConv), IATs can lead to cycle errors (#108491, #110106) which mask the
1517         // feature-gate error, needlessly confusing users that use IATs by accident (#113265).
1518         if !tcx.features().inherent_associated_types {
1519             return Ok(None);
1520         }
1521 
1522         let candidates: Vec<_> = tcx
1523             .inherent_impls(adt_did)
1524             .iter()
1525             .filter_map(|&impl_| Some((impl_, self.lookup_assoc_ty_unchecked(name, block, impl_)?)))
1526             .collect();
1527 
1528         if candidates.is_empty() {
1529             return Ok(None);
1530         }
1531 
1532         //
1533         // Select applicable inherent associated type candidates modulo regions.
1534         //
1535 
1536         // In contexts that have no inference context, just make a new one.
1537         // We do need a local variable to store it, though.
1538         let infcx_;
1539         let infcx = match self.infcx() {
1540             Some(infcx) => infcx,
1541             None => {
1542                 assert!(!self_ty.has_infer());
1543                 infcx_ = tcx.infer_ctxt().ignoring_regions().build();
1544                 &infcx_
1545             }
1546         };
1547 
1548         // FIXME(inherent_associated_types): Acquiring the ParamEnv this early leads to cycle errors
1549         // when inside of an ADT (#108491) or where clause.
1550         let param_env = tcx.param_env(block.owner);
1551         let cause = ObligationCause::misc(span, block.owner.def_id);
1552 
1553         let mut fulfillment_errors = Vec::new();
1554         let mut applicable_candidates: Vec<_> = infcx.probe(|_| {
1555             // Regions are not considered during selection.
1556             let self_ty = self_ty
1557                 .fold_with(&mut BoundVarEraser { tcx, universe: infcx.create_next_universe() });
1558 
1559             struct BoundVarEraser<'tcx> {
1560                 tcx: TyCtxt<'tcx>,
1561                 universe: ty::UniverseIndex,
1562             }
1563 
1564             // FIXME(non_lifetime_binders): Don't assign the same universe to each placeholder.
1565             impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarEraser<'tcx> {
1566                 fn interner(&self) -> TyCtxt<'tcx> {
1567                     self.tcx
1568                 }
1569 
1570                 fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
1571                     if r.is_late_bound() { self.tcx.lifetimes.re_erased } else { r }
1572                 }
1573 
1574                 fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
1575                     match *ty.kind() {
1576                         ty::Bound(_, bv) => Ty::new_placeholder(
1577                             self.tcx,
1578                             ty::PlaceholderType { universe: self.universe, bound: bv },
1579                         ),
1580                         _ => ty.super_fold_with(self),
1581                     }
1582                 }
1583 
1584                 fn fold_const(
1585                     &mut self,
1586                     ct: ty::Const<'tcx>,
1587                 ) -> <TyCtxt<'tcx> as rustc_type_ir::Interner>::Const {
1588                     assert!(!ct.ty().has_escaping_bound_vars());
1589 
1590                     match ct.kind() {
1591                         ty::ConstKind::Bound(_, bv) => ty::Const::new_placeholder(
1592                             self.tcx,
1593                             ty::PlaceholderConst { universe: self.universe, bound: bv },
1594                             ct.ty(),
1595                         ),
1596                         _ => ct.super_fold_with(self),
1597                     }
1598                 }
1599             }
1600 
1601             let InferOk { value: self_ty, obligations } =
1602                 infcx.at(&cause, param_env).normalize(self_ty);
1603 
1604             candidates
1605                 .iter()
1606                 .copied()
1607                 .filter(|&(impl_, _)| {
1608                     infcx.probe(|_| {
1609                         let ocx = ObligationCtxt::new(&infcx);
1610                         ocx.register_obligations(obligations.clone());
1611 
1612                         let impl_substs = infcx.fresh_substs_for_item(span, impl_);
1613                         let impl_ty = tcx.type_of(impl_).subst(tcx, impl_substs);
1614                         let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
1615 
1616                         // Check that the self types can be related.
1617                         // FIXME(inherent_associated_types): Should we use `eq` here? Method probing uses
1618                         // `sup` for this situtation, too. What for? To constrain inference variables?
1619                         if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err()
1620                         {
1621                             return false;
1622                         }
1623 
1624                         // Check whether the impl imposes obligations we have to worry about.
1625                         let impl_bounds = tcx.predicates_of(impl_).instantiate(tcx, impl_substs);
1626                         let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
1627                         let impl_obligations = traits::predicates_for_generics(
1628                             |_, _| cause.clone(),
1629                             param_env,
1630                             impl_bounds,
1631                         );
1632                         ocx.register_obligations(impl_obligations);
1633 
1634                         let mut errors = ocx.select_where_possible();
1635                         if !errors.is_empty() {
1636                             fulfillment_errors.append(&mut errors);
1637                             return false;
1638                         }
1639 
1640                         true
1641                     })
1642                 })
1643                 .collect()
1644         });
1645 
1646         if applicable_candidates.len() > 1 {
1647             return Err(self.complain_about_ambiguous_inherent_assoc_type(
1648                 name,
1649                 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
1650                 span,
1651             ));
1652         }
1653 
1654         if let Some((impl_, (assoc_item, def_scope))) = applicable_candidates.pop() {
1655             self.check_assoc_ty(assoc_item, name, def_scope, block, span);
1656 
1657             // FIXME(fmease): Currently creating throwaway `parent_substs` to please
1658             // `create_substs_for_associated_item`. Modify the latter instead (or sth. similar) to
1659             // not require the parent substs logic.
1660             let parent_substs = InternalSubsts::identity_for_item(tcx, impl_);
1661             let substs =
1662                 self.create_substs_for_associated_item(span, assoc_item, segment, parent_substs);
1663             let substs = tcx.mk_substs_from_iter(
1664                 std::iter::once(ty::GenericArg::from(self_ty))
1665                     .chain(substs.into_iter().skip(parent_substs.len())),
1666             );
1667 
1668             let ty = Ty::new_alias(tcx, ty::Inherent, tcx.mk_alias_ty(assoc_item, substs));
1669 
1670             return Ok(Some((ty, assoc_item)));
1671         }
1672 
1673         Err(self.complain_about_inherent_assoc_type_not_found(
1674             name,
1675             self_ty,
1676             candidates,
1677             fulfillment_errors,
1678             span,
1679         ))
1680     }
1681 
lookup_assoc_ty( &self, name: Ident, block: hir::HirId, span: Span, scope: DefId, ) -> Option<DefId>1682     fn lookup_assoc_ty(
1683         &self,
1684         name: Ident,
1685         block: hir::HirId,
1686         span: Span,
1687         scope: DefId,
1688     ) -> Option<DefId> {
1689         let (item, def_scope) = self.lookup_assoc_ty_unchecked(name, block, scope)?;
1690         self.check_assoc_ty(item, name, def_scope, block, span);
1691         Some(item)
1692     }
1693 
lookup_assoc_ty_unchecked( &self, name: Ident, block: hir::HirId, scope: DefId, ) -> Option<(DefId, DefId)>1694     fn lookup_assoc_ty_unchecked(
1695         &self,
1696         name: Ident,
1697         block: hir::HirId,
1698         scope: DefId,
1699     ) -> Option<(DefId, DefId)> {
1700         let tcx = self.tcx();
1701         let (ident, def_scope) = tcx.adjust_ident_and_get_scope(name, scope, block);
1702 
1703         // We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
1704         // of calling `find_by_name_and_kind`.
1705         let item = tcx.associated_items(scope).in_definition_order().find(|i| {
1706             i.kind.namespace() == Namespace::TypeNS
1707                 && i.ident(tcx).normalize_to_macros_2_0() == ident
1708         })?;
1709 
1710         Some((item.def_id, def_scope))
1711     }
1712 
check_assoc_ty( &self, item: DefId, name: Ident, def_scope: DefId, block: hir::HirId, span: Span, )1713     fn check_assoc_ty(
1714         &self,
1715         item: DefId,
1716         name: Ident,
1717         def_scope: DefId,
1718         block: hir::HirId,
1719         span: Span,
1720     ) {
1721         let tcx = self.tcx();
1722         let kind = DefKind::AssocTy;
1723 
1724         if !tcx.visibility(item).is_accessible_from(def_scope, tcx) {
1725             let kind = tcx.def_kind_descr(kind, item);
1726             let msg = format!("{kind} `{name}` is private");
1727             let def_span = tcx.def_span(item);
1728             tcx.sess
1729                 .struct_span_err_with_code(span, msg, rustc_errors::error_code!(E0624))
1730                 .span_label(span, format!("private {kind}"))
1731                 .span_label(def_span, format!("{kind} defined here"))
1732                 .emit();
1733         }
1734         tcx.check_stability(item, Some(block), span, None);
1735     }
1736 
probe_traits_that_match_assoc_ty( &self, qself_ty: Ty<'tcx>, assoc_ident: Ident, ) -> Vec<String>1737     fn probe_traits_that_match_assoc_ty(
1738         &self,
1739         qself_ty: Ty<'tcx>,
1740         assoc_ident: Ident,
1741     ) -> Vec<String> {
1742         let tcx = self.tcx();
1743 
1744         // In contexts that have no inference context, just make a new one.
1745         // We do need a local variable to store it, though.
1746         let infcx_;
1747         let infcx = if let Some(infcx) = self.infcx() {
1748             infcx
1749         } else {
1750             assert!(!qself_ty.has_infer());
1751             infcx_ = tcx.infer_ctxt().build();
1752             &infcx_
1753         };
1754 
1755         tcx.all_traits()
1756             .filter(|trait_def_id| {
1757                 // Consider only traits with the associated type
1758                 tcx.associated_items(*trait_def_id)
1759                         .in_definition_order()
1760                         .any(|i| {
1761                             i.kind.namespace() == Namespace::TypeNS
1762                                 && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
1763                                 && matches!(i.kind, ty::AssocKind::Type)
1764                         })
1765                     // Consider only accessible traits
1766                     && tcx.visibility(*trait_def_id)
1767                         .is_accessible_from(self.item_def_id(), tcx)
1768                     && tcx.all_impls(*trait_def_id)
1769                         .any(|impl_def_id| {
1770                             let trait_ref = tcx.impl_trait_ref(impl_def_id);
1771                             trait_ref.is_some_and(|trait_ref| {
1772                                 let impl_ = trait_ref.subst(
1773                                     tcx,
1774                                     infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
1775                                 );
1776                                 let value = tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased);
1777                                 // FIXME: Don't bother dealing with non-lifetime binders here...
1778                                 if value.has_escaping_bound_vars() {
1779                                     return false;
1780                                 }
1781                                 infcx
1782                                     .can_eq(
1783                                         ty::ParamEnv::empty(),
1784                                         impl_.self_ty(),
1785                                         value,
1786                                     )
1787                             })
1788                             && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
1789                         })
1790             })
1791             .map(|trait_def_id| tcx.def_path_str(trait_def_id))
1792             .collect()
1793     }
1794 
qpath_to_ty( &self, span: Span, opt_self_ty: Option<Ty<'tcx>>, item_def_id: DefId, trait_segment: &hir::PathSegment<'_>, item_segment: &hir::PathSegment<'_>, constness: ty::BoundConstness, ) -> Ty<'tcx>1795     fn qpath_to_ty(
1796         &self,
1797         span: Span,
1798         opt_self_ty: Option<Ty<'tcx>>,
1799         item_def_id: DefId,
1800         trait_segment: &hir::PathSegment<'_>,
1801         item_segment: &hir::PathSegment<'_>,
1802         constness: ty::BoundConstness,
1803     ) -> Ty<'tcx> {
1804         let tcx = self.tcx();
1805 
1806         let trait_def_id = tcx.parent(item_def_id);
1807 
1808         debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id);
1809 
1810         let Some(self_ty) = opt_self_ty else {
1811             let path_str = tcx.def_path_str(trait_def_id);
1812 
1813             let def_id = self.item_def_id();
1814 
1815             debug!("qpath_to_ty: self.item_def_id()={:?}", def_id);
1816 
1817             let parent_def_id = def_id.as_local().map(|def_id| tcx.hir().local_def_id_to_hir_id(def_id))
1818                 .map(|hir_id| tcx.hir().get_parent_item(hir_id).to_def_id());
1819 
1820             debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id);
1821 
1822             // If the trait in segment is the same as the trait defining the item,
1823             // use the `<Self as ..>` syntax in the error.
1824             let is_part_of_self_trait_constraints = def_id == trait_def_id;
1825             let is_part_of_fn_in_self_trait = parent_def_id == Some(trait_def_id);
1826 
1827             let type_names = if is_part_of_self_trait_constraints || is_part_of_fn_in_self_trait {
1828                 vec!["Self".to_string()]
1829             } else {
1830                 // Find all the types that have an `impl` for the trait.
1831                 tcx.all_impls(trait_def_id)
1832                     .filter(|impl_def_id| {
1833                         // Consider only accessible traits
1834                         tcx.visibility(trait_def_id).is_accessible_from(self.item_def_id(), tcx)
1835                             && tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
1836                     })
1837                     .filter_map(|impl_def_id| tcx.impl_trait_ref(impl_def_id))
1838                     .map(|impl_| impl_.subst_identity().self_ty())
1839                     // We don't care about blanket impls.
1840                     .filter(|self_ty| !self_ty.has_non_region_param())
1841                     .map(|self_ty| tcx.erase_regions(self_ty).to_string())
1842                     .collect()
1843             };
1844             // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
1845             // references the trait. Relevant for the first case in
1846             // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
1847             let reported = self.report_ambiguous_associated_type(
1848                 span,
1849                 &type_names,
1850                 &[path_str],
1851                 item_segment.ident.name,
1852             );
1853             return Ty::new_error(tcx,reported)
1854         };
1855 
1856         debug!("qpath_to_ty: self_type={:?}", self_ty);
1857 
1858         let trait_ref = self.ast_path_to_mono_trait_ref(
1859             span,
1860             trait_def_id,
1861             self_ty,
1862             trait_segment,
1863             false,
1864             constness,
1865         );
1866 
1867         let item_substs = self.create_substs_for_associated_item(
1868             span,
1869             item_def_id,
1870             item_segment,
1871             trait_ref.substs,
1872         );
1873 
1874         debug!("qpath_to_ty: trait_ref={:?}", trait_ref);
1875 
1876         Ty::new_projection(tcx, item_def_id, item_substs)
1877     }
1878 
prohibit_generics<'a>( &self, segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, extend: impl Fn(&mut Diagnostic), ) -> bool1879     pub fn prohibit_generics<'a>(
1880         &self,
1881         segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
1882         extend: impl Fn(&mut Diagnostic),
1883     ) -> bool {
1884         let args = segments.clone().flat_map(|segment| segment.args().args);
1885 
1886         let (lt, ty, ct, inf) =
1887             args.clone().fold((false, false, false, false), |(lt, ty, ct, inf), arg| match arg {
1888                 hir::GenericArg::Lifetime(_) => (true, ty, ct, inf),
1889                 hir::GenericArg::Type(_) => (lt, true, ct, inf),
1890                 hir::GenericArg::Const(_) => (lt, ty, true, inf),
1891                 hir::GenericArg::Infer(_) => (lt, ty, ct, true),
1892             });
1893         let mut emitted = false;
1894         if lt || ty || ct || inf {
1895             let types_and_spans: Vec<_> = segments
1896                 .clone()
1897                 .flat_map(|segment| {
1898                     if segment.args().args.is_empty() {
1899                         None
1900                     } else {
1901                         Some((
1902                             match segment.res {
1903                                 Res::PrimTy(ty) => format!("{} `{}`", segment.res.descr(), ty.name()),
1904                                 Res::Def(_, def_id)
1905                                 if let Some(name) = self.tcx().opt_item_name(def_id) => {
1906                                     format!("{} `{name}`", segment.res.descr())
1907                                 }
1908                                 Res::Err => "this type".to_string(),
1909                                 _ => segment.res.descr().to_string(),
1910                             },
1911                             segment.ident.span,
1912                         ))
1913                     }
1914                 })
1915                 .collect();
1916             let this_type = match &types_and_spans[..] {
1917                 [.., _, (last, _)] => format!(
1918                     "{} and {last}",
1919                     types_and_spans[..types_and_spans.len() - 1]
1920                         .iter()
1921                         .map(|(x, _)| x.as_str())
1922                         .intersperse(&", ")
1923                         .collect::<String>()
1924                 ),
1925                 [(only, _)] => only.to_string(),
1926                 [] => "this type".to_string(),
1927             };
1928 
1929             let arg_spans: Vec<Span> = args.map(|arg| arg.span()).collect();
1930 
1931             let mut kinds = Vec::with_capacity(4);
1932             if lt {
1933                 kinds.push("lifetime");
1934             }
1935             if ty {
1936                 kinds.push("type");
1937             }
1938             if ct {
1939                 kinds.push("const");
1940             }
1941             if inf {
1942                 kinds.push("generic");
1943             }
1944             let (kind, s) = match kinds[..] {
1945                 [.., _, last] => (
1946                     format!(
1947                         "{} and {last}",
1948                         kinds[..kinds.len() - 1]
1949                             .iter()
1950                             .map(|&x| x)
1951                             .intersperse(", ")
1952                             .collect::<String>()
1953                     ),
1954                     "s",
1955                 ),
1956                 [only] => (only.to_string(), ""),
1957                 [] => unreachable!(),
1958             };
1959             let last_span = *arg_spans.last().unwrap();
1960             let span: MultiSpan = arg_spans.into();
1961             let mut err = struct_span_err!(
1962                 self.tcx().sess,
1963                 span,
1964                 E0109,
1965                 "{kind} arguments are not allowed on {this_type}",
1966             );
1967             err.span_label(last_span, format!("{kind} argument{s} not allowed"));
1968             for (what, span) in types_and_spans {
1969                 err.span_label(span, format!("not allowed on {what}"));
1970             }
1971             extend(&mut err);
1972             err.emit();
1973             emitted = true;
1974         }
1975 
1976         for segment in segments {
1977             // Only emit the first error to avoid overloading the user with error messages.
1978             if let Some(b) = segment.args().bindings.first() {
1979                 prohibit_assoc_ty_binding(self.tcx(), b.span, None);
1980                 return true;
1981             }
1982         }
1983         emitted
1984     }
1985 
1986     // FIXME(eddyb, varkor) handle type paths here too, not just value ones.
def_ids_for_value_path_segments( &self, segments: &[hir::PathSegment<'_>], self_ty: Option<Ty<'tcx>>, kind: DefKind, def_id: DefId, span: Span, ) -> Vec<PathSeg>1987     pub fn def_ids_for_value_path_segments(
1988         &self,
1989         segments: &[hir::PathSegment<'_>],
1990         self_ty: Option<Ty<'tcx>>,
1991         kind: DefKind,
1992         def_id: DefId,
1993         span: Span,
1994     ) -> Vec<PathSeg> {
1995         // We need to extract the type parameters supplied by the user in
1996         // the path `path`. Due to the current setup, this is a bit of a
1997         // tricky-process; the problem is that resolve only tells us the
1998         // end-point of the path resolution, and not the intermediate steps.
1999         // Luckily, we can (at least for now) deduce the intermediate steps
2000         // just from the end-point.
2001         //
2002         // There are basically five cases to consider:
2003         //
2004         // 1. Reference to a constructor of a struct:
2005         //
2006         //        struct Foo<T>(...)
2007         //
2008         //    In this case, the parameters are declared in the type space.
2009         //
2010         // 2. Reference to a constructor of an enum variant:
2011         //
2012         //        enum E<T> { Foo(...) }
2013         //
2014         //    In this case, the parameters are defined in the type space,
2015         //    but may be specified either on the type or the variant.
2016         //
2017         // 3. Reference to a fn item or a free constant:
2018         //
2019         //        fn foo<T>() { }
2020         //
2021         //    In this case, the path will again always have the form
2022         //    `a::b::foo::<T>` where only the final segment should have
2023         //    type parameters. However, in this case, those parameters are
2024         //    declared on a value, and hence are in the `FnSpace`.
2025         //
2026         // 4. Reference to a method or an associated constant:
2027         //
2028         //        impl<A> SomeStruct<A> {
2029         //            fn foo<B>(...)
2030         //        }
2031         //
2032         //    Here we can have a path like
2033         //    `a::b::SomeStruct::<A>::foo::<B>`, in which case parameters
2034         //    may appear in two places. The penultimate segment,
2035         //    `SomeStruct::<A>`, contains parameters in TypeSpace, and the
2036         //    final segment, `foo::<B>` contains parameters in fn space.
2037         //
2038         // The first step then is to categorize the segments appropriately.
2039 
2040         let tcx = self.tcx();
2041 
2042         assert!(!segments.is_empty());
2043         let last = segments.len() - 1;
2044 
2045         let mut path_segs = vec![];
2046 
2047         match kind {
2048             // Case 1. Reference to a struct constructor.
2049             DefKind::Ctor(CtorOf::Struct, ..) => {
2050                 // Everything but the final segment should have no
2051                 // parameters at all.
2052                 let generics = tcx.generics_of(def_id);
2053                 // Variant and struct constructors use the
2054                 // generics of their parent type definition.
2055                 let generics_def_id = generics.parent.unwrap_or(def_id);
2056                 path_segs.push(PathSeg(generics_def_id, last));
2057             }
2058 
2059             // Case 2. Reference to a variant constructor.
2060             DefKind::Ctor(CtorOf::Variant, ..) | DefKind::Variant => {
2061                 let (generics_def_id, index) = if let Some(self_ty) = self_ty {
2062                     let adt_def = self.probe_adt(span, self_ty).unwrap();
2063                     debug_assert!(adt_def.is_enum());
2064                     (adt_def.did(), last)
2065                 } else if last >= 1 && segments[last - 1].args.is_some() {
2066                     // Everything but the penultimate segment should have no
2067                     // parameters at all.
2068                     let mut def_id = def_id;
2069 
2070                     // `DefKind::Ctor` -> `DefKind::Variant`
2071                     if let DefKind::Ctor(..) = kind {
2072                         def_id = tcx.parent(def_id);
2073                     }
2074 
2075                     // `DefKind::Variant` -> `DefKind::Enum`
2076                     let enum_def_id = tcx.parent(def_id);
2077                     (enum_def_id, last - 1)
2078                 } else {
2079                     // FIXME: lint here recommending `Enum::<...>::Variant` form
2080                     // instead of `Enum::Variant::<...>` form.
2081 
2082                     // Everything but the final segment should have no
2083                     // parameters at all.
2084                     let generics = tcx.generics_of(def_id);
2085                     // Variant and struct constructors use the
2086                     // generics of their parent type definition.
2087                     (generics.parent.unwrap_or(def_id), last)
2088                 };
2089                 path_segs.push(PathSeg(generics_def_id, index));
2090             }
2091 
2092             // Case 3. Reference to a top-level value.
2093             DefKind::Fn | DefKind::Const | DefKind::ConstParam | DefKind::Static(_) => {
2094                 path_segs.push(PathSeg(def_id, last));
2095             }
2096 
2097             // Case 4. Reference to a method or associated const.
2098             DefKind::AssocFn | DefKind::AssocConst => {
2099                 if segments.len() >= 2 {
2100                     let generics = tcx.generics_of(def_id);
2101                     path_segs.push(PathSeg(generics.parent.unwrap(), last - 1));
2102                 }
2103                 path_segs.push(PathSeg(def_id, last));
2104             }
2105 
2106             kind => bug!("unexpected definition kind {:?} for {:?}", kind, def_id),
2107         }
2108 
2109         debug!("path_segs = {:?}", path_segs);
2110 
2111         path_segs
2112     }
2113 
2114     /// Check a type `Path` and convert it to a `Ty`.
res_to_ty( &self, opt_self_ty: Option<Ty<'tcx>>, path: &hir::Path<'_>, hir_id: hir::HirId, permit_variants: bool, ) -> Ty<'tcx>2115     pub fn res_to_ty(
2116         &self,
2117         opt_self_ty: Option<Ty<'tcx>>,
2118         path: &hir::Path<'_>,
2119         hir_id: hir::HirId,
2120         permit_variants: bool,
2121     ) -> Ty<'tcx> {
2122         let tcx = self.tcx();
2123 
2124         debug!(
2125             "res_to_ty(res={:?}, opt_self_ty={:?}, path_segments={:?})",
2126             path.res, opt_self_ty, path.segments
2127         );
2128 
2129         let span = path.span;
2130         match path.res {
2131             Res::Def(DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder, did) => {
2132                 // Check for desugared `impl Trait`.
2133                 assert!(tcx.is_type_alias_impl_trait(did));
2134                 let item_segment = path.segments.split_last().unwrap();
2135                 self.prohibit_generics(item_segment.1.iter(), |err| {
2136                     err.note("`impl Trait` types can't have type parameters");
2137                 });
2138                 let substs = self.ast_path_substs_for_ty(span, did, item_segment.0);
2139                 Ty::new_opaque(tcx, did, substs)
2140             }
2141             Res::Def(
2142                 DefKind::Enum
2143                 | DefKind::TyAlias
2144                 | DefKind::Struct
2145                 | DefKind::Union
2146                 | DefKind::ForeignTy,
2147                 did,
2148             ) => {
2149                 assert_eq!(opt_self_ty, None);
2150                 self.prohibit_generics(path.segments.split_last().unwrap().1.iter(), |_| {});
2151                 self.ast_path_to_ty(span, did, path.segments.last().unwrap())
2152             }
2153             Res::Def(kind @ DefKind::Variant, def_id) if permit_variants => {
2154                 // Convert "variant type" as if it were a real type.
2155                 // The resulting `Ty` is type of the variant's enum for now.
2156                 assert_eq!(opt_self_ty, None);
2157 
2158                 let path_segs =
2159                     self.def_ids_for_value_path_segments(path.segments, None, kind, def_id, span);
2160                 let generic_segs: FxHashSet<_> =
2161                     path_segs.iter().map(|PathSeg(_, index)| index).collect();
2162                 self.prohibit_generics(
2163                     path.segments.iter().enumerate().filter_map(|(index, seg)| {
2164                         if !generic_segs.contains(&index) { Some(seg) } else { None }
2165                     }),
2166                     |err| {
2167                         err.note("enum variants can't have type parameters");
2168                     },
2169                 );
2170 
2171                 let PathSeg(def_id, index) = path_segs.last().unwrap();
2172                 self.ast_path_to_ty(span, *def_id, &path.segments[*index])
2173             }
2174             Res::Def(DefKind::TyParam, def_id) => {
2175                 assert_eq!(opt_self_ty, None);
2176                 self.prohibit_generics(path.segments.iter(), |err| {
2177                     if let Some(span) = tcx.def_ident_span(def_id) {
2178                         let name = tcx.item_name(def_id);
2179                         err.span_note(span, format!("type parameter `{name}` defined here"));
2180                     }
2181                 });
2182 
2183                 match tcx.named_bound_var(hir_id) {
2184                     Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
2185                         let name =
2186                             tcx.hir().name(tcx.hir().local_def_id_to_hir_id(def_id.expect_local()));
2187                         let br = ty::BoundTy {
2188                             var: ty::BoundVar::from_u32(index),
2189                             kind: ty::BoundTyKind::Param(def_id, name),
2190                         };
2191                         Ty::new_bound(tcx, debruijn, br)
2192                     }
2193                     Some(rbv::ResolvedArg::EarlyBound(_)) => {
2194                         let def_id = def_id.expect_local();
2195                         let item_def_id = tcx.hir().ty_param_owner(def_id);
2196                         let generics = tcx.generics_of(item_def_id);
2197                         let index = generics.param_def_id_to_index[&def_id.to_def_id()];
2198                         Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id))
2199                     }
2200                     Some(rbv::ResolvedArg::Error(guar)) => Ty::new_error(tcx, guar),
2201                     arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"),
2202                 }
2203             }
2204             Res::SelfTyParam { .. } => {
2205                 // `Self` in trait or type alias.
2206                 assert_eq!(opt_self_ty, None);
2207                 self.prohibit_generics(path.segments.iter(), |err| {
2208                     if let [hir::PathSegment { args: Some(args), ident, .. }] = &path.segments {
2209                         err.span_suggestion_verbose(
2210                             ident.span.shrink_to_hi().to(args.span_ext),
2211                             "the `Self` type doesn't accept type parameters",
2212                             "",
2213                             Applicability::MaybeIncorrect,
2214                         );
2215                     }
2216                 });
2217                 tcx.types.self_param
2218             }
2219             Res::SelfTyAlias { alias_to: def_id, forbid_generic, .. } => {
2220                 // `Self` in impl (we know the concrete type).
2221                 assert_eq!(opt_self_ty, None);
2222                 // Try to evaluate any array length constants.
2223                 let ty = tcx.at(span).type_of(def_id).subst_identity();
2224                 let span_of_impl = tcx.span_of_impl(def_id);
2225                 self.prohibit_generics(path.segments.iter(), |err| {
2226                     let def_id = match *ty.kind() {
2227                         ty::Adt(self_def, _) => self_def.did(),
2228                         _ => return,
2229                     };
2230 
2231                     let type_name = tcx.item_name(def_id);
2232                     let span_of_ty = tcx.def_ident_span(def_id);
2233                     let generics = tcx.generics_of(def_id).count();
2234 
2235                     let msg = format!("`Self` is of type `{ty}`");
2236                     if let (Ok(i_sp), Some(t_sp)) = (span_of_impl, span_of_ty) {
2237                         let mut span: MultiSpan = vec![t_sp].into();
2238                         span.push_span_label(
2239                             i_sp,
2240                             format!("`Self` is on type `{type_name}` in this `impl`"),
2241                         );
2242                         let mut postfix = "";
2243                         if generics == 0 {
2244                             postfix = ", which doesn't have generic parameters";
2245                         }
2246                         span.push_span_label(
2247                             t_sp,
2248                             format!("`Self` corresponds to this type{postfix}"),
2249                         );
2250                         err.span_note(span, msg);
2251                     } else {
2252                         err.note(msg);
2253                     }
2254                     for segment in path.segments {
2255                         if let Some(args) = segment.args && segment.ident.name == kw::SelfUpper {
2256                             if generics == 0 {
2257                                 // FIXME(estebank): we could also verify that the arguments being
2258                                 // work for the `enum`, instead of just looking if it takes *any*.
2259                                 err.span_suggestion_verbose(
2260                                     segment.ident.span.shrink_to_hi().to(args.span_ext),
2261                                     "the `Self` type doesn't accept type parameters",
2262                                     "",
2263                                     Applicability::MachineApplicable,
2264                                 );
2265                                 return;
2266                             } else {
2267                                 err.span_suggestion_verbose(
2268                                     segment.ident.span,
2269                                     format!(
2270                                         "the `Self` type doesn't accept type parameters, use the \
2271                                         concrete type's name `{type_name}` instead if you want to \
2272                                         specify its type parameters"
2273                                     ),
2274                                     type_name,
2275                                     Applicability::MaybeIncorrect,
2276                                 );
2277                             }
2278                         }
2279                     }
2280                 });
2281                 // HACK(min_const_generics): Forbid generic `Self` types
2282                 // here as we can't easily do that during nameres.
2283                 //
2284                 // We do this before normalization as we otherwise allow
2285                 // ```rust
2286                 // trait AlwaysApplicable { type Assoc; }
2287                 // impl<T: ?Sized> AlwaysApplicable for T { type Assoc = usize; }
2288                 //
2289                 // trait BindsParam<T> {
2290                 //     type ArrayTy;
2291                 // }
2292                 // impl<T> BindsParam<T> for <T as AlwaysApplicable>::Assoc {
2293                 //    type ArrayTy = [u8; Self::MAX];
2294                 // }
2295                 // ```
2296                 // Note that the normalization happens in the param env of
2297                 // the anon const, which is empty. This is why the
2298                 // `AlwaysApplicable` impl needs a `T: ?Sized` bound for
2299                 // this to compile if we were to normalize here.
2300                 if forbid_generic && ty.has_param() {
2301                     let mut err = tcx.sess.struct_span_err(
2302                         path.span,
2303                         "generic `Self` types are currently not permitted in anonymous constants",
2304                     );
2305                     if let Some(hir::Node::Item(&hir::Item {
2306                         kind: hir::ItemKind::Impl(impl_),
2307                         ..
2308                     })) = tcx.hir().get_if_local(def_id)
2309                     {
2310                         err.span_note(impl_.self_ty.span, "not a concrete type");
2311                     }
2312                     Ty::new_error(tcx, err.emit())
2313                 } else {
2314                     ty
2315                 }
2316             }
2317             Res::Def(DefKind::AssocTy, def_id) => {
2318                 debug_assert!(path.segments.len() >= 2);
2319                 self.prohibit_generics(path.segments[..path.segments.len() - 2].iter(), |_| {});
2320                 // HACK: until we support `<Type as ~const Trait>`, assume all of them are.
2321                 let constness = if tcx.has_attr(tcx.parent(def_id), sym::const_trait) {
2322                     ty::BoundConstness::ConstIfConst
2323                 } else {
2324                     ty::BoundConstness::NotConst
2325                 };
2326                 self.qpath_to_ty(
2327                     span,
2328                     opt_self_ty,
2329                     def_id,
2330                     &path.segments[path.segments.len() - 2],
2331                     path.segments.last().unwrap(),
2332                     constness,
2333                 )
2334             }
2335             Res::PrimTy(prim_ty) => {
2336                 assert_eq!(opt_self_ty, None);
2337                 self.prohibit_generics(path.segments.iter(), |err| {
2338                     let name = prim_ty.name_str();
2339                     for segment in path.segments {
2340                         if let Some(args) = segment.args {
2341                             err.span_suggestion_verbose(
2342                                 segment.ident.span.shrink_to_hi().to(args.span_ext),
2343                                 format!("primitive type `{name}` doesn't have generic parameters"),
2344                                 "",
2345                                 Applicability::MaybeIncorrect,
2346                             );
2347                         }
2348                     }
2349                 });
2350                 match prim_ty {
2351                     hir::PrimTy::Bool => tcx.types.bool,
2352                     hir::PrimTy::Char => tcx.types.char,
2353                     hir::PrimTy::Int(it) => Ty::new_int(tcx, ty::int_ty(it)),
2354                     hir::PrimTy::Uint(uit) => Ty::new_uint(tcx, ty::uint_ty(uit)),
2355                     hir::PrimTy::Float(ft) => Ty::new_float(tcx, ty::float_ty(ft)),
2356                     hir::PrimTy::Str => tcx.types.str_,
2357                 }
2358             }
2359             Res::Err => {
2360                 let e = self
2361                     .tcx()
2362                     .sess
2363                     .delay_span_bug(path.span, "path with `Res::Err` but no error emitted");
2364                 self.set_tainted_by_errors(e);
2365                 Ty::new_error(self.tcx(), e)
2366             }
2367             _ => span_bug!(span, "unexpected resolution: {:?}", path.res),
2368         }
2369     }
2370 
2371     /// Parses the programmer's textual representation of a type into our
2372     /// internal notion of a type.
ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx>2373     pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
2374         self.ast_ty_to_ty_inner(ast_ty, false, false)
2375     }
2376 
2377     /// Parses the programmer's textual representation of a type into our
2378     /// internal notion of a type. This is meant to be used within a path.
ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx>2379     pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
2380         self.ast_ty_to_ty_inner(ast_ty, false, true)
2381     }
2382 
2383     /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
2384     /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
2385     #[instrument(level = "debug", skip(self), ret)]
ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx>2386     fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
2387         let tcx = self.tcx();
2388 
2389         let result_ty = match &ast_ty.kind {
2390             hir::TyKind::Slice(ty) => Ty::new_slice(tcx, self.ast_ty_to_ty(ty)),
2391             hir::TyKind::Ptr(mt) => {
2392                 Ty::new_ptr(tcx, ty::TypeAndMut { ty: self.ast_ty_to_ty(mt.ty), mutbl: mt.mutbl })
2393             }
2394             hir::TyKind::Ref(region, mt) => {
2395                 let r = self.ast_region_to_region(region, None);
2396                 debug!(?r);
2397                 let t = self.ast_ty_to_ty_inner(mt.ty, true, false);
2398                 Ty::new_ref(tcx, r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
2399             }
2400             hir::TyKind::Never => tcx.types.never,
2401             hir::TyKind::Tup(fields) => {
2402                 Ty::new_tup_from_iter(tcx, fields.iter().map(|t| self.ast_ty_to_ty(t)))
2403             }
2404             hir::TyKind::BareFn(bf) => {
2405                 require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span);
2406 
2407                 Ty::new_fn_ptr(
2408                     tcx,
2409                     self.ty_of_fn(ast_ty.hir_id, bf.unsafety, bf.abi, bf.decl, None, Some(ast_ty)),
2410                 )
2411             }
2412             hir::TyKind::TraitObject(bounds, lifetime, repr) => {
2413                 self.maybe_lint_bare_trait(ast_ty, in_path);
2414                 let repr = match repr {
2415                     TraitObjectSyntax::Dyn | TraitObjectSyntax::None => ty::Dyn,
2416                     TraitObjectSyntax::DynStar => ty::DynStar,
2417                 };
2418 
2419                 self.conv_object_ty_poly_trait_ref(
2420                     ast_ty.span,
2421                     ast_ty.hir_id,
2422                     bounds,
2423                     lifetime,
2424                     borrowed,
2425                     repr,
2426                 )
2427             }
2428             hir::TyKind::Path(hir::QPath::Resolved(maybe_qself, path)) => {
2429                 debug!(?maybe_qself, ?path);
2430                 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.ast_ty_to_ty(qself));
2431                 self.res_to_ty(opt_self_ty, path, ast_ty.hir_id, false)
2432             }
2433             &hir::TyKind::OpaqueDef(item_id, lifetimes, in_trait) => {
2434                 let opaque_ty = tcx.hir().item(item_id);
2435 
2436                 match opaque_ty.kind {
2437                     hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
2438                         let local_def_id = item_id.owner_id.def_id;
2439                         // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
2440                         // generate the def_id of an associated type for the trait and return as
2441                         // type a projection.
2442                         let def_id = if in_trait && tcx.lower_impl_trait_in_trait_to_assoc_ty() {
2443                             tcx.associated_type_for_impl_trait_in_trait(local_def_id).to_def_id()
2444                         } else {
2445                             local_def_id.to_def_id()
2446                         };
2447                         self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
2448                     }
2449                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
2450                 }
2451             }
2452             hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
2453                 debug!(?qself, ?segment);
2454                 let ty = self.ast_ty_to_ty_inner(qself, false, true);
2455                 self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false)
2456                     .map(|(ty, _, _)| ty)
2457                     .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
2458             }
2459             &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => {
2460                 let def_id = tcx.require_lang_item(lang_item, Some(span));
2461                 let (substs, _) = self.create_substs_for_ast_path(
2462                     span,
2463                     def_id,
2464                     &[],
2465                     &hir::PathSegment::invalid(),
2466                     &GenericArgs::none(),
2467                     true,
2468                     None,
2469                     ty::BoundConstness::NotConst,
2470                 );
2471                 tcx.at(span).type_of(def_id).subst(tcx, substs)
2472             }
2473             hir::TyKind::Array(ty, length) => {
2474                 let length = match length {
2475                     &hir::ArrayLen::Infer(_, span) => self.ct_infer(tcx.types.usize, None, span),
2476                     hir::ArrayLen::Body(constant) => {
2477                         ty::Const::from_anon_const(tcx, constant.def_id)
2478                     }
2479                 };
2480 
2481                 Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
2482             }
2483             hir::TyKind::Typeof(e) => {
2484                 let ty_erased = tcx.type_of(e.def_id).subst_identity();
2485                 let ty = tcx.fold_regions(ty_erased, |r, _| {
2486                     if r.is_erased() { tcx.lifetimes.re_static } else { r }
2487                 });
2488                 let span = ast_ty.span;
2489                 let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
2490                     (ty, Some((span, Applicability::MachineApplicable)))
2491                 } else {
2492                     (ty, None)
2493                 };
2494                 tcx.sess.emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
2495 
2496                 ty
2497             }
2498             hir::TyKind::Infer => {
2499                 // Infer also appears as the type of arguments or return
2500                 // values in an ExprKind::Closure, or as
2501                 // the type of local variables. Both of these cases are
2502                 // handled specially and will not descend into this routine.
2503                 self.ty_infer(None, ast_ty.span)
2504             }
2505             hir::TyKind::Err(guar) => Ty::new_error(tcx, *guar),
2506         };
2507 
2508         self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span);
2509         result_ty
2510     }
2511 
2512     #[instrument(level = "debug", skip(self), ret)]
impl_trait_ty_to_ty( &self, def_id: DefId, lifetimes: &[hir::GenericArg<'_>], origin: OpaqueTyOrigin, in_trait: bool, ) -> Ty<'tcx>2513     fn impl_trait_ty_to_ty(
2514         &self,
2515         def_id: DefId,
2516         lifetimes: &[hir::GenericArg<'_>],
2517         origin: OpaqueTyOrigin,
2518         in_trait: bool,
2519     ) -> Ty<'tcx> {
2520         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
2521         let tcx = self.tcx();
2522 
2523         let generics = tcx.generics_of(def_id);
2524 
2525         debug!("impl_trait_ty_to_ty: generics={:?}", generics);
2526         let substs = InternalSubsts::for_item(tcx, def_id, |param, _| {
2527             // We use `generics.count() - lifetimes.len()` here instead of `generics.parent_count`
2528             // since return-position impl trait in trait squashes all of the generics from its source fn
2529             // into its own generics, so the opaque's "own" params isn't always just lifetimes.
2530             if let Some(i) = (param.index as usize).checked_sub(generics.count() - lifetimes.len())
2531             {
2532                 // Resolve our own lifetime parameters.
2533                 let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() };
2534                 let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() };
2535                 self.ast_region_to_region(lifetime, None).into()
2536             } else {
2537                 tcx.mk_param_from_def(param)
2538             }
2539         });
2540         debug!("impl_trait_ty_to_ty: substs={:?}", substs);
2541 
2542         if in_trait {
2543             Ty::new_projection(tcx, def_id, substs)
2544         } else {
2545             Ty::new_opaque(tcx, def_id, substs)
2546         }
2547     }
2548 
ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx>2549     pub fn ty_of_arg(&self, ty: &hir::Ty<'_>, expected_ty: Option<Ty<'tcx>>) -> Ty<'tcx> {
2550         match ty.kind {
2551             hir::TyKind::Infer if expected_ty.is_some() => {
2552                 self.record_ty(ty.hir_id, expected_ty.unwrap(), ty.span);
2553                 expected_ty.unwrap()
2554             }
2555             _ => self.ast_ty_to_ty(ty),
2556         }
2557     }
2558 
2559     #[instrument(level = "debug", skip(self, hir_id, unsafety, abi, decl, generics, hir_ty), ret)]
ty_of_fn( &self, hir_id: hir::HirId, unsafety: hir::Unsafety, abi: abi::Abi, decl: &hir::FnDecl<'_>, generics: Option<&hir::Generics<'_>>, hir_ty: Option<&hir::Ty<'_>>, ) -> ty::PolyFnSig<'tcx>2560     pub fn ty_of_fn(
2561         &self,
2562         hir_id: hir::HirId,
2563         unsafety: hir::Unsafety,
2564         abi: abi::Abi,
2565         decl: &hir::FnDecl<'_>,
2566         generics: Option<&hir::Generics<'_>>,
2567         hir_ty: Option<&hir::Ty<'_>>,
2568     ) -> ty::PolyFnSig<'tcx> {
2569         let tcx = self.tcx();
2570         let bound_vars = tcx.late_bound_vars(hir_id);
2571         debug!(?bound_vars);
2572 
2573         // We proactively collect all the inferred type params to emit a single error per fn def.
2574         let mut visitor = HirPlaceholderCollector::default();
2575         let mut infer_replacements = vec![];
2576 
2577         if let Some(generics) = generics {
2578             walk_generics(&mut visitor, generics);
2579         }
2580 
2581         let input_tys: Vec<_> = decl
2582             .inputs
2583             .iter()
2584             .enumerate()
2585             .map(|(i, a)| {
2586                 if let hir::TyKind::Infer = a.kind && !self.allow_ty_infer() {
2587                     if let Some(suggested_ty) =
2588                         self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, Some(i))
2589                     {
2590                         infer_replacements.push((a.span, suggested_ty.to_string()));
2591                         return suggested_ty;
2592                     }
2593                 }
2594 
2595                 // Only visit the type looking for `_` if we didn't fix the type above
2596                 visitor.visit_ty(a);
2597                 self.ty_of_arg(a, None)
2598             })
2599             .collect();
2600 
2601         let output_ty = match decl.output {
2602             hir::FnRetTy::Return(output) => {
2603                 if let hir::TyKind::Infer = output.kind
2604                     && !self.allow_ty_infer()
2605                     && let Some(suggested_ty) =
2606                         self.suggest_trait_fn_ty_for_impl_fn_infer(hir_id, None)
2607                 {
2608                     infer_replacements.push((output.span, suggested_ty.to_string()));
2609                     suggested_ty
2610                 } else {
2611                     visitor.visit_ty(output);
2612                     self.ast_ty_to_ty(output)
2613                 }
2614             }
2615             hir::FnRetTy::DefaultReturn(..) => Ty::new_unit(tcx,),
2616         };
2617 
2618         debug!(?output_ty);
2619 
2620         let fn_ty = tcx.mk_fn_sig(input_tys, output_ty, decl.c_variadic, unsafety, abi);
2621         let bare_fn_ty = ty::Binder::bind_with_vars(fn_ty, bound_vars);
2622 
2623         if !self.allow_ty_infer() && !(visitor.0.is_empty() && infer_replacements.is_empty()) {
2624             // We always collect the spans for placeholder types when evaluating `fn`s, but we
2625             // only want to emit an error complaining about them if infer types (`_`) are not
2626             // allowed. `allow_ty_infer` gates this behavior. We check for the presence of
2627             // `ident_span` to not emit an error twice when we have `fn foo(_: fn() -> _)`.
2628 
2629             let mut diag = crate::collect::placeholder_type_error_diag(
2630                 tcx,
2631                 generics,
2632                 visitor.0,
2633                 infer_replacements.iter().map(|(s, _)| *s).collect(),
2634                 true,
2635                 hir_ty,
2636                 "function",
2637             );
2638 
2639             if !infer_replacements.is_empty() {
2640                 diag.multipart_suggestion(
2641                     format!(
2642                     "try replacing `_` with the type{} in the corresponding trait method signature",
2643                     rustc_errors::pluralize!(infer_replacements.len()),
2644                 ),
2645                     infer_replacements,
2646                     Applicability::MachineApplicable,
2647                 );
2648             }
2649 
2650             diag.emit();
2651         }
2652 
2653         // Find any late-bound regions declared in return type that do
2654         // not appear in the arguments. These are not well-formed.
2655         //
2656         // Example:
2657         //     for<'a> fn() -> &'a str <-- 'a is bad
2658         //     for<'a> fn(&'a String) -> &'a str <-- 'a is ok
2659         let inputs = bare_fn_ty.inputs();
2660         let late_bound_in_args =
2661             tcx.collect_constrained_late_bound_regions(&inputs.map_bound(|i| i.to_owned()));
2662         let output = bare_fn_ty.output();
2663         let late_bound_in_ret = tcx.collect_referenced_late_bound_regions(&output);
2664 
2665         self.validate_late_bound_regions(late_bound_in_args, late_bound_in_ret, |br_name| {
2666             struct_span_err!(
2667                 tcx.sess,
2668                 decl.output.span(),
2669                 E0581,
2670                 "return type references {}, which is not constrained by the fn input types",
2671                 br_name
2672             )
2673         });
2674 
2675         bare_fn_ty
2676     }
2677 
2678     /// Given a fn_hir_id for a impl function, suggest the type that is found on the
2679     /// corresponding function in the trait that the impl implements, if it exists.
2680     /// If arg_idx is Some, then it corresponds to an input type index, otherwise it
2681     /// corresponds to the return type.
suggest_trait_fn_ty_for_impl_fn_infer( &self, fn_hir_id: hir::HirId, arg_idx: Option<usize>, ) -> Option<Ty<'tcx>>2682     fn suggest_trait_fn_ty_for_impl_fn_infer(
2683         &self,
2684         fn_hir_id: hir::HirId,
2685         arg_idx: Option<usize>,
2686     ) -> Option<Ty<'tcx>> {
2687         let tcx = self.tcx();
2688         let hir = tcx.hir();
2689 
2690         let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
2691             hir.get(fn_hir_id) else { return None };
2692         let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
2693 
2694         let trait_ref = self.instantiate_mono_trait_ref(
2695             i.of_trait.as_ref()?,
2696             self.ast_ty_to_ty(i.self_ty),
2697             ty::BoundConstness::NotConst,
2698         );
2699 
2700         let assoc = tcx.associated_items(trait_ref.def_id).find_by_name_and_kind(
2701             tcx,
2702             *ident,
2703             ty::AssocKind::Fn,
2704             trait_ref.def_id,
2705         )?;
2706 
2707         let fn_sig = tcx.fn_sig(assoc.def_id).subst(
2708             tcx,
2709             trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
2710         );
2711         let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);
2712 
2713         Some(if let Some(arg_idx) = arg_idx {
2714             *fn_sig.inputs().get(arg_idx)?
2715         } else {
2716             fn_sig.output()
2717         })
2718     }
2719 
2720     #[instrument(level = "trace", skip(self, generate_err))]
validate_late_bound_regions( &self, constrained_regions: FxHashSet<ty::BoundRegionKind>, referenced_regions: FxHashSet<ty::BoundRegionKind>, generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>, )2721     fn validate_late_bound_regions(
2722         &self,
2723         constrained_regions: FxHashSet<ty::BoundRegionKind>,
2724         referenced_regions: FxHashSet<ty::BoundRegionKind>,
2725         generate_err: impl Fn(&str) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>,
2726     ) {
2727         for br in referenced_regions.difference(&constrained_regions) {
2728             let br_name = match *br {
2729                 ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) | ty::BrEnv => {
2730                     "an anonymous lifetime".to_string()
2731                 }
2732                 ty::BrNamed(_, name) => format!("lifetime `{}`", name),
2733             };
2734 
2735             let mut err = generate_err(&br_name);
2736 
2737             if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) = *br {
2738                 // The only way for an anonymous lifetime to wind up
2739                 // in the return type but **also** be unconstrained is
2740                 // if it only appears in "associated types" in the
2741                 // input. See #47511 and #62200 for examples. In this case,
2742                 // though we can easily give a hint that ought to be
2743                 // relevant.
2744                 err.note(
2745                     "lifetimes appearing in an associated or opaque type are not considered constrained",
2746                 );
2747                 err.note("consider introducing a named lifetime parameter");
2748             }
2749 
2750             err.emit();
2751         }
2752     }
2753 
2754     /// Given the bounds on an object, determines what single region bound (if any) we can
2755     /// use to summarize this type. The basic idea is that we will use the bound the user
2756     /// provided, if they provided one, and otherwise search the supertypes of trait bounds
2757     /// for region bounds. It may be that we can derive no bound at all, in which case
2758     /// we return `None`.
compute_object_lifetime_bound( &self, span: Span, existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Option<ty::Region<'tcx>>2759     fn compute_object_lifetime_bound(
2760         &self,
2761         span: Span,
2762         existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
2763     ) -> Option<ty::Region<'tcx>> // if None, use the default
2764     {
2765         let tcx = self.tcx();
2766 
2767         debug!("compute_opt_region_bound(existential_predicates={:?})", existential_predicates);
2768 
2769         // No explicit region bound specified. Therefore, examine trait
2770         // bounds and see if we can derive region bounds from those.
2771         let derived_region_bounds = object_region_bounds(tcx, existential_predicates);
2772 
2773         // If there are no derived region bounds, then report back that we
2774         // can find no region bound. The caller will use the default.
2775         if derived_region_bounds.is_empty() {
2776             return None;
2777         }
2778 
2779         // If any of the derived region bounds are 'static, that is always
2780         // the best choice.
2781         if derived_region_bounds.iter().any(|r| r.is_static()) {
2782             return Some(tcx.lifetimes.re_static);
2783         }
2784 
2785         // Determine whether there is exactly one unique region in the set
2786         // of derived region bounds. If so, use that. Otherwise, report an
2787         // error.
2788         let r = derived_region_bounds[0];
2789         if derived_region_bounds[1..].iter().any(|r1| r != *r1) {
2790             tcx.sess.emit_err(AmbiguousLifetimeBound { span });
2791         }
2792         Some(r)
2793     }
2794 }
2795