1 use super::IsMethodCall; 2 use crate::astconv::{ 3 AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch, 4 GenericArgCountResult, GenericArgPosition, 5 }; 6 use crate::errors::AssocTypeBindingNotAllowed; 7 use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; 8 use rustc_ast::ast::ParamKindOrd; 9 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorReported}; 10 use rustc_hir as hir; 11 use rustc_hir::def::{DefKind, Res}; 12 use rustc_hir::def_id::DefId; 13 use rustc_hir::GenericArg; 14 use rustc_middle::ty::{ 15 self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt, 16 }; 17 use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS; 18 use rustc_span::{symbol::kw, MultiSpan, Span}; 19 use smallvec::SmallVec; 20 21 impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { 22 /// Report an error that a generic argument did not match the generic parameter that was 23 /// expected. generic_arg_mismatch_err( tcx: TyCtxt<'_>, arg: &GenericArg<'_>, param: &GenericParamDef, possible_ordering_error: bool, help: Option<&str>, )24 fn generic_arg_mismatch_err( 25 tcx: TyCtxt<'_>, 26 arg: &GenericArg<'_>, 27 param: &GenericParamDef, 28 possible_ordering_error: bool, 29 help: Option<&str>, 30 ) { 31 let sess = tcx.sess; 32 let mut err = struct_span_err!( 33 sess, 34 arg.span(), 35 E0747, 36 "{} provided when a {} was expected", 37 arg.descr(), 38 param.kind.descr(), 39 ); 40 41 if let GenericParamDefKind::Const { .. } = param.kind { 42 if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. })) { 43 err.help("const arguments cannot yet be inferred with `_`"); 44 if sess.is_nightly_build() { 45 err.help( 46 "add `#![feature(generic_arg_infer)]` to the crate attributes to enable", 47 ); 48 } 49 } 50 } 51 52 let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| { 53 let suggestions = vec![ 54 (arg.span().shrink_to_lo(), String::from("{ ")), 55 (arg.span().shrink_to_hi(), String::from(" }")), 56 ]; 57 err.multipart_suggestion( 58 "if this generic argument was intended as a const parameter, \ 59 surround it with braces", 60 suggestions, 61 Applicability::MaybeIncorrect, 62 ); 63 }; 64 65 // Specific suggestion set for diagnostics 66 match (arg, ¶m.kind) { 67 ( 68 GenericArg::Type(hir::Ty { 69 kind: hir::TyKind::Path(rustc_hir::QPath::Resolved(_, path)), 70 .. 71 }), 72 GenericParamDefKind::Const { .. }, 73 ) => match path.res { 74 Res::Err => { 75 add_braces_suggestion(arg, &mut err); 76 err.set_primary_message( 77 "unresolved item provided when a constant was expected", 78 ) 79 .emit(); 80 return; 81 } 82 Res::Def(DefKind::TyParam, src_def_id) => { 83 if let Some(param_local_id) = param.def_id.as_local() { 84 let param_hir_id = tcx.hir().local_def_id_to_hir_id(param_local_id); 85 let param_name = tcx.hir().ty_param_name(param_hir_id); 86 let param_type = tcx.type_of(param.def_id); 87 if param_type.is_suggestable() { 88 err.span_suggestion( 89 tcx.def_span(src_def_id), 90 "consider changing this type parameter to be a `const` generic", 91 format!("const {}: {}", param_name, param_type), 92 Applicability::MaybeIncorrect, 93 ); 94 }; 95 } 96 } 97 _ => add_braces_suggestion(arg, &mut err), 98 }, 99 ( 100 GenericArg::Type(hir::Ty { kind: hir::TyKind::Path(_), .. }), 101 GenericParamDefKind::Const { .. }, 102 ) => add_braces_suggestion(arg, &mut err), 103 ( 104 GenericArg::Type(hir::Ty { kind: hir::TyKind::Array(_, len), .. }), 105 GenericParamDefKind::Const { .. }, 106 ) if tcx.type_of(param.def_id) == tcx.types.usize => { 107 let snippet = sess.source_map().span_to_snippet(tcx.hir().span(len.hir_id)); 108 if let Ok(snippet) = snippet { 109 err.span_suggestion( 110 arg.span(), 111 "array type provided where a `usize` was expected, try", 112 format!("{{ {} }}", snippet), 113 Applicability::MaybeIncorrect, 114 ); 115 } 116 } 117 (GenericArg::Const(cnst), GenericParamDefKind::Type { .. }) => { 118 let body = tcx.hir().body(cnst.value.body); 119 if let rustc_hir::ExprKind::Path(rustc_hir::QPath::Resolved(_, path)) = 120 body.value.kind 121 { 122 if let Res::Def(DefKind::Fn { .. }, id) = path.res { 123 err.help(&format!( 124 "`{}` is a function item, not a type", 125 tcx.item_name(id) 126 )); 127 err.help("function item types cannot be named directly"); 128 } 129 } 130 } 131 _ => {} 132 } 133 134 let kind_ord = param.kind.to_ord(tcx); 135 let arg_ord = arg.to_ord(tcx.features()); 136 137 // This note is only true when generic parameters are strictly ordered by their kind. 138 if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal { 139 let (first, last) = if kind_ord < arg_ord { 140 (param.kind.descr(), arg.descr()) 141 } else { 142 (arg.descr(), param.kind.descr()) 143 }; 144 err.note(&format!("{} arguments must be provided before {} arguments", first, last)); 145 if let Some(help) = help { 146 err.help(help); 147 } 148 } 149 150 err.emit(); 151 } 152 153 /// Creates the relevant generic argument substitutions 154 /// corresponding to a set of generic parameters. This is a 155 /// rather complex function. Let us try to explain the role 156 /// of each of its parameters: 157 /// 158 /// To start, we are given the `def_id` of the thing we are 159 /// creating the substitutions for, and a partial set of 160 /// substitutions `parent_substs`. In general, the substitutions 161 /// for an item begin with substitutions for all the "parents" of 162 /// that item -- e.g., for a method it might include the 163 /// parameters from the impl. 164 /// 165 /// Therefore, the method begins by walking down these parents, 166 /// starting with the outermost parent and proceed inwards until 167 /// it reaches `def_id`. For each parent `P`, it will check `parent_substs` 168 /// first to see if the parent's substitutions are listed in there. If so, 169 /// we can append those and move on. Otherwise, it invokes the 170 /// three callback functions: 171 /// 172 /// - `args_for_def_id`: given the `DefId` `P`, supplies back the 173 /// generic arguments that were given to that parent from within 174 /// the path; so e.g., if you have `<T as Foo>::Bar`, the `DefId` 175 /// might refer to the trait `Foo`, and the arguments might be 176 /// `[T]`. The boolean value indicates whether to infer values 177 /// for arguments whose values were not explicitly provided. 178 /// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`, 179 /// instantiate a `GenericArg`. 180 /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then 181 /// creates a suitable inference variable. create_substs_for_generic_args<'a>( tcx: TyCtxt<'tcx>, def_id: DefId, parent_substs: &[subst::GenericArg<'tcx>], has_self: bool, self_ty: Option<Ty<'tcx>>, arg_count: &GenericArgCountResult, ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, ) -> SubstsRef<'tcx>182 pub fn create_substs_for_generic_args<'a>( 183 tcx: TyCtxt<'tcx>, 184 def_id: DefId, 185 parent_substs: &[subst::GenericArg<'tcx>], 186 has_self: bool, 187 self_ty: Option<Ty<'tcx>>, 188 arg_count: &GenericArgCountResult, 189 ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>, 190 ) -> SubstsRef<'tcx> { 191 // Collect the segments of the path; we need to substitute arguments 192 // for parameters throughout the entire path (wherever there are 193 // generic parameters). 194 let mut parent_defs = tcx.generics_of(def_id); 195 let count = parent_defs.count(); 196 let mut stack = vec![(def_id, parent_defs)]; 197 while let Some(def_id) = parent_defs.parent { 198 parent_defs = tcx.generics_of(def_id); 199 stack.push((def_id, parent_defs)); 200 } 201 202 // We manually build up the substitution, rather than using convenience 203 // methods in `subst.rs`, so that we can iterate over the arguments and 204 // parameters in lock-step linearly, instead of trying to match each pair. 205 let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count); 206 // Iterate over each segment of the path. 207 while let Some((def_id, defs)) = stack.pop() { 208 let mut params = defs.params.iter().peekable(); 209 210 // If we have already computed substitutions for parents, we can use those directly. 211 while let Some(¶m) = params.peek() { 212 if let Some(&kind) = parent_substs.get(param.index as usize) { 213 substs.push(kind); 214 params.next(); 215 } else { 216 break; 217 } 218 } 219 220 // `Self` is handled first, unless it's been handled in `parent_substs`. 221 if has_self { 222 if let Some(¶m) = params.peek() { 223 if param.index == 0 { 224 if let GenericParamDefKind::Type { .. } = param.kind { 225 substs.push( 226 self_ty 227 .map(|ty| ty.into()) 228 .unwrap_or_else(|| ctx.inferred_kind(None, param, true)), 229 ); 230 params.next(); 231 } 232 } 233 } 234 } 235 236 // Check whether this segment takes generic arguments and the user has provided any. 237 let (generic_args, infer_args) = ctx.args_for_def_id(def_id); 238 239 let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter()); 240 let mut args = args_iter.clone().peekable(); 241 242 // If we encounter a type or const when we expect a lifetime, we infer the lifetimes. 243 // If we later encounter a lifetime, we know that the arguments were provided in the 244 // wrong order. `force_infer_lt` records the type or const that forced lifetimes to be 245 // inferred, so we can use it for diagnostics later. 246 let mut force_infer_lt = None; 247 248 loop { 249 // We're going to iterate through the generic arguments that the user 250 // provided, matching them with the generic parameters we expect. 251 // Mismatches can occur as a result of elided lifetimes, or for malformed 252 // input. We try to handle both sensibly. 253 match (args.peek(), params.peek()) { 254 (Some(&arg), Some(¶m)) => { 255 match (arg, ¶m.kind, arg_count.explicit_late_bound) { 256 (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _) 257 | ( 258 GenericArg::Type(_) | GenericArg::Infer(_), 259 GenericParamDefKind::Type { .. }, 260 _, 261 ) 262 | ( 263 GenericArg::Const(_) | GenericArg::Infer(_), 264 GenericParamDefKind::Const { .. }, 265 _, 266 ) => { 267 substs.push(ctx.provided_kind(param, arg)); 268 args.next(); 269 params.next(); 270 } 271 ( 272 GenericArg::Infer(_) | GenericArg::Type(_) | GenericArg::Const(_), 273 GenericParamDefKind::Lifetime, 274 _, 275 ) => { 276 // We expected a lifetime argument, but got a type or const 277 // argument. That means we're inferring the lifetimes. 278 substs.push(ctx.inferred_kind(None, param, infer_args)); 279 force_infer_lt = Some((arg, param)); 280 params.next(); 281 } 282 (GenericArg::Lifetime(_), _, ExplicitLateBound::Yes) => { 283 // We've come across a lifetime when we expected something else in 284 // the presence of explicit late bounds. This is most likely 285 // due to the presence of the explicit bound so we're just going to 286 // ignore it. 287 args.next(); 288 } 289 (_, _, _) => { 290 // We expected one kind of parameter, but the user provided 291 // another. This is an error. However, if we already know that 292 // the arguments don't match up with the parameters, we won't issue 293 // an additional error, as the user already knows what's wrong. 294 if arg_count.correct.is_ok() { 295 // We're going to iterate over the parameters to sort them out, and 296 // show that order to the user as a possible order for the parameters 297 let mut param_types_present = defs 298 .params 299 .clone() 300 .into_iter() 301 .map(|param| { 302 ( 303 match param.kind { 304 GenericParamDefKind::Lifetime => { 305 ParamKindOrd::Lifetime 306 } 307 GenericParamDefKind::Type { .. } => { 308 ParamKindOrd::Type 309 } 310 GenericParamDefKind::Const { .. } => { 311 ParamKindOrd::Const { 312 unordered: tcx 313 .features() 314 .unordered_const_ty_params(), 315 } 316 } 317 }, 318 param, 319 ) 320 }) 321 .collect::<Vec<(ParamKindOrd, GenericParamDef)>>(); 322 param_types_present.sort_by_key(|(ord, _)| *ord); 323 let (mut param_types_present, ordered_params): ( 324 Vec<ParamKindOrd>, 325 Vec<GenericParamDef>, 326 ) = param_types_present.into_iter().unzip(); 327 param_types_present.dedup(); 328 329 Self::generic_arg_mismatch_err( 330 tcx, 331 arg, 332 param, 333 !args_iter.clone().is_sorted_by_key(|arg| match arg { 334 GenericArg::Lifetime(_) => ParamKindOrd::Lifetime, 335 GenericArg::Type(_) => ParamKindOrd::Type, 336 GenericArg::Const(_) => ParamKindOrd::Const { 337 unordered: tcx 338 .features() 339 .unordered_const_ty_params(), 340 }, 341 GenericArg::Infer(_) => ParamKindOrd::Infer, 342 }), 343 Some(&format!( 344 "reorder the arguments: {}: `<{}>`", 345 param_types_present 346 .into_iter() 347 .map(|ord| format!("{}s", ord)) 348 .collect::<Vec<String>>() 349 .join(", then "), 350 ordered_params 351 .into_iter() 352 .filter_map(|param| { 353 if param.name == kw::SelfUpper { 354 None 355 } else { 356 Some(param.name.to_string()) 357 } 358 }) 359 .collect::<Vec<String>>() 360 .join(", ") 361 )), 362 ); 363 } 364 365 // We've reported the error, but we want to make sure that this 366 // problem doesn't bubble down and create additional, irrelevant 367 // errors. In this case, we're simply going to ignore the argument 368 // and any following arguments. The rest of the parameters will be 369 // inferred. 370 while args.next().is_some() {} 371 } 372 } 373 } 374 375 (Some(&arg), None) => { 376 // We should never be able to reach this point with well-formed input. 377 // There are three situations in which we can encounter this issue. 378 // 379 // 1. The number of arguments is incorrect. In this case, an error 380 // will already have been emitted, and we can ignore it. 381 // 2. There are late-bound lifetime parameters present, yet the 382 // lifetime arguments have also been explicitly specified by the 383 // user. 384 // 3. We've inferred some lifetimes, which have been provided later (i.e. 385 // after a type or const). We want to throw an error in this case. 386 387 if arg_count.correct.is_ok() 388 && arg_count.explicit_late_bound == ExplicitLateBound::No 389 { 390 let kind = arg.descr(); 391 assert_eq!(kind, "lifetime"); 392 let (provided_arg, param) = 393 force_infer_lt.expect("lifetimes ought to have been inferred"); 394 Self::generic_arg_mismatch_err(tcx, provided_arg, param, false, None); 395 } 396 397 break; 398 } 399 400 (None, Some(¶m)) => { 401 // If there are fewer arguments than parameters, it means 402 // we're inferring the remaining arguments. 403 substs.push(ctx.inferred_kind(Some(&substs), param, infer_args)); 404 params.next(); 405 } 406 407 (None, None) => break, 408 } 409 } 410 } 411 412 tcx.intern_substs(&substs) 413 } 414 415 /// Checks that the correct number of generic arguments have been provided. 416 /// Used specifically for function calls. check_generic_arg_count_for_call( tcx: TyCtxt<'_>, span: Span, def_id: DefId, generics: &ty::Generics, seg: &hir::PathSegment<'_>, is_method_call: IsMethodCall, ) -> GenericArgCountResult417 pub fn check_generic_arg_count_for_call( 418 tcx: TyCtxt<'_>, 419 span: Span, 420 def_id: DefId, 421 generics: &ty::Generics, 422 seg: &hir::PathSegment<'_>, 423 is_method_call: IsMethodCall, 424 ) -> GenericArgCountResult { 425 let empty_args = hir::GenericArgs::none(); 426 let suppress_mismatch = Self::check_impl_trait(tcx, seg, generics); 427 428 let gen_args = seg.args.unwrap_or(&empty_args); 429 let gen_pos = if is_method_call == IsMethodCall::Yes { 430 GenericArgPosition::MethodCall 431 } else { 432 GenericArgPosition::Value 433 }; 434 let has_self = generics.parent.is_none() && generics.has_self; 435 let infer_args = seg.infer_args || suppress_mismatch; 436 437 Self::check_generic_arg_count( 438 tcx, span, def_id, seg, generics, gen_args, gen_pos, has_self, infer_args, 439 ) 440 } 441 442 /// Checks that the correct number of generic arguments have been provided. 443 /// This is used both for datatypes and function calls. 444 #[instrument(skip(tcx, gen_pos), level = "debug")] check_generic_arg_count( tcx: TyCtxt<'_>, span: Span, def_id: DefId, seg: &hir::PathSegment<'_>, gen_params: &ty::Generics, gen_args: &hir::GenericArgs<'_>, gen_pos: GenericArgPosition, has_self: bool, infer_args: bool, ) -> GenericArgCountResult445 pub(crate) fn check_generic_arg_count( 446 tcx: TyCtxt<'_>, 447 span: Span, 448 def_id: DefId, 449 seg: &hir::PathSegment<'_>, 450 gen_params: &ty::Generics, 451 gen_args: &hir::GenericArgs<'_>, 452 gen_pos: GenericArgPosition, 453 has_self: bool, 454 infer_args: bool, 455 ) -> GenericArgCountResult { 456 let default_counts = gen_params.own_defaults(); 457 let param_counts = gen_params.own_counts(); 458 459 // Subtracting from param count to ensure type params synthesized from `impl Trait` 460 // cannot be explictly specified even with `explicit_generic_args_with_impl_trait` 461 // feature enabled. 462 let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait { 463 gen_params 464 .params 465 .iter() 466 .filter(|param| { 467 matches!(param.kind, ty::GenericParamDefKind::Type { synthetic: true, .. }) 468 }) 469 .count() 470 } else { 471 0 472 }; 473 let named_type_param_count = 474 param_counts.types - has_self as usize - synth_type_param_count; 475 let infer_lifetimes = 476 gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params(); 477 478 if gen_pos != GenericArgPosition::Type && !gen_args.bindings.is_empty() { 479 Self::prohibit_assoc_ty_binding(tcx, gen_args.bindings[0].span); 480 } 481 482 let explicit_late_bound = 483 Self::prohibit_explicit_late_bound_lifetimes(tcx, gen_params, gen_args, gen_pos); 484 485 let mut invalid_args = vec![]; 486 487 let mut check_lifetime_args = |min_expected_args: usize, 488 max_expected_args: usize, 489 provided_args: usize, 490 late_bounds_ignore: bool| 491 -> bool { 492 if (min_expected_args..=max_expected_args).contains(&provided_args) { 493 return true; 494 } 495 496 if late_bounds_ignore { 497 return true; 498 } 499 500 if provided_args > max_expected_args { 501 invalid_args.extend( 502 gen_args.args[max_expected_args..provided_args].iter().map(|arg| arg.span()), 503 ); 504 }; 505 506 let gen_args_info = if provided_args > min_expected_args { 507 invalid_args.extend( 508 gen_args.args[min_expected_args..provided_args].iter().map(|arg| arg.span()), 509 ); 510 let num_redundant_args = provided_args - min_expected_args; 511 GenericArgsInfo::ExcessLifetimes { num_redundant_args } 512 } else { 513 let num_missing_args = min_expected_args - provided_args; 514 GenericArgsInfo::MissingLifetimes { num_missing_args } 515 }; 516 517 WrongNumberOfGenericArgs::new( 518 tcx, 519 gen_args_info, 520 seg, 521 gen_params, 522 has_self as usize, 523 gen_args, 524 def_id, 525 ) 526 .diagnostic() 527 .emit(); 528 529 false 530 }; 531 532 let min_expected_lifetime_args = if infer_lifetimes { 0 } else { param_counts.lifetimes }; 533 let max_expected_lifetime_args = param_counts.lifetimes; 534 let num_provided_lifetime_args = gen_args.num_lifetime_params(); 535 536 let lifetimes_correct = check_lifetime_args( 537 min_expected_lifetime_args, 538 max_expected_lifetime_args, 539 num_provided_lifetime_args, 540 explicit_late_bound == ExplicitLateBound::Yes, 541 ); 542 543 let mut check_types_and_consts = 544 |expected_min, expected_max, provided, params_offset, args_offset| { 545 debug!( 546 ?expected_min, 547 ?expected_max, 548 ?provided, 549 ?params_offset, 550 ?args_offset, 551 "check_types_and_consts" 552 ); 553 if (expected_min..=expected_max).contains(&provided) { 554 return true; 555 } 556 557 let num_default_params = expected_max - expected_min; 558 559 let gen_args_info = if provided > expected_max { 560 invalid_args.extend( 561 gen_args.args[args_offset + expected_max..args_offset + provided] 562 .iter() 563 .map(|arg| arg.span()), 564 ); 565 let num_redundant_args = provided - expected_max; 566 567 GenericArgsInfo::ExcessTypesOrConsts { 568 num_redundant_args, 569 num_default_params, 570 args_offset, 571 } 572 } else { 573 let num_missing_args = expected_max - provided; 574 575 GenericArgsInfo::MissingTypesOrConsts { 576 num_missing_args, 577 num_default_params, 578 args_offset, 579 } 580 }; 581 582 debug!(?gen_args_info); 583 584 WrongNumberOfGenericArgs::new( 585 tcx, 586 gen_args_info, 587 seg, 588 gen_params, 589 params_offset, 590 gen_args, 591 def_id, 592 ) 593 .diagnostic() 594 .emit_unless(gen_args.has_err()); 595 596 false 597 }; 598 599 let args_correct = { 600 let expected_min = if infer_args { 601 0 602 } else { 603 param_counts.consts + named_type_param_count 604 - default_counts.types 605 - default_counts.consts 606 }; 607 debug!(?expected_min); 608 debug!(arg_counts.lifetimes=?gen_args.num_lifetime_params()); 609 610 check_types_and_consts( 611 expected_min, 612 param_counts.consts + named_type_param_count, 613 gen_args.num_generic_params(), 614 param_counts.lifetimes + has_self as usize, 615 gen_args.num_lifetime_params(), 616 ) 617 }; 618 619 GenericArgCountResult { 620 explicit_late_bound, 621 correct: if lifetimes_correct && args_correct { 622 Ok(()) 623 } else { 624 Err(GenericArgCountMismatch { reported: Some(ErrorReported), invalid_args }) 625 }, 626 } 627 } 628 629 /// Report error if there is an explicit type parameter when using `impl Trait`. check_impl_trait( tcx: TyCtxt<'_>, seg: &hir::PathSegment<'_>, generics: &ty::Generics, ) -> bool630 pub(crate) fn check_impl_trait( 631 tcx: TyCtxt<'_>, 632 seg: &hir::PathSegment<'_>, 633 generics: &ty::Generics, 634 ) -> bool { 635 if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait { 636 return false; 637 } 638 639 let impl_trait = generics.has_impl_trait(); 640 641 if impl_trait { 642 let spans = seg 643 .args() 644 .args 645 .iter() 646 .filter_map(|arg| match arg { 647 GenericArg::Infer(_) | GenericArg::Type(_) | GenericArg::Const(_) => { 648 Some(arg.span()) 649 } 650 _ => None, 651 }) 652 .collect::<Vec<_>>(); 653 654 let mut err = struct_span_err! { 655 tcx.sess, 656 spans.clone(), 657 E0632, 658 "cannot provide explicit generic arguments when `impl Trait` is \ 659 used in argument position" 660 }; 661 662 for span in spans { 663 err.span_label(span, "explicit generic argument not allowed"); 664 } 665 666 err.note( 667 "see issue #83701 <https://github.com/rust-lang/rust/issues/83701> \ 668 for more information", 669 ); 670 if tcx.sess.is_nightly_build() { 671 err.help( 672 "add `#![feature(explicit_generic_args_with_impl_trait)]` \ 673 to the crate attributes to enable", 674 ); 675 } 676 677 err.emit(); 678 } 679 680 impl_trait 681 } 682 683 /// Emits an error regarding forbidden type binding associations prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span)684 pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) { 685 tcx.sess.emit_err(AssocTypeBindingNotAllowed { span }); 686 } 687 688 /// Prohibits explicit lifetime arguments if late-bound lifetime parameters 689 /// are present. This is used both for datatypes and function calls. prohibit_explicit_late_bound_lifetimes( tcx: TyCtxt<'_>, def: &ty::Generics, args: &hir::GenericArgs<'_>, position: GenericArgPosition, ) -> ExplicitLateBound690 pub(crate) fn prohibit_explicit_late_bound_lifetimes( 691 tcx: TyCtxt<'_>, 692 def: &ty::Generics, 693 args: &hir::GenericArgs<'_>, 694 position: GenericArgPosition, 695 ) -> ExplicitLateBound { 696 let param_counts = def.own_counts(); 697 let infer_lifetimes = position != GenericArgPosition::Type && !args.has_lifetime_params(); 698 699 if infer_lifetimes { 700 return ExplicitLateBound::No; 701 } 702 703 if let Some(span_late) = def.has_late_bound_regions { 704 let msg = "cannot specify lifetime arguments explicitly \ 705 if late bound lifetime parameters are present"; 706 let note = "the late bound lifetime parameter is introduced here"; 707 let span = args.args[0].span(); 708 709 if position == GenericArgPosition::Value 710 && args.num_lifetime_params() != param_counts.lifetimes 711 { 712 let mut err = tcx.sess.struct_span_err(span, msg); 713 err.span_note(span_late, note); 714 err.emit(); 715 } else { 716 let mut multispan = MultiSpan::from_span(span); 717 multispan.push_span_label(span_late, note.to_string()); 718 tcx.struct_span_lint_hir( 719 LATE_BOUND_LIFETIME_ARGUMENTS, 720 args.args[0].id(), 721 multispan, 722 |lint| lint.build(msg).emit(), 723 ); 724 } 725 726 ExplicitLateBound::Yes 727 } else { 728 ExplicitLateBound::No 729 } 730 } 731 } 732