use rustc_middle::ty::subst::{
self, GenericArgKind, InternalSubsts, Subst, SubstsRef, UserSelfTy, UserSubsts,
};
+use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{
self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPolyTraitRef,
ToPredicate, Ty, UserType,
};
use rustc_session::lint;
+use rustc_span::def_id::LocalDefId;
use rustc_span::hygiene::DesugaringKind;
-use rustc_span::source_map::{original_sp, DUMMY_SP};
use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::{self, BytePos, Span};
+use rustc_span::{Span, DUMMY_SP};
use rustc_trait_selection::infer::InferCtxtExt as _;
use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
use rustc_trait_selection::traits::{
- self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt,
- WellFormedLoc,
+ self, ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt,
};
use std::collections::hash_map::Entry;
-use std::iter;
use std::slice;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn record_deferred_call_resolution(
&self,
- closure_def_id: DefId,
+ closure_def_id: LocalDefId,
r: DeferredCallResolution<'tcx>,
) {
let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
pub(in super::super) fn remove_deferred_call_resolutions(
&self,
- closure_def_id: DefId,
+ closure_def_id: LocalDefId,
) -> Vec<DeferredCallResolution<'tcx>> {
let mut deferred_call_resolutions = self.deferred_call_resolutions.borrow_mut();
deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index);
}
+ #[instrument(level = "debug", skip(self))]
pub(in super::super) fn write_resolution(
&self,
hir_id: hir::HirId,
self.typeck_results.borrow_mut().type_dependent_defs_mut().insert(hir_id, r);
}
+ #[instrument(level = "debug", skip(self))]
pub fn write_method_call(&self, hir_id: hir::HirId, method: MethodCallee<'tcx>) {
- debug!("write_method_call(hir_id={:?}, method={:?})", hir_id, method);
self.write_resolution(hir_id, Ok((DefKind::AssocFn, method.def_id)));
self.write_substs(hir_id, method.substs);
if !method.substs.is_empty() {
let method_generics = self.tcx.generics_of(method.def_id);
if !method_generics.params.is_empty() {
- let user_type_annotation = self.infcx.probe(|_| {
+ let user_type_annotation = self.probe(|_| {
let user_substs = UserSubsts {
substs: InternalSubsts::for_item(self.tcx, method.def_id, |param, _| {
let i = param.index as usize;
if i < method_generics.parent_count {
- self.infcx.var_for_def(DUMMY_SP, param)
+ self.var_for_def(DUMMY_SP, param)
} else {
method.substs[i]
}
user_self_ty: None, // not relevant here
};
- self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
+ self.canonicalize_user_type_annotation(UserType::TypeOf(
method.def_id,
user_substs,
))
debug!("fcx {}", self.tag());
if Self::can_contain_user_lifetime_bounds((substs, user_self_ty)) {
- let canonicalized = self.infcx.canonicalize_user_type_annotation(UserType::TypeOf(
+ let canonicalized = self.canonicalize_user_type_annotation(UserType::TypeOf(
def_id,
UserSubsts { substs, user_self_ty },
));
(result, spans)
}
- /// Convenience method which tracks extra diagnostic information for normalization
- /// that occurs as a result of WF checking. The `hir_id` is the `HirId` of the hir item
- /// whose type is being wf-checked - this is used to construct a more precise span if
- /// an error occurs.
- ///
- /// It is never necessary to call this method - calling `normalize_associated_types_in` will
- /// just result in a slightly worse diagnostic span, and will still be sound.
- pub(in super::super) fn normalize_associated_types_in_wf<T>(
- &self,
- span: Span,
- value: T,
- loc: WellFormedLoc,
- ) -> T
- where
- T: TypeFoldable<'tcx>,
- {
- self.inh.normalize_associated_types_in_with_cause(
- ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))),
- self.param_env,
- value,
- )
- }
-
pub(in super::super) fn normalize_associated_types_in<T>(&self, span: Span, value: T) -> T
where
T: TypeFoldable<'tcx>,
rhs_span: opt_input_expr.map(|expr| expr.span),
is_lit: opt_input_expr
.map_or(false, |expr| matches!(expr.kind, ExprKind::Lit(_))),
+ output_pred: None,
},
),
self.param_env,
pub fn to_ty(&self, ast_t: &hir::Ty<'_>) -> Ty<'tcx> {
let t = <dyn AstConv<'_>>::ast_ty_to_ty(self, ast_t);
- self.register_wf_obligation(t.into(), ast_t.span, traits::MiscObligation);
+ self.register_wf_obligation(t.into(), ast_t.span, traits::WellFormed(None));
t
}
debug!("to_ty_saving_user_provided_ty: ty={:?}", ty);
if Self::can_contain_user_lifetime_bounds(ty) {
- let c_ty = self.infcx.canonicalize_response(UserType::Ty(ty));
+ let c_ty = self.canonicalize_response(UserType::Ty(ty));
debug!("to_ty_saving_user_provided_ty: c_ty={:?}", c_ty);
self.typeck_results.borrow_mut().user_provided_types_mut().insert(ast_ty.hir_id, c_ty);
}
self.register_wf_obligation(
c.into(),
self.tcx.hir().span(ast_c.hir_id),
- ObligationCauseCode::MiscObligation,
+ ObligationCauseCode::WellFormed(None),
);
c
}
self.register_wf_obligation(
c.into(),
self.tcx.hir().span(ast_c.hir_id),
- ObligationCauseCode::MiscObligation,
+ ObligationCauseCode::WellFormed(None),
);
c
}
// sufficiently enforced with erased regions. =)
fn can_contain_user_lifetime_bounds<T>(t: T) -> bool
where
- T: TypeFoldable<'tcx>,
+ T: TypeVisitable<'tcx>,
{
t.has_free_regions() || t.has_projections() || t.has_infer_types()
}
for arg in substs.iter().filter(|arg| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
}) {
- self.register_wf_obligation(arg, expr.span, traits::MiscObligation);
+ self.register_wf_obligation(arg, expr.span, traits::WellFormed(None));
}
}
// src/test/ui/impl-trait/hidden-type-is-opaque-2.rs for examples that hit this path.
if formal_ret.has_infer_types() {
for ty in ret_ty.walk() {
- if let ty::subst::GenericArgKind::Type(ty) = ty.unpack() {
- if let ty::Opaque(def_id, _) = *ty.kind() {
- if self.infcx.opaque_type_origin(def_id, DUMMY_SP).is_some() {
- return None;
- }
- }
+ if let ty::subst::GenericArgKind::Type(ty) = ty.unpack()
+ && let ty::Opaque(def_id, _) = *ty.kind()
+ && let Some(def_id) = def_id.as_local()
+ && self.opaque_type_origin(def_id, DUMMY_SP).is_some() {
+ return None;
}
}
}
} else {
self.tcx.bound_type_of(def_id)
};
- let substs = self.infcx.fresh_substs_for_item(span, def_id);
+ let substs = self.fresh_substs_for_item(span, def_id);
let ty = item_ty.subst(self.tcx, substs);
self.write_resolution(hir_id, Ok((def_kind, def_id)));
);
sp.push_span_label(
rcvr.span,
- "you probably want to use this value after calling the method...".to_string(),
+ "you probably want to use this value after calling the method...",
);
err.span_note(
sp,
));
}
- pub(in super::super) fn could_remove_semicolon(
- &self,
- blk: &'tcx hir::Block<'tcx>,
- expected_ty: Ty<'tcx>,
- ) -> Option<(Span, StatementAsExpression)> {
- // Be helpful when the user wrote `{... expr;}` and
- // taking the `;` off is enough to fix the error.
- let last_stmt = blk.stmts.last()?;
- let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else {
- return None;
- };
- let last_expr_ty = self.node_ty(last_expr.hir_id);
- let needs_box = match (last_expr_ty.kind(), expected_ty.kind()) {
- (ty::Opaque(last_def_id, _), ty::Opaque(exp_def_id, _))
- if last_def_id == exp_def_id =>
- {
- StatementAsExpression::CorrectType
- }
- (ty::Opaque(last_def_id, last_bounds), ty::Opaque(exp_def_id, exp_bounds)) => {
- debug!(
- "both opaque, likely future {:?} {:?} {:?} {:?}",
- last_def_id, last_bounds, exp_def_id, exp_bounds
- );
-
- let last_local_id = last_def_id.as_local()?;
- let exp_local_id = exp_def_id.as_local()?;
-
- match (
- &self.tcx.hir().expect_item(last_local_id).kind,
- &self.tcx.hir().expect_item(exp_local_id).kind,
- ) {
- (
- hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
- hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
- ) if iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| {
- match (left, right) {
- (
- hir::GenericBound::Trait(tl, ml),
- hir::GenericBound::Trait(tr, mr),
- ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
- && ml == mr =>
- {
- true
- }
- (
- hir::GenericBound::LangItemTrait(langl, _, _, argsl),
- hir::GenericBound::LangItemTrait(langr, _, _, argsr),
- ) if langl == langr => {
- // FIXME: consider the bounds!
- debug!("{:?} {:?}", argsl, argsr);
- true
- }
- _ => false,
- }
- }) =>
- {
- StatementAsExpression::NeedsBoxing
- }
- _ => StatementAsExpression::CorrectType,
- }
- }
- _ => StatementAsExpression::CorrectType,
- };
- if (matches!(last_expr_ty.kind(), ty::Error(_))
- || self.can_sub(self.param_env, last_expr_ty, expected_ty).is_err())
- && matches!(needs_box, StatementAsExpression::CorrectType)
- {
- return None;
- }
- let span = if last_stmt.span.from_expansion() {
- let mac_call = original_sp(last_stmt.span, blk.span);
- self.tcx.sess.source_map().mac_call_stmt_semi_span(mac_call)?
- } else {
- last_stmt.span.with_lo(last_stmt.span.hi() - BytePos(1))
- };
- Some((span, needs_box))
- }
-
// Instantiates the given path, which must refer to an item with the given
// number of type parameters and type.
#[instrument(skip(self, span), level = "debug")]
is_alias_variant_ctor = true;
}
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
- let container = tcx.associated_item(def_id).container;
- debug!(?def_id, ?container);
+ let assoc_item = tcx.associated_item(def_id);
+ let container = assoc_item.container;
+ let container_id = assoc_item.container_id(tcx);
+ debug!(?def_id, ?container, ?container_id);
match container {
- ty::TraitContainer(trait_did) => {
- callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did)
+ ty::TraitContainer => {
+ callee::check_legal_trait_for_method_call(tcx, span, None, span, container_id)
}
- ty::ImplContainer(impl_def_id) => {
+ ty::ImplContainer => {
if segments.len() == 1 {
// `<T>::assoc` will end up here, and so
// can `T::assoc`. It this came from an
// `T` for posterity (see `UserSelfTy` for
// details).
let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
- user_self_ty = Some(UserSelfTy { impl_def_id, self_ty });
+ user_self_ty = Some(UserSelfTy { impl_def_id: container_id, self_ty });
}
}
}
}
GenericParamDefKind::Const { has_default } => {
if !infer_args && has_default {
- EarlyBinder(tcx.const_param_default(param.def_id))
+ tcx.bound_const_param_default(param.def_id)
.subst(tcx, substs.unwrap())
.into()
} else {
ty
} else {
if !self.is_tainted_by_errors() {
- self.emit_inference_failure_err((**self).body_id, sp, ty.into(), vec![], E0282)
- .note("type must be known at this point")
+ self.emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
.emit();
}
let err = self.tcx.ty_error();