]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / compiler / rustc_typeck / src / check / fn_ctxt / _impl.rs
1 use crate::astconv::{
2 AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
3 GenericArgCountResult, IsMethodCall, PathSeg,
4 };
5 use crate::check::callee::{self, DeferredCallResolution};
6 use crate::check::method::{self, MethodCallee, SelfSource};
7 use crate::check::{BreakableCtxt, Diverges, Expectation, FallbackMode, FnCtxt, LocalTy};
8
9 use rustc_ast::TraitObjectSyntax;
10 use rustc_data_structures::captures::Captures;
11 use rustc_data_structures::fx::FxHashSet;
12 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
13 use rustc_hir as hir;
14 use rustc_hir::def::{CtorOf, DefKind, Res};
15 use rustc_hir::def_id::DefId;
16 use rustc_hir::lang_items::LangItem;
17 use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
18 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
19 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
20 use rustc_infer::infer::{InferOk, InferResult};
21 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
22 use rustc_middle::ty::fold::TypeFoldable;
23 use rustc_middle::ty::subst::{
24 self, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
25 };
26 use rustc_middle::ty::{
27 self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
28 Ty, UserType,
29 };
30 use rustc_session::lint;
31 use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
32 use rustc_session::parse::feature_err;
33 use rustc_span::edition::Edition;
34 use rustc_span::source_map::{original_sp, DUMMY_SP};
35 use rustc_span::symbol::{kw, sym, Ident};
36 use rustc_span::{self, BytePos, MultiSpan, Span};
37 use rustc_span::{hygiene::DesugaringKind, Symbol};
38 use rustc_trait_selection::infer::InferCtxtExt as _;
39 use rustc_trait_selection::opaque_types::InferCtxtExt as _;
40 use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
41 use rustc_trait_selection::traits::{
42 self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt,
43 WellFormedLoc,
44 };
45
46 use std::collections::hash_map::Entry;
47 use std::iter;
48 use std::slice;
49
50 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
51 /// Produces warning on the given node, if the current point in the
52 /// function is unreachable, and there hasn't been another warning.
53 pub(in super::super) fn warn_if_unreachable(&self, id: hir::HirId, span: Span, kind: &str) {
54 // FIXME: Combine these two 'if' expressions into one once
55 // let chains are implemented
56 if let Diverges::Always { span: orig_span, custom_note } = self.diverges.get() {
57 // If span arose from a desugaring of `if` or `while`, then it is the condition itself,
58 // which diverges, that we are about to lint on. This gives suboptimal diagnostics.
59 // Instead, stop here so that the `if`- or `while`-expression's block is linted instead.
60 if !span.is_desugaring(DesugaringKind::CondTemporary)
61 && !span.is_desugaring(DesugaringKind::Async)
62 && !orig_span.is_desugaring(DesugaringKind::Await)
63 {
64 self.diverges.set(Diverges::WarnedAlways);
65
66 debug!("warn_if_unreachable: id={:?} span={:?} kind={}", id, span, kind);
67
68 self.tcx().struct_span_lint_hir(lint::builtin::UNREACHABLE_CODE, id, span, |lint| {
69 let msg = format!("unreachable {}", kind);
70 lint.build(&msg)
71 .span_label(span, &msg)
72 .span_label(
73 orig_span,
74 custom_note
75 .unwrap_or("any code following this expression is unreachable"),
76 )
77 .emit();
78 })
79 }
80 }
81 }
82
83 /// Resolves type and const variables in `ty` if possible. Unlike the infcx
84 /// version (resolve_vars_if_possible), this version will
85 /// also select obligations if it seems useful, in an effort
86 /// to get more type information.
87 pub(in super::super) fn resolve_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
88 debug!("resolve_vars_with_obligations(ty={:?})", ty);
89
90 // No Infer()? Nothing needs doing.
91 if !ty.has_infer_types_or_consts() {
92 debug!("resolve_vars_with_obligations: ty={:?}", ty);
93 return ty;
94 }
95
96 // If `ty` is a type variable, see whether we already know what it is.
97 ty = self.resolve_vars_if_possible(ty);
98 if !ty.has_infer_types_or_consts() {
99 debug!("resolve_vars_with_obligations: ty={:?}", ty);
100 return ty;
101 }
102
103 // If not, try resolving pending obligations as much as
104 // possible. This can help substantially when there are
105 // indirect dependencies that don't seem worth tracking
106 // precisely.
107 self.select_obligations_where_possible(false, |_| {});
108 ty = self.resolve_vars_if_possible(ty);
109
110 debug!("resolve_vars_with_obligations: ty={:?}", ty);
111 ty
112 }
113
114 pub(in super::super) fn record_deferred_call_resolution(
115 &self,
116 closure_def_id: DefId,
117 r: DeferredCallResolution<'tcx>,
118 ) {
119 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
120 deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
121 }
122
123 pub(in super::super) fn remove_deferred_call_resolutions(
124 &self,
125 closure_def_id: DefId,
126 ) -> Vec<DeferredCallResolution<'tcx>> {
127 let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
128 deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
129 }
130
131 pub fn tag(&self) -> String {
132 format!("{:p}", self)
133 }
134
135 pub fn local_ty(&self, span: Span, nid: hir::HirId) -> LocalTy<'tcx> {
136 self.locals.borrow().get(&nid).cloned().unwrap_or_else(|| {
137 span_bug!(span, "no type for local variable {}", self.tcx.hir().node_to_string(nid))
138 })
139 }
140
141 #[inline]
142 pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
143 debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag());
144 self.typeck_results.borrow_mut().node_types_mut().insert(id, ty);
145
146 if ty.references_error() {
147 self.has_errors.set(true);
148 self.set_tainted_by_errors();
149 }
150 }
151
152 pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) {
153 self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
154 }
155
156 pub(in super::super) fn write_resolution(
157 &self,
158 hir_id: hir::HirId,
159 r: Result<(DefKind, DefId), ErrorReported>,
160 ) {
161 self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
162 }
163
164 pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
165 debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
166 self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
167 self.write_substs(hir_id, method.substs);
168
169 // When the method is confirmed, the `method.substs` includes
170 // parameters from not just the method, but also the impl of
171 // the method -- in particular, the `Self` type will be fully
172 // resolved. However, those are not something that the "user
173 // specified" -- i.e., those types come from the inferred type
174 // of the receiver, not something the user wrote. So when we
175 // create the user-substs, we want to replace those earlier
176 // types with just the types that the user actually wrote --
177 // that is, those that appear on the *method itself*.
178 //
179 // As an example, if the user wrote something like
180 // `foo.bar::<u32>(...)` -- the `Self` type here will be the
181 // type of `foo` (possibly adjusted), but we don't want to
182 // include that. We want just the `[_, u32]` part.
183 if !method.substs.is_noop() {
184 let method_generics = self.tcx.generics_of(method.def_id);
185 if !method_generics.params.is_empty() {
186 let user_type_annotation = self.infcx.probe(|_| {
187 let user_substs = UserSubsts {
188 substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
189 let i = param.index as usize;
190 if i < method_generics.parent_count {
191 self.infcx.var_for_def(DUMMY_SP, param)
192 } else {
193 method.substs[i]
194 }
195 }),
196 user_self_ty: None, // not relevant here
197 };
198
199 self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
200 method.def_id,
201 user_substs,
202 ))
203 });
204
205 debug!("write_method_call: user_type_annotation={:?}", user_type_annotation);
206 self.write_user_type_annotation(hir_id, user_type_annotation);
207 }
208 }
209 }
210
211 pub fn write_substs(&self, node_id: hir::HirId, substs: SubstsRef<'tcx>) {
212 if !substs.is_noop() {
213 debug!("write_substs({:?}, {:?}) in fcx {}", node_id, substs, self.tag());
214
215 self.typeck_results.borrow_mut().node_substs_mut().insert(node_id, substs);
216 }
217 }
218
219 /// Given the substs that we just converted from the HIR, try to
220 /// canonicalize them and store them as user-given substitutions
221 /// (i.e., substitutions that must be respected by the NLL check).
222 ///
223 /// This should be invoked **before any unifications have
224 /// occurred**, so that annotations like `Vec<_>` are preserved
225 /// properly.
226 pub fn write_user_type_annotation_from_substs(
227 &self,
228 hir_id: hir::HirId,
229 def_id: DefId,
230 substs: SubstsRef<'tcx>,
231 user_self_ty: Option<UserSelfTy<'tcx>>,
232 ) {
233 debug!(
234 "write_user_type_annotation_from_substs: hir_id={:?} def_id={:?} substs={:?} \
235 user_self_ty={:?} in fcx {}",
236 hir_id,
237 def_id,
238 substs,
239 user_self_ty,
240 self.tag(),
241 );
242
243 if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
244 let canonicalized = self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
245 def_id,
246 UserSubsts { substs, user_self_ty },
247 ));
248 debug!("write_user_type_annotation_from_substs: canonicalized={:?}", canonicalized);
249 self.write_user_type_annotation(hir_id, canonicalized);
250 }
251 }
252
253 pub fn write_user_type_annotation(
254 &self,
255 hir_id: hir::HirId,
256 canonical_user_type_annotation: CanonicalUserType<'tcx>,
257 ) {
258 debug!(
259 "write_user_type_annotation: hir_id={:?} canonical_user_type_annotation={:?} tag={}",
260 hir_id,
261 canonical_user_type_annotation,
262 self.tag(),
263 );
264
265 if !canonical_user_type_annotation.is_identity() {
266 self.typeck_results
267 .borrow_mut()
268 .user_provided_types_mut()
269 .insert(hir_id, canonical_user_type_annotation);
270 } else {
271 debug!("write_user_type_annotation: skipping identity substs");
272 }
273 }
274
275 pub fn apply_adjustments(&self, expr: &hir::Expr<'_>, adj: Vec<Adjustment<'tcx>>) {
276 debug!("apply_adjustments(expr={:?}, adj={:?})", expr, adj);
277
278 if adj.is_empty() {
279 return;
280 }
281
282 let autoborrow_mut = adj.iter().any(|adj| {
283 matches!(
284 adj,
285 &Adjustment {
286 kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
287 ..
288 }
289 )
290 });
291
292 match self.typeck_results.borrow_mut().adjustments_mut().entry(expr.hir_id) {
293 Entry::Vacant(entry) => {
294 entry.insert(adj);
295 }
296 Entry::Occupied(mut entry) => {
297 debug!(" - composing on top of {:?}", entry.get());
298 match (&entry.get()[..], &adj[..]) {
299 // Applying any adjustment on top of a NeverToAny
300 // is a valid NeverToAny adjustment, because it can't
301 // be reached.
302 (&[Adjustment { kind: Adjust::NeverToAny, .. }], _) => return,
303 (&[
304 Adjustment { kind: Adjust::Deref(_), .. },
305 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(..)), .. },
306 ], &[
307 Adjustment { kind: Adjust::Deref(_), .. },
308 .. // Any following adjustments are allowed.
309 ]) => {
310 // A reborrow has no effect before a dereference.
311 }
312 // FIXME: currently we never try to compose autoderefs
313 // and ReifyFnPointer/UnsafeFnPointer, but we could.
314 _ =>
315 bug!("while adjusting {:?}, can't compose {:?} and {:?}",
316 expr, entry.get(), adj)
317 };
318 *entry.get_mut() = adj;
319 }
320 }
321
322 // If there is an mutable auto-borrow, it is equivalent to `&mut <expr>`.
323 // In this case implicit use of `Deref` and `Index` within `<expr>` should
324 // instead be `DerefMut` and `IndexMut`, so fix those up.
325 if autoborrow_mut {
326 self.convert_place_derefs_to_mutable(expr);
327 }
328 }
329
330 /// Basically whenever we are converting from a type scheme into
331 /// the fn body space, we always want to normalize associated
332 /// types as well. This function combines the two.
333 fn instantiate_type_scheme<T>(&self, span: Span, substs: SubstsRef<'tcx>, value: T) -> T
334 where
335 T: TypeFoldable<'tcx>,
336 {
337 debug!("instantiate_type_scheme(value={:?}, substs={:?})", value, substs);
338 let value = value.subst(self.tcx, substs);
339 let result = self.normalize_associated_types_in(span, value);
340 debug!("instantiate_type_scheme = {:?}", result);
341 result
342 }
343
344 /// As `instantiate_type_scheme`, but for the bounds found in a
345 /// generic type scheme.
346 pub(in super::super) fn instantiate_bounds(
347 &self,
348 span: Span,
349 def_id: DefId,
350 substs: SubstsRef<'tcx>,
351 ) -> (ty::InstantiatedPredicates<'tcx>, Vec<Span>) {
352 let bounds = self.tcx.predicates_of(def_id);
353 let spans: Vec<Span> = bounds.predicates.iter().map(|(_, span)| *span).collect();
354 let result = bounds.instantiate(self.tcx, substs);
355 let result = self.normalize_associated_types_in(span, result);
356 debug!(
357 "instantiate_bounds(bounds={:?}, substs={:?}) = {:?}, {:?}",
358 bounds, substs, result, spans,
359 );
360 (result, spans)
361 }
362
363 /// Replaces the opaque types from the given value with type variables,
364 /// and records the `OpaqueTypeMap` for later use during writeback. See
365 /// `InferCtxt::instantiate_opaque_types` for more details.
366 pub(in super::super) fn instantiate_opaque_types_from_value<T: TypeFoldable<'tcx>>(
367 &self,
368 parent_id: hir::HirId,
369 value: T,
370 value_span: Span,
371 feature: Option<Symbol>,
372 ) -> T {
373 let parent_def_id = self.tcx.hir().local_def_id(parent_id);
374 debug!(
375 "instantiate_opaque_types_from_value(parent_def_id={:?}, value={:?})",
376 parent_def_id, value
377 );
378
379 let (value, opaque_type_map) =
380 self.register_infer_ok_obligations(self.instantiate_opaque_types(
381 parent_def_id,
382 self.body_id,
383 self.param_env,
384 value,
385 value_span,
386 ));
387
388 let mut opaque_types = self.opaque_types.borrow_mut();
389 let mut opaque_types_vars = self.opaque_types_vars.borrow_mut();
390
391 for (ty, decl) in opaque_type_map {
392 if let Some(feature) = feature {
393 if let hir::OpaqueTyOrigin::TyAlias = decl.origin {
394 if !self.tcx.features().enabled(feature) {
395 feature_err(
396 &self.tcx.sess.parse_sess,
397 feature,
398 value_span,
399 "type alias impl trait is not permitted here",
400 )
401 .emit();
402 }
403 }
404 }
405 let _ = opaque_types.insert(ty, decl);
406 let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
407 }
408
409 value
410 }
411
412 /// Convenience method which tracks extra diagnostic information for normalization
413 /// that occurs as a result of WF checking. The `hir_id` is the `HirId` of the hir item
414 /// whose type is being wf-checked - this is used to construct a more precise span if
415 /// an error occurs.
416 ///
417 /// It is never necessary to call this method - calling `normalize_associated_types_in` will
418 /// just result in a slightly worse diagnostic span, and will still be sound.
419 pub(in super::super) fn normalize_associated_types_in_wf<T>(
420 &self,
421 span: Span,
422 value: T,
423 loc: WellFormedLoc,
424 ) -> T
425 where
426 T: TypeFoldable<'tcx>,
427 {
428 self.inh.normalize_associated_types_in_with_cause(
429 ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))),
430 self.param_env,
431 value,
432 )
433 }
434
435 pub(in super::super) fn normalize_associated_types_in<T>(&self, span: Span, value: T) -> T
436 where
437 T: TypeFoldable<'tcx>,
438 {
439 self.inh.normalize_associated_types_in(span, self.body_id, self.param_env, value)
440 }
441
442 pub(in super::super) fn normalize_associated_types_in_as_infer_ok<T>(
443 &self,
444 span: Span,
445 value: T,
446 ) -> InferOk<'tcx, T>
447 where
448 T: TypeFoldable<'tcx>,
449 {
450 self.inh.partially_normalize_associated_types_in(
451 ObligationCause::misc(span, self.body_id),
452 self.param_env,
453 value,
454 )
455 }
456
457 pub fn require_type_meets(
458 &self,
459 ty: Ty<'tcx>,
460 span: Span,
461 code: traits::ObligationCauseCode<'tcx>,
462 def_id: DefId,
463 ) {
464 self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
465 }
466
467 pub fn require_type_is_sized(
468 &self,
469 ty: Ty<'tcx>,
470 span: Span,
471 code: traits::ObligationCauseCode<'tcx>,
472 ) {
473 if !ty.references_error() {
474 let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
475 self.require_type_meets(ty, span, code, lang_item);
476 }
477 }
478
479 pub fn require_type_is_sized_deferred(
480 &self,
481 ty: Ty<'tcx>,
482 span: Span,
483 code: traits::ObligationCauseCode<'tcx>,
484 ) {
485 if !ty.references_error() {
486 self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
487 }
488 }
489
490 pub fn register_bound(
491 &self,
492 ty: Ty<'tcx>,
493 def_id: DefId,
494 cause: traits::ObligationCause<'tcx>,
495 ) {
496 if !ty.references_error() {
497 self.fulfillment_cx.borrow_mut().register_bound(
498 self,
499 self.param_env,
500 ty,
501 def_id,
502 cause,
503 );
504 }
505 }
506
507 pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
508 let t = <dyn AstConv<'_>>::ast_ty_to_ty(self, ast_t);
509 self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
510 t
511 }
512
513 pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
514 let ty = self.to_ty(ast_ty);
515 debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
516
517 if Self::can_contain_user_lifetime_bounds(ty) {
518 let c_ty = self.infcx.canonicalize_response(UserType::Ty(ty));
519 debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
520 self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
521 }
522
523 ty
524 }
525
526 pub fn to_const(&self, ast_c: &hir::AnonConst) -> &'tcx ty::Const<'tcx> {
527 let const_def_id = self.tcx.hir().local_def_id(ast_c.hir_id);
528 let c = ty::Const::from_anon_const(self.tcx, const_def_id);
529 self.register_wf_obligation(
530 c.into(),
531 self.tcx.hir().span(ast_c.hir_id),
532 ObligationCauseCode::MiscObligation,
533 );
534 c
535 }
536
537 pub fn const_arg_to_const(
538 &self,
539 ast_c: &hir::AnonConst,
540 param_def_id: DefId,
541 ) -> &'tcx ty::Const<'tcx> {
542 let const_def = ty::WithOptConstParam {
543 did: self.tcx.hir().local_def_id(ast_c.hir_id),
544 const_param_did: Some(param_def_id),
545 };
546 let c = ty::Const::from_opt_const_arg_anon_const(self.tcx, const_def);
547 self.register_wf_obligation(
548 c.into(),
549 self.tcx.hir().span(ast_c.hir_id),
550 ObligationCauseCode::MiscObligation,
551 );
552 c
553 }
554
555 // If the type given by the user has free regions, save it for later, since
556 // NLL would like to enforce those. Also pass in types that involve
557 // projections, since those can resolve to `'static` bounds (modulo #54940,
558 // which hopefully will be fixed by the time you see this comment, dear
559 // reader, although I have my doubts). Also pass in types with inference
560 // types, because they may be repeated. Other sorts of things are already
561 // sufficiently enforced with erased regions. =)
562 fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
563 where
564 T: TypeFoldable<'tcx>,
565 {
566 t.has_free_regions() || t.has_projections() || t.has_infer_types()
567 }
568
569 pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
570 match self.typeck_results.borrow().node_types().get(id) {
571 Some(&t) => t,
572 None if self.is_tainted_by_errors() => self.tcx.ty_error(),
573 None => {
574 bug!(
575 "no type for node {}: {} in fcx {}",
576 id,
577 self.tcx.hir().node_to_string(id),
578 self.tag()
579 );
580 }
581 }
582 }
583
584 /// Registers an obligation for checking later, during regionck, that `arg` is well-formed.
585 pub fn register_wf_obligation(
586 &self,
587 arg: subst::GenericArg<'tcx>,
588 span: Span,
589 code: traits::ObligationCauseCode<'tcx>,
590 ) {
591 // WF obligations never themselves fail, so no real need to give a detailed cause:
592 let cause = traits::ObligationCause::new(span, self.body_id, code);
593 self.register_predicate(traits::Obligation::new(
594 cause,
595 self.param_env,
596 ty::PredicateKind::WellFormed(arg).to_predicate(self.tcx),
597 ));
598 }
599
600 /// Registers obligations that all `substs` are well-formed.
601 pub fn add_wf_bounds(&self, substs: SubstsRef<'tcx>, expr: &hir::Expr<'_>) {
602 for arg in substs.iter().filter(|arg| {
603 matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
604 }) {
605 self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
606 }
607 }
608
609 /// Given a fully substituted set of bounds (`generic_bounds`), and the values with which each
610 /// type/region parameter was instantiated (`substs`), creates and registers suitable
611 /// trait/region obligations.
612 ///
613 /// For example, if there is a function:
614 ///
615 /// ```
616 /// fn foo<'a,T:'a>(...)
617 /// ```
618 ///
619 /// and a reference:
620 ///
621 /// ```
622 /// let f = foo;
623 /// ```
624 ///
625 /// Then we will create a fresh region variable `'$0` and a fresh type variable `$1` for `'a`
626 /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
627 pub fn add_obligations_for_parameters(
628 &self,
629 cause: traits::ObligationCause<'tcx>,
630 predicates: ty::InstantiatedPredicates<'tcx>,
631 ) {
632 assert!(!predicates.has_escaping_bound_vars());
633
634 debug!("add_obligations_for_parameters(predicates={:?})", predicates);
635
636 for obligation in traits::predicates_for_generics(cause, self.param_env, predicates) {
637 self.register_predicate(obligation);
638 }
639 }
640
641 // FIXME(arielb1): use this instead of field.ty everywhere
642 // Only for fields! Returns <none> for methods>
643 // Indifferent to privacy flags
644 pub fn field_ty(
645 &self,
646 span: Span,
647 field: &'tcx ty::FieldDef,
648 substs: SubstsRef<'tcx>,
649 ) -> Ty<'tcx> {
650 self.normalize_associated_types_in(span, &field.ty(self.tcx, substs))
651 }
652
653 pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) {
654 let mut generators = self.deferred_generator_interiors.borrow_mut();
655 for (body_id, interior, kind) in generators.drain(..) {
656 self.select_obligations_where_possible(false, |_| {});
657 crate::check::generator_interior::resolve_interior(
658 self, def_id, body_id, interior, kind,
659 );
660 }
661 }
662
663 // Tries to apply a fallback to `ty` if it is an unsolved variable.
664 //
665 // - Unconstrained ints are replaced with `i32`.
666 //
667 // - Unconstrained floats are replaced with with `f64`.
668 //
669 // - Non-numerics get replaced with `!` when `#![feature(never_type_fallback)]`
670 // is enabled. Otherwise, they are replaced with `()`.
671 //
672 // Fallback becomes very dubious if we have encountered type-checking errors.
673 // In that case, fallback to Error.
674 // The return value indicates whether fallback has occurred.
675 pub(in super::super) fn fallback_if_possible(&self, ty: Ty<'tcx>, mode: FallbackMode) -> bool {
676 use rustc_middle::ty::error::UnconstrainedNumeric::Neither;
677 use rustc_middle::ty::error::UnconstrainedNumeric::{UnconstrainedFloat, UnconstrainedInt};
678
679 assert!(ty.is_ty_infer());
680 let fallback = match self.type_is_unconstrained_numeric(ty) {
681 _ if self.is_tainted_by_errors() => self.tcx().ty_error(),
682 UnconstrainedInt => self.tcx.types.i32,
683 UnconstrainedFloat => self.tcx.types.f64,
684 Neither if self.type_var_diverges(ty) => self.tcx.mk_diverging_default(),
685 Neither => {
686 // This type variable was created from the instantiation of an opaque
687 // type. The fact that we're attempting to perform fallback for it
688 // means that the function neither constrained it to a concrete
689 // type, nor to the opaque type itself.
690 //
691 // For example, in this code:
692 //
693 //```
694 // type MyType = impl Copy;
695 // fn defining_use() -> MyType { true }
696 // fn other_use() -> MyType { defining_use() }
697 // ```
698 //
699 // `defining_use` will constrain the instantiated inference
700 // variable to `bool`, while `other_use` will constrain
701 // the instantiated inference variable to `MyType`.
702 //
703 // When we process opaque types during writeback, we
704 // will handle cases like `other_use`, and not count
705 // them as defining usages
706 //
707 // However, we also need to handle cases like this:
708 //
709 // ```rust
710 // pub type Foo = impl Copy;
711 // fn produce() -> Option<Foo> {
712 // None
713 // }
714 // ```
715 //
716 // In the above snippet, the inference variable created by
717 // instantiating `Option<Foo>` will be completely unconstrained.
718 // We treat this as a non-defining use by making the inference
719 // variable fall back to the opaque type itself.
720 if let FallbackMode::All = mode {
721 if let Some(opaque_ty) = self.opaque_types_vars.borrow().get(ty) {
722 debug!(
723 "fallback_if_possible: falling back opaque type var {:?} to {:?}",
724 ty, opaque_ty
725 );
726 *opaque_ty
727 } else {
728 return false;
729 }
730 } else {
731 return false;
732 }
733 }
734 };
735 debug!("fallback_if_possible: defaulting `{:?}` to `{:?}`", ty, fallback);
736 self.demand_eqtype(rustc_span::DUMMY_SP, ty, fallback);
737 true
738 }
739
740 pub(in super::super) fn select_all_obligations_or_error(&self) {
741 debug!("select_all_obligations_or_error");
742 if let Err(errors) = self.fulfillment_cx.borrow_mut().select_all_or_error(&self) {
743 self.report_fulfillment_errors(&errors, self.inh.body_id, false);
744 }
745 }
746
747 /// Select as many obligations as we can at present.
748 pub(in super::super) fn select_obligations_where_possible(
749 &self,
750 fallback_has_occurred: bool,
751 mutate_fulfillment_errors: impl Fn(&mut Vec<traits::FulfillmentError<'tcx>>),
752 ) {
753 let result = self.fulfillment_cx.borrow_mut().select_where_possible(self);
754 if let Err(mut errors) = result {
755 mutate_fulfillment_errors(&mut errors);
756 self.report_fulfillment_errors(&errors, self.inh.body_id, fallback_has_occurred);
757 }
758 }
759
760 /// For the overloaded place expressions (`*x`, `x[3]`), the trait
761 /// returns a type of `&T`, but the actual type we assign to the
762 /// *expression* is `T`. So this function just peels off the return
763 /// type by one layer to yield `T`.
764 pub(in super::super) fn make_overloaded_place_return_type(
765 &self,
766 method: MethodCallee<'tcx>,
767 ) -> ty::TypeAndMut<'tcx> {
768 // extract method return type, which will be &T;
769 let ret_ty = method.sig.output();
770
771 // method returns &T, but the type as visible to user is T, so deref
772 ret_ty.builtin_deref(true).unwrap()
773 }
774
775 fn self_type_matches_expected_vid(
776 &self,
777 trait_ref: ty::PolyTraitRef<'tcx>,
778 expected_vid: ty::TyVid,
779 ) -> bool {
780 let self_ty = self.shallow_resolve(trait_ref.skip_binder().self_ty());
781 debug!(
782 "self_type_matches_expected_vid(trait_ref={:?}, self_ty={:?}, expected_vid={:?})",
783 trait_ref, self_ty, expected_vid
784 );
785 match *self_ty.kind() {
786 ty::Infer(ty::TyVar(found_vid)) => {
787 // FIXME: consider using `sub_root_var` here so we
788 // can see through subtyping.
789 let found_vid = self.root_var(found_vid);
790 debug!("self_type_matches_expected_vid - found_vid={:?}", found_vid);
791 expected_vid == found_vid
792 }
793 _ => false,
794 }
795 }
796
797 pub(in super::super) fn obligations_for_self_ty<'b>(
798 &'b self,
799 self_ty: ty::TyVid,
800 ) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, traits::PredicateObligation<'tcx>)>
801 + Captures<'tcx>
802 + 'b {
803 // FIXME: consider using `sub_root_var` here so we
804 // can see through subtyping.
805 let ty_var_root = self.root_var(self_ty);
806 debug!(
807 "obligations_for_self_ty: self_ty={:?} ty_var_root={:?} pending_obligations={:?}",
808 self_ty,
809 ty_var_root,
810 self.fulfillment_cx.borrow().pending_obligations()
811 );
812
813 self.fulfillment_cx
814 .borrow()
815 .pending_obligations()
816 .into_iter()
817 .filter_map(move |obligation| {
818 let bound_predicate = obligation.predicate.kind();
819 match bound_predicate.skip_binder() {
820 ty::PredicateKind::Projection(data) => Some((
821 bound_predicate.rebind(data).required_poly_trait_ref(self.tcx),
822 obligation,
823 )),
824 ty::PredicateKind::Trait(data, _) => {
825 Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
826 }
827 ty::PredicateKind::Subtype(..) => None,
828 ty::PredicateKind::RegionOutlives(..) => None,
829 ty::PredicateKind::TypeOutlives(..) => None,
830 ty::PredicateKind::WellFormed(..) => None,
831 ty::PredicateKind::ObjectSafe(..) => None,
832 ty::PredicateKind::ConstEvaluatable(..) => None,
833 ty::PredicateKind::ConstEquate(..) => None,
834 // N.B., this predicate is created by breaking down a
835 // `ClosureType: FnFoo()` predicate, where
836 // `ClosureType` represents some `Closure`. It can't
837 // possibly be referring to the current closure,
838 // because we haven't produced the `Closure` for
839 // this closure yet; this is exactly why the other
840 // code is looking for a self type of a unresolved
841 // inference variable.
842 ty::PredicateKind::ClosureKind(..) => None,
843 ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
844 }
845 })
846 .filter(move |(tr, _)| self.self_type_matches_expected_vid(*tr, ty_var_root))
847 }
848
849 pub(in super::super) fn type_var_is_sized(&self, self_ty: ty::TyVid) -> bool {
850 self.obligations_for_self_ty(self_ty)
851 .any(|(tr, _)| Some(tr.def_id()) == self.tcx.lang_items().sized_trait())
852 }
853
854 pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> {
855 vec![self.tcx.ty_error(); len]
856 }
857
858 /// Unifies the output type with the expected type early, for more coercions
859 /// and forward type information on the input expressions.
860 pub(in super::super) fn expected_inputs_for_expected_output(
861 &self,
862 call_span: Span,
863 expected_ret: Expectation<'tcx>,
864 formal_ret: Ty<'tcx>,
865 formal_args: &[Ty<'tcx>],
866 ) -> Vec<Ty<'tcx>> {
867 let formal_ret = self.resolve_vars_with_obligations(formal_ret);
868 let ret_ty = match expected_ret.only_has_type(self) {
869 Some(ret) => ret,
870 None => return Vec::new(),
871 };
872 let expect_args = self
873 .fudge_inference_if_ok(|| {
874 // Attempt to apply a subtyping relationship between the formal
875 // return type (likely containing type variables if the function
876 // is polymorphic) and the expected return type.
877 // No argument expectations are produced if unification fails.
878 let origin = self.misc(call_span);
879 let ures = self.at(&origin, self.param_env).sup(ret_ty, &formal_ret);
880
881 // FIXME(#27336) can't use ? here, Try::from_error doesn't default
882 // to identity so the resulting type is not constrained.
883 match ures {
884 Ok(ok) => {
885 // Process any obligations locally as much as
886 // we can. We don't care if some things turn
887 // out unconstrained or ambiguous, as we're
888 // just trying to get hints here.
889 self.save_and_restore_in_snapshot_flag(|_| {
890 let mut fulfill = <dyn TraitEngine<'_>>::new(self.tcx);
891 for obligation in ok.obligations {
892 fulfill.register_predicate_obligation(self, obligation);
893 }
894 fulfill.select_where_possible(self)
895 })
896 .map_err(|_| ())?;
897 }
898 Err(_) => return Err(()),
899 }
900
901 // Record all the argument types, with the substitutions
902 // produced from the above subtyping unification.
903 Ok(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect())
904 })
905 .unwrap_or_default();
906 debug!(
907 "expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
908 formal_args, formal_ret, expect_args, expected_ret
909 );
910 expect_args
911 }
912
913 pub(in super::super) fn resolve_lang_item_path(
914 &self,
915 lang_item: hir::LangItem,
916 span: Span,
917 hir_id: hir::HirId,
918 ) -> (Res, Ty<'tcx>) {
919 let def_id = self.tcx.require_lang_item(lang_item, Some(span));
920 let def_kind = self.tcx.def_kind(def_id);
921
922 let item_ty = if let DefKind::Variant = def_kind {
923 self.tcx.type_of(self.tcx.parent(def_id).expect("variant w/out parent"))
924 } else {
925 self.tcx.type_of(def_id)
926 };
927 let substs = self.infcx.fresh_substs_for_item(span, def_id);
928 let ty = item_ty.subst(self.tcx, substs);
929
930 self.write_resolution(hir_id, Ok((def_kind, def_id)));
931 self.add_required_obligations(span, def_id, &substs);
932 (Res::Def(def_kind, def_id), ty)
933 }
934
935 /// Resolves an associated value path into a base type and associated constant, or method
936 /// resolution. The newly resolved definition is written into `type_dependent_defs`.
937 pub fn resolve_ty_and_res_fully_qualified_call(
938 &self,
939 qpath: &'tcx QPath<'tcx>,
940 hir_id: hir::HirId,
941 span: Span,
942 ) -> (Res, Option<Ty<'tcx>>, &'tcx [hir::PathSegment<'tcx>]) {
943 debug!(
944 "resolve_ty_and_res_fully_qualified_call: qpath={:?} hir_id={:?} span={:?}",
945 qpath, hir_id, span
946 );
947 let (ty, qself, item_segment) = match *qpath {
948 QPath::Resolved(ref opt_qself, ref path) => {
949 return (
950 path.res,
951 opt_qself.as_ref().map(|qself| self.to_ty(qself)),
952 path.segments,
953 );
954 }
955 QPath::TypeRelative(ref qself, ref segment) => (self.to_ty(qself), qself, segment),
956 QPath::LangItem(..) => {
957 bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
958 }
959 };
960 if let Some(&cached_result) = self.typeck_results.borrow().type_dependent_defs().get(hir_id)
961 {
962 // Return directly on cache hit. This is useful to avoid doubly reporting
963 // errors with default match binding modes. See #44614.
964 let def = cached_result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id));
965 return (def, Some(ty), slice::from_ref(&**item_segment));
966 }
967 let item_name = item_segment.ident;
968 let result = self
969 .resolve_fully_qualified_call(span, item_name, ty, qself.span, hir_id)
970 .or_else(|error| {
971 let result = match error {
972 method::MethodError::PrivateMatch(kind, def_id, _) => Ok((kind, def_id)),
973 _ => Err(ErrorReported),
974 };
975 if item_name.name != kw::Empty {
976 if let Some(mut e) = self.report_method_error(
977 span,
978 ty,
979 item_name,
980 SelfSource::QPath(qself),
981 error,
982 None,
983 ) {
984 e.emit();
985 }
986 }
987 result
988 });
989
990 if result.is_ok() {
991 self.maybe_lint_bare_trait(qpath, hir_id);
992 }
993
994 // Write back the new resolution.
995 self.write_resolution(hir_id, result);
996 (
997 result.map_or(Res::Err, |(kind, def_id)| Res::Def(kind, def_id)),
998 Some(ty),
999 slice::from_ref(&**item_segment),
1000 )
1001 }
1002
1003 fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId) {
1004 if let QPath::TypeRelative(self_ty, _) = qpath {
1005 if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
1006 self_ty.kind
1007 {
1008 let msg = "trait objects without an explicit `dyn` are deprecated";
1009 let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) {
1010 Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
1011 (format!("<dyn ({})>", s), Applicability::MachineApplicable)
1012 }
1013 Ok(s) => (format!("<dyn {}>", s), Applicability::MachineApplicable),
1014 Err(_) => ("<dyn <type>>".to_string(), Applicability::HasPlaceholders),
1015 };
1016 let replace = String::from("use `dyn`");
1017 if self.sess().edition() >= Edition::Edition2021 {
1018 let mut err = rustc_errors::struct_span_err!(
1019 self.sess(),
1020 self_ty.span,
1021 E0783,
1022 "{}",
1023 msg,
1024 );
1025 err.span_suggestion(
1026 self_ty.span,
1027 &sugg,
1028 replace,
1029 Applicability::MachineApplicable,
1030 )
1031 .emit();
1032 } else {
1033 self.tcx.struct_span_lint_hir(
1034 BARE_TRAIT_OBJECTS,
1035 hir_id,
1036 self_ty.span,
1037 |lint| {
1038 let mut db = lint.build(msg);
1039 db.span_suggestion(self_ty.span, &replace, sugg, app);
1040 db.emit()
1041 },
1042 );
1043 }
1044 }
1045 }
1046 }
1047
1048 /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
1049 pub(in super::super) fn get_node_fn_decl(
1050 &self,
1051 node: Node<'tcx>,
1052 ) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
1053 match node {
1054 Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
1055 // This is less than ideal, it will not suggest a return type span on any
1056 // method called `main`, regardless of whether it is actually the entry point,
1057 // but it will still present it as the reason for the expected type.
1058 Some((&sig.decl, ident, ident.name != sym::main))
1059 }
1060 Node::TraitItem(&hir::TraitItem {
1061 ident,
1062 kind: hir::TraitItemKind::Fn(ref sig, ..),
1063 ..
1064 }) => Some((&sig.decl, ident, true)),
1065 Node::ImplItem(&hir::ImplItem {
1066 ident,
1067 kind: hir::ImplItemKind::Fn(ref sig, ..),
1068 ..
1069 }) => Some((&sig.decl, ident, false)),
1070 _ => None,
1071 }
1072 }
1073
1074 /// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
1075 /// suggestion can be made, `None` otherwise.
1076 pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
1077 // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
1078 // `while` before reaching it, as block tail returns are not available in them.
1079 self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
1080 let parent = self.tcx.hir().get(blk_id);
1081 self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
1082 })
1083 }
1084
1085 pub(in super::super) fn note_internal_mutation_in_method(
1086 &self,
1087 err: &mut DiagnosticBuilder<'_>,
1088 expr: &hir::Expr<'_>,
1089 expected: Ty<'tcx>,
1090 found: Ty<'tcx>,
1091 ) {
1092 if found != self.tcx.types.unit {
1093 return;
1094 }
1095 if let ExprKind::MethodCall(path_segment, _, [rcvr, ..], _) = expr.kind {
1096 if self
1097 .typeck_results
1098 .borrow()
1099 .expr_ty_adjusted_opt(rcvr)
1100 .map_or(true, |ty| expected.peel_refs() != ty.peel_refs())
1101 {
1102 return;
1103 }
1104 let mut sp = MultiSpan::from_span(path_segment.ident.span);
1105 sp.push_span_label(
1106 path_segment.ident.span,
1107 format!(
1108 "this call modifies {} in-place",
1109 match rcvr.kind {
1110 ExprKind::Path(QPath::Resolved(
1111 None,
1112 hir::Path { segments: [segment], .. },
1113 )) => format!("`{}`", segment.ident),
1114 _ => "its receiver".to_string(),
1115 }
1116 ),
1117 );
1118 sp.push_span_label(
1119 rcvr.span,
1120 "you probably want to use this value after calling the method...".to_string(),
1121 );
1122 err.span_note(
1123 sp,
1124 &format!("method `{}` modifies its receiver in-place", path_segment.ident),
1125 );
1126 err.note(&format!("...instead of the `()` output of method `{}`", path_segment.ident));
1127 }
1128 }
1129
1130 pub(in super::super) fn note_need_for_fn_pointer(
1131 &self,
1132 err: &mut DiagnosticBuilder<'_>,
1133 expected: Ty<'tcx>,
1134 found: Ty<'tcx>,
1135 ) {
1136 let (sig, did, substs) = match (&expected.kind(), &found.kind()) {
1137 (ty::FnDef(did1, substs1), ty::FnDef(did2, substs2)) => {
1138 let sig1 = self.tcx.fn_sig(*did1).subst(self.tcx, substs1);
1139 let sig2 = self.tcx.fn_sig(*did2).subst(self.tcx, substs2);
1140 if sig1 != sig2 {
1141 return;
1142 }
1143 err.note(
1144 "different `fn` items always have unique types, even if their signatures are \
1145 the same",
1146 );
1147 (sig1, *did1, substs1)
1148 }
1149 (ty::FnDef(did, substs), ty::FnPtr(sig2)) => {
1150 let sig1 = self.tcx.fn_sig(*did).subst(self.tcx, substs);
1151 if sig1 != *sig2 {
1152 return;
1153 }
1154 (sig1, *did, substs)
1155 }
1156 _ => return,
1157 };
1158 err.help(&format!("change the expected type to be function pointer `{}`", sig));
1159 err.help(&format!(
1160 "if the expected type is due to type inference, cast the expected `fn` to a function \
1161 pointer: `{} as {}`",
1162 self.tcx.def_path_str_with_substs(did, substs),
1163 sig
1164 ));
1165 }
1166
1167 pub(in super::super) fn could_remove_semicolon(
1168 &self,
1169 blk: &'tcx hir::Block<'tcx>,
1170 expected_ty: Ty<'tcx>,
1171 ) -> Option<(Span, StatementAsExpression)> {
1172 // Be helpful when the user wrote `{... expr;}` and
1173 // taking the `;` off is enough to fix the error.
1174 let last_stmt = blk.stmts.last()?;
1175 let last_expr = match last_stmt.kind {
1176 hir::StmtKind::Semi(ref e) => e,
1177 _ => return None,
1178 };
1179 let last_expr_ty = self.node_ty(last_expr.hir_id);
1180 let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
1181 (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _))
1182 if last_def_id == exp_def_id =>
1183 {
1184 StatementAsExpression::CorrectType
1185 }
1186 (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => {
1187 debug!(
1188 "both opaque, likely future {:?} {:?} {:?} {:?}",
1189 last_def_id, last_bounds, exp_def_id, exp_bounds
1190 );
1191
1192 let (last_local_id, exp_local_id) =
1193 match (last_def_id.as_local(), exp_def_id.as_local()) {
1194 (Some(last_hir_id), Some(exp_hir_id)) => (last_hir_id, exp_hir_id),
1195 (_, _) => return None,
1196 };
1197
1198 let last_hir_id = self.tcx.hir().local_def_id_to_hir_id(last_local_id);
1199 let exp_hir_id = self.tcx.hir().local_def_id_to_hir_id(exp_local_id);
1200
1201 match (
1202 &self.tcx.hir().expect_item(last_hir_id).kind,
1203 &self.tcx.hir().expect_item(exp_hir_id).kind,
1204 ) {
1205 (
1206 hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
1207 hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
1208 ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| {
1209 match (left, right) {
1210 (
1211 hir::GenericBound::Trait(tl, ml),
1212 hir::GenericBound::Trait(tr, mr),
1213 ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
1214 && ml == mr =>
1215 {
1216 true
1217 }
1218 (
1219 hir::GenericBound::LangItemTrait(langl, _, _, argsl),
1220 hir::GenericBound::LangItemTrait(langr, _, _, argsr),
1221 ) if langl == langr => {
1222 // FIXME: consider the bounds!
1223 debug!("{:?} {:?}", argsl, argsr);
1224 true
1225 }
1226 _ => false,
1227 }
1228 }) =>
1229 {
1230 StatementAsExpression::NeedsBoxing
1231 }
1232 _ => StatementAsExpression::CorrectType,
1233 }
1234 }
1235 _ => StatementAsExpression::CorrectType,
1236 };
1237 if (matches!(last_expr_ty.kind(), ty::Error(_))
1238 || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err())
1239 && matches!(needs_box, StatementAsExpression::CorrectType)
1240 {
1241 return None;
1242 }
1243 let original_span = original_sp(last_stmt.span, blk.span);
1244 Some((original_span.with_lo(original_span.hi() - BytePos(1)), needs_box))
1245 }
1246
1247 // Instantiates the given path, which must refer to an item with the given
1248 // number of type parameters and type.
1249 pub fn instantiate_value_path(
1250 &self,
1251 segments: &[hir::PathSegment<'_>],
1252 self_ty: Option<Ty<'tcx>>,
1253 res: Res,
1254 span: Span,
1255 hir_id: hir::HirId,
1256 ) -> (Ty<'tcx>, Res) {
1257 debug!(
1258 "instantiate_value_path(segments={:?}, self_ty={:?}, res={:?}, hir_id={})",
1259 segments, self_ty, res, hir_id,
1260 );
1261
1262 let tcx = self.tcx;
1263
1264 let path_segs = match res {
1265 Res::Local(_) | Res::SelfCtor(_) => vec![],
1266 Res::Def(kind, def_id) => <dyn AstConv<'_>>::def_ids_for_value_path_segments(
1267 self, segments, self_ty, kind, def_id,
1268 ),
1269 _ => bug!("instantiate_value_path on {:?}", res),
1270 };
1271
1272 let mut user_self_ty = None;
1273 let mut is_alias_variant_ctor = false;
1274 match res {
1275 Res::Def(DefKind::Ctor(CtorOf::Variant, _), _) => {
1276 if let Some(self_ty) = self_ty {
1277 let adt_def = self_ty.ty_adt_def().unwrap();
1278 user_self_ty = Some(UserSelfTy { impl_def_id: adt_def.did, self_ty });
1279 is_alias_variant_ctor = true;
1280 }
1281 }
1282 Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
1283 let container = tcx.associated_item(def_id).container;
1284 debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container);
1285 match container {
1286 ty::TraitContainer(trait_did) => {
1287 callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did)
1288 }
1289 ty::ImplContainer(impl_def_id) => {
1290 if segments.len() == 1 {
1291 // `<T>::assoc` will end up here, and so
1292 // can `T::assoc`. It this came from an
1293 // inherent impl, we need to record the
1294 // `T` for posterity (see `UserSelfTy` for
1295 // details).
1296 let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
1297 user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
1298 }
1299 }
1300 }
1301 }
1302 _ => {}
1303 }
1304
1305 // Now that we have categorized what space the parameters for each
1306 // segment belong to, let's sort out the parameters that the user
1307 // provided (if any) into their appropriate spaces. We'll also report
1308 // errors if type parameters are provided in an inappropriate place.
1309
1310 let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect();
1311 let generics_has_err = <dyn AstConv<'_>>::prohibit_generics(
1312 self,
1313 segments.iter().enumerate().filter_map(|(index, seg)| {
1314 if !generic_segs.contains(&index) || is_alias_variant_ctor {
1315 Some(seg)
1316 } else {
1317 None
1318 }
1319 }),
1320 );
1321
1322 if let Res::Local(hid) = res {
1323 let ty = self.local_ty(span, hid).decl_ty;
1324 let ty = self.normalize_associated_types_in(span, ty);
1325 self.write_ty(hir_id, ty);
1326 return (ty, res);
1327 }
1328
1329 if generics_has_err {
1330 // Don't try to infer type parameters when prohibited generic arguments were given.
1331 user_self_ty = None;
1332 }
1333
1334 // Now we have to compare the types that the user *actually*
1335 // provided against the types that were *expected*. If the user
1336 // did not provide any types, then we want to substitute inference
1337 // variables. If the user provided some types, we may still need
1338 // to add defaults. If the user provided *too many* types, that's
1339 // a problem.
1340
1341 let mut infer_args_for_err = FxHashSet::default();
1342
1343 let mut explicit_late_bound = ExplicitLateBound::No;
1344 for &PathSeg(def_id, index) in &path_segs {
1345 let seg = &segments[index];
1346 let generics = tcx.generics_of(def_id);
1347
1348 // Argument-position `impl Trait` is treated as a normal generic
1349 // parameter internally, but we don't allow users to specify the
1350 // parameter's value explicitly, so we have to do some error-
1351 // checking here.
1352 let arg_count = <dyn AstConv<'_>>::check_generic_arg_count_for_call(
1353 tcx,
1354 span,
1355 def_id,
1356 &generics,
1357 seg,
1358 IsMethodCall::No,
1359 );
1360
1361 if let ExplicitLateBound::Yes = arg_count.explicit_late_bound {
1362 explicit_late_bound = ExplicitLateBound::Yes;
1363 }
1364
1365 if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct {
1366 infer_args_for_err.insert(index);
1367 self.set_tainted_by_errors(); // See issue #53251.
1368 }
1369 }
1370
1371 let has_self = path_segs
1372 .last()
1373 .map(|PathSeg(def_id, _)| tcx.generics_of(*def_id).has_self)
1374 .unwrap_or(false);
1375
1376 let (res, self_ctor_substs) = if let Res::SelfCtor(impl_def_id) = res {
1377 let ty = self.normalize_ty(span, tcx.at(span).type_of(impl_def_id));
1378 match *ty.kind() {
1379 ty::Adt(adt_def, substs) if adt_def.has_ctor() => {
1380 let variant = adt_def.non_enum_variant();
1381 let ctor_def_id = variant.ctor_def_id.unwrap();
1382 (
1383 Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id),
1384 Some(substs),
1385 )
1386 }
1387 _ => {
1388 let mut err = tcx.sess.struct_span_err(
1389 span,
1390 "the `Self` constructor can only be used with tuple or unit structs",
1391 );
1392 if let Some(adt_def) = ty.ty_adt_def() {
1393 match adt_def.adt_kind() {
1394 AdtKind::Enum => {
1395 err.help("did you mean to use one of the enum's variants?");
1396 }
1397 AdtKind::Struct | AdtKind::Union => {
1398 err.span_suggestion(
1399 span,
1400 "use curly brackets",
1401 String::from("Self { /* fields */ }"),
1402 Applicability::HasPlaceholders,
1403 );
1404 }
1405 }
1406 }
1407 err.emit();
1408
1409 return (tcx.ty_error(), res);
1410 }
1411 }
1412 } else {
1413 (res, None)
1414 };
1415 let def_id = res.def_id();
1416
1417 // The things we are substituting into the type should not contain
1418 // escaping late-bound regions, and nor should the base type scheme.
1419 let ty = tcx.type_of(def_id);
1420
1421 let arg_count = GenericArgCountResult {
1422 explicit_late_bound,
1423 correct: if infer_args_for_err.is_empty() {
1424 Ok(())
1425 } else {
1426 Err(GenericArgCountMismatch::default())
1427 },
1428 };
1429
1430 struct CreateCtorSubstsContext<'a, 'tcx> {
1431 fcx: &'a FnCtxt<'a, 'tcx>,
1432 span: Span,
1433 path_segs: &'a [PathSeg],
1434 infer_args_for_err: &'a FxHashSet<usize>,
1435 segments: &'a [hir::PathSegment<'a>],
1436 }
1437 impl<'tcx, 'a> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for CreateCtorSubstsContext<'a, 'tcx> {
1438 fn args_for_def_id(
1439 &mut self,
1440 def_id: DefId,
1441 ) -> (Option<&'a hir::GenericArgs<'a>>, bool) {
1442 if let Some(&PathSeg(_, index)) =
1443 self.path_segs.iter().find(|&PathSeg(did, _)| *did == def_id)
1444 {
1445 // If we've encountered an `impl Trait`-related error, we're just
1446 // going to infer the arguments for better error messages.
1447 if !self.infer_args_for_err.contains(&index) {
1448 // Check whether the user has provided generic arguments.
1449 if let Some(ref data) = self.segments[index].args {
1450 return (Some(data), self.segments[index].infer_args);
1451 }
1452 }
1453 return (None, self.segments[index].infer_args);
1454 }
1455
1456 (None, true)
1457 }
1458
1459 fn provided_kind(
1460 &mut self,
1461 param: &ty::GenericParamDef,
1462 arg: &GenericArg<'_>,
1463 ) -> subst::GenericArg<'tcx> {
1464 match (&param.kind, arg) {
1465 (GenericParamDefKind::Lifetime, GenericArg::Lifetime(lt)) => {
1466 <dyn AstConv<'_>>::ast_region_to_region(self.fcx, lt, Some(param)).into()
1467 }
1468 (GenericParamDefKind::Type { .. }, GenericArg::Type(ty)) => {
1469 self.fcx.to_ty(ty).into()
1470 }
1471 (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
1472 self.fcx.const_arg_to_const(&ct.value, param.def_id).into()
1473 }
1474 _ => unreachable!(),
1475 }
1476 }
1477
1478 fn inferred_kind(
1479 &mut self,
1480 substs: Option<&[subst::GenericArg<'tcx>]>,
1481 param: &ty::GenericParamDef,
1482 infer_args: bool,
1483 ) -> subst::GenericArg<'tcx> {
1484 let tcx = self.fcx.tcx();
1485 match param.kind {
1486 GenericParamDefKind::Lifetime => {
1487 self.fcx.re_infer(Some(param), self.span).unwrap().into()
1488 }
1489 GenericParamDefKind::Type { has_default, .. } => {
1490 if !infer_args && has_default {
1491 // If we have a default, then we it doesn't matter that we're not
1492 // inferring the type arguments: we provide the default where any
1493 // is missing.
1494 let default = tcx.type_of(param.def_id);
1495 self.fcx
1496 .normalize_ty(
1497 self.span,
1498 default.subst_spanned(tcx, substs.unwrap(), Some(self.span)),
1499 )
1500 .into()
1501 } else {
1502 // If no type arguments were provided, we have to infer them.
1503 // This case also occurs as a result of some malformed input, e.g.
1504 // a lifetime argument being given instead of a type parameter.
1505 // Using inference instead of `Error` gives better error messages.
1506 self.fcx.var_for_def(self.span, param)
1507 }
1508 }
1509 GenericParamDefKind::Const { has_default, .. } => {
1510 if !infer_args && has_default {
1511 tcx.const_param_default(param.def_id)
1512 .subst_spanned(tcx, substs.unwrap(), Some(self.span))
1513 .into()
1514 } else {
1515 self.fcx.var_for_def(self.span, param)
1516 }
1517 }
1518 }
1519 }
1520 }
1521
1522 let substs = self_ctor_substs.unwrap_or_else(|| {
1523 <dyn AstConv<'_>>::create_substs_for_generic_args(
1524 tcx,
1525 def_id,
1526 &[][..],
1527 has_self,
1528 self_ty,
1529 &arg_count,
1530 &mut CreateCtorSubstsContext {
1531 fcx: self,
1532 span,
1533 path_segs: &path_segs,
1534 infer_args_for_err: &infer_args_for_err,
1535 segments,
1536 },
1537 )
1538 });
1539 assert!(!substs.has_escaping_bound_vars());
1540 assert!(!ty.has_escaping_bound_vars());
1541
1542 // First, store the "user substs" for later.
1543 self.write_user_type_annotation_from_substs(hir_id, def_id, substs, user_self_ty);
1544
1545 self.add_required_obligations(span, def_id, &substs);
1546
1547 // Substitute the values for the type parameters into the type of
1548 // the referenced item.
1549 let ty_substituted = self.instantiate_type_scheme(span, &substs, ty);
1550
1551 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
1552 // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
1553 // is inherent, there is no `Self` parameter; instead, the impl needs
1554 // type parameters, which we can infer by unifying the provided `Self`
1555 // with the substituted impl type.
1556 // This also occurs for an enum variant on a type alias.
1557 let ty = tcx.type_of(impl_def_id);
1558
1559 let impl_ty = self.instantiate_type_scheme(span, &substs, ty);
1560 match self.at(&self.misc(span), self.param_env).eq(impl_ty, self_ty) {
1561 Ok(ok) => self.register_infer_ok_obligations(ok),
1562 Err(_) => {
1563 self.tcx.sess.delay_span_bug(
1564 span,
1565 &format!(
1566 "instantiate_value_path: (UFCS) {:?} was a subtype of {:?} but now is not?",
1567 self_ty,
1568 impl_ty,
1569 ),
1570 );
1571 }
1572 }
1573 }
1574
1575 debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
1576 self.write_substs(hir_id, substs);
1577
1578 (ty_substituted, res)
1579 }
1580
1581 /// Add all the obligations that are required, substituting and normalized appropriately.
1582 #[tracing::instrument(level = "debug", skip(self, span, def_id, substs))]
1583 fn add_required_obligations(&self, span: Span, def_id: DefId, substs: &SubstsRef<'tcx>) {
1584 let (bounds, spans) = self.instantiate_bounds(span, def_id, &substs);
1585
1586 for (i, mut obligation) in traits::predicates_for_generics(
1587 traits::ObligationCause::new(span, self.body_id, traits::ItemObligation(def_id)),
1588 self.param_env,
1589 bounds,
1590 )
1591 .enumerate()
1592 {
1593 // This makes the error point at the bound, but we want to point at the argument
1594 if let Some(span) = spans.get(i) {
1595 obligation.cause.make_mut().code = traits::BindingObligation(def_id, *span);
1596 }
1597 self.register_predicate(obligation);
1598 }
1599 }
1600
1601 /// Resolves `typ` by a single level if `typ` is a type variable.
1602 /// If no resolution is possible, then an error is reported.
1603 /// Numeric inference variables may be left unresolved.
1604 pub fn structurally_resolved_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
1605 let ty = self.resolve_vars_with_obligations(ty);
1606 if !ty.is_ty_var() {
1607 ty
1608 } else {
1609 if !self.is_tainted_by_errors() {
1610 self.emit_inference_failure_err((**self).body_id, sp, ty.into(), vec![], E0282)
1611 .note("type must be known at this point")
1612 .emit();
1613 }
1614 let err = self.tcx.ty_error();
1615 self.demand_suptype(sp, err, ty);
1616 err
1617 }
1618 }
1619
1620 pub(in super::super) fn with_breakable_ctxt<F: FnOnce() -> R, R>(
1621 &self,
1622 id: hir::HirId,
1623 ctxt: BreakableCtxt<'tcx>,
1624 f: F,
1625 ) -> (BreakableCtxt<'tcx>, R) {
1626 let index;
1627 {
1628 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
1629 index = enclosing_breakables.stack.len();
1630 enclosing_breakables.by_id.insert(id, index);
1631 enclosing_breakables.stack.push(ctxt);
1632 }
1633 let result = f();
1634 let ctxt = {
1635 let mut enclosing_breakables = self.enclosing_breakables.borrow_mut();
1636 debug_assert!(enclosing_breakables.stack.len() == index + 1);
1637 enclosing_breakables.by_id.remove(&id).expect("missing breakable context");
1638 enclosing_breakables.stack.pop().expect("missing breakable context")
1639 };
1640 (ctxt, result)
1641 }
1642
1643 /// Instantiate a QueryResponse in a probe context, without a
1644 /// good ObligationCause.
1645 pub(in super::super) fn probe_instantiate_query_response(
1646 &self,
1647 span: Span,
1648 original_values: &OriginalQueryValues<'tcx>,
1649 query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
1650 ) -> InferResult<'tcx, Ty<'tcx>> {
1651 self.instantiate_query_response_and_region_obligations(
1652 &traits::ObligationCause::misc(span, self.body_id),
1653 self.param_env,
1654 original_values,
1655 query_result,
1656 )
1657 }
1658
1659 /// Returns `true` if an expression is contained inside the LHS of an assignment expression.
1660 pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
1661 let mut contained_in_place = false;
1662
1663 while let hir::Node::Expr(parent_expr) =
1664 self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
1665 {
1666 match &parent_expr.kind {
1667 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
1668 if lhs.hir_id == expr_id {
1669 contained_in_place = true;
1670 break;
1671 }
1672 }
1673 _ => (),
1674 }
1675 expr_id = parent_expr.hir_id;
1676 }
1677
1678 contained_in_place
1679 }
1680 }