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