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::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
ExprKind::Err => { ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
}
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => { 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> { fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
match block { match block {
Some(block) => self.lower_block_expr(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> { fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
let kind = match &t.kind { let kind = match &t.kind {
TyKind::Infer => hir::TyKind::Infer, TyKind::Infer => hir::TyKind::Infer,
TyKind::Err => { TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered"))
}
// Lower the anonymous structs or unions in a nested lowering context. // 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> { impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
#[track_caller] #[track_caller]
fn fail(&self, location: Location, msg: impl AsRef<str>) { fn fail(&self, location: Location, msg: impl AsRef<str>) {
let span = self.body.source_info(location).span; // We might see broken MIR when other errors have already occurred.
// We use `span_delayed_bug` as we might see broken MIR when other errors have already assert!(
// occurred. self.tcx.dcx().has_errors().is_some(),
self.tcx.dcx().span_delayed_bug( "broken MIR in {:?} ({}) at {:?}:\n{}",
span, self.body.source.instance,
format!( self.when,
"broken MIR in {:?} ({}) at {:?}:\n{}", location,
self.body.source.instance, msg.as_ref(),
self.when,
location,
msg.as_ref()
),
); );
} }

View file

@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
self.future_breakage_diagnostics.push(diagnostic.clone()); 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 { if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
diagnostic.level = Error; diagnostic.level = Error;
} }
@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
diagnostic.level = Bug; diagnostic.level = Bug;
} }
DelayedBug => { DelayedBug => {
// FIXME(eddyb) this should check for `has_errors` and stop pushing // If we have already emitted at least one error, we don't need
// once *any* errors were emitted (and truncate `delayed_bugs` // to record the delayed bug, because it'll never be used.
// when an error is first emitted, also), but maybe there's a case return if let Some(guar) = self.has_errors_or_lint_errors() {
// in which that's not sound? otherwise this is really inefficient. Some(guar)
let backtrace = std::backtrace::Backtrace::capture(); } else {
// This `unchecked_error_guaranteed` is valid. It is where the let backtrace = std::backtrace::Backtrace::capture();
// `ErrorGuaranteed` for delayed bugs originates. // This `unchecked_error_guaranteed` is valid. It is where the
#[allow(deprecated)] // `ErrorGuaranteed` for delayed bugs originates.
let guar = ErrorGuaranteed::unchecked_error_guaranteed(); #[allow(deprecated)]
self.delayed_bugs let guar = ErrorGuaranteed::unchecked_error_guaranteed();
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar)); self.delayed_bugs
return Some(guar); .push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
Some(guar)
};
} }
Warning if !self.flags.can_emit_warnings => { Warning if !self.flags.can_emit_warnings => {
if diagnostic.has_future_breakage() { if diagnostic.has_future_breakage() {
@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
} }
if is_error { 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 // This `unchecked_error_guaranteed` is valid. It is where the
// `ErrorGuaranteed` for errors and lint errors originates. // `ErrorGuaranteed` for errors and lint errors originates.
#[allow(deprecated)] #[allow(deprecated)]

View file

@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>(
if try_success_result.is_ok() { if try_success_result.is_ok() {
// Nonterminal parser recovery might turn failed matches into successful ones, // Nonterminal parser recovery might turn failed matches into successful ones,
// but for that it must have emitted an error already // but for that it must have emitted an error already
tracker assert!(
.cx tracker.cx.dcx().has_errors().is_some(),
.dcx() "Macro matching returned a success on the second try"
.span_delayed_bug(sp, "Macro matching returned a success on the second try"); );
} }
if let Some(result) = tracker.result { 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| { 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() { if self_ty.span.can_be_used_for_suggestions() {
lint.multipart_suggestion_verbose( lint.multipart_suggestion_verbose(
"use `dyn`", "if this is an object-safe trait, use `dyn`",
sugg, sugg,
Applicability::MachineApplicable, 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 // since we should have emitten an error for them earlier, and they will
// not be well-formed! // not be well-formed!
if polarity == ty::ImplPolarity::Negative { if polarity == ty::ImplPolarity::Negative {
self.tcx().dcx().span_delayed_bug( assert!(
binding.span, self.tcx().dcx().has_errors().is_some(),
"negative trait bounds should not have bindings", "negative trait bounds should not have bindings",
); );
continue; continue;

View file

@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>(
let hir_param = &hir_generics.params[index]; let hir_param = &hir_generics.params[index];
if ty_param.def_id != hir_param.def_id.into() { 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 // 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 // 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 // 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) // got an error about it (or I'm wrong about this).
tcx.dcx().span_delayed_bug( tcx.dcx().span_delayed_bug(
hir_param.span, hir_param.span,
"hir generics and ty generics in different order", "hir generics and ty generics in different order",

View file

@ -85,7 +85,7 @@ pub(super) fn check_item(
(_, _, Unsafety::Unsafe, Negative) => { (_, _, Unsafety::Unsafe, Negative) => {
// Reported in AST validation // 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(()) Ok(())
} }
(_, _, Unsafety::Normal, Negative) (_, _, Unsafety::Normal, Negative)

View file

@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
| ty::Never | ty::Never
| ty::Dynamic(_, _, ty::DynStar) | ty::Dynamic(_, _, ty::DynStar)
| ty::Error(_) => { | ty::Error(_) => {
let reported = self let guar = self
.dcx() .dcx()
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?")); .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() { if base_ty.is_none() {
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base // 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 // 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) // emitted. (#64638)
self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`")); assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`");
} }
if let Some(base_ty) = base_ty if let Some(base_ty) = base_ty
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind() && 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 // Errors in earlier passes can yield error variables without
// resolution errors here; delay ICE in favor of those errors. // resolution errors here; ICE if no errors have been emitted yet.
self.tcx().dcx().span_delayed_bug( assert!(
self.var_infos[node_idx].origin.span(), self.tcx().dcx().has_errors().is_some(),
format!( "collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
"collect_error_for_expanding_node() could not find \ universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \ upper_bounds={upper_bounds:#?}",
upper_bounds={upper_bounds:#?}"
),
); );
} }

View file

@ -300,9 +300,9 @@ where
self.components_must_outlive(origin, subcomponents, region, category); self.components_must_outlive(origin, subcomponents, region, category);
} }
Component::UnresolvedInferenceVariable(v) => { Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error // Ignore this, we presume it will yield an error later,
// later, since if a type variable is not resolved by // since if a type variable is not resolved by this point
// this point it never will be // it never will be.
self.tcx.dcx().span_delayed_bug( self.tcx.dcx().span_delayed_bug(
origin.span(), origin.span(),
format!("unresolved inference variable in outlives: {v:?}"), 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) self.bound_from_components(components, visited)
} }
Component::UnresolvedInferenceVariable(v) => { Component::UnresolvedInferenceVariable(v) => {
// ignore this, we presume it will yield an error // Ignore this, we presume it will yield an error later, since
// later, since if a type variable is not resolved by // if a type variable is not resolved by this point it never
// this point it never will be // will be.
self.tcx self.tcx
.dcx() .dcx()
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}")); .delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
// add a bound that never holds // Add a bound that never holds.
VerifyBound::AnyBound(vec![]) 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 // 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. // that was not lint-checked (perhaps it doesn't exist?). This is a bug.
for (id, lints) in cx.context.buffered.map { for (id, lints) in cx.context.buffered.map {
for early_lint in lints { if !lints.is_empty() {
sess.dcx().span_delayed_bug( assert!(
early_lint.span, sess.dcx().has_errors().is_some(),
format!( "failed to process buffered lint here (dummy = {})",
"failed to process buffered lint here (dummy = {})", id == ast::DUMMY_NODE_ID
id == ast::DUMMY_NODE_ID
),
); );
break;
} }
} }
} }

View file

@ -207,6 +207,11 @@ pub fn explain_lint_level_source(
err: &mut Diagnostic, err: &mut Diagnostic,
) { ) {
let name = lint.name_lower(); 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 { match src {
LintLevelSource::Default => { LintLevelSource::Default => {
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name)); 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> { impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
fn ty(self) -> Ty<'tcx> { fn ty(self) -> Ty<'tcx> {
self.ty() self.ty()
@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> {
self.0.kind self.0.kind
} }
// FIXME(compiler-errors): Think about removing this.
#[inline] #[inline]
pub fn flags(self) -> TypeFlags { pub fn flags(self) -> TypeFlags {
self.0.flags self.0.flags
} }
// FIXME(compiler-errors): Think about removing this.
#[inline] #[inline]
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex { pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
self.0.outer_exclusive_binder self.0.outer_exclusive_binder

View file

@ -28,7 +28,7 @@ use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind, self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate, ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
Visibility, TypeVisitable, Visibility,
}; };
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef}; use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr}; use rustc_ast::{self as ast, attr};
@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type GenericArg = ty::GenericArg<'tcx>; type GenericArg = ty::GenericArg<'tcx>;
type Term = ty::Term<'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 CanonicalVars = CanonicalVarInfos<'tcx>;
type Ty = Ty<'tcx>; type Ty = Ty<'tcx>;
@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
) -> Self::Const { ) -> Self::Const {
Const::new_bound(self, debruijn, var, ty) 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>, ()>; 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 { impl EarlyParamRegion {
/// Does this early bound region have a name? Early bound regions normally /// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`). /// 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>>>>, 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> { impl<'tcx> Predicate<'tcx> {
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`. /// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
#[inline] #[inline]
@ -36,11 +46,13 @@ impl<'tcx> Predicate<'tcx> {
self.0.internee self.0.internee
} }
// FIXME(compiler-errors): Think about removing this.
#[inline(always)] #[inline(always)]
pub fn flags(self) -> TypeFlags { pub fn flags(self) -> TypeFlags {
self.0.flags self.0.flags
} }
// FIXME(compiler-errors): Think about removing this.
#[inline(always)] #[inline(always)]
pub fn outer_exclusive_binder(self) -> DebruijnIndex { pub fn outer_exclusive_binder(self) -> DebruijnIndex {
self.0.outer_exclusive_binder 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> { impl<'tcx> Region<'tcx> {
#[inline] #[inline]
pub fn new_early_param( 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> { impl<'tcx, T> Binder<'tcx, T> {
/// Skips the binder and returns the "bound" value. This is a /// Skips the binder and returns the "bound" value. This is a
/// risky thing to do because it's easy to get confused about /// risky thing to do because it's easy to get confused about
@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> {
self.0.0 self.0.0
} }
// FIXME(compiler-errors): Think about removing this.
#[inline(always)] #[inline(always)]
pub fn flags(self) -> TypeFlags { pub fn flags(self) -> TypeFlags {
self.0.0.flags self.0.0.flags

View file

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

View file

@ -1,140 +1,10 @@
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags}; use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
use rustc_errors::ErrorGuaranteed;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sso::SsoHashSet; use rustc_data_structures::sso::SsoHashSet;
use std::ops::ControlFlow; use std::ops::ControlFlow;
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, 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 {}
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Region folder // 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 /// Collects all the late-bound regions at the innermost binding level
/// into a hash set. /// into a hash set.
struct LateBoundRegionsCollector { struct LateBoundRegionsCollector {

View file

@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
body_target_features: &'tcx [Symbol], body_target_features: &'tcx [Symbol],
/// When inside the LHS of an assignment to a field, this is the type /// When inside the LHS of an assignment to a field, this is the type
/// of the LHS and the span of the assignment expression. /// 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, in_union_destructure: bool,
param_env: ParamEnv<'tcx>, param_env: ParamEnv<'tcx>,
inside_adt: bool, 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() if let ty::Adt(adt_def, _) = lhs.ty.kind()
&& adt_def.is_union() && 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) { if assigned_ty.needs_drop(self.tcx, self.param_env) {
// This would be unsafe, but should be outright impossible since we reject such unions. // This would be unsafe, but should be outright impossible since we
self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}")); // reject such unions.
assert!(
self.tcx.dcx().has_errors().is_some(),
"union fields that need dropping should be impossible: \
{assigned_ty}"
);
} }
} else { } else {
self.requires_unsafe(expr.span, AccessToUnionField); 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); self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
} }
// Second, check for accesses to union fields // Second, check for accesses to union fields. Don't have any
// don't have any special handling for AssignOp since it causes a read *and* write to lhs // special handling for AssignOp since it causes a read *and*
// write to lhs.
if matches!(expr.kind, ExprKind::Assign { .. }) { 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); visit::walk_expr(self, lhs);
self.assignment_info = None; self.assignment_info = None;
visit::walk_expr(self, &self.thir()[rhs]); 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 } => { 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 // 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. // the valtree that is not structural; then this can all be made a lot simpler.
let structural = let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty());
traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
debug!( debug!(
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}", "search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
cv.ty(), cv.ty(),

View file

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

View file

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

View file

@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
let body = &tcx.mir_const(def).borrow(); let body = &tcx.mir_const(def).borrow();
if body.return_ty().references_error() { 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(); return Default::default();
} }

View file

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

View file

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

View file

@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>(
match unexpanded_ct.kind() { match unexpanded_ct.kind() {
ty::ConstKind::Expr(_) => { ty::ConstKind::Expr(_) => {
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but // FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete,
// currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it // but currently it is not possible to evaluate `ConstKind::Expr` so we are unable
// is evaluatable or not. For now we just ICE until this is implemented. // 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( Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
span, span,
"evaluating `ConstKind::Expr` is not currently supported", "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"; this = "the implicit `Sized` requirement on this type parameter";
} }
if let Some(hir::Node::TraitItem(hir::TraitItem { if let Some(hir::Node::TraitItem(hir::TraitItem {
ident, generics,
kind: hir::TraitItemKind::Type(bounds, None), kind: hir::TraitItemKind::Type(bounds, None),
.. ..
})) = tcx.hir().get_if_local(item_def_id) })) = 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 { let (span, separator) = if let [.., last] = bounds {
(last.span().shrink_to_hi(), " +") (last.span().shrink_to_hi(), " +")
} else { } else {
(ident.span.shrink_to_hi(), ":") (generics.span.shrink_to_hi(), ":")
}; };
err.span_suggestion_verbose( err.span_suggestion_verbose(
span, 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. // It could be that we don't report an error because we have seen an `ErrorReported` from
// We should probably be able to fix most of these, but some are delayed bugs that get a proper error // another source. We should probably be able to fix most of these, but some are delayed
// after this function. // bugs that get a proper error after this function.
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors")) 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, trait_ref,
span, 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 { GetSafeTransmuteErrorAndReason::Error {
err_msg, err_msg,
safe_transmute_explanation, safe_transmute_explanation,
@ -2990,7 +2994,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{ {
(s, " +") (s, " +")
} else { } else {
(span.shrink_to_hi(), ":") (param.name.ident().span.shrink_to_hi(), ":")
}; };
err.span_suggestion_verbose( err.span_suggestion_verbose(
span, 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 // NOTE: This check happens last, because it results in a lint, and not a
// hard error. // 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: // dyn Trait is okay:
// //
// trait Trait { // trait Trait {
@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>(
// would already have reported an error at the definition of the // would already have reported an error at the definition of the
// auto trait. // auto trait.
if pred_trait_ref.args.len() != 1 { 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; return false;
} }

View file

@ -1,7 +1,6 @@
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
use rustc_span::Span;
use std::ops::ControlFlow; use std::ops::ControlFlow;
/// This method traverses the structure of `ty`, trying to find an /// 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 /// that arose when the requirement was not enforced completely, see
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307. /// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
pub fn search_for_structural_match_violation<'tcx>( pub fn search_for_structural_match_violation<'tcx>(
span: Span,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
) -> Option<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 /// 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 /// find instances of ADTs (specifically structs or enums) that do not implement
/// `StructuralPartialEq`. /// `StructuralPartialEq`.
struct Search<'tcx> { struct Search<'tcx> {
span: Span,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
/// Tracks ADTs previously encountered during search, so that /// 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); bug!("unexpected type during structural-match checking: {:?}", ty);
} }
ty::Error(_) => { 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, // We still want to check other types after encountering an error,
// as this may still emit relevant errors. // as this may still emit relevant errors.
return ControlFlow::Continue(()); 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::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
use crate::{ use crate::{
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind, BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
UniverseIndex, TyKind, UniverseIndex,
}; };
pub trait Interner: Sized { pub trait Interner: Sized {
@ -19,7 +20,10 @@ pub trait Interner: Sized {
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord; type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
type Term: Copy + Debug + 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>>; type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
// Kinds of tys // Kinds of tys
@ -28,7 +32,9 @@ pub trait Interner: Sized {
+ Hash + Hash
+ Ord + Ord
+ Into<Self::GenericArg> + 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 Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord; type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
type ParamTy: Copy + Debug + Hash + Ord; type ParamTy: Copy + Debug + Hash + Ord;
@ -48,7 +54,9 @@ pub trait Interner: Sized {
+ Ord + Ord
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = ConstKind<Self>> + IntoKind<Kind = ConstKind<Self>>
+ ConstTy<Self>; + ConstTy<Self>
+ TypeSuperVisitable<Self>
+ Flags;
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord; type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike; type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
type ParamConst: Copy + Debug + Hash + Ord; type ParamConst: Copy + Debug + Hash + Ord;
@ -62,7 +70,8 @@ pub trait Interner: Sized {
+ Hash + Hash
+ Ord + Ord
+ Into<Self::GenericArg> + Into<Self::GenericArg>
+ IntoKind<Kind = RegionKind<Self>>; + IntoKind<Kind = RegionKind<Self>>
+ Flags;
type EarlyParamRegion: Copy + Debug + Hash + Ord; type EarlyParamRegion: Copy + Debug + Hash + Ord;
type LateParamRegion: Copy + Debug + Hash + Ord; type LateParamRegion: Copy + Debug + Hash + Ord;
type BoundRegion: 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; type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
// Predicates // Predicates
type Predicate: Copy + Debug + Hash + Eq; type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
type TraitPredicate: Copy + Debug + Hash + Eq; type TraitPredicate: Copy + Debug + Hash + Eq;
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq; type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
type TypeOutlivesPredicate: 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_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region; 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; 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 /// Common capabilities of placeholder kinds

View file

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

View file

@ -45,8 +45,7 @@ use rustc_index::{Idx, IndexVec};
use std::fmt; use std::fmt;
use std::ops::ControlFlow; use std::ops::ControlFlow;
use crate::Interner; use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
use crate::Lrc;
/// This trait is implemented for every type that can be visited, /// This trait is implemented for every type that can be visited,
/// providing the skeleton of the traversal. /// providing the skeleton of the traversal.
@ -88,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized {
#[cfg(not(feature = "nightly"))] #[cfg(not(feature = "nightly"))]
type BreakTy; type BreakTy;
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy> fn visit_binder<T: TypeVisitable<I>>(
where &mut self,
I::Binder<T>: TypeSuperVisitable<I>, t: &I::Binder<T>,
{ ) -> ControlFlow<Self::BreakTy> {
t.super_visit_with(self) t.super_visit_with(self)
} }
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
where
I::Ty: TypeSuperVisitable<I>,
{
t.super_visit_with(self) t.super_visit_with(self)
} }
// The default region visitor is a no-op because `Region` is non-recursive // 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 // and has no `super_visit_with` method to call.
// lack of `I::Region: TypeSuperVisitable<I>` bound.
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> { fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
ControlFlow::Continue(()) ControlFlow::Continue(())
} }
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
where
I::Const: TypeSuperVisitable<I>,
{
c.super_visit_with(self) c.super_visit_with(self)
} }
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
where
I::Predicate: TypeSuperVisitable<I>,
{
p.super_visit_with(self) 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)) 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. /// The implementation of waking a task on an executor.
/// ///
/// This trait can be used to create a [`Waker`]. An executor can define an /// 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. /// to the tasks that are executed on that executor.
/// ///
/// This trait is a memory-safe and ergonomic alternative to constructing a /// 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`] /// those for embedded systems) cannot use this API, which is why [`RawWaker`]
/// exists as an alternative for those systems. /// 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 /// # Examples
/// ///
@ -100,7 +107,7 @@ pub trait Wake {
#[cfg(target_has_atomic = "ptr")] #[cfg(target_has_atomic = "ptr")]
#[stable(feature = "wake_trait", since = "1.51.0")] #[stable(feature = "wake_trait", since = "1.51.0")]
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker { 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. /// No heap allocations or atomic operations are used for this conversion.
fn from(waker: Arc<W>) -> Waker { fn from(waker: Arc<W>) -> Waker {

View file

@ -95,8 +95,10 @@ impl fmt::Display for AllocError {
/// # Safety /// # Safety
/// ///
/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to /// * 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 /// valid memory and retain their validity while they are [*currently allocated*] and the shorter
/// least one of the instance and all of its clones has not been dropped. /// 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 /// * 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 /// 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 /// The returned block may have a larger size than specified by `layout.size()`, and may or may
/// not have its contents initialized. /// 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 /// # Errors
/// ///
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet /// 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")] #[unstable(feature = "ascii_char", issue = "110998")]
#[repr(u8)] #[repr(u8)]
pub enum AsciiChar { pub enum AsciiChar {
/// U+0000 /// U+0000 (The default variant)
#[unstable(feature = "ascii_char_variants", issue = "110998")] #[unstable(feature = "ascii_char_variants", issue = "110998")]
Null = 0, Null = 0,
/// U+0001 /// U+0001

View file

@ -2,6 +2,8 @@
#![stable(feature = "rust1", since = "1.0.0")] #![stable(feature = "rust1", since = "1.0.0")]
use crate::ascii::Char as AsciiChar;
/// A trait for giving a type a useful default value. /// A trait for giving a type a useful default value.
/// ///
/// Sometimes, you want to fall back to some kind of default value, and /// 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! { (), (), "Returns the default value of `()`" }
default_impl! { bool, false, "Returns the default value of `false`" } default_impl! { bool, false, "Returns the default value of `false`" }
default_impl! { char, '\x00', "Returns the default value of `\\x00`" } 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! { usize, 0, "Returns the default value of `0`" }
default_impl! { u8, 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`] /// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
/// or a [`LocalWaker`] which provides customized wakeup behavior. /// 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] /// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
/// that customizes the behavior of the `RawWaker`. /// 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)] #[derive(PartialEq, Debug)]
#[stable(feature = "futures_api", since = "1.36.0")] #[stable(feature = "futures_api", since = "1.36.0")]
pub struct RawWaker { pub struct RawWaker {
@ -355,8 +359,12 @@ impl<'a> ContextBuilder<'a> {
/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker /// 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). /// 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 /// [`Future::poll()`]: core::future::Future::poll
/// [`Poll::Pending`]: core::task::Poll::Pending /// [`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 #[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
#[stable(feature = "futures_api", since = "1.36.0")] #[stable(feature = "futures_api", since = "1.36.0")]
pub struct Waker { pub struct Waker {
@ -438,9 +446,15 @@ impl Waker {
/// Creates a new `Waker` from [`RawWaker`]. /// Creates a new `Waker` from [`RawWaker`].
/// ///
/// # Safety
///
/// The behavior of the returned `Waker` is undefined if the contract defined /// The behavior of the returned `Waker` is undefined if the contract defined
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. /// 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] #[inline]
#[must_use] #[must_use]
#[stable(feature = "futures_api", since = "1.36.0")] #[stable(feature = "futures_api", since = "1.36.0")]

View file

@ -7,7 +7,9 @@ fn main() {
let target_vendor = let target_vendor =
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set"); 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"); 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" if target_os == "linux"
|| target_os == "android" || target_os == "android"
|| target_os == "netbsd" || target_os == "netbsd"

View file

@ -13,7 +13,7 @@ use crate::sync::Once;
/// ///
/// # Examples /// # 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): /// lazy static or memoizing):
/// ///
/// ``` /// ```

View file

@ -62,7 +62,7 @@ mod imp {
unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) } 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 { fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) } unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
} }
@ -72,7 +72,8 @@ mod imp {
target_os = "android", target_os = "android",
target_os = "espidf", target_os = "espidf",
target_os = "horizon", target_os = "horizon",
target_os = "freebsd" target_os = "freebsd",
netbsd10
)))] )))]
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool { fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
false false
@ -83,7 +84,8 @@ mod imp {
target_os = "android", target_os = "android",
target_os = "espidf", target_os = "espidf",
target_os = "horizon", target_os = "horizon",
target_os = "freebsd" target_os = "freebsd",
netbsd10
))] ))]
fn getrandom_fill_bytes(v: &mut [u8]) -> bool { fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
use crate::sync::atomic::{AtomicBool, Ordering}; 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. // 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 { mod imp {
use crate::ptr; 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_global_oom_handling", None),
(Some(Mode::Std), "no_rc", None), (Some(Mode::Std), "no_rc", None),
(Some(Mode::Std), "no_sync", None), (Some(Mode::Std), "no_sync", None),
(Some(Mode::Std), "netbsd10", None),
(Some(Mode::Std), "backtrace_in_libstd", None), (Some(Mode::Std), "backtrace_in_libstd", None),
/* Extra values not defined in the built-in targets yet, but used in std */ /* Extra values not defined in the built-in targets yet, but used in std */
(Some(Mode::Std), "target_env", Some(&["libnx"])), (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 error: unknown directive
--> $DIR/inline-syntax.rs:38:15 --> $DIR/inline-syntax.rs:35:15
| |
LL | asm!(".intel_syntax noprefix", "nop"); LL | asm!(".intel_syntax noprefix", "nop");
| ^ | ^
@ -25,7 +25,7 @@ LL | .intel_syntax noprefix
| ^ | ^
error: unknown directive error: unknown directive
--> $DIR/inline-syntax.rs:42:15 --> $DIR/inline-syntax.rs:39:15
| |
LL | asm!(".intel_syntax aaa noprefix", "nop"); LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^ | ^
@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix
| ^ | ^
error: unknown directive error: unknown directive
--> $DIR/inline-syntax.rs:46:15 --> $DIR/inline-syntax.rs:43:15
| |
LL | asm!(".att_syntax noprefix", "nop"); LL | asm!(".att_syntax noprefix", "nop");
| ^ | ^
@ -49,7 +49,7 @@ LL | .att_syntax noprefix
| ^ | ^
error: unknown directive error: unknown directive
--> $DIR/inline-syntax.rs:50:15 --> $DIR/inline-syntax.rs:47:15
| |
LL | asm!(".att_syntax bbb noprefix", "nop"); LL | asm!(".att_syntax bbb noprefix", "nop");
| ^ | ^
@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix
| ^ | ^
error: unknown directive error: unknown directive
--> $DIR/inline-syntax.rs:54:15 --> $DIR/inline-syntax.rs:51:15
| |
LL | asm!(".intel_syntax noprefix; nop"); LL | asm!(".intel_syntax noprefix; nop");
| ^ | ^
@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop
| ^ | ^
error: unknown directive error: unknown directive
--> $DIR/inline-syntax.rs:61:13 --> $DIR/inline-syntax.rs:58:13
| |
LL | .intel_syntax noprefix LL | .intel_syntax noprefix
| ^ | ^

View file

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

View file

@ -2,14 +2,11 @@
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu //[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64] check-pass //[x86_64] check-pass
//[x86_64] needs-llvm-components: x86 //[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] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm] build-fail //[arm] build-fail
//[arm] needs-llvm-components: arm //[arm] needs-llvm-components: arm
//[arm] ignore-llvm-version: 18 - 99 //[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] compile-flags: --target armv7-unknown-linux-gnueabihf
//[arm_llvm_18] build-fail //[arm_llvm_18] build-fail
//[arm_llvm_18] needs-llvm-components: arm //[arm_llvm_18] needs-llvm-components: arm

View file

@ -1,5 +1,5 @@
warning: avoid using `.intel_syntax`, Intel syntax is the default 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"); 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 = note: `#[warn(bad_asm_style)]` on by default
warning: avoid using `.intel_syntax`, Intel syntax is the 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"); LL | asm!(".intel_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default 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"); LL | asm!(".intel_syntax aaa noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead 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"); LL | asm!(".att_syntax noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead 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"); LL | asm!(".att_syntax bbb noprefix", "nop");
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default 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"); LL | asm!(".intel_syntax noprefix; nop");
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
warning: avoid using `.intel_syntax`, Intel syntax is the default 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 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 DataStruct();
pub struct HelperStruct<'n> { 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: 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: 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: 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! = 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: 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 = 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; 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)] 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>) { 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! = 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> = 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>) { 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! = 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> = 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!(); LL | let _x: &dyn SomeTrait = todo!();
| +++ | +++

View file

@ -11,7 +11,7 @@ note: the lint level is defined here
| |
LL | #![deny(bare_trait_objects)] 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) 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! = 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: 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 = 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(&())> { 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! = 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: 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 = 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); 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! = 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: 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; 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! = 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: 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 = 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(()); 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! = 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: 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 = 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> 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! = 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: 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 = 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; 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! = 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: 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(); 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! = 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: 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(); 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! = 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: 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; 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! = 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: 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` = 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>) {} 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! = 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: 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` = 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>) {} 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: 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` = 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: 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>) {} 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: 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` = 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: 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>) {} 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: 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` = 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: 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>) {} 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 --> $DIR/future-incompat-json-test.rs:9:9
| |
LL | let x = 1; LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x` | ^ 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; LL | let x = 1;
| ^ help: if this is intentional, prefix it with an underscore: `_x` | ^ 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: 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: 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: 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) = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic: 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! = 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: 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) = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic: 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! = 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: 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) = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic: 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! = 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: 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) = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
Future breakage diagnostic: 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! = 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: 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 = 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 { 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! = 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: 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` = 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 { 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! = 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: 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 = 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; } 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! = 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: 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; } 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! = 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: 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; } 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! = 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: 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; } 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! = 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: 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` = 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; } 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! = 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: 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` = 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; } 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! = 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: 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 = 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 {} 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)] 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 { 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! = 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: 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 = 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>)>; 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! = 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: 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)>; 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! = 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: 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)>; 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: 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: 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: 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! = 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: 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) = 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: 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! = 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: 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) = 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)] LL | #![deny(bare_trait_objects)]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
help: use `dyn` help: if this is an object-safe trait, use `dyn`
| |
LL | bar: Box<dyn Bar>, 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! = 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: 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 { 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! = 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: 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 = 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> {} 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! = 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: 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 = 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) { 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 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 error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/issue-28576.rs:5:16 --> $DIR/issue-28576.rs:5:16
@ -56,8 +56,8 @@ LL | ) where Self: Sized;
| +++++++++++++++++ | +++++++++++++++++
help: consider relaxing the implicit `Sized` restriction 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 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! = 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: 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! = 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: 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 = 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(); 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! = 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: 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(); 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! = 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: 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(); 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! = 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: 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(); 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! = 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: 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(); LL | let e = <dyn Bar::<usize>>::lol();
| ++++ + | ++++ +