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:
bors 2022-11-25 19:09:30 +00:00
commit 8681d4cffc
22 changed files with 248 additions and 297 deletions

View file

@ -9,6 +9,7 @@ use super::{
};
use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use crate::infer::InferCtxtExt as _;
use crate::infer::{self, InferCtxt, TyCtxtInferExt};
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use crate::traits::query::normalize::AtExt as _;
@ -28,7 +29,7 @@ use rustc_hir::GenericParam;
use rustc_hir::Item;
use rustc_hir::Node;
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::TypeTrace;
use rustc_infer::infer::{InferOk, TypeTrace};
use rustc_middle::traits::select::OverflowError;
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
use rustc_middle::ty::error::ExpectedFound;
@ -2530,18 +2531,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
self.probe(|_| {
let mut selcx = SelectionContext::new(self);
let cleaned_pred =
pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() });
let cleaned_pred = super::project::normalize(
&mut selcx,
param_env,
ObligationCause::dummy(),
cleaned_pred,
)
.value;
let InferOk { value: cleaned_pred, .. } =
self.infcx.partially_normalize_associated_types_in(
ObligationCause::dummy(),
param_env,
cleaned_pred,
);
let obligation =
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);

View file

@ -1,11 +1,7 @@
use super::{
DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation,
SelectionContext,
};
use super::{DefIdOrName, Obligation, ObligationCause, ObligationCauseCode, PredicateObligation};
use crate::autoderef::Autoderef;
use crate::infer::InferCtxt;
use crate::traits::normalize_to;
use hir::def::CtorOf;
use hir::HirId;
@ -23,7 +19,7 @@ use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::LateBoundRegionConversionTime;
use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
use rustc_middle::hir::map;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree,
@ -2979,13 +2975,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.tcx.mk_substs_trait(trait_pred.self_ty(), []),
)
});
let projection_ty = normalize_to(
&mut SelectionContext::new(self),
obligation.param_env,
obligation.cause.clone(),
projection_ty,
&mut vec![],
);
let InferOk { value: projection_ty, .. } = self
.partially_normalize_associated_types_in(
obligation.cause.clone(),
obligation.param_env,
projection_ty,
);
debug!(
normalized_projection_type = ?self.resolve_vars_if_possible(projection_ty)

View file

@ -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>(

View file

@ -282,10 +282,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
// `DiscriminantKind` is automatically implemented for every type.
candidates.vec.push(DiscriminantKindCandidate);
candidates.vec.push(BuiltinCandidate { has_nested: false });
} else if lang_items.pointee_trait() == Some(def_id) {
// `Pointee` is automatically implemented for every type.
candidates.vec.push(PointeeCandidate);
candidates.vec.push(BuiltinCandidate { has_nested: false });
} else if lang_items.sized_trait() == Some(def_id) {
// Sized is never implementable by end-users, it is
// always automatically computed.

View file

@ -22,12 +22,11 @@ use crate::traits::util::{self, closure_trait_ref_and_return_type, predicate_for
use crate::traits::{
BuiltinDerivedObligation, ImplDerivedObligation, ImplDerivedObligationCause, ImplSource,
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
ImplSourceConstDestructData, ImplSourceDiscriminantKindData, ImplSourceFnPointerData,
ImplSourceFutureData, ImplSourceGeneratorData, ImplSourceObjectData, ImplSourcePointeeData,
ImplSourceTraitAliasData, ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized,
ObjectCastObligation, Obligation, ObligationCause, OutputTypeParameterMismatch,
PredicateObligation, Selection, SelectionError, TraitNotObjectSafe, TraitObligation,
Unimplemented, VtblSegment,
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented, VtblSegment,
};
use super::BuiltinImplConditions;
@ -100,12 +99,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ImplSource::FnPointer(data)
}
DiscriminantKindCandidate => {
ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData)
}
PointeeCandidate => ImplSource::Pointee(ImplSourcePointeeData),
TraitAliasCandidate => {
let data = self.confirm_trait_alias_candidate(obligation);
ImplSource::TraitAlias(data)

View file

@ -1573,20 +1573,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
(TransmutabilityCandidate, _) | (_, TransmutabilityCandidate) => false,
// (*)
(
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
| PointeeCandidate
| ConstDestructCandidate(_),
_,
) => true,
(
_,
BuiltinCandidate { has_nested: false }
| DiscriminantKindCandidate
| PointeeCandidate
| ConstDestructCandidate(_),
) => false,
(BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_), _) => true,
(_, BuiltinCandidate { has_nested: false } | ConstDestructCandidate(_)) => false,
(ParamCandidate(other), ParamCandidate(victim)) => {
let same_except_bound_vars = other.skip_binder().trait_ref

View file

@ -8,7 +8,9 @@ use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable};
use rustc_middle::ty::{GenericArg, SubstsRef};
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
use super::{Obligation, ObligationCause, PredicateObligation, SelectionContext};
use crate::infer::InferCtxtExt;
use rustc_infer::infer::InferOk;
pub use rustc_infer::traits::{self, util::*};
///////////////////////////////////////////////////////////////////////////
@ -200,13 +202,15 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
) -> (ImplSubject<'tcx>, impl Iterator<Item = PredicateObligation<'tcx>>) {
let subject = selcx.tcx().bound_impl_subject(impl_def_id);
let subject = subject.subst(selcx.tcx(), impl_substs);
let Normalized { value: subject, obligations: normalization_obligations1 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), subject);
let InferOk { value: subject, obligations: normalization_obligations1 } = selcx
.infcx()
.partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, subject);
let predicates = selcx.tcx().predicates_of(impl_def_id);
let predicates = predicates.instantiate(selcx.tcx(), impl_substs);
let Normalized { value: predicates, obligations: normalization_obligations2 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
let InferOk { value: predicates, obligations: normalization_obligations2 } = selcx
.infcx()
.partially_normalize_associated_types_in(ObligationCause::dummy(), param_env, predicates);
let impl_obligations =
super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);