]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_typeck/src/astconv/generics.rs
Rollup merge of #79211 - yoshuawuyts:future-doc-alias, r=Mark-Simulacrum
[rust.git] / compiler / rustc_typeck / src / astconv / generics.rs
1 use crate::astconv::{
2     AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
3     GenericArgCountResult, GenericArgPosition,
4 };
5 use crate::errors::AssocTypeBindingNotAllowed;
6 use rustc_ast::ast::ParamKindOrd;
7 use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorReported};
8 use rustc_hir as hir;
9 use rustc_hir::def_id::DefId;
10 use rustc_hir::GenericArg;
11 use rustc_middle::ty::{
12     self, subst, subst::SubstsRef, GenericParamDef, GenericParamDefKind, Ty, TyCtxt,
13 };
14 use rustc_session::{lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS, Session};
15 use rustc_span::{symbol::kw, MultiSpan, Span};
16
17 use smallvec::SmallVec;
18
19 impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
20     /// Report an error that a generic argument did not match the generic parameter that was
21     /// expected.
22     fn generic_arg_mismatch_err(
23         sess: &Session,
24         arg: &GenericArg<'_>,
25         kind: &'static str,
26         possible_ordering_error: bool,
27         help: Option<&str>,
28     ) {
29         let mut err = struct_span_err!(
30             sess,
31             arg.span(),
32             E0747,
33             "{} provided when a {} was expected",
34             arg.descr(),
35             kind,
36         );
37
38         let unordered = sess.features_untracked().const_generics;
39         let kind_ord = match kind {
40             "lifetime" => ParamKindOrd::Lifetime,
41             "type" => ParamKindOrd::Type,
42             "constant" => ParamKindOrd::Const { unordered },
43             // It's more concise to match on the string representation, though it means
44             // the match is non-exhaustive.
45             _ => bug!("invalid generic parameter kind {}", kind),
46         };
47
48         if let ParamKindOrd::Const { .. } = kind_ord {
49             if let GenericArg::Type(hir::Ty { kind: hir::TyKind::Infer, .. }) = arg {
50                 err.help("const arguments cannot yet be inferred with `_`");
51             }
52         }
53
54         let arg_ord = match arg {
55             GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
56             GenericArg::Type(_) => ParamKindOrd::Type,
57             GenericArg::Const(_) => ParamKindOrd::Const { unordered },
58         };
59
60         if matches!(arg, GenericArg::Type(hir::Ty { kind: hir::TyKind::Path { .. }, .. }))
61             && matches!(kind_ord, ParamKindOrd::Const { .. })
62         {
63             let suggestions = vec![
64                 (arg.span().shrink_to_lo(), String::from("{ ")),
65                 (arg.span().shrink_to_hi(), String::from(" }")),
66             ];
67             err.multipart_suggestion(
68                 "if this generic argument was intended as a const parameter, \
69                 try surrounding it with braces:",
70                 suggestions,
71                 Applicability::MaybeIncorrect,
72             );
73         }
74
75         // This note is only true when generic parameters are strictly ordered by their kind.
76         if possible_ordering_error && kind_ord.cmp(&arg_ord) != core::cmp::Ordering::Equal {
77             let (first, last) =
78                 if kind_ord < arg_ord { (kind, arg.descr()) } else { (arg.descr(), kind) };
79             err.note(&format!("{} arguments must be provided before {} arguments", first, last));
80             if let Some(help) = help {
81                 err.help(help);
82             }
83         }
84
85         err.emit();
86     }
87
88     /// Creates the relevant generic argument substitutions
89     /// corresponding to a set of generic parameters. This is a
90     /// rather complex function. Let us try to explain the role
91     /// of each of its parameters:
92     ///
93     /// To start, we are given the `def_id` of the thing we are
94     /// creating the substitutions for, and a partial set of
95     /// substitutions `parent_substs`. In general, the substitutions
96     /// for an item begin with substitutions for all the "parents" of
97     /// that item -- e.g., for a method it might include the
98     /// parameters from the impl.
99     ///
100     /// Therefore, the method begins by walking down these parents,
101     /// starting with the outermost parent and proceed inwards until
102     /// it reaches `def_id`. For each parent `P`, it will check `parent_substs`
103     /// first to see if the parent's substitutions are listed in there. If so,
104     /// we can append those and move on. Otherwise, it invokes the
105     /// three callback functions:
106     ///
107     /// - `args_for_def_id`: given the `DefId` `P`, supplies back the
108     ///   generic arguments that were given to that parent from within
109     ///   the path; so e.g., if you have `<T as Foo>::Bar`, the `DefId`
110     ///   might refer to the trait `Foo`, and the arguments might be
111     ///   `[T]`. The boolean value indicates whether to infer values
112     ///   for arguments whose values were not explicitly provided.
113     /// - `provided_kind`: given the generic parameter and the value from `args_for_def_id`,
114     ///   instantiate a `GenericArg`.
115     /// - `inferred_kind`: if no parameter was provided, and inference is enabled, then
116     ///   creates a suitable inference variable.
117     pub fn create_substs_for_generic_args<'a>(
118         tcx: TyCtxt<'tcx>,
119         def_id: DefId,
120         parent_substs: &[subst::GenericArg<'tcx>],
121         has_self: bool,
122         self_ty: Option<Ty<'tcx>>,
123         arg_count: GenericArgCountResult,
124         ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
125     ) -> SubstsRef<'tcx> {
126         // Collect the segments of the path; we need to substitute arguments
127         // for parameters throughout the entire path (wherever there are
128         // generic parameters).
129         let mut parent_defs = tcx.generics_of(def_id);
130         let count = parent_defs.count();
131         let mut stack = vec![(def_id, parent_defs)];
132         while let Some(def_id) = parent_defs.parent {
133             parent_defs = tcx.generics_of(def_id);
134             stack.push((def_id, parent_defs));
135         }
136
137         // We manually build up the substitution, rather than using convenience
138         // methods in `subst.rs`, so that we can iterate over the arguments and
139         // parameters in lock-step linearly, instead of trying to match each pair.
140         let mut substs: SmallVec<[subst::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
141         // Iterate over each segment of the path.
142         while let Some((def_id, defs)) = stack.pop() {
143             let mut params = defs.params.iter().peekable();
144
145             // If we have already computed substitutions for parents, we can use those directly.
146             while let Some(&param) = params.peek() {
147                 if let Some(&kind) = parent_substs.get(param.index as usize) {
148                     substs.push(kind);
149                     params.next();
150                 } else {
151                     break;
152                 }
153             }
154
155             // `Self` is handled first, unless it's been handled in `parent_substs`.
156             if has_self {
157                 if let Some(&param) = params.peek() {
158                     if param.index == 0 {
159                         if let GenericParamDefKind::Type { .. } = param.kind {
160                             substs.push(
161                                 self_ty
162                                     .map(|ty| ty.into())
163                                     .unwrap_or_else(|| ctx.inferred_kind(None, param, true)),
164                             );
165                             params.next();
166                         }
167                     }
168                 }
169             }
170
171             // Check whether this segment takes generic arguments and the user has provided any.
172             let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
173
174             let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
175             let mut args = args_iter.clone().peekable();
176
177             // If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
178             // If we later encounter a lifetime, we know that the arguments were provided in the
179             // wrong order. `force_infer_lt` records the type or const that forced lifetimes to be
180             // inferred, so we can use it for diagnostics later.
181             let mut force_infer_lt = None;
182
183             loop {
184                 // We're going to iterate through the generic arguments that the user
185                 // provided, matching them with the generic parameters we expect.
186                 // Mismatches can occur as a result of elided lifetimes, or for malformed
187                 // input. We try to handle both sensibly.
188                 match (args.peek(), params.peek()) {
189                     (Some(&arg), Some(&param)) => {
190                         match (arg, &param.kind, arg_count.explicit_late_bound) {
191                             (GenericArg::Lifetime(_), GenericParamDefKind::Lifetime, _)
192                             | (GenericArg::Type(_), GenericParamDefKind::Type { .. }, _)
193                             | (GenericArg::Const(_), GenericParamDefKind::Const, _) => {
194                                 substs.push(ctx.provided_kind(param, arg));
195                                 args.next();
196                                 params.next();
197                             }
198                             (
199                                 GenericArg::Type(_) | GenericArg::Const(_),
200                                 GenericParamDefKind::Lifetime,
201                                 _,
202                             ) => {
203                                 // We expected a lifetime argument, but got a type or const
204                                 // argument. That means we're inferring the lifetimes.
205                                 substs.push(ctx.inferred_kind(None, param, infer_args));
206                                 force_infer_lt = Some(arg);
207                                 params.next();
208                             }
209                             (GenericArg::Lifetime(_), _, ExplicitLateBound::Yes) => {
210                                 // We've come across a lifetime when we expected something else in
211                                 // the presence of explicit late bounds. This is most likely
212                                 // due to the presence of the explicit bound so we're just going to
213                                 // ignore it.
214                                 args.next();
215                             }
216                             (_, kind, _) => {
217                                 // We expected one kind of parameter, but the user provided
218                                 // another. This is an error. However, if we already know that
219                                 // the arguments don't match up with the parameters, we won't issue
220                                 // an additional error, as the user already knows what's wrong.
221                                 if arg_count.correct.is_ok()
222                                     && arg_count.explicit_late_bound == ExplicitLateBound::No
223                                 {
224                                     // We're going to iterate over the parameters to sort them out, and
225                                     // show that order to the user as a possible order for the parameters
226                                     let mut param_types_present = defs
227                                         .params
228                                         .clone()
229                                         .into_iter()
230                                         .map(|param| {
231                                             (
232                                                 match param.kind {
233                                                     GenericParamDefKind::Lifetime => {
234                                                         ParamKindOrd::Lifetime
235                                                     }
236                                                     GenericParamDefKind::Type { .. } => {
237                                                         ParamKindOrd::Type
238                                                     }
239                                                     GenericParamDefKind::Const => {
240                                                         ParamKindOrd::Const {
241                                                             unordered: tcx
242                                                                 .features()
243                                                                 .const_generics,
244                                                         }
245                                                     }
246                                                 },
247                                                 param,
248                                             )
249                                         })
250                                         .collect::<Vec<(ParamKindOrd, GenericParamDef)>>();
251                                     param_types_present.sort_by_key(|(ord, _)| *ord);
252                                     let (mut param_types_present, ordered_params): (
253                                         Vec<ParamKindOrd>,
254                                         Vec<GenericParamDef>,
255                                     ) = param_types_present.into_iter().unzip();
256                                     param_types_present.dedup();
257
258                                     Self::generic_arg_mismatch_err(
259                                         tcx.sess,
260                                         arg,
261                                         kind.descr(),
262                                         !args_iter.clone().is_sorted_by_key(|arg| match arg {
263                                             GenericArg::Lifetime(_) => ParamKindOrd::Lifetime,
264                                             GenericArg::Type(_) => ParamKindOrd::Type,
265                                             GenericArg::Const(_) => ParamKindOrd::Const {
266                                                 unordered: tcx.features().const_generics,
267                                             },
268                                         }),
269                                         Some(&format!(
270                                             "reorder the arguments: {}: `<{}>`",
271                                             param_types_present
272                                                 .into_iter()
273                                                 .map(|ord| format!("{}s", ord.to_string()))
274                                                 .collect::<Vec<String>>()
275                                                 .join(", then "),
276                                             ordered_params
277                                                 .into_iter()
278                                                 .filter_map(|param| {
279                                                     if param.name == kw::SelfUpper {
280                                                         None
281                                                     } else {
282                                                         Some(param.name.to_string())
283                                                     }
284                                                 })
285                                                 .collect::<Vec<String>>()
286                                                 .join(", ")
287                                         )),
288                                     );
289                                 }
290
291                                 // We've reported the error, but we want to make sure that this
292                                 // problem doesn't bubble down and create additional, irrelevant
293                                 // errors. In this case, we're simply going to ignore the argument
294                                 // and any following arguments. The rest of the parameters will be
295                                 // inferred.
296                                 while args.next().is_some() {}
297                             }
298                         }
299                     }
300
301                     (Some(&arg), None) => {
302                         // We should never be able to reach this point with well-formed input.
303                         // There are three situations in which we can encounter this issue.
304                         //
305                         //  1.  The number of arguments is incorrect. In this case, an error
306                         //      will already have been emitted, and we can ignore it.
307                         //  2.  There are late-bound lifetime parameters present, yet the
308                         //      lifetime arguments have also been explicitly specified by the
309                         //      user.
310                         //  3.  We've inferred some lifetimes, which have been provided later (i.e.
311                         //      after a type or const). We want to throw an error in this case.
312
313                         if arg_count.correct.is_ok()
314                             && arg_count.explicit_late_bound == ExplicitLateBound::No
315                         {
316                             let kind = arg.descr();
317                             assert_eq!(kind, "lifetime");
318                             let provided =
319                                 force_infer_lt.expect("lifetimes ought to have been inferred");
320                             Self::generic_arg_mismatch_err(tcx.sess, provided, kind, false, None);
321                         }
322
323                         break;
324                     }
325
326                     (None, Some(&param)) => {
327                         // If there are fewer arguments than parameters, it means
328                         // we're inferring the remaining arguments.
329                         substs.push(ctx.inferred_kind(Some(&substs), param, infer_args));
330                         params.next();
331                     }
332
333                     (None, None) => break,
334                 }
335             }
336         }
337
338         tcx.intern_substs(&substs)
339     }
340
341     /// Checks that the correct number of generic arguments have been provided.
342     /// Used specifically for function calls.
343     pub fn check_generic_arg_count_for_call(
344         tcx: TyCtxt<'_>,
345         span: Span,
346         def: &ty::Generics,
347         seg: &hir::PathSegment<'_>,
348         is_method_call: bool,
349     ) -> GenericArgCountResult {
350         let empty_args = hir::GenericArgs::none();
351         let suppress_mismatch = Self::check_impl_trait(tcx, seg, &def);
352         Self::check_generic_arg_count(
353             tcx,
354             span,
355             def,
356             if let Some(ref args) = seg.args { args } else { &empty_args },
357             if is_method_call { GenericArgPosition::MethodCall } else { GenericArgPosition::Value },
358             def.parent.is_none() && def.has_self, // `has_self`
359             seg.infer_args || suppress_mismatch,  // `infer_args`
360         )
361     }
362
363     /// Checks that the correct number of generic arguments have been provided.
364     /// This is used both for datatypes and function calls.
365     pub(crate) fn check_generic_arg_count(
366         tcx: TyCtxt<'_>,
367         span: Span,
368         def: &ty::Generics,
369         args: &hir::GenericArgs<'_>,
370         position: GenericArgPosition,
371         has_self: bool,
372         infer_args: bool,
373     ) -> GenericArgCountResult {
374         // At this stage we are guaranteed that the generic arguments are in the correct order, e.g.
375         // that lifetimes will proceed types. So it suffices to check the number of each generic
376         // arguments in order to validate them with respect to the generic parameters.
377         let param_counts = def.own_counts();
378         let named_type_param_count = param_counts.types - has_self as usize;
379         let arg_counts = args.own_counts();
380         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
381
382         let mut defaults: ty::GenericParamCount = Default::default();
383         for param in &def.params {
384             match param.kind {
385                 GenericParamDefKind::Lifetime => {}
386                 GenericParamDefKind::Type { has_default, .. } => {
387                     defaults.types += has_default as usize
388                 }
389                 GenericParamDefKind::Const => {
390                     // FIXME(const_generics:defaults)
391                 }
392             };
393         }
394
395         if position != GenericArgPosition::Type && !args.bindings.is_empty() {
396             AstConv::prohibit_assoc_ty_binding(tcx, args.bindings[0].span);
397         }
398
399         let explicit_late_bound =
400             Self::prohibit_explicit_late_bound_lifetimes(tcx, def, args, position);
401
402         let check_kind_count = |kind,
403                                 required,
404                                 permitted,
405                                 provided,
406                                 offset,
407                                 unexpected_spans: &mut Vec<Span>,
408                                 silent| {
409             debug!(
410                 "check_kind_count: kind: {} required: {} permitted: {} provided: {} offset: {}",
411                 kind, required, permitted, provided, offset
412             );
413             // We enforce the following: `required` <= `provided` <= `permitted`.
414             // For kinds without defaults (e.g.., lifetimes), `required == permitted`.
415             // For other kinds (i.e., types), `permitted` may be greater than `required`.
416             if required <= provided && provided <= permitted {
417                 return true;
418             }
419
420             if silent {
421                 return false;
422             }
423
424             // Unfortunately lifetime and type parameter mismatches are typically styled
425             // differently in diagnostics, which means we have a few cases to consider here.
426             let (bound, quantifier) = if required != permitted {
427                 if provided < required {
428                     (required, "at least ")
429                 } else {
430                     // provided > permitted
431                     (permitted, "at most ")
432                 }
433             } else {
434                 (required, "")
435             };
436
437             let (spans, labels) = if provided > permitted {
438                 // In the case when the user has provided too many arguments,
439                 // we want to point to the unexpected arguments.
440                 let (spans, labels): (Vec<Span>, Vec<String>) = args.args
441                     [offset + permitted..offset + provided]
442                     .iter()
443                     .map(|arg| (arg.span(), format!("unexpected {} argument", arg.short_descr())))
444                     .unzip();
445                 unexpected_spans.extend(spans.clone());
446                 (spans, labels)
447             } else {
448                 (
449                     vec![span],
450                     vec![format!(
451                         "expected {}{} {} argument{}",
452                         quantifier,
453                         bound,
454                         kind,
455                         pluralize!(bound),
456                     )],
457                 )
458             };
459
460             let mut err = tcx.sess.struct_span_err_with_code(
461                 spans.clone(),
462                 &format!(
463                     "wrong number of {} arguments: expected {}{}, found {}",
464                     kind, quantifier, bound, provided,
465                 ),
466                 DiagnosticId::Error("E0107".into()),
467             );
468             for (span, label) in spans.into_iter().zip(labels) {
469                 err.span_label(span, label.as_str());
470             }
471             err.emit();
472             false
473         };
474
475         let mut unexpected_spans = vec![];
476
477         let lifetime_count_correct = check_kind_count(
478             "lifetime",
479             if infer_lifetimes { 0 } else { param_counts.lifetimes },
480             param_counts.lifetimes,
481             arg_counts.lifetimes,
482             0,
483             &mut unexpected_spans,
484             explicit_late_bound == ExplicitLateBound::Yes,
485         );
486
487         let kind_str = if param_counts.consts + arg_counts.consts == 0 {
488             "type"
489         } else if named_type_param_count + arg_counts.types == 0 {
490             "const"
491         } else {
492             "generic"
493         };
494
495         let arg_count_correct = check_kind_count(
496             kind_str,
497             if infer_args {
498                 0
499             } else {
500                 param_counts.consts + named_type_param_count - defaults.types
501             },
502             param_counts.consts + named_type_param_count,
503             arg_counts.consts + arg_counts.types,
504             arg_counts.lifetimes,
505             &mut unexpected_spans,
506             false,
507         );
508
509         GenericArgCountResult {
510             explicit_late_bound,
511             correct: if lifetime_count_correct && arg_count_correct {
512                 Ok(())
513             } else {
514                 Err(GenericArgCountMismatch {
515                     reported: Some(ErrorReported),
516                     invalid_args: unexpected_spans,
517                 })
518             },
519         }
520     }
521
522     /// Report error if there is an explicit type parameter when using `impl Trait`.
523     pub(crate) fn check_impl_trait(
524         tcx: TyCtxt<'_>,
525         seg: &hir::PathSegment<'_>,
526         generics: &ty::Generics,
527     ) -> bool {
528         let explicit = !seg.infer_args;
529         let impl_trait =
530             generics.params.iter().any(|param| match param.kind {
531                 ty::GenericParamDefKind::Type {
532                     synthetic:
533                         Some(
534                             hir::SyntheticTyParamKind::ImplTrait
535                             | hir::SyntheticTyParamKind::FromAttr,
536                         ),
537                     ..
538                 } => true,
539                 _ => false,
540             });
541
542         if explicit && impl_trait {
543             let spans = seg
544                 .generic_args()
545                 .args
546                 .iter()
547                 .filter_map(|arg| match arg {
548                     GenericArg::Type(_) | GenericArg::Const(_) => Some(arg.span()),
549                     _ => None,
550                 })
551                 .collect::<Vec<_>>();
552
553             let mut err = struct_span_err! {
554                 tcx.sess,
555                 spans.clone(),
556                 E0632,
557                 "cannot provide explicit generic arguments when `impl Trait` is \
558                 used in argument position"
559             };
560
561             for span in spans {
562                 err.span_label(span, "explicit generic argument not allowed");
563             }
564
565             err.emit();
566         }
567
568         impl_trait
569     }
570
571     /// Emits an error regarding forbidden type binding associations
572     pub fn prohibit_assoc_ty_binding(tcx: TyCtxt<'_>, span: Span) {
573         tcx.sess.emit_err(AssocTypeBindingNotAllowed { span });
574     }
575
576     /// Prohibits explicit lifetime arguments if late-bound lifetime parameters
577     /// are present. This is used both for datatypes and function calls.
578     pub(crate) fn prohibit_explicit_late_bound_lifetimes(
579         tcx: TyCtxt<'_>,
580         def: &ty::Generics,
581         args: &hir::GenericArgs<'_>,
582         position: GenericArgPosition,
583     ) -> ExplicitLateBound {
584         let param_counts = def.own_counts();
585         let arg_counts = args.own_counts();
586         let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
587
588         if infer_lifetimes {
589             ExplicitLateBound::No
590         } else if let Some(span_late) = def.has_late_bound_regions {
591             let msg = "cannot specify lifetime arguments explicitly \
592                        if late bound lifetime parameters are present";
593             let note = "the late bound lifetime parameter is introduced here";
594             let span = args.args[0].span();
595             if position == GenericArgPosition::Value
596                 && arg_counts.lifetimes != param_counts.lifetimes
597             {
598                 let mut err = tcx.sess.struct_span_err(span, msg);
599                 err.span_note(span_late, note);
600                 err.emit();
601             } else {
602                 let mut multispan = MultiSpan::from_span(span);
603                 multispan.push_span_label(span_late, note.to_string());
604                 tcx.struct_span_lint_hir(
605                     LATE_BOUND_LIFETIME_ARGUMENTS,
606                     args.args[0].id(),
607                     multispan,
608                     |lint| lint.build(msg).emit(),
609                 );
610             }
611             ExplicitLateBound::Yes
612         } else {
613             ExplicitLateBound::No
614         }
615     }
616 }