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 (¶m.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