1
Fork 0

Auto merge of #104935 - matthiaskrgr:rollup-nuca86l, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #104121 (Refine `instruction_set` MIR inline rules)
 - #104675 (Unsupported query error now specifies if its unsupported for local or external crate)
 - #104839 (improve array_from_fn documenation)
 - #104880 ([llvm-wrapper] adapt for LLVM API change)
 - #104899 (rustdoc: remove no-op CSS `#help dt { display: block }`)
 - #104906 (Remove AscribeUserTypeCx)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-11-26 12:11:32 +00:00
commit 579c993b35
10 changed files with 149 additions and 141 deletions

View file

@ -627,7 +627,11 @@ LLVMRustOptimize(
bool DebugPassManager = false;
PassInstrumentationCallbacks PIC;
#if LLVM_VERSION_LT(16, 0)
StandardInstrumentations SI(DebugPassManager);
#else
StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
#endif
SI.registerCallbacks(PIC);
if (LlvmSelfProfiler){

View file

@ -276,13 +276,16 @@ macro_rules! define_callbacks {
impl Default for Providers {
fn default() -> Self {
use crate::query::Key;
Providers {
$($name: |_, key| bug!(
"`tcx.{}({:?})` is not supported for external or local crate;\n
hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported (likely the local crate).\n
"`tcx.{}({:?})` is not supported for {} crate;\n
hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.\n
If that's not the case, {} was likely never assigned to a provider function.\n",
stringify!($name),
key,
if key.query_crate_is_local() { "local" } else { "external" },
stringify!($name),
),)*
}

View file

@ -375,7 +375,12 @@ impl<'tcx> Inliner<'tcx> {
return Err("incompatible sanitizer set");
}
if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set {
// Two functions are compatible if the callee has no attribute (meaning
// that it's codegen agnostic), or sets an attribute that is identical
// to this function's attribute.
if callee_attrs.instruction_set.is_some()
&& callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set
{
return Err("incompatible instruction set");
}
@ -453,6 +458,15 @@ impl<'tcx> Inliner<'tcx> {
if ty.needs_drop(tcx, self.param_env) && let Some(unwind) = unwind {
work_list.push(unwind);
}
} else if callee_attrs.instruction_set != self.codegen_fn_attrs.instruction_set
&& matches!(term.kind, TerminatorKind::InlineAsm { .. })
{
// During the attribute checking stage we allow a callee with no
// instruction_set assigned to count as compatible with a function that does
// assign one. However, during this stage we require an exact match when any
// inline-asm is detected. LLVM will still possibly do an inline later on
// if the no-attribute function ends up with the same instruction set anyway.
return Err("Cannot move inline-asm across instruction sets");
} else {
work_list.extend(term.successors())
}

View file

@ -20,6 +20,7 @@ extern crate rustc_middle;
use rustc_data_structures::sync::AtomicU64;
use rustc_middle::arena::Arena;
use rustc_middle::dep_graph::{self, DepKindStruct};
use rustc_middle::query::Key;
use rustc_middle::ty::query::{query_keys, query_storage, query_stored, query_values};
use rustc_middle::ty::query::{ExternProviders, Providers, QueryEngine};
use rustc_middle::ty::TyCtxt;
@ -32,8 +33,6 @@ use rustc_query_system::query::*;
#[cfg(parallel_compiler)]
pub use rustc_query_system::query::{deadlock, QueryContext};
use rustc_middle::query::Key;
pub use rustc_query_system::query::QueryConfig;
pub(crate) use rustc_query_system::query::QueryVTable;

View file

@ -1,6 +1,4 @@
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::at::ToTrace;
use rustc_infer::infer::canonical::{Canonical, QueryResponse};
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
use rustc_infer::traits::ObligationCauseCode;
@ -57,122 +55,67 @@ pub fn type_op_ascribe_user_type_with_span<'tcx>(
"type_op_ascribe_user_type: mir_ty={:?} def_id={:?} user_substs={:?}",
mir_ty, def_id, user_substs
);
let cx = AscribeUserTypeCx { ocx, param_env, span: span.unwrap_or(DUMMY_SP) };
cx.relate_mir_and_user_ty(mir_ty, def_id, user_substs)?;
Ok(())
}
let span = span.unwrap_or(DUMMY_SP);
struct AscribeUserTypeCx<'me, 'tcx> {
ocx: &'me ObligationCtxt<'me, 'tcx>,
param_env: ty::ParamEnv<'tcx>,
span: Span,
}
let UserSubsts { user_self_ty, substs } = user_substs;
let tcx = ocx.infcx.tcx;
let cause = ObligationCause::dummy_with_span(span);
impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
fn normalize<T>(&self, value: T) -> T
where
T: TypeFoldable<'tcx>,
let ty = tcx.bound_type_of(def_id).subst(tcx, substs);
let ty = ocx.normalize(cause.clone(), param_env, ty);
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
ocx.eq(&cause, param_env, mir_ty, ty)?;
// Prove the predicates coming along with `def_id`.
//
// Also, normalize the `instantiated_predicates`
// because otherwise we wind up with duplicate "type
// outlives" error messages.
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
debug!(?instantiated_predicates);
for (instantiated_predicate, predicate_span) in
zip(instantiated_predicates.predicates, instantiated_predicates.spans)
{
self.normalize_with_cause(value, ObligationCause::misc(self.span, hir::CRATE_HIR_ID))
}
fn normalize_with_cause<T>(&self, value: T, cause: ObligationCause<'tcx>) -> T
where
T: TypeFoldable<'tcx>,
{
self.ocx.normalize(cause, self.param_env, value)
}
fn eq<T>(&self, a: T, b: T) -> Result<(), NoSolution>
where
T: ToTrace<'tcx>,
{
Ok(self.ocx.eq(&ObligationCause::dummy_with_span(self.span), self.param_env, a, b)?)
}
fn prove_predicate(&self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) {
self.ocx.register_obligation(Obligation::new(
self.ocx.infcx.tcx,
cause,
self.param_env,
predicate,
));
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.ocx.infcx.tcx
}
#[instrument(level = "debug", skip(self))]
fn relate_mir_and_user_ty(
&self,
mir_ty: Ty<'tcx>,
def_id: DefId,
user_substs: UserSubsts<'tcx>,
) -> Result<(), NoSolution> {
let UserSubsts { user_self_ty, substs } = user_substs;
let tcx = self.tcx();
let ty = tcx.bound_type_of(def_id).subst(tcx, substs);
let ty = self.normalize(ty);
debug!("relate_type_and_user_type: ty of def-id is {:?}", ty);
self.eq(mir_ty, ty)?;
// Prove the predicates coming along with `def_id`.
//
// Also, normalize the `instantiated_predicates`
// because otherwise we wind up with duplicate "type
// outlives" error messages.
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
let cause = ObligationCause::dummy_with_span(self.span);
debug!(?instantiated_predicates);
for (instantiated_predicate, predicate_span) in
zip(instantiated_predicates.predicates, instantiated_predicates.spans)
{
let span = if self.span == DUMMY_SP { predicate_span } else { self.span };
let cause = ObligationCause::new(
span,
hir::CRATE_HIR_ID,
ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
);
let instantiated_predicate =
self.normalize_with_cause(instantiated_predicate, cause.clone());
self.prove_predicate(instantiated_predicate, cause);
}
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs);
let impl_self_ty = self.normalize(impl_self_ty);
self.eq(self_ty, impl_self_ty)?;
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into()))
.to_predicate(tcx),
cause.clone(),
);
}
// In addition to proving the predicates, we have to
// prove that `ty` is well-formed -- this is because
// the WF of `ty` is predicated on the substs being
// well-formed, and we haven't proven *that*. We don't
// want to prove the WF of types from `substs` directly because they
// haven't been normalized.
//
// FIXME(nmatsakis): Well, perhaps we should normalize
// them? This would only be relevant if some input
// type were ill-formed but did not appear in `ty`,
// which...could happen with normalization...
self.prove_predicate(
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(tcx),
cause,
let span = if span == DUMMY_SP { predicate_span } else { span };
let cause = ObligationCause::new(
span,
hir::CRATE_HIR_ID,
ObligationCauseCode::AscribeUserTypeProvePredicate(predicate_span),
);
Ok(())
let instantiated_predicate =
ocx.normalize(cause.clone(), param_env, instantiated_predicate);
ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate));
}
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
let impl_self_ty = tcx.bound_type_of(impl_def_id).subst(tcx, substs);
let impl_self_ty = ocx.normalize(cause.clone(), param_env, impl_self_ty);
ocx.eq(&cause, param_env, self_ty, impl_self_ty)?;
let predicate: Predicate<'tcx> =
ty::Binder::dummy(ty::PredicateKind::WellFormed(impl_self_ty.into())).to_predicate(tcx);
ocx.register_obligation(Obligation::new(tcx, cause.clone(), param_env, predicate));
}
// In addition to proving the predicates, we have to
// prove that `ty` is well-formed -- this is because
// the WF of `ty` is predicated on the substs being
// well-formed, and we haven't proven *that*. We don't
// want to prove the WF of types from `substs` directly because they
// haven't been normalized.
//
// FIXME(nmatsakis): Well, perhaps we should normalize
// them? This would only be relevant if some input
// type were ill-formed but did not appear in `ty`,
// which...could happen with normalization...
let predicate: Predicate<'tcx> =
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())).to_predicate(tcx);
ocx.register_obligation(Obligation::new(tcx, cause, param_env, predicate));
Ok(())
}
fn type_op_eq<'tcx>(