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