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