Auto merge of #105187 - matthiaskrgr:rollup-nxyxpko, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #105026 (v8a as default aarch64 target) - #105033 (sparc-struct-abi: work around new tail-call optimization) - #105144 (Document normalization methods `At::{normalize,query_normalize}`) - #105155 (rustdoc: clean up help and settings button CSS) - #105162 (Properly synthesize `FnSig` value during cycle) - #105163 (Check lifetime param count in `collect_trait_impl_trait_tys`) - #105185 (Move `normalize_fn_sig` to `TypeErrCtxt`) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
e526d123aa
19 changed files with 198 additions and 151 deletions
|
@ -494,6 +494,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
|
||||||
.flatten();
|
.flatten();
|
||||||
features.extend(feats);
|
features.extend(feats);
|
||||||
|
|
||||||
|
// FIXME: Move v8a to target definition list when earliest supported LLVM is 14.
|
||||||
|
if get_version() >= (14, 0, 0) && sess.target.arch == "aarch64" {
|
||||||
|
features.push("+v8a".into());
|
||||||
|
}
|
||||||
|
|
||||||
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
|
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
|
||||||
sess.emit_err(TargetFeatureDisableOrEnable {
|
sess.emit_err(TargetFeatureDisableOrEnable {
|
||||||
features: f,
|
features: f,
|
||||||
|
|
|
@ -173,13 +173,11 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
|
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
|
||||||
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
|
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
|
||||||
|
|
||||||
let impl_m_generics = tcx.generics_of(impl_m.def_id);
|
|
||||||
let trait_m_generics = tcx.generics_of(trait_m.def_id);
|
|
||||||
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
|
let impl_m_predicates = tcx.predicates_of(impl_m.def_id);
|
||||||
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
|
let trait_m_predicates = tcx.predicates_of(trait_m.def_id);
|
||||||
|
|
||||||
// Check region bounds.
|
// Check region bounds.
|
||||||
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, &trait_m_generics, &impl_m_generics)?;
|
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, false)?;
|
||||||
|
|
||||||
// Create obligations for each predicate declared by the impl
|
// Create obligations for each predicate declared by the impl
|
||||||
// definition in the context of the trait's parameter
|
// definition in the context of the trait's parameter
|
||||||
|
@ -338,6 +336,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||||
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
|
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
|
||||||
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
|
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?;
|
||||||
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
|
compare_generic_param_kinds(tcx, impl_m, trait_m, true)?;
|
||||||
|
check_region_bounds_on_impl_item(tcx, impl_m, trait_m, true)?;
|
||||||
|
|
||||||
let trait_to_impl_substs = impl_trait_ref.substs;
|
let trait_to_impl_substs = impl_trait_ref.substs;
|
||||||
|
|
||||||
|
@ -722,12 +721,14 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
impl_m: &ty::AssocItem,
|
impl_m: &ty::AssocItem,
|
||||||
trait_m: &ty::AssocItem,
|
trait_m: &ty::AssocItem,
|
||||||
trait_generics: &ty::Generics,
|
delay: bool,
|
||||||
impl_generics: &ty::Generics,
|
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
let trait_params = trait_generics.own_counts().lifetimes;
|
let impl_generics = tcx.generics_of(impl_m.def_id);
|
||||||
let impl_params = impl_generics.own_counts().lifetimes;
|
let impl_params = impl_generics.own_counts().lifetimes;
|
||||||
|
|
||||||
|
let trait_generics = tcx.generics_of(trait_m.def_id);
|
||||||
|
let trait_params = trait_generics.own_counts().lifetimes;
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"check_region_bounds_on_impl_item: \
|
"check_region_bounds_on_impl_item: \
|
||||||
trait_generics={:?} \
|
trait_generics={:?} \
|
||||||
|
@ -761,12 +762,16 @@ fn check_region_bounds_on_impl_item<'tcx>(
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let reported = tcx.sess.emit_err(LifetimesOrBoundsMismatchOnTrait {
|
let reported = tcx
|
||||||
span,
|
.sess
|
||||||
item_kind: assoc_item_kind_str(impl_m),
|
.create_err(LifetimesOrBoundsMismatchOnTrait {
|
||||||
ident: impl_m.ident(tcx),
|
span,
|
||||||
generics_span,
|
item_kind: assoc_item_kind_str(impl_m),
|
||||||
});
|
ident: impl_m.ident(tcx),
|
||||||
|
generics_span,
|
||||||
|
})
|
||||||
|
.emit_unless(delay);
|
||||||
|
|
||||||
return Err(reported);
|
return Err(reported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,18 +1509,10 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
let trait_to_impl_substs =
|
let trait_to_impl_substs =
|
||||||
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
|
impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
|
||||||
|
|
||||||
let impl_ty_generics = tcx.generics_of(impl_ty.def_id);
|
|
||||||
let trait_ty_generics = tcx.generics_of(trait_ty.def_id);
|
|
||||||
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
|
let impl_ty_predicates = tcx.predicates_of(impl_ty.def_id);
|
||||||
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
||||||
|
|
||||||
check_region_bounds_on_impl_item(
|
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
|
||||||
tcx,
|
|
||||||
impl_ty,
|
|
||||||
trait_ty,
|
|
||||||
&trait_ty_generics,
|
|
||||||
&impl_ty_generics,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
|
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_middle::ty::{self, Const, Ty, TyCtxt};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{self, Span};
|
use rustc_span::{self, Span};
|
||||||
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
|
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -162,6 +162,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
infcx: &self.infcx,
|
infcx: &self.infcx,
|
||||||
typeck_results: Some(self.typeck_results.borrow()),
|
typeck_results: Some(self.typeck_results.borrow()),
|
||||||
fallback_has_occurred: self.fallback_has_occurred.get(),
|
fallback_has_occurred: self.fallback_has_occurred.get(),
|
||||||
|
normalize_fn_sig: Box::new(|fn_sig| {
|
||||||
|
if fn_sig.has_escaping_bound_vars() {
|
||||||
|
return fn_sig;
|
||||||
|
}
|
||||||
|
self.probe(|_| {
|
||||||
|
let ocx = ObligationCtxt::new_in_snapshot(self);
|
||||||
|
let normalized_fn_sig =
|
||||||
|
ocx.normalize(&ObligationCause::dummy(), self.param_env, fn_sig);
|
||||||
|
if ocx.select_all_or_error().is_empty() {
|
||||||
|
let normalized_fn_sig = self.resolve_vars_if_possible(normalized_fn_sig);
|
||||||
|
if !normalized_fn_sig.needs_infer() {
|
||||||
|
return normalized_fn_sig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn_sig
|
||||||
|
})
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::callee::DeferredCallResolution;
|
use super::callee::DeferredCallResolution;
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::sync::Lrc;
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::HirIdMap;
|
use rustc_hir::HirIdMap;
|
||||||
|
@ -11,9 +10,7 @@ use rustc_middle::ty::visit::TypeVisitable;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_span::def_id::LocalDefIdMap;
|
use rustc_span::def_id::LocalDefIdMap;
|
||||||
use rustc_span::{self, Span};
|
use rustc_span::{self, Span};
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{self, TraitEngine, TraitEngineExt as _};
|
||||||
self, ObligationCause, ObligationCtxt, TraitEngine, TraitEngineExt as _,
|
|
||||||
};
|
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -92,29 +89,7 @@ impl<'tcx> Inherited<'tcx> {
|
||||||
infcx: tcx
|
infcx: tcx
|
||||||
.infer_ctxt()
|
.infer_ctxt()
|
||||||
.ignoring_regions()
|
.ignoring_regions()
|
||||||
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id))
|
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
|
||||||
.with_normalize_fn_sig_for_diagnostic(Lrc::new(move |infcx, fn_sig| {
|
|
||||||
if fn_sig.has_escaping_bound_vars() {
|
|
||||||
return fn_sig;
|
|
||||||
}
|
|
||||||
infcx.probe(|_| {
|
|
||||||
let ocx = ObligationCtxt::new_in_snapshot(infcx);
|
|
||||||
let normalized_fn_sig = ocx.normalize(
|
|
||||||
&ObligationCause::dummy(),
|
|
||||||
// FIXME(compiler-errors): This is probably not the right param-env...
|
|
||||||
infcx.tcx.param_env(def_id),
|
|
||||||
fn_sig,
|
|
||||||
);
|
|
||||||
if ocx.select_all_or_error().is_empty() {
|
|
||||||
let normalized_fn_sig =
|
|
||||||
infcx.resolve_vars_if_possible(normalized_fn_sig);
|
|
||||||
if !normalized_fn_sig.needs_infer() {
|
|
||||||
return normalized_fn_sig;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn_sig
|
|
||||||
})
|
|
||||||
})),
|
|
||||||
def_id,
|
def_id,
|
||||||
typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
|
typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,10 +77,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
err_count_on_creation: self.err_count_on_creation,
|
err_count_on_creation: self.err_count_on_creation,
|
||||||
in_snapshot: self.in_snapshot.clone(),
|
in_snapshot: self.in_snapshot.clone(),
|
||||||
universe: self.universe.clone(),
|
universe: self.universe.clone(),
|
||||||
normalize_fn_sig_for_diagnostic: self
|
|
||||||
.normalize_fn_sig_for_diagnostic
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.clone()),
|
|
||||||
intercrate: self.intercrate,
|
intercrate: self.intercrate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ pub mod nice_region_error;
|
||||||
pub struct TypeErrCtxt<'a, 'tcx> {
|
pub struct TypeErrCtxt<'a, 'tcx> {
|
||||||
pub infcx: &'a InferCtxt<'tcx>,
|
pub infcx: &'a InferCtxt<'tcx>,
|
||||||
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
pub typeck_results: Option<std::cell::Ref<'a, ty::TypeckResults<'tcx>>>,
|
||||||
|
pub normalize_fn_sig: Box<dyn Fn(ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> + 'a>,
|
||||||
pub fallback_has_occurred: bool,
|
pub fallback_has_occurred: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,22 +1008,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn normalize_fn_sig_for_diagnostic(&self, sig: ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx> {
|
|
||||||
if let Some(normalize) = &self.normalize_fn_sig_for_diagnostic {
|
|
||||||
normalize(self, sig)
|
|
||||||
} else {
|
|
||||||
sig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given two `fn` signatures highlight only sub-parts that are different.
|
/// Given two `fn` signatures highlight only sub-parts that are different.
|
||||||
fn cmp_fn_sig(
|
fn cmp_fn_sig(
|
||||||
&self,
|
&self,
|
||||||
sig1: &ty::PolyFnSig<'tcx>,
|
sig1: &ty::PolyFnSig<'tcx>,
|
||||||
sig2: &ty::PolyFnSig<'tcx>,
|
sig2: &ty::PolyFnSig<'tcx>,
|
||||||
) -> (DiagnosticStyledString, DiagnosticStyledString) {
|
) -> (DiagnosticStyledString, DiagnosticStyledString) {
|
||||||
let sig1 = &self.normalize_fn_sig_for_diagnostic(*sig1);
|
let sig1 = &(self.normalize_fn_sig)(*sig1);
|
||||||
let sig2 = &self.normalize_fn_sig_for_diagnostic(*sig2);
|
let sig2 = &(self.normalize_fn_sig)(*sig2);
|
||||||
|
|
||||||
let get_lifetimes = |sig| {
|
let get_lifetimes = |sig| {
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
|
|
|
@ -80,7 +80,6 @@ pub struct InferOk<'tcx, T> {
|
||||||
}
|
}
|
||||||
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
|
pub type InferResult<'tcx, T> = Result<InferOk<'tcx, T>, TypeError<'tcx>>;
|
||||||
|
|
||||||
pub type Bound<T> = Option<T>;
|
|
||||||
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
pub type UnitResult<'tcx> = RelateResult<'tcx, ()>; // "unify result"
|
||||||
pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
|
pub type FixupResult<'tcx, T> = Result<T, FixupError<'tcx>>; // "fixup result"
|
||||||
|
|
||||||
|
@ -334,9 +333,6 @@ pub struct InferCtxt<'tcx> {
|
||||||
/// bound.
|
/// bound.
|
||||||
universe: Cell<ty::UniverseIndex>,
|
universe: Cell<ty::UniverseIndex>,
|
||||||
|
|
||||||
normalize_fn_sig_for_diagnostic:
|
|
||||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
|
||||||
|
|
||||||
/// During coherence we have to assume that other crates may add
|
/// During coherence we have to assume that other crates may add
|
||||||
/// additional impls which we currently don't know about.
|
/// additional impls which we currently don't know about.
|
||||||
///
|
///
|
||||||
|
@ -573,8 +569,6 @@ pub struct InferCtxtBuilder<'tcx> {
|
||||||
considering_regions: bool,
|
considering_regions: bool,
|
||||||
/// Whether we are in coherence mode.
|
/// Whether we are in coherence mode.
|
||||||
intercrate: bool,
|
intercrate: bool,
|
||||||
normalize_fn_sig_for_diagnostic:
|
|
||||||
Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TyCtxtInferExt<'tcx> {
|
pub trait TyCtxtInferExt<'tcx> {
|
||||||
|
@ -587,7 +581,6 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
|
||||||
tcx: self,
|
tcx: self,
|
||||||
defining_use_anchor: DefiningAnchor::Error,
|
defining_use_anchor: DefiningAnchor::Error,
|
||||||
considering_regions: true,
|
considering_regions: true,
|
||||||
normalize_fn_sig_for_diagnostic: None,
|
|
||||||
intercrate: false,
|
intercrate: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,14 +608,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_normalize_fn_sig_for_diagnostic(
|
|
||||||
mut self,
|
|
||||||
fun: Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>,
|
|
||||||
) -> Self {
|
|
||||||
self.normalize_fn_sig_for_diagnostic = Some(fun);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a canonical value `C` as a starting point, create an
|
/// Given a canonical value `C` as a starting point, create an
|
||||||
/// inference context that contains each of the bound values
|
/// inference context that contains each of the bound values
|
||||||
/// within instantiated as a fresh variable. The `f` closure is
|
/// within instantiated as a fresh variable. The `f` closure is
|
||||||
|
@ -644,13 +629,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(&mut self) -> InferCtxt<'tcx> {
|
pub fn build(&mut self) -> InferCtxt<'tcx> {
|
||||||
let InferCtxtBuilder {
|
let InferCtxtBuilder { tcx, defining_use_anchor, considering_regions, intercrate } = *self;
|
||||||
tcx,
|
|
||||||
defining_use_anchor,
|
|
||||||
considering_regions,
|
|
||||||
ref normalize_fn_sig_for_diagnostic,
|
|
||||||
intercrate,
|
|
||||||
} = *self;
|
|
||||||
InferCtxt {
|
InferCtxt {
|
||||||
tcx,
|
tcx,
|
||||||
defining_use_anchor,
|
defining_use_anchor,
|
||||||
|
@ -666,9 +645,6 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||||
in_snapshot: Cell::new(false),
|
in_snapshot: Cell::new(false),
|
||||||
skip_leak_check: Cell::new(false),
|
skip_leak_check: Cell::new(false),
|
||||||
universe: Cell::new(ty::UniverseIndex::ROOT),
|
universe: Cell::new(ty::UniverseIndex::ROOT),
|
||||||
normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.clone()),
|
|
||||||
intercrate,
|
intercrate,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -709,7 +685,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||||
/// Creates a `TypeErrCtxt` for emitting various inference errors.
|
/// Creates a `TypeErrCtxt` for emitting various inference errors.
|
||||||
/// During typeck, use `FnCtxt::err_ctxt` instead.
|
/// During typeck, use `FnCtxt::err_ctxt` instead.
|
||||||
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
|
pub fn err_ctxt(&self) -> TypeErrCtxt<'_, 'tcx> {
|
||||||
TypeErrCtxt { infcx: self, typeck_results: None, fallback_has_occurred: false }
|
TypeErrCtxt {
|
||||||
|
infcx: self,
|
||||||
|
typeck_results: None,
|
||||||
|
fallback_has_occurred: false,
|
||||||
|
normalize_fn_sig: Box::new(|fn_sig| fn_sig),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_in_snapshot(&self) -> bool {
|
pub fn is_in_snapshot(&self) -> bool {
|
||||||
|
|
|
@ -32,13 +32,23 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
|
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
|
||||||
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo]) -> Self {
|
fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo]) -> Self {
|
||||||
let err = tcx.ty_error();
|
let err = tcx.ty_error();
|
||||||
// FIXME(compiler-errors): It would be nice if we could get the
|
|
||||||
// query key, so we could at least generate a fn signature that
|
let arity = if let Some(frame) = stack.get(0)
|
||||||
// has the right arity.
|
&& frame.query.name == "fn_sig"
|
||||||
|
&& let Some(def_id) = frame.query.def_id
|
||||||
|
&& let Some(node) = tcx.hir().get_if_local(def_id)
|
||||||
|
&& let Some(sig) = node.fn_sig()
|
||||||
|
{
|
||||||
|
sig.decl.inputs.len() + sig.decl.implicit_self.has_implicit_self() as usize
|
||||||
|
} else {
|
||||||
|
tcx.sess.abort_if_errors();
|
||||||
|
unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
let fn_sig = ty::Binder::dummy(tcx.mk_fn_sig(
|
||||||
[].into_iter(),
|
std::iter::repeat(err).take(arity),
|
||||||
err,
|
err,
|
||||||
false,
|
false,
|
||||||
rustc_hir::Unsafety::Normal,
|
rustc_hir::Unsafety::Normal,
|
||||||
|
|
|
@ -11,8 +11,8 @@ use crate::traits::select::IntercrateAmbiguityCause;
|
||||||
use crate::traits::util::impl_subject_and_oblig;
|
use crate::traits::util::impl_subject_and_oblig;
|
||||||
use crate::traits::SkipLeakCheck;
|
use crate::traits::SkipLeakCheck;
|
||||||
use crate::traits::{
|
use crate::traits::{
|
||||||
self, Normalized, Obligation, ObligationCause, ObligationCtxt, PredicateObligation,
|
self, Obligation, ObligationCause, ObligationCtxt, PredicateObligation, PredicateObligations,
|
||||||
PredicateObligations, SelectionContext,
|
SelectionContext,
|
||||||
};
|
};
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
|
@ -30,6 +30,8 @@ use std::fmt::Debug;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
|
||||||
|
use super::NormalizeExt;
|
||||||
|
|
||||||
/// Whether we do the orphan check relative to this crate or
|
/// Whether we do the orphan check relative to this crate or
|
||||||
/// to some remote crate.
|
/// to some remote crate.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
@ -128,8 +130,8 @@ fn with_fresh_ty_vars<'cx, 'tcx>(
|
||||||
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
|
predicates: tcx.predicates_of(impl_def_id).instantiate(tcx, impl_substs).predicates,
|
||||||
};
|
};
|
||||||
|
|
||||||
let Normalized { value: mut header, obligations } =
|
let InferOk { value: mut header, obligations } =
|
||||||
traits::normalize(selcx, param_env, ObligationCause::dummy(), header);
|
selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(header);
|
||||||
|
|
||||||
header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
|
header.predicates.extend(obligations.into_iter().map(|o| o.predicate));
|
||||||
header
|
header
|
||||||
|
|
|
@ -56,7 +56,6 @@ pub use self::object_safety::astconv_object_safety_violations;
|
||||||
pub use self::object_safety::is_vtable_safe_method;
|
pub use self::object_safety::is_vtable_safe_method;
|
||||||
pub use self::object_safety::MethodViolationCode;
|
pub use self::object_safety::MethodViolationCode;
|
||||||
pub use self::object_safety::ObjectSafetyViolation;
|
pub use self::object_safety::ObjectSafetyViolation;
|
||||||
pub(crate) use self::project::{normalize, normalize_to};
|
|
||||||
pub use self::project::{normalize_projection_type, NormalizeExt};
|
pub use self::project::{normalize_projection_type, NormalizeExt};
|
||||||
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
|
pub use self::select::{EvaluationCache, SelectionCache, SelectionContext};
|
||||||
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
|
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
|
||||||
|
|
|
@ -50,6 +50,10 @@ pub type ProjectionTyObligation<'tcx> = Obligation<'tcx, ty::ProjectionTy<'tcx>>
|
||||||
pub(super) struct InProgress;
|
pub(super) struct InProgress;
|
||||||
|
|
||||||
pub trait NormalizeExt<'tcx> {
|
pub trait NormalizeExt<'tcx> {
|
||||||
|
/// Normalize a value using the `AssocTypeNormalizer`.
|
||||||
|
///
|
||||||
|
/// This normalization should be used when the type contains inference variables or the
|
||||||
|
/// projection may be fallible.
|
||||||
fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
|
fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +61,7 @@ impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> {
|
||||||
fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
|
fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> {
|
||||||
let mut selcx = SelectionContext::new(self.infcx);
|
let mut selcx = SelectionContext::new(self.infcx);
|
||||||
let Normalized { value, obligations } =
|
let Normalized { value, obligations } =
|
||||||
normalize(&mut selcx, self.param_env, self.cause.clone(), value);
|
normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value);
|
||||||
InferOk { value, obligations }
|
InferOk { value, obligations }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,37 +307,6 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalizes any associated type projections in `value`, replacing
|
|
||||||
/// them with a fully resolved type where possible. The return value
|
|
||||||
/// combines the normalized result and any additional obligations that
|
|
||||||
/// were incurred as result.
|
|
||||||
pub(crate) fn normalize<'a, 'b, 'tcx, T>(
|
|
||||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
cause: ObligationCause<'tcx>,
|
|
||||||
value: T,
|
|
||||||
) -> Normalized<'tcx, T>
|
|
||||||
where
|
|
||||||
T: TypeFoldable<'tcx>,
|
|
||||||
{
|
|
||||||
let mut obligations = Vec::new();
|
|
||||||
let value = normalize_to(selcx, param_env, cause, value, &mut obligations);
|
|
||||||
Normalized { value, obligations }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn normalize_to<'a, 'b, 'tcx, T>(
|
|
||||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
cause: ObligationCause<'tcx>,
|
|
||||||
value: T,
|
|
||||||
obligations: &mut Vec<PredicateObligation<'tcx>>,
|
|
||||||
) -> T
|
|
||||||
where
|
|
||||||
T: TypeFoldable<'tcx>,
|
|
||||||
{
|
|
||||||
normalize_with_depth_to(selcx, param_env, cause, 0, value, obligations)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// As `normalize`, but with a custom depth.
|
/// As `normalize`, but with a custom depth.
|
||||||
pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
|
pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>(
|
||||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||||
|
@ -2324,10 +2297,11 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
let ty = super::normalize_to(
|
let ty = normalize_with_depth_to(
|
||||||
selcx,
|
selcx,
|
||||||
obligation.param_env,
|
obligation.param_env,
|
||||||
cause.clone(),
|
cause.clone(),
|
||||||
|
obligation.recursion_depth + 1,
|
||||||
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
|
tcx.bound_trait_impl_trait_tys(impl_fn_def_id)
|
||||||
.map_bound(|tys| {
|
.map_bound(|tys| {
|
||||||
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
|
tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.item_def_id])
|
||||||
|
|
|
@ -23,6 +23,13 @@ use super::NoSolution;
|
||||||
pub use rustc_middle::traits::query::NormalizationResult;
|
pub use rustc_middle::traits::query::NormalizationResult;
|
||||||
|
|
||||||
pub trait QueryNormalizeExt<'tcx> {
|
pub trait QueryNormalizeExt<'tcx> {
|
||||||
|
/// Normalize a value using the `QueryNormalizer`.
|
||||||
|
///
|
||||||
|
/// This normalization should *only* be used when the projection does not
|
||||||
|
/// have possible ambiguity or may not be well-formed.
|
||||||
|
///
|
||||||
|
/// After codegen, when lifetimes do not matter, it is preferable to instead
|
||||||
|
/// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure.
|
||||||
fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
|
fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution>
|
||||||
where
|
where
|
||||||
T: TypeFoldable<'tcx>;
|
T: TypeFoldable<'tcx>;
|
||||||
|
|
|
@ -908,6 +908,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
|
||||||
|
|
||||||
.popover {
|
.popover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
right: 0;
|
right: 0;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -1357,22 +1358,24 @@ a.test-arrow:hover {
|
||||||
}
|
}
|
||||||
#settings-menu, #help-button {
|
#settings-menu, #help-button {
|
||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
outline: none;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings-menu > a, #help-button > a, #copy-path {
|
#settings-menu > a, #help-button > a, #copy-path {
|
||||||
width: 33px;
|
width: 33px;
|
||||||
line-height: 1.5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings-menu > a, #help-button > a {
|
#settings-menu > a, #help-button > a {
|
||||||
padding: 5px;
|
display: flex;
|
||||||
height: 100%;
|
align-items: center;
|
||||||
display: block;
|
justify-content: center;
|
||||||
background-color: var(--button-background-color);
|
background-color: var(--button-background-color);
|
||||||
border: 1px solid var(--border-color);
|
border: 1px solid var(--border-color);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
color: var(--settings-button-color);
|
color: var(--settings-button-color);
|
||||||
|
/* Rare exception to specifying font sizes in rem. Since this is acting
|
||||||
|
as an icon, it's okay to specify their sizes in pixels. */
|
||||||
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#settings-menu > a:hover, #settings-menu > a:focus,
|
#settings-menu > a:hover, #settings-menu > a:focus,
|
||||||
|
@ -1408,14 +1411,6 @@ a.test-arrow:hover {
|
||||||
animation: rotating 2s linear infinite;
|
animation: rotating 2s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
#help-button > a {
|
|
||||||
text-align: center;
|
|
||||||
/* Rare exception to specifying font sizes in rem. Since this is acting
|
|
||||||
as an icon, it's okay to specify their sizes in pixels. */
|
|
||||||
font-size: 20px;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
kbd {
|
kbd {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
|
@ -1658,10 +1653,6 @@ in storage.js
|
||||||
content: "Since ";
|
content: "Since ";
|
||||||
}
|
}
|
||||||
|
|
||||||
#copy-path {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hide the logo and item name from the sidebar. Those are displayed
|
/* Hide the logo and item name from the sidebar. Those are displayed
|
||||||
in the mobile-topbar instead. */
|
in the mobile-topbar instead. */
|
||||||
.sidebar .sidebar-logo,
|
.sidebar .sidebar-logo,
|
||||||
|
@ -1795,8 +1786,8 @@ in storage.js
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We don't display the help button on mobile devices. */
|
/* We don't display these buttons on mobile devices. */
|
||||||
#help-button {
|
#copy-path, #help-button {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
37
src/test/assembly/asm/aarch64-el2vmsa.rs
Normal file
37
src/test/assembly/asm/aarch64-el2vmsa.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// assembly-output: emit-asm
|
||||||
|
// compile-flags: --target aarch64-unknown-linux-gnu
|
||||||
|
// needs-llvm-components: aarch64
|
||||||
|
|
||||||
|
#![feature(no_core, lang_items, rustc_attrs)]
|
||||||
|
#![crate_type = "rlib"]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
#[rustc_builtin_macro]
|
||||||
|
macro_rules! asm {
|
||||||
|
() => {};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[lang = "sized"]
|
||||||
|
trait Sized {}
|
||||||
|
|
||||||
|
// CHECK-LABEL: ttbr0_el2:
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn ttbr0_el2() {
|
||||||
|
// CHECK: //APP
|
||||||
|
// CHECK-NEXT: msr TTBR0_EL2, x0
|
||||||
|
// CHECK-NEXT: //NO_APP
|
||||||
|
unsafe {
|
||||||
|
asm!("msr ttbr0_el2, x0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CHECK-LABEL: vttbr_el2:
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn vttbr_el2() {
|
||||||
|
// CHECK: //APP
|
||||||
|
// CHECK-NEXT: msr VTTBR_EL2, x0
|
||||||
|
// CHECK-NEXT: //NO_APP
|
||||||
|
unsafe {
|
||||||
|
asm!("msr vttbr_el2, x0");
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,12 +44,16 @@ pub unsafe extern "C" fn callee(arg: Franta) {
|
||||||
tst_use(arg.b);
|
tst_use(arg.b);
|
||||||
tst_use(arg.c);
|
tst_use(arg.c);
|
||||||
tst_use(arg.d);
|
tst_use(arg.d);
|
||||||
|
tail_call_avoidance_fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn opaque_callee(arg: Franta, intarg: i32);
|
fn opaque_callee(arg: Franta, intarg: i32);
|
||||||
fn tst_use(arg: f32);
|
fn tst_use(arg: f32);
|
||||||
fn clobber();
|
fn clobber();
|
||||||
|
// This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't
|
||||||
|
// tail-call away some of our assertions.
|
||||||
|
fn tail_call_avoidance_fn();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -62,4 +66,5 @@ pub unsafe extern "C" fn caller() {
|
||||||
// CHECK: call opaque_callee
|
// CHECK: call opaque_callee
|
||||||
// CHECK: mov 3, %o2
|
// CHECK: mov 3, %o2
|
||||||
opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
|
opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
|
||||||
|
tail_call_avoidance_fn();
|
||||||
}
|
}
|
||||||
|
|
20
src/test/ui/async-await/in-trait/lifetime-mismatch.rs
Normal file
20
src/test/ui/async-await/in-trait/lifetime-mismatch.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// edition:2021
|
||||||
|
|
||||||
|
#![feature(async_fn_in_trait)]
|
||||||
|
//~^ WARN the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
|
||||||
|
trait MyTrait {
|
||||||
|
async fn foo<'a>(&self);
|
||||||
|
async fn bar(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MyTrait for i32 {
|
||||||
|
async fn foo(&self) {}
|
||||||
|
//~^ ERROR lifetime parameters or bounds on method `foo` do not match the trait declaration
|
||||||
|
|
||||||
|
async fn bar(&self) {
|
||||||
|
self.foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
21
src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
Normal file
21
src/test/ui/async-await/in-trait/lifetime-mismatch.stderr
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/lifetime-mismatch.rs:3:12
|
||||||
|
|
|
||||||
|
LL | #![feature(async_fn_in_trait)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0195]: lifetime parameters or bounds on method `foo` do not match the trait declaration
|
||||||
|
--> $DIR/lifetime-mismatch.rs:12:17
|
||||||
|
|
|
||||||
|
LL | async fn foo<'a>(&self);
|
||||||
|
| ---- lifetimes in impl do not match this method in trait
|
||||||
|
...
|
||||||
|
LL | async fn foo(&self) {}
|
||||||
|
| ^ lifetimes do not match method in trait
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0195`.
|
8
src/test/ui/query-system/fn-sig-cycle-arity.rs
Normal file
8
src/test/ui/query-system/fn-sig-cycle-arity.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
trait Dancer {
|
||||||
|
fn dance(&self) -> _ {
|
||||||
|
//~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
self.dance()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
9
src/test/ui/query-system/fn-sig-cycle-arity.stderr
Normal file
9
src/test/ui/query-system/fn-sig-cycle-arity.stderr
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
|
||||||
|
--> $DIR/fn-sig-cycle-arity.rs:2:24
|
||||||
|
|
|
||||||
|
LL | fn dance(&self) -> _ {
|
||||||
|
| ^ not allowed in type signatures
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0121`.
|
Loading…
Add table
Add a link
Reference in a new issue