Auto merge of #140682 - GuillaumeGomez:rollup-6xjf6zn, r=GuillaumeGomez
Rollup of 11 pull requests Successful merges: - #140080 (mir-opt: Use one MirPatch in MatchBranchSimplification) - #140115 (mir-opt: execute MatchBranchSimplification after GVN) - #140357 (bypass linker configuration and cross target check on `x check`) - #140374 (Resolve instance for SymFn in global/naked asm) - #140559 (Removing rustc_type_ir in the rustc_infer codebase) - #140605 (`fn check_opaque_type_parameter_valid` defer error) - #140636 (implement `PanicTracker` to track `t` panics) - #140661 (Make `-Zfixed-x18` into a target modifier) - #140670 (calculate step duration in a panic-safe way) - #140672 (Deeply normalize in the new solver in WF) - #140676 (Update books) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
4a0969e06d
75 changed files with 520 additions and 280 deletions
|
|
@ -4515,6 +4515,7 @@ dependencies = [
|
|||
"rustc_session",
|
||||
"rustc_span",
|
||||
"rustc_transmute",
|
||||
"rustc_type_ir",
|
||||
"smallvec",
|
||||
"thin-vec",
|
||||
"tracing",
|
||||
|
|
|
|||
|
|
@ -267,13 +267,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
return Ty::new_error(self.tcx, e);
|
||||
}
|
||||
|
||||
if let Err(guar) = check_opaque_type_parameter_valid(
|
||||
if let Err(err) = check_opaque_type_parameter_valid(
|
||||
self,
|
||||
opaque_type_key,
|
||||
instantiated_ty.span,
|
||||
DefiningScopeKind::MirBorrowck,
|
||||
) {
|
||||
return Ty::new_error(self.tcx, guar);
|
||||
return Ty::new_error(self.tcx, err.report(self));
|
||||
}
|
||||
|
||||
let definition_ty = instantiated_ty
|
||||
|
|
|
|||
|
|
@ -1282,7 +1282,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
|
|||
intrinsic.name,
|
||||
);
|
||||
}
|
||||
return Err(Instance::new(instance.def_id(), instance.args));
|
||||
return Err(Instance::new_raw(instance.def_id(), instance.args));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -399,7 +399,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
|
|||
}
|
||||
|
||||
// Fall back to default body
|
||||
_ => return Err(Instance::new(instance.def_id(), instance.args)),
|
||||
_ => return Err(Instance::new_raw(instance.def_id(), instance.args)),
|
||||
};
|
||||
|
||||
if !fn_abi.ret.is_ignore() {
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ fn make_dummy_instance<'tcx>(tcx: TyCtxt<'tcx>, local_def_id: LocalDefId) -> ty:
|
|||
let def_id = local_def_id.to_def_id();
|
||||
|
||||
// Make a dummy instance that fills in all generics with placeholders.
|
||||
ty::Instance::new(
|
||||
ty::Instance::new_raw(
|
||||
def_id,
|
||||
ty::GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||
if let ty::GenericParamDefKind::Lifetime = param.kind {
|
||||
|
|
|
|||
|
|
@ -613,7 +613,7 @@ impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
|
|||
_ => {
|
||||
debug!("unknown intrinsic '{}' -- falling back to default body", name);
|
||||
// Call the fallback body instead of generating the intrinsic code
|
||||
return Err(ty::Instance::new(instance.def_id(), instance.args));
|
||||
return Err(ty::Instance::new_raw(instance.def_id(), instance.args));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -612,7 +612,7 @@ pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
|
|||
ExportedSymbol::Generic(def_id, args) => {
|
||||
rustc_symbol_mangling::symbol_name_for_instance_in_crate(
|
||||
tcx,
|
||||
Instance::new(def_id, args),
|
||||
Instance::new_raw(def_id, args),
|
||||
instantiating_crate,
|
||||
)
|
||||
}
|
||||
|
|
@ -660,7 +660,7 @@ fn calling_convention_for_symbol<'tcx>(
|
|||
None
|
||||
}
|
||||
ExportedSymbol::NonGeneric(def_id) => Some(Instance::mono(tcx, def_id)),
|
||||
ExportedSymbol::Generic(def_id, args) => Some(Instance::new(def_id, args)),
|
||||
ExportedSymbol::Generic(def_id, args) => Some(Instance::new_raw(def_id, args)),
|
||||
// DropGlue always use the Rust calling convention and thus follow the target's default
|
||||
// symbol decoration scheme.
|
||||
ExportedSymbol::DropGlue(..) => None,
|
||||
|
|
|
|||
|
|
@ -457,7 +457,13 @@ where
|
|||
rustc_hir::InlineAsmOperand::SymFn { expr } => {
|
||||
let ty = cx.tcx().typeck(item_id.owner_id).expr_ty(expr);
|
||||
let instance = match ty.kind() {
|
||||
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||
&ty::FnDef(def_id, args) => Instance::expect_resolve(
|
||||
cx.tcx(),
|
||||
ty::TypingEnv::fully_monomorphized(),
|
||||
def_id,
|
||||
args,
|
||||
expr.span,
|
||||
),
|
||||
_ => span_bug!(*op_sp, "asm sym is not a function"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -95,7 +95,9 @@ fn inline_to_global_operand<'a, 'tcx, Cx: LayoutOf<'tcx, LayoutOfResult = TyAndL
|
|||
);
|
||||
|
||||
let instance = match mono_type.kind() {
|
||||
&ty::FnDef(def_id, args) => Instance::new(def_id, args),
|
||||
&ty::FnDef(def_id, args) => {
|
||||
Instance::expect_resolve(cx.tcx(), cx.typing_env(), def_id, args, value.span)
|
||||
}
|
||||
_ => bug!("asm sym is not a function"),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,36 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
/// Convenience function to *deeply* normalize during wfcheck. In the old solver,
|
||||
/// this just dispatches to [`WfCheckingCtxt::normalize`], but in the new solver
|
||||
/// this calls `deeply_normalize` and reports errors if they are encountered.
|
||||
///
|
||||
/// This function should be called in favor of `normalize` in cases where we will
|
||||
/// then check the well-formedness of the type, since we only use the normalized
|
||||
/// signature types for implied bounds when checking regions.
|
||||
// FIXME(-Znext-solver): This should be removed when we compute implied outlives
|
||||
// bounds using the unnormalized signature of the function we're checking.
|
||||
fn deeply_normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if self.infcx.next_trait_solver() {
|
||||
match self.ocx.deeply_normalize(
|
||||
&ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)),
|
||||
self.param_env,
|
||||
value.clone(),
|
||||
) {
|
||||
Ok(value) => value,
|
||||
Err(errors) => {
|
||||
self.infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.normalize(span, loc, value)
|
||||
}
|
||||
}
|
||||
|
||||
fn register_wf_obligation(&self, span: Span, loc: Option<WellFormedLoc>, term: ty::Term<'tcx>) {
|
||||
let cause = traits::ObligationCause::new(
|
||||
span,
|
||||
|
|
@ -297,7 +327,8 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
|
|||
{
|
||||
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
||||
let ty = tcx.type_of(def_id).instantiate_identity();
|
||||
let item_ty = wfcx.normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
|
||||
let item_ty =
|
||||
wfcx.deeply_normalize(hir_ty.span, Some(WellFormedLoc::Ty(def_id)), ty);
|
||||
wfcx.register_wf_obligation(
|
||||
hir_ty.span,
|
||||
Some(WellFormedLoc::Ty(def_id)),
|
||||
|
|
@ -1073,7 +1104,7 @@ fn check_associated_item(
|
|||
match item.kind {
|
||||
ty::AssocKind::Const { .. } => {
|
||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||
check_sized_if_body(
|
||||
wfcx,
|
||||
|
|
@ -1102,7 +1133,7 @@ fn check_associated_item(
|
|||
}
|
||||
if item.defaultness(tcx).has_value() {
|
||||
let ty = tcx.type_of(item.def_id).instantiate_identity();
|
||||
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
let ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
wfcx.register_wf_obligation(span, loc, ty.into());
|
||||
}
|
||||
Ok(())
|
||||
|
|
@ -1149,7 +1180,7 @@ fn check_type_defn<'tcx>(
|
|||
let field_id = field.did.expect_local();
|
||||
let hir::FieldDef { ty: hir_ty, .. } =
|
||||
tcx.hir_node_by_def_id(field_id).expect_field();
|
||||
let ty = wfcx.normalize(
|
||||
let ty = wfcx.deeply_normalize(
|
||||
hir_ty.span,
|
||||
None,
|
||||
tcx.type_of(field.did).instantiate_identity(),
|
||||
|
|
@ -1310,7 +1341,7 @@ fn check_item_type(
|
|||
|
||||
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
|
||||
let ty = tcx.type_of(item_id).instantiate_identity();
|
||||
let item_ty = wfcx.normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
|
||||
let forbid_unsized = match unsized_handling {
|
||||
UnsizedHandling::Forbid => true,
|
||||
|
|
@ -1375,7 +1406,7 @@ fn check_impl<'tcx>(
|
|||
// other `Foo` impls are incoherent.
|
||||
tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
|
||||
let trait_span = hir_trait_ref.path.span;
|
||||
let trait_ref = wfcx.normalize(
|
||||
let trait_ref = wfcx.deeply_normalize(
|
||||
trait_span,
|
||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||
trait_ref,
|
||||
|
|
@ -1435,7 +1466,7 @@ fn check_impl<'tcx>(
|
|||
}
|
||||
None => {
|
||||
let self_ty = tcx.type_of(item.owner_id).instantiate_identity();
|
||||
let self_ty = wfcx.normalize(
|
||||
let self_ty = wfcx.deeply_normalize(
|
||||
item.span,
|
||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||
self_ty,
|
||||
|
|
@ -1640,7 +1671,7 @@ fn check_fn_or_method<'tcx>(
|
|||
|
||||
sig.inputs_and_output =
|
||||
tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| {
|
||||
wfcx.normalize(
|
||||
wfcx.deeply_normalize(
|
||||
arg_span(idx),
|
||||
Some(WellFormedLoc::Param {
|
||||
function: def_id,
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
|
|||
check::maybe_check_static_with_link_section(tcx, item_def_id);
|
||||
}
|
||||
DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
|
||||
let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
|
||||
let instance = ty::Instance::new_raw(item_def_id.into(), ty::GenericArgs::empty());
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let typing_env = ty::TypingEnv::fully_monomorphized();
|
||||
tcx.ensure_ok().eval_to_const_value_raw(typing_env.as_query_input(cid));
|
||||
|
|
|
|||
|
|
@ -555,15 +555,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Err(guar) = check_opaque_type_parameter_valid(
|
||||
if let Err(err) = check_opaque_type_parameter_valid(
|
||||
&self.fcx,
|
||||
opaque_type_key,
|
||||
hidden_type.span,
|
||||
DefiningScopeKind::HirTypeck,
|
||||
) {
|
||||
self.typeck_results
|
||||
.concrete_opaque_types
|
||||
.insert(opaque_type_key.def_id, ty::OpaqueHiddenType::new_error(tcx, guar));
|
||||
self.typeck_results.concrete_opaque_types.insert(
|
||||
opaque_type_key.def_id,
|
||||
ty::OpaqueHiddenType::new_error(tcx, err.report(self.fcx)),
|
||||
);
|
||||
}
|
||||
|
||||
let hidden_type = hidden_type.remap_generic_params_to_declaration_params(
|
||||
|
|
|
|||
|
|
@ -121,19 +121,19 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
|
|||
self.enter_forall(value, f)
|
||||
}
|
||||
|
||||
fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
|
||||
fn equate_ty_vids_raw(&self, a: ty::TyVid, b: ty::TyVid) {
|
||||
self.inner.borrow_mut().type_variables().equate(a, b);
|
||||
}
|
||||
|
||||
fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
|
||||
fn equate_int_vids_raw(&self, a: ty::IntVid, b: ty::IntVid) {
|
||||
self.inner.borrow_mut().int_unification_table().union(a, b);
|
||||
}
|
||||
|
||||
fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
|
||||
fn equate_float_vids_raw(&self, a: ty::FloatVid, b: ty::FloatVid) {
|
||||
self.inner.borrow_mut().float_unification_table().union(a, b);
|
||||
}
|
||||
|
||||
fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
|
||||
fn equate_const_vids_raw(&self, a: ty::ConstVid, b: ty::ConstVid) {
|
||||
self.inner.borrow_mut().const_unification_table().union(a, b);
|
||||
}
|
||||
|
||||
|
|
@ -141,8 +141,8 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
|
|||
&self,
|
||||
relation: &mut R,
|
||||
target_is_expected: bool,
|
||||
target_vid: rustc_type_ir::TyVid,
|
||||
instantiation_variance: rustc_type_ir::Variance,
|
||||
target_vid: ty::TyVid,
|
||||
instantiation_variance: ty::Variance,
|
||||
source_ty: Ty<'tcx>,
|
||||
) -> RelateResult<'tcx, ()> {
|
||||
self.instantiate_ty_var(
|
||||
|
|
@ -154,19 +154,11 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
fn instantiate_int_var_raw(
|
||||
&self,
|
||||
vid: rustc_type_ir::IntVid,
|
||||
value: rustc_type_ir::IntVarValue,
|
||||
) {
|
||||
fn instantiate_int_var_raw(&self, vid: ty::IntVid, value: ty::IntVarValue) {
|
||||
self.inner.borrow_mut().int_unification_table().union_value(vid, value);
|
||||
}
|
||||
|
||||
fn instantiate_float_var_raw(
|
||||
&self,
|
||||
vid: rustc_type_ir::FloatVid,
|
||||
value: rustc_type_ir::FloatVarValue,
|
||||
) {
|
||||
fn instantiate_float_var_raw(&self, vid: ty::FloatVid, value: ty::FloatVarValue) {
|
||||
self.inner.borrow_mut().float_unification_table().union_value(vid, value);
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +166,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
|
|||
&self,
|
||||
relation: &mut R,
|
||||
target_is_expected: bool,
|
||||
target_vid: rustc_type_ir::ConstVid,
|
||||
target_vid: ty::ConstVid,
|
||||
source_ct: ty::Const<'tcx>,
|
||||
) -> RelateResult<'tcx, ()> {
|
||||
self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
|
||||
|
|
|
|||
|
|
@ -63,11 +63,11 @@ use rustc_data_structures::undo_log::UndoLogs;
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::ty::outlives::{Component, push_outlives_components};
|
||||
use rustc_middle::ty::{
|
||||
self, GenericArgKind, GenericArgsRef, PolyTypeOutlivesPredicate, Region, Ty, TyCtxt,
|
||||
TypeFoldable as _, TypeVisitableExt,
|
||||
};
|
||||
use rustc_type_ir::outlives::{Component, push_outlives_components};
|
||||
use smallvec::smallvec;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::assert_matches::assert_matches;
|
||||
|
||||
use rustc_middle::ty::outlives::{Component, compute_alias_components_recursive};
|
||||
use rustc_middle::ty::{self, OutlivesPredicate, Ty, TyCtxt};
|
||||
use rustc_type_ir::outlives::{Component, compute_alias_components_recursive};
|
||||
use smallvec::smallvec;
|
||||
use tracing::{debug, instrument, trace};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@
|
|||
//! (except for some relations used for diagnostics and heuristics in the compiler).
|
||||
//! As well as the implementation of `Relate` for interned things (`Ty`/`Const`/etc).
|
||||
|
||||
pub use rustc_middle::ty::relate::RelateResult;
|
||||
pub use rustc_type_ir::relate::combine::PredicateEmittingRelation;
|
||||
pub use rustc_type_ir::relate::*;
|
||||
pub use rustc_middle::ty::relate::combine::PredicateEmittingRelation;
|
||||
pub use rustc_middle::ty::relate::{RelateResult, *};
|
||||
|
||||
mod generalize;
|
||||
mod higher_ranked;
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ use rustc_middle::ty::relate::combine::{super_combine_consts, super_combine_tys}
|
|||
use rustc_middle::ty::relate::{
|
||||
Relate, RelateResult, TypeRelation, relate_args_invariantly, relate_args_with_variances,
|
||||
};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TyVar};
|
||||
use rustc_middle::ty::{self, DelayedSet, Ty, TyCtxt, TyVar};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::data_structures::DelayedSet;
|
||||
use tracing::{debug, instrument};
|
||||
|
||||
use crate::infer::BoundRegionConversionTime::HigherRankedType;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::{
|
||||
self, Const, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder,
|
||||
self, Const, DelayedMap, FallibleTypeFolder, InferConst, Ty, TyCtxt, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable, TypeVisitableExt,
|
||||
};
|
||||
use rustc_type_ir::data_structures::DelayedMap;
|
||||
|
||||
use super::{FixupError, FixupResult, InferCtxt};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,8 @@ use std::ops::Range;
|
|||
use rustc_data_structures::{snapshot_vec as sv, unify as ut};
|
||||
use rustc_middle::ty::{
|
||||
self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid, TypeFoldable, TypeFolder,
|
||||
TypeSuperFoldable,
|
||||
TypeSuperFoldable, TypeVisitableExt,
|
||||
};
|
||||
use rustc_type_ir::TypeVisitableExt;
|
||||
use tracing::instrument;
|
||||
use ut::UnifyKey;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
pub use rustc_middle::ty::elaborate::*;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::{Ident, Span};
|
||||
pub use rustc_type_ir::elaborate::*;
|
||||
|
||||
use crate::traits::{self, Obligation, ObligationCauseCode, PredicateObligation};
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ impl ClashingExternDeclarations {
|
|||
/// for the item, return its HirId without updating the set.
|
||||
fn insert(&mut self, tcx: TyCtxt<'_>, fi: hir::ForeignItemId) -> Option<hir::OwnerId> {
|
||||
let did = fi.owner_id.to_def_id();
|
||||
let instance = Instance::new(did, ty::List::identity_for_item(tcx, did));
|
||||
let instance = Instance::new_raw(did, ty::List::identity_for_item(tcx, did));
|
||||
let name = Symbol::intern(tcx.symbol_name(instance).name);
|
||||
if let Some(&existing_id) = self.seen_decls.get(&name) {
|
||||
// Avoid updating the map with the new entry when we do find a collision. We want to
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl<'tcx> ExportedSymbol<'tcx> {
|
|||
match *self {
|
||||
ExportedSymbol::NonGeneric(def_id) => tcx.symbol_name(ty::Instance::mono(tcx, def_id)),
|
||||
ExportedSymbol::Generic(def_id, args) => {
|
||||
tcx.symbol_name(ty::Instance::new(def_id, args))
|
||||
tcx.symbol_name(ty::Instance::new_raw(def_id, args))
|
||||
}
|
||||
ExportedSymbol::DropGlue(ty) => {
|
||||
tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty))
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
|
||||
// encountered.
|
||||
let args = GenericArgs::identity_for_item(self, def_id);
|
||||
let instance = ty::Instance::new(def_id, args);
|
||||
let instance = ty::Instance::new_raw(def_id, args);
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let typing_env = ty::TypingEnv::post_analysis(self, def_id);
|
||||
self.const_eval_global_id(typing_env, cid, DUMMY_SP)
|
||||
|
|
@ -39,7 +39,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
|
||||
// encountered.
|
||||
let args = GenericArgs::identity_for_item(self, def_id);
|
||||
let instance = ty::Instance::new(def_id, args);
|
||||
let instance = ty::Instance::new_raw(def_id, args);
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let typing_env = ty::TypingEnv::post_analysis(self, def_id);
|
||||
let inputs = self.erase_regions(typing_env.as_query_input(cid));
|
||||
|
|
@ -209,7 +209,7 @@ impl<'tcx> TyCtxtEnsureOk<'tcx> {
|
|||
// into `const_eval` which will return `ErrorHandled::TooGeneric` if any of them are
|
||||
// encountered.
|
||||
let args = GenericArgs::identity_for_item(self.tcx, def_id);
|
||||
let instance = ty::Instance::new(def_id, self.tcx.erase_regions(args));
|
||||
let instance = ty::Instance::new_raw(def_id, self.tcx.erase_regions(args));
|
||||
let cid = GlobalId { instance, promoted: None };
|
||||
let typing_env = ty::TypingEnv::post_analysis(self.tcx, def_id);
|
||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||
|
|
|
|||
|
|
@ -318,7 +318,7 @@ impl<'tcx> fmt::Display for MonoItem<'tcx> {
|
|||
match *self {
|
||||
MonoItem::Fn(instance) => write!(f, "fn {instance}"),
|
||||
MonoItem::Static(def_id) => {
|
||||
write!(f, "static {}", Instance::new(def_id, GenericArgs::empty()))
|
||||
write!(f, "static {}", Instance::new_raw(def_id, GenericArgs::empty()))
|
||||
}
|
||||
MonoItem::GlobalAsm(..) => write!(f, "global_asm"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2481,7 +2481,7 @@ rustc_queries! {
|
|||
query resolve_instance_raw(
|
||||
key: ty::PseudoCanonicalInput<'tcx, (DefId, GenericArgsRef<'tcx>)>
|
||||
) -> Result<Option<ty::Instance<'tcx>>, ErrorGuaranteed> {
|
||||
desc { "resolving instance `{}`", ty::Instance::new(key.value.0, key.value.1) }
|
||||
desc { "resolving instance `{}`", ty::Instance::new_raw(key.value.0, key.value.1) }
|
||||
}
|
||||
|
||||
query reveal_opaque_types_in_bounds(key: ty::Clauses<'tcx>) -> ty::Clauses<'tcx> {
|
||||
|
|
|
|||
|
|
@ -491,7 +491,15 @@ fn resolve_async_drop_poll<'tcx>(mut cor_ty: Ty<'tcx>) -> Instance<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
|
||||
/// Creates a new [`InstanceKind::Item`] from the `def_id` and `args`.
|
||||
///
|
||||
/// Note that this item corresponds to the body of `def_id` directly, which
|
||||
/// likely does not make sense for trait items which need to be resolved to an
|
||||
/// implementation, and which may not even have a body themselves. Usages of
|
||||
/// this function should probably use [`Instance::expect_resolve`], or if run
|
||||
/// in a polymorphic environment or within a lint (that may encounter ambiguity)
|
||||
/// [`Instance::try_resolve`] instead.
|
||||
pub fn new_raw(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
|
||||
assert!(
|
||||
!args.has_escaping_bound_vars(),
|
||||
"args of instance {def_id:?} has escaping bound vars: {args:?}"
|
||||
|
|
@ -510,7 +518,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
}
|
||||
});
|
||||
|
||||
Instance::new(def_id, args)
|
||||
Instance::new_raw(def_id, args)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -603,7 +611,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
let type_length = type_length(args);
|
||||
if !tcx.type_length_limit().value_within_limit(type_length) {
|
||||
let (shrunk, written_to_path) =
|
||||
shrunk_instance_name(tcx, Instance::new(def_id, args));
|
||||
shrunk_instance_name(tcx, Instance::new_raw(def_id, args));
|
||||
let mut path = PathBuf::new();
|
||||
let was_written = if let Some(path2) = written_to_path {
|
||||
path = path2;
|
||||
|
|
@ -773,7 +781,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
|
||||
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
|
||||
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args),
|
||||
_ => Instance::new(def_id, args),
|
||||
_ => Instance::new_raw(def_id, args),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -899,7 +907,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
// This is important for `Iterator`'s combinators, but also useful for
|
||||
// adding future default methods to `Future`, for instance.
|
||||
debug_assert!(tcx.defaultness(trait_item_id).has_value());
|
||||
Some(Instance::new(trait_item_id, rcvr_args))
|
||||
Some(Instance::new_raw(trait_item_id, rcvr_args))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,9 +51,17 @@ use rustc_session::lint::LintBuffer;
|
|||
pub use rustc_session::lint::RegisteredTools;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::{DUMMY_SP, ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
|
||||
pub use rustc_type_ir::data_structures::DelayedSet;
|
||||
pub use rustc_type_ir::data_structures::{DelayedMap, DelayedSet};
|
||||
#[allow(
|
||||
hidden_glob_reexports,
|
||||
rustc::usage_of_type_ir_inherent,
|
||||
rustc::non_glob_import_of_type_ir_inherent
|
||||
)]
|
||||
use rustc_type_ir::inherent;
|
||||
pub use rustc_type_ir::relate::VarianceDiagInfo;
|
||||
pub use rustc_type_ir::*;
|
||||
#[allow(hidden_glob_reexports, unused_imports)]
|
||||
use rustc_type_ir::{InferCtxtLike, Interner};
|
||||
use tracing::{debug, instrument};
|
||||
pub use vtable::*;
|
||||
use {rustc_ast as ast, rustc_attr_data_structures as attr, rustc_hir as hir};
|
||||
|
|
|
|||
|
|
@ -701,8 +701,6 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
|
|||
// Now, we need to shrink the generated MIR.
|
||||
&ref_prop::ReferencePropagation,
|
||||
&sroa::ScalarReplacementOfAggregates,
|
||||
&match_branches::MatchBranchSimplification,
|
||||
// inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
|
||||
&multiple_return_terminators::MultipleReturnTerminators,
|
||||
// After simplifycfg, it allows us to discover new opportunities for peephole
|
||||
// optimizations.
|
||||
|
|
@ -711,6 +709,7 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
|
|||
&dead_store_elimination::DeadStoreElimination::Initial,
|
||||
&gvn::GVN,
|
||||
&simplify::SimplifyLocals::AfterGVN,
|
||||
&match_branches::MatchBranchSimplification,
|
||||
&dataflow_const_prop::DataflowConstProp,
|
||||
&single_use_consts::SingleUseConsts,
|
||||
&o1(simplify_branches::SimplifyConstCondition::AfterConstProp),
|
||||
|
|
|
|||
|
|
@ -19,30 +19,32 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
|
|||
|
||||
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
let typing_env = body.typing_env(tcx);
|
||||
let mut should_cleanup = false;
|
||||
for bb_idx in body.basic_blocks.indices() {
|
||||
match &body.basic_blocks[bb_idx].terminator().kind {
|
||||
let mut apply_patch = false;
|
||||
let mut patch = MirPatch::new(body);
|
||||
for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
|
||||
match &bb_data.terminator().kind {
|
||||
TerminatorKind::SwitchInt {
|
||||
discr: Operand::Copy(_) | Operand::Move(_),
|
||||
targets,
|
||||
..
|
||||
// We require that the possible target blocks don't contain this block.
|
||||
} if !targets.all_targets().contains(&bb_idx) => {}
|
||||
} if !targets.all_targets().contains(&bb) => {}
|
||||
// Only optimize switch int statements
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
if SimplifyToIf.simplify(tcx, body, bb_idx, typing_env).is_some() {
|
||||
should_cleanup = true;
|
||||
if SimplifyToIf.simplify(tcx, body, &mut patch, bb, typing_env).is_some() {
|
||||
apply_patch = true;
|
||||
continue;
|
||||
}
|
||||
if SimplifyToExp::default().simplify(tcx, body, bb_idx, typing_env).is_some() {
|
||||
should_cleanup = true;
|
||||
if SimplifyToExp::default().simplify(tcx, body, &mut patch, bb, typing_env).is_some() {
|
||||
apply_patch = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if should_cleanup {
|
||||
if apply_patch {
|
||||
patch.apply(body);
|
||||
simplify_cfg(tcx, body);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,7 +61,8 @@ trait SimplifyMatch<'tcx> {
|
|||
fn simplify(
|
||||
&mut self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &mut Body<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
patch: &mut MirPatch<'tcx>,
|
||||
switch_bb_idx: BasicBlock,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
) -> Option<()> {
|
||||
|
|
@ -73,8 +76,6 @@ trait SimplifyMatch<'tcx> {
|
|||
let discr_ty = discr.ty(body.local_decls(), tcx);
|
||||
self.can_simplify(tcx, targets, typing_env, bbs, discr_ty)?;
|
||||
|
||||
let mut patch = MirPatch::new(body);
|
||||
|
||||
// Take ownership of items now that we know we can optimize.
|
||||
let discr = discr.clone();
|
||||
|
||||
|
|
@ -87,19 +88,9 @@ trait SimplifyMatch<'tcx> {
|
|||
let parent_end = Location { block: switch_bb_idx, statement_index };
|
||||
patch.add_statement(parent_end, StatementKind::StorageLive(discr_local));
|
||||
patch.add_assign(parent_end, Place::from(discr_local), Rvalue::Use(discr));
|
||||
self.new_stmts(
|
||||
tcx,
|
||||
targets,
|
||||
typing_env,
|
||||
&mut patch,
|
||||
parent_end,
|
||||
bbs,
|
||||
discr_local,
|
||||
discr_ty,
|
||||
);
|
||||
self.new_stmts(tcx, targets, typing_env, patch, parent_end, bbs, discr_local, discr_ty);
|
||||
patch.add_statement(parent_end, StatementKind::StorageDead(discr_local));
|
||||
patch.patch_terminator(switch_bb_idx, bbs[first].terminator().kind.clone());
|
||||
patch.apply(body);
|
||||
Some(())
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -931,7 +931,7 @@ fn visit_instance_use<'tcx>(
|
|||
// We explicitly skip this otherwise to ensure we get a linker error
|
||||
// if anyone tries to call this intrinsic and the codegen backend did not
|
||||
// override the implementation.
|
||||
let instance = ty::Instance::new(instance.def_id(), instance.args);
|
||||
let instance = ty::Instance::new_raw(instance.def_id(), instance.args);
|
||||
if tcx.should_codegen_locally(instance) {
|
||||
output.push(create_fn_mono_item(tcx, instance, source));
|
||||
}
|
||||
|
|
@ -1520,7 +1520,7 @@ impl<'v> RootCollector<'_, 'v> {
|
|||
ty::Closure(def_id, args)
|
||||
| ty::Coroutine(def_id, args)
|
||||
| ty::CoroutineClosure(def_id, args) => {
|
||||
Instance::new(def_id, self.tcx.erase_regions(args))
|
||||
Instance::new_raw(def_id, self.tcx.erase_regions(args))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2210,7 +2210,7 @@ options! {
|
|||
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
|
||||
(default: no)"),
|
||||
fixed_x18: bool = (false, parse_bool, [TRACKED],
|
||||
fixed_x18: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
|
||||
"make the x18 register reserved on AArch64 (default: no)"),
|
||||
flatten_format_args: bool = (true, parse_bool, [TRACKED],
|
||||
"flatten nested format_args!() and literals into a simplified format_args!() call \
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl<'tcx> BodyBuilder<'tcx> {
|
|||
pub(crate) fn new(tcx: TyCtxt<'tcx>, instance: ty::Instance<'tcx>) -> Self {
|
||||
let instance = match instance.def {
|
||||
// To get the fallback body of an intrinsic, we need to convert it to an item.
|
||||
ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new(def_id, instance.args),
|
||||
ty::InstanceKind::Intrinsic(def_id) => ty::Instance::new_raw(def_id, instance.args),
|
||||
_ => instance,
|
||||
};
|
||||
BodyBuilder { tcx, instance }
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl SymbolNamesTest<'_> {
|
|||
// some subset.
|
||||
for attr in tcx.get_attrs(def_id, SYMBOL_NAME) {
|
||||
let def_id = def_id.to_def_id();
|
||||
let instance = Instance::new(
|
||||
let instance = Instance::new_raw(
|
||||
def_id,
|
||||
tcx.erase_regions(GenericArgs::identity_for_item(tcx, def_id)),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ rustc_parse_format = { path = "../rustc_parse_format" }
|
|||
rustc_session = { path = "../rustc_session" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_transmute = { path = "../rustc_transmute", features = ["rustc"] }
|
||||
rustc_type_ir = { path = "../rustc_type_ir" }
|
||||
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
|
||||
thin-vec = "0.2"
|
||||
tracing = "0.1"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,49 @@ use crate::errors::NonGenericOpaqueTypeParam;
|
|||
use crate::regions::OutlivesEnvironmentBuildExt;
|
||||
use crate::traits::ObligationCtxt;
|
||||
|
||||
pub enum InvalidOpaqueTypeArgs<'tcx> {
|
||||
AlreadyReported(ErrorGuaranteed),
|
||||
NotAParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_index: usize, span: Span },
|
||||
DuplicateParam { opaque_type_key: OpaqueTypeKey<'tcx>, param_indices: Vec<usize>, span: Span },
|
||||
}
|
||||
impl From<ErrorGuaranteed> for InvalidOpaqueTypeArgs<'_> {
|
||||
fn from(guar: ErrorGuaranteed) -> Self {
|
||||
InvalidOpaqueTypeArgs::AlreadyReported(guar)
|
||||
}
|
||||
}
|
||||
impl<'tcx> InvalidOpaqueTypeArgs<'tcx> {
|
||||
pub fn report(self, infcx: &InferCtxt<'tcx>) -> ErrorGuaranteed {
|
||||
let tcx = infcx.tcx;
|
||||
match self {
|
||||
InvalidOpaqueTypeArgs::AlreadyReported(guar) => guar,
|
||||
InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index, span } => {
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let opaque_param = opaque_generics.param_at(param_index, tcx);
|
||||
let kind = opaque_param.kind.descr();
|
||||
infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
||||
arg: opaque_type_key.args[param_index],
|
||||
kind,
|
||||
span,
|
||||
param_span: tcx.def_span(opaque_param.def_id),
|
||||
})
|
||||
}
|
||||
InvalidOpaqueTypeArgs::DuplicateParam { opaque_type_key, param_indices, span } => {
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let descr = opaque_generics.param_at(param_indices[0], tcx).kind.descr();
|
||||
let spans: Vec<_> = param_indices
|
||||
.into_iter()
|
||||
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
|
||||
.collect();
|
||||
infcx
|
||||
.dcx()
|
||||
.struct_span_err(span, "non-defining opaque type use in defining scope")
|
||||
.with_span_note(spans, format!("{descr} used multiple times"))
|
||||
.emit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Opaque type parameter validity check as documented in the [rustc-dev-guide chapter].
|
||||
///
|
||||
/// [rustc-dev-guide chapter]:
|
||||
|
|
@ -22,23 +65,19 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
|
|||
opaque_type_key: OpaqueTypeKey<'tcx>,
|
||||
span: Span,
|
||||
defining_scope_kind: DefiningScopeKind,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
) -> Result<(), InvalidOpaqueTypeArgs<'tcx>> {
|
||||
let tcx = infcx.tcx;
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let opaque_env = LazyOpaqueTyEnv::new(tcx, opaque_type_key.def_id);
|
||||
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
||||
|
||||
// Avoid duplicate errors in case the opaque has already been malformed in
|
||||
// HIR typeck.
|
||||
if let DefiningScopeKind::MirBorrowck = defining_scope_kind {
|
||||
if let Err(guar) = infcx
|
||||
infcx
|
||||
.tcx
|
||||
.type_of_opaque_hir_typeck(opaque_type_key.def_id)
|
||||
.instantiate_identity()
|
||||
.error_reported()
|
||||
{
|
||||
return Err(guar);
|
||||
}
|
||||
.error_reported()?;
|
||||
}
|
||||
|
||||
for (i, arg) in opaque_type_key.iter_captured_args(tcx) {
|
||||
|
|
@ -64,32 +103,18 @@ pub fn check_opaque_type_parameter_valid<'tcx>(
|
|||
}
|
||||
} else {
|
||||
// Prevent `fn foo() -> Foo<u32>` from being defining.
|
||||
let opaque_param = opaque_generics.param_at(i, tcx);
|
||||
let kind = opaque_param.kind.descr();
|
||||
|
||||
opaque_env.param_is_error(i)?;
|
||||
|
||||
return Err(infcx.dcx().emit_err(NonGenericOpaqueTypeParam {
|
||||
arg,
|
||||
kind,
|
||||
span,
|
||||
param_span: tcx.def_span(opaque_param.def_id),
|
||||
}));
|
||||
return Err(InvalidOpaqueTypeArgs::NotAParam { opaque_type_key, param_index: i, span });
|
||||
}
|
||||
}
|
||||
|
||||
for (_, indices) in seen_params {
|
||||
if indices.len() > 1 {
|
||||
let descr = opaque_generics.param_at(indices[0], tcx).kind.descr();
|
||||
let spans: Vec<_> = indices
|
||||
.into_iter()
|
||||
.map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
|
||||
.collect();
|
||||
return Err(infcx
|
||||
.dcx()
|
||||
.struct_span_err(span, "non-defining opaque type use in defining scope")
|
||||
.with_span_note(spans, format!("{descr} used multiple times"))
|
||||
.emit());
|
||||
for (_, param_indices) in seen_params {
|
||||
if param_indices.len() > 1 {
|
||||
return Err(InvalidOpaqueTypeArgs::DuplicateParam {
|
||||
opaque_type_key,
|
||||
param_indices,
|
||||
span,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,9 +156,9 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
|
|||
fn register_hidden_type_in_storage(
|
||||
&self,
|
||||
opaque_type_key: ty::OpaqueTypeKey<'tcx>,
|
||||
hidden_ty: <Self::Interner as ty::Interner>::Ty,
|
||||
span: <Self::Interner as ty::Interner>::Span,
|
||||
) -> Option<<Self::Interner as ty::Interner>::Ty> {
|
||||
hidden_ty: <Self::Interner as rustc_type_ir::Interner>::Ty,
|
||||
span: <Self::Interner as rustc_type_ir::Interner>::Span,
|
||||
) -> Option<<Self::Interner as rustc_type_ir::Interner>::Ty> {
|
||||
self.0.register_hidden_type_in_storage(
|
||||
opaque_type_key,
|
||||
ty::OpaqueHiddenType { span, ty: hidden_ty },
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ fn resolve_associated_item<'tcx>(
|
|||
tcx.ensure_ok().compare_impl_item(leaf_def_item)?;
|
||||
}
|
||||
|
||||
Some(ty::Instance::new(leaf_def.item.def_id, args))
|
||||
Some(ty::Instance::new_raw(leaf_def.item.def_id, args))
|
||||
}
|
||||
traits::ImplSource::Builtin(BuiltinImplSource::Object(_), _) => {
|
||||
let trait_ref = ty::TraitRef::from_method(tcx, trait_id, rcvr_args);
|
||||
|
|
@ -280,7 +280,7 @@ fn resolve_associated_item<'tcx>(
|
|||
|
||||
// Use the default `fn clone_from` from `trait Clone`.
|
||||
let args = tcx.erase_regions(rcvr_args);
|
||||
Some(ty::Instance::new(trait_item_id, args))
|
||||
Some(ty::Instance::new_raw(trait_item_id, args))
|
||||
}
|
||||
} else if tcx.is_lang_item(trait_ref.def_id, LangItem::FnPtrTrait) {
|
||||
if tcx.is_lang_item(trait_item_id, LangItem::FnPtrAddr) {
|
||||
|
|
@ -329,7 +329,7 @@ fn resolve_associated_item<'tcx>(
|
|||
// sync with the built-in trait implementations (since all of the
|
||||
// implementations return `FnOnce::Output`).
|
||||
if ty::ClosureKind::FnOnce == args.as_coroutine_closure().kind() {
|
||||
Some(Instance::new(coroutine_closure_def_id, args))
|
||||
Some(Instance::new_raw(coroutine_closure_def_id, args))
|
||||
} else {
|
||||
Some(Instance {
|
||||
def: ty::InstanceKind::ConstructCoroutineInClosureShim {
|
||||
|
|
@ -362,7 +362,7 @@ fn resolve_associated_item<'tcx>(
|
|||
args,
|
||||
})
|
||||
} else {
|
||||
Some(Instance::new(coroutine_closure_def_id, args))
|
||||
Some(Instance::new_raw(coroutine_closure_def_id, args))
|
||||
}
|
||||
}
|
||||
ty::Closure(closure_def_id, args) => {
|
||||
|
|
@ -381,7 +381,7 @@ fn resolve_associated_item<'tcx>(
|
|||
let name = tcx.item_name(trait_item_id);
|
||||
assert_eq!(name, sym::transmute);
|
||||
let args = tcx.erase_regions(rcvr_args);
|
||||
Some(ty::Instance::new(trait_item_id, args))
|
||||
Some(ty::Instance::new_raw(trait_item_id, args))
|
||||
} else {
|
||||
Instance::try_resolve_item_for_coroutine(tcx, trait_item_id, trait_id, rcvr_args)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,9 +112,8 @@ impl Cargo {
|
|||
let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
|
||||
|
||||
match cmd_kind {
|
||||
// No need to configure the target linker for these command types,
|
||||
// as they don't invoke rustc at all.
|
||||
Kind::Clean | Kind::Suggest | Kind::Format | Kind::Setup => {}
|
||||
// No need to configure the target linker for these command types.
|
||||
Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {}
|
||||
_ => {
|
||||
cargo.configure_linker(builder);
|
||||
}
|
||||
|
|
@ -205,6 +204,8 @@ impl Cargo {
|
|||
self
|
||||
}
|
||||
|
||||
// FIXME(onur-ozkan): Add coverage to make sure modifications to this function
|
||||
// doesn't cause cache invalidations (e.g., #130108).
|
||||
fn configure_linker(&mut self, builder: &Builder<'_>) -> &mut Cargo {
|
||||
let target = self.target;
|
||||
let compiler = self.compiler;
|
||||
|
|
|
|||
|
|
@ -1534,7 +1534,7 @@ impl<'a> Builder<'a> {
|
|||
let out = step.clone().run(self);
|
||||
let dur = start.elapsed();
|
||||
let deps = self.time_spent_on_dependencies.replace(parent + dur);
|
||||
(out, dur - deps)
|
||||
(out, dur.saturating_sub(deps))
|
||||
};
|
||||
|
||||
if self.config.print_step_timings && !self.config.dry_run() {
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ use tracing::{instrument, span};
|
|||
pub use utils::change_tracker::{
|
||||
CONFIG_CHANGE_HISTORY, find_recent_config_change_ids, human_readable_changes,
|
||||
};
|
||||
pub use utils::helpers::PanicTracker;
|
||||
|
||||
use crate::core::build_steps::vendor::VENDOR_DIR;
|
||||
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ pub fn find(build: &Build) {
|
|||
let targets: HashSet<_> = match build.config.cmd {
|
||||
// We don't need to check cross targets for these commands.
|
||||
crate::Subcommand::Clean { .. }
|
||||
| crate::Subcommand::Check { .. }
|
||||
| crate::Subcommand::Suggest { .. }
|
||||
| crate::Subcommand::Format { .. }
|
||||
| crate::Subcommand::Setup { .. } => {
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ fn test_language_clang() {
|
|||
|
||||
#[test]
|
||||
fn test_new_cc_build() {
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
|
||||
let cfg = new_cc_build(&build, target.clone());
|
||||
let compiler = cfg.get_compiler();
|
||||
|
|
@ -190,7 +190,7 @@ fn test_new_cc_build() {
|
|||
|
||||
#[test]
|
||||
fn test_default_compiler_wasi() {
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target = TargetSelection::from_user("wasm32-wasi");
|
||||
let wasi_sdk = PathBuf::from("/wasi-sdk");
|
||||
// SAFETY: bootstrap tests run on a single thread
|
||||
|
|
@ -215,7 +215,7 @@ fn test_default_compiler_wasi() {
|
|||
|
||||
#[test]
|
||||
fn test_default_compiler_fallback() {
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
|
||||
let mut cfg = cc::Build::new();
|
||||
let result = default_compiler(&mut cfg, Language::C, target, &build);
|
||||
|
|
@ -224,7 +224,7 @@ fn test_default_compiler_fallback() {
|
|||
|
||||
#[test]
|
||||
fn test_find_target_with_config() {
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
|
||||
let mut target_config = Target::default();
|
||||
target_config.cc = Some(PathBuf::from("dummy-cc"));
|
||||
|
|
@ -249,7 +249,7 @@ fn test_find_target_with_config() {
|
|||
|
||||
#[test]
|
||||
fn test_find_target_without_config() {
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target = TargetSelection::from_user("x86_64-unknown-linux-gnu");
|
||||
build.config.target_config.clear();
|
||||
find_target(&build, target.clone());
|
||||
|
|
@ -262,7 +262,7 @@ fn test_find_target_without_config() {
|
|||
|
||||
#[test]
|
||||
fn test_find() {
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["check".to_owned()])) });
|
||||
let mut build = Build::new(Config { ..Config::parse(Flags::parse(&["build".to_owned()])) });
|
||||
let target1 = TargetSelection::from_user("x86_64-unknown-linux-gnu");
|
||||
let target2 = TargetSelection::from_user("x86_64-unknown-openbsd");
|
||||
build.targets.push(target1.clone());
|
||||
|
|
|
|||
|
|
@ -7,8 +7,9 @@ use std::ffi::OsStr;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::sync::OnceLock;
|
||||
use std::thread::panicking;
|
||||
use std::time::{Instant, SystemTime, UNIX_EPOCH};
|
||||
use std::{env, fs, io, str};
|
||||
use std::{env, fs, io, panic, str};
|
||||
|
||||
use build_helper::util::fail;
|
||||
use object::read::archive::ArchiveFile;
|
||||
|
|
@ -22,6 +23,23 @@ pub use crate::utils::shared_helpers::{dylib_path, dylib_path_var};
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
/// A wrapper around `std::panic::Location` used to track the location of panics
|
||||
/// triggered by `t` macro usage.
|
||||
pub struct PanicTracker<'a>(pub &'a panic::Location<'a>);
|
||||
|
||||
impl Drop for PanicTracker<'_> {
|
||||
fn drop(&mut self) {
|
||||
if panicking() {
|
||||
eprintln!(
|
||||
"Panic was initiated from {}:{}:{}",
|
||||
self.0.file(),
|
||||
self.0.line(),
|
||||
self.0.column()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A helper macro to `unwrap` a result except also print out details like:
|
||||
///
|
||||
/// * The file/line of the panic
|
||||
|
|
@ -32,19 +50,21 @@ mod tests;
|
|||
/// using a `Result` with `try!`, but this may change one day...
|
||||
#[macro_export]
|
||||
macro_rules! t {
|
||||
($e:expr) => {
|
||||
($e:expr) => {{
|
||||
let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
|
||||
match $e {
|
||||
Ok(e) => e,
|
||||
Err(e) => panic!("{} failed with {}", stringify!($e), e),
|
||||
}
|
||||
};
|
||||
}};
|
||||
// it can show extra info in the second parameter
|
||||
($e:expr, $extra:expr) => {
|
||||
($e:expr, $extra:expr) => {{
|
||||
let _panic_guard = $crate::PanicTracker(std::panic::Location::caller());
|
||||
match $e {
|
||||
Ok(e) => e,
|
||||
Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra),
|
||||
}
|
||||
};
|
||||
}};
|
||||
}
|
||||
|
||||
pub use t;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3bf3402aea982b876eb56c87da17b0685c6461d5
|
||||
Subproject commit 387392674d74656f7cb437c05a96f0c52ea8e601
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 0d7964d5b22cf920237ef1282d869564b4883b88
|
||||
Subproject commit 8a8918c698534547fa8a1a693cb3e7277f0bfb2f
|
||||
|
|
@ -263,7 +263,7 @@ impl<'tcx> NonCopyConst<'tcx> {
|
|||
fn is_value_unfrozen_poly(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool {
|
||||
let def_id = body_id.hir_id.owner.to_def_id();
|
||||
let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
|
||||
let instance = ty::Instance::new(def_id, args);
|
||||
let instance = ty::Instance::new_raw(def_id, args);
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
let mut _3: u16;
|
||||
let mut _4: u32;
|
||||
+ scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
|
||||
+ let mut _5: bool;
|
||||
+ let _6: ();
|
||||
+ let _5: ();
|
||||
+ scope 2 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _6: bool;
|
||||
+ scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
- _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ switchInt(move _5) -> [0: bb2, otherwise: bb1];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = UbChecks();
|
||||
+ switchInt(copy _6) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ _6 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ _5 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_5);
|
||||
+ _0 = ShlUnchecked(copy _3, copy _4);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
let mut _3: u16;
|
||||
let mut _4: u32;
|
||||
+ scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
|
||||
+ let mut _5: bool;
|
||||
+ let _6: ();
|
||||
+ let _5: ();
|
||||
+ scope 2 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _6: bool;
|
||||
+ scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
- _0 = core::num::<impl u16>::unchecked_shl(move _3, move _4) -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ switchInt(move _5) -> [0: bb2, otherwise: bb1];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = UbChecks();
|
||||
+ switchInt(copy _6) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ _6 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ _5 = core::num::<impl u16>::unchecked_shl::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_5);
|
||||
+ _0 = ShlUnchecked(copy _3, copy _4);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
let mut _3: i64;
|
||||
let mut _4: u32;
|
||||
+ scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
|
||||
+ let mut _5: bool;
|
||||
+ let _6: ();
|
||||
+ let _5: ();
|
||||
+ scope 2 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _6: bool;
|
||||
+ scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
- _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ switchInt(move _5) -> [0: bb2, otherwise: bb1];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = UbChecks();
|
||||
+ switchInt(copy _6) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ _6 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ _5 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_5);
|
||||
+ _0 = ShrUnchecked(copy _3, copy _4);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
let mut _3: i64;
|
||||
let mut _4: u32;
|
||||
+ scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
|
||||
+ let mut _5: bool;
|
||||
+ let _6: ();
|
||||
+ let _5: ();
|
||||
+ scope 2 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _6: bool;
|
||||
+ scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -22,20 +22,20 @@
|
|||
StorageLive(_4);
|
||||
_4 = copy _2;
|
||||
- _0 = core::num::<impl i64>::unchecked_shr(move _3, move _4) -> [return: bb1, unwind continue];
|
||||
+ StorageLive(_6);
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ switchInt(move _5) -> [0: bb2, otherwise: bb1];
|
||||
+ StorageLive(_6);
|
||||
+ _6 = UbChecks();
|
||||
+ switchInt(copy _6) -> [0: bb2, otherwise: bb1];
|
||||
}
|
||||
|
||||
bb1: {
|
||||
+ _6 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ _5 = core::num::<impl i64>::unchecked_shr::precondition_check(copy _4) -> [return: bb2, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_5);
|
||||
+ _0 = ShrUnchecked(copy _3, copy _4);
|
||||
+ StorageDead(_6);
|
||||
+ StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
+ scope 2 {
|
||||
+ }
|
||||
+ scope 3 (inlined unreachable_unchecked) {
|
||||
+ let mut _4: bool;
|
||||
+ let _5: ();
|
||||
+ let _4: ();
|
||||
+ scope 4 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _5: bool;
|
||||
+ scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
_2 = move _1;
|
||||
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_3);
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_4);
|
||||
+ _3 = discriminant(_2);
|
||||
+ switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
|
||||
}
|
||||
|
|
@ -34,15 +34,15 @@
|
|||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageLive(_4);
|
||||
+ _4 = UbChecks();
|
||||
+ assume(copy _4);
|
||||
+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ assume(copy _5);
|
||||
+ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ _0 = move ((_2 as Some).0: T);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_4);
|
||||
+ StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
+ scope 2 {
|
||||
+ }
|
||||
+ scope 3 (inlined unreachable_unchecked) {
|
||||
+ let mut _4: bool;
|
||||
+ let _5: ();
|
||||
+ let _4: ();
|
||||
+ scope 4 (inlined core::ub_checks::check_language_ub) {
|
||||
+ let mut _5: bool;
|
||||
+ scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
+ }
|
||||
+ }
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
_2 = move _1;
|
||||
- _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2];
|
||||
+ StorageLive(_3);
|
||||
+ StorageLive(_5);
|
||||
+ StorageLive(_4);
|
||||
+ _3 = discriminant(_2);
|
||||
+ switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
|
||||
}
|
||||
|
|
@ -38,15 +38,15 @@
|
|||
- bb2 (cleanup): {
|
||||
- resume;
|
||||
+ bb2: {
|
||||
+ StorageLive(_4);
|
||||
+ _4 = UbChecks();
|
||||
+ assume(copy _4);
|
||||
+ _5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
+ StorageLive(_5);
|
||||
+ _5 = UbChecks();
|
||||
+ assume(copy _5);
|
||||
+ _4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
+ }
|
||||
+
|
||||
+ bb3: {
|
||||
+ _0 = move ((_2 as Some).0: T);
|
||||
+ StorageDead(_5);
|
||||
+ StorageDead(_4);
|
||||
+ StorageDead(_3);
|
||||
+ StorageDead(_2);
|
||||
+ return;
|
||||
|
|
|
|||
|
|
@ -10,9 +10,9 @@
|
|||
scope 2 {
|
||||
}
|
||||
scope 3 (inlined unreachable_unchecked) {
|
||||
let mut _4: bool;
|
||||
let _5: ();
|
||||
let _4: ();
|
||||
scope 4 (inlined core::ub_checks::check_language_ub) {
|
||||
let mut _5: bool;
|
||||
scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
StorageLive(_2);
|
||||
_2 = copy _1;
|
||||
StorageLive(_3);
|
||||
StorageLive(_5);
|
||||
StorageLive(_4);
|
||||
_3 = discriminant(_2);
|
||||
switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
|
||||
}
|
||||
|
|
@ -33,16 +33,16 @@
|
|||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_4);
|
||||
- _4 = UbChecks();
|
||||
+ _4 = const false;
|
||||
assume(copy _4);
|
||||
_5 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
StorageLive(_5);
|
||||
- _5 = UbChecks();
|
||||
+ _5 = const false;
|
||||
assume(copy _5);
|
||||
_4 = unreachable_unchecked::precondition_check() -> [return: bb1, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
_0 = move ((_2 as Some).0: i32);
|
||||
StorageDead(_5);
|
||||
StorageDead(_4);
|
||||
StorageDead(_3);
|
||||
StorageDead(_2);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -5,23 +5,18 @@
|
|||
debug bytes => _1;
|
||||
let mut _0: std::option::Option<[u8; 4]>;
|
||||
let _2: [u32; 4];
|
||||
let mut _3: [u8; 16];
|
||||
let mut _5: [u8; 4];
|
||||
let mut _6: u32;
|
||||
let mut _4: [u8; 4];
|
||||
scope 1 {
|
||||
debug dwords => _2;
|
||||
scope 2 {
|
||||
debug ip => _4;
|
||||
let _4: u32;
|
||||
debug ip => _3;
|
||||
let _3: u32;
|
||||
}
|
||||
}
|
||||
|
||||
bb0: {
|
||||
StorageLive(_2);
|
||||
StorageLive(_3);
|
||||
_3 = copy _1;
|
||||
_2 = move _3 as [u32; 4] (Transmute);
|
||||
StorageDead(_3);
|
||||
_2 = copy _1 as [u32; 4] (Transmute);
|
||||
switchInt(copy _2[0 of 4]) -> [0: bb1, otherwise: bb4];
|
||||
}
|
||||
|
||||
|
|
@ -34,15 +29,10 @@
|
|||
}
|
||||
|
||||
bb3: {
|
||||
_3 = copy _2[3 of 4];
|
||||
StorageLive(_4);
|
||||
_4 = copy _2[3 of 4];
|
||||
StorageLive(_5);
|
||||
StorageLive(_6);
|
||||
_6 = copy _4;
|
||||
_5 = move _6 as [u8; 4] (Transmute);
|
||||
StorageDead(_6);
|
||||
_0 = Option::<[u8; 4]>::Some(move _5);
|
||||
StorageDead(_5);
|
||||
_4 = copy _3 as [u8; 4] (Transmute);
|
||||
_0 = Option::<[u8; 4]>::Some(move _4);
|
||||
StorageDead(_4);
|
||||
goto -> bb5;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
// MIR for `match1` after PreCodegen
|
||||
|
||||
fn match1(_1: bool, _2: i32, _3: i32) -> i32 {
|
||||
debug c => _1;
|
||||
debug v1 => _2;
|
||||
debug v2 => _3;
|
||||
let mut _0: i32;
|
||||
|
||||
bb0: {
|
||||
_0 = Sub(copy _2, copy _3);
|
||||
return;
|
||||
}
|
||||
}
|
||||
10
tests/mir-opt/pre-codegen/matchbr.rs
Normal file
10
tests/mir-opt/pre-codegen/matchbr.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR matchbr.match1.PreCodegen.after.mir
|
||||
pub fn match1(c: bool, v1: i32, v2: i32) -> i32 {
|
||||
// CHECK-LABEL: fn match1(
|
||||
// CHECK: bb0:
|
||||
// CHECK-NEXT: _0 = Sub
|
||||
// CHECK-NEXT: return;
|
||||
if c { v1 - v2 } else { v1 - v2 }
|
||||
}
|
||||
|
|
@ -8,6 +8,9 @@
|
|||
let mut _3: std::option::Option<T>;
|
||||
let mut _4: isize;
|
||||
let mut _5: isize;
|
||||
- let mut _7: bool;
|
||||
- let mut _8: u8;
|
||||
- let mut _9: bool;
|
||||
scope 1 {
|
||||
debug a => _6;
|
||||
let _6: u8;
|
||||
|
|
@ -32,9 +35,7 @@
|
|||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_6);
|
||||
_6 = copy (((_1.0: std::option::Option<u8>) as Some).0: u8);
|
||||
StorageDead(_6);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,9 @@
|
|||
let mut _3: std::option::Option<T>;
|
||||
let mut _4: isize;
|
||||
let mut _5: isize;
|
||||
- let mut _7: bool;
|
||||
- let mut _8: u8;
|
||||
- let mut _9: bool;
|
||||
scope 1 {
|
||||
debug a => _6;
|
||||
let _6: u8;
|
||||
|
|
@ -32,9 +35,7 @@
|
|||
}
|
||||
|
||||
bb2: {
|
||||
StorageLive(_6);
|
||||
_6 = copy (((_1.0: std::option::Option<u8>) as Some).0: u8);
|
||||
StorageDead(_6);
|
||||
goto -> bb3;
|
||||
}
|
||||
|
||||
|
|
|
|||
27
tests/ui/asm/global-asm-mono-sym-fn.rs
Normal file
27
tests/ui/asm/global-asm-mono-sym-fn.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Test that we're properly monomorphizing sym args in global asm blocks
|
||||
// that point to associated items.
|
||||
|
||||
//@ edition: 2021
|
||||
//@ needs-asm-support
|
||||
//@ only-x86_64-unknown-linux-gnu
|
||||
//@ build-pass
|
||||
|
||||
#![no_main]
|
||||
|
||||
use std::arch::global_asm;
|
||||
|
||||
fn foo() {
|
||||
loop {}
|
||||
}
|
||||
|
||||
trait Foo {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
impl Foo for i32 {
|
||||
fn bar() {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
global_asm!(".global main", "main:", "call {}", sym <i32 as Foo>::bar);
|
||||
35
tests/ui/asm/naked-asm-mono-sym-fn.rs
Normal file
35
tests/ui/asm/naked-asm-mono-sym-fn.rs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Regression test for <https://github.com/rust-lang/rust/issues/140373>.
|
||||
// Test that we're properly monomorphizing sym args in naked asm blocks
|
||||
// that point to associated items.
|
||||
|
||||
//@ edition: 2021
|
||||
//@ needs-asm-support
|
||||
//@ only-x86_64
|
||||
//@ build-pass
|
||||
|
||||
trait Tr {
|
||||
extern "C" fn t();
|
||||
}
|
||||
|
||||
enum E<const C: usize> {}
|
||||
|
||||
impl<const C: usize> Tr for E<C> {
|
||||
extern "C" fn t() {
|
||||
println!("Const generic: {}", C);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(naked)]
|
||||
extern "C" fn foo<U: Tr>() {
|
||||
core::arch::naked_asm!(
|
||||
"push rax",
|
||||
"call {fn}",
|
||||
"pop rax",
|
||||
"ret",
|
||||
fn = sym <U as Tr>::t,
|
||||
);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo::<E<42>>();
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
|
||||
--> $DIR/wf-check-skipped.rs:17:25
|
||||
|
|
||||
LL | fn main() -> Foo::Bar::<Vec<[u32]>> {}
|
||||
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u32]`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[current] known-bug: #100041
|
||||
//@[current] check-pass
|
||||
//@ known-bug: #100041
|
||||
//@ check-pass
|
||||
// FIXME(inherent_associated_types): This should fail.
|
||||
|
||||
#![feature(inherent_associated_types)]
|
||||
|
|
@ -15,4 +15,3 @@ impl Foo {
|
|||
}
|
||||
|
||||
fn main() -> Foo::Bar::<Vec<[u32]>> {}
|
||||
//[next]~^ ERROR the size for values of type `[u32]` cannot be known at compilation time
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ LL | type Loop = Loop;
|
|||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||
|
||||
error[E0275]: overflow normalizing the type alias `Loop`
|
||||
--> $DIR/inherent-impls-overflow.rs:10:1
|
||||
--> $DIR/inherent-impls-overflow.rs:12:1
|
||||
|
|
||||
LL | impl Loop {}
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
@ -15,7 +15,7 @@ LL | impl Loop {}
|
|||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||
|
||||
error[E0275]: overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
|
||||
--> $DIR/inherent-impls-overflow.rs:14:17
|
||||
--> $DIR/inherent-impls-overflow.rs:17:17
|
||||
|
|
||||
LL | type Poly0<T> = Poly1<(T,)>;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -23,7 +23,7 @@ LL | type Poly0<T> = Poly1<(T,)>;
|
|||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||
|
||||
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
|
||||
--> $DIR/inherent-impls-overflow.rs:17:17
|
||||
--> $DIR/inherent-impls-overflow.rs:21:17
|
||||
|
|
||||
LL | type Poly1<T> = Poly0<(T,)>;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
@ -31,7 +31,7 @@ LL | type Poly1<T> = Poly0<(T,)>;
|
|||
= note: in case this is a recursive type alias, consider using a struct, enum, or union instead
|
||||
|
||||
error[E0275]: overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
|
||||
--> $DIR/inherent-impls-overflow.rs:21:1
|
||||
--> $DIR/inherent-impls-overflow.rs:26:1
|
||||
|
|
||||
LL | impl Poly0<()> {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,11 +1,31 @@
|
|||
error[E0271]: type mismatch resolving `Loop normalizes-to _`
|
||||
--> $DIR/inherent-impls-overflow.rs:10:6
|
||||
--> $DIR/inherent-impls-overflow.rs:8:13
|
||||
|
|
||||
LL | type Loop = Loop;
|
||||
| ^^^^ types differ
|
||||
|
||||
error[E0271]: type mismatch resolving `Loop normalizes-to _`
|
||||
--> $DIR/inherent-impls-overflow.rs:12:1
|
||||
|
|
||||
LL | impl Loop {}
|
||||
| ^^^^^^^^^^^^ types differ
|
||||
|
||||
error[E0271]: type mismatch resolving `Loop normalizes-to _`
|
||||
--> $DIR/inherent-impls-overflow.rs:12:6
|
||||
|
|
||||
LL | impl Loop {}
|
||||
| ^^^^ types differ
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _`
|
||||
--> $DIR/inherent-impls-overflow.rs:17:17
|
||||
|
|
||||
LL | type Poly0<T> = Poly1<(T,)>;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
|
||||
|
||||
error: type parameter `T` is only used recursively
|
||||
--> $DIR/inherent-impls-overflow.rs:14:24
|
||||
--> $DIR/inherent-impls-overflow.rs:17:24
|
||||
|
|
||||
LL | type Poly0<T> = Poly1<(T,)>;
|
||||
| - ^
|
||||
|
|
@ -15,8 +35,16 @@ LL | type Poly0<T> = Poly1<(T,)>;
|
|||
= help: consider removing `T` or referring to it in the body of the type alias
|
||||
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _`
|
||||
--> $DIR/inherent-impls-overflow.rs:21:17
|
||||
|
|
||||
LL | type Poly1<T> = Poly0<(T,)>;
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
|
||||
|
||||
error: type parameter `T` is only used recursively
|
||||
--> $DIR/inherent-impls-overflow.rs:17:24
|
||||
--> $DIR/inherent-impls-overflow.rs:21:24
|
||||
|
|
||||
LL | type Poly1<T> = Poly0<(T,)>;
|
||||
| - ^
|
||||
|
|
@ -27,14 +55,22 @@ LL | type Poly1<T> = Poly0<(T,)>;
|
|||
= note: all type parameters must be used in a non-recursive way in order to constrain their variance
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
|
||||
--> $DIR/inherent-impls-overflow.rs:21:6
|
||||
--> $DIR/inherent-impls-overflow.rs:26:1
|
||||
|
|
||||
LL | impl Poly0<()> {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Poly0<()> == _`
|
||||
--> $DIR/inherent-impls-overflow.rs:26:6
|
||||
|
|
||||
LL | impl Poly0<()> {}
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0271, E0275.
|
||||
For more information about an error, try `rustc --explain E0271`.
|
||||
|
|
|
|||
|
|
@ -5,21 +5,27 @@
|
|||
#![feature(lazy_type_alias)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
type Loop = Loop; //[current]~ ERROR overflow normalizing the type alias `Loop`
|
||||
type Loop = Loop;
|
||||
//[current]~^ ERROR overflow normalizing the type alias `Loop`
|
||||
//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
|
||||
|
||||
impl Loop {}
|
||||
//[current]~^ ERROR overflow normalizing the type alias `Loop`
|
||||
//[next]~^^ ERROR type mismatch resolving `Loop normalizes-to _`
|
||||
//[next]~| ERROR type mismatch resolving `Loop normalizes-to _`
|
||||
|
||||
type Poly0<T> = Poly1<(T,)>;
|
||||
//[current]~^ ERROR overflow normalizing the type alias `Poly0<(((((((...,),),),),),),)>`
|
||||
//[next]~^^ ERROR type parameter `T` is only used recursively
|
||||
//[next]~| ERROR overflow evaluating the requirement
|
||||
type Poly1<T> = Poly0<(T,)>;
|
||||
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
|
||||
//[next]~^^ ERROR type parameter `T` is only used recursively
|
||||
//[next]~| ERROR overflow evaluating the requirement
|
||||
|
||||
impl Poly0<()> {}
|
||||
//[current]~^ ERROR overflow normalizing the type alias `Poly1<(((((((...,),),),),),),)>`
|
||||
//[next]~^^ ERROR overflow evaluating the requirement `Poly0<()> == _`
|
||||
//[next]~| ERROR overflow evaluating the requirement
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
7
tests/ui/target_modifiers/auxiliary/fixed_x18.rs
Normal file
7
tests/ui/target_modifiers/auxiliary/fixed_x18.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
//@ no-prefer-dynamic
|
||||
//@ compile-flags: --target aarch64-unknown-none -Zfixed-x18
|
||||
//@ needs-llvm-components: aarch64
|
||||
|
||||
#![feature(no_core)]
|
||||
#![crate_type = "rlib"]
|
||||
#![no_core]
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
error: mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18`
|
||||
--> $DIR/incompatible_fixedx18.rs:12:1
|
||||
|
|
||||
LL | #![feature(no_core)]
|
||||
| ^
|
||||
|
|
||||
= help: the `-Zfixed-x18` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
|
||||
= note: unset `-Zfixed-x18` in this crate is incompatible with `-Zfixed-x18=` in dependency `fixed_x18`
|
||||
= help: set `-Zfixed-x18=` in this crate or unset `-Zfixed-x18` in `fixed_x18`
|
||||
= help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=fixed-x18` to silence this error
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
17
tests/ui/target_modifiers/incompatible_fixedx18.rs
Normal file
17
tests/ui/target_modifiers/incompatible_fixedx18.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
//@ aux-build:fixed_x18.rs
|
||||
//@ compile-flags: --target aarch64-unknown-none
|
||||
//@ needs-llvm-components: aarch64
|
||||
|
||||
//@ revisions:allow_match allow_mismatch error_generated
|
||||
//@[allow_match] compile-flags: -Zfixed-x18
|
||||
//@[allow_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=fixed-x18
|
||||
//@[error_generated] compile-flags:
|
||||
//@[allow_mismatch] check-pass
|
||||
//@[allow_match] check-pass
|
||||
|
||||
#![feature(no_core)]
|
||||
//[error_generated]~^ ERROR mixing `-Zfixed-x18` will cause an ABI mismatch in crate `incompatible_fixedx18`
|
||||
#![crate_type = "rlib"]
|
||||
#![no_core]
|
||||
|
||||
extern crate fixed_x18;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `for<'a> (): Trait<'a>` is not satisfied
|
||||
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:11
|
||||
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:7:22
|
||||
|
|
||||
LL | fn foo(x: for<'a> fn(<() as Trait<'a>>::Assoc)) {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a>` is not implemented for `()`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/dont-ice-on-bad-transmute-in-typeck.rs:3:1
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ impl<T> Overlap<T> for T {}
|
|||
impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
//~^ ERROR cannot find type `Missing` in this scope
|
||||
//~| ERROR the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
|
||||
//~| ERROR the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,18 @@ LL | trait ToUnit<'a> {
|
|||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: ['^0.Named(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), "'a"), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc), .. }
|
||||
error[E0277]: the trait bound `for<'a> *const T: ToUnit<'a>` is not satisfied
|
||||
--> $DIR/issue-118950-root-region.rs:19:9
|
||||
|
|
||||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `*const T`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/issue-118950-root-region.rs:8:1
|
||||
|
|
||||
LL | trait ToUnit<'a> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: Overlap<for<'a> fn(Assoc<'a, T>)>` is not satisfied
|
||||
--> $DIR/issue-118950-root-region.rs:19:47
|
||||
|
|
||||
|
|
@ -37,7 +49,7 @@ help: consider further restricting type parameter `T` with trait `Overlap`
|
|||
LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T>, T: Overlap<for<'a> fn(Assoc<'a, T>)> {}
|
||||
| ++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors; 1 warning emitted
|
||||
error: aborting due to 4 previous errors; 1 warning emitted
|
||||
|
||||
Some errors have detailed explanations: E0277, E0412.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the trait bound `(): Wf` is not satisfied
|
||||
--> $DIR/non-wf-in-coerce-pointers.rs:8:17
|
||||
--> $DIR/non-wf-in-coerce-pointers.rs:8:8
|
||||
|
|
||||
LL | f: &'static <() as Wf>::Assoc,
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Wf` is not implemented for `()`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/non-wf-in-coerce-pointers.rs:3:1
|
||||
|
|
|
|||
24
tests/ui/wf/check-wf-of-normalized-signature.rs
Normal file
24
tests/ui/wf/check-wf-of-normalized-signature.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
//@ revisions: current next
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@ check-pass
|
||||
|
||||
// Regression test for <https://github.com/rust-lang/trait-system-refactor-initiative/issues/194>.
|
||||
// Ensure that we check the well-formedness of `<Check as Mode>::Output<T>` after normalizing
|
||||
// the type to `()`, since we only imply outlives bounds from the normalized signature, so we
|
||||
// don't know (e.g.) that `&mut T` is WF.
|
||||
|
||||
|
||||
trait Mode {
|
||||
type Output<T>;
|
||||
fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T>;
|
||||
}
|
||||
|
||||
struct Check;
|
||||
|
||||
impl Mode for Check {
|
||||
type Output<T> = ();
|
||||
fn from_mut<T>(_r: &mut Self::Output<T>) -> Self::Output<&mut T> {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -8,7 +8,7 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
|
|||
= note: slice and array elements must have `Sized` type
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/wf-normalization-sized.rs:22:11
|
||||
--> $DIR/wf-normalization-sized.rs:21:11
|
||||
|
|
||||
LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
@ -17,27 +17,6 @@ LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
|||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
|
||||
error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
|
||||
--> $DIR/wf-normalization-sized.rs:19:11
|
||||
|
|
||||
LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
|
||||
| ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
|
||||
= note: slice and array elements must have `Sized` type
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/wf-normalization-sized.rs:22:11
|
||||
|
|
||||
LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
||||
| ^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
note: required by an implicit `Sized` bound in `Vec`
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
|
|
|||
|
|
@ -18,9 +18,7 @@ impl<T: ?Sized> WellUnformed for T {
|
|||
|
||||
const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
|
||||
//[next]~^ ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
|
||||
//[next]~| ERROR the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
|
||||
const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
|
||||
//[next]~^ ERROR the size for values of type `str` cannot be known at compilation time
|
||||
//[next]~| ERROR the size for values of type `str` cannot be known at compilation time
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue