Auto merge of #104902 - matthiaskrgr:rollup-oo27a4u, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #104716 (move 2 candidates into builtin candidate) - #104760 (Clarify `SyntaxExtensionKind::LegacyDerive`.) - #104797 (rustc_codegen_ssa: write `.dwp` in a streaming fashion) - #104835 (Use infcx.partially_normalize_associated_types_in) - #104853 (Fix typo in miri sysroot) - #104879 (jsondoclint: Recognise Typedef as valid kind for Type::ResolvedPath) - #104887 (rustbuild: Don't build doc::SharedAssets when building JSON docs.) - #104896 (rustdoc: fix broken tooltip CSS) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
8681d4cffc
22 changed files with 248 additions and 297 deletions
|
@ -11,8 +11,7 @@ use super::Selection;
|
|||
use super::SelectionContext;
|
||||
use super::SelectionError;
|
||||
use super::{
|
||||
ImplSourceClosureData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
|
||||
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourcePointeeData,
|
||||
ImplSourceClosureData, ImplSourceFnPointerData, ImplSourceFutureData, ImplSourceGeneratorData,
|
||||
ImplSourceUserDefinedData,
|
||||
};
|
||||
use super::{Normalized, NormalizedTy, ProjectionCacheEntry, ProjectionCacheKey};
|
||||
|
@ -29,6 +28,7 @@ use rustc_hir::def::DefKind;
|
|||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::traits::ImplSourceBuiltinData;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable};
|
||||
|
@ -1599,128 +1599,126 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
}
|
||||
}
|
||||
}
|
||||
super::ImplSource::DiscriminantKind(..) => {
|
||||
// While `DiscriminantKind` is automatically implemented for every type,
|
||||
// the concrete discriminant may not be known yet.
|
||||
//
|
||||
// Any type with multiple potential discriminant types is therefore not eligible.
|
||||
super::ImplSource::Builtin(..) => {
|
||||
// While a builtin impl may be known to exist, the associated type may not yet
|
||||
// be known. Any type with multiple potential associated types is therefore
|
||||
// not eligible.
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
match self_ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Adt(..)
|
||||
| ty::Foreign(_)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(..)
|
||||
// Integers and floats always have `u8` as their discriminant.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
let lang_items = selcx.tcx().lang_items();
|
||||
if lang_items.discriminant_kind_trait() == Some(poly_trait_ref.def_id()) {
|
||||
match self_ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Adt(..)
|
||||
| ty::Foreign(_)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Never
|
||||
| ty::Tuple(..)
|
||||
// Integers and floats always have `u8` as their discriminant.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
|
||||
ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Param(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(_) => false,
|
||||
}
|
||||
}
|
||||
super::ImplSource::Pointee(..) => {
|
||||
// While `Pointee` is automatically implemented for every type,
|
||||
// the concrete metadata type may not be known yet.
|
||||
//
|
||||
// Any type with multiple potential metadata types is therefore not eligible.
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let tail = selcx.tcx().struct_tail_with_normalize(
|
||||
self_ty,
|
||||
|ty| {
|
||||
// We throw away any obligations we get from this, since we normalize
|
||||
// and confirm these obligations once again during confirmation
|
||||
normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
ty,
|
||||
)
|
||||
.value
|
||||
},
|
||||
|| {},
|
||||
);
|
||||
|
||||
match tail.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Never
|
||||
// Extern types have unit metadata, according to RFC 2850
|
||||
| ty::Foreign(_)
|
||||
// If returned by `struct_tail_without_normalization` this is a unit struct
|
||||
// without any fields, or not a struct, and therefore is Sized.
|
||||
| ty::Adt(..)
|
||||
// If returned by `struct_tail_without_normalization` this is the empty tuple.
|
||||
| ty::Tuple(..)
|
||||
// Integers and floats are always Sized, and so have unit type metadata.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
|
||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref(
|
||||
LangItem::Sized,
|
||||
[self_ty],
|
||||
))
|
||||
.without_const(),
|
||||
),
|
||||
) =>
|
||||
{
|
||||
true
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(_) => false,
|
||||
}
|
||||
} else if lang_items.pointee_trait() == Some(poly_trait_ref.def_id()) {
|
||||
let tail = selcx.tcx().struct_tail_with_normalize(
|
||||
self_ty,
|
||||
|ty| {
|
||||
// We throw away any obligations we get from this, since we normalize
|
||||
// and confirm these obligations once again during confirmation
|
||||
normalize_with_depth(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
ty,
|
||||
)
|
||||
.value
|
||||
},
|
||||
|| {},
|
||||
);
|
||||
|
||||
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(_) => {
|
||||
if tail.has_infer_types() {
|
||||
candidate_set.mark_ambiguous();
|
||||
match tail.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
| ty::Uint(_)
|
||||
| ty::Float(_)
|
||||
| ty::Str
|
||||
| ty::Array(..)
|
||||
| ty::Slice(_)
|
||||
| ty::RawPtr(..)
|
||||
| ty::Ref(..)
|
||||
| ty::FnDef(..)
|
||||
| ty::FnPtr(..)
|
||||
| ty::Dynamic(..)
|
||||
| ty::Closure(..)
|
||||
| ty::Generator(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Never
|
||||
// Extern types have unit metadata, according to RFC 2850
|
||||
| ty::Foreign(_)
|
||||
// If returned by `struct_tail_without_normalization` this is a unit struct
|
||||
// without any fields, or not a struct, and therefore is Sized.
|
||||
| ty::Adt(..)
|
||||
// If returned by `struct_tail_without_normalization` this is the empty tuple.
|
||||
| ty::Tuple(..)
|
||||
// Integers and floats are always Sized, and so have unit type metadata.
|
||||
| ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
|
||||
|
||||
// type parameters, opaques, and unnormalized projections have pointer
|
||||
// metadata if they're known (e.g. by the param_env) to be sized
|
||||
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
|
||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::Binder::dummy(
|
||||
selcx.tcx().at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const(),
|
||||
),
|
||||
) =>
|
||||
{
|
||||
true
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): are Bound and Placeholder types ever known sized?
|
||||
ty::Param(_)
|
||||
| ty::Projection(..)
|
||||
| ty::Opaque(..)
|
||||
| ty::Bound(..)
|
||||
| ty::Placeholder(..)
|
||||
| ty::Infer(..)
|
||||
| ty::Error(_) => {
|
||||
if tail.has_infer_types() {
|
||||
candidate_set.mark_ambiguous();
|
||||
}
|
||||
false
|
||||
}
|
||||
false
|
||||
}
|
||||
} else {
|
||||
bug!("unexpected builtin trait with associated type: {poly_trait_ref:?}")
|
||||
}
|
||||
}
|
||||
super::ImplSource::Param(..) => {
|
||||
|
@ -1758,7 +1756,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
false
|
||||
}
|
||||
super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
// These traits have no associated types.
|
||||
|
@ -1838,14 +1835,10 @@ fn confirm_select_candidate<'cx, 'tcx>(
|
|||
super::ImplSource::Future(data) => confirm_future_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Closure(data) => confirm_closure_candidate(selcx, obligation, data),
|
||||
super::ImplSource::FnPointer(data) => confirm_fn_pointer_candidate(selcx, obligation, data),
|
||||
super::ImplSource::DiscriminantKind(data) => {
|
||||
confirm_discriminant_kind_candidate(selcx, obligation, data)
|
||||
}
|
||||
super::ImplSource::Pointee(data) => confirm_pointee_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Builtin(data) => confirm_builtin_candidate(selcx, obligation, data),
|
||||
super::ImplSource::Object(_)
|
||||
| super::ImplSource::AutoImpl(..)
|
||||
| super::ImplSource::Param(..)
|
||||
| super::ImplSource::Builtin(..)
|
||||
| super::ImplSource::TraitUpcasting(_)
|
||||
| super::ImplSource::TraitAlias(..)
|
||||
| super::ImplSource::ConstDestruct(_) => {
|
||||
|
@ -1951,68 +1944,55 @@ fn confirm_future_candidate<'cx, 'tcx>(
|
|||
.with_addl_obligations(obligations)
|
||||
}
|
||||
|
||||
fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
|
||||
fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
_: ImplSourceDiscriminantKindData,
|
||||
data: ImplSourceBuiltinData<PredicateObligation<'tcx>>,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
// with placeholders
|
||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||
let self_ty = obligation.predicate.self_ty();
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let lang_items = tcx.lang_items();
|
||||
let item_def_id = obligation.predicate.item_def_id;
|
||||
let trait_def_id = tcx.trait_of_item(item_def_id).unwrap();
|
||||
let (term, obligations) = if lang_items.discriminant_kind_trait() == Some(trait_def_id) {
|
||||
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
||||
assert_eq!(discriminant_def_id, item_def_id);
|
||||
|
||||
let discriminant_def_id = tcx.require_lang_item(LangItem::Discriminant, None);
|
||||
(self_ty.discriminant_ty(tcx).into(), Vec::new())
|
||||
} else if lang_items.pointee_trait() == Some(trait_def_id) {
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
|
||||
assert_eq!(metadata_def_id, item_def_id);
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: discriminant_def_id },
|
||||
term: self_ty.discriminant_ty(tcx).into(),
|
||||
let mut obligations = Vec::new();
|
||||
let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||
normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
ty,
|
||||
&mut obligations,
|
||||
)
|
||||
});
|
||||
if check_is_sized {
|
||||
let sized_predicate = ty::Binder::dummy(
|
||||
tcx.at(obligation.cause.span()).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const();
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
(metadata_ty.into(), obligations)
|
||||
} else {
|
||||
bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
|
||||
};
|
||||
|
||||
// We get here from `poly_project_and_unify_type` which replaces bound vars
|
||||
// with placeholders, so dummy is okay here.
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
}
|
||||
|
||||
fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
selcx: &mut SelectionContext<'cx, 'tcx>,
|
||||
obligation: &ProjectionTyObligation<'tcx>,
|
||||
_: ImplSourcePointeeData,
|
||||
) -> Progress<'tcx> {
|
||||
let tcx = selcx.tcx();
|
||||
let self_ty = selcx.infcx().shallow_resolve(obligation.predicate.self_ty());
|
||||
|
||||
let mut obligations = vec![];
|
||||
let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
|
||||
normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
ty,
|
||||
&mut obligations,
|
||||
)
|
||||
});
|
||||
if check_is_sized {
|
||||
let sized_predicate = ty::Binder::dummy(
|
||||
tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]),
|
||||
)
|
||||
.without_const();
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span));
|
||||
|
||||
let predicate = ty::ProjectionPredicate {
|
||||
projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id },
|
||||
term: metadata_ty.into(),
|
||||
};
|
||||
let predicate =
|
||||
ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id }, term };
|
||||
|
||||
confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
|
||||
.with_addl_obligations(obligations)
|
||||
.with_addl_obligations(data.nested)
|
||||
}
|
||||
|
||||
fn confirm_fn_pointer_candidate<'cx, 'tcx>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue