Auto merge of #2679 - RalfJung:clock_gettime, r=RalfJung
implement clock_gettime on macos and pull in rustc changes so we can test this against https://github.com/rust-lang/rust/pull/103594. Fixes https://github.com/rust-lang/miri/issues/2664
This commit is contained in:
commit
fc105ef61f
@ -11,7 +11,7 @@ use super::LoweringContext;
|
||||
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::definitions::DefPathData;
|
||||
@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
.emit();
|
||||
}
|
||||
|
||||
let mut clobber_abis = FxHashMap::default();
|
||||
let mut clobber_abis = FxIndexMap::default();
|
||||
if let Some(asm_arch) = asm_arch {
|
||||
for (abi_name, abi_span) in &asm.clobber_abis {
|
||||
match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) {
|
||||
|
@ -655,15 +655,40 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
hir::ExprKind::Closure(c)
|
||||
};
|
||||
let generator = hir::Expr {
|
||||
hir_id: self.lower_node_id(closure_node_id),
|
||||
kind: generator_kind,
|
||||
span: self.lower_span(span),
|
||||
};
|
||||
|
||||
// `future::from_generator`:
|
||||
let parent_has_track_caller = self
|
||||
.attrs
|
||||
.values()
|
||||
.find(|attrs| attrs.into_iter().find(|attr| attr.has_name(sym::track_caller)).is_some())
|
||||
.is_some();
|
||||
let unstable_span =
|
||||
self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
|
||||
|
||||
let hir_id = if parent_has_track_caller {
|
||||
let generator_hir_id = self.lower_node_id(closure_node_id);
|
||||
self.lower_attrs(
|
||||
generator_hir_id,
|
||||
&[Attribute {
|
||||
kind: AttrKind::Normal(ptr::P(NormalAttr {
|
||||
item: AttrItem {
|
||||
path: Path::from_ident(Ident::new(sym::track_caller, span)),
|
||||
args: MacArgs::Empty,
|
||||
tokens: None,
|
||||
},
|
||||
tokens: None,
|
||||
})),
|
||||
id: self.tcx.sess.parse_sess.attr_id_generator.mk_attr_id(),
|
||||
style: AttrStyle::Outer,
|
||||
span: unstable_span,
|
||||
}],
|
||||
);
|
||||
generator_hir_id
|
||||
} else {
|
||||
self.lower_node_id(closure_node_id)
|
||||
};
|
||||
|
||||
let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
|
||||
|
||||
// `future::from_generator`:
|
||||
let gen_future = self.expr_lang_item_path(
|
||||
unstable_span,
|
||||
hir::LangItem::FromGenerator,
|
||||
|
@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::AssocCtxt;
|
||||
use rustc_ast::*;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sorted_map::SortedMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
@ -67,7 +66,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||
// HirId handling.
|
||||
bodies: Vec::new(),
|
||||
attrs: SortedMap::default(),
|
||||
children: FxHashMap::default(),
|
||||
children: Vec::default(),
|
||||
current_hir_id_owner: hir::CRATE_OWNER_ID,
|
||||
item_local_id_counter: hir::ItemLocalId::new(0),
|
||||
node_id_to_local_id: Default::default(),
|
||||
@ -86,7 +85,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
|
||||
impl_trait_defs: Vec::new(),
|
||||
impl_trait_bounds: Vec::new(),
|
||||
allow_try_trait: Some([sym::try_trait_v2, sym::yeet_desugar_details][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future][..].into()),
|
||||
allow_gen_future: Some([sym::gen_future, sym::closure_track_caller][..].into()),
|
||||
allow_into_future: Some([sym::into_future][..].into()),
|
||||
generics_def_id_map: Default::default(),
|
||||
};
|
||||
@ -534,12 +533,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
for new_node_id in [id1, id2] {
|
||||
let new_id = self.local_def_id(new_node_id);
|
||||
let Some(res) = resolutions.next() else {
|
||||
debug_assert!(self.children.iter().find(|(id, _)| id == &new_id).is_none());
|
||||
// Associate an HirId to both ids even if there is no resolution.
|
||||
let _old = self.children.insert(
|
||||
self.children.push((
|
||||
new_id,
|
||||
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)),
|
||||
hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id))),
|
||||
);
|
||||
debug_assert!(_old.is_none());
|
||||
continue;
|
||||
};
|
||||
let ident = *ident;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#![feature(let_chains)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![deny(rustc::untranslatable_diagnostic)]
|
||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||
|
||||
@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> {
|
||||
/// Attributes inside the owner being lowered.
|
||||
attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>,
|
||||
/// Collect items that were created by lowering the current owner.
|
||||
children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
|
||||
children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>,
|
||||
|
||||
generator_kind: Option<hir::GeneratorKind>,
|
||||
|
||||
@ -611,8 +610,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
self.impl_trait_defs = current_impl_trait_defs;
|
||||
self.impl_trait_bounds = current_impl_trait_bounds;
|
||||
|
||||
let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info));
|
||||
debug_assert!(_old.is_none())
|
||||
debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none());
|
||||
self.children.push((def_id, hir::MaybeOwner::Owner(info)));
|
||||
}
|
||||
|
||||
/// Installs the remapping `remap` in scope while `f` is being executed.
|
||||
@ -719,8 +718,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
|
||||
assert_ne!(local_id, hir::ItemLocalId::new(0));
|
||||
if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
|
||||
// Do not override a `MaybeOwner::Owner` that may already here.
|
||||
self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id));
|
||||
self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
|
||||
self.local_id_to_def_id.insert(local_id, def_id);
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,7 @@ use rustc_infer::infer::{DefiningAnchor, InferCtxt};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable,
|
||||
};
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
@ -256,8 +254,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
// 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
|
||||
// hidden type is well formed even without those bounds.
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
|
||||
.to_predicate(infcx.tcx);
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()));
|
||||
|
||||
let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id());
|
||||
|
||||
@ -282,6 +279,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
}
|
||||
|
||||
ocx.register_obligation(Obligation::misc(
|
||||
infcx.tcx,
|
||||
instantiated_ty.span,
|
||||
body_id,
|
||||
param_env,
|
||||
|
@ -92,8 +92,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}))
|
||||
.to_predicate(self.tcx()),
|
||||
})),
|
||||
locations,
|
||||
category,
|
||||
);
|
||||
@ -122,14 +121,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
pub(super) fn prove_predicates(
|
||||
&mut self,
|
||||
predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>,
|
||||
predicates: impl IntoIterator<
|
||||
Item = impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug,
|
||||
>,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
for predicate in predicates {
|
||||
let predicate = predicate.to_predicate(self.tcx());
|
||||
debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,);
|
||||
|
||||
self.prove_predicate(predicate, locations, category);
|
||||
}
|
||||
}
|
||||
@ -137,11 +135,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub(super) fn prove_predicate(
|
||||
&mut self,
|
||||
predicate: ty::Predicate<'tcx>,
|
||||
predicate: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug,
|
||||
locations: Locations,
|
||||
category: ConstraintCategory<'tcx>,
|
||||
) {
|
||||
let param_env = self.param_env;
|
||||
let predicate = predicate.to_predicate(self.tcx());
|
||||
self.fully_perform_op(
|
||||
locations,
|
||||
category,
|
||||
|
@ -33,8 +33,7 @@ use rustc_middle::ty::subst::{SubstsRef, UserSubsts};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic,
|
||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType,
|
||||
UserTypeAnnotationIndex,
|
||||
OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex,
|
||||
};
|
||||
use rustc_span::def_id::CRATE_DEF_ID;
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
@ -1069,8 +1068,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into()))
|
||||
.to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())),
|
||||
Locations::All(span),
|
||||
ConstraintCategory::TypeAnnotation,
|
||||
);
|
||||
|
@ -732,7 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
let obligation =
|
||||
Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred);
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, poly_trait_pred);
|
||||
|
||||
let implsrc = {
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
@ -816,6 +816,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
|
||||
if !nonconst_call_permission {
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(*fn_span),
|
||||
param_env,
|
||||
tcx.mk_predicate(
|
||||
|
@ -62,7 +62,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
|
||||
}
|
||||
|
||||
fn is_async(&self) -> bool {
|
||||
self.tcx.asyncness(self.def_id()) == hir::IsAsync::Async
|
||||
self.tcx.asyncness(self.def_id()).is_async()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,6 +147,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
||||
}
|
||||
Adt(..) => {
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
Binder::dummy(TraitPredicate {
|
||||
|
@ -156,6 +156,7 @@ impl Qualif for NeedsNonConstDrop {
|
||||
let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None);
|
||||
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy(),
|
||||
cx.param_env,
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
@ -351,7 +352,11 @@ where
|
||||
// FIXME(valtrees): check whether const qualifs should behave the same
|
||||
// way for type and mir constants.
|
||||
let uneval = match constant.literal {
|
||||
ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Param(_)) => None,
|
||||
ConstantKind::Ty(ct)
|
||||
if matches!(ct.kind(), ty::ConstKind::Param(_) | ty::ConstKind::Error(_)) =>
|
||||
{
|
||||
None
|
||||
}
|
||||
ConstantKind::Ty(c) => bug!("expected ConstKind::Param here, found {:?}", c),
|
||||
ConstantKind::Unevaluated(uv, _) => Some(uv),
|
||||
ConstantKind::Val(..) => None,
|
||||
|
@ -2720,6 +2720,12 @@ pub enum IsAsync {
|
||||
NotAsync,
|
||||
}
|
||||
|
||||
impl IsAsync {
|
||||
pub fn is_async(self) -> bool {
|
||||
self == IsAsync::Async
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
|
||||
pub enum Defaultness {
|
||||
Default { has_value: bool },
|
||||
|
@ -19,9 +19,7 @@ use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||
use rustc_middle::ty::subst::GenericArgKind;
|
||||
use rustc_middle::ty::util::{Discr, IntTypeExt};
|
||||
use rustc_middle::ty::{
|
||||
self, ParamEnv, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
|
||||
};
|
||||
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
|
||||
use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{self, Span};
|
||||
@ -464,9 +462,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
// 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
|
||||
// hidden type is well formed even without those bounds.
|
||||
let predicate =
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())).to_predicate(tcx);
|
||||
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
|
||||
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into()));
|
||||
ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate));
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
// version.
|
||||
|
@ -238,7 +238,7 @@ fn compare_predicate_entailment<'tcx>(
|
||||
kind: impl_m.kind,
|
||||
},
|
||||
);
|
||||
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
||||
// We now need to check that the signature of the impl method is
|
||||
@ -521,7 +521,13 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
|
||||
let num_trait_substs = trait_to_impl_substs.len();
|
||||
let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len();
|
||||
let ty = tcx.fold_regions(ty, |region, _| {
|
||||
let (ty::ReFree(_) | ty::ReEarlyBound(_)) = region.kind() else { return region; };
|
||||
match region.kind() {
|
||||
// Remap all free regions, which correspond to late-bound regions in the function.
|
||||
ty::ReFree(_) => {}
|
||||
// Remap early-bound regions as long as they don't come from the `impl` itself.
|
||||
ty::ReEarlyBound(ebr) if tcx.parent(ebr.def_id) != impl_m.container_id(tcx) => {}
|
||||
_ => return region,
|
||||
}
|
||||
let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind())
|
||||
else {
|
||||
tcx
|
||||
@ -605,6 +611,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
||||
);
|
||||
|
||||
self.ocx.register_obligation(traits::Obligation::new(
|
||||
self.tcx(),
|
||||
ObligationCause::new(
|
||||
self.span,
|
||||
self.body_id,
|
||||
@ -681,9 +688,7 @@ fn report_trait_method_mismatch<'tcx>(
|
||||
// Suggestion to change output type. We do not suggest in `async` functions
|
||||
// to avoid complex logic or incorrect output.
|
||||
match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind {
|
||||
ImplItemKind::Fn(ref sig, _)
|
||||
if sig.header.asyncness == hir::IsAsync::NotAsync =>
|
||||
{
|
||||
ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => {
|
||||
let msg = "change the output type to match the trait";
|
||||
let ap = Applicability::MachineApplicable;
|
||||
match sig.decl.output {
|
||||
@ -1579,7 +1584,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
},
|
||||
);
|
||||
ocx.register_obligations(obligations);
|
||||
ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate));
|
||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
||||
// Check that all obligations are satisfied by the implementation's
|
||||
@ -1784,7 +1789,7 @@ pub fn check_type_bounds<'tcx>(
|
||||
.subst_iter_copied(tcx, rebased_substs)
|
||||
.map(|(concrete_ty_bound, span)| {
|
||||
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
|
||||
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
|
||||
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
||||
})
|
||||
.collect();
|
||||
debug!("check_type_bounds: item_bounds={:?}", obligations);
|
||||
|
@ -14,8 +14,8 @@ use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable,
|
||||
TypeSuperVisitable, TypeVisitable, TypeVisitor,
|
||||
self, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
|
||||
TypeVisitable, TypeVisitor,
|
||||
};
|
||||
use rustc_middle::ty::{GenericArgKind, InternalSubsts};
|
||||
use rustc_session::parse::feature_err;
|
||||
@ -75,9 +75,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||
// for a type to be WF, we do not need to check if const trait predicates satisfy.
|
||||
let param_env = self.param_env.without_const();
|
||||
self.ocx.register_obligation(traits::Obligation::new(
|
||||
self.tcx(),
|
||||
cause,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1111,12 +1112,12 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
||||
traits::MiscObligation,
|
||||
);
|
||||
wfcx.register_obligation(traits::Obligation::new(
|
||||
tcx,
|
||||
cause,
|
||||
wfcx.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
|
||||
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
|
||||
))
|
||||
.to_predicate(tcx),
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -1453,7 +1454,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||
wfcx.body_id,
|
||||
traits::ItemObligation(def_id.to_def_id()),
|
||||
);
|
||||
traits::Obligation::new(cause, wfcx.param_env, pred)
|
||||
traits::Obligation::new(tcx, cause, wfcx.param_env, pred)
|
||||
});
|
||||
|
||||
let predicates = predicates.0.instantiate_identity(tcx);
|
||||
@ -1783,8 +1784,7 @@ fn receiver_is_implemented<'tcx>(
|
||||
substs: tcx.mk_substs_trait(receiver_ty, &[]),
|
||||
});
|
||||
|
||||
let obligation =
|
||||
traits::Obligation::new(cause, wfcx.param_env, trait_ref.without_const().to_predicate(tcx));
|
||||
let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const());
|
||||
|
||||
if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
|
||||
true
|
||||
@ -1931,6 +1931,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||
}
|
||||
|
||||
let obligation = traits::Obligation::new(
|
||||
tcx,
|
||||
traits::ObligationCause::new(span, self.body_id, traits::TrivialBound),
|
||||
empty_env,
|
||||
pred,
|
||||
|
@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind, HirId};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder};
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
pub fn provide(providers: &mut Providers) {
|
||||
@ -74,10 +74,10 @@ fn diagnostic_hir_wf_check<'tcx>(
|
||||
let errors = traits::fully_solve_obligation(
|
||||
&infcx,
|
||||
traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into()))
|
||||
.to_predicate(self.tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())),
|
||||
),
|
||||
);
|
||||
if !errors.is_empty() {
|
||||
|
@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diagnostic, MultiSpan};
|
||||
use rustc_hir::{self as hir, ExprKind};
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use rustc_trait_selection::traits::{
|
||||
@ -538,23 +538,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
.bound_explicit_item_bounds(rpit_def_id)
|
||||
.subst_iter_copied(self.tcx, substs)
|
||||
{
|
||||
let pred = match pred.kind().skip_binder() {
|
||||
let pred = pred.kind().rebind(match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(mut trait_pred) => {
|
||||
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
|
||||
trait_pred.trait_ref.substs =
|
||||
self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]);
|
||||
pred.kind().rebind(trait_pred).to_predicate(self.tcx)
|
||||
ty::PredicateKind::Trait(trait_pred)
|
||||
}
|
||||
ty::PredicateKind::Projection(mut proj_pred) => {
|
||||
assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty);
|
||||
proj_pred.projection_ty.substs = self
|
||||
.tcx
|
||||
.mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]);
|
||||
pred.kind().rebind(proj_pred).to_predicate(self.tcx)
|
||||
ty::PredicateKind::Projection(proj_pred)
|
||||
}
|
||||
_ => continue,
|
||||
};
|
||||
});
|
||||
if !self.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::misc(span, self.body_id),
|
||||
self.param_env,
|
||||
pred,
|
||||
|
@ -380,6 +380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
predicates.predicates.iter().zip(&predicates.spans)
|
||||
{
|
||||
let obligation = Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::dummy_with_span(callee_expr.span),
|
||||
self.param_env,
|
||||
*predicate,
|
||||
|
@ -102,7 +102,7 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||
|
||||
inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig);
|
||||
|
||||
if let ty::Dynamic(..) = declared_ret_ty.kind() {
|
||||
if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() {
|
||||
// FIXME: We need to verify that the return type is `Sized` after the return expression has
|
||||
// been evaluated so that we have types available for all the nodes being returned, but that
|
||||
// requires the coerced evaluated type to be stored. Moving `check_return_expr` before this
|
||||
|
@ -55,7 +55,7 @@ use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::relate::RelateResult;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TypeAndMut};
|
||||
use rustc_middle::ty::{self, Ty, TypeAndMut};
|
||||
use rustc_session::parse::feature_err;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::{self, BytePos, DesugaringKind, Span};
|
||||
@ -278,13 +278,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
for &source_ty in &[a, b] {
|
||||
if source_ty != target_ty {
|
||||
obligations.push(Obligation::new(
|
||||
self.tcx(),
|
||||
self.cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate {
|
||||
a: source_ty,
|
||||
b: target_ty,
|
||||
}))
|
||||
.to_predicate(self.tcx()),
|
||||
})),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -669,7 +669,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
match selcx.select(&obligation.with(trait_pred)) {
|
||||
match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
|
||||
// Uncertain or unimplemented.
|
||||
Ok(None) => {
|
||||
if trait_pred.def_id() == unsize_did {
|
||||
@ -783,10 +783,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
|
||||
// and then require that the resulting predicate (e.g., `usize: Clone`)
|
||||
// holds (it does).
|
||||
let predicate = predicate.with_self_ty(self.tcx, a);
|
||||
Obligation::new(self.cause.clone(), self.param_env, predicate)
|
||||
Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate)
|
||||
})
|
||||
// Enforce the region bound (e.g., `usize: 'static`, in our example).
|
||||
.chain([Obligation::new(
|
||||
self.tcx,
|
||||
self.cause.clone(),
|
||||
self.param_env,
|
||||
self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
|
||||
|
@ -22,8 +22,7 @@ use rustc_middle::ty::error::TypeError;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty,
|
||||
UserType,
|
||||
self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, Ty, UserType,
|
||||
};
|
||||
use rustc_middle::ty::{GenericArgKind, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts};
|
||||
use rustc_session::lint;
|
||||
@ -559,9 +558,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// WF obligations never themselves fail, so no real need to give a detailed cause:
|
||||
let cause = traits::ObligationCause::new(span, self.body_id, code);
|
||||
self.register_predicate(traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let ty = self.typeck_results.borrow().expr_ty_adjusted(expr);
|
||||
let ty = self.resolve_vars_if_possible(ty);
|
||||
if ty.has_non_region_infer() {
|
||||
assert!(self.is_tainted_by_errors());
|
||||
self.tcx.ty_error()
|
||||
} else {
|
||||
self.tcx.erase_regions(ty)
|
||||
@ -2150,6 +2149,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
),
|
||||
);
|
||||
let obligation = traits::Obligation::new(
|
||||
self.tcx,
|
||||
traits::ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
|
@ -1090,14 +1090,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
if let Some(into_def_id) = self.tcx.get_diagnostic_item(sym::Into)
|
||||
&& self.predicate_must_hold_modulo_regions(&traits::Obligation::new(
|
||||
self.tcx,
|
||||
self.misc(expr.span),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::TraitRef {
|
||||
def_id: into_def_id,
|
||||
substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]),
|
||||
})
|
||||
.to_poly_trait_predicate()
|
||||
.to_predicate(self.tcx),
|
||||
.to_poly_trait_predicate(),
|
||||
))
|
||||
{
|
||||
let sugg = if expr.precedence().order() >= PREC_POSTFIX {
|
||||
|
@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::{self, InferOk};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::subst::{InternalSubsts, SubstsRef};
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TypeVisitable};
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
@ -293,10 +293,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
(
|
||||
traits::Obligation::misc(
|
||||
self.tcx,
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const().to_predicate(self.tcx),
|
||||
poly_trait_ref.without_const(),
|
||||
),
|
||||
substs,
|
||||
)
|
||||
@ -335,6 +336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
(
|
||||
traits::Obligation::new(
|
||||
self.tcx,
|
||||
traits::ObligationCause::new(
|
||||
span,
|
||||
self.body_id,
|
||||
@ -346,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
},
|
||||
),
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const().to_predicate(self.tcx),
|
||||
poly_trait_ref.without_const(),
|
||||
),
|
||||
substs,
|
||||
)
|
||||
@ -523,9 +525,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
method_ty, obligation
|
||||
);
|
||||
obligations.push(traits::Obligation::new(
|
||||
tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())),
|
||||
));
|
||||
|
||||
let callee = MethodCallee { def_id, substs, sig: fn_sig };
|
||||
|
@ -19,7 +19,8 @@ use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::AssocItem;
|
||||
use rustc_middle::ty::GenericParamDefKind;
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
||||
use rustc_session::lint;
|
||||
use rustc_span::def_id::DefId;
|
||||
@ -1429,7 +1430,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate();
|
||||
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
|
||||
let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, predicate);
|
||||
traits::SelectionContext::new(self).select(&obligation)
|
||||
}
|
||||
|
||||
@ -1560,7 +1561,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
let predicate =
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
|
||||
parent_pred = Some(predicate);
|
||||
let obligation = traits::Obligation::new(cause, self.param_env, predicate);
|
||||
let obligation =
|
||||
traits::Obligation::new(self.tcx, cause, self.param_env, predicate);
|
||||
if !self.predicate_may_hold(&obligation) {
|
||||
result = ProbeResult::NoMatch;
|
||||
if self.probe(|_| {
|
||||
|
@ -23,7 +23,7 @@ use rustc_middle::traits::util::supertraits;
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::fast_reject::{simplify_type, TreatParams};
|
||||
use rustc_middle::ty::print::with_crate_prefix;
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef};
|
||||
use rustc_span::symbol::{kw, sym, Ident};
|
||||
use rustc_span::Symbol;
|
||||
@ -80,10 +80,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
let obligation = Obligation::misc(
|
||||
tcx,
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const().to_predicate(tcx),
|
||||
poly_trait_ref.without_const(),
|
||||
);
|
||||
self.predicate_may_hold(&obligation)
|
||||
})
|
||||
|
@ -581,9 +581,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
|
||||
}
|
||||
};
|
||||
let predicate = predicate.0.rebind(atom).to_predicate(self.tcx);
|
||||
let predicate = predicate.0.rebind(atom);
|
||||
|
||||
Obligation::new(cause, param_env, predicate)
|
||||
Obligation::new(self.tcx, cause, param_env, predicate)
|
||||
}
|
||||
|
||||
/// Given two sets of values for the same set of canonical variables, unify them.
|
||||
|
@ -37,7 +37,7 @@ use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{IntType, UintType};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
@ -347,10 +347,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||
|
||||
if needs_wf {
|
||||
self.obligations.push(Obligation::new(
|
||||
self.tcx(),
|
||||
self.trace.cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into()))
|
||||
.to_predicate(self.infcx.tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())),
|
||||
));
|
||||
}
|
||||
|
||||
@ -444,9 +444,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
|
||||
ty::PredicateKind::ConstEquate(b, a)
|
||||
};
|
||||
self.obligations.push(Obligation::new(
|
||||
self.tcx(),
|
||||
self.trace.cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(predicate).to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(predicate),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -595,7 +595,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
}
|
||||
// Require that the predicate holds for the concrete type.
|
||||
debug!(?predicate);
|
||||
obligations.push(traits::Obligation::new(cause.clone(), param_env, predicate));
|
||||
obligations.push(traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
predicate,
|
||||
));
|
||||
}
|
||||
Ok(InferOk { value: (), obligations })
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty};
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
|
||||
use crate::traits::{Obligation, PredicateObligation};
|
||||
|
||||
@ -28,12 +28,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
});
|
||||
let projection =
|
||||
ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, term: ty_var.into() });
|
||||
let obligation = Obligation::with_depth(
|
||||
cause,
|
||||
recursion_depth,
|
||||
param_env,
|
||||
projection.to_predicate(self.tcx),
|
||||
);
|
||||
let obligation =
|
||||
Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection);
|
||||
obligations.push(obligation);
|
||||
ty_var
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ use crate::traits::Obligation;
|
||||
use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
|
||||
use rustc_middle::ty::visit::TypeVisitable;
|
||||
use rustc_middle::ty::TyVar;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use std::mem;
|
||||
|
||||
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
|
||||
@ -95,14 +95,14 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
|
||||
// can't make progress on `A <: B` if both A and B are
|
||||
// type variables, so record an obligation.
|
||||
self.fields.obligations.push(Obligation::new(
|
||||
self.tcx(),
|
||||
self.fields.trace.cause.clone(),
|
||||
self.fields.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate {
|
||||
a_is_expected: self.a_is_expected,
|
||||
a,
|
||||
b,
|
||||
}))
|
||||
.to_predicate(self.tcx()),
|
||||
})),
|
||||
));
|
||||
|
||||
Ok(a)
|
||||
|
@ -10,7 +10,7 @@ pub mod util;
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, Const, ToPredicate, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
pub use self::FulfillmentErrorCode::*;
|
||||
@ -124,38 +124,41 @@ pub enum FulfillmentErrorCode<'tcx> {
|
||||
|
||||
impl<'tcx, O> Obligation<'tcx, O> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: O,
|
||||
predicate: impl ToPredicate<'tcx, O>,
|
||||
) -> Obligation<'tcx, O> {
|
||||
Obligation { cause, param_env, recursion_depth: 0, predicate }
|
||||
Self::with_depth(tcx, cause, 0, param_env, predicate)
|
||||
}
|
||||
|
||||
pub fn with_depth(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
recursion_depth: usize,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
predicate: O,
|
||||
predicate: impl ToPredicate<'tcx, O>,
|
||||
) -> Obligation<'tcx, O> {
|
||||
let predicate = predicate.to_predicate(tcx);
|
||||
Obligation { cause, param_env, recursion_depth, predicate }
|
||||
}
|
||||
|
||||
pub fn misc(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
span: Span,
|
||||
body_id: hir::HirId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
trait_ref: O,
|
||||
trait_ref: impl ToPredicate<'tcx, O>,
|
||||
) -> Obligation<'tcx, O> {
|
||||
Obligation::new(ObligationCause::misc(span, body_id), param_env, trait_ref)
|
||||
Obligation::new(tcx, ObligationCause::misc(span, body_id), param_env, trait_ref)
|
||||
}
|
||||
|
||||
pub fn with<P>(&self, value: P) -> Obligation<'tcx, P> {
|
||||
Obligation {
|
||||
cause: self.cause.clone(),
|
||||
param_env: self.param_env,
|
||||
recursion_depth: self.recursion_depth,
|
||||
predicate: value,
|
||||
}
|
||||
pub fn with<P>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
value: impl ToPredicate<'tcx, P>,
|
||||
) -> Obligation<'tcx, P> {
|
||||
Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
||||
// then we must've taken advantage of the hack in `project_and_unify_types` where
|
||||
// we replace opaques with inference vars. Emit a warning!
|
||||
if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
|
||||
cx.tcx,
|
||||
traits::ObligationCause::dummy(),
|
||||
cx.param_env,
|
||||
assoc_pred,
|
||||
|
@ -533,16 +533,14 @@ trait UnusedDelimLint {
|
||||
right_pos: Option<BytePos>,
|
||||
) {
|
||||
let spans = match value.kind {
|
||||
ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => {
|
||||
let start = block.stmts[0].span;
|
||||
let end = block.stmts[block.stmts.len() - 1].span;
|
||||
if let Some(start) = start.find_ancestor_inside(value.span)
|
||||
&& let Some(end) = end.find_ancestor_inside(value.span)
|
||||
ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => {
|
||||
if let StmtKind::Expr(expr) = &block.stmts[0].kind
|
||||
&& let ExprKind::Err = expr.kind
|
||||
{
|
||||
Some((
|
||||
value.span.with_hi(start.lo()),
|
||||
value.span.with_lo(end.hi()),
|
||||
))
|
||||
return
|
||||
}
|
||||
if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) {
|
||||
Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi())))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -924,10 +924,13 @@ impl ObjectSafetyViolation {
|
||||
}
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
MethodViolationCode::ReferencesImplTraitInTrait,
|
||||
MethodViolationCode::ReferencesImplTraitInTrait(_),
|
||||
_,
|
||||
) => format!("method `{}` references an `impl Trait` type in its return type", name)
|
||||
.into(),
|
||||
ObjectSafetyViolation::Method(name, MethodViolationCode::AsyncFn, _) => {
|
||||
format!("method `{}` is `async`", name).into()
|
||||
}
|
||||
ObjectSafetyViolation::Method(
|
||||
name,
|
||||
MethodViolationCode::WhereClauseReferencesSelf,
|
||||
@ -1035,7 +1038,10 @@ pub enum MethodViolationCode {
|
||||
ReferencesSelfOutput,
|
||||
|
||||
/// e.g., `fn foo(&self) -> impl Sized`
|
||||
ReferencesImplTraitInTrait,
|
||||
ReferencesImplTraitInTrait(Span),
|
||||
|
||||
/// e.g., `async fn foo(&self)`
|
||||
AsyncFn,
|
||||
|
||||
/// e.g., `fn foo(&self) where Self: Clone`
|
||||
WhereClauseReferencesSelf,
|
||||
|
@ -1125,42 +1125,42 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>;
|
||||
pub trait ToPredicate<'tcx, Predicate> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate;
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for Predicate<'tcx> {
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
impl<'tcx, T> ToPredicate<'tcx, T> for T {
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> {
|
||||
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tcx>> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
tcx.mk_predicate(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTraitPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.map_bound(PredicateKind::Trait).to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyRegionOutlivesPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.map_bound(PredicateKind::RegionOutlives).to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTypeOutlivesPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.map_bound(PredicateKind::TypeOutlives).to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyProjectionPredicate<'tcx> {
|
||||
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
|
||||
self.map_bound(PredicateKind::Projection).to_predicate(tcx)
|
||||
}
|
||||
|
@ -893,6 +893,7 @@ symbols! {
|
||||
masked,
|
||||
match_beginning_vert,
|
||||
match_default_bindings,
|
||||
matches_macro,
|
||||
maxnumf32,
|
||||
maxnumf64,
|
||||
may_dangle,
|
||||
|
@ -12,6 +12,8 @@ pub fn target() -> Target {
|
||||
features: "+neon,+fp-armv8,+apple-a7".into(),
|
||||
max_atomic_width: Some(128),
|
||||
forces_embed_bitcode: true,
|
||||
dynamic_linking: false,
|
||||
position_independent_executables: true,
|
||||
// These arguments are not actually invoked - they just have
|
||||
// to look right to pass App Store validation.
|
||||
bitcode_llvm_cmdline: "-triple\0\
|
||||
|
@ -12,6 +12,8 @@ pub fn target() -> Target {
|
||||
features: "+v7,+vfp4,+neon".into(),
|
||||
max_atomic_width: Some(64),
|
||||
forces_embed_bitcode: true,
|
||||
dynamic_linking: false,
|
||||
position_independent_executables: true,
|
||||
// These arguments are not actually invoked - they just have
|
||||
// to look right to pass App Store validation.
|
||||
bitcode_llvm_cmdline: "-triple\0\
|
||||
|
@ -3,8 +3,8 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{self, TraitEngine, TraitEngineExt};
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::ty::TypeVisitable;
|
||||
use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{ToPredicate, TypeVisitable};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::def_id::LOCAL_CRATE;
|
||||
use rustc_span::Span;
|
||||
@ -130,9 +130,10 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
let obligation = traits::Obligation::new(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
self.param_env,
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
|
||||
ty::Binder::dummy(trait_ref).without_const(),
|
||||
);
|
||||
if !self.infcx.predicate_may_hold(&obligation) {
|
||||
debug!("overloaded_deref_ty: cannot match obligation");
|
||||
|
@ -96,8 +96,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
PolyTraitRef::to_poly_trait_predicate,
|
||||
PolyTraitRef::to_poly_trait_predicate_negative_polarity,
|
||||
] {
|
||||
let result =
|
||||
selcx.select(&Obligation::new(ObligationCause::dummy(), orig_env, f(&trait_pred)));
|
||||
let result = selcx.select(&Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy(),
|
||||
orig_env,
|
||||
f(&trait_pred),
|
||||
));
|
||||
if let Ok(Some(ImplSource::UserDefined(_))) = result {
|
||||
debug!(
|
||||
"find_auto_trait_generics({:?}): \
|
||||
@ -280,8 +284,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
|
||||
// Call `infcx.resolve_vars_if_possible` to see if we can
|
||||
// get rid of any inference variables.
|
||||
let obligation =
|
||||
infcx.resolve_vars_if_possible(Obligation::new(dummy_cause.clone(), new_env, pred));
|
||||
let obligation = infcx.resolve_vars_if_possible(Obligation::new(
|
||||
tcx,
|
||||
dummy_cause.clone(),
|
||||
new_env,
|
||||
pred,
|
||||
));
|
||||
let result = select.select(&obligation);
|
||||
|
||||
match result {
|
||||
@ -706,7 +714,10 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
// and turn them into an explicit negative impl for our type.
|
||||
debug!("Projecting and unifying projection predicate {:?}", predicate);
|
||||
|
||||
match project::poly_project_and_unify_type(select, &obligation.with(p)) {
|
||||
match project::poly_project_and_unify_type(
|
||||
select,
|
||||
&obligation.with(self.tcx, p),
|
||||
) {
|
||||
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
|
||||
debug!(
|
||||
"evaluate_nested_obligations: Unable to unify predicate \
|
||||
|
@ -40,7 +40,7 @@ pub fn codegen_select_candidate<'tcx>(
|
||||
|
||||
let obligation_cause = ObligationCause::dummy();
|
||||
let obligation =
|
||||
Obligation::new(obligation_cause, param_env, trait_ref.to_poly_trait_predicate());
|
||||
Obligation::new(tcx, obligation_cause, param_env, trait_ref.to_poly_trait_predicate());
|
||||
|
||||
let selection = match selcx.select(&obligation) {
|
||||
Ok(Some(selection)) => selection,
|
||||
|
@ -32,7 +32,7 @@ pub fn recompute_applicable_impls<'tcx>(
|
||||
impl_predicates
|
||||
.predicates
|
||||
.iter()
|
||||
.map(|&predicate| Obligation::new(dummy_cause.clone(), param_env, predicate)),
|
||||
.map(|&predicate| Obligation::new(tcx, dummy_cause.clone(), param_env, predicate)),
|
||||
);
|
||||
|
||||
ocx.select_where_possible().is_empty()
|
||||
|
@ -344,14 +344,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
});
|
||||
let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]);
|
||||
let obligation = Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::new(trait_def_id, substs),
|
||||
constness,
|
||||
polarity,
|
||||
})
|
||||
.to_predicate(self.tcx),
|
||||
}),
|
||||
);
|
||||
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx);
|
||||
fulfill_cx.register_predicate_obligation(self, obligation);
|
||||
@ -984,7 +984,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
);
|
||||
trait_pred
|
||||
});
|
||||
let unit_obligation = obligation.with(predicate.to_predicate(tcx));
|
||||
let unit_obligation = obligation.with(tcx, predicate);
|
||||
if self.predicate_may_hold(&unit_obligation) {
|
||||
err.note(
|
||||
"this error might have been caused by changes to \
|
||||
@ -2012,7 +2012,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
..*tr
|
||||
});
|
||||
|
||||
Obligation::new(ObligationCause::dummy(), param_env, trait_pred.to_predicate(self.tcx))
|
||||
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
@ -2100,11 +2100,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
)
|
||||
};
|
||||
|
||||
let obligation = Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
trait_ref.to_poly_trait_predicate(),
|
||||
);
|
||||
let obligation = obligation.with(self.tcx, trait_ref.to_poly_trait_predicate());
|
||||
let mut selcx = SelectionContext::with_query_mode(
|
||||
&self,
|
||||
crate::traits::TraitQueryMode::Standard,
|
||||
@ -2534,11 +2530,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
)
|
||||
.value;
|
||||
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
cleaned_pred.to_predicate(selcx.tcx()),
|
||||
);
|
||||
let obligation =
|
||||
Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred);
|
||||
|
||||
self.predicate_may_hold(&obligation)
|
||||
})
|
||||
|
@ -301,7 +301,7 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||
obligated_types: &mut Vec<Ty<'tcx>>,
|
||||
seen_requirements: &mut FxHashSet<DefId>,
|
||||
) where
|
||||
T: fmt::Display;
|
||||
T: fmt::Display + ToPredicate<'tcx, T>;
|
||||
|
||||
/// Suggest to await before try: future? => future.await?
|
||||
fn suggest_await_before_try(
|
||||
@ -334,7 +334,7 @@ pub trait TypeErrCtxtExt<'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
|
||||
fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
|
||||
(
|
||||
generics.tail_span_for_predicate_suggestion(),
|
||||
format!("{} {}", generics.add_where_or_trailing_comma(), pred),
|
||||
@ -416,7 +416,7 @@ fn suggest_restriction<'tcx>(
|
||||
},
|
||||
// `fn foo(t: impl Trait)`
|
||||
// ^ suggest `where <T as Trait>::A: Bound`
|
||||
predicate_constraint(hir_generics, trait_pred.to_predicate(tcx).to_string()),
|
||||
predicate_constraint(hir_generics, trait_pred.to_predicate(tcx)),
|
||||
];
|
||||
sugg.extend(ty_spans.into_iter().map(|s| (s, type_param_name.to_string())));
|
||||
|
||||
@ -440,9 +440,7 @@ fn suggest_restriction<'tcx>(
|
||||
.find(|p| !matches!(p.kind, hir::GenericParamKind::Type { synthetic: true, .. })),
|
||||
super_traits,
|
||||
) {
|
||||
(_, None) => {
|
||||
predicate_constraint(hir_generics, trait_pred.to_predicate(tcx).to_string())
|
||||
}
|
||||
(_, None) => predicate_constraint(hir_generics, trait_pred.to_predicate(tcx)),
|
||||
(None, Some((ident, []))) => (
|
||||
ident.span.shrink_to_hi(),
|
||||
format!(": {}", trait_pred.print_modifiers_and_trait_path()),
|
||||
@ -1162,7 +1160,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
for predicate in predicates.iter() {
|
||||
if !self.predicate_must_hold_modulo_regions(
|
||||
&obligation.with(predicate.with_self_ty(self.tcx, self_ref_ty)),
|
||||
&obligation.with(self.tcx, predicate.with_self_ty(self.tcx, self_ref_ty)),
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@ -1523,7 +1521,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
let self_ty_satisfies_dyn_predicates = |self_ty| {
|
||||
predicates.iter().all(|predicate| {
|
||||
let pred = predicate.with_self_ty(self.tcx, self_ty);
|
||||
let obl = Obligation::new(cause.clone(), param_env, pred);
|
||||
let obl = Obligation::new(self.tcx, cause.clone(), param_env, pred);
|
||||
self.predicate_may_hold(&obl)
|
||||
})
|
||||
};
|
||||
@ -2704,7 +2702,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
obligated_types.push(ty);
|
||||
|
||||
let parent_predicate = parent_trait_ref.to_predicate(tcx);
|
||||
let parent_predicate = parent_trait_ref;
|
||||
if !self.is_recursive_obligation(obligated_types, &data.parent_code) {
|
||||
// #74711: avoid a stack overflow
|
||||
ensure_sufficient_stack(|| {
|
||||
@ -2766,7 +2764,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
_ => err.note(&msg),
|
||||
};
|
||||
|
||||
let mut parent_predicate = parent_trait_pred.to_predicate(tcx);
|
||||
let mut parent_predicate = parent_trait_pred;
|
||||
let mut data = &data.derived;
|
||||
let mut count = 0;
|
||||
seen_requirements.insert(parent_def_id);
|
||||
@ -2826,7 +2824,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
}
|
||||
ObligationCauseCode::DerivedObligation(ref data) => {
|
||||
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
|
||||
let parent_predicate = parent_trait_ref.to_predicate(tcx);
|
||||
let parent_predicate = parent_trait_ref;
|
||||
// #74711: avoid a stack overflow
|
||||
ensure_sufficient_stack(|| {
|
||||
self.note_obligation_cause_code(
|
||||
@ -3070,9 +3068,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
..*tr
|
||||
});
|
||||
let field_obl = Obligation::new(
|
||||
self.tcx,
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
trait_pred.to_predicate(self.tcx),
|
||||
trait_pred,
|
||||
);
|
||||
self.predicate_must_hold_modulo_regions(&field_obl)
|
||||
})
|
||||
|
@ -9,7 +9,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
use rustc_middle::ty::{self, Binder, Const, Ty, TypeVisitable};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
@ -296,7 +295,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
&mut obligations,
|
||||
);
|
||||
if predicate != obligation.predicate {
|
||||
obligations.push(obligation.with(predicate));
|
||||
obligations.push(obligation.with(infcx.tcx, predicate));
|
||||
return ProcessResult::Changed(mk_pending(obligations));
|
||||
}
|
||||
}
|
||||
@ -307,7 +306,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
// This means we need to pass it the bound version of our
|
||||
// predicate.
|
||||
ty::PredicateKind::Trait(trait_ref) => {
|
||||
let trait_obligation = obligation.with(binder.rebind(trait_ref));
|
||||
let trait_obligation = obligation.with(infcx.tcx, binder.rebind(trait_ref));
|
||||
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
@ -316,7 +315,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
)
|
||||
}
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let project_obligation = obligation.with(binder.rebind(data));
|
||||
let project_obligation = obligation.with(infcx.tcx, binder.rebind(data));
|
||||
|
||||
self.process_projection_obligation(
|
||||
obligation,
|
||||
@ -335,9 +334,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
| ty::PredicateKind::ConstEquate(..) => {
|
||||
let pred =
|
||||
ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder));
|
||||
ProcessResult::Changed(mk_pending(vec![
|
||||
obligation.with(pred.to_predicate(self.selcx.tcx())),
|
||||
]))
|
||||
ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
|
||||
}
|
||||
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
|
||||
bug!("TypeWellFormedFromEnv is only used for Chalk")
|
||||
@ -345,7 +342,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
},
|
||||
Some(pred) => match pred {
|
||||
ty::PredicateKind::Trait(data) => {
|
||||
let trait_obligation = obligation.with(Binder::dummy(data));
|
||||
let trait_obligation = obligation.with(infcx.tcx, Binder::dummy(data));
|
||||
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
@ -370,7 +367,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||
}
|
||||
|
||||
ty::PredicateKind::Projection(ref data) => {
|
||||
let project_obligation = obligation.with(Binder::dummy(*data));
|
||||
let project_obligation = obligation.with(infcx.tcx, Binder::dummy(*data));
|
||||
|
||||
self.process_projection_obligation(
|
||||
obligation,
|
||||
@ -697,7 +694,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> {
|
||||
}
|
||||
// Let the caller handle the recursion
|
||||
ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![
|
||||
project_obligation.with(project_obligation.predicate.to_predicate(tcx)),
|
||||
project_obligation.with(tcx, project_obligation.predicate),
|
||||
])),
|
||||
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => {
|
||||
ProcessResult::Error(CodeProjectionError(e))
|
||||
|
@ -440,7 +440,7 @@ pub fn impossible_predicates<'tcx>(
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates);
|
||||
for predicate in predicates {
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
|
||||
let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate);
|
||||
ocx.register_obligation(obligation);
|
||||
}
|
||||
let errors = ocx.select_all_or_error();
|
||||
@ -530,6 +530,7 @@ fn is_impossible_method<'tcx>(
|
||||
let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| {
|
||||
if pred.visit_with(&mut visitor).is_continue() {
|
||||
Some(Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(*span),
|
||||
param_env,
|
||||
ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs),
|
||||
|
@ -375,6 +375,7 @@ fn object_safety_violation_for_method(
|
||||
let span = match (&v, node) {
|
||||
(MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span,
|
||||
(MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span,
|
||||
(MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span,
|
||||
(MethodViolationCode::ReferencesSelfOutput, Some(node)) => {
|
||||
node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span())
|
||||
}
|
||||
@ -437,8 +438,8 @@ fn virtual_call_violation_for_method<'tcx>(
|
||||
if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
|
||||
return Some(MethodViolationCode::ReferencesSelfOutput);
|
||||
}
|
||||
if contains_illegal_impl_trait_in_trait(tcx, sig.output()) {
|
||||
return Some(MethodViolationCode::ReferencesImplTraitInTrait);
|
||||
if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) {
|
||||
return Some(code);
|
||||
}
|
||||
|
||||
// We can't monomorphize things like `fn foo<A>(...)`.
|
||||
@ -723,10 +724,9 @@ fn receiver_is_dispatchable<'tcx>(
|
||||
def_id: dispatch_from_dyn_did,
|
||||
substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]),
|
||||
})
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
.without_const();
|
||||
|
||||
Obligation::new(ObligationCause::dummy(), param_env, predicate)
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
|
||||
};
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
@ -865,16 +865,24 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
|
||||
|
||||
pub fn contains_illegal_impl_trait_in_trait<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
fn_def_id: DefId,
|
||||
ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
) -> bool {
|
||||
) -> Option<MethodViolationCode> {
|
||||
// This would be caught below, but rendering the error as a separate
|
||||
// `async-specific` message is better.
|
||||
if tcx.asyncness(fn_def_id).is_async() {
|
||||
return Some(MethodViolationCode::AsyncFn);
|
||||
}
|
||||
|
||||
// FIXME(RPITIT): Perhaps we should use a visitor here?
|
||||
ty.skip_binder().walk().any(|arg| {
|
||||
ty.skip_binder().walk().find_map(|arg| {
|
||||
if let ty::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Projection(proj) = ty.kind()
|
||||
&& tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||
{
|
||||
tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder
|
||||
Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id)))
|
||||
} else {
|
||||
false
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
|
||||
infcx.replace_bound_vars_with_placeholders(obligation.predicate);
|
||||
let new_universe = infcx.universe();
|
||||
|
||||
let placeholder_obligation = obligation.with(placeholder_predicate);
|
||||
let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
|
||||
match project_and_unify_type(selcx, &placeholder_obligation) {
|
||||
ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e),
|
||||
ProjectAndUnifyResult::Holds(obligations)
|
||||
@ -517,6 +517,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.depth) {
|
||||
let obligation = Obligation::with_depth(
|
||||
self.tcx(),
|
||||
self.cause.clone(),
|
||||
recursion_limit.0,
|
||||
self.param_env,
|
||||
@ -573,6 +574,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
||||
&& !self.tcx().sess.opts.actually_rustdoc
|
||||
{
|
||||
let obligation = Obligation::with_depth(
|
||||
self.selcx.tcx(),
|
||||
self.cause.clone(),
|
||||
recursion_limit.0,
|
||||
self.param_env,
|
||||
@ -1110,7 +1112,8 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty);
|
||||
let obligation =
|
||||
Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty);
|
||||
|
||||
match project(selcx, &obligation) {
|
||||
Ok(Projected::Progress(Progress {
|
||||
@ -1343,8 +1346,8 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
||||
ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs })
|
||||
.to_poly_trait_predicate();
|
||||
|
||||
let _ =
|
||||
selcx.infcx().commit_if_ok(|_| match selcx.select(&obligation.with(trait_predicate)) {
|
||||
let _ = selcx.infcx().commit_if_ok(|_| {
|
||||
match selcx.select(&obligation.with(tcx, trait_predicate)) {
|
||||
Ok(Some(super::ImplSource::UserDefined(data))) => {
|
||||
candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait(
|
||||
ImplTraitInTraitCandidate::Impl(data),
|
||||
@ -1364,7 +1367,8 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
|
||||
candidate_set.mark_error(e);
|
||||
return Err(());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1538,7 +1542,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
|
||||
// start out by selecting the predicate `T as TraitRef<...>`:
|
||||
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
|
||||
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
|
||||
let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref.to_poly_trait_predicate());
|
||||
let _ = selcx.infcx().commit_if_ok(|_| {
|
||||
let impl_source = match selcx.select(&trait_obligation) {
|
||||
Ok(Some(impl_source)) => impl_source,
|
||||
@ -1705,12 +1709,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
ty::Param(_) | ty::Projection(..) | ty::Opaque(..)
|
||||
if selcx.infcx().predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::Binder::dummy(ty::TraitRef::new(
|
||||
selcx.tcx().require_lang_item(LangItem::Sized, None),
|
||||
selcx.tcx().mk_substs_trait(self_ty, &[]),
|
||||
))
|
||||
.without_const()
|
||||
.to_predicate(selcx.tcx()),
|
||||
.without_const(),
|
||||
),
|
||||
) =>
|
||||
{
|
||||
@ -1966,13 +1970,8 @@ fn confirm_pointee_candidate<'cx, 'tcx>(
|
||||
tcx.require_lang_item(LangItem::Sized, None),
|
||||
tcx.mk_substs_trait(self_ty, &[]),
|
||||
))
|
||||
.without_const()
|
||||
.to_predicate(tcx);
|
||||
obligations.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
sized_predicate,
|
||||
));
|
||||
.without_const();
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
|
||||
let substs = tcx.mk_substs([self_ty.into()].iter());
|
||||
@ -2289,6 +2288,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map(
|
||||
|(pred, span)| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
@ -2342,6 +2342,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
|
||||
nested,
|
||||
);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
|
@ -208,6 +208,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
||||
let recursion_limit = self.tcx().recursion_limit();
|
||||
if !recursion_limit.value_within_limit(self.anon_depth) {
|
||||
let obligation = Obligation::with_depth(
|
||||
self.tcx(),
|
||||
self.cause.clone(),
|
||||
recursion_limit.0,
|
||||
self.param_env,
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::infer::InferCtxt;
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt;
|
||||
use crate::traits::{ObligationCause, PredicateObligation};
|
||||
use crate::traits::PredicateObligation;
|
||||
use rustc_infer::traits::TraitEngine;
|
||||
use rustc_middle::ty::{self, ToPredicate};
|
||||
use rustc_middle::ty;
|
||||
|
||||
pub(crate) fn update<'tcx, T>(
|
||||
engine: &mut T,
|
||||
@ -25,9 +25,7 @@ pub(crate) fn update<'tcx, T>(
|
||||
|
||||
// Then construct a new obligation with Self = () added
|
||||
// to the ParamEnv, and see if it holds.
|
||||
let o = rustc_infer::traits::Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
obligation.param_env,
|
||||
let o = obligation.with(infcx.tcx,
|
||||
obligation
|
||||
.predicate
|
||||
.kind()
|
||||
@ -38,8 +36,7 @@ pub(crate) fn update<'tcx, T>(
|
||||
constness: tpred.constness,
|
||||
polarity: tpred.polarity,
|
||||
})
|
||||
)
|
||||
.to_predicate(infcx.tcx),
|
||||
),
|
||||
);
|
||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||
if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) && result.may_apply() {
|
||||
|
@ -13,7 +13,7 @@ use rustc_infer::traits::ObligationCause;
|
||||
use rustc_infer::traits::{Obligation, SelectionError, TraitObligation};
|
||||
use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable};
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitable};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::traits;
|
||||
@ -718,9 +718,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
};
|
||||
|
||||
let obligation = traits::Obligation::new(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
param_env,
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
|
||||
ty::Binder::dummy(trait_ref).without_const(),
|
||||
);
|
||||
if !self.infcx.predicate_may_hold(&obligation) {
|
||||
return None;
|
||||
|
@ -194,6 +194,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.push(Obligation::with_depth(
|
||||
self.tcx(),
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
@ -482,11 +483,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
super_trait,
|
||||
&mut nested,
|
||||
);
|
||||
nested.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
normalized_super_trait,
|
||||
));
|
||||
nested.push(obligation.with(tcx, normalized_super_trait));
|
||||
}
|
||||
|
||||
let assoc_types: Vec<_> = tcx
|
||||
@ -581,11 +578,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
subst_bound,
|
||||
&mut nested,
|
||||
);
|
||||
nested.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
normalized_bound,
|
||||
));
|
||||
nested.push(obligation.with(tcx, normalized_bound));
|
||||
}
|
||||
}
|
||||
|
||||
@ -644,9 +637,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.tcx().mk_substs_trait(output_ty, &[]),
|
||||
));
|
||||
nested.push(Obligation::new(
|
||||
self.infcx.tcx,
|
||||
cause,
|
||||
obligation.param_env,
|
||||
tr.to_poly_trait_predicate().to_predicate(self.tcx()),
|
||||
tr.to_poly_trait_predicate(),
|
||||
));
|
||||
|
||||
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
|
||||
@ -727,11 +721,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// FIXME: Chalk
|
||||
|
||||
if !self.tcx().sess.opts.unstable_opts.chalk {
|
||||
nested.push(Obligation::new(
|
||||
obligation.cause.clone(),
|
||||
obligation.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind))
|
||||
.to_predicate(self.tcx()),
|
||||
nested.push(obligation.with(
|
||||
self.tcx(),
|
||||
ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)),
|
||||
));
|
||||
}
|
||||
|
||||
@ -860,10 +852,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives).to_predicate(tcx),
|
||||
obligation.predicate.rebind(outlives),
|
||||
));
|
||||
}
|
||||
_ => bug!(),
|
||||
@ -957,10 +950,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives).to_predicate(tcx),
|
||||
obligation.predicate.rebind(outlives),
|
||||
));
|
||||
}
|
||||
|
||||
@ -979,6 +973,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
let predicate_to_obligation = |predicate| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
@ -1255,20 +1250,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.param_env,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
self_ty
|
||||
.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
.to_predicate(tcx),
|
||||
self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
&mut nested,
|
||||
);
|
||||
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
@ -1280,18 +1274,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// since it's either not `const Drop` (and we raise an error during selection),
|
||||
// or it's an ADT (and we need to check for a custom impl during selection)
|
||||
_ => {
|
||||
let predicate = self_ty
|
||||
.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
.to_predicate(tcx);
|
||||
let predicate = self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef {
|
||||
def_id: self.tcx().require_lang_item(LangItem::Destruct, None),
|
||||
substs: self.tcx().mk_substs_trait(nested_ty, &[]),
|
||||
},
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
|
@ -445,7 +445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ty::PredicateKind::Trait(t) => {
|
||||
let t = bound_predicate.rebind(t);
|
||||
debug_assert!(!t.has_escaping_bound_vars());
|
||||
let obligation = obligation.with(t);
|
||||
let obligation = obligation.with(self.tcx(), t);
|
||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||
}
|
||||
|
||||
@ -596,7 +596,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ty::PredicateKind::Projection(data) => {
|
||||
let data = bound_predicate.rebind(data);
|
||||
let project_obligation = obligation.with(data);
|
||||
let project_obligation = obligation.with(self.tcx(), data);
|
||||
match project::poly_project_and_unify_type(self, &project_obligation) {
|
||||
ProjectAndUnifyResult::Holds(mut subobligations) => {
|
||||
'compute_res: {
|
||||
|
@ -4,7 +4,7 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
|
||||
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::iter;
|
||||
@ -324,7 +324,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
extend_cause_with_original_assoc_item_obligation(
|
||||
tcx, trait_ref, item, &mut cause, predicate,
|
||||
);
|
||||
traits::Obligation::with_depth(cause, depth, param_env, predicate)
|
||||
traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate)
|
||||
};
|
||||
|
||||
if let Elaborate::All = elaborate {
|
||||
@ -356,10 +356,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
}
|
||||
}
|
||||
traits::Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
||||
)
|
||||
}),
|
||||
);
|
||||
@ -407,10 +408,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
.filter(|arg| !arg.has_escaping_bound_vars())
|
||||
.map(|arg| {
|
||||
traits::Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
|
||||
)
|
||||
}),
|
||||
);
|
||||
@ -424,10 +426,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
substs: self.tcx.mk_substs_trait(subty, &[]),
|
||||
};
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
|
||||
ty::Binder::dummy(trait_ref).without_const(),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -454,10 +457,10 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
self.out.extend(obligations);
|
||||
|
||||
let predicate =
|
||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct))
|
||||
.to_predicate(self.tcx());
|
||||
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct));
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
@ -468,11 +471,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into()))
|
||||
.to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())),
|
||||
));
|
||||
}
|
||||
ty::ConstKind::Error(_)
|
||||
@ -556,13 +559,13 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
|
||||
let cause = self.cause(traits::ReferenceOutlivesReferent(ty));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
|
||||
ty::OutlivesPredicate(rty, r),
|
||||
))
|
||||
.to_predicate(self.tcx()),
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -656,11 +659,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
let tcx = self.tcx();
|
||||
self.out.extend(component_traits.map(|did| {
|
||||
traits::Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did))
|
||||
.to_predicate(tcx),
|
||||
ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)),
|
||||
)
|
||||
}));
|
||||
}
|
||||
@ -681,11 +684,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
ty::Infer(_) => {
|
||||
let cause = self.cause(traits::WellFormed(None));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
param_env,
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))
|
||||
.to_predicate(self.tcx()),
|
||||
ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -724,7 +727,13 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
if remap_constness {
|
||||
pred = pred.without_const(self.tcx);
|
||||
}
|
||||
traits::Obligation::with_depth(cause, self.recursion_depth, self.param_env, pred)
|
||||
traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
pred,
|
||||
)
|
||||
})
|
||||
.filter(|pred| !pred.has_escaping_bound_vars())
|
||||
.collect()
|
||||
@ -794,10 +803,11 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
let outlives =
|
||||
ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound));
|
||||
self.out.push(traits::Obligation::with_depth(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
outlives.to_predicate(self.tcx),
|
||||
outlives,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ fn evaluate_obligation<'tcx>(
|
||||
let ParamEnvAnd { param_env, value: predicate } = goal;
|
||||
|
||||
let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate);
|
||||
let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate);
|
||||
|
||||
selcx.evaluate_root_obligation(&obligation)
|
||||
}
|
||||
|
@ -91,7 +91,12 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> {
|
||||
}
|
||||
|
||||
fn prove_predicate(&self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) {
|
||||
self.ocx.register_obligation(Obligation::new(cause, self.param_env, predicate));
|
||||
self.ocx.register_obligation(Obligation::new(
|
||||
self.ocx.infcx.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
predicate,
|
||||
));
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
@ -256,5 +261,5 @@ pub fn type_op_prove_predicate_with_cause<'tcx>(
|
||||
cause: ObligationCause<'tcx>,
|
||||
) {
|
||||
let (param_env, ProvePredicate { predicate }) = key.into_parts();
|
||||
ocx.register_obligation(Obligation::new(cause, param_env, predicate));
|
||||
ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate));
|
||||
}
|
||||
|
@ -293,6 +293,15 @@ struct RcBox<T: ?Sized> {
|
||||
value: T,
|
||||
}
|
||||
|
||||
/// Calculate layout for `RcBox<T>` using the inner value's layout
|
||||
fn rcbox_layout_for_value_layout(layout: Layout) -> Layout {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
Layout::new::<RcBox<()>>().extend(layout).unwrap().0.pad_to_align()
|
||||
}
|
||||
|
||||
/// A single-threaded reference-counting pointer. 'Rc' stands for 'Reference
|
||||
/// Counted'.
|
||||
///
|
||||
@ -1334,11 +1343,7 @@ impl<T: ?Sized> Rc<T> {
|
||||
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
|
||||
mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>,
|
||||
) -> *mut RcBox<T> {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
|
||||
let layout = rcbox_layout_for_value_layout(value_layout);
|
||||
unsafe {
|
||||
Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rcbox)
|
||||
.unwrap_or_else(|_| handle_alloc_error(layout))
|
||||
@ -1357,11 +1362,7 @@ impl<T: ?Sized> Rc<T> {
|
||||
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
|
||||
mem_to_rcbox: impl FnOnce(*mut u8) -> *mut RcBox<T>,
|
||||
) -> Result<*mut RcBox<T>, AllocError> {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const RcBox<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
let layout = Layout::new::<RcBox<()>>().extend(value_layout).unwrap().0.pad_to_align();
|
||||
let layout = rcbox_layout_for_value_layout(value_layout);
|
||||
|
||||
// Allocate for the layout.
|
||||
let ptr = allocate(layout)?;
|
||||
@ -1428,7 +1429,7 @@ impl<T> Rc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy elements from slice into newly allocated Rc<\[T\]>
|
||||
/// Copy elements from slice into newly allocated `Rc<[T]>`
|
||||
///
|
||||
/// Unsafe because the caller must either take ownership or bind `T: Copy`
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
@ -1440,6 +1441,48 @@ impl<T> Rc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an `Rc<[T]>` by reusing the underlying memory
|
||||
/// of a `Vec<T>`. This will return the vector if the existing allocation
|
||||
/// is not large enough.
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Rc<[T]>, Vec<T>> {
|
||||
let layout_elements = Layout::array::<T>(v.len()).unwrap();
|
||||
let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
|
||||
let layout_rcbox = rcbox_layout_for_value_layout(layout_elements);
|
||||
let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
|
||||
if layout_rcbox.size() > layout_allocation.size()
|
||||
|| layout_rcbox.align() > layout_allocation.align()
|
||||
{
|
||||
// Can't fit - calling `grow` would involve `realloc`
|
||||
// (which copies the elements), followed by copying again.
|
||||
return Err(v);
|
||||
}
|
||||
if layout_rcbox.size() < layout_allocation.size()
|
||||
|| layout_rcbox.align() < layout_allocation.align()
|
||||
{
|
||||
// We need to shrink the allocation so that it fits
|
||||
// https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
|
||||
// SAFETY:
|
||||
// - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
|
||||
// - `layout_rcbox` is smaller
|
||||
// If this fails, the ownership has not been transferred
|
||||
if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_rcbox) } {
|
||||
ptr = p.cast();
|
||||
} else {
|
||||
return Err(v);
|
||||
}
|
||||
}
|
||||
// Make sure the vec's memory isn't deallocated now
|
||||
let v = mem::ManuallyDrop::new(v);
|
||||
let ptr: *mut RcBox<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
|
||||
unsafe {
|
||||
ptr::copy(ptr.cast::<T>(), &mut (*ptr).value as *mut [T] as *mut T, v.len());
|
||||
ptr::write(&mut (*ptr).strong, Cell::new(1));
|
||||
ptr::write(&mut (*ptr).weak, Cell::new(1));
|
||||
Ok(Self::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an `Rc<[T]>` from an iterator known to be of a certain size.
|
||||
///
|
||||
/// Behavior is undefined should the size be wrong.
|
||||
@ -1965,14 +2008,17 @@ impl<T> From<Vec<T>> for Rc<[T]> {
|
||||
/// assert_eq!(vec![1, 2, 3], *shared);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from(mut v: Vec<T>) -> Rc<[T]> {
|
||||
unsafe {
|
||||
let rc = Rc::copy_from_slice(&v);
|
||||
|
||||
// Allow the Vec to free its memory, but not destroy its contents
|
||||
v.set_len(0);
|
||||
|
||||
rc
|
||||
fn from(v: Vec<T>) -> Rc<[T]> {
|
||||
match Rc::try_from_vec_in_place(v) {
|
||||
Ok(rc) => rc,
|
||||
Err(mut v) => {
|
||||
unsafe {
|
||||
let rc = Rc::copy_from_slice(&v);
|
||||
// Allow the Vec to free its memory, but not destroy its contents
|
||||
v.set_len(0);
|
||||
rc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -333,6 +333,15 @@ struct ArcInner<T: ?Sized> {
|
||||
data: T,
|
||||
}
|
||||
|
||||
/// Calculate layout for `ArcInner<T>` using the inner value's layout
|
||||
fn arcinner_layout_for_value_layout(layout: Layout) -> Layout {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
Layout::new::<ArcInner<()>>().extend(layout).unwrap().0.pad_to_align()
|
||||
}
|
||||
|
||||
unsafe impl<T: ?Sized + Sync + Send> Send for ArcInner<T> {}
|
||||
unsafe impl<T: ?Sized + Sync + Send> Sync for ArcInner<T> {}
|
||||
|
||||
@ -1154,11 +1163,7 @@ impl<T: ?Sized> Arc<T> {
|
||||
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
|
||||
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
|
||||
) -> *mut ArcInner<T> {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
|
||||
let layout = arcinner_layout_for_value_layout(value_layout);
|
||||
unsafe {
|
||||
Arc::try_allocate_for_layout(value_layout, allocate, mem_to_arcinner)
|
||||
.unwrap_or_else(|_| handle_alloc_error(layout))
|
||||
@ -1176,11 +1181,7 @@ impl<T: ?Sized> Arc<T> {
|
||||
allocate: impl FnOnce(Layout) -> Result<NonNull<[u8]>, AllocError>,
|
||||
mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner<T>,
|
||||
) -> Result<*mut ArcInner<T>, AllocError> {
|
||||
// Calculate layout using the given value layout.
|
||||
// Previously, layout was calculated on the expression
|
||||
// `&*(ptr as *const ArcInner<T>)`, but this created a misaligned
|
||||
// reference (see #54908).
|
||||
let layout = Layout::new::<ArcInner<()>>().extend(value_layout).unwrap().0.pad_to_align();
|
||||
let layout = arcinner_layout_for_value_layout(value_layout);
|
||||
|
||||
let ptr = allocate(layout)?;
|
||||
|
||||
@ -1246,7 +1247,7 @@ impl<T> Arc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy elements from slice into newly allocated Arc<\[T\]>
|
||||
/// Copy elements from slice into newly allocated `Arc<[T]>`
|
||||
///
|
||||
/// Unsafe because the caller must either take ownership or bind `T: Copy`.
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
@ -1260,6 +1261,49 @@ impl<T> Arc<[T]> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Create an `Arc<[T]>` by reusing the underlying memory
|
||||
/// of a `Vec<T>`. This will return the vector if the existing allocation
|
||||
/// is not large enough.
|
||||
#[cfg(not(no_global_oom_handling))]
|
||||
fn try_from_vec_in_place(mut v: Vec<T>) -> Result<Arc<[T]>, Vec<T>> {
|
||||
let layout_elements = Layout::array::<T>(v.len()).unwrap();
|
||||
let layout_allocation = Layout::array::<T>(v.capacity()).unwrap();
|
||||
let layout_arcinner = arcinner_layout_for_value_layout(layout_elements);
|
||||
let mut ptr = NonNull::new(v.as_mut_ptr()).expect("`Vec<T>` stores `NonNull<T>`");
|
||||
if layout_arcinner.size() > layout_allocation.size()
|
||||
|| layout_arcinner.align() > layout_allocation.align()
|
||||
{
|
||||
// Can't fit - calling `grow` would involve `realloc`
|
||||
// (which copies the elements), followed by copying again.
|
||||
return Err(v);
|
||||
}
|
||||
if layout_arcinner.size() < layout_allocation.size()
|
||||
|| layout_arcinner.align() < layout_allocation.align()
|
||||
{
|
||||
// We need to shrink the allocation so that it fits
|
||||
// https://doc.rust-lang.org/nightly/std/alloc/trait.Allocator.html#memory-fitting
|
||||
// SAFETY:
|
||||
// - Vec allocates by requesting `Layout::array::<T>(capacity)`, so this capacity matches
|
||||
// - `layout_arcinner` is smaller
|
||||
// If this fails, the ownership has not been transferred
|
||||
if let Ok(p) = unsafe { Global.shrink(ptr.cast(), layout_allocation, layout_arcinner) }
|
||||
{
|
||||
ptr = p.cast();
|
||||
} else {
|
||||
return Err(v);
|
||||
}
|
||||
}
|
||||
// Make sure the vec's memory isn't deallocated now
|
||||
let v = mem::ManuallyDrop::new(v);
|
||||
let ptr: *mut ArcInner<[T]> = ptr::slice_from_raw_parts_mut(ptr.as_ptr(), v.len()) as _;
|
||||
unsafe {
|
||||
ptr::copy(ptr.cast::<T>(), &mut (*ptr).data as *mut [T] as *mut T, v.len());
|
||||
ptr::write(&mut (*ptr).strong, atomic::AtomicUsize::new(1));
|
||||
ptr::write(&mut (*ptr).weak, atomic::AtomicUsize::new(1));
|
||||
Ok(Self::from_ptr(ptr))
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs an `Arc<[T]>` from an iterator known to be of a certain size.
|
||||
///
|
||||
/// Behavior is undefined should the size be wrong.
|
||||
@ -2571,14 +2615,17 @@ impl<T> From<Vec<T>> for Arc<[T]> {
|
||||
/// assert_eq!(&[1, 2, 3], &shared[..]);
|
||||
/// ```
|
||||
#[inline]
|
||||
fn from(mut v: Vec<T>) -> Arc<[T]> {
|
||||
unsafe {
|
||||
let arc = Arc::copy_from_slice(&v);
|
||||
|
||||
// Allow the Vec to free its memory, but not destroy its contents
|
||||
v.set_len(0);
|
||||
|
||||
arc
|
||||
fn from(v: Vec<T>) -> Arc<[T]> {
|
||||
match Arc::try_from_vec_in_place(v) {
|
||||
Ok(rc) => rc,
|
||||
Err(mut v) => {
|
||||
unsafe {
|
||||
let rc = Arc::copy_from_slice(&v);
|
||||
// Allow the Vec to free its memory, but not destroy its contents
|
||||
v.set_len(0);
|
||||
rc
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -210,3 +210,18 @@ fn weak_may_dangle() {
|
||||
// `val` dropped here while still borrowed
|
||||
// borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak`
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn arc_from_vec_opt() {
|
||||
let mut v = Vec::with_capacity(64);
|
||||
v.push(0usize);
|
||||
let addr = v.as_ptr().cast::<u8>();
|
||||
let arc: Arc<[_]> = v.into();
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
arc.as_ptr().cast::<u8>().offset_from(addr),
|
||||
(std::mem::size_of::<usize>() * 2) as isize,
|
||||
"Vector allocation not reused"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -206,3 +206,18 @@ fn weak_may_dangle() {
|
||||
// `val` dropped here while still borrowed
|
||||
// borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak`
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rc_from_vec_opt() {
|
||||
let mut v = Vec::with_capacity(64);
|
||||
v.push(0usize);
|
||||
let addr = v.as_ptr().cast::<u8>();
|
||||
let rc: Rc<[_]> = v.into();
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
rc.as_ptr().cast::<u8>().offset_from(addr),
|
||||
(std::mem::size_of::<usize>() * 2) as isize,
|
||||
"Vector allocation not reused"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,7 @@ where
|
||||
|
||||
impl<T: Generator<ResumeTy, Yield = ()>> Future for GenFuture<T> {
|
||||
type Output = T::Return;
|
||||
#[track_caller]
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
// SAFETY: Safe because we're !Unpin + !Drop, and this is just a field projection.
|
||||
let gen = unsafe { Pin::map_unchecked_mut(self, |s| &mut s.0) };
|
||||
|
@ -338,6 +338,7 @@ pub macro debug_assert_matches($($arg:tt)*) {
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable(feature = "matches_macro", since = "1.42.0")]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "matches_macro")]
|
||||
macro_rules! matches {
|
||||
($expression:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => {
|
||||
match $expression {
|
||||
|
@ -168,23 +168,7 @@ fn set_compiler(
|
||||
// compiler already takes into account the triple in question.
|
||||
t if t.contains("android") => {
|
||||
if let Some(ndk) = config.and_then(|c| c.ndk.as_ref()) {
|
||||
let mut triple_iter = target.triple.split("-");
|
||||
let triple_translated = if let Some(arch) = triple_iter.next() {
|
||||
let arch_new = match arch {
|
||||
"arm" | "armv7" | "armv7neon" | "thumbv7" | "thumbv7neon" => "armv7a",
|
||||
other => other,
|
||||
};
|
||||
std::iter::once(arch_new).chain(triple_iter).collect::<Vec<&str>>().join("-")
|
||||
} else {
|
||||
target.triple.to_string()
|
||||
};
|
||||
|
||||
// API 19 is the earliest API level supported by NDK r25b but AArch64 and x86_64 support
|
||||
// begins at API level 21.
|
||||
let api_level =
|
||||
if t.contains("aarch64") || t.contains("x86_64") { "21" } else { "19" };
|
||||
let compiler = format!("{}{}-{}", triple_translated, api_level, compiler.clang());
|
||||
cfg.compiler(ndk.join("bin").join(compiler));
|
||||
cfg.compiler(ndk_compiler(compiler, &*target.triple, ndk));
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,8 +220,28 @@ fn set_compiler(
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn ndk_compiler(compiler: Language, triple: &str, ndk: &Path) -> PathBuf {
|
||||
let mut triple_iter = triple.split("-");
|
||||
let triple_translated = if let Some(arch) = triple_iter.next() {
|
||||
let arch_new = match arch {
|
||||
"arm" | "armv7" | "armv7neon" | "thumbv7" | "thumbv7neon" => "armv7a",
|
||||
other => other,
|
||||
};
|
||||
std::iter::once(arch_new).chain(triple_iter).collect::<Vec<&str>>().join("-")
|
||||
} else {
|
||||
triple.to_string()
|
||||
};
|
||||
|
||||
// API 19 is the earliest API level supported by NDK r25b but AArch64 and x86_64 support
|
||||
// begins at API level 21.
|
||||
let api_level =
|
||||
if triple.contains("aarch64") || triple.contains("x86_64") { "21" } else { "19" };
|
||||
let compiler = format!("{}{}-{}", triple_translated, api_level, compiler.clang());
|
||||
ndk.join("bin").join(compiler)
|
||||
}
|
||||
|
||||
/// The target programming language for a native compiler.
|
||||
enum Language {
|
||||
pub(crate) enum Language {
|
||||
/// The compiler is targeting C.
|
||||
C,
|
||||
/// The compiler is targeting C++.
|
||||
|
@ -15,6 +15,7 @@ use std::str::FromStr;
|
||||
|
||||
use crate::builder::TaskPath;
|
||||
use crate::cache::{Interned, INTERNER};
|
||||
use crate::cc_detect::{ndk_compiler, Language};
|
||||
use crate::channel::{self, GitInfo};
|
||||
pub use crate::flags::Subcommand;
|
||||
use crate::flags::{Color, Flags};
|
||||
@ -1237,8 +1238,12 @@ impl Config {
|
||||
if let Some(s) = cfg.no_std {
|
||||
target.no_std = s;
|
||||
}
|
||||
target.cc = cfg.cc.map(PathBuf::from);
|
||||
target.cxx = cfg.cxx.map(PathBuf::from);
|
||||
target.cc = cfg.cc.map(PathBuf::from).or_else(|| {
|
||||
target.ndk.as_ref().map(|ndk| ndk_compiler(Language::C, &triple, ndk))
|
||||
});
|
||||
target.cxx = cfg.cxx.map(PathBuf::from).or_else(|| {
|
||||
target.ndk.as_ref().map(|ndk| ndk_compiler(Language::CPlusPlus, &triple, ndk))
|
||||
});
|
||||
target.ar = cfg.ar.map(PathBuf::from);
|
||||
target.ranlib = cfg.ranlib.map(PathBuf::from);
|
||||
target.linker = cfg.linker.map(PathBuf::from);
|
||||
|
@ -9,7 +9,7 @@ RUN apt-get update -y && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-
|
||||
curl \
|
||||
file \
|
||||
g++ \
|
||||
gcc-arm-linux-gnueabihf \
|
||||
g++-arm-linux-gnueabihf \
|
||||
git \
|
||||
libc6-dev \
|
||||
libc6-dev-armhf-cross \
|
||||
|
@ -76,6 +76,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
|
||||
for predicate in predicates {
|
||||
debug!("testing predicate {:?}", predicate);
|
||||
let obligation = traits::Obligation::new(
|
||||
infcx.tcx,
|
||||
traits::ObligationCause::dummy(),
|
||||
param_env,
|
||||
predicate,
|
||||
|
@ -217,10 +217,7 @@ h1 a,
|
||||
.search-results a,
|
||||
.module-item .stab,
|
||||
.import-item .stab,
|
||||
.result-name .primitive > i, .result-name .keyword > i,
|
||||
.method .where,
|
||||
.fn .where,
|
||||
.where.fmt-newline {
|
||||
.result-name .primitive > i, .result-name .keyword > i {
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
@ -1162,6 +1159,8 @@ pre.rust .doccomment {
|
||||
width: max-content;
|
||||
top: -2px;
|
||||
z-index: 1;
|
||||
background-color: var(--tooltip-background-color);
|
||||
color: var(--tooltip-color);
|
||||
}
|
||||
|
||||
.example-wrap .tooltip::before {
|
||||
@ -1170,10 +1169,10 @@ pre.rust .doccomment {
|
||||
top: 50%;
|
||||
left: 16px;
|
||||
margin-top: -5px;
|
||||
border-width: 5px;
|
||||
border-style: solid;
|
||||
display: none;
|
||||
z-index: 1;
|
||||
border: 5px solid transparent;
|
||||
border-right-color: var(--tooltip-background-color);
|
||||
}
|
||||
|
||||
.example-wrap.ignore .tooltip::after {
|
||||
@ -1393,12 +1392,6 @@ h3.variant {
|
||||
background-color: var(--button-background-color);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 2px;
|
||||
color: var(--settings-button-color);
|
||||
}
|
||||
|
||||
#settings-menu > a:hover, #settings-menu > a:focus,
|
||||
#help-button > a:hover, #help-button > a:focus {
|
||||
border-color: var(--settings-button-border-focus);
|
||||
}
|
||||
|
||||
#copy-path {
|
||||
|
@ -7,8 +7,6 @@ Original by Dempfi (https://github.com/dempfi/ayu)
|
||||
--main-background-color: #0f1419;
|
||||
--main-color: #c5c5c5;
|
||||
--settings-input-color: #ffb454;
|
||||
--settings-button-color: #fff;
|
||||
--settings-button-border-focus: #e0e0e0;
|
||||
--sidebar-background-color: #14191f;
|
||||
--sidebar-background-color-hover: rgba(70, 70, 70, 0.33);
|
||||
--code-block-background-color: #191f26;
|
||||
@ -67,6 +65,8 @@ Original by Dempfi (https://github.com/dempfi/ayu)
|
||||
--test-arrow-hover-background-color: rgba(57, 175, 215, 0.368);
|
||||
--target-background-color: rgba(255, 236, 164, 0.06);
|
||||
--target-border-color: rgba(255, 180, 76, 0.85);
|
||||
--tooltip-background-color: #314559;
|
||||
--tooltip-color: #c5c5c5;
|
||||
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
|
||||
drop-shadow(0 1px 0 #fff)
|
||||
drop-shadow(-1px 0 0 #fff)
|
||||
@ -162,15 +162,6 @@ details.rustdoc-toggle > summary::before {
|
||||
color: #788797;
|
||||
}
|
||||
|
||||
.tooltip::after {
|
||||
background-color: #314559;
|
||||
color: #c5c5c5;
|
||||
}
|
||||
|
||||
.tooltip::before {
|
||||
border-color: transparent #314559 transparent transparent;
|
||||
}
|
||||
|
||||
#titles > button.selected {
|
||||
background-color: #141920 !important;
|
||||
border-bottom: 1px solid #ffb44c !important;
|
||||
@ -208,10 +199,19 @@ kbd {
|
||||
box-shadow: inset 0 -1px 0 #5c6773;
|
||||
}
|
||||
|
||||
#settings-menu > a, #help-button > a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#settings-menu > a img {
|
||||
filter: invert(100);
|
||||
}
|
||||
|
||||
#settings-menu > a:hover, #settings-menu > a:focus,
|
||||
#help-button > a:hover, #help-button > a:focus {
|
||||
border-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.search-results .result-name span.alias {
|
||||
color: #c5c5c5;
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
--main-background-color: #353535;
|
||||
--main-color: #ddd;
|
||||
--settings-input-color: #2196f3;
|
||||
--settings-button-color: #000;
|
||||
--settings-button-border-focus: #ffb900;
|
||||
--sidebar-background-color: #505050;
|
||||
--sidebar-background-color-hover: #676767;
|
||||
--code-block-background-color: #2A2A2A;
|
||||
@ -62,6 +60,8 @@
|
||||
--test-arrow-hover-background-color: #4e8bca;
|
||||
--target-background-color: #494a3d;
|
||||
--target-border-color: #bb7410;
|
||||
--tooltip-background-color: #000;
|
||||
--tooltip-color: #fff;
|
||||
--rust-logo-filter: drop-shadow(1px 0 0px #fff)
|
||||
drop-shadow(0 1px 0 #fff)
|
||||
drop-shadow(-1px 0 0 #fff)
|
||||
@ -84,16 +84,6 @@ details.rustdoc-toggle > summary::before {
|
||||
filter: invert(100%);
|
||||
}
|
||||
|
||||
.tooltip::after {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.tooltip::before {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
#titles > button:not(.selected) {
|
||||
background-color: #252525;
|
||||
border-top-color: #252525;
|
||||
@ -114,6 +104,15 @@ kbd {
|
||||
box-shadow: inset 0 -1px 0 #c6cbd1;
|
||||
}
|
||||
|
||||
#settings-menu > a, #help-button > a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#settings-menu > a:hover, #settings-menu > a:focus,
|
||||
#help-button > a:hover, #help-button > a:focus {
|
||||
border-color: #ffb900;
|
||||
}
|
||||
|
||||
.search-results .result-name span.alias {
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
--main-background-color: white;
|
||||
--main-color: black;
|
||||
--settings-input-color: #2196f3;
|
||||
--settings-button-color: #000;
|
||||
--settings-button-border-focus: #717171;
|
||||
--sidebar-background-color: #F5F5F5;
|
||||
--sidebar-background-color-hover: #E0E0E0;
|
||||
--code-block-background-color: #F5F5F5;
|
||||
@ -60,8 +58,10 @@
|
||||
--test-arrow-background-color: rgba(78, 139, 202, 0.2);
|
||||
--test-arrow-hover-color: #f5f5f5;
|
||||
--test-arrow-hover-background-color: #4e8bca;
|
||||
--target-background-color: #fdFfd3;
|
||||
--target-background-color: #fdffd3;
|
||||
--target-border-color: #ad7c37;
|
||||
--tooltip-background-color: #fdffd3;
|
||||
--tooltip-color: #fff;
|
||||
--rust-logo-filter: initial;
|
||||
/* match border-color; uses https://codepen.io/sosuke/pen/Pjoqqp */
|
||||
--crate-search-div-filter: invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg)
|
||||
@ -77,15 +77,6 @@ body.source .example-wrap pre.rust a {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.tooltip::after {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tooltip::before {
|
||||
border-color: transparent black transparent transparent;
|
||||
}
|
||||
|
||||
#titles > button:not(.selected) {
|
||||
background-color: #e6e6e6;
|
||||
border-top-color: #e6e6e6;
|
||||
@ -106,6 +97,15 @@ kbd {
|
||||
box-shadow: inset 0 -1px 0 #c6cbd1;
|
||||
}
|
||||
|
||||
#settings-menu > a, #help-button > a {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
#settings-menu > a:hover, #settings-menu > a:focus,
|
||||
#help-button > a:hover, #help-button > a:focus {
|
||||
border-color: #717171;
|
||||
}
|
||||
|
||||
.search-results .result-name span.alias {
|
||||
color: #000;
|
||||
}
|
||||
|
@ -9,13 +9,16 @@
|
||||
const isSettingsPage = window.location.pathname.endsWith("/settings.html");
|
||||
|
||||
function changeSetting(settingName, value) {
|
||||
if (settingName === "theme") {
|
||||
const useSystem = value === "system preference" ? "true" : "false";
|
||||
updateLocalStorage("use-system-theme", useSystem);
|
||||
}
|
||||
updateLocalStorage(settingName, value);
|
||||
|
||||
switch (settingName) {
|
||||
case "theme":
|
||||
case "preferred-dark-theme":
|
||||
case "preferred-light-theme":
|
||||
case "use-system-theme":
|
||||
updateSystemTheme();
|
||||
updateLightAndDark();
|
||||
break;
|
||||
@ -45,7 +48,6 @@
|
||||
}
|
||||
|
||||
function showLightAndDark() {
|
||||
addClass(document.getElementById("theme").parentElement, "hidden");
|
||||
removeClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
|
||||
removeClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
|
||||
}
|
||||
@ -53,11 +55,11 @@
|
||||
function hideLightAndDark() {
|
||||
addClass(document.getElementById("preferred-light-theme").parentElement, "hidden");
|
||||
addClass(document.getElementById("preferred-dark-theme").parentElement, "hidden");
|
||||
removeClass(document.getElementById("theme").parentElement, "hidden");
|
||||
}
|
||||
|
||||
function updateLightAndDark() {
|
||||
if (getSettingValue("use-system-theme") !== "false") {
|
||||
const useSystem = getSettingValue("use-system-theme");
|
||||
if (useSystem === "true" || (useSystem === null && getSettingValue("theme") === null)) {
|
||||
showLightAndDark();
|
||||
} else {
|
||||
hideLightAndDark();
|
||||
@ -91,7 +93,18 @@
|
||||
});
|
||||
onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"), elem => {
|
||||
const settingId = elem.name;
|
||||
const settingValue = getSettingValue(settingId);
|
||||
let settingValue = getSettingValue(settingId);
|
||||
if (settingId === "theme") {
|
||||
const useSystem = getSettingValue("use-system-theme");
|
||||
if (useSystem === "true" || settingValue === null) {
|
||||
if (useSystem !== "false") {
|
||||
settingValue = "system preference";
|
||||
} else {
|
||||
// This is the default theme.
|
||||
settingValue = "light";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (settingValue !== null && settingValue !== "null") {
|
||||
elem.checked = settingValue === elem.value;
|
||||
}
|
||||
@ -120,26 +133,30 @@
|
||||
|
||||
if (setting["options"] !== undefined) {
|
||||
// This is a select setting.
|
||||
output += `<div class="radio-line" id="${js_data_name}">\
|
||||
<span class="setting-name">${setting_name}</span>\
|
||||
<div class="choices">`;
|
||||
output += `\
|
||||
<div class="radio-line" id="${js_data_name}">
|
||||
<span class="setting-name">${setting_name}</span>
|
||||
<div class="choices">`;
|
||||
onEach(setting["options"], option => {
|
||||
const checked = option === setting["default"] ? " checked" : "";
|
||||
const full = `${js_data_name}-${option.replace(/ /g,"-")}`;
|
||||
|
||||
output += `<label for="${js_data_name}-${option}" class="choice">\
|
||||
<input type="radio" name="${js_data_name}" \
|
||||
id="${js_data_name}-${option}" value="${option}"${checked}>\
|
||||
<span>${option}</span>\
|
||||
</label>`;
|
||||
output += `\
|
||||
<label for="${full}" class="choice">
|
||||
<input type="radio" name="${js_data_name}"
|
||||
id="${full}" value="${option}"${checked}>
|
||||
<span>${option}</span>
|
||||
</label>`;
|
||||
});
|
||||
output += "</div></div>";
|
||||
} else {
|
||||
// This is a toggle.
|
||||
const checked = setting["default"] === true ? " checked" : "";
|
||||
output += `<label class="toggle">\
|
||||
<input type="checkbox" id="${js_data_name}"${checked}>\
|
||||
<span class="label">${setting_name}</span>\
|
||||
</label>`;
|
||||
output += `\
|
||||
<label class="toggle">\
|
||||
<input type="checkbox" id="${js_data_name}"${checked}>\
|
||||
<span class="label">${setting_name}</span>\
|
||||
</label>`;
|
||||
}
|
||||
output += "</div>";
|
||||
}
|
||||
@ -156,16 +173,11 @@
|
||||
theme_names.push("light", "dark", "ayu");
|
||||
|
||||
const settings = [
|
||||
{
|
||||
"name": "Use system theme",
|
||||
"js_name": "use-system-theme",
|
||||
"default": true,
|
||||
},
|
||||
{
|
||||
"name": "Theme",
|
||||
"js_name": "theme",
|
||||
"default": "light",
|
||||
"options": theme_names,
|
||||
"default": "system preference",
|
||||
"options": theme_names.concat("system preference"),
|
||||
},
|
||||
{
|
||||
"name": "Preferred light theme",
|
||||
|
@ -40,6 +40,17 @@ endif
|
||||
# e.g. for `$(CC) -o $(RUN_BINFILE)`.
|
||||
RUN_BINFILE = $(TMPDIR)/$(1)
|
||||
|
||||
# Invoke the generated binary on the remote machine if compiletest was
|
||||
# configured to use a remote test device, otherwise run it on the current host.
|
||||
ifdef REMOTE_TEST_CLIENT
|
||||
# FIXME: if a test requires additional files, this will need to be changed to
|
||||
# also push them (by changing the 0 to the number of additional files, and
|
||||
# providing the path of the additional files as the last arguments).
|
||||
EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE)
|
||||
else
|
||||
EXECUTE = $(RUN_BINFILE)
|
||||
endif
|
||||
|
||||
# RUN and FAIL are basic way we will invoke the generated binary. On
|
||||
# non-windows platforms, they set the LD_LIBRARY_PATH environment
|
||||
# variable before running the binary.
|
||||
@ -50,16 +61,16 @@ BIN = $(1)
|
||||
UNAME = $(shell uname)
|
||||
|
||||
ifeq ($(UNAME),Darwin)
|
||||
RUN = $(TARGET_RPATH_ENV) $(RUN_BINFILE)
|
||||
FAIL = $(TARGET_RPATH_ENV) $(RUN_BINFILE) && exit 1 || exit 0
|
||||
RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
|
||||
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
|
||||
DYLIB_GLOB = lib$(1)*.dylib
|
||||
DYLIB = $(TMPDIR)/lib$(1).dylib
|
||||
STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
STATICLIB_GLOB = lib$(1)*.a
|
||||
else
|
||||
ifdef IS_WINDOWS
|
||||
RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(RUN_BINFILE)
|
||||
FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(RUN_BINFILE) && exit 1 || exit 0
|
||||
RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE)
|
||||
FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0
|
||||
DYLIB_GLOB = $(1)*.dll
|
||||
DYLIB = $(TMPDIR)/$(1).dll
|
||||
ifdef IS_MSVC
|
||||
@ -73,8 +84,8 @@ endif
|
||||
BIN = $(1).exe
|
||||
LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)")
|
||||
else
|
||||
RUN = $(TARGET_RPATH_ENV) $(RUN_BINFILE)
|
||||
FAIL = $(TARGET_RPATH_ENV) $(RUN_BINFILE) && exit 1 || exit 0
|
||||
RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
|
||||
FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
|
||||
DYLIB_GLOB = lib$(1)*.so
|
||||
DYLIB = $(TMPDIR)/lib$(1).so
|
||||
STATICLIB = $(TMPDIR)/lib$(1).a
|
||||
|
@ -1,6 +1,7 @@
|
||||
# ignore-cross-compile $(call RUN,foo) expects to run the target executable natively
|
||||
# so it won't work with remote-test-server
|
||||
# ignore-none no-std is not supported
|
||||
# ignore-wasm32 FIXME: don't attempt to compile C++ to WASM
|
||||
# ignore-wasm64 FIXME: don't attempt to compile C++ to WASM
|
||||
# ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std`
|
||||
# ignore-musl FIXME: this makefile needs teaching how to use a musl toolchain
|
||||
# (see dist-i586-gnu-i586-i686-musl Dockerfile)
|
||||
|
||||
|
@ -4,7 +4,7 @@ show-text: true
|
||||
|
||||
define-function: (
|
||||
"check-colors",
|
||||
(theme),
|
||||
(theme, background, color, border),
|
||||
[
|
||||
// Setting the theme.
|
||||
("local-storage", {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}),
|
||||
@ -30,6 +30,25 @@ define-function: (
|
||||
".docblock .example-wrap.compile_fail",
|
||||
{"border-left": "2px solid rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.compile_fail .tooltip::after",
|
||||
{
|
||||
"content": '"This example deliberately fails to compile"',
|
||||
"text-align": "center",
|
||||
"padding": "5px 3px 3px",
|
||||
"background-color": |background|,
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.compile_fail .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
|
||||
// should_panic block
|
||||
("assert-css", (
|
||||
@ -51,6 +70,25 @@ define-function: (
|
||||
".docblock .example-wrap.should_panic",
|
||||
{"border-left": "2px solid rgb(255, 0, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.should_panic .tooltip::after",
|
||||
{
|
||||
"content": '"This example panics"',
|
||||
"text-align": "center",
|
||||
"padding": "5px 3px 3px",
|
||||
"background-color": |background|,
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.should_panic .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
|
||||
// ignore block
|
||||
("assert-css", (
|
||||
@ -72,9 +110,43 @@ define-function: (
|
||||
".docblock .example-wrap.ignore",
|
||||
{"border-left": "2px solid rgb(255, 142, 0)"},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.ignore .tooltip::after",
|
||||
{
|
||||
"content": '"This example is not tested"',
|
||||
"text-align": "center",
|
||||
"padding": "5px 3px 3px",
|
||||
"background-color": |background|,
|
||||
"color": |color|,
|
||||
"border": "1px solid " + |border|,
|
||||
},
|
||||
)),
|
||||
("assert-css", (
|
||||
".docblock .example-wrap.ignore .tooltip::before",
|
||||
{
|
||||
"border-width": "5px",
|
||||
"border-style": "solid",
|
||||
"border-color": "rgba(0, 0, 0, 0) " + |background| + " rgba(0, 0, 0, 0) rgba(0, 0, 0, 0)",
|
||||
},
|
||||
)),
|
||||
],
|
||||
)
|
||||
|
||||
call-function: ("check-colors", ("ayu"))
|
||||
call-function: ("check-colors", ("dark"))
|
||||
call-function: ("check-colors", ("light"))
|
||||
call-function: ("check-colors", {
|
||||
"theme": "ayu",
|
||||
"background": "rgb(49, 69, 89)",
|
||||
"color": "rgb(197, 197, 197)",
|
||||
"border": "rgb(92, 103, 115)",
|
||||
})
|
||||
call-function: ("check-colors", {
|
||||
"theme": "dark",
|
||||
"background": "rgb(0, 0, 0)",
|
||||
"color": "rgb(255, 255, 255)",
|
||||
"border": "rgb(224, 224, 224)",
|
||||
})
|
||||
call-function: ("check-colors", {
|
||||
"theme": "light",
|
||||
"background": "rgb(253, 255, 211)",
|
||||
"color": "rgb(255, 255, 255)",
|
||||
"border": "rgb(224, 224, 224)",
|
||||
})
|
||||
|
@ -37,8 +37,7 @@ click: "#settings-menu"
|
||||
wait-for: "#settings"
|
||||
|
||||
// We check that the "Use system theme" is disabled.
|
||||
assert-property: ("#use-system-theme", {"checked": "false"})
|
||||
assert: "//*[@class='setting-line']//span[text()='Use system theme']"
|
||||
assert-property: ("#theme-system-preference", {"checked": "false"})
|
||||
// Meaning that only the "theme" menu is showing up.
|
||||
assert: ".setting-line:not(.hidden) #theme"
|
||||
assert: ".setting-line.hidden #preferred-dark-theme"
|
||||
@ -115,13 +114,6 @@ assert-css: (
|
||||
"border-color": "rgb(221, 221, 221)",
|
||||
},
|
||||
)
|
||||
assert-css: (
|
||||
"#use-system-theme",
|
||||
{
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
"border-color": "rgb(221, 221, 221)",
|
||||
}
|
||||
)
|
||||
// Let's start with the hover for toggles.
|
||||
move-cursor-to: "#auto-hide-large-items"
|
||||
assert-css: (
|
||||
@ -131,14 +123,6 @@ assert-css: (
|
||||
"border-color": "rgb(33, 150, 243)",
|
||||
},
|
||||
)
|
||||
move-cursor-to: "#use-system-theme"
|
||||
assert-css: (
|
||||
"#use-system-theme",
|
||||
{
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
"border-color": "rgb(33, 150, 243)",
|
||||
}
|
||||
)
|
||||
move-cursor-to: "#settings-menu > a"
|
||||
// Let's now check with the focus for toggles.
|
||||
focus: "#auto-hide-large-items"
|
||||
@ -150,15 +134,6 @@ assert-css: (
|
||||
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||
},
|
||||
)
|
||||
focus: "#use-system-theme"
|
||||
assert-css: (
|
||||
"#use-system-theme",
|
||||
{
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
"border-color": "rgb(221, 221, 221)",
|
||||
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||
},
|
||||
)
|
||||
// Now we check we both focus and hover for toggles.
|
||||
move-cursor-to: "#auto-hide-large-items"
|
||||
focus: "#auto-hide-large-items"
|
||||
@ -170,24 +145,12 @@ assert-css: (
|
||||
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||
},
|
||||
)
|
||||
move-cursor-to: "#use-system-theme"
|
||||
focus: "#use-system-theme"
|
||||
assert-css: (
|
||||
"#use-system-theme",
|
||||
{
|
||||
"background-color": "rgba(0, 0, 0, 0)",
|
||||
"border-color": "rgb(33, 150, 243)",
|
||||
"box-shadow": "rgb(33, 150, 243) 0px 0px 1px 1px",
|
||||
},
|
||||
)
|
||||
|
||||
// We now switch the display.
|
||||
click: "#use-system-theme"
|
||||
click: "#theme-system-preference"
|
||||
// Wait for the hidden element to show up.
|
||||
wait-for: ".setting-line:not(.hidden) #preferred-dark-theme"
|
||||
assert: ".setting-line:not(.hidden) #preferred-light-theme"
|
||||
// Check that the theme picking is hidden.
|
||||
assert: ".setting-line.hidden #theme"
|
||||
|
||||
// We check their text as well.
|
||||
assert-text: ("#preferred-dark-theme .setting-name", "Preferred dark theme")
|
||||
|
@ -2,31 +2,66 @@
|
||||
goto: "file://" + |DOC_PATH| + "/test_docs/index.html"
|
||||
local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
|
||||
reload:
|
||||
|
||||
store-value: (background_light, "rgb(255, 255, 255)")
|
||||
store-value: (background_dark, "rgb(53, 53, 53)")
|
||||
store-value: (background_ayu, "rgb(15, 20, 25)")
|
||||
|
||||
click: "#settings-menu"
|
||||
wait-for: "#theme-ayu"
|
||||
click: "#theme-ayu"
|
||||
// should be the ayu theme so let's check the color.
|
||||
wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
|
||||
wait-for-css: ("body", { "background-color": |background_ayu| })
|
||||
assert-local-storage: { "rustdoc-theme": "ayu" }
|
||||
click: "#theme-light"
|
||||
// should be the light theme so let's check the color.
|
||||
wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
|
||||
wait-for-css: ("body", { "background-color": |background_light| })
|
||||
assert-local-storage: { "rustdoc-theme": "light" }
|
||||
click: "#theme-dark"
|
||||
// Should be the dark theme so let's check the color.
|
||||
wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
|
||||
wait-for-css: ("body", { "background-color": |background_dark| })
|
||||
assert-local-storage: { "rustdoc-theme": "dark" }
|
||||
|
||||
local-storage: {
|
||||
"rustdoc-preferred-light-theme": "light",
|
||||
"rustdoc-preferred-dark-theme": "light",
|
||||
}
|
||||
goto: "file://" + |DOC_PATH| + "/settings.html"
|
||||
|
||||
wait-for: "#settings"
|
||||
click: "#theme-light"
|
||||
wait-for-css: ("body", { "background-color": "rgb(255, 255, 255)" })
|
||||
wait-for-css: ("body", { "background-color": |background_light| })
|
||||
assert-local-storage: { "rustdoc-theme": "light" }
|
||||
|
||||
click: "#theme-dark"
|
||||
wait-for-css: ("body", { "background-color": "rgb(53, 53, 53)" })
|
||||
wait-for-css: ("body", { "background-color": |background_dark| })
|
||||
assert-local-storage: { "rustdoc-theme": "dark" }
|
||||
|
||||
click: "#theme-ayu"
|
||||
wait-for-css: ("body", { "background-color": "rgb(15, 20, 25)" })
|
||||
wait-for-css: ("body", { "background-color": |background_ayu| })
|
||||
assert-local-storage: { "rustdoc-theme": "ayu" }
|
||||
|
||||
assert-local-storage-false: { "rustdoc-use-system-theme": "true" }
|
||||
click: "#theme-system-preference"
|
||||
wait-for: ".setting-line:not(.hidden) #preferred-light-theme"
|
||||
assert-local-storage: { "rustdoc-use-system-theme": "true" }
|
||||
// We click on both preferred light and dark themes to be sure that there is a change.
|
||||
click: "#preferred-light-theme-dark"
|
||||
click: "#preferred-dark-theme-dark"
|
||||
wait-for-css: ("body", { "background-color": |background_dark| })
|
||||
|
||||
reload:
|
||||
// Ensure that the "preferred themes" are still displayed.
|
||||
wait-for: ".setting-line:not(.hidden) #preferred-light-theme"
|
||||
click: "#theme-light"
|
||||
wait-for-css: ("body", { "background-color": |background_light| })
|
||||
assert-local-storage: { "rustdoc-theme": "light" }
|
||||
// Ensure it's now hidden again
|
||||
wait-for: ".setting-line.hidden #preferred-light-theme"
|
||||
// And ensure the theme was rightly set.
|
||||
wait-for-css: ("body", { "background-color": |background_light| })
|
||||
assert-local-storage: { "rustdoc-theme": "light" }
|
||||
|
||||
reload:
|
||||
wait-for: "#settings"
|
||||
assert: ".setting-line.hidden #preferred-light-theme"
|
||||
|
17
src/test/ui/async-await/in-trait/early-bound-1.rs
Normal file
17
src/test/ui/async-await/in-trait/early-bound-1.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait Foo {
|
||||
async fn foo(&mut self);
|
||||
}
|
||||
|
||||
struct MyFoo<'a>(&'a mut ());
|
||||
|
||||
impl<'a> Foo for MyFoo<'a> {
|
||||
async fn foo(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
15
src/test/ui/async-await/in-trait/early-bound-2.rs
Normal file
15
src/test/ui/async-await/in-trait/early-bound-2.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
|
||||
#![feature(async_fn_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait Foo {
|
||||
async fn foo(&mut self);
|
||||
}
|
||||
|
||||
impl<T: Foo> Foo for &mut T {
|
||||
async fn foo(&mut self) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
13
src/test/ui/async-await/in-trait/object-safety.rs
Normal file
13
src/test/ui/async-await/in-trait/object-safety.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// 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 Foo {
|
||||
async fn foo(&self);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: &dyn Foo = todo!();
|
||||
//~^ ERROR the trait `Foo` cannot be made into an object
|
||||
}
|
27
src/test/ui/async-await/in-trait/object-safety.stderr
Normal file
27
src/test/ui/async-await/in-trait/object-safety.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/object-safety.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[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:11:12
|
||||
|
|
||||
LL | let x: &dyn Foo = todo!();
|
||||
| ^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:7:14
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | async fn foo(&self);
|
||||
| ^^^ ...because method `foo` is `async`
|
||||
= help: consider moving `foo` to another trait
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0038`.
|
76
src/test/ui/async-await/track-caller/panic-track-caller.rs
Normal file
76
src/test/ui/async-await/track-caller/panic-track-caller.rs
Normal file
@ -0,0 +1,76 @@
|
||||
// run-pass
|
||||
// edition:2021
|
||||
// needs-unwind
|
||||
#![feature(closure_track_caller)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::panic;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::task::{Context, Poll, Wake};
|
||||
use std::thread::{self, Thread};
|
||||
|
||||
/// A waker that wakes up the current thread when called.
|
||||
struct ThreadWaker(Thread);
|
||||
|
||||
impl Wake for ThreadWaker {
|
||||
fn wake(self: Arc<Self>) {
|
||||
self.0.unpark();
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a future to completion on the current thread.
|
||||
fn block_on<T>(fut: impl Future<Output = T>) -> T {
|
||||
// Pin the future so it can be polled.
|
||||
let mut fut = Box::pin(fut);
|
||||
|
||||
// Create a new context to be passed to the future.
|
||||
let t = thread::current();
|
||||
let waker = Arc::new(ThreadWaker(t)).into();
|
||||
let mut cx = Context::from_waker(&waker);
|
||||
|
||||
// Run the future to completion.
|
||||
loop {
|
||||
match fut.as_mut().poll(&mut cx) {
|
||||
Poll::Ready(res) => return res,
|
||||
Poll::Pending => thread::park(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn bar() {
|
||||
panic!()
|
||||
}
|
||||
|
||||
async fn foo() {
|
||||
bar().await
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
async fn bar_track_caller() {
|
||||
panic!()
|
||||
}
|
||||
|
||||
async fn foo_track_caller() {
|
||||
bar_track_caller().await
|
||||
}
|
||||
|
||||
fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
|
||||
let loc = Arc::new(Mutex::new(None));
|
||||
|
||||
let hook = panic::take_hook();
|
||||
{
|
||||
let loc = loc.clone();
|
||||
panic::set_hook(Box::new(move |info| {
|
||||
*loc.lock().unwrap() = info.location().map(|loc| loc.line())
|
||||
}));
|
||||
}
|
||||
panic::catch_unwind(f).unwrap_err();
|
||||
panic::set_hook(hook);
|
||||
let x = loc.lock().unwrap().unwrap();
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(panicked_at(|| block_on(foo())), 41);
|
||||
assert_eq!(panicked_at(|| block_on(foo_track_caller())), 54);
|
||||
}
|
10
src/test/ui/consts/const-eval/issue-104390.rs
Normal file
10
src/test/ui/consts/const-eval/issue-104390.rs
Normal file
@ -0,0 +1,10 @@
|
||||
fn f1() -> impl Sized { & 2E } //~ ERROR expected at least one digit in exponent
|
||||
fn f2() -> impl Sized { && 2E } //~ ERROR expected at least one digit in exponent
|
||||
fn f3() -> impl Sized { &'a 2E } //~ ERROR expected at least one digit in exponent
|
||||
//~^ ERROR borrow expressions cannot be annotated with lifetimes
|
||||
fn f4() -> impl Sized { &'static 2E } //~ ERROR expected at least one digit in exponent
|
||||
//~^ ERROR borrow expressions cannot be annotated with lifetimes
|
||||
fn f5() -> impl Sized { *& 2E } //~ ERROR expected at least one digit in exponent
|
||||
fn f6() -> impl Sized { &'_ 2E } //~ ERROR expected at least one digit in exponent
|
||||
//~^ ERROR borrow expressions cannot be annotated with lifetimes
|
||||
fn main() {}
|
65
src/test/ui/consts/const-eval/issue-104390.stderr
Normal file
65
src/test/ui/consts/const-eval/issue-104390.stderr
Normal file
@ -0,0 +1,65 @@
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:1:27
|
||||
|
|
||||
LL | fn f1() -> impl Sized { & 2E }
|
||||
| ^^
|
||||
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:2:28
|
||||
|
|
||||
LL | fn f2() -> impl Sized { && 2E }
|
||||
| ^^
|
||||
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:3:29
|
||||
|
|
||||
LL | fn f3() -> impl Sized { &'a 2E }
|
||||
| ^^
|
||||
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:5:34
|
||||
|
|
||||
LL | fn f4() -> impl Sized { &'static 2E }
|
||||
| ^^
|
||||
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:7:28
|
||||
|
|
||||
LL | fn f5() -> impl Sized { *& 2E }
|
||||
| ^^
|
||||
|
||||
error: expected at least one digit in exponent
|
||||
--> $DIR/issue-104390.rs:8:29
|
||||
|
|
||||
LL | fn f6() -> impl Sized { &'_ 2E }
|
||||
| ^^
|
||||
|
||||
error: borrow expressions cannot be annotated with lifetimes
|
||||
--> $DIR/issue-104390.rs:3:25
|
||||
|
|
||||
LL | fn f3() -> impl Sized { &'a 2E }
|
||||
| ^--^^^
|
||||
| |
|
||||
| annotated with lifetime here
|
||||
| help: remove the lifetime annotation
|
||||
|
||||
error: borrow expressions cannot be annotated with lifetimes
|
||||
--> $DIR/issue-104390.rs:5:25
|
||||
|
|
||||
LL | fn f4() -> impl Sized { &'static 2E }
|
||||
| ^-------^^^
|
||||
| |
|
||||
| annotated with lifetime here
|
||||
| help: remove the lifetime annotation
|
||||
|
||||
error: borrow expressions cannot be annotated with lifetimes
|
||||
--> $DIR/issue-104390.rs:8:25
|
||||
|
|
||||
LL | fn f6() -> impl Sized { &'_ 2E }
|
||||
| ^--^^^
|
||||
| |
|
||||
| annotated with lifetime here
|
||||
| help: remove the lifetime annotation
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
10
src/test/ui/dyn-star/return.rs
Normal file
10
src/test/ui/dyn-star/return.rs
Normal file
@ -0,0 +1,10 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(dyn_star)]
|
||||
//~^ WARN the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
|
||||
fn _foo() -> dyn* Unpin {
|
||||
4usize
|
||||
}
|
||||
|
||||
fn main() {}
|
11
src/test/ui/dyn-star/return.stderr
Normal file
11
src/test/ui/dyn-star/return.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
warning: the feature `dyn_star` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/return.rs:3:12
|
||||
|
|
||||
LL | #![feature(dyn_star)]
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
@ -5,12 +5,12 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>;
|
||||
| ^^^^^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:7:8
|
||||
--> $DIR/object-safety.rs:7:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn baz(&self) -> impl Debug;
|
||||
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
@ -20,12 +20,12 @@ LL | let s = i.baz();
|
||||
| ^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:7:8
|
||||
--> $DIR/object-safety.rs:7:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn baz(&self) -> impl Debug;
|
||||
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
@ -35,12 +35,12 @@ LL | let i = Box::new(42_u32) as Box<dyn Foo>;
|
||||
| ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:7:8
|
||||
--> $DIR/object-safety.rs:7:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn baz(&self) -> impl Debug;
|
||||
| ^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
|
||||
= note: required by cast to type `Box<dyn Foo>`
|
||||
|
11
src/test/ui/lint/issue-104392.rs
Normal file
11
src/test/ui/lint/issue-104392.rs
Normal file
@ -0,0 +1,11 @@
|
||||
fn main() {
|
||||
{ unsafe 92 } //~ ERROR expected `{`, found `92`
|
||||
}
|
||||
|
||||
fn foo() {
|
||||
{ mod 92 } //~ ERROR expected identifier, found `92`
|
||||
}
|
||||
|
||||
fn bar() {
|
||||
{ trait 92 } //~ ERROR expected identifier, found `92`
|
||||
}
|
27
src/test/ui/lint/issue-104392.stderr
Normal file
27
src/test/ui/lint/issue-104392.stderr
Normal file
@ -0,0 +1,27 @@
|
||||
error: expected `{`, found `92`
|
||||
--> $DIR/issue-104392.rs:2:14
|
||||
|
|
||||
LL | { unsafe 92 }
|
||||
| ------ ^^ expected `{`
|
||||
| |
|
||||
| while parsing this `unsafe` expression
|
||||
|
|
||||
help: try placing this code inside a block
|
||||
|
|
||||
LL | { unsafe { 92 } }
|
||||
| + +
|
||||
|
||||
error: expected identifier, found `92`
|
||||
--> $DIR/issue-104392.rs:6:11
|
||||
|
|
||||
LL | { mod 92 }
|
||||
| ^^ expected identifier
|
||||
|
||||
error: expected identifier, found `92`
|
||||
--> $DIR/issue-104392.rs:10:13
|
||||
|
|
||||
LL | { trait 92 }
|
||||
| ^^ expected identifier
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -1,9 +1,6 @@
|
||||
// check-fail
|
||||
// failure-status: 101
|
||||
// normalize-stderr-test "note: .*" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' .*" -> ""
|
||||
// normalize-stderr-test " .*\n" -> ""
|
||||
// normalize-stderr-test " .*\n" -> ""
|
||||
// dont-check-compiler-stderr
|
||||
// known-bug: #103899
|
||||
|
||||
trait BaseWithAssoc {
|
||||
|
@ -1,12 +0,0 @@
|
||||
|
||||
stack
|
||||
error:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
query#0#1end
|
16
src/test/ui/typeck/issue-104510-ice.rs
Normal file
16
src/test/ui/typeck/issue-104510-ice.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// needs-asm-support
|
||||
// only-x86_64
|
||||
|
||||
struct W<T: ?Sized>(Oops);
|
||||
//~^ ERROR cannot find type `Oops` in this scope
|
||||
|
||||
unsafe fn test() {
|
||||
let j = W(());
|
||||
let pointer = &j as *const _;
|
||||
core::arch::asm!(
|
||||
"nop",
|
||||
in("eax") pointer,
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {}
|
9
src/test/ui/typeck/issue-104510-ice.stderr
Normal file
9
src/test/ui/typeck/issue-104510-ice.stderr
Normal file
@ -0,0 +1,9 @@
|
||||
error[E0412]: cannot find type `Oops` in this scope
|
||||
--> $DIR/issue-104510-ice.rs:4:21
|
||||
|
|
||||
LL | struct W<T: ?Sized>(Oops);
|
||||
| ^^^^ not found in this scope
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0412`.
|
@ -1156,7 +1156,7 @@ fn needless_borrow_impl_arg_position<'tcx>(
|
||||
}
|
||||
|
||||
let predicate = EarlyBinder(predicate).subst(cx.tcx, &substs_with_referent_ty);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
infcx.predicate_must_hold_modulo_regions(&obligation)
|
||||
})
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
||||
use rustc_hir::intravisit::FnKind;
|
||||
use rustc_hir::{
|
||||
AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound,
|
||||
HirId, IsAsync, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
HirId, ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind,
|
||||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
|
||||
) {
|
||||
if_chain! {
|
||||
if let Some(header) = kind.header();
|
||||
if header.asyncness == IsAsync::NotAsync;
|
||||
if !header.asyncness.is_async();
|
||||
// Check that this function returns `impl Future`
|
||||
if let FnRetTy::Return(ret_ty) = decl.output;
|
||||
if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
|
||||
|
@ -419,7 +419,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
|
||||
|
||||
if trait_predicates.any(|predicate| {
|
||||
let predicate = EarlyBinder(predicate).subst(cx.tcx, new_subst);
|
||||
let obligation = Obligation::new(ObligationCause::dummy(), cx.param_env, predicate);
|
||||
let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
|
||||
!cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
|
||||
}) {
|
||||
return false;
|
||||
|
@ -695,6 +695,7 @@ fn matches_preds<'tcx>(
|
||||
.type_implements_trait(p.def_id, ty, p.substs, cx.param_env)
|
||||
.must_apply_modulo_regions(),
|
||||
ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy(),
|
||||
cx.param_env,
|
||||
cx.tcx.mk_predicate(Binder::bind_with_vars(
|
||||
|
@ -1,6 +1,6 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_help;
|
||||
use rustc_hir::intravisit::{walk_expr, walk_fn, FnKind, Visitor};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, IsAsync, YieldSource};
|
||||
use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, YieldSource};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
|
||||
span: Span,
|
||||
hir_id: HirId,
|
||||
) {
|
||||
if !span.from_expansion() && fn_kind.asyncness() == IsAsync::Async {
|
||||
if !span.from_expansion() && fn_kind.asyncness().is_async() {
|
||||
let mut visitor = AsyncFnVisitor { cx, found_await: false };
|
||||
walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), hir_id);
|
||||
if !visitor.found_await {
|
||||
|
@ -87,10 +87,10 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
|
||||
use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
|
||||
use rustc_hir::LangItem::{OptionNone, ResultErr, ResultOk};
|
||||
use rustc_hir::{
|
||||
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness, Destination, Expr,
|
||||
ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, IsAsync, Item, ItemKind, LangItem, Local, MatchSource,
|
||||
Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind,
|
||||
TraitRef, TyKind, UnOp,
|
||||
def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Constness,
|
||||
Destination, Expr, ExprKind, FnDecl, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind,
|
||||
LangItem, Local, MatchSource, Mutability, Node, Param, Pat, PatKind, Path, PathSegment, PrimTy,
|
||||
QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitRef, TyKind, UnOp,
|
||||
};
|
||||
use rustc_lexer::{tokenize, TokenKind};
|
||||
use rustc_lint::{LateContext, Level, Lint, LintContext};
|
||||
@ -1861,7 +1861,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
|
||||
|
||||
/// Checks if the given function kind is an async function.
|
||||
pub fn is_async_fn(kind: FnKind<'_>) -> bool {
|
||||
matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async)
|
||||
matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness.is_async())
|
||||
}
|
||||
|
||||
/// Peels away all the compiler generated code surrounding the body of an async function,
|
||||
|
@ -2987,6 +2987,10 @@ impl<'test> TestCx<'test> {
|
||||
cmd.env("LLVM_BIN_DIR", llvm_bin_dir);
|
||||
}
|
||||
|
||||
if let Some(ref remote_test_client) = self.config.remote_test_client {
|
||||
cmd.env("REMOTE_TEST_CLIENT", remote_test_client);
|
||||
}
|
||||
|
||||
// We don't want RUSTFLAGS set from the outside to interfere with
|
||||
// compiler flags set in the test cases:
|
||||
cmd.env_remove("RUSTFLAGS");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user