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