Auto merge of #121078 - oli-obk:rollup-p11zsav, r=oli-obk

Rollup of 13 pull requests

Successful merges:

 - #116387 (Additional doc links and explanation of `Wake`.)
 - #118738 (Netbsd10 update)
 - #118890 (Clarify the lifetimes of allocations returned by the `Allocator` trait)
 - #120498 (Uplift `TypeVisitableExt` into `rustc_type_ir`)
 - #120530 (Be less confident when `dyn` suggestion is not checked for object safety)
 - #120915 (Fix suggestion span for `?Sized` when param type has default)
 - #121015 (Optimize `delayed_bug` handling.)
 - #121024 (implement `Default` for `AsciiChar`)
 - #121039 (Correctly compute adjustment casts in GVN)
 - #121045 (Fix two UI tests with incorrect directive / invalid revision)
 - #121049 (Do not point at `#[allow(_)]` as the reason for compat lint triggering)
 - #121071 (Use fewer delayed bugs.)
 - #121073 (Fix typos in `OneLock` doc)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-02-14 12:04:03 +00:00
commit 340bb19fea
93 changed files with 966 additions and 589 deletions

View file

@ -323,9 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
}
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
ExprKind::Err => {
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
}
ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {

View file

@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
match block {
Some(block) => self.lower_block_expr(block),
None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")),
None => self.expr_err(span, self.dcx().has_errors().unwrap()),
}
}

View file

@ -1285,9 +1285,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => {
hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered"))
}
TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
// Lower the anonymous structs or unions in a nested lowering context.
//
// ```

View file

@ -117,18 +117,14 @@ struct CfgChecker<'a, 'tcx> {
impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
#[track_caller]
fn fail(&self, location: Location, msg: impl AsRef<str>) {
let span = self.body.source_info(location).span;
// We use `span_delayed_bug` as we might see broken MIR when other errors have already
// occurred.
self.tcx.dcx().span_delayed_bug(
span,
format!(
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
location,
msg.as_ref()
),
// We might see broken MIR when other errors have already occurred.
assert!(
self.tcx.dcx().has_errors().is_some(),
"broken MIR in {:?} ({}) at {:?}:\n{}",
self.body.source.instance,
self.when,
location,
msg.as_ref(),
);
}

View file

@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
self.future_breakage_diagnostics.push(diagnostic.clone());
}
// Note that because this comes before the `match` below,
// `-Zeagerly-emit-delayed-bugs` continues to work even after we've
// issued an error and stopped recording new delayed bugs.
if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
diagnostic.level = Error;
}
@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
diagnostic.level = Bug;
}
DelayedBug => {
// FIXME(eddyb) this should check for `has_errors` and stop pushing
// once *any* errors were emitted (and truncate `delayed_bugs`
// when an error is first emitted, also), but maybe there's a case
// in which that's not sound? otherwise this is really inefficient.
let backtrace = std::backtrace::Backtrace::capture();
// This `unchecked_error_guaranteed` is valid. It is where the
// `ErrorGuaranteed` for delayed bugs originates.
#[allow(deprecated)]
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
self.delayed_bugs
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
return Some(guar);
// If we have already emitted at least one error, we don't need
// to record the delayed bug, because it'll never be used.
return if let Some(guar) = self.has_errors_or_lint_errors() {
Some(guar)
} else {
let backtrace = std::backtrace::Backtrace::capture();
// This `unchecked_error_guaranteed` is valid. It is where the
// `ErrorGuaranteed` for delayed bugs originates.
#[allow(deprecated)]
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
self.delayed_bugs
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
Some(guar)
};
}
Warning if !self.flags.can_emit_warnings => {
if diagnostic.has_future_breakage() {
@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
}
if is_error {
// If we have any delayed bugs recorded, we can discard them
// because they won't be used. (This should only occur if there
// have been no errors previously emitted, because we don't add
// new delayed bugs once the first error is emitted.)
if !self.delayed_bugs.is_empty() {
assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
self.delayed_bugs.clear();
self.delayed_bugs.shrink_to_fit();
}
// This `unchecked_error_guaranteed` is valid. It is where the
// `ErrorGuaranteed` for errors and lint errors originates.
#[allow(deprecated)]

View file

@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>(
if try_success_result.is_ok() {
// Nonterminal parser recovery might turn failed matches into successful ones,
// but for that it must have emitted an error already
tracker
.cx
.dcx()
.span_delayed_bug(sp, "Macro matching returned a success on the second try");
assert!(
tracker.cx.dcx().has_errors().is_some(),
"Macro matching returned a success on the second try"
);
}
if let Some(result) = tracker.result {

View file

@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose(
"use `dyn`",
"if this is an object-safe trait, use `dyn`",
sugg,
Applicability::MachineApplicable,
);

View file

@ -758,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// since we should have emitten an error for them earlier, and they will
// not be well-formed!
if polarity == ty::ImplPolarity::Negative {
self.tcx().dcx().span_delayed_bug(
binding.span,
assert!(
self.tcx().dcx().has_errors().is_some(),
"negative trait bounds should not have bindings",
);
continue;

View file

@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>(
let hir_param = &hir_generics.params[index];
if ty_param.def_id != hir_param.def_id.into() {
// valid programs always have lifetimes before types in the generic parameter list
// Valid programs always have lifetimes before types in the generic parameter list.
// ty_generics are normalized to be in this required order, and variances are built
// from ty generics, not from hir generics. but we need hir generics to get
// a span out
// a span out.
//
// if they aren't in the same order, then the user has written invalid code, and already
// got an error about it (or I'm wrong about this)
// If they aren't in the same order, then the user has written invalid code, and already
// got an error about it (or I'm wrong about this).
tcx.dcx().span_delayed_bug(
hir_param.span,
"hir generics and ty generics in different order",

View file

@ -85,7 +85,7 @@ pub(super) fn check_item(
(_, _, Unsafety::Unsafe, Negative) => {
// Reported in AST validation
tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "unsafe negative impl");
assert!(tcx.dcx().has_errors().is_some(), "unsafe negative impl");
Ok(())
}
(_, _, Unsafety::Normal, Negative)

View file

@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Never
| ty::Dynamic(_, _, ty::DynStar)
| ty::Error(_) => {
let reported = self
let guar = self
.dcx()
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
return Err(reported);
return Err(guar);
}
})
}

View file

@ -221,8 +221,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
if base_ty.is_none() {
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
// that isn't in the type table. We assume more relevant errors have already been
// emitted, so we delay an ICE if none have. (#64638)
self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`"));
// emitted. (#64638)
assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`");
}
if let Some(base_ty) = base_ty
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()

View file

@ -802,14 +802,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
// Errors in earlier passes can yield error variables without
// resolution errors here; delay ICE in favor of those errors.
self.tcx().dcx().span_delayed_bug(
self.var_infos[node_idx].origin.span(),
format!(
"collect_error_for_expanding_node() could not find \
error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
upper_bounds={upper_bounds:#?}"
),
// resolution errors here; ICE if no errors have been emitted yet.
assert!(
self.tcx().dcx().has_errors().is_some(),
"collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
upper_bounds={upper_bounds:#?}",
);
}

View file

@ -300,9 +300,9 @@ where
self.components_must_outlive(origin, subcomponents, region, category);
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
// later, since if a type variable is not resolved by
// this point it never will be
// Ignore this, we presume it will yield an error later,
// since if a type variable is not resolved by this point
// it never will be.
self.tcx.dcx().span_delayed_bug(
origin.span(),
format!("unresolved inference variable in outlives: {v:?}"),

View file

@ -172,13 +172,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
self.bound_from_components(components, visited)
}
Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error
// later, since if a type variable is not resolved by
// this point it never will be
// Ignore this, we presume it will yield an error later, since
// if a type variable is not resolved by this point it never
// will be.
self.tcx
.dcx()
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
// add a bound that never holds
// Add a bound that never holds.
VerifyBound::AnyBound(vec![])
}
}

View file

@ -431,14 +431,13 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
// If not, that means that we somehow buffered a lint for a node id
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
for (id, lints) in cx.context.buffered.map {
for early_lint in lints {
sess.dcx().span_delayed_bug(
early_lint.span,
format!(
"failed to process buffered lint here (dummy = {})",
id == ast::DUMMY_NODE_ID
),
if !lints.is_empty() {
assert!(
sess.dcx().has_errors().is_some(),
"failed to process buffered lint here (dummy = {})",
id == ast::DUMMY_NODE_ID
);
break;
}
}
}

View file

@ -207,6 +207,11 @@ pub fn explain_lint_level_source(
err: &mut Diagnostic,
) {
let name = lint.name_lower();
if let Level::Allow = level {
// Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint
// triggering. (#121009)
return;
}
match src {
LintLevelSource::Default => {
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name));

View file

@ -35,6 +35,16 @@ impl<'tcx> IntoKind for Const<'tcx> {
}
}
impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
fn flags(&self) -> TypeFlags {
self.0.flags
}
fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
self.0.outer_exclusive_binder
}
}
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
fn ty(self) -> Ty<'tcx> {
self.ty()
@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> {
self.0.kind
}
// FIXME(compiler-errors): Think about removing this.
#[inline]
pub fn flags(self) -> TypeFlags {
self.0.flags
}
// FIXME(compiler-errors): Think about removing this.
#[inline]
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
self.0.outer_exclusive_binder

View file

@ -28,7 +28,7 @@ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
Visibility,
TypeVisitable, Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'tcx>;
type Binder<T> = Binder<'tcx, T>;
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
type BoundVars = &'tcx List<ty::BoundVariableKind>;
type BoundVar = ty::BoundVariableKind;
type CanonicalVars = CanonicalVarInfos<'tcx>;
type Ty = Ty<'tcx>;
@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
) -> Self::Const {
Const::new_bound(self, debruijn, var, ty)
}
fn expect_error_or_delayed_bug() {
let has_errors = ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs());
assert!(has_errors.is_some());
}
}
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;

View file

@ -504,6 +504,16 @@ impl<'tcx> IntoKind for Ty<'tcx> {
}
}
impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> {
fn flags(&self) -> TypeFlags {
self.0.flags
}
fn outer_exclusive_binder(&self) -> DebruijnIndex {
self.0.outer_exclusive_binder
}
}
impl EarlyParamRegion {
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).

View file

@ -29,6 +29,16 @@ pub struct Predicate<'tcx>(
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
);
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
fn flags(&self) -> TypeFlags {
self.0.flags
}
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
self.0.outer_exclusive_binder
}
}
impl<'tcx> Predicate<'tcx> {
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
#[inline]
@ -36,11 +46,13 @@ impl<'tcx> Predicate<'tcx> {
self.0.internee
}
// FIXME(compiler-errors): Think about removing this.
#[inline(always)]
pub fn flags(self) -> TypeFlags {
self.0.flags
}
// FIXME(compiler-errors): Think about removing this.
#[inline(always)]
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
self.0.outer_exclusive_binder

View file

@ -26,6 +26,19 @@ impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
}
}
impl<'tcx> rustc_type_ir::visit::Flags for Region<'tcx> {
fn flags(&self) -> TypeFlags {
self.type_flags()
}
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
match **self {
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
_ => ty::INNERMOST,
}
}
}
impl<'tcx> Region<'tcx> {
#[inline]
pub fn new_early_param(

View file

@ -942,6 +942,16 @@ where
}
}
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
self.bound_vars
}
fn has_no_bound_vars(&self) -> bool {
self.bound_vars.is_empty()
}
}
impl<'tcx, T> Binder<'tcx, T> {
/// Skips the binder and returns the "bound" value. This is a
/// risky thing to do because it's easy to get confused about
@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> {
self.0.0
}
// FIXME(compiler-errors): Think about removing this.
#[inline(always)]
pub fn flags(self) -> TypeFlags {
self.0.0.flags

View file

@ -1320,6 +1320,7 @@ impl<'tcx> Ty<'tcx> {
ty
}
// FIXME(compiler-errors): Think about removing this.
#[inline]
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
self.0.outer_exclusive_binder

View file

@ -1,140 +1,10 @@
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
use rustc_errors::ErrorGuaranteed;
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sso::SsoHashSet;
use std::ops::ControlFlow;
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
/// Returns `true` if `self` has any late-bound regions that are either
/// bound by `binder` or bound by some binder outside of `binder`.
/// If `binder` is `ty::INNERMOST`, this indicates whether
/// there are any late-bound regions that appear free.
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
}
/// Returns `true` if this type has any regions that escape `binder` (and
/// hence are not bound by it).
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
self.has_vars_bound_at_or_above(binder.shifted_in(1))
}
/// Return `true` if this type has regions that are not a part of the type.
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
/// would return `true`. The latter can occur when traversing through the
/// former.
///
/// See [`HasEscapingVarsVisitor`] for more information.
fn has_escaping_bound_vars(&self) -> bool {
self.has_vars_bound_at_or_above(ty::INNERMOST)
}
fn has_type_flags(&self, flags: TypeFlags) -> bool {
let res =
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
trace!(?self, ?flags, ?res, "has_type_flags");
res
}
fn has_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PROJECTION)
}
fn has_inherent_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
}
fn has_opaque_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
}
fn has_coroutines(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
}
fn references_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_ERROR)
}
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
if self.references_error() {
// We must include lint errors and delayed bugs here.
if let Some(reported) =
ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs())
{
Err(reported)
} else {
bug!("expected some kind of error in `error_reported`");
}
} else {
Ok(())
}
}
fn has_non_region_param(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
}
fn has_infer_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_INFER)
}
fn has_infer_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
fn has_non_region_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
}
fn has_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_INFER)
}
fn has_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
}
fn has_non_region_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
}
fn has_param(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAM)
}
/// "Free" regions in this context means that it has any region
/// that is not (a) erased or (b) late-bound.
fn has_free_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
fn has_erased_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
}
/// True if there are any un-erased free regions.
fn has_erasable_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
/// Indicates whether this value references only 'global'
/// generic parameters that are the same regardless of what fn we are
/// in. This is used for caching.
fn is_global(&self) -> bool {
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
}
/// True if there are any late-bound regions
fn has_bound_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
}
/// True if there are any late-bound non-region variables
fn has_non_region_bound_vars(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
}
/// True if there are any bound variables
fn has_bound_vars(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
}
/// Indicates whether this value still has parameters/placeholders/inference variables
/// which could be replaced later, in a way that would change the results of `impl`
/// specialization.
fn still_further_specializable(&self) -> bool {
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
}
}
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
///////////////////////////////////////////////////////////////////////////
// Region folder
@ -370,185 +240,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
struct FoundEscapingVars;
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
/// bound region or a bound type.
///
/// So, for example, consider a type like the following, which has two binders:
///
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
///
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
/// fn type*, that type has an escaping region: `'a`.
///
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
/// we already use the term "free var". It refers to the regions or types that we use to represent
/// bound regions or type params on a fn definition while we are type checking its body.
///
/// To clarify, conceptually there is no particular difference between
/// an "escaping" var and a "free" var. However, there is a big
/// difference in practice. Basically, when "entering" a binding
/// level, one is generally required to do some sort of processing to
/// a bound var, such as replacing it with a fresh/placeholder
/// var, or making an entry in the environment to represent the
/// scope to which it is attached, etc. An escaping var represents
/// a bound var for which this processing has not yet been done.
struct HasEscapingVarsVisitor {
/// Anything bound by `outer_index` or "above" is escaping.
outer_index: ty::DebruijnIndex,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
type BreakTy = FoundEscapingVars;
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
self.outer_index.shift_in(1);
let result = t.super_visit_with(self);
self.outer_index.shift_out(1);
result
}
#[inline]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
// If the outer-exclusive-binder is *strictly greater* than
// `outer_index`, that means that `t` contains some content
// bound at `outer_index` or above (because
// `outer_exclusive_binder` is always 1 higher than the
// content in `t`). Therefore, `t` has some escaping vars.
if t.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
// If the region is bound by `outer_index` or anything outside
// of outer index, then it escapes the binders we have
// visited.
if r.bound_at_or_above_binder(self.outer_index) {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// If the outer-exclusive-binder is *strictly greater* than
// `outer_index`, that means that `ct` contains some content
// bound at `outer_index` or above (because
// `outer_exclusive_binder` is always 1 higher than the
// content in `t`). Therefore, `t` has some escaping vars.
if ct.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
if predicate.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
struct FoundFlags;
// FIXME: Optimize for checking for infer flags
struct HasTypeFlagsVisitor {
flags: ty::TypeFlags,
}
impl std::fmt::Debug for HasTypeFlagsVisitor {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.flags.fmt(fmt)
}
}
// Note: this visitor traverses values down to the level of
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
// type flags at the outer layer are enough. So it's faster than it first
// looks, particular for `Ty`/`Predicate` where it's just a field access.
//
// N.B. The only case where this isn't totally true is binders, which also
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
// are present, regardless of whether those bound variables are used. This
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
// specifically detect this case in `visit_binder`.
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
&mut self,
t: &Binder<'tcx, T>,
) -> ControlFlow<Self::BreakTy> {
// If we're looking for the HAS_BINDER_VARS flag, check if the
// binder has vars. This won't be present in the binder's bound
// value, so we need to check here too.
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.bound_vars().is_empty() {
return ControlFlow::Break(FoundFlags);
}
t.super_visit_with(self)
}
#[inline]
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
let flags = t.flags();
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call, as usual for `Region`.
let flags = r.type_flags();
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
if c.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
if predicate.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
}
/// Collects all the late-bound regions at the innermost binding level
/// into a hash set.
struct LateBoundRegionsCollector {

View file

@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
body_target_features: &'tcx [Symbol],
/// When inside the LHS of an assignment to a field, this is the type
/// of the LHS and the span of the assignment expression.
assignment_info: Option<(Ty<'tcx>, Span)>,
assignment_info: Option<Ty<'tcx>>,
in_union_destructure: bool,
param_env: ParamEnv<'tcx>,
inside_adt: bool,
@ -473,10 +473,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
if let ty::Adt(adt_def, _) = lhs.ty.kind()
&& adt_def.is_union()
{
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
if let Some(assigned_ty) = self.assignment_info {
if assigned_ty.needs_drop(self.tcx, self.param_env) {
// This would be unsafe, but should be outright impossible since we reject such unions.
self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
// This would be unsafe, but should be outright impossible since we
// reject such unions.
assert!(
self.tcx.dcx().has_errors().is_some(),
"union fields that need dropping should be impossible: \
{assigned_ty}"
);
}
} else {
self.requires_unsafe(expr.span, AccessToUnionField);
@ -492,14 +497,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
}
// Second, check for accesses to union fields
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
// Second, check for accesses to union fields. Don't have any
// special handling for AssignOp since it causes a read *and*
// write to lhs.
if matches!(expr.kind, ExprKind::Assign { .. }) {
self.assignment_info = Some((lhs.ty, expr.span));
self.assignment_info = Some(lhs.ty);
visit::walk_expr(self, lhs);
self.assignment_info = None;
visit::walk_expr(self, &self.thir()[rhs]);
return; // we have already visited everything by now
return; // We have already visited everything by now.
}
}
ExprKind::Borrow { borrow_kind, arg } => {

View file

@ -153,8 +153,7 @@ impl<'tcx> ConstToPat<'tcx> {
// a hard error when we don't have a valtree or when we find something in
// the valtree that is not structural; then this can all be made a lot simpler.
let structural =
traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty());
debug!(
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
cv.ty(),

View file

@ -243,10 +243,11 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
// old value is being dropped.
let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
if assigned_ty.needs_drop(self.tcx, self.param_env) {
// This would be unsafe, but should be outright impossible since we reject such unions.
self.tcx.dcx().span_delayed_bug(
self.source_info.span,
format!("union fields that need dropping should be impossible: {assigned_ty}")
// This would be unsafe, but should be outright impossible since we reject
// such unions.
assert!(
self.tcx.dcx().has_errors().is_some(),
"union fields that need dropping should be impossible: {assigned_ty}"
);
}
} else {

View file

@ -561,9 +561,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
.ok()?;
dest.into()
}
CastKind::FnPtrToPtr
| CastKind::PtrToPtr
| CastKind::PointerCoercion(
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
let src = self.evaluated[value].as_ref()?;
let src = self.ecx.read_immediate(src).ok()?;
let to = self.ecx.layout_of(to).ok()?;
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
ret.into()
}
CastKind::PointerCoercion(
ty::adjustment::PointerCoercion::MutToConstPointer
| ty::adjustment::PointerCoercion::ArrayToPointer
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
@ -571,8 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
let src = self.evaluated[value].as_ref()?;
let src = self.ecx.read_immediate(src).ok()?;
let to = self.ecx.layout_of(to).ok()?;
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
ret.into()
ImmTy::from_immediate(*src, to).into()
}
_ => return None,
},

View file

@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
let body = &tcx.mir_const(def).borrow();
if body.return_ty().references_error() {
tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
assert!(tcx.dcx().has_errors().is_some(), "mir_const_qualif: MIR had errors");
return Default::default();
}

View file

@ -1,6 +1,7 @@
use std::cmp::Ordering;
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
use rustc_type_ir::visit::TypeVisitableExt;
use rustc_type_ir::{
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
@ -62,8 +63,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
let value = value.fold_with(&mut canonicalizer);
// FIXME: Restore these assertions. Should we uplift type flags?
// assert!(!value.has_infer(), "unexpected infer in {value:?}");
// assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
assert!(!value.has_infer(), "unexpected infer in {value:?}");
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
let (max_universe, variables) = canonicalizer.finalize();

View file

@ -429,16 +429,16 @@ where
let formatter = query.format_value();
if old_hash != new_hash {
// We have an inconsistency. This can happen if one of the two
// results is tainted by errors. In this case, delay a bug to
// ensure compilation is doomed.
qcx.dep_context().sess().dcx().delayed_bug(format!(
// results is tainted by errors.
assert!(
qcx.dep_context().sess().dcx().has_errors().is_some(),
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
computed={:#?}\nfed={:#?}",
query.dep_kind(),
key,
formatter(&result),
formatter(&cached_result),
));
);
}
}
}

View file

@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>(
match unexpanded_ct.kind() {
ty::ConstKind::Expr(_) => {
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but
// currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it
// is evaluatable or not. For now we just ICE until this is implemented.
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete,
// but currently it is not possible to evaluate `ConstKind::Expr` so we are unable
// to tell if it is evaluatable or not. For now we just ICE until this is
// implemented.
Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
span,
"evaluating `ConstKind::Expr` is not currently supported",

View file

@ -3041,7 +3041,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
this = "the implicit `Sized` requirement on this type parameter";
}
if let Some(hir::Node::TraitItem(hir::TraitItem {
ident,
generics,
kind: hir::TraitItemKind::Type(bounds, None),
..
})) = tcx.hir().get_if_local(item_def_id)
@ -3053,7 +3053,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let (span, separator) = if let [.., last] = bounds {
(last.span().shrink_to_hi(), " +")
} else {
(ident.span.shrink_to_hi(), ":")
(generics.span.shrink_to_hi(), ":")
};
err.span_suggestion_verbose(
span,

View file

@ -236,9 +236,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
}
// It could be that we don't report an error because we have seen an `ErrorReported` from another source.
// We should probably be able to fix most of these, but some are delayed bugs that get a proper error
// after this function.
// It could be that we don't report an error because we have seen an `ErrorReported` from
// another source. We should probably be able to fix most of these, but some are delayed
// bugs that get a proper error after this function.
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
}
@ -519,7 +519,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_ref,
span,
) {
GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"),
GetSafeTransmuteErrorAndReason::Silent => {
return self.dcx().span_delayed_bug(
span, "silent safe transmute error"
);
}
GetSafeTransmuteErrorAndReason::Error {
err_msg,
safe_transmute_explanation,
@ -2990,7 +2994,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
(s, " +")
} else {
(span.shrink_to_hi(), ":")
(param.name.ident().span.shrink_to_hi(), ":")
};
err.span_suggestion_verbose(
span,

View file

@ -555,7 +555,7 @@ fn virtual_call_violations_for_method<'tcx>(
// NOTE: This check happens last, because it results in a lint, and not a
// hard error.
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| {
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, _span)| {
// dyn Trait is okay:
//
// trait Trait {
@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>(
// would already have reported an error at the definition of the
// auto trait.
if pred_trait_ref.args.len() != 1 {
tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters");
assert!(
tcx.dcx().has_errors().is_some(),
"auto traits cannot have generic parameters"
);
}
return false;
}

View file

@ -1,7 +1,6 @@
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::Span;
use std::ops::ControlFlow;
/// This method traverses the structure of `ty`, trying to find an
@ -30,19 +29,16 @@ use std::ops::ControlFlow;
/// that arose when the requirement was not enforced completely, see
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
pub fn search_for_structural_match_violation<'tcx>(
span: Span,
tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>,
) -> Option<Ty<'tcx>> {
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
ty.visit_with(&mut Search { tcx, seen: FxHashSet::default() }).break_value()
}
/// This implements the traversal over the structure of a given type to try to
/// find instances of ADTs (specifically structs or enums) that do not implement
/// `StructuralPartialEq`.
struct Search<'tcx> {
span: Span,
tcx: TyCtxt<'tcx>,
/// Tracks ADTs previously encountered during search, so that
@ -138,7 +134,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
bug!("unexpected type during structural-match checking: {:?}", ty);
}
ty::Error(_) => {
self.tcx.dcx().span_delayed_bug(self.span, "ty::Error in structural-match check");
// We still want to check other types after encountering an error,
// as this may still emit relevant errors.
return ControlFlow::Continue(());

View file

@ -0,0 +1,7 @@
use crate::Interner;
pub trait BoundVars<I: Interner> {
fn bound_vars(&self) -> I::BoundVars;
fn has_no_bound_vars(&self) -> bool;
}

View file

@ -2,9 +2,10 @@ use smallvec::SmallVec;
use std::fmt::Debug;
use std::hash::Hash;
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
use crate::{
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
UniverseIndex,
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
TyKind, UniverseIndex,
};
pub trait Interner: Sized {
@ -19,7 +20,10 @@ pub trait Interner: Sized {
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
type Term: Copy + Debug + Hash + Ord;
type Binder<T>;
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
type BoundVars: IntoIterator<Item = Self::BoundVar>;
type BoundVar;
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
// Kinds of tys
@ -28,7 +32,9 @@ pub trait Interner: Sized {
+ Hash
+ Ord
+ Into<Self::GenericArg>
+ IntoKind<Kind = TyKind<Self>>;
+ IntoKind<Kind = TyKind<Self>>
+ TypeSuperVisitable<Self>
+ Flags;
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
type ParamTy: Copy + Debug + Hash + Ord;
@ -48,7 +54,9 @@ pub trait Interner: Sized {
+ Ord
+ Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>>
+ ConstTy<Self>;
+ ConstTy<Self>
+ TypeSuperVisitable<Self>
+ Flags;
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
type ParamConst: Copy + Debug + Hash + Ord;
@ -62,7 +70,8 @@ pub trait Interner: Sized {
+ Hash
+ Ord
+ Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>>;
+ IntoKind<Kind = RegionKind<Self>>
+ Flags;
type EarlyParamRegion: Copy + Debug + Hash + Ord;
type LateParamRegion: Copy + Debug + Hash + Ord;
type BoundRegion: Copy + Debug + Hash + Ord;
@ -70,7 +79,7 @@ pub trait Interner: Sized {
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
// Predicates
type Predicate: Copy + Debug + Hash + Eq;
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
type TraitPredicate: Copy + Debug + Hash + Eq;
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
@ -86,6 +95,9 @@ pub trait Interner: Sized {
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
/// Assert that an error has been delayed or emitted.
fn expect_error_or_delayed_bug();
}
/// Common capabilities of placeholder kinds

View file

@ -30,6 +30,7 @@ pub mod visit;
#[macro_use]
mod macros;
mod binder;
mod canonical;
mod const_kind;
mod debug;
@ -39,6 +40,7 @@ mod interner;
mod predicate_kind;
mod region_kind;
pub use binder::*;
pub use canonical::*;
#[cfg(feature = "nightly")]
pub use codec::*;

View file

@ -45,8 +45,7 @@ use rustc_index::{Idx, IndexVec};
use std::fmt;
use std::ops::ControlFlow;
use crate::Interner;
use crate::Lrc;
use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
/// This trait is implemented for every type that can be visited,
/// providing the skeleton of the traversal.
@ -88,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized {
#[cfg(not(feature = "nightly"))]
type BreakTy;
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
where
I::Binder<T>: TypeSuperVisitable<I>,
{
fn visit_binder<T: TypeVisitable<I>>(
&mut self,
t: &I::Binder<T>,
) -> ControlFlow<Self::BreakTy> {
t.super_visit_with(self)
}
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy>
where
I::Ty: TypeSuperVisitable<I>,
{
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
t.super_visit_with(self)
}
// The default region visitor is a no-op because `Region` is non-recursive
// and has no `super_visit_with` method to call. That also explains the
// lack of `I::Region: TypeSuperVisitable<I>` bound.
// and has no `super_visit_with` method to call.
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
ControlFlow::Continue(())
}
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy>
where
I::Const: TypeSuperVisitable<I>,
{
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
c.super_visit_with(self)
}
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy>
where
I::Predicate: TypeSuperVisitable<I>,
{
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
p.super_visit_with(self)
}
}
@ -200,3 +189,363 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
self.iter().try_for_each(|t| t.visit_with(visitor))
}
}
pub trait Flags {
fn flags(&self) -> TypeFlags;
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex;
}
pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
fn has_type_flags(&self, flags: TypeFlags) -> bool;
/// Returns `true` if `self` has any late-bound regions that are either
/// bound by `binder` or bound by some binder outside of `binder`.
/// If `binder` is `ty::INNERMOST`, this indicates whether
/// there are any late-bound regions that appear free.
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool;
/// Returns `true` if this type has any regions that escape `binder` (and
/// hence are not bound by it).
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
self.has_vars_bound_at_or_above(binder.shifted_in(1))
}
/// Return `true` if this type has regions that are not a part of the type.
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
/// would return `true`. The latter can occur when traversing through the
/// former.
///
/// See [`HasEscapingVarsVisitor`] for more information.
fn has_escaping_bound_vars(&self) -> bool {
self.has_vars_bound_at_or_above(ty::INNERMOST)
}
fn has_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PROJECTION)
}
fn has_inherent_projections(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
}
fn has_opaque_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
}
fn has_coroutines(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
}
fn references_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_ERROR)
}
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>;
fn has_non_region_param(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
}
fn has_infer_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_INFER)
}
fn has_infer_types(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER)
}
fn has_non_region_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
}
fn has_infer(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_INFER)
}
fn has_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
}
fn has_non_region_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
}
fn has_param(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_PARAM)
}
/// "Free" regions in this context means that it has any region
/// that is not (a) erased or (b) late-bound.
fn has_free_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
fn has_erased_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
}
/// True if there are any un-erased free regions.
fn has_erasable_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
}
/// Indicates whether this value references only 'global'
/// generic parameters that are the same regardless of what fn we are
/// in. This is used for caching.
fn is_global(&self) -> bool {
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
}
/// True if there are any late-bound regions
fn has_bound_regions(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
}
/// True if there are any late-bound non-region variables
fn has_non_region_bound_vars(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
}
/// True if there are any bound variables
fn has_bound_vars(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
}
/// Indicates whether this value still has parameters/placeholders/inference variables
/// which could be replaced later, in a way that would change the results of `impl`
/// specialization.
fn still_further_specializable(&self) -> bool {
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
}
}
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
fn has_type_flags(&self, flags: TypeFlags) -> bool {
let res =
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
res
}
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
}
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
if self.references_error() {
if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) {
Err(guar)
} else {
panic!("type flags said there was an error, but now there is not")
}
} else {
Ok(())
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
struct FoundFlags;
// FIXME: Optimize for checking for infer flags
struct HasTypeFlagsVisitor {
flags: ty::TypeFlags,
}
impl std::fmt::Debug for HasTypeFlagsVisitor {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.flags.fmt(fmt)
}
}
// Note: this visitor traverses values down to the level of
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
// type flags at the outer layer are enough. So it's faster than it first
// looks, particular for `Ty`/`Predicate` where it's just a field access.
//
// N.B. The only case where this isn't totally true is binders, which also
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
// are present, regardless of whether those bound variables are used. This
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
// specifically detect this case in `visit_binder`.
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
type BreakTy = FoundFlags;
fn visit_binder<T: TypeVisitable<I>>(
&mut self,
t: &I::Binder<T>,
) -> ControlFlow<Self::BreakTy> {
// If we're looking for the HAS_BINDER_VARS flag, check if the
// binder has vars. This won't be present in the binder's bound
// value, so we need to check here too.
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.has_no_bound_vars() {
return ControlFlow::Break(FoundFlags);
}
t.super_visit_with(self)
}
#[inline]
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
let flags = t.flags();
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call, as usual for `Region`.
let flags = r.flags();
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
if c.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
// Note: no `super_visit_with` call.
if predicate.flags().intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::Continue(())
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
struct FoundEscapingVars;
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
/// bound region or a bound type.
///
/// So, for example, consider a type like the following, which has two binders:
///
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
///
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
/// fn type*, that type has an escaping region: `'a`.
///
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
/// we already use the term "free var". It refers to the regions or types that we use to represent
/// bound regions or type params on a fn definition while we are type checking its body.
///
/// To clarify, conceptually there is no particular difference between
/// an "escaping" var and a "free" var. However, there is a big
/// difference in practice. Basically, when "entering" a binding
/// level, one is generally required to do some sort of processing to
/// a bound var, such as replacing it with a fresh/placeholder
/// var, or making an entry in the environment to represent the
/// scope to which it is attached, etc. An escaping var represents
/// a bound var for which this processing has not yet been done.
struct HasEscapingVarsVisitor {
/// Anything bound by `outer_index` or "above" is escaping.
outer_index: ty::DebruijnIndex,
}
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
type BreakTy = FoundEscapingVars;
fn visit_binder<T: TypeVisitable<I>>(
&mut self,
t: &I::Binder<T>,
) -> ControlFlow<Self::BreakTy> {
self.outer_index.shift_in(1);
let result = t.super_visit_with(self);
self.outer_index.shift_out(1);
result
}
#[inline]
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
// If the outer-exclusive-binder is *strictly greater* than
// `outer_index`, that means that `t` contains some content
// bound at `outer_index` or above (because
// `outer_exclusive_binder` is always 1 higher than the
// content in `t`). Therefore, `t` has some escaping vars.
if t.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
// If the region is bound by `outer_index` or anything outside
// of outer index, then it escapes the binders we have
// visited.
if r.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
fn visit_const(&mut self, ct: I::Const) -> ControlFlow<Self::BreakTy> {
// If the outer-exclusive-binder is *strictly greater* than
// `outer_index`, that means that `ct` contains some content
// bound at `outer_index` or above (because
// `outer_exclusive_binder` is always 1 higher than the
// content in `t`). Therefore, `t` has some escaping vars.
if ct.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
#[inline]
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
if predicate.outer_exclusive_binder() > self.outer_index {
ControlFlow::Break(FoundEscapingVars)
} else {
ControlFlow::Continue(())
}
}
}
struct HasErrorVisitor;
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
type BreakTy = I::ErrorGuaranteed;
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> {
if let ty::Error(guar) = t.kind() {
ControlFlow::Break(guar)
} else {
t.super_visit_with(self)
}
}
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> {
if let ty::ConstKind::Error(guar) = c.kind() {
ControlFlow::Break(guar)
} else {
c.super_visit_with(self)
}
}
fn visit_region(&mut self, r: <I as Interner>::Region) -> ControlFlow<Self::BreakTy> {
if let ty::ReError(guar) = r.kind() {
ControlFlow::Break(guar)
} else {
ControlFlow::Continue(())
}
}
}

View file

@ -19,7 +19,7 @@ use core::task::Waker;
/// The implementation of waking a task on an executor.
///
/// This trait can be used to create a [`Waker`]. An executor can define an
/// implementation of this trait, and use that to construct a Waker to pass
/// implementation of this trait, and use that to construct a [`Waker`] to pass
/// to the tasks that are executed on that executor.
///
/// This trait is a memory-safe and ergonomic alternative to constructing a
@ -28,7 +28,14 @@ use core::task::Waker;
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems.
///
/// [arc]: ../../std/sync/struct.Arc.html
/// To construct a [`Waker`] from some type `W` implementing this trait,
/// wrap it in an [`Arc<W>`](Arc) and call `Waker::from()` on that.
/// It is also possible to convert to [`RawWaker`] in the same way.
///
/// <!-- Ideally we'd link to the `From` impl, but rustdoc doesn't generate any page for it within
/// `alloc` because `alloc` neither defines nor re-exports `From` or `Waker`, and we can't
/// link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker
/// without getting a link-checking error in CI. -->
///
/// # Examples
///
@ -100,7 +107,7 @@ pub trait Wake {
#[cfg(target_has_atomic = "ptr")]
#[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
/// Use a `Wake`-able type as a `Waker`.
/// Use a [`Wake`]-able type as a `Waker`.
///
/// No heap allocations or atomic operations are used for this conversion.
fn from(waker: Arc<W>) -> Waker {

View file

@ -95,8 +95,10 @@ impl fmt::Display for AllocError {
/// # Safety
///
/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to
/// valid memory and retain their validity while they are [*currently allocated*] and at
/// least one of the instance and all of its clones has not been dropped.
/// valid memory and retain their validity while they are [*currently allocated*] and the shorter
/// of:
/// - the borrow-checker lifetime of the allocator type itself.
/// - as long as at least one of the instance and all of its clones has not been dropped.
///
/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this
/// allocator. A copied or cloned allocator must behave like the same allocator, and
@ -114,6 +116,10 @@ pub unsafe trait Allocator {
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
/// not have its contents initialized.
///
/// The returned block of memory remains valid as long as it is [*currently allocated*] and the shorter of:
/// - the borrow-checker lifetime of the allocator type itself.
/// - as long as at the allocator and all its clones has not been dropped.
///
/// # Errors
///
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet

View file

@ -58,7 +58,7 @@ use crate::mem::transmute;
#[unstable(feature = "ascii_char", issue = "110998")]
#[repr(u8)]
pub enum AsciiChar {
/// U+0000
/// U+0000 (The default variant)
#[unstable(feature = "ascii_char_variants", issue = "110998")]
Null = 0,
/// U+0001

View file

@ -2,6 +2,8 @@
#![stable(feature = "rust1", since = "1.0.0")]
use crate::ascii::Char as AsciiChar;
/// A trait for giving a type a useful default value.
///
/// Sometimes, you want to fall back to some kind of default value, and
@ -158,6 +160,7 @@ macro_rules! default_impl {
default_impl! { (), (), "Returns the default value of `()`" }
default_impl! { bool, false, "Returns the default value of `false`" }
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" }
default_impl! { usize, 0, "Returns the default value of `0`" }
default_impl! { u8, 0, "Returns the default value of `0`" }

View file

@ -9,10 +9,14 @@ use crate::ptr;
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
/// or a [`LocalWaker`] which provides customized wakeup behavior.
///
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
///
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
/// that customizes the behavior of the `RawWaker`.
///
/// `RawWaker`s are unsafe to use.
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
///
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
/// [`Wake`]: ../../alloc/task/trait.Wake.html
#[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker {
@ -355,8 +359,12 @@ impl<'a> ContextBuilder<'a> {
/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
///
/// Constructing a `Waker` from a [`RawWaker`] is unsafe.
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
///
/// [`Future::poll()`]: core::future::Future::poll
/// [`Poll::Pending`]: core::task::Poll::Pending
/// [`Wake`]: ../../alloc/task/trait.Wake.html
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
#[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker {
@ -438,9 +446,15 @@ impl Waker {
/// Creates a new `Waker` from [`RawWaker`].
///
/// # Safety
///
/// The behavior of the returned `Waker` is undefined if the contract defined
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
/// Therefore this method is unsafe.
///
/// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
/// cost of a required heap allocation.)
///
/// [`Wake`]: ../../alloc/task/trait.Wake.html
#[inline]
#[must_use]
#[stable(feature = "futures_api", since = "1.36.0")]

View file

@ -7,7 +7,9 @@ fn main() {
let target_vendor =
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
println!("cargo:rustc-cfg=netbsd10");
}
if target_os == "linux"
|| target_os == "android"
|| target_os == "netbsd"

View file

@ -13,7 +13,7 @@ use crate::sync::Once;
///
/// # Examples
///
/// Using `OnceCell` to store a functions previously computed value (a.k.a.
/// Using `OnceLock` to store a functions previously computed value (a.k.a.
/// lazy static or memoizing):
///
/// ```

View file

@ -62,7 +62,7 @@ mod imp {
unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
}
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd"))]
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))]
fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
}
@ -72,7 +72,8 @@ mod imp {
target_os = "android",
target_os = "espidf",
target_os = "horizon",
target_os = "freebsd"
target_os = "freebsd",
netbsd10
)))]
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
false
@ -83,7 +84,8 @@ mod imp {
target_os = "android",
target_os = "espidf",
target_os = "horizon",
target_os = "freebsd"
target_os = "freebsd",
netbsd10
))]
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
use crate::sync::atomic::{AtomicBool, Ordering};
@ -230,7 +232,7 @@ mod imp {
}
// FIXME: once the 10.x release becomes the minimum, this can be dropped for simplification.
#[cfg(target_os = "netbsd")]
#[cfg(all(target_os = "netbsd", not(netbsd10)))]
mod imp {
use crate::ptr;

View file

@ -86,6 +86,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
(Some(Mode::Std), "no_global_oom_handling", None),
(Some(Mode::Std), "no_rc", None),
(Some(Mode::Std), "no_sync", None),
(Some(Mode::Std), "netbsd10", None),
(Some(Mode::Std), "backtrace_in_libstd", None),
/* Extra values not defined in the built-in targets yet, but used in std */
(Some(Mode::Std), "target_env", Some(&["libnx"])),

View file

@ -0,0 +1,25 @@
// Verify that we do not ICE when attempting to interpret casts between fn types.
// skip-filecheck
static FOO: fn() = || assert_ne!(42, 43);
static BAR: fn(i32, i32) = |a, b| assert_ne!(a, b);
fn main() {
FOO();
let bar: unsafe fn(i32, i32) = BAR;
let f: fn() = || {};
f();
f();
f();
let g: fn(i32) = |i| assert_eq!(i, 2);
g(2);
g(2);
g(2);
}

View file

@ -13,7 +13,7 @@ LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:38:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^
@ -25,7 +25,7 @@ LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:42:15
--> $DIR/inline-syntax.rs:39:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^
@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:46:15
--> $DIR/inline-syntax.rs:43:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^
@ -49,7 +49,7 @@ LL | .att_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:50:15
--> $DIR/inline-syntax.rs:47:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^
@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:54:15
--> $DIR/inline-syntax.rs:51:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^
@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:61:13
--> $DIR/inline-syntax.rs:58:13
|
LL | .intel_syntax noprefix
| ^

View file

@ -15,7 +15,7 @@ LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:38:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^
@ -27,7 +27,7 @@ LL | .intel_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:42:15
--> $DIR/inline-syntax.rs:39:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^
@ -39,7 +39,7 @@ LL | .intel_syntax aaa noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:46:15
--> $DIR/inline-syntax.rs:43:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^
@ -51,7 +51,7 @@ LL | .att_syntax noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:50:15
--> $DIR/inline-syntax.rs:47:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^
@ -63,7 +63,7 @@ LL | .att_syntax bbb noprefix
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:54:15
--> $DIR/inline-syntax.rs:51:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^
@ -75,7 +75,7 @@ LL | .intel_syntax noprefix; nop
| ^
error: unknown directive
--> $DIR/inline-syntax.rs:61:13
--> $DIR/inline-syntax.rs:58:13
|
LL | .intel_syntax noprefix
| ^

View file

@ -2,14 +2,11 @@
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64] check-pass
//[x86_64] needs-llvm-components: x86
//[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64_allowed] check-pass
//[x86_64_allowed] needs-llvm-components: x86
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm] build-fail
//[arm] needs-llvm-components: arm
//[arm] ignore-llvm-version: 18 - 99
// Newer LLVM produces extra error notes.
//Newer LLVM produces extra error notes.
//[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm_llvm_18] build-fail
//[arm_llvm_18] needs-llvm-components: arm

View file

@ -1,5 +1,5 @@
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:70:14
--> $DIR/inline-syntax.rs:67:14
|
LL | global_asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
= note: `#[warn(bad_asm_style)]` on by default
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:38:15
--> $DIR/inline-syntax.rs:35:15
|
LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:42:15
--> $DIR/inline-syntax.rs:39:15
|
LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:46:15
--> $DIR/inline-syntax.rs:43:15
|
LL | asm!(".att_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
--> $DIR/inline-syntax.rs:50:15
--> $DIR/inline-syntax.rs:47:15
|
LL | asm!(".att_syntax bbb noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:54:15
--> $DIR/inline-syntax.rs:51:15
|
LL | asm!(".intel_syntax noprefix; nop");
| ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default
--> $DIR/inline-syntax.rs:61:13
--> $DIR/inline-syntax.rs:58:13
|
LL | .intel_syntax noprefix
| ^^^^^^^^^^^^^^^^^^^^^^

View file

@ -0,0 +1,18 @@
// run-rustfix
pub struct DataStruct();
pub struct HelperStruct<'n> {
pub helpers: [Vec<&'n i64>; 2],
pub is_empty: bool,
}
impl DataStruct {
pub fn f(&self) -> HelperStruct {
let helpers = [vec![], vec![]];
HelperStruct { helpers: helpers.clone(), is_empty: helpers[0].is_empty() }
//~^ ERROR borrow of moved value
}
}
fn main() {}

View file

@ -1,4 +1,4 @@
//@run-rustfix
// run-rustfix
pub struct DataStruct();
pub struct HelperStruct<'n> {

View file

@ -9,9 +9,4 @@ LL | FOO => todo!(),
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the lint level is defined here
--> $DIR/issue-89088.rs:5:10
|
LL | #![allow(indirect_structural_match)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | type H = <dyn Fn(u8) -> (u8)>::Output;
| ++++ +

View file

@ -11,7 +11,7 @@ note: the lint level is defined here
|
LL | #[deny(bare_trait_objects)]
| ^^^^^^^^^^^^^^^^^^
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
| +++
@ -24,7 +24,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
| +++
@ -37,7 +37,7 @@ LL | let _x: &SomeTrait = todo!();
|
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let _x: &dyn SomeTrait = todo!();
| +++

View file

@ -11,7 +11,7 @@ note: the lint level is defined here
|
LL | #![deny(bare_trait_objects)]
| ^^^^^^^^^^^^^^^^^^
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | <dyn fmt::Debug>::fmt(self, f)
| +++

View file

@ -7,7 +7,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
| +++

View file

@ -7,7 +7,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
| ++++ +
@ -35,7 +35,7 @@ LL | let g = BitXor::bitor;
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let g = <dyn BitXor>::bitor;
| ++++ +

View file

@ -7,7 +7,7 @@ LL | Trait::nonexistent(());
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | <dyn Trait>::nonexistent(());
| ++++ +

View file

@ -21,7 +21,7 @@ LL | eq::<dyn, Foo>
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | eq::<dyn, dyn Foo>
| +++

View file

@ -7,7 +7,7 @@ LL | let _: Dyn::Ty;
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let _: <dyn Dyn>::Ty;
| ++++ +
@ -26,7 +26,7 @@ LL | Dyn::func();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | <dyn Dyn>::func();
| ++++ +
@ -39,7 +39,7 @@ LL | ::Dyn::func();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | <dyn (::Dyn)>::func();
| ++++++ ++
@ -52,7 +52,7 @@ LL | Dyn::CONST;
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | <dyn Dyn>::CONST;
| ++++ +

View file

@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: requested on the command line with `--force-warn bare-trait-objects`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
| +++

View file

@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: requested on the command line with `--force-warn bare-trait-objects`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
| +++

View file

@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
| +++

View file

@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
| +++

View file

@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
| +++

View file

@ -1,10 +1,7 @@
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
--> $DIR/future-incompat-json-test.rs:9:9
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
= note: `-A unused-variables` implied by `-A unused`
= help: to override `-A unused` add `#[allow(unused_variables)]`
"}}]}

View file

@ -4,7 +4,4 @@ warning: unused variable: `x`
|
LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
= note: `-A unused-variables` implied by `-A unused`
= help: to override `-A unused` add `#[allow(unused_variables)]`

View file

@ -60,11 +60,6 @@ LL | foo!(first)
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
= note: macro invocations at the end of a block are treated as expressions
= note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:24:13
|
LL | #[allow(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
@ -79,11 +74,6 @@ LL | let _ = foo!(second);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:29:13
|
LL | #[allow(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
@ -98,11 +88,6 @@ LL | let _ = foo!(third);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:32:13
|
LL | #[allow(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
@ -117,11 +102,6 @@ LL | let _ = foo!(fourth);
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
note: the lint level is defined here
--> $DIR/semicolon-in-expressions-from-macros.rs:37:13
|
LL | #[allow(semicolon_in_expressions_from_macros)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:

View file

@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize {
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn id<F>(f: dyn Copy) -> usize {
| +++
@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize {
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn id<F>(f: dyn Copy) -> usize {
| +++

View file

@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; }
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait B { fn f(a: dyn A) -> A; }
| +++
@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; }
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait B { fn f(a: A) -> dyn A; }
| +++
@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; }
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait A { fn g(b: dyn B) -> B; }
| +++
@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; }
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait A { fn g(b: B) -> dyn B; }
| +++
@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; }
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait B { fn f(a: dyn A) -> A; }
| +++
@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; }
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | trait A { fn g(b: dyn B) -> B; }
| +++

View file

@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
| +++

View file

@ -11,7 +11,7 @@ note: the lint level is defined here
|
LL | #![deny(bare_trait_objects)]
| ^^^^^^^^^^^^^^^^^^
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn ord_prefer_dot(s: String) -> dyn Ord {
| +++

View file

@ -25,7 +25,7 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
| +++
@ -49,7 +49,7 @@ LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
| +++
@ -73,7 +73,7 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
| +++

View file

@ -20,10 +20,4 @@ LL | if let CONSTANT = &&MyType {
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
= note: the traits must be derived, manual `impl`s are not sufficient
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
note: the lint level is defined here
--> $DIR/const-partial_eq-fallback-ice.rs:1:10
|
LL | #![allow(warnings)]
| ^^^^^^^^
= note: `#[allow(indirect_structural_match)]` implied by `#[allow(warnings)]`

View file

@ -139,11 +139,6 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
note: the lint level is defined here
--> $DIR/generate-mod.rs:30:10
|
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic:
@ -155,10 +150,5 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
note: the lint level is defined here
--> $DIR/generate-mod.rs:30:10
|
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)

View file

@ -0,0 +1,23 @@
trait Foo {
type Clone;
fn foo() -> Clone;
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
//~| ERROR the trait `Clone` cannot be made into an object [E0038]
}
trait DbHandle: Sized {}
trait DbInterface {
type DbHandle;
fn handle() -> DbHandle;
//~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
//~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
//~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
//~| ERROR the trait `DbHandle` cannot be made into an object [E0038]
}
fn main() {}

View file

@ -0,0 +1,81 @@
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:3:17
|
LL | fn foo() -> Clone;
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: if this is an object-safe trait, use `dyn`
|
LL | fn foo() -> dyn Clone;
| +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:15:20
|
LL | fn handle() -> DbHandle;
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: if this is an object-safe trait, use `dyn`
|
LL | fn handle() -> dyn DbHandle;
| +++
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:3:17
|
LL | fn foo() -> Clone;
| ^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is an object-safe trait, use `dyn`
|
LL | fn foo() -> dyn Clone;
| +++
error[E0038]: the trait `Clone` cannot be made into an object
--> $DIR/issue-116434-2015.rs:3:17
|
LL | fn foo() -> Clone;
| ^^^^^ `Clone` cannot be made into an object
|
= note: the trait cannot be made into an object because it requires `Self: Sized`
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
warning: trait objects without an explicit `dyn` are deprecated
--> $DIR/issue-116434-2015.rs:15:20
|
LL | fn handle() -> DbHandle;
| ^^^^^^^^
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: if this is an object-safe trait, use `dyn`
|
LL | fn handle() -> dyn DbHandle;
| +++
error[E0038]: the trait `DbHandle` cannot be made into an object
--> $DIR/issue-116434-2015.rs:15:20
|
LL | fn handle() -> DbHandle;
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-116434-2015.rs:11:17
|
LL | trait DbHandle: Sized {}
| -------- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
error: aborting due to 2 previous errors; 4 warnings emitted
For more information about this error, try `rustc --explain E0038`.

View file

@ -0,0 +1,17 @@
// edition:2021
trait Foo {
type Clone;
fn foo() -> Clone;
//~^ ERROR the trait `Clone` cannot be made into an object [E0038]
}
trait DbHandle: Sized {}
trait DbInterface {
type DbHandle;
fn handle() -> DbHandle;
//~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
}
fn main() {}

View file

@ -0,0 +1,26 @@
error[E0038]: the trait `Clone` cannot be made into an object
--> $DIR/issue-116434-2021.rs:5:17
|
LL | fn foo() -> Clone;
| ^^^^^ `Clone` cannot be made into an object
|
= note: the trait cannot be made into an object because it requires `Self: Sized`
= note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
error[E0038]: the trait `DbHandle` cannot be made into an object
--> $DIR/issue-116434-2021.rs:13:20
|
LL | fn handle() -> DbHandle;
| ^^^^^^^^ `DbHandle` cannot be made into an object
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> $DIR/issue-116434-2021.rs:9:17
|
LL | trait DbHandle: Sized {}
| -------- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait cannot be made into an object...
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -11,7 +11,7 @@ note: the lint level is defined here
|
LL | #![deny(bare_trait_objects)]
| ^^^^^^^^^^^^^^^^^^
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | bar: Box<dyn Bar>,
| +++
@ -24,7 +24,7 @@ LL | pub struct Foo {
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | dyn pub struct Foo {
| +++

View file

@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
| +++

View file

@ -0,0 +1,20 @@
// issue: 120878
fn main() {
struct StructA<A, B = A> {
_marker: std::marker::PhantomData<fn() -> (A, B)>,
}
struct StructB {
a: StructA<isize, [u8]>,
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
}
trait Trait {
type P<X>;
}
impl Trait for () {
type P<X> = [u8];
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time [E0277]
}
}

View file

@ -0,0 +1,37 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/suggest-maybe-sized-bound.rs:8:12
|
LL | a: StructA<isize, [u8]>,
| ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by an implicit `Sized` bound in `StructA`
--> $DIR/suggest-maybe-sized-bound.rs:3:23
|
LL | struct StructA<A, B = A> {
| ^^^^^ required by the implicit `Sized` requirement on this type parameter in `StructA`
help: consider relaxing the implicit `Sized` restriction
|
LL | struct StructA<A, B: ?Sized = A> {
| ++++++++
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/suggest-maybe-sized-bound.rs:17:21
|
LL | type P<X> = [u8];
| ^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
note: required by a bound in `Trait::P`
--> $DIR/suggest-maybe-sized-bound.rs:13:9
|
LL | type P<X>;
| ^^^^^^^^^^ required by this bound in `Trait::P`
help: consider relaxing the implicit `Sized` restriction
|
LL | type P<X>: ?Sized;
| ++++++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) {
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | fn foo(_x: dyn Foo + Send) {
| +++

View file

@ -36,8 +36,8 @@ LL | pub trait Bar: Foo<Assoc=()> + Sized {
| +++++++
help: consider relaxing the implicit `Sized` restriction
|
LL | pub trait Foo<RHS=Self: ?Sized> {
| ++++++++
LL | pub trait Foo<RHS: ?Sized=Self> {
| ++++++++
error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/issue-28576.rs:5:16
@ -56,8 +56,8 @@ LL | ) where Self: Sized;
| +++++++++++++++++
help: consider relaxing the implicit `Sized` restriction
|
LL | pub trait Foo<RHS=Self: ?Sized> {
| ++++++++
LL | pub trait Foo<RHS: ?Sized=Self> {
| ++++++++
error: aborting due to 3 previous errors

View file

@ -77,9 +77,4 @@ LL | impl Trait0 for dyn Send {}
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
note: the lint level is defined here
--> $DIR/issue-33140-hack-boundaries.rs:2:10
|
LL | #![allow(order_dependent_trait_objects)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -7,7 +7,7 @@ LL | let a = Foo::lol();
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
= note: `#[warn(bare_trait_objects)]` on by default
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let a = <dyn Foo>::lol();
| ++++ +
@ -26,7 +26,7 @@ LL | let b = Foo::<_>::lol();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let b = <dyn Foo::<_>>::lol();
| ++++ +
@ -45,7 +45,7 @@ LL | let c = Bar::lol();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let c = <dyn Bar>::lol();
| ++++ +
@ -64,7 +64,7 @@ LL | let d = Bar::<usize, _>::lol();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let d = <dyn Bar::<usize, _>>::lol();
| ++++ +
@ -83,7 +83,7 @@ LL | let e = Bar::<usize>::lol();
|
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
help: use `dyn`
help: if this is an object-safe trait, use `dyn`
|
LL | let e = <dyn Bar::<usize>>::lol();
| ++++ +