1use rustc_hir::def::DefKind;
2use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
3use rustc_infer::traits::Obligation;
4use rustc_middle::traits::query::NoSolution;
5pub use rustc_middle::traits::query::type_op::AscribeUserType;
6use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
7use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, UserArgs, UserSelfTy, UserTypeKind};
8use rustc_span::{DUMMY_SP, Span};
9use tracing::{debug, instrument};
10
11use crate::infer::canonical::{CanonicalQueryInput, CanonicalQueryResponse};
12use crate::traits::ObligationCtxt;
13
14impl<'tcx> super::QueryTypeOp<'tcx> for AscribeUserType<'tcx> {
15 type QueryResponse = ();
16
17 fn try_fast_path(
18 _tcx: TyCtxt<'tcx>,
19 _key: &ParamEnvAnd<'tcx, Self>,
20 ) -> Option<Self::QueryResponse> {
21 None
22 }
23
24 fn perform_query(
25 tcx: TyCtxt<'tcx>,
26 canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
27 ) -> Result<CanonicalQueryResponse<'tcx, ()>, NoSolution> {
28 tcx.type_op_ascribe_user_type(canonicalized)
29 }
30
31 fn perform_locally_with_next_solver(
32 ocx: &ObligationCtxt<'_, 'tcx>,
33 key: ParamEnvAnd<'tcx, Self>,
34 span: Span,
35 ) -> Result<Self::QueryResponse, NoSolution> {
36 type_op_ascribe_user_type_with_span(ocx, key, span)
37 }
38}
39
40pub fn type_op_ascribe_user_type_with_span<'tcx>(
44 ocx: &ObligationCtxt<'_, 'tcx>,
45 key: ParamEnvAnd<'tcx, AscribeUserType<'tcx>>,
46 span: Span,
47) -> Result<(), NoSolution> {
48 let ty::ParamEnvAnd { param_env, value: AscribeUserType { mir_ty, user_ty } } = key;
49 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:49",
"rustc_trait_selection::traits::query::type_op::ascribe_user_type",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
::tracing_core::__macro_support::Option::Some(49u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("type_op_ascribe_user_type: mir_ty={0:?} user_ty={1:?}",
mir_ty, user_ty) as &dyn Value))])
});
} else { ; }
};debug!("type_op_ascribe_user_type: mir_ty={:?} user_ty={:?}", mir_ty, user_ty);
50 match user_ty.kind {
51 UserTypeKind::Ty(user_ty) => relate_mir_and_user_ty(ocx, param_env, span, mir_ty, user_ty)?,
52 UserTypeKind::TypeOf(def_id, user_args) => {
53 relate_mir_and_user_args(ocx, param_env, span, mir_ty, def_id, user_args)?
54 }
55 };
56
57 ocx.register_obligations(user_ty.bounds.iter().map(|clause| {
59 Obligation::new(ocx.infcx.tcx, ObligationCause::dummy_with_span(span), param_env, clause)
60 }));
61
62 Ok(())
63}
64
65#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("relate_mir_and_user_ty",
"rustc_trait_selection::traits::query::type_op::ascribe_user_type",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
::tracing_core::__macro_support::Option::Some(65u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
::tracing_core::field::FieldSet::new(&["mir_ty", "user_ty"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mir_ty)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_ty)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<(), NoSolution> = loop {};
return __tracing_attr_fake_return;
}
{
let cause = ObligationCause::dummy_with_span(span);
ocx.register_obligation(Obligation::new(ocx.infcx.tcx,
cause.clone(), param_env,
ty::ClauseKind::WellFormed(user_ty.into())));
let user_ty = ocx.normalize(&cause, param_env, user_ty);
ocx.eq(&cause, param_env, mir_ty, user_ty)?;
Ok(())
}
}
}#[instrument(level = "debug", skip(ocx, param_env, span))]
66fn relate_mir_and_user_ty<'tcx>(
67 ocx: &ObligationCtxt<'_, 'tcx>,
68 param_env: ty::ParamEnv<'tcx>,
69 span: Span,
70 mir_ty: Ty<'tcx>,
71 user_ty: Ty<'tcx>,
72) -> Result<(), NoSolution> {
73 let cause = ObligationCause::dummy_with_span(span);
74 ocx.register_obligation(Obligation::new(
75 ocx.infcx.tcx,
76 cause.clone(),
77 param_env,
78 ty::ClauseKind::WellFormed(user_ty.into()),
79 ));
80
81 let user_ty = ocx.normalize(&cause, param_env, user_ty);
82 ocx.eq(&cause, param_env, mir_ty, user_ty)?;
83
84 Ok(())
85}
86
87#[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("relate_mir_and_user_args",
"rustc_trait_selection::traits::query::type_op::ascribe_user_type",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
::tracing_core::__macro_support::Option::Some(87u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
::tracing_core::field::FieldSet::new(&["mir_ty", "def_id",
"user_args"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&mir_ty)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&def_id)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&user_args)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<(), NoSolution> = loop {};
return __tracing_attr_fake_return;
}
{
let UserArgs { user_self_ty, args } = user_args;
let tcx = ocx.infcx.tcx;
let cause = ObligationCause::dummy_with_span(span);
let is_inherent_assoc_const =
#[allow(non_exhaustive_omitted_patterns)] match tcx.def_kind(def_id)
{
DefKind::AssocConst { .. } => true,
_ => false,
} &&
tcx.def_kind(tcx.parent(def_id)) ==
DefKind::Impl { of_trait: false } &&
tcx.is_type_const(def_id);
let args =
if is_inherent_assoc_const {
let impl_def_id = tcx.parent(def_id);
let impl_args =
ocx.infcx.fresh_args_for_item(span, impl_def_id);
let impl_self_ty =
ocx.normalize(&cause, param_env,
tcx.type_of(impl_def_id).instantiate(tcx, impl_args));
let user_self_ty =
ocx.normalize(&cause, param_env, args[0].expect_ty());
ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?;
let gat_args = &args[1..];
tcx.mk_args_from_iter(impl_args.iter().chain(gat_args.iter().copied()))
} else { args };
let ty = tcx.type_of(def_id).instantiate(tcx, args);
let ty = ocx.normalize(&cause, param_env, ty);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:122",
"rustc_trait_selection::traits::query::type_op::ascribe_user_type",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
::tracing_core::__macro_support::Option::Some(122u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("relate_type_and_user_type: ty of def-id is {0:?}",
ty) as &dyn Value))])
});
} else { ; }
};
ocx.eq(&cause, param_env, mir_ty, ty)?;
let instantiated_predicates =
tcx.predicates_of(def_id).instantiate(tcx, args);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs:133",
"rustc_trait_selection::traits::query::type_op::ascribe_user_type",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_trait_selection/src/traits/query/type_op/ascribe_user_type.rs"),
::tracing_core::__macro_support::Option::Some(133u32),
::tracing_core::__macro_support::Option::Some("rustc_trait_selection::traits::query::type_op::ascribe_user_type"),
::tracing_core::field::FieldSet::new(&["instantiated_predicates"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&instantiated_predicates)
as &dyn Value))])
});
} else { ; }
};
for (instantiated_predicate, predicate_span) in
instantiated_predicates {
let span =
if span == DUMMY_SP { predicate_span } else { span };
let cause =
ObligationCause::new(span, CRATE_DEF_ID,
ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span));
let instantiated_predicate =
ocx.normalize(&cause, param_env, instantiated_predicate);
ocx.register_obligation(Obligation::new(tcx, cause, param_env,
instantiated_predicate));
}
for term in args.iter().filter_map(ty::GenericArg::as_term) {
ocx.register_obligation(Obligation::new(tcx, cause.clone(),
param_env, ty::ClauseKind::WellFormed(term)));
}
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
ocx.register_obligation(Obligation::new(tcx, cause.clone(),
param_env, ty::ClauseKind::WellFormed(self_ty.into())));
let self_ty = ocx.normalize(&cause, param_env, self_ty);
let impl_self_ty =
tcx.type_of(impl_def_id).instantiate(tcx, args);
let impl_self_ty =
ocx.normalize(&cause, param_env, impl_self_ty);
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
}
Ok(())
}
}
}#[instrument(level = "debug", skip(ocx, param_env, span))]
88fn relate_mir_and_user_args<'tcx>(
89 ocx: &ObligationCtxt<'_, 'tcx>,
90 param_env: ty::ParamEnv<'tcx>,
91 span: Span,
92 mir_ty: Ty<'tcx>,
93 def_id: DefId,
94 user_args: UserArgs<'tcx>,
95) -> Result<(), NoSolution> {
96 let UserArgs { user_self_ty, args } = user_args;
97 let tcx = ocx.infcx.tcx;
98 let cause = ObligationCause::dummy_with_span(span);
99
100 let is_inherent_assoc_const = matches!(tcx.def_kind(def_id), DefKind::AssocConst { .. })
103 && tcx.def_kind(tcx.parent(def_id)) == DefKind::Impl { of_trait: false }
104 && tcx.is_type_const(def_id);
105
106 let args = if is_inherent_assoc_const {
107 let impl_def_id = tcx.parent(def_id);
108 let impl_args = ocx.infcx.fresh_args_for_item(span, impl_def_id);
109 let impl_self_ty =
110 ocx.normalize(&cause, param_env, tcx.type_of(impl_def_id).instantiate(tcx, impl_args));
111 let user_self_ty = ocx.normalize(&cause, param_env, args[0].expect_ty());
112 ocx.eq(&cause, param_env, impl_self_ty, user_self_ty)?;
113
114 let gat_args = &args[1..];
115 tcx.mk_args_from_iter(impl_args.iter().chain(gat_args.iter().copied()))
116 } else {
117 args
118 };
119
120 let ty = tcx.type_of(def_id).instantiate(tcx, args);
121 let ty = ocx.normalize(&cause, param_env, ty);
122 debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
123
124 ocx.eq(&cause, param_env, mir_ty, ty)?;
125
126 let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
132
133 debug!(?instantiated_predicates);
134 for (instantiated_predicate, predicate_span) in instantiated_predicates {
135 let span = if span == DUMMY_SP { predicate_span } else { span };
136 let cause = ObligationCause::new(
137 span,
138 CRATE_DEF_ID,
139 ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
140 );
141 let instantiated_predicate = ocx.normalize(&cause, param_env, instantiated_predicate);
142
143 ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate));
144 }
145
146 for term in args.iter().filter_map(ty::GenericArg::as_term) {
156 ocx.register_obligation(Obligation::new(
157 tcx,
158 cause.clone(),
159 param_env,
160 ty::ClauseKind::WellFormed(term),
161 ));
162 }
163
164 if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
165 ocx.register_obligation(Obligation::new(
166 tcx,
167 cause.clone(),
168 param_env,
169 ty::ClauseKind::WellFormed(self_ty.into()),
170 ));
171
172 let self_ty = ocx.normalize(&cause, param_env, self_ty);
173 let impl_self_ty = tcx.type_of(impl_def_id).instantiate(tcx, args);
174 let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
175
176 ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
177 }
178
179 Ok(())
180}