Rollup merge of #112667 - compiler-errors:wf-goal-is-clause, r=lcnr
Move WF/ConstEvaluatable goal to clause It can show up in a param-env, so I think it needs to be a clause kind. r? ```@lcnr``` or ```@oli-obk```
This commit is contained in:
commit
8d3d3cc0ba
40 changed files with 719 additions and 685 deletions
|
@ -330,7 +330,8 @@ fn check_opaque_type_well_formed<'tcx>(
|
||||||
// Require the hidden type to be well-formed with only the generics of the opaque type.
|
// Require the hidden type to be well-formed with only the generics of the opaque type.
|
||||||
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
||||||
// hidden type is well formed even without those bounds.
|
// hidden type is well formed even without those bounds.
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()));
|
let predicate =
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(definition_ty.into())));
|
||||||
ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate));
|
ocx.register_obligation(Obligation::misc(tcx, definition_span, def_id, param_env, predicate));
|
||||||
|
|
||||||
// Check that all obligations are satisfied by the implementation's
|
// Check that all obligations are satisfied by the implementation's
|
||||||
|
|
|
@ -1419,9 +1419,11 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
//
|
//
|
||||||
// See #91068 for an example.
|
// See #91068 for an example.
|
||||||
self.prove_predicates(
|
self.prove_predicates(
|
||||||
sig.inputs_and_output
|
sig.inputs_and_output.iter().map(|ty| {
|
||||||
.iter()
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
|
||||||
.map(|ty| ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))),
|
ty.into(),
|
||||||
|
)))
|
||||||
|
}),
|
||||||
term_location.to_locations(),
|
term_location.to_locations(),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
);
|
);
|
||||||
|
@ -1850,7 +1852,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
|
|
||||||
let array_ty = rvalue.ty(body.local_decls(), tcx);
|
let array_ty = rvalue.ty(body.local_decls(), tcx);
|
||||||
self.prove_predicate(
|
self.prove_predicate(
|
||||||
ty::PredicateKind::WellFormed(array_ty.into()),
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(array_ty.into())),
|
||||||
Locations::Single(location),
|
Locations::Single(location),
|
||||||
ConstraintCategory::Boring,
|
ConstraintCategory::Boring,
|
||||||
);
|
);
|
||||||
|
|
583
compiler/rustc_hir_analysis/src/astconv/bounds.rs
Normal file
583
compiler/rustc_hir_analysis/src/astconv/bounds.rs
Normal file
|
@ -0,0 +1,583 @@
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_errors::struct_span_err;
|
||||||
|
use rustc_hir as hir;
|
||||||
|
use rustc_hir::def::{DefKind, Res};
|
||||||
|
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||||
|
use rustc_lint_defs::Applicability;
|
||||||
|
use rustc_middle::ty::{self as ty, Ty, TypeVisitableExt};
|
||||||
|
use rustc_span::symbol::Ident;
|
||||||
|
use rustc_span::{ErrorGuaranteed, Span};
|
||||||
|
use rustc_trait_selection::traits;
|
||||||
|
|
||||||
|
use crate::astconv::{AstConv, ConvertedBinding, ConvertedBindingKind};
|
||||||
|
use crate::bounds::Bounds;
|
||||||
|
use crate::errors::{MultipleRelaxedDefaultBounds, ValueOfAssociatedStructAlreadySpecified};
|
||||||
|
|
||||||
|
use super::OnlySelfBounds;
|
||||||
|
|
||||||
|
impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
|
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
||||||
|
pub(crate) fn add_implicitly_sized(
|
||||||
|
&self,
|
||||||
|
bounds: &mut Bounds<'tcx>,
|
||||||
|
self_ty: Ty<'tcx>,
|
||||||
|
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||||
|
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
// Try to find an unbound in bounds.
|
||||||
|
let mut unbound = None;
|
||||||
|
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
||||||
|
for ab in ast_bounds {
|
||||||
|
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
||||||
|
if unbound.is_none() {
|
||||||
|
unbound = Some(&ptr.trait_ref);
|
||||||
|
} else {
|
||||||
|
tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
search_bounds(ast_bounds);
|
||||||
|
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
||||||
|
for clause in where_clause {
|
||||||
|
if let hir::WherePredicate::BoundPredicate(pred) = clause {
|
||||||
|
if pred.is_param_bound(self_ty.to_def_id()) {
|
||||||
|
search_bounds(pred.bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sized_def_id = tcx.lang_items().sized_trait();
|
||||||
|
match (&sized_def_id, unbound) {
|
||||||
|
(Some(sized_def_id), Some(tpb))
|
||||||
|
if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
|
||||||
|
{
|
||||||
|
// There was in fact a `?Sized` bound, return without doing anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(_, Some(_)) => {
|
||||||
|
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
||||||
|
tcx.sess.span_warn(
|
||||||
|
span,
|
||||||
|
"default bound relaxed for a type parameter, but \
|
||||||
|
this does nothing because the given bound is not \
|
||||||
|
a default; only `?Sized` is supported",
|
||||||
|
);
|
||||||
|
// Otherwise, add implicitly sized if `Sized` is available.
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if sized_def_id.is_none() {
|
||||||
|
// No lang item for `Sized`, so we can't add it as a bound.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bounds.push_sized(tcx, self_ty, span);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This helper takes a *converted* parameter type (`param_ty`)
|
||||||
|
/// and an *unconverted* list of bounds:
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// fn foo<T: Debug>
|
||||||
|
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
|
||||||
|
/// |
|
||||||
|
/// `param_ty`, in ty form
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// It adds these `ast_bounds` into the `bounds` structure.
|
||||||
|
///
|
||||||
|
/// **A note on binders:** there is an implied binder around
|
||||||
|
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
||||||
|
/// for more details.
|
||||||
|
#[instrument(level = "debug", skip(self, ast_bounds, bounds))]
|
||||||
|
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'hir>>>(
|
||||||
|
&self,
|
||||||
|
param_ty: Ty<'tcx>,
|
||||||
|
ast_bounds: I,
|
||||||
|
bounds: &mut Bounds<'tcx>,
|
||||||
|
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
|
) {
|
||||||
|
for ast_bound in ast_bounds {
|
||||||
|
match ast_bound {
|
||||||
|
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
||||||
|
let (constness, polarity) = match modifier {
|
||||||
|
hir::TraitBoundModifier::MaybeConst => {
|
||||||
|
(ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive)
|
||||||
|
}
|
||||||
|
hir::TraitBoundModifier::None => {
|
||||||
|
(ty::BoundConstness::NotConst, ty::ImplPolarity::Positive)
|
||||||
|
}
|
||||||
|
hir::TraitBoundModifier::Negative => {
|
||||||
|
(ty::BoundConstness::NotConst, ty::ImplPolarity::Negative)
|
||||||
|
}
|
||||||
|
hir::TraitBoundModifier::Maybe => continue,
|
||||||
|
};
|
||||||
|
let _ = self.instantiate_poly_trait_ref(
|
||||||
|
&poly_trait_ref.trait_ref,
|
||||||
|
poly_trait_ref.span,
|
||||||
|
constness,
|
||||||
|
polarity,
|
||||||
|
param_ty,
|
||||||
|
bounds,
|
||||||
|
false,
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||||
|
self.instantiate_lang_item_trait_ref(
|
||||||
|
lang_item,
|
||||||
|
span,
|
||||||
|
hir_id,
|
||||||
|
args,
|
||||||
|
param_ty,
|
||||||
|
bounds,
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
|
let region = self.ast_region_to_region(lifetime, None);
|
||||||
|
bounds.push_region_bound(
|
||||||
|
self.tcx(),
|
||||||
|
ty::Binder::bind_with_vars(
|
||||||
|
ty::OutlivesPredicate(param_ty, region),
|
||||||
|
bound_vars,
|
||||||
|
),
|
||||||
|
lifetime.ident.span,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Translates a list of bounds from the HIR into the `Bounds` data structure.
|
||||||
|
/// The self-type for the bounds is given by `param_ty`.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
///
|
||||||
|
/// ```ignore (illustrative)
|
||||||
|
/// fn foo<T: Bar + Baz>() { }
|
||||||
|
/// // ^ ^^^^^^^^^ ast_bounds
|
||||||
|
/// // param_ty
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
||||||
|
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
||||||
|
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
||||||
|
///
|
||||||
|
/// `span` should be the declaration size of the parameter.
|
||||||
|
pub(crate) fn compute_bounds(
|
||||||
|
&self,
|
||||||
|
param_ty: Ty<'tcx>,
|
||||||
|
ast_bounds: &[hir::GenericBound<'_>],
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
|
) -> Bounds<'tcx> {
|
||||||
|
let mut bounds = Bounds::default();
|
||||||
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
ast_bounds.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
|
debug!(?bounds);
|
||||||
|
|
||||||
|
bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
|
||||||
|
/// named `assoc_name` into ty::Bounds. Ignore the rest.
|
||||||
|
pub(crate) fn compute_bounds_that_match_assoc_item(
|
||||||
|
&self,
|
||||||
|
param_ty: Ty<'tcx>,
|
||||||
|
ast_bounds: &[hir::GenericBound<'_>],
|
||||||
|
assoc_name: Ident,
|
||||||
|
) -> Bounds<'tcx> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
|
||||||
|
for ast_bound in ast_bounds {
|
||||||
|
if let Some(trait_ref) = ast_bound.trait_ref()
|
||||||
|
&& let Some(trait_did) = trait_ref.trait_def_id()
|
||||||
|
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
|
||||||
|
{
|
||||||
|
result.push(ast_bound.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bounds = Bounds::default();
|
||||||
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
result.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
OnlySelfBounds(true),
|
||||||
|
);
|
||||||
|
debug!(?bounds);
|
||||||
|
|
||||||
|
bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
||||||
|
/// onto `bounds`.
|
||||||
|
///
|
||||||
|
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
|
||||||
|
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
|
||||||
|
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
|
||||||
|
#[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))]
|
||||||
|
pub(super) fn add_predicates_for_ast_type_binding(
|
||||||
|
&self,
|
||||||
|
hir_ref_id: hir::HirId,
|
||||||
|
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
binding: &ConvertedBinding<'_, 'tcx>,
|
||||||
|
bounds: &mut Bounds<'tcx>,
|
||||||
|
speculative: bool,
|
||||||
|
dup_bindings: &mut FxHashMap<DefId, Span>,
|
||||||
|
path_span: Span,
|
||||||
|
constness: ty::BoundConstness,
|
||||||
|
only_self_bounds: OnlySelfBounds,
|
||||||
|
polarity: ty::ImplPolarity,
|
||||||
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
|
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
||||||
|
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
||||||
|
// subtle in the event that `T` is defined in a supertrait of
|
||||||
|
// `SomeTrait`, because in that case we need to upcast.
|
||||||
|
//
|
||||||
|
// That is, consider this case:
|
||||||
|
//
|
||||||
|
// ```
|
||||||
|
// trait SubTrait: SuperTrait<i32> { }
|
||||||
|
// trait SuperTrait<A> { type T; }
|
||||||
|
//
|
||||||
|
// ... B: SubTrait<T = foo> ...
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
||||||
|
|
||||||
|
let tcx = self.tcx();
|
||||||
|
|
||||||
|
let return_type_notation =
|
||||||
|
binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation;
|
||||||
|
|
||||||
|
let candidate = if return_type_notation {
|
||||||
|
if self.trait_defines_associated_item_named(
|
||||||
|
trait_ref.def_id(),
|
||||||
|
ty::AssocKind::Fn,
|
||||||
|
binding.item_name,
|
||||||
|
) {
|
||||||
|
trait_ref
|
||||||
|
} else {
|
||||||
|
self.one_bound_for_assoc_method(
|
||||||
|
traits::supertraits(tcx, trait_ref),
|
||||||
|
trait_ref.print_only_trait_path(),
|
||||||
|
binding.item_name,
|
||||||
|
path_span,
|
||||||
|
)?
|
||||||
|
}
|
||||||
|
} else if self.trait_defines_associated_item_named(
|
||||||
|
trait_ref.def_id(),
|
||||||
|
ty::AssocKind::Type,
|
||||||
|
binding.item_name,
|
||||||
|
) {
|
||||||
|
// Simple case: X is defined in the current trait.
|
||||||
|
trait_ref
|
||||||
|
} else {
|
||||||
|
// Otherwise, we have to walk through the supertraits to find
|
||||||
|
// those that do.
|
||||||
|
self.one_bound_for_assoc_type(
|
||||||
|
|| traits::supertraits(tcx, trait_ref),
|
||||||
|
trait_ref.skip_binder().print_only_trait_name(),
|
||||||
|
binding.item_name,
|
||||||
|
path_span,
|
||||||
|
match binding.kind {
|
||||||
|
ConvertedBindingKind::Equality(term) => Some(term),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
|
let (assoc_ident, def_scope) =
|
||||||
|
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
||||||
|
|
||||||
|
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
|
||||||
|
// of calling `filter_by_name_and_kind`.
|
||||||
|
let find_item_of_kind = |kind| {
|
||||||
|
tcx.associated_items(candidate.def_id())
|
||||||
|
.filter_by_name_unhygienic(assoc_ident.name)
|
||||||
|
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
|
||||||
|
};
|
||||||
|
let assoc_item = if return_type_notation {
|
||||||
|
find_item_of_kind(ty::AssocKind::Fn)
|
||||||
|
} else {
|
||||||
|
find_item_of_kind(ty::AssocKind::Type)
|
||||||
|
.or_else(|| find_item_of_kind(ty::AssocKind::Const))
|
||||||
|
}
|
||||||
|
.expect("missing associated type");
|
||||||
|
|
||||||
|
if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
|
||||||
|
tcx.sess
|
||||||
|
.struct_span_err(
|
||||||
|
binding.span,
|
||||||
|
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
||||||
|
)
|
||||||
|
.span_label(binding.span, format!("private {}", assoc_item.kind))
|
||||||
|
.emit();
|
||||||
|
}
|
||||||
|
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
||||||
|
|
||||||
|
if !speculative {
|
||||||
|
dup_bindings
|
||||||
|
.entry(assoc_item.def_id)
|
||||||
|
.and_modify(|prev_span| {
|
||||||
|
tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified {
|
||||||
|
span: binding.span,
|
||||||
|
prev_span: *prev_span,
|
||||||
|
item_name: binding.item_name,
|
||||||
|
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.or_insert(binding.span);
|
||||||
|
}
|
||||||
|
|
||||||
|
let projection_ty = if return_type_notation {
|
||||||
|
let mut emitted_bad_param_err = false;
|
||||||
|
// If we have an method return type bound, then we need to substitute
|
||||||
|
// the method's early bound params with suitable late-bound params.
|
||||||
|
let mut num_bound_vars = candidate.bound_vars().len();
|
||||||
|
let substs =
|
||||||
|
candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| {
|
||||||
|
let subst = match param.kind {
|
||||||
|
ty::GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
|
||||||
|
tcx,
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundRegion {
|
||||||
|
var: ty::BoundVar::from_usize(num_bound_vars),
|
||||||
|
kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
ty::GenericParamDefKind::Type { .. } => {
|
||||||
|
if !emitted_bad_param_err {
|
||||||
|
tcx.sess.emit_err(
|
||||||
|
crate::errors::ReturnTypeNotationIllegalParam::Type {
|
||||||
|
span: path_span,
|
||||||
|
param_span: tcx.def_span(param.def_id),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
emitted_bad_param_err = true;
|
||||||
|
}
|
||||||
|
tcx.mk_bound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundTy {
|
||||||
|
var: ty::BoundVar::from_usize(num_bound_vars),
|
||||||
|
kind: ty::BoundTyKind::Param(param.def_id, param.name),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
ty::GenericParamDefKind::Const { .. } => {
|
||||||
|
if !emitted_bad_param_err {
|
||||||
|
tcx.sess.emit_err(
|
||||||
|
crate::errors::ReturnTypeNotationIllegalParam::Const {
|
||||||
|
span: path_span,
|
||||||
|
param_span: tcx.def_span(param.def_id),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
emitted_bad_param_err = true;
|
||||||
|
}
|
||||||
|
let ty = tcx
|
||||||
|
.type_of(param.def_id)
|
||||||
|
.no_bound_vars()
|
||||||
|
.expect("ct params cannot have early bound vars");
|
||||||
|
tcx.mk_const(
|
||||||
|
ty::ConstKind::Bound(
|
||||||
|
ty::INNERMOST,
|
||||||
|
ty::BoundVar::from_usize(num_bound_vars),
|
||||||
|
),
|
||||||
|
ty,
|
||||||
|
)
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
num_bound_vars += 1;
|
||||||
|
subst
|
||||||
|
});
|
||||||
|
|
||||||
|
// Next, we need to check that the return-type notation is being used on
|
||||||
|
// an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
|
||||||
|
let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output();
|
||||||
|
let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
|
||||||
|
&& tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder
|
||||||
|
{
|
||||||
|
alias_ty
|
||||||
|
} else {
|
||||||
|
return Err(self.tcx().sess.emit_err(
|
||||||
|
crate::errors::ReturnTypeNotationOnNonRpitit {
|
||||||
|
span: binding.span,
|
||||||
|
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
|
||||||
|
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
|
||||||
|
note: (),
|
||||||
|
},
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Finally, move the fn return type's bound vars over to account for the early bound
|
||||||
|
// params (and trait ref's late bound params). This logic is very similar to
|
||||||
|
// `Predicate::subst_supertrait`, and it's no coincidence why.
|
||||||
|
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
||||||
|
let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs);
|
||||||
|
|
||||||
|
let bound_vars = tcx.late_bound_vars(binding.hir_id);
|
||||||
|
ty::Binder::bind_with_vars(subst_output, bound_vars)
|
||||||
|
} else {
|
||||||
|
// Include substitutions for generic parameters of associated types
|
||||||
|
candidate.map_bound(|trait_ref| {
|
||||||
|
let ident = Ident::new(assoc_item.name, binding.item_name.span);
|
||||||
|
let item_segment = hir::PathSegment {
|
||||||
|
ident,
|
||||||
|
hir_id: binding.hir_id,
|
||||||
|
res: Res::Err,
|
||||||
|
args: Some(binding.gen_args),
|
||||||
|
infer_args: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item(
|
||||||
|
path_span,
|
||||||
|
assoc_item.def_id,
|
||||||
|
&item_segment,
|
||||||
|
trait_ref.substs,
|
||||||
|
);
|
||||||
|
|
||||||
|
debug!(?substs_trait_ref_and_assoc_item);
|
||||||
|
|
||||||
|
tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
if !speculative {
|
||||||
|
// Find any late-bound regions declared in `ty` that are not
|
||||||
|
// declared in the trait-ref or assoc_item. These are not well-formed.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
||||||
|
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
||||||
|
if let ConvertedBindingKind::Equality(ty) = binding.kind {
|
||||||
|
let late_bound_in_trait_ref =
|
||||||
|
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
||||||
|
let late_bound_in_ty =
|
||||||
|
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
|
||||||
|
debug!(?late_bound_in_trait_ref);
|
||||||
|
debug!(?late_bound_in_ty);
|
||||||
|
|
||||||
|
// FIXME: point at the type params that don't have appropriate lifetimes:
|
||||||
|
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
||||||
|
// ---- ---- ^^^^^^^
|
||||||
|
self.validate_late_bound_regions(
|
||||||
|
late_bound_in_trait_ref,
|
||||||
|
late_bound_in_ty,
|
||||||
|
|br_name| {
|
||||||
|
struct_span_err!(
|
||||||
|
tcx.sess,
|
||||||
|
binding.span,
|
||||||
|
E0582,
|
||||||
|
"binding for associated type `{}` references {}, \
|
||||||
|
which does not appear in the trait input types",
|
||||||
|
binding.item_name,
|
||||||
|
br_name
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match binding.kind {
|
||||||
|
ConvertedBindingKind::Equality(..) if return_type_notation => {
|
||||||
|
return Err(self.tcx().sess.emit_err(
|
||||||
|
crate::errors::ReturnTypeNotationEqualityBound { span: binding.span },
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ConvertedBindingKind::Equality(mut term) => {
|
||||||
|
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
||||||
|
// the "projection predicate" for:
|
||||||
|
//
|
||||||
|
// `<T as Iterator>::Item = u32`
|
||||||
|
let assoc_item_def_id = projection_ty.skip_binder().def_id;
|
||||||
|
let def_kind = tcx.def_kind(assoc_item_def_id);
|
||||||
|
match (def_kind, term.unpack()) {
|
||||||
|
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
|
||||||
|
| (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
|
||||||
|
(_, _) => {
|
||||||
|
let got = if let Some(_) = term.ty() { "type" } else { "constant" };
|
||||||
|
let expected = tcx.def_descr(assoc_item_def_id);
|
||||||
|
let mut err = tcx.sess.struct_span_err(
|
||||||
|
binding.span,
|
||||||
|
format!("expected {expected} bound, found {got}"),
|
||||||
|
);
|
||||||
|
err.span_note(
|
||||||
|
tcx.def_span(assoc_item_def_id),
|
||||||
|
format!("{expected} defined here"),
|
||||||
|
);
|
||||||
|
|
||||||
|
if let hir::def::DefKind::AssocConst = def_kind
|
||||||
|
&& let Some(t) = term.ty() && (t.is_enum() || t.references_error())
|
||||||
|
&& tcx.features().associated_const_equality {
|
||||||
|
err.span_suggestion(
|
||||||
|
binding.span,
|
||||||
|
"if equating a const, try wrapping with braces",
|
||||||
|
format!("{} = {{ const }}", binding.item_name),
|
||||||
|
Applicability::HasPlaceholders,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let reported = err.emit();
|
||||||
|
term = match def_kind {
|
||||||
|
hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(),
|
||||||
|
hir::def::DefKind::AssocConst => tcx
|
||||||
|
.const_error(
|
||||||
|
tcx.type_of(assoc_item_def_id)
|
||||||
|
.subst(tcx, projection_ty.skip_binder().substs),
|
||||||
|
reported,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bounds.push_projection_bound(
|
||||||
|
tcx,
|
||||||
|
projection_ty
|
||||||
|
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
|
||||||
|
binding.span,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ConvertedBindingKind::Constraint(ast_bounds) => {
|
||||||
|
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
||||||
|
//
|
||||||
|
// `<T as Iterator>::Item: Debug`
|
||||||
|
//
|
||||||
|
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||||
|
// parameter to have a skipped binder.
|
||||||
|
//
|
||||||
|
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
||||||
|
// type bound into a trait predicate, since we only want to add predicates
|
||||||
|
// for the `Self` type.
|
||||||
|
if !only_self_bounds.0 {
|
||||||
|
let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
|
||||||
|
self.add_bounds(
|
||||||
|
param_ty,
|
||||||
|
ast_bounds.iter(),
|
||||||
|
bounds,
|
||||||
|
projection_ty.bound_vars(),
|
||||||
|
only_self_bounds,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
|
//! The main routine here is `ast_ty_to_ty()`; each use is parameterized by an
|
||||||
//! instance of `AstConv`.
|
//! instance of `AstConv`.
|
||||||
|
|
||||||
|
mod bounds;
|
||||||
mod errors;
|
mod errors;
|
||||||
pub mod generics;
|
pub mod generics;
|
||||||
mod lint;
|
mod lint;
|
||||||
|
@ -11,8 +12,7 @@ use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generi
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::HirPlaceholderCollector;
|
use crate::collect::HirPlaceholderCollector;
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
AmbiguousLifetimeBound, MultipleRelaxedDefaultBounds, TraitObjectDeclaredWithNoTraits,
|
AmbiguousLifetimeBound, TraitObjectDeclaredWithNoTraits, TypeofReservedKeywordUsed,
|
||||||
TypeofReservedKeywordUsed, ValueOfAssociatedStructAlreadySpecified,
|
|
||||||
};
|
};
|
||||||
use crate::middle::resolve_bound_vars as rbv;
|
use crate::middle::resolve_bound_vars as rbv;
|
||||||
use crate::require_c_abi_if_c_variadic;
|
use crate::require_c_abi_if_c_variadic;
|
||||||
|
@ -885,571 +885,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
.is_some()
|
.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets `implicitly_sized` to true on `Bounds` if necessary
|
|
||||||
pub(crate) fn add_implicitly_sized(
|
|
||||||
&self,
|
|
||||||
bounds: &mut Bounds<'tcx>,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
|
||||||
self_ty_where_predicates: Option<(LocalDefId, &'tcx [hir::WherePredicate<'tcx>])>,
|
|
||||||
span: Span,
|
|
||||||
) {
|
|
||||||
let tcx = self.tcx();
|
|
||||||
|
|
||||||
// Try to find an unbound in bounds.
|
|
||||||
let mut unbound = None;
|
|
||||||
let mut search_bounds = |ast_bounds: &'tcx [hir::GenericBound<'tcx>]| {
|
|
||||||
for ab in ast_bounds {
|
|
||||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
|
||||||
if unbound.is_none() {
|
|
||||||
unbound = Some(&ptr.trait_ref);
|
|
||||||
} else {
|
|
||||||
tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
search_bounds(ast_bounds);
|
|
||||||
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
|
||||||
for clause in where_clause {
|
|
||||||
if let hir::WherePredicate::BoundPredicate(pred) = clause {
|
|
||||||
if pred.is_param_bound(self_ty.to_def_id()) {
|
|
||||||
search_bounds(pred.bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let sized_def_id = tcx.lang_items().sized_trait();
|
|
||||||
match (&sized_def_id, unbound) {
|
|
||||||
(Some(sized_def_id), Some(tpb))
|
|
||||||
if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
|
|
||||||
{
|
|
||||||
// There was in fact a `?Sized` bound, return without doing anything
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
(_, Some(_)) => {
|
|
||||||
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
|
||||||
tcx.sess.span_warn(
|
|
||||||
span,
|
|
||||||
"default bound relaxed for a type parameter, but \
|
|
||||||
this does nothing because the given bound is not \
|
|
||||||
a default; only `?Sized` is supported",
|
|
||||||
);
|
|
||||||
// Otherwise, add implicitly sized if `Sized` is available.
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if sized_def_id.is_none() {
|
|
||||||
// No lang item for `Sized`, so we can't add it as a bound.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
bounds.push_sized(tcx, self_ty, span);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
|
||||||
/// and an *unconverted* list of bounds:
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// fn foo<T: Debug>
|
|
||||||
/// ^ ^^^^^ `ast_bounds` parameter, in HIR form
|
|
||||||
/// |
|
|
||||||
/// `param_ty`, in ty form
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// It adds these `ast_bounds` into the `bounds` structure.
|
|
||||||
///
|
|
||||||
/// **A note on binders:** there is an implied binder around
|
|
||||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
|
||||||
/// for more details.
|
|
||||||
#[instrument(level = "debug", skip(self, ast_bounds, bounds))]
|
|
||||||
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'hir>>>(
|
|
||||||
&self,
|
|
||||||
param_ty: Ty<'tcx>,
|
|
||||||
ast_bounds: I,
|
|
||||||
bounds: &mut Bounds<'tcx>,
|
|
||||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
|
||||||
only_self_bounds: OnlySelfBounds,
|
|
||||||
) {
|
|
||||||
for ast_bound in ast_bounds {
|
|
||||||
match ast_bound {
|
|
||||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
|
||||||
let (constness, polarity) = match modifier {
|
|
||||||
hir::TraitBoundModifier::MaybeConst => {
|
|
||||||
(ty::BoundConstness::ConstIfConst, ty::ImplPolarity::Positive)
|
|
||||||
}
|
|
||||||
hir::TraitBoundModifier::None => {
|
|
||||||
(ty::BoundConstness::NotConst, ty::ImplPolarity::Positive)
|
|
||||||
}
|
|
||||||
hir::TraitBoundModifier::Negative => {
|
|
||||||
(ty::BoundConstness::NotConst, ty::ImplPolarity::Negative)
|
|
||||||
}
|
|
||||||
hir::TraitBoundModifier::Maybe => continue,
|
|
||||||
};
|
|
||||||
let _ = self.instantiate_poly_trait_ref(
|
|
||||||
&poly_trait_ref.trait_ref,
|
|
||||||
poly_trait_ref.span,
|
|
||||||
constness,
|
|
||||||
polarity,
|
|
||||||
param_ty,
|
|
||||||
bounds,
|
|
||||||
false,
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
|
||||||
self.instantiate_lang_item_trait_ref(
|
|
||||||
lang_item,
|
|
||||||
span,
|
|
||||||
hir_id,
|
|
||||||
args,
|
|
||||||
param_ty,
|
|
||||||
bounds,
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
|
||||||
let region = self.ast_region_to_region(lifetime, None);
|
|
||||||
bounds.push_region_bound(
|
|
||||||
self.tcx(),
|
|
||||||
ty::Binder::bind_with_vars(
|
|
||||||
ty::OutlivesPredicate(param_ty, region),
|
|
||||||
bound_vars,
|
|
||||||
),
|
|
||||||
lifetime.ident.span,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Translates a list of bounds from the HIR into the `Bounds` data structure.
|
|
||||||
/// The self-type for the bounds is given by `param_ty`.
|
|
||||||
///
|
|
||||||
/// Example:
|
|
||||||
///
|
|
||||||
/// ```ignore (illustrative)
|
|
||||||
/// fn foo<T: Bar + Baz>() { }
|
|
||||||
/// // ^ ^^^^^^^^^ ast_bounds
|
|
||||||
/// // param_ty
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be
|
|
||||||
/// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the
|
|
||||||
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
|
||||||
///
|
|
||||||
/// `span` should be the declaration size of the parameter.
|
|
||||||
pub(crate) fn compute_bounds(
|
|
||||||
&self,
|
|
||||||
param_ty: Ty<'tcx>,
|
|
||||||
ast_bounds: &[hir::GenericBound<'_>],
|
|
||||||
only_self_bounds: OnlySelfBounds,
|
|
||||||
) -> Bounds<'tcx> {
|
|
||||||
let mut bounds = Bounds::default();
|
|
||||||
self.add_bounds(
|
|
||||||
param_ty,
|
|
||||||
ast_bounds.iter(),
|
|
||||||
&mut bounds,
|
|
||||||
ty::List::empty(),
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
debug!(?bounds);
|
|
||||||
|
|
||||||
bounds
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
|
|
||||||
/// named `assoc_name` into ty::Bounds. Ignore the rest.
|
|
||||||
pub(crate) fn compute_bounds_that_match_assoc_item(
|
|
||||||
&self,
|
|
||||||
param_ty: Ty<'tcx>,
|
|
||||||
ast_bounds: &[hir::GenericBound<'_>],
|
|
||||||
assoc_name: Ident,
|
|
||||||
) -> Bounds<'tcx> {
|
|
||||||
let mut result = Vec::new();
|
|
||||||
|
|
||||||
for ast_bound in ast_bounds {
|
|
||||||
if let Some(trait_ref) = ast_bound.trait_ref()
|
|
||||||
&& let Some(trait_did) = trait_ref.trait_def_id()
|
|
||||||
&& self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
|
|
||||||
{
|
|
||||||
result.push(ast_bound.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut bounds = Bounds::default();
|
|
||||||
self.add_bounds(
|
|
||||||
param_ty,
|
|
||||||
result.iter(),
|
|
||||||
&mut bounds,
|
|
||||||
ty::List::empty(),
|
|
||||||
OnlySelfBounds(true),
|
|
||||||
);
|
|
||||||
debug!(?bounds);
|
|
||||||
|
|
||||||
bounds
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates
|
|
||||||
/// onto `bounds`.
|
|
||||||
///
|
|
||||||
/// **A note on binders:** given something like `T: for<'a> Iterator<Item = &'a u32>`, the
|
|
||||||
/// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside*
|
|
||||||
/// the binder (e.g., `&'a u32`) and hence may reference bound regions.
|
|
||||||
#[instrument(level = "debug", skip(self, bounds, speculative, dup_bindings, path_span))]
|
|
||||||
fn add_predicates_for_ast_type_binding(
|
|
||||||
&self,
|
|
||||||
hir_ref_id: hir::HirId,
|
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
|
||||||
binding: &ConvertedBinding<'_, 'tcx>,
|
|
||||||
bounds: &mut Bounds<'tcx>,
|
|
||||||
speculative: bool,
|
|
||||||
dup_bindings: &mut FxHashMap<DefId, Span>,
|
|
||||||
path_span: Span,
|
|
||||||
constness: ty::BoundConstness,
|
|
||||||
only_self_bounds: OnlySelfBounds,
|
|
||||||
polarity: ty::ImplPolarity,
|
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
|
||||||
// Given something like `U: SomeTrait<T = X>`, we want to produce a
|
|
||||||
// predicate like `<U as SomeTrait>::T = X`. This is somewhat
|
|
||||||
// subtle in the event that `T` is defined in a supertrait of
|
|
||||||
// `SomeTrait`, because in that case we need to upcast.
|
|
||||||
//
|
|
||||||
// That is, consider this case:
|
|
||||||
//
|
|
||||||
// ```
|
|
||||||
// trait SubTrait: SuperTrait<i32> { }
|
|
||||||
// trait SuperTrait<A> { type T; }
|
|
||||||
//
|
|
||||||
// ... B: SubTrait<T = foo> ...
|
|
||||||
// ```
|
|
||||||
//
|
|
||||||
// We want to produce `<B as SuperTrait<i32>>::T == foo`.
|
|
||||||
|
|
||||||
let tcx = self.tcx();
|
|
||||||
|
|
||||||
let return_type_notation =
|
|
||||||
binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation;
|
|
||||||
|
|
||||||
let candidate = if return_type_notation {
|
|
||||||
if self.trait_defines_associated_item_named(
|
|
||||||
trait_ref.def_id(),
|
|
||||||
ty::AssocKind::Fn,
|
|
||||||
binding.item_name,
|
|
||||||
) {
|
|
||||||
trait_ref
|
|
||||||
} else {
|
|
||||||
self.one_bound_for_assoc_method(
|
|
||||||
traits::supertraits(tcx, trait_ref),
|
|
||||||
trait_ref.print_only_trait_path(),
|
|
||||||
binding.item_name,
|
|
||||||
path_span,
|
|
||||||
)?
|
|
||||||
}
|
|
||||||
} else if self.trait_defines_associated_item_named(
|
|
||||||
trait_ref.def_id(),
|
|
||||||
ty::AssocKind::Type,
|
|
||||||
binding.item_name,
|
|
||||||
) {
|
|
||||||
// Simple case: X is defined in the current trait.
|
|
||||||
trait_ref
|
|
||||||
} else {
|
|
||||||
// Otherwise, we have to walk through the supertraits to find
|
|
||||||
// those that do.
|
|
||||||
self.one_bound_for_assoc_type(
|
|
||||||
|| traits::supertraits(tcx, trait_ref),
|
|
||||||
trait_ref.skip_binder().print_only_trait_name(),
|
|
||||||
binding.item_name,
|
|
||||||
path_span,
|
|
||||||
match binding.kind {
|
|
||||||
ConvertedBindingKind::Equality(term) => Some(term),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
let (assoc_ident, def_scope) =
|
|
||||||
tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id);
|
|
||||||
|
|
||||||
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
|
|
||||||
// of calling `filter_by_name_and_kind`.
|
|
||||||
let find_item_of_kind = |kind| {
|
|
||||||
tcx.associated_items(candidate.def_id())
|
|
||||||
.filter_by_name_unhygienic(assoc_ident.name)
|
|
||||||
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
|
|
||||||
};
|
|
||||||
let assoc_item = if return_type_notation {
|
|
||||||
find_item_of_kind(ty::AssocKind::Fn)
|
|
||||||
} else {
|
|
||||||
find_item_of_kind(ty::AssocKind::Type)
|
|
||||||
.or_else(|| find_item_of_kind(ty::AssocKind::Const))
|
|
||||||
}
|
|
||||||
.expect("missing associated type");
|
|
||||||
|
|
||||||
if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
|
|
||||||
tcx.sess
|
|
||||||
.struct_span_err(
|
|
||||||
binding.span,
|
|
||||||
format!("{} `{}` is private", assoc_item.kind, binding.item_name),
|
|
||||||
)
|
|
||||||
.span_label(binding.span, format!("private {}", assoc_item.kind))
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
tcx.check_stability(assoc_item.def_id, Some(hir_ref_id), binding.span, None);
|
|
||||||
|
|
||||||
if !speculative {
|
|
||||||
dup_bindings
|
|
||||||
.entry(assoc_item.def_id)
|
|
||||||
.and_modify(|prev_span| {
|
|
||||||
tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified {
|
|
||||||
span: binding.span,
|
|
||||||
prev_span: *prev_span,
|
|
||||||
item_name: binding.item_name,
|
|
||||||
def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.or_insert(binding.span);
|
|
||||||
}
|
|
||||||
|
|
||||||
let projection_ty = if return_type_notation {
|
|
||||||
let mut emitted_bad_param_err = false;
|
|
||||||
// If we have an method return type bound, then we need to substitute
|
|
||||||
// the method's early bound params with suitable late-bound params.
|
|
||||||
let mut num_bound_vars = candidate.bound_vars().len();
|
|
||||||
let substs =
|
|
||||||
candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| {
|
|
||||||
let subst = match param.kind {
|
|
||||||
GenericParamDefKind::Lifetime => ty::Region::new_late_bound(
|
|
||||||
tcx,
|
|
||||||
ty::INNERMOST,
|
|
||||||
ty::BoundRegion {
|
|
||||||
var: ty::BoundVar::from_usize(num_bound_vars),
|
|
||||||
kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
GenericParamDefKind::Type { .. } => {
|
|
||||||
if !emitted_bad_param_err {
|
|
||||||
tcx.sess.emit_err(
|
|
||||||
crate::errors::ReturnTypeNotationIllegalParam::Type {
|
|
||||||
span: path_span,
|
|
||||||
param_span: tcx.def_span(param.def_id),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
emitted_bad_param_err = true;
|
|
||||||
}
|
|
||||||
tcx.mk_bound(
|
|
||||||
ty::INNERMOST,
|
|
||||||
ty::BoundTy {
|
|
||||||
var: ty::BoundVar::from_usize(num_bound_vars),
|
|
||||||
kind: ty::BoundTyKind::Param(param.def_id, param.name),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
GenericParamDefKind::Const { .. } => {
|
|
||||||
if !emitted_bad_param_err {
|
|
||||||
tcx.sess.emit_err(
|
|
||||||
crate::errors::ReturnTypeNotationIllegalParam::Const {
|
|
||||||
span: path_span,
|
|
||||||
param_span: tcx.def_span(param.def_id),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
emitted_bad_param_err = true;
|
|
||||||
}
|
|
||||||
let ty = tcx
|
|
||||||
.type_of(param.def_id)
|
|
||||||
.no_bound_vars()
|
|
||||||
.expect("ct params cannot have early bound vars");
|
|
||||||
tcx.mk_const(
|
|
||||||
ty::ConstKind::Bound(
|
|
||||||
ty::INNERMOST,
|
|
||||||
ty::BoundVar::from_usize(num_bound_vars),
|
|
||||||
),
|
|
||||||
ty,
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
num_bound_vars += 1;
|
|
||||||
subst
|
|
||||||
});
|
|
||||||
|
|
||||||
// Next, we need to check that the return-type notation is being used on
|
|
||||||
// an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait).
|
|
||||||
let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output();
|
|
||||||
let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind()
|
|
||||||
&& tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder
|
|
||||||
{
|
|
||||||
alias_ty
|
|
||||||
} else {
|
|
||||||
return Err(self.tcx().sess.emit_err(
|
|
||||||
crate::errors::ReturnTypeNotationOnNonRpitit {
|
|
||||||
span: binding.span,
|
|
||||||
ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output),
|
|
||||||
fn_span: tcx.hir().span_if_local(assoc_item.def_id),
|
|
||||||
note: (),
|
|
||||||
},
|
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
// Finally, move the fn return type's bound vars over to account for the early bound
|
|
||||||
// params (and trait ref's late bound params). This logic is very similar to
|
|
||||||
// `Predicate::subst_supertrait`, and it's no coincidence why.
|
|
||||||
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
|
|
||||||
let subst_output = ty::EarlyBinder::bind(shifted_output).subst(tcx, substs);
|
|
||||||
|
|
||||||
let bound_vars = tcx.late_bound_vars(binding.hir_id);
|
|
||||||
ty::Binder::bind_with_vars(subst_output, bound_vars)
|
|
||||||
} else {
|
|
||||||
// Include substitutions for generic parameters of associated types
|
|
||||||
candidate.map_bound(|trait_ref| {
|
|
||||||
let ident = Ident::new(assoc_item.name, binding.item_name.span);
|
|
||||||
let item_segment = hir::PathSegment {
|
|
||||||
ident,
|
|
||||||
hir_id: binding.hir_id,
|
|
||||||
res: Res::Err,
|
|
||||||
args: Some(binding.gen_args),
|
|
||||||
infer_args: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item(
|
|
||||||
path_span,
|
|
||||||
assoc_item.def_id,
|
|
||||||
&item_segment,
|
|
||||||
trait_ref.substs,
|
|
||||||
);
|
|
||||||
|
|
||||||
debug!(?substs_trait_ref_and_assoc_item);
|
|
||||||
|
|
||||||
tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item)
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
if !speculative {
|
|
||||||
// Find any late-bound regions declared in `ty` that are not
|
|
||||||
// declared in the trait-ref or assoc_item. These are not well-formed.
|
|
||||||
//
|
|
||||||
// Example:
|
|
||||||
//
|
|
||||||
// for<'a> <T as Iterator>::Item = &'a str // <-- 'a is bad
|
|
||||||
// for<'a> <T as FnMut<(&'a u32,)>>::Output = &'a str // <-- 'a is ok
|
|
||||||
if let ConvertedBindingKind::Equality(ty) = binding.kind {
|
|
||||||
let late_bound_in_trait_ref =
|
|
||||||
tcx.collect_constrained_late_bound_regions(&projection_ty);
|
|
||||||
let late_bound_in_ty =
|
|
||||||
tcx.collect_referenced_late_bound_regions(&trait_ref.rebind(ty));
|
|
||||||
debug!(?late_bound_in_trait_ref);
|
|
||||||
debug!(?late_bound_in_ty);
|
|
||||||
|
|
||||||
// FIXME: point at the type params that don't have appropriate lifetimes:
|
|
||||||
// struct S1<F: for<'a> Fn(&i32, &i32) -> &'a i32>(F);
|
|
||||||
// ---- ---- ^^^^^^^
|
|
||||||
self.validate_late_bound_regions(
|
|
||||||
late_bound_in_trait_ref,
|
|
||||||
late_bound_in_ty,
|
|
||||||
|br_name| {
|
|
||||||
struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
binding.span,
|
|
||||||
E0582,
|
|
||||||
"binding for associated type `{}` references {}, \
|
|
||||||
which does not appear in the trait input types",
|
|
||||||
binding.item_name,
|
|
||||||
br_name
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match binding.kind {
|
|
||||||
ConvertedBindingKind::Equality(..) if return_type_notation => {
|
|
||||||
return Err(self.tcx().sess.emit_err(
|
|
||||||
crate::errors::ReturnTypeNotationEqualityBound { span: binding.span },
|
|
||||||
));
|
|
||||||
}
|
|
||||||
ConvertedBindingKind::Equality(mut term) => {
|
|
||||||
// "Desugar" a constraint like `T: Iterator<Item = u32>` this to
|
|
||||||
// the "projection predicate" for:
|
|
||||||
//
|
|
||||||
// `<T as Iterator>::Item = u32`
|
|
||||||
let assoc_item_def_id = projection_ty.skip_binder().def_id;
|
|
||||||
let def_kind = tcx.def_kind(assoc_item_def_id);
|
|
||||||
match (def_kind, term.unpack()) {
|
|
||||||
(hir::def::DefKind::AssocTy, ty::TermKind::Ty(_))
|
|
||||||
| (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (),
|
|
||||||
(_, _) => {
|
|
||||||
let got = if let Some(_) = term.ty() { "type" } else { "constant" };
|
|
||||||
let expected = tcx.def_descr(assoc_item_def_id);
|
|
||||||
let mut err = tcx.sess.struct_span_err(
|
|
||||||
binding.span,
|
|
||||||
format!("expected {expected} bound, found {got}"),
|
|
||||||
);
|
|
||||||
err.span_note(
|
|
||||||
tcx.def_span(assoc_item_def_id),
|
|
||||||
format!("{expected} defined here"),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let hir::def::DefKind::AssocConst = def_kind
|
|
||||||
&& let Some(t) = term.ty() && (t.is_enum() || t.references_error())
|
|
||||||
&& tcx.features().associated_const_equality {
|
|
||||||
err.span_suggestion(
|
|
||||||
binding.span,
|
|
||||||
"if equating a const, try wrapping with braces",
|
|
||||||
format!("{} = {{ const }}", binding.item_name),
|
|
||||||
Applicability::HasPlaceholders,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let reported = err.emit();
|
|
||||||
term = match def_kind {
|
|
||||||
hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(),
|
|
||||||
hir::def::DefKind::AssocConst => tcx
|
|
||||||
.const_error(
|
|
||||||
tcx.type_of(assoc_item_def_id)
|
|
||||||
.subst(tcx, projection_ty.skip_binder().substs),
|
|
||||||
reported,
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
_ => unreachable!(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bounds.push_projection_bound(
|
|
||||||
tcx,
|
|
||||||
projection_ty
|
|
||||||
.map_bound(|projection_ty| ty::ProjectionPredicate { projection_ty, term }),
|
|
||||||
binding.span,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ConvertedBindingKind::Constraint(ast_bounds) => {
|
|
||||||
// "Desugar" a constraint like `T: Iterator<Item: Debug>` to
|
|
||||||
//
|
|
||||||
// `<T as Iterator>::Item: Debug`
|
|
||||||
//
|
|
||||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
|
||||||
// parameter to have a skipped binder.
|
|
||||||
//
|
|
||||||
// NOTE: If `only_self_bounds` is true, do NOT expand this associated
|
|
||||||
// type bound into a trait predicate, since we only want to add predicates
|
|
||||||
// for the `Self` type.
|
|
||||||
if !only_self_bounds.0 {
|
|
||||||
let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder());
|
|
||||||
self.add_bounds(
|
|
||||||
param_ty,
|
|
||||||
ast_bounds.iter(),
|
|
||||||
bounds,
|
|
||||||
projection_ty.bound_vars(),
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ast_path_to_ty(
|
fn ast_path_to_ty(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -1527,15 +962,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
ty::Clause::TypeOutlives(_) => {
|
ty::Clause::TypeOutlives(_) => {
|
||||||
// Do nothing, we deal with regions separately
|
// Do nothing, we deal with regions separately
|
||||||
}
|
}
|
||||||
ty::Clause::RegionOutlives(_) | ty::Clause::ConstArgHasType(..) => bug!(),
|
ty::Clause::RegionOutlives(_)
|
||||||
|
| ty::Clause::ConstArgHasType(..)
|
||||||
|
| ty::Clause::WellFormed(_)
|
||||||
|
| ty::Clause::ConstEvaluatable(_) => bug!(),
|
||||||
},
|
},
|
||||||
ty::PredicateKind::WellFormed(_)
|
ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(_, _, _)
|
| ty::PredicateKind::ClosureKind(_, _, _)
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
| ty::PredicateKind::Coerce(_)
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::ConstEvaluatable(_)
|
|
||||||
| ty::PredicateKind::ConstEquate(_, _)
|
| ty::PredicateKind::ConstEquate(_, _)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(_)
|
| ty::PredicateKind::TypeWellFormedFromEnv(_)
|
||||||
| ty::PredicateKind::Ambiguous => bug!(),
|
| ty::PredicateKind::Ambiguous => bug!(),
|
||||||
|
|
|
@ -439,7 +439,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||||
// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
|
// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
|
||||||
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
|
||||||
// hidden type is well formed even without those bounds.
|
// hidden type is well formed even without those bounds.
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into()));
|
let predicate =
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(hidden_ty.into())));
|
||||||
ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate));
|
ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate));
|
||||||
|
|
||||||
// Check that all obligations are satisfied by the implementation's
|
// Check that all obligations are satisfied by the implementation's
|
||||||
|
|
|
@ -321,7 +321,9 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
infcx.tcx,
|
infcx.tcx,
|
||||||
ObligationCause::dummy(),
|
ObligationCause::dummy(),
|
||||||
param_env,
|
param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_impl_fty.into())),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
|
||||||
|
unnormalized_impl_fty.into(),
|
||||||
|
))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
cause,
|
cause,
|
||||||
param_env,
|
param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1032,9 +1032,9 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||||
tcx,
|
tcx,
|
||||||
cause,
|
cause,
|
||||||
wfcx.param_env,
|
wfcx.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(
|
||||||
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
|
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
|
||||||
)),
|
))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1876,7 +1876,8 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
// We lower empty bounds like `Vec<dyn Copy>:` as
|
// We lower empty bounds like `Vec<dyn Copy>:` as
|
||||||
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
|
// `WellFormed(Vec<dyn Copy>)`, which will later get checked by
|
||||||
// regular WF checking
|
// regular WF checking
|
||||||
if let ty::PredicateKind::WellFormed(..) = pred.kind().skip_binder() {
|
if let ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) = pred.kind().skip_binder()
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Match the existing behavior.
|
// Match the existing behavior.
|
||||||
|
|
|
@ -219,7 +219,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||||
} else {
|
} else {
|
||||||
let span = bound_pred.bounded_ty.span;
|
let span = bound_pred.bounded_ty.span;
|
||||||
let predicate = ty::Binder::bind_with_vars(
|
let predicate = ty::Binder::bind_with_vars(
|
||||||
ty::PredicateKind::WellFormed(ty.into()),
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(ty.into())),
|
||||||
bound_vars,
|
bound_vars,
|
||||||
);
|
);
|
||||||
predicates.insert((predicate.to_predicate(tcx), span));
|
predicates.insert((predicate.to_predicate(tcx), span));
|
||||||
|
@ -353,7 +353,7 @@ fn const_evaluatable_predicates_of(
|
||||||
if let ty::ConstKind::Unevaluated(_) = ct.kind() {
|
if let ty::ConstKind::Unevaluated(_) = ct.kind() {
|
||||||
let span = self.tcx.def_span(c.def_id);
|
let span = self.tcx.def_span(c.def_id);
|
||||||
self.preds.insert((
|
self.preds.insert((
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct))
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)))
|
||||||
.to_predicate(self.tcx),
|
.to_predicate(self.tcx),
|
||||||
span,
|
span,
|
||||||
));
|
));
|
||||||
|
|
|
@ -79,7 +79,7 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
cause,
|
cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::PredicateKind::WellFormed(tcx_ty.into()),
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(tcx_ty.into())),
|
||||||
));
|
));
|
||||||
|
|
||||||
for error in ocx.select_all_or_error() {
|
for error in ocx.select_all_or_error() {
|
||||||
|
|
|
@ -542,12 +542,12 @@ fn trait_predicate_kind<'tcx>(
|
||||||
| ty::PredicateKind::Clause(ty::Clause::Projection(_))
|
| ty::PredicateKind::Clause(ty::Clause::Projection(_))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::WellFormed(_)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(_))
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
| ty::PredicateKind::Coerce(_)
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
|
|
@ -55,13 +55,13 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
ty::PredicateKind::Clause(ty::Clause::Trait(..))
|
ty::PredicateKind::Clause(ty::Clause::Trait(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => (),
|
||||||
|
|
|
@ -483,7 +483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
self.tcx,
|
self.tcx,
|
||||||
cause,
|
cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,10 +668,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
// N.B., this predicate is created by breaking down a
|
// N.B., this predicate is created by breaking down a
|
||||||
// `ClosureType: FnFoo()` predicate, where
|
// `ClosureType: FnFoo()` predicate, where
|
||||||
|
|
|
@ -32,7 +32,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => {
|
||||||
vec![ty.into(), arg.into()]
|
vec![ty.into(), arg.into()]
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEvaluatable(e) => vec![e.into()],
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(e)) => vec![e.into()],
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
tcx,
|
tcx,
|
||||||
obligation.cause,
|
obligation.cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(method_ty.into()))),
|
||||||
));
|
));
|
||||||
|
|
||||||
let callee = MethodCallee { def_id, substs, sig: fn_sig };
|
let callee = MethodCallee { def_id, substs, sig: fn_sig };
|
||||||
|
|
|
@ -838,11 +838,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
|
|
|
@ -696,7 +696,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't point out the span of `WellFormed` predicates.
|
// Don't point out the span of `WellFormed` predicates.
|
||||||
if !matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) {
|
if !matches!(
|
||||||
|
p.kind().skip_binder(),
|
||||||
|
ty::PredicateKind::Clause(ty::Clause::Projection(..) | ty::Clause::Trait(..))
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -417,7 +417,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
self.trace.cause.clone(),
|
self.trace.cause.clone(),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(b_ty.into()))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ pub fn explicit_outlives_bounds<'tcx>(
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
|
|
@ -227,7 +227,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
||||||
debug!(?data, ?obligations, "super_predicates");
|
debug!(?data, ?obligations, "super_predicates");
|
||||||
self.extend_deduped(obligations);
|
self.extend_deduped(obligations);
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(..) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) => {
|
||||||
// Currently, we do not elaborate WF predicates,
|
// Currently, we do not elaborate WF predicates,
|
||||||
// although we easily could.
|
// although we easily could.
|
||||||
}
|
}
|
||||||
|
@ -249,7 +249,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
||||||
ty::PredicateKind::ClosureKind(..) => {
|
ty::PredicateKind::ClosureKind(..) => {
|
||||||
// Nothing to elaborate when waiting for a closure's kind to be inferred.
|
// Nothing to elaborate when waiting for a closure's kind to be inferred.
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEvaluatable(..) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => {
|
||||||
// Currently, we do not elaborate const-evaluatable
|
// Currently, we do not elaborate const-evaluatable
|
||||||
// predicates.
|
// predicates.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1610,13 +1610,13 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
||||||
Clause(Clause::Projection(..)) |
|
Clause(Clause::Projection(..)) |
|
||||||
AliasRelate(..) |
|
AliasRelate(..) |
|
||||||
// Ignore bounds that a user can't type
|
// Ignore bounds that a user can't type
|
||||||
WellFormed(..) |
|
Clause(Clause::WellFormed(..)) |
|
||||||
|
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
||||||
|
Clause(Clause::ConstEvaluatable(..)) |
|
||||||
ObjectSafe(..) |
|
ObjectSafe(..) |
|
||||||
ClosureKind(..) |
|
ClosureKind(..) |
|
||||||
Subtype(..) |
|
Subtype(..) |
|
||||||
Coerce(..) |
|
Coerce(..) |
|
||||||
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
|
||||||
ConstEvaluatable(..) |
|
|
||||||
ConstEquate(..) |
|
ConstEquate(..) |
|
||||||
Ambiguous |
|
Ambiguous |
|
||||||
TypeWellFormedFromEnv(..) => continue,
|
TypeWellFormedFromEnv(..) => continue,
|
||||||
|
|
|
@ -270,14 +270,14 @@ impl FlagComputation {
|
||||||
self.add_alias_ty(projection_ty);
|
self.add_alias_ty(projection_ty);
|
||||||
self.add_term(term);
|
self.add_term(term);
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
self.add_substs(slice::from_ref(&arg));
|
self.add_substs(slice::from_ref(&arg));
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ObjectSafe(_def_id) => {}
|
ty::PredicateKind::ObjectSafe(_def_id) => {}
|
||||||
ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => {
|
ty::PredicateKind::ClosureKind(_def_id, substs, _kind) => {
|
||||||
self.add_substs(substs);
|
self.add_substs(substs);
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => {
|
||||||
self.add_const(uv);
|
self.add_const(uv);
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEquate(expected, found) => {
|
ty::PredicateKind::ConstEquate(expected, found) => {
|
||||||
|
|
|
@ -523,7 +523,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
|
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
|
||||||
tcx.trait_is_coinductive(data.def_id())
|
tcx.trait_is_coinductive(data.def_id())
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(_) => true,
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(_)) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,7 +536,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn allow_normalization(self) -> bool {
|
pub fn allow_normalization(self) -> bool {
|
||||||
match self.kind().skip_binder() {
|
match self.kind().skip_binder() {
|
||||||
PredicateKind::WellFormed(_) => false,
|
PredicateKind::Clause(Clause::WellFormed(_)) => false,
|
||||||
PredicateKind::Clause(Clause::Trait(_))
|
PredicateKind::Clause(Clause::Trait(_))
|
||||||
| PredicateKind::Clause(Clause::RegionOutlives(_))
|
| PredicateKind::Clause(Clause::RegionOutlives(_))
|
||||||
| PredicateKind::Clause(Clause::TypeOutlives(_))
|
| PredicateKind::Clause(Clause::TypeOutlives(_))
|
||||||
|
@ -547,7 +547,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateKind::ClosureKind(_, _, _)
|
| PredicateKind::ClosureKind(_, _, _)
|
||||||
| PredicateKind::Subtype(_)
|
| PredicateKind::Subtype(_)
|
||||||
| PredicateKind::Coerce(_)
|
| PredicateKind::Coerce(_)
|
||||||
| PredicateKind::ConstEvaluatable(_)
|
| PredicateKind::Clause(Clause::ConstEvaluatable(_))
|
||||||
| PredicateKind::ConstEquate(_, _)
|
| PredicateKind::ConstEquate(_, _)
|
||||||
| PredicateKind::Ambiguous
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(_) => true,
|
| PredicateKind::TypeWellFormedFromEnv(_) => true,
|
||||||
|
@ -584,6 +584,12 @@ pub enum Clause<'tcx> {
|
||||||
/// Ensures that a const generic argument to a parameter `const N: u8`
|
/// Ensures that a const generic argument to a parameter `const N: u8`
|
||||||
/// is of type `u8`.
|
/// is of type `u8`.
|
||||||
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
ConstArgHasType(Const<'tcx>, Ty<'tcx>),
|
||||||
|
|
||||||
|
/// No syntax: `T` well-formed.
|
||||||
|
WellFormed(GenericArg<'tcx>),
|
||||||
|
|
||||||
|
/// Constant initializer must evaluate successfully.
|
||||||
|
ConstEvaluatable(ty::Const<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Binder<'tcx, Clause<'tcx>> {
|
impl<'tcx> Binder<'tcx, Clause<'tcx>> {
|
||||||
|
@ -610,9 +616,6 @@ pub enum PredicateKind<'tcx> {
|
||||||
/// Prove a clause
|
/// Prove a clause
|
||||||
Clause(Clause<'tcx>),
|
Clause(Clause<'tcx>),
|
||||||
|
|
||||||
/// No syntax: `T` well-formed.
|
|
||||||
WellFormed(GenericArg<'tcx>),
|
|
||||||
|
|
||||||
/// Trait must be object-safe.
|
/// Trait must be object-safe.
|
||||||
ObjectSafe(DefId),
|
ObjectSafe(DefId),
|
||||||
|
|
||||||
|
@ -638,9 +641,6 @@ pub enum PredicateKind<'tcx> {
|
||||||
/// logic.
|
/// logic.
|
||||||
Coerce(CoercePredicate<'tcx>),
|
Coerce(CoercePredicate<'tcx>),
|
||||||
|
|
||||||
/// Constant initializer must evaluate successfully.
|
|
||||||
ConstEvaluatable(ty::Const<'tcx>),
|
|
||||||
|
|
||||||
/// Constants must be equal. The first component is the const that is expected.
|
/// Constants must be equal. The first component is the const that is expected.
|
||||||
ConstEquate(Const<'tcx>, Const<'tcx>),
|
ConstEquate(Const<'tcx>, Const<'tcx>),
|
||||||
|
|
||||||
|
@ -1324,11 +1324,11 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
| PredicateKind::Coerce(..)
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
||||||
| PredicateKind::WellFormed(..)
|
| PredicateKind::Clause(Clause::WellFormed(..))
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
| PredicateKind::ClosureKind(..)
|
| PredicateKind::ClosureKind(..)
|
||||||
| PredicateKind::Clause(Clause::TypeOutlives(..))
|
| PredicateKind::Clause(Clause::TypeOutlives(..))
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::Clause(Clause::ConstEvaluatable(..))
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
| PredicateKind::Ambiguous
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
@ -1345,11 +1345,11 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
| PredicateKind::Coerce(..)
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
||||||
| PredicateKind::WellFormed(..)
|
| PredicateKind::Clause(Clause::WellFormed(..))
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
| PredicateKind::ClosureKind(..)
|
| PredicateKind::ClosureKind(..)
|
||||||
| PredicateKind::Clause(Clause::TypeOutlives(..))
|
| PredicateKind::Clause(Clause::TypeOutlives(..))
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::Clause(Clause::ConstEvaluatable(..))
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
| PredicateKind::Ambiguous
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
@ -1367,10 +1367,10 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
| PredicateKind::Coerce(..)
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
| PredicateKind::Clause(Clause::RegionOutlives(..))
|
||||||
| PredicateKind::WellFormed(..)
|
| PredicateKind::Clause(Clause::WellFormed(..))
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
| PredicateKind::ClosureKind(..)
|
| PredicateKind::ClosureKind(..)
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
| PredicateKind::Clause(Clause::ConstEvaluatable(..))
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
| PredicateKind::Ambiguous
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
@ -1384,10 +1384,8 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
PredicateKind::AliasRelate(..)
|
PredicateKind::AliasRelate(..)
|
||||||
| PredicateKind::Subtype(..)
|
| PredicateKind::Subtype(..)
|
||||||
| PredicateKind::Coerce(..)
|
| PredicateKind::Coerce(..)
|
||||||
| PredicateKind::WellFormed(..)
|
|
||||||
| PredicateKind::ObjectSafe(..)
|
| PredicateKind::ObjectSafe(..)
|
||||||
| PredicateKind::ClosureKind(..)
|
| PredicateKind::ClosureKind(..)
|
||||||
| PredicateKind::ConstEvaluatable(..)
|
|
||||||
| PredicateKind::ConstEquate(..)
|
| PredicateKind::ConstEquate(..)
|
||||||
| PredicateKind::Ambiguous
|
| PredicateKind::Ambiguous
|
||||||
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
|
|
@ -2877,7 +2877,7 @@ define_print_and_forward_display! {
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
|
||||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||||
},
|
},
|
||||||
ty::PredicateKind::WellFormed(arg) => p!(print(arg), " well-formed"),
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => p!(print(arg), " well-formed"),
|
||||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||||
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
p!("the trait `", print_def_path(trait_def_id, &[]), "` is object-safe")
|
||||||
}
|
}
|
||||||
|
@ -2886,7 +2886,7 @@ define_print_and_forward_display! {
|
||||||
print_value_path(closure_def_id, &[]),
|
print_value_path(closure_def_id, &[]),
|
||||||
write("` implements the trait `{}`", kind)
|
write("` implements the trait `{}`", kind)
|
||||||
),
|
),
|
||||||
ty::PredicateKind::ConstEvaluatable(ct) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => {
|
||||||
p!("the constant `", print(ct), "` can be evaluated")
|
p!("the constant `", print(ct), "` can be evaluated")
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEquate(c1, c2) => {
|
ty::PredicateKind::ConstEquate(c1, c2) => {
|
||||||
|
|
|
@ -179,6 +179,10 @@ impl<'tcx> fmt::Debug for ty::Clause<'tcx> {
|
||||||
ty::Clause::RegionOutlives(ref pair) => pair.fmt(f),
|
ty::Clause::RegionOutlives(ref pair) => pair.fmt(f),
|
||||||
ty::Clause::TypeOutlives(ref pair) => pair.fmt(f),
|
ty::Clause::TypeOutlives(ref pair) => pair.fmt(f),
|
||||||
ty::Clause::Projection(ref pair) => pair.fmt(f),
|
ty::Clause::Projection(ref pair) => pair.fmt(f),
|
||||||
|
ty::Clause::WellFormed(ref data) => write!(f, "WellFormed({:?})", data),
|
||||||
|
ty::Clause::ConstEvaluatable(ct) => {
|
||||||
|
write!(f, "ConstEvaluatable({ct:?})")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,16 +193,12 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> {
|
||||||
ty::PredicateKind::Clause(ref a) => a.fmt(f),
|
ty::PredicateKind::Clause(ref a) => a.fmt(f),
|
||||||
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
|
ty::PredicateKind::Subtype(ref pair) => pair.fmt(f),
|
||||||
ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
|
ty::PredicateKind::Coerce(ref pair) => pair.fmt(f),
|
||||||
ty::PredicateKind::WellFormed(data) => write!(f, "WellFormed({:?})", data),
|
|
||||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||||
write!(f, "ObjectSafe({:?})", trait_def_id)
|
write!(f, "ObjectSafe({:?})", trait_def_id)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
|
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind) => {
|
||||||
write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
|
write!(f, "ClosureKind({:?}, {:?}, {:?})", closure_def_id, closure_substs, kind)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEvaluatable(ct) => {
|
|
||||||
write!(f, "ConstEvaluatable({ct:?})")
|
|
||||||
}
|
|
||||||
ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
|
ty::PredicateKind::ConstEquate(c1, c2) => write!(f, "ConstEquate({:?}, {:?})", c1, c2),
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(ty) => {
|
||||||
write!(f, "TypeWellFormedFromEnv({:?})", ty)
|
write!(f, "TypeWellFormedFromEnv({:?})", ty)
|
||||||
|
|
|
@ -182,8 +182,8 @@ where
|
||||||
ct.visit_with(self)?;
|
ct.visit_with(self)?;
|
||||||
ty.visit_with(self)
|
ty.visit_with(self)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEvaluatable(ct) => ct.visit_with(self),
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => ct.visit_with(self),
|
||||||
ty::PredicateKind::WellFormed(arg) => arg.visit_with(self),
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => arg.visit_with(self),
|
||||||
|
|
||||||
ty::PredicateKind::ObjectSafe(_)
|
ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(_, _, _)
|
| ty::PredicateKind::ClosureKind(_, _, _)
|
||||||
|
|
|
@ -319,14 +319,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
ty::PredicateKind::ObjectSafe(trait_def_id) => {
|
||||||
self.compute_object_safe_goal(trait_def_id)
|
self.compute_object_safe_goal(trait_def_id)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
|
self.compute_well_formed_goal(Goal { param_env, predicate: arg })
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Ambiguous => {
|
ty::PredicateKind::Ambiguous => {
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||||
}
|
}
|
||||||
// FIXME: implement this predicate :)
|
// FIXME: implement this predicate :)
|
||||||
ty::PredicateKind::ConstEvaluatable(_) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(_)) => {
|
||||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::ConstEquate(_, _) => {
|
ty::PredicateKind::ConstEquate(_, _) => {
|
||||||
|
|
|
@ -119,10 +119,8 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(_)
|
ty::PredicateKind::Clause(_)
|
||||||
| ty::PredicateKind::WellFormed(_)
|
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(_, _, _)
|
| ty::PredicateKind::ClosureKind(_, _, _)
|
||||||
| ty::PredicateKind::ConstEvaluatable(_)
|
|
||||||
| ty::PredicateKind::Ambiguous => {
|
| ty::PredicateKind::Ambiguous => {
|
||||||
FulfillmentErrorCode::CodeSelectionError(
|
FulfillmentErrorCode::CodeSelectionError(
|
||||||
SelectionError::Unimplemented,
|
SelectionError::Unimplemented,
|
||||||
|
|
|
@ -826,14 +826,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
// we start out with a `ParamEnv` with no inference variables,
|
// we start out with a `ParamEnv` with no inference variables,
|
||||||
// and these don't correspond to adding any new bounds to
|
// and these don't correspond to adding any new bounds to
|
||||||
// the `ParamEnv`.
|
// the `ParamEnv`.
|
||||||
ty::PredicateKind::WellFormed(..)
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
|
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::Coerce(..) => {}
|
| ty::PredicateKind::Coerce(..) => {}
|
||||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
bug!("predicate should only exist in the environment: {bound_predicate:?}")
|
bug!("predicate should only exist in the environment: {bound_predicate:?}")
|
||||||
|
|
|
@ -207,7 +207,7 @@ fn satisfied_from_param_env<'tcx>(
|
||||||
|
|
||||||
for pred in param_env.caller_bounds() {
|
for pred in param_env.caller_bounds() {
|
||||||
match pred.kind().skip_binder() {
|
match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::ConstEvaluatable(ce) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ce)) => {
|
||||||
let b_ct = tcx.expand_abstract_consts(ce);
|
let b_ct = tcx.expand_abstract_consts(ce);
|
||||||
let mut v = Visitor { ct, infcx, param_env, single_match };
|
let mut v = Visitor { ct, infcx, param_env, single_match };
|
||||||
let _ = b_ct.visit_with(&mut v);
|
let _ = b_ct.visit_with(&mut v);
|
||||||
|
|
|
@ -1048,7 +1048,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
self.report_closure_error(&obligation, closure_def_id, found_kind, kind)
|
self.report_closure_error(&obligation, closure_def_id, found_kind, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::WellFormed(ty) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(ty)) => {
|
||||||
match self.tcx.sess.opts.unstable_opts.trait_solver {
|
match self.tcx.sess.opts.unstable_opts.trait_solver {
|
||||||
TraitSolver::Classic => {
|
TraitSolver::Classic => {
|
||||||
// WF predicates cannot themselves make
|
// WF predicates cannot themselves make
|
||||||
|
@ -1069,7 +1069,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::ConstEvaluatable(..) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => {
|
||||||
// Errors for `ConstEvaluatable` predicates show up as
|
// Errors for `ConstEvaluatable` predicates show up as
|
||||||
// `SelectionError::ConstEvalFailure`,
|
// `SelectionError::ConstEvalFailure`,
|
||||||
// not `Unimplemented`.
|
// not `Unimplemented`.
|
||||||
|
@ -2415,7 +2415,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
// Same hacky approach as above to avoid deluging user
|
// Same hacky approach as above to avoid deluging user
|
||||||
// with error messages.
|
// with error messages.
|
||||||
if arg.references_error()
|
if arg.references_error()
|
||||||
|
@ -2487,7 +2487,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::ConstEvaluatable(data) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(data)) => {
|
||||||
if predicate.references_error() || self.tainted_by_errors().is_some() {
|
if predicate.references_error() || self.tainted_by_errors().is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3325,7 +3325,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match obligation.predicate.kind().skip_binder() {
|
match obligation.predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::ConstEvaluatable(ct) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => {
|
||||||
let ty::ConstKind::Unevaluated(uv) = ct.kind() else {
|
let ty::ConstKind::Unevaluated(uv) = ct.kind() else {
|
||||||
bug!("const evaluatable failed for non-unevaluated const `{ct:?}`");
|
bug!("const evaluatable failed for non-unevaluated const `{ct:?}`");
|
||||||
};
|
};
|
||||||
|
|
|
@ -354,12 +354,12 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_))
|
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::WellFormed(_)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(_))
|
||||||
| ty::PredicateKind::ObjectSafe(_)
|
| ty::PredicateKind::ObjectSafe(_)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
| ty::PredicateKind::Coerce(_)
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..) => {
|
||||||
let pred =
|
let pred =
|
||||||
ty::Binder::dummy(infcx.instantiate_binder_with_placeholders(binder));
|
ty::Binder::dummy(infcx.instantiate_binder_with_placeholders(binder));
|
||||||
|
@ -433,7 +433,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
match wf::obligations(
|
match wf::obligations(
|
||||||
self.selcx.infcx,
|
self.selcx.infcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
|
@ -498,7 +498,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => {
|
||||||
match const_evaluatable::is_const_evaluatable(
|
match const_evaluatable::is_const_evaluatable(
|
||||||
self.selcx.infcx,
|
self.selcx.infcx,
|
||||||
uv,
|
uv,
|
||||||
|
|
|
@ -310,7 +310,7 @@ fn predicate_references_self<'tcx>(
|
||||||
|
|
||||||
ty::PredicateKind::AliasRelate(..) => bug!("`AliasRelate` not allowed as assumption"),
|
ty::PredicateKind::AliasRelate(..) => bug!("`AliasRelate` not allowed as assumption"),
|
||||||
|
|
||||||
ty::PredicateKind::WellFormed(..)
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
|
@ -318,7 +318,7 @@ fn predicate_references_self<'tcx>(
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
// FIXME(generic_const_exprs): this can mention `Self`
|
// FIXME(generic_const_exprs): this can mention `Self`
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
|
||||||
|
@ -361,11 +361,11 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
|
|
|
@ -67,7 +67,8 @@ fn relate_mir_and_user_ty<'tcx>(
|
||||||
ocx.eq(&cause, param_env, mir_ty, user_ty)?;
|
ocx.eq(&cause, param_env, mir_ty, user_ty)?;
|
||||||
|
|
||||||
// FIXME(#104764): We should check well-formedness before normalization.
|
// FIXME(#104764): We should check well-formedness before normalization.
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(user_ty.into()));
|
let predicate =
|
||||||
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(user_ty.into())));
|
||||||
ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate));
|
ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,9 @@ fn relate_mir_and_user_substs<'tcx>(
|
||||||
let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
|
let impl_self_ty = ocx.normalize(&cause, param_env, impl_self_ty);
|
||||||
|
|
||||||
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
|
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()));
|
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
|
||||||
|
impl_self_ty.into(),
|
||||||
|
)));
|
||||||
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
|
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +137,7 @@ fn relate_mir_and_user_substs<'tcx>(
|
||||||
// them? This would only be relevant if some input
|
// them? This would only be relevant if some input
|
||||||
// type were ill-formed but did not appear in `ty`,
|
// type were ill-formed but did not appear in `ty`,
|
||||||
// which...could happen with normalization...
|
// which...could happen with normalization...
|
||||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()));
|
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(ty.into())));
|
||||||
ocx.register_obligation(Obligation::new(tcx, cause, param_env, predicate));
|
ocx.register_obligation(Obligation::new(tcx, cause, param_env, predicate));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,14 +130,14 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
||||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {}
|
||||||
|
|
||||||
// We need to search through *all* WellFormed predicates
|
// We need to search through *all* WellFormed predicates
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
wf_args.push(arg);
|
wf_args.push(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -674,7 +674,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
// So, there is a bit going on here. First, `WellFormed` predicates
|
// So, there is a bit going on here. First, `WellFormed` predicates
|
||||||
// are coinductive, like trait predicates with auto traits.
|
// are coinductive, like trait predicates with auto traits.
|
||||||
// This means that we need to detect if we have recursively
|
// This means that we need to detect if we have recursively
|
||||||
|
@ -862,7 +862,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::ConstEvaluatable(uv) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(uv)) => {
|
||||||
match const_evaluatable::is_const_evaluatable(
|
match const_evaluatable::is_const_evaluatable(
|
||||||
self.infcx,
|
self.infcx,
|
||||||
uv,
|
uv,
|
||||||
|
|
|
@ -160,11 +160,11 @@ pub fn predicate_obligations<'tcx>(
|
||||||
wf.compute(ct.into());
|
wf.compute(ct.into());
|
||||||
wf.compute(ty.into());
|
wf.compute(ty.into());
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => {
|
||||||
wf.compute(arg);
|
wf.compute(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::PredicateKind::ConstEvaluatable(ct) => {
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(ct)) => {
|
||||||
wf.compute(ct.into());
|
wf.compute(ct.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -386,7 +386,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
cause,
|
cause,
|
||||||
depth,
|
depth,
|
||||||
param_env,
|
param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -478,7 +478,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
depth,
|
depth,
|
||||||
param_env,
|
param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(arg))),
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -521,8 +521,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
let obligations = self.nominal_obligations(uv.def, uv.substs);
|
let obligations = self.nominal_obligations(uv.def, uv.substs);
|
||||||
self.out.extend(obligations);
|
self.out.extend(obligations);
|
||||||
|
|
||||||
let predicate =
|
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct));
|
ty::Clause::ConstEvaluatable(ct),
|
||||||
|
));
|
||||||
let cause = self.cause(traits::WellFormed(None));
|
let cause = self.cause(traits::WellFormed(None));
|
||||||
self.out.push(traits::Obligation::with_depth(
|
self.out.push(traits::Obligation::with_depth(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
|
@ -541,7 +542,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
cause,
|
cause,
|
||||||
self.recursion_depth,
|
self.recursion_depth,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())),
|
ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||||
|
ty::Clause::WellFormed(ct.into()),
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
ty::ConstKind::Expr(_) => {
|
ty::ConstKind::Expr(_) => {
|
||||||
|
@ -552,8 +555,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
// the future we may allow directly lowering to `ConstKind::Expr` in which case
|
// the future we may allow directly lowering to `ConstKind::Expr` in which case
|
||||||
// we would not be proving bounds we should.
|
// we would not be proving bounds we should.
|
||||||
|
|
||||||
let predicate =
|
let predicate = ty::Binder::dummy(ty::PredicateKind::Clause(
|
||||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct));
|
ty::Clause::ConstEvaluatable(ct),
|
||||||
|
));
|
||||||
let cause = self.cause(traits::WellFormed(None));
|
let cause = self.cause(traits::WellFormed(None));
|
||||||
self.out.push(traits::Obligation::with_depth(
|
self.out.push(traits::Obligation::with_depth(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
|
@ -784,7 +788,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||||
cause,
|
cause,
|
||||||
self.recursion_depth,
|
self.recursion_depth,
|
||||||
param_env,
|
param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::WellFormed(
|
||||||
|
ty.into(),
|
||||||
|
))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -969,11 +975,11 @@ pub(crate) fn required_region_bounds<'tcx>(
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
predicate.lower_into(interner),
|
predicate.lower_into(interner),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => match arg.unpack() {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => match arg.unpack() {
|
||||||
ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed(
|
ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed(
|
||||||
chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
|
chalk_ir::WellFormed::Ty(ty.lower_into(interner)),
|
||||||
),
|
),
|
||||||
|
@ -137,7 +137,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
| ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate),
|
||||||
};
|
};
|
||||||
|
@ -192,7 +192,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
||||||
chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)),
|
chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(arg) => match arg.unpack() {
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(arg)) => match arg.unpack() {
|
||||||
GenericArgKind::Type(ty) => match ty.kind() {
|
GenericArgKind::Type(ty) => match ty.kind() {
|
||||||
// FIXME(chalk): In Chalk, a placeholder is WellFormed if it
|
// FIXME(chalk): In Chalk, a placeholder is WellFormed if it
|
||||||
// `FromEnv`. However, when we "lower" Params, we don't update
|
// `FromEnv`. However, when we "lower" Params, we don't update
|
||||||
|
@ -231,7 +231,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..) => {
|
||||||
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner))
|
||||||
|
@ -672,7 +672,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
||||||
ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) => {
|
ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) => {
|
||||||
Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)))
|
Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(_ty) => None,
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(_ty)) => None,
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
||||||
|
|
||||||
ty::PredicateKind::ObjectSafe(..)
|
ty::PredicateKind::ObjectSafe(..)
|
||||||
|
@ -680,7 +680,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
|
@ -807,7 +807,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_predicate)) => None,
|
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_predicate)) => None,
|
||||||
ty::PredicateKind::WellFormed(_ty) => None,
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(_ty)) => None,
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
||||||
|
|
||||||
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
|
||||||
|
@ -816,7 +816,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||||
|
|
|
@ -62,12 +62,12 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
|
||||||
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
|
||||||
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::WellFormed(..)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(..))
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
| ty::PredicateKind::ClosureKind(..)
|
| ty::PredicateKind::ClosureKind(..)
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::Ambiguous
|
| ty::PredicateKind::Ambiguous
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => true,
|
||||||
|
|
|
@ -344,8 +344,8 @@ pub(crate) fn clean_predicate<'tcx>(
|
||||||
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
|
Some(clean_projection_predicate(bound_predicate.rebind(pred), cx))
|
||||||
}
|
}
|
||||||
// FIXME(generic_const_exprs): should this do something?
|
// FIXME(generic_const_exprs): should this do something?
|
||||||
ty::PredicateKind::ConstEvaluatable(..) => None,
|
ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..)) => None,
|
||||||
ty::PredicateKind::WellFormed(..) => None,
|
ty::PredicateKind::Clause(ty::Clause::WellFormed(..)) => None,
|
||||||
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) => None,
|
||||||
|
|
||||||
ty::PredicateKind::Subtype(..)
|
ty::PredicateKind::Subtype(..)
|
||||||
|
|
|
@ -33,8 +33,8 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv)
|
||||||
| ty::Clause::Trait(..)
|
| ty::Clause::Trait(..)
|
||||||
| ty::Clause::ConstArgHasType(..),
|
| ty::Clause::ConstArgHasType(..),
|
||||||
)
|
)
|
||||||
| ty::PredicateKind::WellFormed(_)
|
| ty::PredicateKind::Clause(ty::Clause::WellFormed(_))
|
||||||
| ty::PredicateKind::ConstEvaluatable(..)
|
| ty::PredicateKind::Clause(ty::Clause::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
| ty::PredicateKind::TypeWellFormedFromEnv(..) => continue,
|
||||||
ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"),
|
ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue