mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 14:23:45 +00:00
Auto merge of #133234 - jhpratt:rollup-42dmg4p, r=jhpratt
Rollup of 5 pull requests Successful merges: - #132732 (Use attributes for `dangling_pointers_from_temporaries` lint) - #133108 (lints_that_dont_need_to_run: never skip future-compat-reported lints) - #133190 (CI: use free runner in dist-aarch64-msvc) - #133196 (Make rustc --explain compatible with BusyBox less) - #133216 (Implement `~const Fn` trait goal in the new solver) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
fda6892747
@ -577,7 +577,7 @@ fn show_md_content_with_pager(content: &str, color: ColorConfig) {
|
|||||||
let mut cmd = Command::new(&pager_name);
|
let mut cmd = Command::new(&pager_name);
|
||||||
// FIXME: find if other pagers accept color options
|
// FIXME: find if other pagers accept color options
|
||||||
let mut print_formatted = if pager_name == "less" {
|
let mut print_formatted = if pager_name == "less" {
|
||||||
cmd.arg("-r");
|
cmd.arg("-R");
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
|
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
|
||||||
|
@ -879,6 +879,11 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
|
|||||||
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
|
lang, Normal, template!(NameValueStr: "name"), DuplicatesOk, EncodeCrossCrate::No, lang_items,
|
||||||
"lang items are subject to change",
|
"lang items are subject to change",
|
||||||
),
|
),
|
||||||
|
rustc_attr!(
|
||||||
|
rustc_as_ptr, Normal, template!(Word), ErrorFollowing,
|
||||||
|
EncodeCrossCrate::Yes,
|
||||||
|
"#[rustc_as_ptr] is used to mark functions returning pointers to their inner allocations."
|
||||||
|
),
|
||||||
rustc_attr!(
|
rustc_attr!(
|
||||||
rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
|
rustc_pass_by_value, Normal, template!(Word), ErrorFollowing,
|
||||||
EncodeCrossCrate::Yes,
|
EncodeCrossCrate::Yes,
|
||||||
|
@ -43,13 +43,10 @@ declare_lint! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME: false negatives (i.e. the lint is not emitted when it should be)
|
/// FIXME: false negatives (i.e. the lint is not emitted when it should be)
|
||||||
/// 1. Method calls that are not checked for:
|
/// 1. Ways to get a temporary that are not recognized:
|
||||||
/// - [`temporary_unsafe_cell.get()`][`core::cell::UnsafeCell::get()`]
|
|
||||||
/// - [`temporary_sync_unsafe_cell.get()`][`core::cell::SyncUnsafeCell::get()`]
|
|
||||||
/// 2. Ways to get a temporary that are not recognized:
|
|
||||||
/// - `owning_temporary.field`
|
/// - `owning_temporary.field`
|
||||||
/// - `owning_temporary[index]`
|
/// - `owning_temporary[index]`
|
||||||
/// 3. No checks for ref-to-ptr conversions:
|
/// 2. No checks for ref-to-ptr conversions:
|
||||||
/// - `&raw [mut] temporary`
|
/// - `&raw [mut] temporary`
|
||||||
/// - `&temporary as *(const|mut) _`
|
/// - `&temporary as *(const|mut) _`
|
||||||
/// - `ptr::from_ref(&temporary)` and friends
|
/// - `ptr::from_ref(&temporary)` and friends
|
||||||
@ -133,10 +130,11 @@ impl DanglingPointerSearcher<'_, '_> {
|
|||||||
|
|
||||||
fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) {
|
||||||
if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind
|
if let ExprKind::MethodCall(method, receiver, _args, _span) = expr.kind
|
||||||
&& matches!(method.ident.name, sym::as_ptr | sym::as_mut_ptr)
|
&& let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
|
||||||
|
&& cx.tcx.has_attr(fn_id, sym::rustc_as_ptr)
|
||||||
&& is_temporary_rvalue(receiver)
|
&& is_temporary_rvalue(receiver)
|
||||||
&& let ty = cx.typeck_results().expr_ty(receiver)
|
&& let ty = cx.typeck_results().expr_ty(receiver)
|
||||||
&& is_interesting(cx.tcx, ty)
|
&& owns_allocation(cx.tcx, ty)
|
||||||
{
|
{
|
||||||
// FIXME: use `emit_node_lint` when `#[primary_span]` is added.
|
// FIXME: use `emit_node_lint` when `#[primary_span]` is added.
|
||||||
cx.tcx.emit_node_span_lint(
|
cx.tcx.emit_node_span_lint(
|
||||||
@ -199,24 +197,25 @@ fn is_temporary_rvalue(expr: &Expr<'_>) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Array, Vec, String, CString, MaybeUninit, Cell, Box<[_]>, Box<str>, Box<CStr>,
|
// Array, Vec, String, CString, MaybeUninit, Cell, Box<[_]>, Box<str>, Box<CStr>, UnsafeCell,
|
||||||
// or any of the above in arbitrary many nested Box'es.
|
// SyncUnsafeCell, or any of the above in arbitrary many nested Box'es.
|
||||||
fn is_interesting(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
|
fn owns_allocation(tcx: TyCtxt<'_>, ty: Ty<'_>) -> bool {
|
||||||
if ty.is_array() {
|
if ty.is_array() {
|
||||||
true
|
true
|
||||||
} else if let Some(inner) = ty.boxed_ty() {
|
} else if let Some(inner) = ty.boxed_ty() {
|
||||||
inner.is_slice()
|
inner.is_slice()
|
||||||
|| inner.is_str()
|
|| inner.is_str()
|
||||||
|| inner.ty_adt_def().is_some_and(|def| tcx.is_lang_item(def.did(), LangItem::CStr))
|
|| inner.ty_adt_def().is_some_and(|def| tcx.is_lang_item(def.did(), LangItem::CStr))
|
||||||
|| is_interesting(tcx, inner)
|
|| owns_allocation(tcx, inner)
|
||||||
} else if let Some(def) = ty.ty_adt_def() {
|
} else if let Some(def) = ty.ty_adt_def() {
|
||||||
for lang_item in [LangItem::String, LangItem::MaybeUninit] {
|
for lang_item in [LangItem::String, LangItem::MaybeUninit, LangItem::UnsafeCell] {
|
||||||
if tcx.is_lang_item(def.did(), lang_item) {
|
if tcx.is_lang_item(def.did(), lang_item) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tcx.get_diagnostic_name(def.did())
|
tcx.get_diagnostic_name(def.did()).is_some_and(|name| {
|
||||||
.is_some_and(|name| matches!(name, sym::cstring_type | sym::Vec | sym::Cell))
|
matches!(name, sym::cstring_type | sym::Vec | sym::Cell | sym::SyncUnsafeCell)
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -123,17 +123,19 @@ fn lints_that_dont_need_to_run(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LintId> {
|
|||||||
let dont_need_to_run: FxIndexSet<LintId> = store
|
let dont_need_to_run: FxIndexSet<LintId> = store
|
||||||
.get_lints()
|
.get_lints()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
.filter(|lint| {
|
||||||
|
// Lints that show up in future-compat reports must always be run.
|
||||||
|
let has_future_breakage =
|
||||||
|
lint.future_incompatible.is_some_and(|fut| fut.reason.has_future_breakage());
|
||||||
|
!has_future_breakage && !lint.eval_always
|
||||||
|
})
|
||||||
.filter_map(|lint| {
|
.filter_map(|lint| {
|
||||||
if !lint.eval_always {
|
let lint_level = map.lint_level_id_at_node(tcx, LintId::of(lint), CRATE_HIR_ID);
|
||||||
let lint_level = map.lint_level_id_at_node(tcx, LintId::of(lint), CRATE_HIR_ID);
|
if matches!(lint_level, (Level::Allow, ..))
|
||||||
if matches!(lint_level, (Level::Allow, ..))
|
|| (matches!(lint_level, (.., LintLevelSource::Default)))
|
||||||
|| (matches!(lint_level, (.., LintLevelSource::Default)))
|
&& lint.default_level(tcx.sess.edition()) == Level::Allow
|
||||||
&& lint.default_level(tcx.sess.edition()) == Level::Allow
|
{
|
||||||
{
|
Some(LintId::of(lint))
|
||||||
Some(LintId::of(lint))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -466,6 +466,20 @@ impl FutureIncompatibilityReason {
|
|||||||
| FutureIncompatibilityReason::Custom(_) => None,
|
| FutureIncompatibilityReason::Custom(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_future_breakage(self) -> bool {
|
||||||
|
match self {
|
||||||
|
FutureIncompatibilityReason::FutureReleaseErrorReportInDeps => true,
|
||||||
|
|
||||||
|
FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps
|
||||||
|
| FutureIncompatibilityReason::FutureReleaseSemanticsChange
|
||||||
|
| FutureIncompatibilityReason::EditionError(_)
|
||||||
|
| FutureIncompatibilityReason::EditionSemanticsChange(_)
|
||||||
|
| FutureIncompatibilityReason::EditionAndFutureReleaseError(_)
|
||||||
|
| FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(_)
|
||||||
|
| FutureIncompatibilityReason::Custom(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FutureIncompatibleInfo {
|
impl FutureIncompatibleInfo {
|
||||||
|
@ -290,12 +290,7 @@ pub fn lint_level(
|
|||||||
let has_future_breakage = future_incompatible.map_or(
|
let has_future_breakage = future_incompatible.map_or(
|
||||||
// Default allow lints trigger too often for testing.
|
// Default allow lints trigger too often for testing.
|
||||||
sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow,
|
sess.opts.unstable_opts.future_incompat_test && lint.default_level != Level::Allow,
|
||||||
|incompat| {
|
|incompat| incompat.reason.has_future_breakage(),
|
||||||
matches!(
|
|
||||||
incompat.reason,
|
|
||||||
FutureIncompatibilityReason::FutureReleaseErrorReportInDeps
|
|
||||||
)
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Convert lint level to error level.
|
// Convert lint level to error level.
|
||||||
|
@ -376,7 +376,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_const_impl(self, def_id: DefId) -> bool {
|
fn impl_is_const(self, def_id: DefId) -> bool {
|
||||||
|
self.is_conditionally_const(def_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fn_is_const(self, def_id: DefId) -> bool {
|
||||||
self.is_conditionally_const(def_id)
|
self.is_conditionally_const(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,6 +633,76 @@ fn coroutine_closure_to_ambiguous_coroutine<I: Interner>(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This duplicates `extract_tupled_inputs_and_output_from_callable` but needs
|
||||||
|
/// to return different information (namely, the def id and args) so that we can
|
||||||
|
/// create const conditions.
|
||||||
|
///
|
||||||
|
/// Doing so on all calls to `extract_tupled_inputs_and_output_from_callable`
|
||||||
|
/// would be wasteful.
|
||||||
|
pub(in crate::solve) fn extract_fn_def_from_const_callable<I: Interner>(
|
||||||
|
cx: I,
|
||||||
|
self_ty: I::Ty,
|
||||||
|
) -> Result<(ty::Binder<I, (I::FnInputTys, I::Ty)>, I::DefId, I::GenericArgs), NoSolution> {
|
||||||
|
match self_ty.kind() {
|
||||||
|
ty::FnDef(def_id, args) => {
|
||||||
|
let sig = cx.fn_sig(def_id);
|
||||||
|
if sig.skip_binder().is_fn_trait_compatible()
|
||||||
|
&& !cx.has_target_features(def_id)
|
||||||
|
&& cx.fn_is_const(def_id)
|
||||||
|
{
|
||||||
|
Ok((
|
||||||
|
sig.instantiate(cx, args).map_bound(|sig| (sig.inputs(), sig.output())),
|
||||||
|
def_id,
|
||||||
|
args,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// `FnPtr`s are not const for now.
|
||||||
|
ty::FnPtr(..) => {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
// `Closure`s are not const for now.
|
||||||
|
ty::Closure(..) => {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
// `CoroutineClosure`s are not const for now.
|
||||||
|
ty::CoroutineClosure(..) => {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::Bool
|
||||||
|
| ty::Char
|
||||||
|
| ty::Int(_)
|
||||||
|
| ty::Uint(_)
|
||||||
|
| ty::Float(_)
|
||||||
|
| ty::Adt(_, _)
|
||||||
|
| ty::Foreign(_)
|
||||||
|
| ty::Str
|
||||||
|
| ty::Array(_, _)
|
||||||
|
| ty::Slice(_)
|
||||||
|
| ty::RawPtr(_, _)
|
||||||
|
| ty::Ref(_, _, _)
|
||||||
|
| ty::Dynamic(_, _, _)
|
||||||
|
| ty::Coroutine(_, _)
|
||||||
|
| ty::CoroutineWitness(..)
|
||||||
|
| ty::Never
|
||||||
|
| ty::Tuple(_)
|
||||||
|
| ty::Pat(_, _)
|
||||||
|
| ty::Alias(_, _)
|
||||||
|
| ty::Param(_)
|
||||||
|
| ty::Placeholder(..)
|
||||||
|
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
|
||||||
|
| ty::Error(_) => return Err(NoSolution),
|
||||||
|
|
||||||
|
ty::Bound(..)
|
||||||
|
| ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
|
||||||
|
panic!("unexpected type `{self_ty:?}`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Assemble a list of predicates that would be present on a theoretical
|
/// Assemble a list of predicates that would be present on a theoretical
|
||||||
/// user impl for an object type. These predicates must be checked any time
|
/// user impl for an object type. These predicates must be checked any time
|
||||||
/// we assemble a built-in object candidate for an object type, since they
|
/// we assemble a built-in object candidate for an object type, since they
|
||||||
|
@ -3,15 +3,15 @@
|
|||||||
|
|
||||||
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||||
use rustc_type_ir::inherent::*;
|
use rustc_type_ir::inherent::*;
|
||||||
|
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||||
use rustc_type_ir::{self as ty, Interner, elaborate};
|
use rustc_type_ir::{self as ty, Interner, elaborate};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use super::assembly::Candidate;
|
use super::assembly::{Candidate, structural_traits};
|
||||||
use crate::delegate::SolverDelegate;
|
use crate::delegate::SolverDelegate;
|
||||||
use crate::solve::assembly::{self};
|
|
||||||
use crate::solve::{
|
use crate::solve::{
|
||||||
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution,
|
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution,
|
||||||
QueryResult,
|
QueryResult, assembly,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I>
|
impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I>
|
||||||
@ -142,7 +142,7 @@ where
|
|||||||
ty::ImplPolarity::Positive => {}
|
ty::ImplPolarity::Positive => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !cx.is_const_impl(impl_def_id) {
|
if !cx.impl_is_const(impl_def_id) {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ where
|
|||||||
_ecx: &mut EvalCtxt<'_, D>,
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
_goal: Goal<I, Self>,
|
_goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
todo!("Copy/Clone is not yet const")
|
Err(NoSolution)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_pointer_like_candidate(
|
fn consider_builtin_pointer_like_candidate(
|
||||||
@ -225,11 +225,48 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_fn_trait_candidates(
|
fn consider_builtin_fn_trait_candidates(
|
||||||
_ecx: &mut EvalCtxt<'_, D>,
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
_goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
_kind: rustc_type_ir::ClosureKind,
|
_kind: rustc_type_ir::ClosureKind,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
todo!("Fn* are not yet const")
|
let cx = ecx.cx();
|
||||||
|
|
||||||
|
let self_ty = goal.predicate.self_ty();
|
||||||
|
let (inputs_and_output, def_id, args) =
|
||||||
|
structural_traits::extract_fn_def_from_const_callable(cx, self_ty)?;
|
||||||
|
|
||||||
|
// A built-in `Fn` impl only holds if the output is sized.
|
||||||
|
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
||||||
|
let output_is_sized_pred = inputs_and_output.map_bound(|(_, output)| {
|
||||||
|
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
|
||||||
|
});
|
||||||
|
let requirements = cx
|
||||||
|
.const_conditions(def_id)
|
||||||
|
.iter_instantiated(cx, args)
|
||||||
|
.map(|trait_ref| {
|
||||||
|
(
|
||||||
|
GoalSource::ImplWhereBound,
|
||||||
|
goal.with(cx, trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.chain([(GoalSource::ImplWhereBound, goal.with(cx, output_is_sized_pred))]);
|
||||||
|
|
||||||
|
let pred = inputs_and_output
|
||||||
|
.map_bound(|(inputs, _)| {
|
||||||
|
ty::TraitRef::new(cx, goal.predicate.def_id(), [
|
||||||
|
goal.predicate.self_ty(),
|
||||||
|
Ty::new_tup(cx, inputs.as_slice()),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
.to_host_effect_clause(cx, goal.predicate.constness);
|
||||||
|
|
||||||
|
Self::probe_and_consider_implied_clause(
|
||||||
|
ecx,
|
||||||
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||||
|
goal,
|
||||||
|
pred,
|
||||||
|
requirements,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_async_fn_trait_candidates(
|
fn consider_builtin_async_fn_trait_candidates(
|
||||||
@ -314,7 +351,7 @@ where
|
|||||||
_ecx: &mut EvalCtxt<'_, D>,
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
_goal: Goal<I, Self>,
|
_goal: Goal<I, Self>,
|
||||||
) -> Result<Candidate<I>, NoSolution> {
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
unreachable!("Destruct is not const")
|
Err(NoSolution)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_transmute_candidate(
|
fn consider_builtin_transmute_candidate(
|
||||||
|
@ -394,6 +394,9 @@ where
|
|||||||
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
|
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A built-in `Fn` impl only holds if the output is sized.
|
||||||
|
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
||||||
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
||||||
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
|
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
|
||||||
});
|
});
|
||||||
@ -408,8 +411,6 @@ where
|
|||||||
})
|
})
|
||||||
.upcast(cx);
|
.upcast(cx);
|
||||||
|
|
||||||
// A built-in `Fn` impl only holds if the output is sized.
|
|
||||||
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
|
||||||
Self::probe_and_consider_implied_clause(
|
Self::probe_and_consider_implied_clause(
|
||||||
ecx,
|
ecx,
|
||||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||||
@ -438,6 +439,9 @@ where
|
|||||||
goal_kind,
|
goal_kind,
|
||||||
env_region,
|
env_region,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// A built-in `AsyncFn` impl only holds if the output is sized.
|
||||||
|
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
||||||
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
||||||
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
|
|AsyncCallableRelevantTypes { output_coroutine_ty: output_ty, .. }| {
|
||||||
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output_ty])
|
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output_ty])
|
||||||
@ -494,8 +498,6 @@ where
|
|||||||
)
|
)
|
||||||
.upcast(cx);
|
.upcast(cx);
|
||||||
|
|
||||||
// A built-in `AsyncFn` impl only holds if the output is sized.
|
|
||||||
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
|
||||||
Self::probe_and_consider_implied_clause(
|
Self::probe_and_consider_implied_clause(
|
||||||
ecx,
|
ecx,
|
||||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||||
|
@ -326,6 +326,9 @@ where
|
|||||||
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
|
return ecx.forced_ambiguity(MaybeCause::Ambiguity);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// A built-in `Fn` impl only holds if the output is sized.
|
||||||
|
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
||||||
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
let output_is_sized_pred = tupled_inputs_and_output.map_bound(|(_, output)| {
|
||||||
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
|
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [output])
|
||||||
});
|
});
|
||||||
@ -335,8 +338,6 @@ where
|
|||||||
ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
|
ty::TraitRef::new(cx, goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
|
||||||
})
|
})
|
||||||
.upcast(cx);
|
.upcast(cx);
|
||||||
// A built-in `Fn` impl only holds if the output is sized.
|
|
||||||
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
|
||||||
Self::probe_and_consider_implied_clause(
|
Self::probe_and_consider_implied_clause(
|
||||||
ecx,
|
ecx,
|
||||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||||
@ -364,6 +365,9 @@ where
|
|||||||
// This region doesn't matter because we're throwing away the coroutine type
|
// This region doesn't matter because we're throwing away the coroutine type
|
||||||
Region::new_static(cx),
|
Region::new_static(cx),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// A built-in `AsyncFn` impl only holds if the output is sized.
|
||||||
|
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
||||||
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
let output_is_sized_pred = tupled_inputs_and_output_and_coroutine.map_bound(
|
||||||
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
|
|AsyncCallableRelevantTypes { output_coroutine_ty, .. }| {
|
||||||
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
|
ty::TraitRef::new(cx, cx.require_lang_item(TraitSolverLangItem::Sized), [
|
||||||
@ -380,8 +384,6 @@ where
|
|||||||
])
|
])
|
||||||
})
|
})
|
||||||
.upcast(cx);
|
.upcast(cx);
|
||||||
// A built-in `AsyncFn` impl only holds if the output is sized.
|
|
||||||
// (FIXME: technically we only need to check this if the type is a fn ptr...)
|
|
||||||
Self::probe_and_consider_implied_clause(
|
Self::probe_and_consider_implied_clause(
|
||||||
ecx,
|
ecx,
|
||||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
|
||||||
|
@ -162,6 +162,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||||||
self.check_rustc_std_internal_symbol(attr, span, target)
|
self.check_rustc_std_internal_symbol(attr, span, target)
|
||||||
}
|
}
|
||||||
[sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),
|
[sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs),
|
||||||
|
[sym::rustc_as_ptr, ..] => {
|
||||||
|
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||||
|
}
|
||||||
[sym::rustc_never_returns_null_ptr, ..] => {
|
[sym::rustc_never_returns_null_ptr, ..] => {
|
||||||
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
self.check_applied_to_fn_or_method(hir_id, attr, span, target)
|
||||||
}
|
}
|
||||||
|
@ -316,6 +316,7 @@ symbols! {
|
|||||||
SubdiagMessage,
|
SubdiagMessage,
|
||||||
Subdiagnostic,
|
Subdiagnostic,
|
||||||
Sync,
|
Sync,
|
||||||
|
SyncUnsafeCell,
|
||||||
T,
|
T,
|
||||||
Target,
|
Target,
|
||||||
ToOwned,
|
ToOwned,
|
||||||
@ -409,7 +410,6 @@ symbols! {
|
|||||||
arm,
|
arm,
|
||||||
arm_target_feature,
|
arm_target_feature,
|
||||||
array,
|
array,
|
||||||
as_mut_ptr,
|
|
||||||
as_ptr,
|
as_ptr,
|
||||||
as_ref,
|
as_ref,
|
||||||
as_str,
|
as_str,
|
||||||
@ -1655,6 +1655,7 @@ symbols! {
|
|||||||
rustc_allow_const_fn_unstable,
|
rustc_allow_const_fn_unstable,
|
||||||
rustc_allow_incoherent_impl,
|
rustc_allow_incoherent_impl,
|
||||||
rustc_allowed_through_unstable_modules,
|
rustc_allowed_through_unstable_modules,
|
||||||
|
rustc_as_ptr,
|
||||||
rustc_attrs,
|
rustc_attrs,
|
||||||
rustc_autodiff,
|
rustc_autodiff,
|
||||||
rustc_box,
|
rustc_box,
|
||||||
|
@ -223,7 +223,8 @@ pub trait Interner:
|
|||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
|
||||||
|
|
||||||
fn is_const_impl(self, def_id: Self::DefId) -> bool;
|
fn impl_is_const(self, def_id: Self::DefId) -> bool;
|
||||||
|
fn fn_is_const(self, def_id: Self::DefId) -> bool;
|
||||||
fn const_conditions(
|
fn const_conditions(
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
|
@ -1500,6 +1500,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||||||
/// [`as_ptr`]: Self::as_ptr
|
/// [`as_ptr`]: Self::as_ptr
|
||||||
#[unstable(feature = "box_as_ptr", issue = "129090")]
|
#[unstable(feature = "box_as_ptr", issue = "129090")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_mut_ptr(b: &mut Self) -> *mut T {
|
pub fn as_mut_ptr(b: &mut Self) -> *mut T {
|
||||||
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
|
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
|
||||||
@ -1548,6 +1549,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
|
|||||||
/// [`as_ptr`]: Self::as_ptr
|
/// [`as_ptr`]: Self::as_ptr
|
||||||
#[unstable(feature = "box_as_ptr", issue = "129090")]
|
#[unstable(feature = "box_as_ptr", issue = "129090")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn as_ptr(b: &Self) -> *const T {
|
pub fn as_ptr(b: &Self) -> *const T {
|
||||||
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
|
// This is a primitive deref, not going through `DerefMut`, and therefore not materializing
|
||||||
|
@ -1662,6 +1662,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
||||||
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
|
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn as_ptr(&self) -> *const T {
|
pub const fn as_ptr(&self) -> *const T {
|
||||||
// We shadow the slice method of the same name to avoid going through
|
// We shadow the slice method of the same name to avoid going through
|
||||||
@ -1724,6 +1725,7 @@ impl<T, A: Allocator> Vec<T, A> {
|
|||||||
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
|
||||||
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
|
#[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
||||||
// We shadow the slice method of the same name to avoid going through
|
// We shadow the slice method of the same name to avoid going through
|
||||||
|
@ -587,6 +587,7 @@ impl<T: ?Sized> Cell<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
||||||
#[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_cell_as_ptr", since = "1.32.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
pub const fn as_ptr(&self) -> *mut T {
|
pub const fn as_ptr(&self) -> *mut T {
|
||||||
self.value.get()
|
self.value.get()
|
||||||
@ -1149,6 +1150,7 @@ impl<T: ?Sized> RefCell<T> {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
#[stable(feature = "cell_as_ptr", since = "1.12.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
pub fn as_ptr(&self) -> *mut T {
|
pub fn as_ptr(&self) -> *mut T {
|
||||||
self.value.get()
|
self.value.get()
|
||||||
@ -2158,6 +2160,7 @@ impl<T: ?Sized> UnsafeCell<T> {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_unsafecell_get", since = "1.32.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
pub const fn get(&self) -> *mut T {
|
pub const fn get(&self) -> *mut T {
|
||||||
// We can just cast the pointer from `UnsafeCell<T>` to `T` because of
|
// We can just cast the pointer from `UnsafeCell<T>` to `T` because of
|
||||||
@ -2271,6 +2274,7 @@ impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T>
|
|||||||
/// See [`UnsafeCell`] for details.
|
/// See [`UnsafeCell`] for details.
|
||||||
#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
|
#[unstable(feature = "sync_unsafe_cell", issue = "95439")]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
#[rustc_diagnostic_item = "SyncUnsafeCell"]
|
||||||
#[rustc_pub_transparent]
|
#[rustc_pub_transparent]
|
||||||
pub struct SyncUnsafeCell<T: ?Sized> {
|
pub struct SyncUnsafeCell<T: ?Sized> {
|
||||||
value: UnsafeCell<T>,
|
value: UnsafeCell<T>,
|
||||||
@ -2304,6 +2308,7 @@ impl<T: ?Sized> SyncUnsafeCell<T> {
|
|||||||
/// when casting to `&mut T`, and ensure that there are no mutations
|
/// when casting to `&mut T`, and ensure that there are no mutations
|
||||||
/// or mutable aliases going on when casting to `&T`
|
/// or mutable aliases going on when casting to `&T`
|
||||||
#[inline]
|
#[inline]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
pub const fn get(&self) -> *mut T {
|
pub const fn get(&self) -> *mut T {
|
||||||
self.value.get()
|
self.value.get()
|
||||||
|
@ -500,6 +500,7 @@ impl CStr {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_str_as_ptr", since = "1.32.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
pub const fn as_ptr(&self) -> *const c_char {
|
pub const fn as_ptr(&self) -> *const c_char {
|
||||||
self.inner.as_ptr()
|
self.inner.as_ptr()
|
||||||
|
@ -525,6 +525,7 @@ impl<T> MaybeUninit<T> {
|
|||||||
/// until they are, it is advisable to avoid them.)
|
/// until they are, it is advisable to avoid them.)
|
||||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||||
#[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")]
|
#[rustc_const_stable(feature = "const_maybe_uninit_as_ptr", since = "1.59.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn as_ptr(&self) -> *const T {
|
pub const fn as_ptr(&self) -> *const T {
|
||||||
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
||||||
@ -566,6 +567,7 @@ impl<T> MaybeUninit<T> {
|
|||||||
/// until they are, it is advisable to avoid them.)
|
/// until they are, it is advisable to avoid them.)
|
||||||
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
#[stable(feature = "maybe_uninit", since = "1.36.0")]
|
||||||
#[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")]
|
#[rustc_const_stable(feature = "const_maybe_uninit_as_mut_ptr", since = "1.83.0")]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
||||||
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
// `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
|
||||||
|
@ -735,6 +735,7 @@ impl<T> [T] {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]
|
#[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn as_ptr(&self) -> *const T {
|
pub const fn as_ptr(&self) -> *const T {
|
||||||
@ -765,6 +766,7 @@ impl<T> [T] {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
|
#[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
pub const fn as_mut_ptr(&mut self) -> *mut T {
|
||||||
|
@ -373,6 +373,7 @@ impl str {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")]
|
#[rustc_const_stable(feature = "rustc_str_as_ptr", since = "1.32.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn as_ptr(&self) -> *const u8 {
|
pub const fn as_ptr(&self) -> *const u8 {
|
||||||
@ -390,6 +391,7 @@ impl str {
|
|||||||
#[stable(feature = "str_as_mut_ptr", since = "1.36.0")]
|
#[stable(feature = "str_as_mut_ptr", since = "1.36.0")]
|
||||||
#[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")]
|
#[rustc_const_stable(feature = "const_str_as_mut", since = "1.83.0")]
|
||||||
#[rustc_never_returns_null_ptr]
|
#[rustc_never_returns_null_ptr]
|
||||||
|
#[cfg_attr(not(bootstrap), rustc_as_ptr)]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const fn as_mut_ptr(&mut self) -> *mut u8 {
|
pub const fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||||
|
@ -477,7 +477,7 @@ auto:
|
|||||||
--enable-profiler
|
--enable-profiler
|
||||||
SCRIPT: python x.py dist bootstrap --include-default-paths
|
SCRIPT: python x.py dist bootstrap --include-default-paths
|
||||||
DIST_REQUIRE_ALL_TOOLS: 1
|
DIST_REQUIRE_ALL_TOOLS: 1
|
||||||
<<: *job-windows-8c
|
<<: *job-windows
|
||||||
|
|
||||||
- image: dist-i686-mingw
|
- image: dist-i686-mingw
|
||||||
env:
|
env:
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#![deny(dangling_pointers_from_temporaries)]
|
#![deny(dangling_pointers_from_temporaries)]
|
||||||
|
#![feature(sync_unsafe_cell)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::{Cell, SyncUnsafeCell, UnsafeCell};
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
@ -47,6 +48,10 @@ fn main() {
|
|||||||
//~^ ERROR a dangling pointer will be produced because the temporary `MaybeUninit<u8>` will be dropped
|
//~^ ERROR a dangling pointer will be produced because the temporary `MaybeUninit<u8>` will be dropped
|
||||||
declval::<Vec<AsPtrFake>>().as_ptr();
|
declval::<Vec<AsPtrFake>>().as_ptr();
|
||||||
//~^ ERROR a dangling pointer will be produced because the temporary `Vec<AsPtrFake>` will be dropped
|
//~^ ERROR a dangling pointer will be produced because the temporary `Vec<AsPtrFake>` will be dropped
|
||||||
|
declval::<UnsafeCell<u8>>().get();
|
||||||
|
//~^ ERROR a dangling pointer will be produced because the temporary `UnsafeCell<u8>` will be dropped
|
||||||
|
declval::<SyncUnsafeCell<u8>>().get();
|
||||||
|
//~^ ERROR a dangling pointer will be produced because the temporary `SyncUnsafeCell<u8>` will be dropped
|
||||||
declval::<Box<AsPtrFake>>().as_ptr();
|
declval::<Box<AsPtrFake>>().as_ptr();
|
||||||
declval::<AsPtrFake>().as_ptr();
|
declval::<AsPtrFake>().as_ptr();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error: a dangling pointer will be produced because the temporary `CString` will be dropped
|
error: a dangling pointer will be produced because the temporary `CString` will be dropped
|
||||||
--> $DIR/types.rs:20:26
|
--> $DIR/types.rs:21:26
|
||||||
|
|
|
|
||||||
LL | declval::<CString>().as_ptr();
|
LL | declval::<CString>().as_ptr();
|
||||||
| -------------------- ^^^^^^ this pointer will immediately be invalid
|
| -------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -15,7 +15,7 @@ LL | #![deny(dangling_pointers_from_temporaries)]
|
|||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `String` will be dropped
|
error: a dangling pointer will be produced because the temporary `String` will be dropped
|
||||||
--> $DIR/types.rs:22:25
|
--> $DIR/types.rs:23:25
|
||||||
|
|
|
|
||||||
LL | declval::<String>().as_ptr();
|
LL | declval::<String>().as_ptr();
|
||||||
| ------------------- ^^^^^^ this pointer will immediately be invalid
|
| ------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -26,7 +26,7 @@ LL | declval::<String>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Vec<u8>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Vec<u8>` will be dropped
|
||||||
--> $DIR/types.rs:24:26
|
--> $DIR/types.rs:25:26
|
||||||
|
|
|
|
||||||
LL | declval::<Vec<u8>>().as_ptr();
|
LL | declval::<Vec<u8>>().as_ptr();
|
||||||
| -------------------- ^^^^^^ this pointer will immediately be invalid
|
| -------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -37,7 +37,7 @@ LL | declval::<Vec<u8>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<CString>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<CString>` will be dropped
|
||||||
--> $DIR/types.rs:26:31
|
--> $DIR/types.rs:27:31
|
||||||
|
|
|
|
||||||
LL | declval::<Box<CString>>().as_ptr();
|
LL | declval::<Box<CString>>().as_ptr();
|
||||||
| ------------------------- ^^^^^^ this pointer will immediately be invalid
|
| ------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -48,7 +48,7 @@ LL | declval::<Box<CString>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<[u8]>` will be dropped
|
||||||
--> $DIR/types.rs:28:28
|
--> $DIR/types.rs:29:28
|
||||||
|
|
|
|
||||||
LL | declval::<Box<[u8]>>().as_ptr();
|
LL | declval::<Box<[u8]>>().as_ptr();
|
||||||
| ---------------------- ^^^^^^ this pointer will immediately be invalid
|
| ---------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -59,7 +59,7 @@ LL | declval::<Box<[u8]>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<str>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<str>` will be dropped
|
||||||
--> $DIR/types.rs:30:27
|
--> $DIR/types.rs:31:27
|
||||||
|
|
|
|
||||||
LL | declval::<Box<str>>().as_ptr();
|
LL | declval::<Box<str>>().as_ptr();
|
||||||
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -70,7 +70,7 @@ LL | declval::<Box<str>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<CStr>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<CStr>` will be dropped
|
||||||
--> $DIR/types.rs:32:28
|
--> $DIR/types.rs:33:28
|
||||||
|
|
|
|
||||||
LL | declval::<Box<CStr>>().as_ptr();
|
LL | declval::<Box<CStr>>().as_ptr();
|
||||||
| ---------------------- ^^^^^^ this pointer will immediately be invalid
|
| ---------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -81,7 +81,7 @@ LL | declval::<Box<CStr>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped
|
error: a dangling pointer will be produced because the temporary `[u8; 10]` will be dropped
|
||||||
--> $DIR/types.rs:34:27
|
--> $DIR/types.rs:35:27
|
||||||
|
|
|
|
||||||
LL | declval::<[u8; 10]>().as_ptr();
|
LL | declval::<[u8; 10]>().as_ptr();
|
||||||
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -92,7 +92,7 @@ LL | declval::<[u8; 10]>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<[u8; 10]>` will be dropped
|
||||||
--> $DIR/types.rs:36:32
|
--> $DIR/types.rs:37:32
|
||||||
|
|
|
|
||||||
LL | declval::<Box<[u8; 10]>>().as_ptr();
|
LL | declval::<Box<[u8; 10]>>().as_ptr();
|
||||||
| -------------------------- ^^^^^^ this pointer will immediately be invalid
|
| -------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -103,7 +103,7 @@ LL | declval::<Box<[u8; 10]>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<Vec<u8>>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<Vec<u8>>` will be dropped
|
||||||
--> $DIR/types.rs:38:31
|
--> $DIR/types.rs:39:31
|
||||||
|
|
|
|
||||||
LL | declval::<Box<Vec<u8>>>().as_ptr();
|
LL | declval::<Box<Vec<u8>>>().as_ptr();
|
||||||
| ------------------------- ^^^^^^ this pointer will immediately be invalid
|
| ------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -114,7 +114,7 @@ LL | declval::<Box<Vec<u8>>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<String>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<String>` will be dropped
|
||||||
--> $DIR/types.rs:40:30
|
--> $DIR/types.rs:41:30
|
||||||
|
|
|
|
||||||
LL | declval::<Box<String>>().as_ptr();
|
LL | declval::<Box<String>>().as_ptr();
|
||||||
| ------------------------ ^^^^^^ this pointer will immediately be invalid
|
| ------------------------ ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -125,7 +125,7 @@ LL | declval::<Box<String>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Box<Box<Box<Box<[u8]>>>>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Box<Box<Box<Box<[u8]>>>>` will be dropped
|
||||||
--> $DIR/types.rs:42:43
|
--> $DIR/types.rs:43:43
|
||||||
|
|
|
|
||||||
LL | declval::<Box<Box<Box<Box<[u8]>>>>>().as_ptr();
|
LL | declval::<Box<Box<Box<Box<[u8]>>>>>().as_ptr();
|
||||||
| ------------------------------------- ^^^^^^ this pointer will immediately be invalid
|
| ------------------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -136,7 +136,7 @@ LL | declval::<Box<Box<Box<Box<[u8]>>>>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Cell<u8>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Cell<u8>` will be dropped
|
||||||
--> $DIR/types.rs:44:27
|
--> $DIR/types.rs:45:27
|
||||||
|
|
|
|
||||||
LL | declval::<Cell<u8>>().as_ptr();
|
LL | declval::<Cell<u8>>().as_ptr();
|
||||||
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
| --------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -147,7 +147,7 @@ LL | declval::<Cell<u8>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `MaybeUninit<u8>` will be dropped
|
error: a dangling pointer will be produced because the temporary `MaybeUninit<u8>` will be dropped
|
||||||
--> $DIR/types.rs:46:34
|
--> $DIR/types.rs:47:34
|
||||||
|
|
|
|
||||||
LL | declval::<MaybeUninit<u8>>().as_ptr();
|
LL | declval::<MaybeUninit<u8>>().as_ptr();
|
||||||
| ---------------------------- ^^^^^^ this pointer will immediately be invalid
|
| ---------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -158,7 +158,7 @@ LL | declval::<MaybeUninit<u8>>().as_ptr();
|
|||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: a dangling pointer will be produced because the temporary `Vec<AsPtrFake>` will be dropped
|
error: a dangling pointer will be produced because the temporary `Vec<AsPtrFake>` will be dropped
|
||||||
--> $DIR/types.rs:48:33
|
--> $DIR/types.rs:49:33
|
||||||
|
|
|
|
||||||
LL | declval::<Vec<AsPtrFake>>().as_ptr();
|
LL | declval::<Vec<AsPtrFake>>().as_ptr();
|
||||||
| --------------------------- ^^^^^^ this pointer will immediately be invalid
|
| --------------------------- ^^^^^^ this pointer will immediately be invalid
|
||||||
@ -168,5 +168,27 @@ LL | declval::<Vec<AsPtrFake>>().as_ptr();
|
|||||||
= note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<AsPtrFake>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
= note: pointers do not have a lifetime; when calling `as_ptr` the `Vec<AsPtrFake>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||||
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
error: aborting due to 15 previous errors
|
error: a dangling pointer will be produced because the temporary `UnsafeCell<u8>` will be dropped
|
||||||
|
--> $DIR/types.rs:51:33
|
||||||
|
|
|
||||||
|
LL | declval::<UnsafeCell<u8>>().get();
|
||||||
|
| --------------------------- ^^^ this pointer will immediately be invalid
|
||||||
|
| |
|
||||||
|
| this `UnsafeCell<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
||||||
|
|
|
||||||
|
= note: pointers do not have a lifetime; when calling `get` the `UnsafeCell<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||||
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
|
error: a dangling pointer will be produced because the temporary `SyncUnsafeCell<u8>` will be dropped
|
||||||
|
--> $DIR/types.rs:53:37
|
||||||
|
|
|
||||||
|
LL | declval::<SyncUnsafeCell<u8>>().get();
|
||||||
|
| ------------------------------- ^^^ this pointer will immediately be invalid
|
||||||
|
| |
|
||||||
|
| this `SyncUnsafeCell<u8>` is deallocated at the end of the statement, bind it to a variable to extend its lifetime
|
||||||
|
|
|
||||||
|
= note: pointers do not have a lifetime; when calling `get` the `SyncUnsafeCell<u8>` will be deallocated at the end of the statement because nothing is referencing it as far as the type system is concerned
|
||||||
|
= help: for more information, see <https://doc.rust-lang.org/reference/destructors.html>
|
||||||
|
|
||||||
|
error: aborting due to 17 previous errors
|
||||||
|
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
//@ known-bug: #110395
|
|
||||||
//@ failure-status: 101
|
|
||||||
//@ dont-check-compiler-stderr
|
|
||||||
// FIXME(const_trait_impl) check-pass
|
|
||||||
//@ compile-flags: -Znext-solver
|
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
|
||||||
#![allow(internal_features, incomplete_features)]
|
|
||||||
#![no_std]
|
|
||||||
#![no_core]
|
|
||||||
#![feature(
|
|
||||||
auto_traits,
|
|
||||||
const_trait_impl,
|
|
||||||
effects,
|
|
||||||
lang_items,
|
|
||||||
no_core,
|
|
||||||
staged_api,
|
|
||||||
unboxed_closures,
|
|
||||||
rustc_attrs,
|
|
||||||
marker_trait_attr,
|
|
||||||
)]
|
|
||||||
#![stable(feature = "minicore", since = "1.0.0")]
|
|
||||||
|
|
||||||
fn test() {
|
|
||||||
fn is_const_fn<F>(_: F)
|
|
||||||
where
|
|
||||||
F: const FnOnce<()>,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const fn foo() {}
|
|
||||||
|
|
||||||
is_const_fn(foo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ---------------------------------------------------------------------- ///
|
|
||||||
/// Const fn trait definitions
|
|
||||||
|
|
||||||
#[const_trait]
|
|
||||||
#[lang = "fn"]
|
|
||||||
#[rustc_paren_sugar]
|
|
||||||
trait Fn<Args: Tuple>: ~const FnMut<Args> {
|
|
||||||
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[const_trait]
|
|
||||||
#[lang = "fn_mut"]
|
|
||||||
#[rustc_paren_sugar]
|
|
||||||
trait FnMut<Args: Tuple>: ~const FnOnce<Args> {
|
|
||||||
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[const_trait]
|
|
||||||
#[lang = "fn_once"]
|
|
||||||
#[rustc_paren_sugar]
|
|
||||||
trait FnOnce<Args: Tuple> {
|
|
||||||
#[lang = "fn_once_output"]
|
|
||||||
type Output;
|
|
||||||
|
|
||||||
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ---------------------------------------------------------------------- ///
|
|
||||||
/// All this other stuff needed for core. Unrelated to test.
|
|
||||||
|
|
||||||
#[lang = "destruct"]
|
|
||||||
#[const_trait]
|
|
||||||
trait Destruct {}
|
|
||||||
|
|
||||||
#[lang = "freeze"]
|
|
||||||
unsafe auto trait Freeze {}
|
|
||||||
|
|
||||||
#[lang = "drop"]
|
|
||||||
#[const_trait]
|
|
||||||
trait Drop {
|
|
||||||
fn drop(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[lang = "sized"]
|
|
||||||
trait Sized {}
|
|
||||||
#[lang = "copy"]
|
|
||||||
trait Copy {}
|
|
||||||
|
|
||||||
#[lang = "tuple_trait"]
|
|
||||||
trait Tuple {}
|
|
||||||
|
|
||||||
#[lang = "legacy_receiver"]
|
|
||||||
trait LegacyReceiver {}
|
|
||||||
|
|
||||||
impl<T: ?Sized> LegacyReceiver for &T {}
|
|
@ -0,0 +1,22 @@
|
|||||||
|
//@ aux-build:minicore.rs
|
||||||
|
//@ compile-flags: --crate-type=lib -Znext-solver -Cpanic=abort
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
#![feature(no_core, const_trait_impl)]
|
||||||
|
#![no_std]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
extern crate minicore;
|
||||||
|
use minicore::*;
|
||||||
|
|
||||||
|
fn is_const_fn<F>(_: F)
|
||||||
|
where
|
||||||
|
F: const FnOnce(),
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn foo() {}
|
||||||
|
|
||||||
|
fn test() {
|
||||||
|
is_const_fn(foo);
|
||||||
|
}
|
21
tests/ui/traits/const-traits/effects/minicore-fn-fail.rs
Normal file
21
tests/ui/traits/const-traits/effects/minicore-fn-fail.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//@ aux-build:minicore.rs
|
||||||
|
//@ compile-flags: --crate-type=lib -Znext-solver
|
||||||
|
|
||||||
|
#![feature(no_core, const_trait_impl)]
|
||||||
|
#![no_std]
|
||||||
|
#![no_core]
|
||||||
|
|
||||||
|
extern crate minicore;
|
||||||
|
use minicore::*;
|
||||||
|
|
||||||
|
const fn call_indirect<T: ~const Fn()>(t: &T) { t() }
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Foo {}
|
||||||
|
impl Foo for () {}
|
||||||
|
const fn foo<T: ~const Foo>() {}
|
||||||
|
|
||||||
|
const fn test() {
|
||||||
|
call_indirect(&foo::<()>);
|
||||||
|
//~^ ERROR the trait bound `(): ~const Foo` is not satisfied
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
error[E0277]: the trait bound `(): ~const Foo` is not satisfied
|
||||||
|
--> $DIR/minicore-fn-fail.rs:19:5
|
||||||
|
|
|
||||||
|
LL | call_indirect(&foo::<()>);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
@ -20,3 +20,9 @@ const fn test_op() {
|
|||||||
let _x = Add::add(1, 2);
|
let _x = Add::add(1, 2);
|
||||||
let _y = Custom + Custom;
|
let _y = Custom + Custom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fn call_indirect<T: ~const Fn()>(t: &T) { t() }
|
||||||
|
|
||||||
|
const fn call() {
|
||||||
|
call_indirect(&call);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user