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:
commit
340bb19fea
93 changed files with 966 additions and 589 deletions
|
@ -323,9 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
)
|
||||
}
|
||||
ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
|
||||
ExprKind::Err => {
|
||||
hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
|
||||
}
|
||||
ExprKind::Err => hir::ExprKind::Err(self.dcx().has_errors().unwrap()),
|
||||
ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
|
||||
|
||||
ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
|
||||
|
|
|
@ -1068,7 +1068,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||
fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> {
|
||||
match block {
|
||||
Some(block) => self.lower_block_expr(block),
|
||||
None => self.expr_err(span, self.dcx().span_delayed_bug(span, "no block")),
|
||||
None => self.expr_err(span, self.dcx().has_errors().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1285,9 +1285,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
|
||||
let kind = match &t.kind {
|
||||
TyKind::Infer => hir::TyKind::Infer,
|
||||
TyKind::Err => {
|
||||
hir::TyKind::Err(self.dcx().span_delayed_bug(t.span, "TyKind::Err lowered"))
|
||||
}
|
||||
TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
|
||||
// Lower the anonymous structs or unions in a nested lowering context.
|
||||
//
|
||||
// ```
|
||||
|
|
|
@ -117,18 +117,14 @@ struct CfgChecker<'a, 'tcx> {
|
|||
impl<'a, 'tcx> CfgChecker<'a, 'tcx> {
|
||||
#[track_caller]
|
||||
fn fail(&self, location: Location, msg: impl AsRef<str>) {
|
||||
let span = self.body.source_info(location).span;
|
||||
// We use `span_delayed_bug` as we might see broken MIR when other errors have already
|
||||
// occurred.
|
||||
self.tcx.dcx().span_delayed_bug(
|
||||
span,
|
||||
format!(
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
self.body.source.instance,
|
||||
self.when,
|
||||
location,
|
||||
msg.as_ref()
|
||||
),
|
||||
// We might see broken MIR when other errors have already occurred.
|
||||
assert!(
|
||||
self.tcx.dcx().has_errors().is_some(),
|
||||
"broken MIR in {:?} ({}) at {:?}:\n{}",
|
||||
self.body.source.instance,
|
||||
self.when,
|
||||
location,
|
||||
msg.as_ref(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -1315,6 +1315,9 @@ impl DiagCtxtInner {
|
|||
self.future_breakage_diagnostics.push(diagnostic.clone());
|
||||
}
|
||||
|
||||
// Note that because this comes before the `match` below,
|
||||
// `-Zeagerly-emit-delayed-bugs` continues to work even after we've
|
||||
// issued an error and stopped recording new delayed bugs.
|
||||
if diagnostic.level == DelayedBug && self.flags.eagerly_emit_delayed_bugs {
|
||||
diagnostic.level = Error;
|
||||
}
|
||||
|
@ -1326,18 +1329,20 @@ impl DiagCtxtInner {
|
|||
diagnostic.level = Bug;
|
||||
}
|
||||
DelayedBug => {
|
||||
// FIXME(eddyb) this should check for `has_errors` and stop pushing
|
||||
// once *any* errors were emitted (and truncate `delayed_bugs`
|
||||
// when an error is first emitted, also), but maybe there's a case
|
||||
// in which that's not sound? otherwise this is really inefficient.
|
||||
let backtrace = std::backtrace::Backtrace::capture();
|
||||
// This `unchecked_error_guaranteed` is valid. It is where the
|
||||
// `ErrorGuaranteed` for delayed bugs originates.
|
||||
#[allow(deprecated)]
|
||||
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
|
||||
self.delayed_bugs
|
||||
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
|
||||
return Some(guar);
|
||||
// If we have already emitted at least one error, we don't need
|
||||
// to record the delayed bug, because it'll never be used.
|
||||
return if let Some(guar) = self.has_errors_or_lint_errors() {
|
||||
Some(guar)
|
||||
} else {
|
||||
let backtrace = std::backtrace::Backtrace::capture();
|
||||
// This `unchecked_error_guaranteed` is valid. It is where the
|
||||
// `ErrorGuaranteed` for delayed bugs originates.
|
||||
#[allow(deprecated)]
|
||||
let guar = ErrorGuaranteed::unchecked_error_guaranteed();
|
||||
self.delayed_bugs
|
||||
.push((DelayedDiagnostic::with_backtrace(diagnostic, backtrace), guar));
|
||||
Some(guar)
|
||||
};
|
||||
}
|
||||
Warning if !self.flags.can_emit_warnings => {
|
||||
if diagnostic.has_future_breakage() {
|
||||
|
@ -1403,6 +1408,16 @@ impl DiagCtxtInner {
|
|||
}
|
||||
|
||||
if is_error {
|
||||
// If we have any delayed bugs recorded, we can discard them
|
||||
// because they won't be used. (This should only occur if there
|
||||
// have been no errors previously emitted, because we don't add
|
||||
// new delayed bugs once the first error is emitted.)
|
||||
if !self.delayed_bugs.is_empty() {
|
||||
assert_eq!(self.lint_err_guars.len() + self.err_guars.len(), 0);
|
||||
self.delayed_bugs.clear();
|
||||
self.delayed_bugs.shrink_to_fit();
|
||||
}
|
||||
|
||||
// This `unchecked_error_guaranteed` is valid. It is where the
|
||||
// `ErrorGuaranteed` for errors and lint errors originates.
|
||||
#[allow(deprecated)]
|
||||
|
|
|
@ -34,10 +34,10 @@ pub(super) fn failed_to_match_macro<'cx>(
|
|||
if try_success_result.is_ok() {
|
||||
// Nonterminal parser recovery might turn failed matches into successful ones,
|
||||
// but for that it must have emitted an error already
|
||||
tracker
|
||||
.cx
|
||||
.dcx()
|
||||
.span_delayed_bug(sp, "Macro matching returned a success on the second try");
|
||||
assert!(
|
||||
tracker.cx.dcx().has_errors().is_some(),
|
||||
"Macro matching returned a success on the second try"
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(result) = tracker.result {
|
||||
|
|
|
@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
|
||||
if self_ty.span.can_be_used_for_suggestions() {
|
||||
lint.multipart_suggestion_verbose(
|
||||
"use `dyn`",
|
||||
"if this is an object-safe trait, use `dyn`",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
|
|
@ -758,8 +758,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
// since we should have emitten an error for them earlier, and they will
|
||||
// not be well-formed!
|
||||
if polarity == ty::ImplPolarity::Negative {
|
||||
self.tcx().dcx().span_delayed_bug(
|
||||
binding.span,
|
||||
assert!(
|
||||
self.tcx().dcx().has_errors().is_some(),
|
||||
"negative trait bounds should not have bindings",
|
||||
);
|
||||
continue;
|
||||
|
|
|
@ -1865,13 +1865,13 @@ fn check_variances_for_type_defn<'tcx>(
|
|||
let hir_param = &hir_generics.params[index];
|
||||
|
||||
if ty_param.def_id != hir_param.def_id.into() {
|
||||
// valid programs always have lifetimes before types in the generic parameter list
|
||||
// Valid programs always have lifetimes before types in the generic parameter list.
|
||||
// ty_generics are normalized to be in this required order, and variances are built
|
||||
// from ty generics, not from hir generics. but we need hir generics to get
|
||||
// a span out
|
||||
// a span out.
|
||||
//
|
||||
// if they aren't in the same order, then the user has written invalid code, and already
|
||||
// got an error about it (or I'm wrong about this)
|
||||
// If they aren't in the same order, then the user has written invalid code, and already
|
||||
// got an error about it (or I'm wrong about this).
|
||||
tcx.dcx().span_delayed_bug(
|
||||
hir_param.span,
|
||||
"hir generics and ty generics in different order",
|
||||
|
|
|
@ -85,7 +85,7 @@ pub(super) fn check_item(
|
|||
|
||||
(_, _, Unsafety::Unsafe, Negative) => {
|
||||
// Reported in AST validation
|
||||
tcx.dcx().span_delayed_bug(tcx.def_span(def_id), "unsafe negative impl");
|
||||
assert!(tcx.dcx().has_errors().is_some(), "unsafe negative impl");
|
||||
Ok(())
|
||||
}
|
||||
(_, _, Unsafety::Normal, Negative)
|
||||
|
|
|
@ -139,10 +139,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
| ty::Never
|
||||
| ty::Dynamic(_, _, ty::DynStar)
|
||||
| ty::Error(_) => {
|
||||
let reported = self
|
||||
let guar = self
|
||||
.dcx()
|
||||
.span_delayed_bug(span, format!("`{t:?}` should be sized but is not?"));
|
||||
return Err(reported);
|
||||
return Err(guar);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -221,8 +221,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
if base_ty.is_none() {
|
||||
// When encountering `return [0][0]` outside of a `fn` body we can encounter a base
|
||||
// that isn't in the type table. We assume more relevant errors have already been
|
||||
// emitted, so we delay an ICE if none have. (#64638)
|
||||
self.tcx().dcx().span_delayed_bug(e.span, format!("bad base: `{base:?}`"));
|
||||
// emitted. (#64638)
|
||||
assert!(self.tcx().dcx().has_errors().is_some(), "bad base: `{base:?}`");
|
||||
}
|
||||
if let Some(base_ty) = base_ty
|
||||
&& let ty::Ref(_, base_ty_inner, _) = *base_ty.kind()
|
||||
|
|
|
@ -802,14 +802,12 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
// Errors in earlier passes can yield error variables without
|
||||
// resolution errors here; delay ICE in favor of those errors.
|
||||
self.tcx().dcx().span_delayed_bug(
|
||||
self.var_infos[node_idx].origin.span(),
|
||||
format!(
|
||||
"collect_error_for_expanding_node() could not find \
|
||||
error for var {node_idx:?} in universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
|
||||
upper_bounds={upper_bounds:#?}"
|
||||
),
|
||||
// resolution errors here; ICE if no errors have been emitted yet.
|
||||
assert!(
|
||||
self.tcx().dcx().has_errors().is_some(),
|
||||
"collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
|
||||
universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
|
||||
upper_bounds={upper_bounds:#?}",
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -300,9 +300,9 @@ where
|
|||
self.components_must_outlive(origin, subcomponents, region, category);
|
||||
}
|
||||
Component::UnresolvedInferenceVariable(v) => {
|
||||
// ignore this, we presume it will yield an error
|
||||
// later, since if a type variable is not resolved by
|
||||
// this point it never will be
|
||||
// Ignore this, we presume it will yield an error later,
|
||||
// since if a type variable is not resolved by this point
|
||||
// it never will be.
|
||||
self.tcx.dcx().span_delayed_bug(
|
||||
origin.span(),
|
||||
format!("unresolved inference variable in outlives: {v:?}"),
|
||||
|
|
|
@ -172,13 +172,13 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
|||
self.bound_from_components(components, visited)
|
||||
}
|
||||
Component::UnresolvedInferenceVariable(v) => {
|
||||
// ignore this, we presume it will yield an error
|
||||
// later, since if a type variable is not resolved by
|
||||
// this point it never will be
|
||||
// Ignore this, we presume it will yield an error later, since
|
||||
// if a type variable is not resolved by this point it never
|
||||
// will be.
|
||||
self.tcx
|
||||
.dcx()
|
||||
.delayed_bug(format!("unresolved inference variable in outlives: {v:?}"));
|
||||
// add a bound that never holds
|
||||
// Add a bound that never holds.
|
||||
VerifyBound::AnyBound(vec![])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -431,14 +431,13 @@ pub fn check_ast_node_inner<'a, T: EarlyLintPass>(
|
|||
// If not, that means that we somehow buffered a lint for a node id
|
||||
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.
|
||||
for (id, lints) in cx.context.buffered.map {
|
||||
for early_lint in lints {
|
||||
sess.dcx().span_delayed_bug(
|
||||
early_lint.span,
|
||||
format!(
|
||||
"failed to process buffered lint here (dummy = {})",
|
||||
id == ast::DUMMY_NODE_ID
|
||||
),
|
||||
if !lints.is_empty() {
|
||||
assert!(
|
||||
sess.dcx().has_errors().is_some(),
|
||||
"failed to process buffered lint here (dummy = {})",
|
||||
id == ast::DUMMY_NODE_ID
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,6 +207,11 @@ pub fn explain_lint_level_source(
|
|||
err: &mut Diagnostic,
|
||||
) {
|
||||
let name = lint.name_lower();
|
||||
if let Level::Allow = level {
|
||||
// Do not point at `#[allow(compat_lint)]` as the reason for a compatibility lint
|
||||
// triggering. (#121009)
|
||||
return;
|
||||
}
|
||||
match src {
|
||||
LintLevelSource::Default => {
|
||||
err.note_once(format!("`#[{}({})]` on by default", level.as_str(), name));
|
||||
|
|
|
@ -35,6 +35,16 @@ impl<'tcx> IntoKind for Const<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::visit::Flags for Const<'tcx> {
|
||||
fn flags(&self) -> TypeFlags {
|
||||
self.0.flags
|
||||
}
|
||||
|
||||
fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ConstTy<TyCtxt<'tcx>> for Const<'tcx> {
|
||||
fn ty(self) -> Ty<'tcx> {
|
||||
self.ty()
|
||||
|
@ -63,11 +73,13 @@ impl<'tcx> Const<'tcx> {
|
|||
self.0.kind
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline]
|
||||
pub fn flags(self) -> TypeFlags {
|
||||
self.0.flags
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline]
|
||||
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
|
|
|
@ -28,7 +28,7 @@ use crate::ty::{
|
|||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
|
||||
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
|
||||
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
||||
Visibility,
|
||||
TypeVisitable, Visibility,
|
||||
};
|
||||
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
|
||||
use rustc_ast::{self as ast, attr};
|
||||
|
@ -87,7 +87,9 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type GenericArg = ty::GenericArg<'tcx>;
|
||||
type Term = ty::Term<'tcx>;
|
||||
|
||||
type Binder<T> = Binder<'tcx, T>;
|
||||
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
|
||||
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
||||
type BoundVar = ty::BoundVariableKind;
|
||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||
|
||||
type Ty = Ty<'tcx>;
|
||||
|
@ -151,6 +153,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
) -> Self::Const {
|
||||
Const::new_bound(self, debruijn, var, ty)
|
||||
}
|
||||
|
||||
fn expect_error_or_delayed_bug() {
|
||||
let has_errors = ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs());
|
||||
assert!(has_errors.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;
|
||||
|
|
|
@ -504,6 +504,16 @@ impl<'tcx> IntoKind for Ty<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::visit::Flags for Ty<'tcx> {
|
||||
fn flags(&self) -> TypeFlags {
|
||||
self.0.flags
|
||||
}
|
||||
|
||||
fn outer_exclusive_binder(&self) -> DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
}
|
||||
}
|
||||
|
||||
impl EarlyParamRegion {
|
||||
/// Does this early bound region have a name? Early bound regions normally
|
||||
/// always have names except when using anonymous lifetimes (`'_`).
|
||||
|
|
|
@ -29,6 +29,16 @@ pub struct Predicate<'tcx>(
|
|||
pub(super) Interned<'tcx, WithCachedTypeInfo<ty::Binder<'tcx, PredicateKind<'tcx>>>>,
|
||||
);
|
||||
|
||||
impl<'tcx> rustc_type_ir::visit::Flags for Predicate<'tcx> {
|
||||
fn flags(&self) -> TypeFlags {
|
||||
self.0.flags
|
||||
}
|
||||
|
||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Predicate<'tcx> {
|
||||
/// Gets the inner `ty::Binder<'tcx, PredicateKind<'tcx>>`.
|
||||
#[inline]
|
||||
|
@ -36,11 +46,13 @@ impl<'tcx> Predicate<'tcx> {
|
|||
self.0.internee
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline(always)]
|
||||
pub fn flags(self) -> TypeFlags {
|
||||
self.0.flags
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline(always)]
|
||||
pub fn outer_exclusive_binder(self) -> DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
|
|
|
@ -26,6 +26,19 @@ impl<'tcx> rustc_type_ir::IntoKind for Region<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::visit::Flags for Region<'tcx> {
|
||||
fn flags(&self) -> TypeFlags {
|
||||
self.type_flags()
|
||||
}
|
||||
|
||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex {
|
||||
match **self {
|
||||
ty::ReBound(debruijn, _) => debruijn.shifted_in(1),
|
||||
_ => ty::INNERMOST,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Region<'tcx> {
|
||||
#[inline]
|
||||
pub fn new_early_param(
|
||||
|
|
|
@ -942,6 +942,16 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> rustc_type_ir::BoundVars<TyCtxt<'tcx>> for ty::Binder<'tcx, T> {
|
||||
fn bound_vars(&self) -> &'tcx List<ty::BoundVariableKind> {
|
||||
self.bound_vars
|
||||
}
|
||||
|
||||
fn has_no_bound_vars(&self) -> bool {
|
||||
self.bound_vars.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> Binder<'tcx, T> {
|
||||
/// Skips the binder and returns the "bound" value. This is a
|
||||
/// risky thing to do because it's easy to get confused about
|
||||
|
@ -1808,6 +1818,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
self.0.0
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline(always)]
|
||||
pub fn flags(self) -> TypeFlags {
|
||||
self.0.0.flags
|
||||
|
|
|
@ -1320,6 +1320,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
ty
|
||||
}
|
||||
|
||||
// FIXME(compiler-errors): Think about removing this.
|
||||
#[inline]
|
||||
pub fn outer_exclusive_binder(self) -> ty::DebruijnIndex {
|
||||
self.0.outer_exclusive_binder
|
||||
|
|
|
@ -1,140 +1,10 @@
|
|||
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::sso::SsoHashSet;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
|
||||
pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> {
|
||||
/// Returns `true` if `self` has any late-bound regions that are either
|
||||
/// bound by `binder` or bound by some binder outside of `binder`.
|
||||
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
||||
/// there are any late-bound regions that appear free.
|
||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
|
||||
}
|
||||
|
||||
/// Returns `true` if this type has any regions that escape `binder` (and
|
||||
/// hence are not bound by it).
|
||||
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.has_vars_bound_at_or_above(binder.shifted_in(1))
|
||||
}
|
||||
|
||||
/// Return `true` if this type has regions that are not a part of the type.
|
||||
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
|
||||
/// would return `true`. The latter can occur when traversing through the
|
||||
/// former.
|
||||
///
|
||||
/// See [`HasEscapingVarsVisitor`] for more information.
|
||||
fn has_escaping_bound_vars(&self) -> bool {
|
||||
self.has_vars_bound_at_or_above(ty::INNERMOST)
|
||||
}
|
||||
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
let res =
|
||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }).break_value() == Some(FoundFlags);
|
||||
trace!(?self, ?flags, ?res, "has_type_flags");
|
||||
res
|
||||
}
|
||||
fn has_projections(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PROJECTION)
|
||||
}
|
||||
fn has_inherent_projections(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
|
||||
}
|
||||
fn has_opaque_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
||||
}
|
||||
fn has_coroutines(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
|
||||
}
|
||||
fn references_error(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_ERROR)
|
||||
}
|
||||
fn error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
||||
if self.references_error() {
|
||||
// We must include lint errors and delayed bugs here.
|
||||
if let Some(reported) =
|
||||
ty::tls::with(|tcx| tcx.dcx().has_errors_or_lint_errors_or_delayed_bugs())
|
||||
{
|
||||
Err(reported)
|
||||
} else {
|
||||
bug!("expected some kind of error in `error_reported`");
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
fn has_non_region_param(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
|
||||
}
|
||||
fn has_infer_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
fn has_infer_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INFER)
|
||||
}
|
||||
fn has_non_region_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
fn has_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_INFER)
|
||||
}
|
||||
fn has_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
|
||||
}
|
||||
fn has_non_region_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
|
||||
}
|
||||
fn has_param(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PARAM)
|
||||
}
|
||||
/// "Free" regions in this context means that it has any region
|
||||
/// that is not (a) erased or (b) late-bound.
|
||||
fn has_free_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||
}
|
||||
|
||||
fn has_erased_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
|
||||
}
|
||||
|
||||
/// True if there are any un-erased free regions.
|
||||
fn has_erasable_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||
}
|
||||
|
||||
/// Indicates whether this value references only 'global'
|
||||
/// generic parameters that are the same regardless of what fn we are
|
||||
/// in. This is used for caching.
|
||||
fn is_global(&self) -> bool {
|
||||
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
|
||||
}
|
||||
|
||||
/// True if there are any late-bound regions
|
||||
fn has_bound_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
|
||||
}
|
||||
/// True if there are any late-bound non-region variables
|
||||
fn has_non_region_bound_vars(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
|
||||
}
|
||||
/// True if there are any bound variables
|
||||
fn has_bound_vars(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
|
||||
}
|
||||
|
||||
/// Indicates whether this value still has parameters/placeholders/inference variables
|
||||
/// which could be replaced later, in a way that would change the results of `impl`
|
||||
/// specialization.
|
||||
fn still_further_specializable(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {}
|
||||
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Region folder
|
||||
|
@ -370,185 +240,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct FoundEscapingVars;
|
||||
|
||||
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
|
||||
/// bound region or a bound type.
|
||||
///
|
||||
/// So, for example, consider a type like the following, which has two binders:
|
||||
///
|
||||
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
|
||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
|
||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
|
||||
///
|
||||
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
|
||||
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
|
||||
/// fn type*, that type has an escaping region: `'a`.
|
||||
///
|
||||
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
|
||||
/// we already use the term "free var". It refers to the regions or types that we use to represent
|
||||
/// bound regions or type params on a fn definition while we are type checking its body.
|
||||
///
|
||||
/// To clarify, conceptually there is no particular difference between
|
||||
/// an "escaping" var and a "free" var. However, there is a big
|
||||
/// difference in practice. Basically, when "entering" a binding
|
||||
/// level, one is generally required to do some sort of processing to
|
||||
/// a bound var, such as replacing it with a fresh/placeholder
|
||||
/// var, or making an entry in the environment to represent the
|
||||
/// scope to which it is attached, etc. An escaping var represents
|
||||
/// a bound var for which this processing has not yet been done.
|
||||
struct HasEscapingVarsVisitor {
|
||||
/// Anything bound by `outer_index` or "above" is escaping.
|
||||
outer_index: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor {
|
||||
type BreakTy = FoundEscapingVars;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// If the outer-exclusive-binder is *strictly greater* than
|
||||
// `outer_index`, that means that `t` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
if t.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// If the region is bound by `outer_index` or anything outside
|
||||
// of outer index, then it escapes the binders we have
|
||||
// visited.
|
||||
if r.bound_at_or_above_binder(self.outer_index) {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// If the outer-exclusive-binder is *strictly greater* than
|
||||
// `outer_index`, that means that `ct` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
if ct.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if predicate.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct FoundFlags;
|
||||
|
||||
// FIXME: Optimize for checking for infer flags
|
||||
struct HasTypeFlagsVisitor {
|
||||
flags: ty::TypeFlags,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for HasTypeFlagsVisitor {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.flags.fmt(fmt)
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this visitor traverses values down to the level of
|
||||
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
|
||||
// type flags at the outer layer are enough. So it's faster than it first
|
||||
// looks, particular for `Ty`/`Predicate` where it's just a field access.
|
||||
//
|
||||
// N.B. The only case where this isn't totally true is binders, which also
|
||||
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
|
||||
// are present, regardless of whether those bound variables are used. This
|
||||
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
||||
// specifically detect this case in `visit_binder`.
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor {
|
||||
type BreakTy = FoundFlags;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(
|
||||
&mut self,
|
||||
t: &Binder<'tcx, T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
||||
// binder has vars. This won't be present in the binder's bound
|
||||
// value, so we need to check here too.
|
||||
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.bound_vars().is_empty() {
|
||||
return ControlFlow::Break(FoundFlags);
|
||||
}
|
||||
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
let flags = t.flags();
|
||||
if flags.intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call, as usual for `Region`.
|
||||
let flags = r.type_flags();
|
||||
if flags.intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
if c.flags().intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
if predicate.flags().intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Collects all the late-bound regions at the innermost binding level
|
||||
/// into a hash set.
|
||||
struct LateBoundRegionsCollector {
|
||||
|
|
|
@ -33,7 +33,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
|||
body_target_features: &'tcx [Symbol],
|
||||
/// When inside the LHS of an assignment to a field, this is the type
|
||||
/// of the LHS and the span of the assignment expression.
|
||||
assignment_info: Option<(Ty<'tcx>, Span)>,
|
||||
assignment_info: Option<Ty<'tcx>>,
|
||||
in_union_destructure: bool,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
inside_adt: bool,
|
||||
|
@ -473,10 +473,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
if let ty::Adt(adt_def, _) = lhs.ty.kind()
|
||||
&& adt_def.is_union()
|
||||
{
|
||||
if let Some((assigned_ty, assignment_span)) = self.assignment_info {
|
||||
if let Some(assigned_ty) = self.assignment_info {
|
||||
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
||||
// This would be unsafe, but should be outright impossible since we reject such unions.
|
||||
self.tcx.dcx().span_delayed_bug(assignment_span, format!("union fields that need dropping should be impossible: {assigned_ty}"));
|
||||
// This would be unsafe, but should be outright impossible since we
|
||||
// reject such unions.
|
||||
assert!(
|
||||
self.tcx.dcx().has_errors().is_some(),
|
||||
"union fields that need dropping should be impossible: \
|
||||
{assigned_ty}"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.requires_unsafe(expr.span, AccessToUnionField);
|
||||
|
@ -492,14 +497,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
self.requires_unsafe(expr.span, MutationOfLayoutConstrainedField);
|
||||
}
|
||||
|
||||
// Second, check for accesses to union fields
|
||||
// don't have any special handling for AssignOp since it causes a read *and* write to lhs
|
||||
// Second, check for accesses to union fields. Don't have any
|
||||
// special handling for AssignOp since it causes a read *and*
|
||||
// write to lhs.
|
||||
if matches!(expr.kind, ExprKind::Assign { .. }) {
|
||||
self.assignment_info = Some((lhs.ty, expr.span));
|
||||
self.assignment_info = Some(lhs.ty);
|
||||
visit::walk_expr(self, lhs);
|
||||
self.assignment_info = None;
|
||||
visit::walk_expr(self, &self.thir()[rhs]);
|
||||
return; // we have already visited everything by now
|
||||
return; // We have already visited everything by now.
|
||||
}
|
||||
}
|
||||
ExprKind::Borrow { borrow_kind, arg } => {
|
||||
|
|
|
@ -153,8 +153,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||
// a hard error when we don't have a valtree or when we find something in
|
||||
// the valtree that is not structural; then this can all be made a lot simpler.
|
||||
|
||||
let structural =
|
||||
traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
|
||||
let structural = traits::search_for_structural_match_violation(self.tcx(), cv.ty());
|
||||
debug!(
|
||||
"search_for_structural_match_violation cv.ty: {:?} returned: {:?}",
|
||||
cv.ty(),
|
||||
|
|
|
@ -243,10 +243,11 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
|
|||
// old value is being dropped.
|
||||
let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
|
||||
if assigned_ty.needs_drop(self.tcx, self.param_env) {
|
||||
// This would be unsafe, but should be outright impossible since we reject such unions.
|
||||
self.tcx.dcx().span_delayed_bug(
|
||||
self.source_info.span,
|
||||
format!("union fields that need dropping should be impossible: {assigned_ty}")
|
||||
// This would be unsafe, but should be outright impossible since we reject
|
||||
// such unions.
|
||||
assert!(
|
||||
self.tcx.dcx().has_errors().is_some(),
|
||||
"union fields that need dropping should be impossible: {assigned_ty}"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -561,9 +561,14 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
.ok()?;
|
||||
dest.into()
|
||||
}
|
||||
CastKind::FnPtrToPtr
|
||||
| CastKind::PtrToPtr
|
||||
| CastKind::PointerCoercion(
|
||||
CastKind::FnPtrToPtr | CastKind::PtrToPtr => {
|
||||
let src = self.evaluated[value].as_ref()?;
|
||||
let src = self.ecx.read_immediate(src).ok()?;
|
||||
let to = self.ecx.layout_of(to).ok()?;
|
||||
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
||||
ret.into()
|
||||
}
|
||||
CastKind::PointerCoercion(
|
||||
ty::adjustment::PointerCoercion::MutToConstPointer
|
||||
| ty::adjustment::PointerCoercion::ArrayToPointer
|
||||
| ty::adjustment::PointerCoercion::UnsafeFnPointer,
|
||||
|
@ -571,8 +576,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||
let src = self.evaluated[value].as_ref()?;
|
||||
let src = self.ecx.read_immediate(src).ok()?;
|
||||
let to = self.ecx.layout_of(to).ok()?;
|
||||
let ret = self.ecx.ptr_to_ptr(&src, to).ok()?;
|
||||
ret.into()
|
||||
ImmTy::from_immediate(*src, to).into()
|
||||
}
|
||||
_ => return None,
|
||||
},
|
||||
|
|
|
@ -265,7 +265,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
|
|||
let body = &tcx.mir_const(def).borrow();
|
||||
|
||||
if body.return_ty().references_error() {
|
||||
tcx.dcx().span_delayed_bug(body.span, "mir_const_qualif: MIR had errors");
|
||||
assert!(tcx.dcx().has_errors().is_some(), "mir_const_qualif: MIR had errors");
|
||||
return Default::default();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::cmp::Ordering;
|
||||
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use rustc_type_ir::{
|
||||
self as ty, Canonical, CanonicalTyVarKind, CanonicalVarInfo, CanonicalVarKind, ConstTy,
|
||||
InferCtxtLike, Interner, IntoKind, PlaceholderLike,
|
||||
|
@ -62,8 +63,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
|
|||
|
||||
let value = value.fold_with(&mut canonicalizer);
|
||||
// FIXME: Restore these assertions. Should we uplift type flags?
|
||||
// assert!(!value.has_infer(), "unexpected infer in {value:?}");
|
||||
// assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
|
||||
assert!(!value.has_infer(), "unexpected infer in {value:?}");
|
||||
assert!(!value.has_placeholders(), "unexpected placeholders in {value:?}");
|
||||
|
||||
let (max_universe, variables) = canonicalizer.finalize();
|
||||
|
||||
|
|
|
@ -429,16 +429,16 @@ where
|
|||
let formatter = query.format_value();
|
||||
if old_hash != new_hash {
|
||||
// We have an inconsistency. This can happen if one of the two
|
||||
// results is tainted by errors. In this case, delay a bug to
|
||||
// ensure compilation is doomed.
|
||||
qcx.dep_context().sess().dcx().delayed_bug(format!(
|
||||
// results is tainted by errors.
|
||||
assert!(
|
||||
qcx.dep_context().sess().dcx().has_errors().is_some(),
|
||||
"Computed query value for {:?}({:?}) is inconsistent with fed value,\n\
|
||||
computed={:#?}\nfed={:#?}",
|
||||
query.dep_kind(),
|
||||
key,
|
||||
formatter(&result),
|
||||
formatter(&cached_result),
|
||||
));
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,9 +62,10 @@ pub fn is_const_evaluatable<'tcx>(
|
|||
|
||||
match unexpanded_ct.kind() {
|
||||
ty::ConstKind::Expr(_) => {
|
||||
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete, but
|
||||
// currently it is not possible to evaluate `ConstKind::Expr` so we are unable to tell if it
|
||||
// is evaluatable or not. For now we just ICE until this is implemented.
|
||||
// FIXME(generic_const_exprs): we have a `ConstKind::Expr` which is fully concrete,
|
||||
// but currently it is not possible to evaluate `ConstKind::Expr` so we are unable
|
||||
// to tell if it is evaluatable or not. For now we just ICE until this is
|
||||
// implemented.
|
||||
Err(NotConstEvaluatable::Error(tcx.dcx().span_delayed_bug(
|
||||
span,
|
||||
"evaluating `ConstKind::Expr` is not currently supported",
|
||||
|
|
|
@ -3041,7 +3041,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
this = "the implicit `Sized` requirement on this type parameter";
|
||||
}
|
||||
if let Some(hir::Node::TraitItem(hir::TraitItem {
|
||||
ident,
|
||||
generics,
|
||||
kind: hir::TraitItemKind::Type(bounds, None),
|
||||
..
|
||||
})) = tcx.hir().get_if_local(item_def_id)
|
||||
|
@ -3053,7 +3053,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
let (span, separator) = if let [.., last] = bounds {
|
||||
(last.span().shrink_to_hi(), " +")
|
||||
} else {
|
||||
(ident.span.shrink_to_hi(), ":")
|
||||
(generics.span.shrink_to_hi(), ":")
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
|
|
|
@ -236,9 +236,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// It could be that we don't report an error because we have seen an `ErrorReported` from another source.
|
||||
// We should probably be able to fix most of these, but some are delayed bugs that get a proper error
|
||||
// after this function.
|
||||
// It could be that we don't report an error because we have seen an `ErrorReported` from
|
||||
// another source. We should probably be able to fix most of these, but some are delayed
|
||||
// bugs that get a proper error after this function.
|
||||
reported.unwrap_or_else(|| self.dcx().delayed_bug("failed to report fulfillment errors"))
|
||||
}
|
||||
|
||||
|
@ -519,7 +519,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
trait_ref,
|
||||
span,
|
||||
) {
|
||||
GetSafeTransmuteErrorAndReason::Silent => return self.dcx().span_delayed_bug(span, "silent safe transmute error"),
|
||||
GetSafeTransmuteErrorAndReason::Silent => {
|
||||
return self.dcx().span_delayed_bug(
|
||||
span, "silent safe transmute error"
|
||||
);
|
||||
}
|
||||
GetSafeTransmuteErrorAndReason::Error {
|
||||
err_msg,
|
||||
safe_transmute_explanation,
|
||||
|
@ -2990,7 +2994,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
{
|
||||
(s, " +")
|
||||
} else {
|
||||
(span.shrink_to_hi(), ":")
|
||||
(param.name.ident().span.shrink_to_hi(), ":")
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
span,
|
||||
|
|
|
@ -555,7 +555,7 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
|
||||
// NOTE: This check happens last, because it results in a lint, and not a
|
||||
// hard error.
|
||||
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, span)| {
|
||||
if tcx.predicates_of(method.def_id).predicates.iter().any(|&(pred, _span)| {
|
||||
// dyn Trait is okay:
|
||||
//
|
||||
// trait Trait {
|
||||
|
@ -594,7 +594,10 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
// would already have reported an error at the definition of the
|
||||
// auto trait.
|
||||
if pred_trait_ref.args.len() != 1 {
|
||||
tcx.dcx().span_delayed_bug(span, "auto traits cannot have generic parameters");
|
||||
assert!(
|
||||
tcx.dcx().has_errors().is_some(),
|
||||
"auto traits cannot have generic parameters"
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
use rustc_span::Span;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
/// This method traverses the structure of `ty`, trying to find an
|
||||
|
@ -30,19 +29,16 @@ use std::ops::ControlFlow;
|
|||
/// that arose when the requirement was not enforced completely, see
|
||||
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
|
||||
pub fn search_for_structural_match_violation<'tcx>(
|
||||
span: Span,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> Option<Ty<'tcx>> {
|
||||
ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
|
||||
ty.visit_with(&mut Search { tcx, seen: FxHashSet::default() }).break_value()
|
||||
}
|
||||
|
||||
/// This implements the traversal over the structure of a given type to try to
|
||||
/// find instances of ADTs (specifically structs or enums) that do not implement
|
||||
/// `StructuralPartialEq`.
|
||||
struct Search<'tcx> {
|
||||
span: Span,
|
||||
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// Tracks ADTs previously encountered during search, so that
|
||||
|
@ -138,7 +134,6 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
|
|||
bug!("unexpected type during structural-match checking: {:?}", ty);
|
||||
}
|
||||
ty::Error(_) => {
|
||||
self.tcx.dcx().span_delayed_bug(self.span, "ty::Error in structural-match check");
|
||||
// We still want to check other types after encountering an error,
|
||||
// as this may still emit relevant errors.
|
||||
return ControlFlow::Continue(());
|
||||
|
|
7
compiler/rustc_type_ir/src/binder.rs
Normal file
7
compiler/rustc_type_ir/src/binder.rs
Normal 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;
|
||||
}
|
|
@ -2,9 +2,10 @@ use smallvec::SmallVec;
|
|||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||
use crate::{
|
||||
BoundVar, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind, TyKind,
|
||||
UniverseIndex,
|
||||
BoundVar, BoundVars, CanonicalVarInfo, ConstKind, DebruijnIndex, DebugWithInfcx, RegionKind,
|
||||
TyKind, UniverseIndex,
|
||||
};
|
||||
|
||||
pub trait Interner: Sized {
|
||||
|
@ -19,7 +20,10 @@ pub trait Interner: Sized {
|
|||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||
type Term: Copy + Debug + Hash + Ord;
|
||||
|
||||
type Binder<T>;
|
||||
type Binder<T: TypeVisitable<Self>>: BoundVars<Self> + TypeSuperVisitable<Self>;
|
||||
type BoundVars: IntoIterator<Item = Self::BoundVar>;
|
||||
type BoundVar;
|
||||
|
||||
type CanonicalVars: Copy + Debug + Hash + Eq + IntoIterator<Item = CanonicalVarInfo<Self>>;
|
||||
|
||||
// Kinds of tys
|
||||
|
@ -28,7 +32,9 @@ pub trait Interner: Sized {
|
|||
+ Hash
|
||||
+ Ord
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = TyKind<Self>>;
|
||||
+ IntoKind<Kind = TyKind<Self>>
|
||||
+ TypeSuperVisitable<Self>
|
||||
+ Flags;
|
||||
type Tys: Copy + Debug + Hash + Ord + IntoIterator<Item = Self::Ty>;
|
||||
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||
type ParamTy: Copy + Debug + Hash + Ord;
|
||||
|
@ -48,7 +54,9 @@ pub trait Interner: Sized {
|
|||
+ Ord
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = ConstKind<Self>>
|
||||
+ ConstTy<Self>;
|
||||
+ ConstTy<Self>
|
||||
+ TypeSuperVisitable<Self>
|
||||
+ Flags;
|
||||
type AliasConst: Copy + DebugWithInfcx<Self> + Hash + Ord;
|
||||
type PlaceholderConst: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||
type ParamConst: Copy + Debug + Hash + Ord;
|
||||
|
@ -62,7 +70,8 @@ pub trait Interner: Sized {
|
|||
+ Hash
|
||||
+ Ord
|
||||
+ Into<Self::GenericArg>
|
||||
+ IntoKind<Kind = RegionKind<Self>>;
|
||||
+ IntoKind<Kind = RegionKind<Self>>
|
||||
+ Flags;
|
||||
type EarlyParamRegion: Copy + Debug + Hash + Ord;
|
||||
type LateParamRegion: Copy + Debug + Hash + Ord;
|
||||
type BoundRegion: Copy + Debug + Hash + Ord;
|
||||
|
@ -70,7 +79,7 @@ pub trait Interner: Sized {
|
|||
type PlaceholderRegion: Copy + Debug + Hash + Ord + PlaceholderLike;
|
||||
|
||||
// Predicates
|
||||
type Predicate: Copy + Debug + Hash + Eq;
|
||||
type Predicate: Copy + Debug + Hash + Eq + TypeSuperVisitable<Self> + Flags;
|
||||
type TraitPredicate: Copy + Debug + Hash + Eq;
|
||||
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||
|
@ -86,6 +95,9 @@ pub trait Interner: Sized {
|
|||
fn mk_bound_ty(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Ty;
|
||||
fn mk_bound_region(self, debruijn: DebruijnIndex, var: BoundVar) -> Self::Region;
|
||||
fn mk_bound_const(self, debruijn: DebruijnIndex, var: BoundVar, ty: Self::Ty) -> Self::Const;
|
||||
|
||||
/// Assert that an error has been delayed or emitted.
|
||||
fn expect_error_or_delayed_bug();
|
||||
}
|
||||
|
||||
/// Common capabilities of placeholder kinds
|
||||
|
|
|
@ -30,6 +30,7 @@ pub mod visit;
|
|||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod binder;
|
||||
mod canonical;
|
||||
mod const_kind;
|
||||
mod debug;
|
||||
|
@ -39,6 +40,7 @@ mod interner;
|
|||
mod predicate_kind;
|
||||
mod region_kind;
|
||||
|
||||
pub use binder::*;
|
||||
pub use canonical::*;
|
||||
#[cfg(feature = "nightly")]
|
||||
pub use codec::*;
|
||||
|
|
|
@ -45,8 +45,7 @@ use rustc_index::{Idx, IndexVec};
|
|||
use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::Interner;
|
||||
use crate::Lrc;
|
||||
use crate::{self as ty, BoundVars, Interner, IntoKind, Lrc, TypeFlags};
|
||||
|
||||
/// This trait is implemented for every type that can be visited,
|
||||
/// providing the skeleton of the traversal.
|
||||
|
@ -88,38 +87,28 @@ pub trait TypeVisitor<I: Interner>: Sized {
|
|||
#[cfg(not(feature = "nightly"))]
|
||||
type BreakTy;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<I>>(&mut self, t: &I::Binder<T>) -> ControlFlow<Self::BreakTy>
|
||||
where
|
||||
I::Binder<T>: TypeSuperVisitable<I>,
|
||||
{
|
||||
fn visit_binder<T: TypeVisitable<I>>(
|
||||
&mut self,
|
||||
t: &I::Binder<T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy>
|
||||
where
|
||||
I::Ty: TypeSuperVisitable<I>,
|
||||
{
|
||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
// The default region visitor is a no-op because `Region` is non-recursive
|
||||
// and has no `super_visit_with` method to call. That also explains the
|
||||
// lack of `I::Region: TypeSuperVisitable<I>` bound.
|
||||
// and has no `super_visit_with` method to call.
|
||||
fn visit_region(&mut self, _r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy>
|
||||
where
|
||||
I::Const: TypeSuperVisitable<I>,
|
||||
{
|
||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy>
|
||||
where
|
||||
I::Predicate: TypeSuperVisitable<I>,
|
||||
{
|
||||
fn visit_predicate(&mut self, p: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||
p.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
@ -200,3 +189,363 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
|
|||
self.iter().try_for_each(|t| t.visit_with(visitor))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Flags {
|
||||
fn flags(&self) -> TypeFlags;
|
||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex;
|
||||
}
|
||||
|
||||
pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool;
|
||||
|
||||
/// Returns `true` if `self` has any late-bound regions that are either
|
||||
/// bound by `binder` or bound by some binder outside of `binder`.
|
||||
/// If `binder` is `ty::INNERMOST`, this indicates whether
|
||||
/// there are any late-bound regions that appear free.
|
||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool;
|
||||
|
||||
/// Returns `true` if this type has any regions that escape `binder` (and
|
||||
/// hence are not bound by it).
|
||||
fn has_vars_bound_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.has_vars_bound_at_or_above(binder.shifted_in(1))
|
||||
}
|
||||
|
||||
/// Return `true` if this type has regions that are not a part of the type.
|
||||
/// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
|
||||
/// would return `true`. The latter can occur when traversing through the
|
||||
/// former.
|
||||
///
|
||||
/// See [`HasEscapingVarsVisitor`] for more information.
|
||||
fn has_escaping_bound_vars(&self) -> bool {
|
||||
self.has_vars_bound_at_or_above(ty::INNERMOST)
|
||||
}
|
||||
|
||||
fn has_projections(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PROJECTION)
|
||||
}
|
||||
|
||||
fn has_inherent_projections(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INHERENT)
|
||||
}
|
||||
|
||||
fn has_opaque_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
|
||||
}
|
||||
|
||||
fn has_coroutines(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_COROUTINE)
|
||||
}
|
||||
|
||||
fn references_error(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_ERROR)
|
||||
}
|
||||
|
||||
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed>;
|
||||
|
||||
fn has_non_region_param(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PARAM - TypeFlags::HAS_RE_PARAM)
|
||||
}
|
||||
|
||||
fn has_infer_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
|
||||
fn has_infer_types(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_TY_INFER)
|
||||
}
|
||||
|
||||
fn has_non_region_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_INFER - TypeFlags::HAS_RE_INFER)
|
||||
}
|
||||
|
||||
fn has_infer(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_INFER)
|
||||
}
|
||||
|
||||
fn has_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER)
|
||||
}
|
||||
|
||||
fn has_non_region_placeholders(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PLACEHOLDER - TypeFlags::HAS_RE_PLACEHOLDER)
|
||||
}
|
||||
|
||||
fn has_param(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_PARAM)
|
||||
}
|
||||
|
||||
/// "Free" regions in this context means that it has any region
|
||||
/// that is not (a) erased or (b) late-bound.
|
||||
fn has_free_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||
}
|
||||
|
||||
fn has_erased_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_ERASED)
|
||||
}
|
||||
|
||||
/// True if there are any un-erased free regions.
|
||||
fn has_erasable_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_FREE_REGIONS)
|
||||
}
|
||||
|
||||
/// Indicates whether this value references only 'global'
|
||||
/// generic parameters that are the same regardless of what fn we are
|
||||
/// in. This is used for caching.
|
||||
fn is_global(&self) -> bool {
|
||||
!self.has_type_flags(TypeFlags::HAS_FREE_LOCAL_NAMES)
|
||||
}
|
||||
|
||||
/// True if there are any late-bound regions
|
||||
fn has_bound_regions(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_RE_BOUND)
|
||||
}
|
||||
/// True if there are any late-bound non-region variables
|
||||
fn has_non_region_bound_vars(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS - TypeFlags::HAS_RE_BOUND)
|
||||
}
|
||||
/// True if there are any bound variables
|
||||
fn has_bound_vars(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::HAS_BOUND_VARS)
|
||||
}
|
||||
|
||||
/// Indicates whether this value still has parameters/placeholders/inference variables
|
||||
/// which could be replaced later, in a way that would change the results of `impl`
|
||||
/// specialization.
|
||||
fn still_further_specializable(&self) -> bool {
|
||||
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, T: TypeVisitable<I>> TypeVisitableExt<I> for T {
|
||||
fn has_type_flags(&self, flags: TypeFlags) -> bool {
|
||||
let res =
|
||||
self.visit_with(&mut HasTypeFlagsVisitor { flags }) == ControlFlow::Break(FoundFlags);
|
||||
res
|
||||
}
|
||||
|
||||
fn has_vars_bound_at_or_above(&self, binder: ty::DebruijnIndex) -> bool {
|
||||
self.visit_with(&mut HasEscapingVarsVisitor { outer_index: binder }).is_break()
|
||||
}
|
||||
|
||||
fn error_reported(&self) -> Result<(), I::ErrorGuaranteed> {
|
||||
if self.references_error() {
|
||||
if let ControlFlow::Break(guar) = self.visit_with(&mut HasErrorVisitor) {
|
||||
Err(guar)
|
||||
} else {
|
||||
panic!("type flags said there was an error, but now there is not")
|
||||
}
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct FoundFlags;
|
||||
|
||||
// FIXME: Optimize for checking for infer flags
|
||||
struct HasTypeFlagsVisitor {
|
||||
flags: ty::TypeFlags,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for HasTypeFlagsVisitor {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.flags.fmt(fmt)
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this visitor traverses values down to the level of
|
||||
// `Ty`/`Const`/`Predicate`, but not within those types. This is because the
|
||||
// type flags at the outer layer are enough. So it's faster than it first
|
||||
// looks, particular for `Ty`/`Predicate` where it's just a field access.
|
||||
//
|
||||
// N.B. The only case where this isn't totally true is binders, which also
|
||||
// add `HAS_{RE,TY,CT}_LATE_BOUND` flag depending on the *bound variables* that
|
||||
// are present, regardless of whether those bound variables are used. This
|
||||
// is important for anonymization of binders in `TyCtxt::erase_regions`. We
|
||||
// specifically detect this case in `visit_binder`.
|
||||
impl<I: Interner> TypeVisitor<I> for HasTypeFlagsVisitor {
|
||||
type BreakTy = FoundFlags;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<I>>(
|
||||
&mut self,
|
||||
t: &I::Binder<T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
// If we're looking for the HAS_BINDER_VARS flag, check if the
|
||||
// binder has vars. This won't be present in the binder's bound
|
||||
// value, so we need to check here too.
|
||||
if self.flags.intersects(TypeFlags::HAS_BINDER_VARS) && !t.has_no_bound_vars() {
|
||||
return ControlFlow::Break(FoundFlags);
|
||||
}
|
||||
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
let flags = t.flags();
|
||||
if flags.intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call, as usual for `Region`.
|
||||
let flags = r.flags();
|
||||
if flags.intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_const(&mut self, c: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
if c.flags().intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||
// Note: no `super_visit_with` call.
|
||||
if predicate.flags().intersects(self.flags) {
|
||||
ControlFlow::Break(FoundFlags)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
struct FoundEscapingVars;
|
||||
|
||||
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a
|
||||
/// bound region or a bound type.
|
||||
///
|
||||
/// So, for example, consider a type like the following, which has two binders:
|
||||
///
|
||||
/// for<'a> fn(x: for<'b> fn(&'a isize, &'b isize))
|
||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ outer scope
|
||||
/// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ inner scope
|
||||
///
|
||||
/// This type has *bound regions* (`'a`, `'b`), but it does not have escaping regions, because the
|
||||
/// binders of both `'a` and `'b` are part of the type itself. However, if we consider the *inner
|
||||
/// fn type*, that type has an escaping region: `'a`.
|
||||
///
|
||||
/// Note that what I'm calling an "escaping var" is often just called a "free var". However,
|
||||
/// we already use the term "free var". It refers to the regions or types that we use to represent
|
||||
/// bound regions or type params on a fn definition while we are type checking its body.
|
||||
///
|
||||
/// To clarify, conceptually there is no particular difference between
|
||||
/// an "escaping" var and a "free" var. However, there is a big
|
||||
/// difference in practice. Basically, when "entering" a binding
|
||||
/// level, one is generally required to do some sort of processing to
|
||||
/// a bound var, such as replacing it with a fresh/placeholder
|
||||
/// var, or making an entry in the environment to represent the
|
||||
/// scope to which it is attached, etc. An escaping var represents
|
||||
/// a bound var for which this processing has not yet been done.
|
||||
struct HasEscapingVarsVisitor {
|
||||
/// Anything bound by `outer_index` or "above" is escaping.
|
||||
outer_index: ty::DebruijnIndex,
|
||||
}
|
||||
|
||||
impl<I: Interner> TypeVisitor<I> for HasEscapingVarsVisitor {
|
||||
type BreakTy = FoundEscapingVars;
|
||||
|
||||
fn visit_binder<T: TypeVisitable<I>>(
|
||||
&mut self,
|
||||
t: &I::Binder<T>,
|
||||
) -> ControlFlow<Self::BreakTy> {
|
||||
self.outer_index.shift_in(1);
|
||||
let result = t.super_visit_with(self);
|
||||
self.outer_index.shift_out(1);
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_ty(&mut self, t: I::Ty) -> ControlFlow<Self::BreakTy> {
|
||||
// If the outer-exclusive-binder is *strictly greater* than
|
||||
// `outer_index`, that means that `t` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
if t.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_region(&mut self, r: I::Region) -> ControlFlow<Self::BreakTy> {
|
||||
// If the region is bound by `outer_index` or anything outside
|
||||
// of outer index, then it escapes the binders we have
|
||||
// visited.
|
||||
if r.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, ct: I::Const) -> ControlFlow<Self::BreakTy> {
|
||||
// If the outer-exclusive-binder is *strictly greater* than
|
||||
// `outer_index`, that means that `ct` contains some content
|
||||
// bound at `outer_index` or above (because
|
||||
// `outer_exclusive_binder` is always 1 higher than the
|
||||
// content in `t`). Therefore, `t` has some escaping vars.
|
||||
if ct.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_predicate(&mut self, predicate: I::Predicate) -> ControlFlow<Self::BreakTy> {
|
||||
if predicate.outer_exclusive_binder() > self.outer_index {
|
||||
ControlFlow::Break(FoundEscapingVars)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct HasErrorVisitor;
|
||||
|
||||
impl<I: Interner> TypeVisitor<I> for HasErrorVisitor {
|
||||
type BreakTy = I::ErrorGuaranteed;
|
||||
|
||||
fn visit_ty(&mut self, t: <I as Interner>::Ty) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::Error(guar) = t.kind() {
|
||||
ControlFlow::Break(guar)
|
||||
} else {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_const(&mut self, c: <I as Interner>::Const) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::ConstKind::Error(guar) = c.kind() {
|
||||
ControlFlow::Break(guar)
|
||||
} else {
|
||||
c.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, r: <I as Interner>::Region) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::ReError(guar) = r.kind() {
|
||||
ControlFlow::Break(guar)
|
||||
} else {
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ use core::task::Waker;
|
|||
/// The implementation of waking a task on an executor.
|
||||
///
|
||||
/// This trait can be used to create a [`Waker`]. An executor can define an
|
||||
/// implementation of this trait, and use that to construct a Waker to pass
|
||||
/// implementation of this trait, and use that to construct a [`Waker`] to pass
|
||||
/// to the tasks that are executed on that executor.
|
||||
///
|
||||
/// This trait is a memory-safe and ergonomic alternative to constructing a
|
||||
|
@ -28,7 +28,14 @@ use core::task::Waker;
|
|||
/// those for embedded systems) cannot use this API, which is why [`RawWaker`]
|
||||
/// exists as an alternative for those systems.
|
||||
///
|
||||
/// [arc]: ../../std/sync/struct.Arc.html
|
||||
/// To construct a [`Waker`] from some type `W` implementing this trait,
|
||||
/// wrap it in an [`Arc<W>`](Arc) and call `Waker::from()` on that.
|
||||
/// It is also possible to convert to [`RawWaker`] in the same way.
|
||||
///
|
||||
/// <!-- Ideally we'd link to the `From` impl, but rustdoc doesn't generate any page for it within
|
||||
/// `alloc` because `alloc` neither defines nor re-exports `From` or `Waker`, and we can't
|
||||
/// link ../../std/task/struct.Waker.html#impl-From%3CArc%3CW,+Global%3E%3E-for-Waker
|
||||
/// without getting a link-checking error in CI. -->
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -100,7 +107,7 @@ pub trait Wake {
|
|||
#[cfg(target_has_atomic = "ptr")]
|
||||
#[stable(feature = "wake_trait", since = "1.51.0")]
|
||||
impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for Waker {
|
||||
/// Use a `Wake`-able type as a `Waker`.
|
||||
/// Use a [`Wake`]-able type as a `Waker`.
|
||||
///
|
||||
/// No heap allocations or atomic operations are used for this conversion.
|
||||
fn from(waker: Arc<W>) -> Waker {
|
||||
|
|
|
@ -95,8 +95,10 @@ impl fmt::Display for AllocError {
|
|||
/// # Safety
|
||||
///
|
||||
/// * Memory blocks returned from an allocator that are [*currently allocated*] must point to
|
||||
/// valid memory and retain their validity while they are [*currently allocated*] and at
|
||||
/// least one of the instance and all of its clones has not been dropped.
|
||||
/// valid memory and retain their validity while they are [*currently allocated*] and the shorter
|
||||
/// of:
|
||||
/// - the borrow-checker lifetime of the allocator type itself.
|
||||
/// - as long as at least one of the instance and all of its clones has not been dropped.
|
||||
///
|
||||
/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this
|
||||
/// allocator. A copied or cloned allocator must behave like the same allocator, and
|
||||
|
@ -114,6 +116,10 @@ pub unsafe trait Allocator {
|
|||
/// The returned block may have a larger size than specified by `layout.size()`, and may or may
|
||||
/// not have its contents initialized.
|
||||
///
|
||||
/// The returned block of memory remains valid as long as it is [*currently allocated*] and the shorter of:
|
||||
/// - the borrow-checker lifetime of the allocator type itself.
|
||||
/// - as long as at the allocator and all its clones has not been dropped.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returning `Err` indicates that either memory is exhausted or `layout` does not meet
|
||||
|
|
|
@ -58,7 +58,7 @@ use crate::mem::transmute;
|
|||
#[unstable(feature = "ascii_char", issue = "110998")]
|
||||
#[repr(u8)]
|
||||
pub enum AsciiChar {
|
||||
/// U+0000
|
||||
/// U+0000 (The default variant)
|
||||
#[unstable(feature = "ascii_char_variants", issue = "110998")]
|
||||
Null = 0,
|
||||
/// U+0001
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
use crate::ascii::Char as AsciiChar;
|
||||
|
||||
/// A trait for giving a type a useful default value.
|
||||
///
|
||||
/// Sometimes, you want to fall back to some kind of default value, and
|
||||
|
@ -158,6 +160,7 @@ macro_rules! default_impl {
|
|||
default_impl! { (), (), "Returns the default value of `()`" }
|
||||
default_impl! { bool, false, "Returns the default value of `false`" }
|
||||
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
|
||||
default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" }
|
||||
|
||||
default_impl! { usize, 0, "Returns the default value of `0`" }
|
||||
default_impl! { u8, 0, "Returns the default value of `0`" }
|
||||
|
|
|
@ -9,10 +9,14 @@ use crate::ptr;
|
|||
/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`]
|
||||
/// or a [`LocalWaker`] which provides customized wakeup behavior.
|
||||
///
|
||||
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
|
||||
///
|
||||
/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable]
|
||||
/// that customizes the behavior of the `RawWaker`.
|
||||
///
|
||||
/// `RawWaker`s are unsafe to use.
|
||||
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
|
||||
///
|
||||
/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table
|
||||
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||
#[derive(PartialEq, Debug)]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub struct RawWaker {
|
||||
|
@ -355,8 +359,12 @@ impl<'a> ContextBuilder<'a> {
|
|||
/// of `*waker = new_waker.clone()`, as the former will avoid cloning the waker
|
||||
/// unnecessarily if the two wakers [wake the same task](Self::will_wake).
|
||||
///
|
||||
/// Constructing a `Waker` from a [`RawWaker`] is unsafe.
|
||||
/// Implementing the [`Wake`] trait is a safe alternative that requires memory allocation.
|
||||
///
|
||||
/// [`Future::poll()`]: core::future::Future::poll
|
||||
/// [`Poll::Pending`]: core::task::Poll::Pending
|
||||
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||
#[cfg_attr(not(doc), repr(transparent))] // work around https://github.com/rust-lang/rust/issues/66401
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
pub struct Waker {
|
||||
|
@ -438,9 +446,15 @@ impl Waker {
|
|||
|
||||
/// Creates a new `Waker` from [`RawWaker`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// The behavior of the returned `Waker` is undefined if the contract defined
|
||||
/// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld.
|
||||
/// Therefore this method is unsafe.
|
||||
///
|
||||
/// (Authors wishing to avoid unsafe code may implement the [`Wake`] trait instead, at the
|
||||
/// cost of a required heap allocation.)
|
||||
///
|
||||
/// [`Wake`]: ../../alloc/task/trait.Wake.html
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
|
|
|
@ -7,7 +7,9 @@ fn main() {
|
|||
let target_vendor =
|
||||
env::var("CARGO_CFG_TARGET_VENDOR").expect("CARGO_CFG_TARGET_VENDOR was not set");
|
||||
let target_env = env::var("CARGO_CFG_TARGET_ENV").expect("CARGO_CFG_TARGET_ENV was not set");
|
||||
|
||||
if target_os == "netbsd" && env::var("RUSTC_STD_NETBSD10").is_ok() {
|
||||
println!("cargo:rustc-cfg=netbsd10");
|
||||
}
|
||||
if target_os == "linux"
|
||||
|| target_os == "android"
|
||||
|| target_os == "netbsd"
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::sync::Once;
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Using `OnceCell` to store a function’s previously computed value (a.k.a.
|
||||
/// Using `OnceLock` to store a function’s previously computed value (a.k.a.
|
||||
/// ‘lazy static’ or ‘memoizing’):
|
||||
///
|
||||
/// ```
|
||||
|
|
|
@ -62,7 +62,7 @@ mod imp {
|
|||
unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd"))]
|
||||
#[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))]
|
||||
fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
|
||||
unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
|
||||
}
|
||||
|
@ -72,7 +72,8 @@ mod imp {
|
|||
target_os = "android",
|
||||
target_os = "espidf",
|
||||
target_os = "horizon",
|
||||
target_os = "freebsd"
|
||||
target_os = "freebsd",
|
||||
netbsd10
|
||||
)))]
|
||||
fn getrandom_fill_bytes(_buf: &mut [u8]) -> bool {
|
||||
false
|
||||
|
@ -83,7 +84,8 @@ mod imp {
|
|||
target_os = "android",
|
||||
target_os = "espidf",
|
||||
target_os = "horizon",
|
||||
target_os = "freebsd"
|
||||
target_os = "freebsd",
|
||||
netbsd10
|
||||
))]
|
||||
fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
|
||||
use crate::sync::atomic::{AtomicBool, Ordering};
|
||||
|
@ -230,7 +232,7 @@ mod imp {
|
|||
}
|
||||
|
||||
// FIXME: once the 10.x release becomes the minimum, this can be dropped for simplification.
|
||||
#[cfg(target_os = "netbsd")]
|
||||
#[cfg(all(target_os = "netbsd", not(netbsd10)))]
|
||||
mod imp {
|
||||
use crate::ptr;
|
||||
|
||||
|
|
|
@ -86,6 +86,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
|
|||
(Some(Mode::Std), "no_global_oom_handling", None),
|
||||
(Some(Mode::Std), "no_rc", None),
|
||||
(Some(Mode::Std), "no_sync", None),
|
||||
(Some(Mode::Std), "netbsd10", None),
|
||||
(Some(Mode::Std), "backtrace_in_libstd", None),
|
||||
/* Extra values not defined in the built-in targets yet, but used in std */
|
||||
(Some(Mode::Std), "target_env", Some(&["libnx"])),
|
||||
|
|
25
tests/mir-opt/issue_120925_unsafefncast.rs
Normal file
25
tests/mir-opt/issue_120925_unsafefncast.rs
Normal 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);
|
||||
}
|
|
@ -13,7 +13,7 @@ LL | .intel_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:38:15
|
||||
--> $DIR/inline-syntax.rs:35:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix", "nop");
|
||||
| ^
|
||||
|
@ -25,7 +25,7 @@ LL | .intel_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:42:15
|
||||
--> $DIR/inline-syntax.rs:39:15
|
||||
|
|
||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||
| ^
|
||||
|
@ -37,7 +37,7 @@ LL | .intel_syntax aaa noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:46:15
|
||||
--> $DIR/inline-syntax.rs:43:15
|
||||
|
|
||||
LL | asm!(".att_syntax noprefix", "nop");
|
||||
| ^
|
||||
|
@ -49,7 +49,7 @@ LL | .att_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:50:15
|
||||
--> $DIR/inline-syntax.rs:47:15
|
||||
|
|
||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||
| ^
|
||||
|
@ -61,7 +61,7 @@ LL | .att_syntax bbb noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:54:15
|
||||
--> $DIR/inline-syntax.rs:51:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix; nop");
|
||||
| ^
|
||||
|
@ -73,7 +73,7 @@ LL | .intel_syntax noprefix; nop
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:61:13
|
||||
--> $DIR/inline-syntax.rs:58:13
|
||||
|
|
||||
LL | .intel_syntax noprefix
|
||||
| ^
|
||||
|
|
|
@ -15,7 +15,7 @@ LL | .intel_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:38:15
|
||||
--> $DIR/inline-syntax.rs:35:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix", "nop");
|
||||
| ^
|
||||
|
@ -27,7 +27,7 @@ LL | .intel_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:42:15
|
||||
--> $DIR/inline-syntax.rs:39:15
|
||||
|
|
||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||
| ^
|
||||
|
@ -39,7 +39,7 @@ LL | .intel_syntax aaa noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:46:15
|
||||
--> $DIR/inline-syntax.rs:43:15
|
||||
|
|
||||
LL | asm!(".att_syntax noprefix", "nop");
|
||||
| ^
|
||||
|
@ -51,7 +51,7 @@ LL | .att_syntax noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:50:15
|
||||
--> $DIR/inline-syntax.rs:47:15
|
||||
|
|
||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||
| ^
|
||||
|
@ -63,7 +63,7 @@ LL | .att_syntax bbb noprefix
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:54:15
|
||||
--> $DIR/inline-syntax.rs:51:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix; nop");
|
||||
| ^
|
||||
|
@ -75,7 +75,7 @@ LL | .intel_syntax noprefix; nop
|
|||
| ^
|
||||
|
||||
error: unknown directive
|
||||
--> $DIR/inline-syntax.rs:61:13
|
||||
--> $DIR/inline-syntax.rs:58:13
|
||||
|
|
||||
LL | .intel_syntax noprefix
|
||||
| ^
|
||||
|
|
|
@ -2,14 +2,11 @@
|
|||
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//[x86_64] check-pass
|
||||
//[x86_64] needs-llvm-components: x86
|
||||
//[x86_64_allowed] compile-flags: --target x86_64-unknown-linux-gnu
|
||||
//[x86_64_allowed] check-pass
|
||||
//[x86_64_allowed] needs-llvm-components: x86
|
||||
//[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||
//[arm] build-fail
|
||||
//[arm] needs-llvm-components: arm
|
||||
//[arm] ignore-llvm-version: 18 - 99
|
||||
// Newer LLVM produces extra error notes.
|
||||
//Newer LLVM produces extra error notes.
|
||||
//[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
|
||||
//[arm_llvm_18] build-fail
|
||||
//[arm_llvm_18] needs-llvm-components: arm
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||
--> $DIR/inline-syntax.rs:70:14
|
||||
--> $DIR/inline-syntax.rs:67:14
|
||||
|
|
||||
LL | global_asm!(".intel_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
|
|||
= note: `#[warn(bad_asm_style)]` on by default
|
||||
|
||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||
--> $DIR/inline-syntax.rs:38:15
|
||||
--> $DIR/inline-syntax.rs:35:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||
--> $DIR/inline-syntax.rs:42:15
|
||||
--> $DIR/inline-syntax.rs:39:15
|
||||
|
|
||||
LL | asm!(".intel_syntax aaa noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
||||
--> $DIR/inline-syntax.rs:46:15
|
||||
--> $DIR/inline-syntax.rs:43:15
|
||||
|
|
||||
LL | asm!(".att_syntax noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
|
||||
--> $DIR/inline-syntax.rs:50:15
|
||||
--> $DIR/inline-syntax.rs:47:15
|
||||
|
|
||||
LL | asm!(".att_syntax bbb noprefix", "nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||
--> $DIR/inline-syntax.rs:54:15
|
||||
--> $DIR/inline-syntax.rs:51:15
|
||||
|
|
||||
LL | asm!(".intel_syntax noprefix; nop");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: avoid using `.intel_syntax`, Intel syntax is the default
|
||||
--> $DIR/inline-syntax.rs:61:13
|
||||
--> $DIR/inline-syntax.rs:58:13
|
||||
|
|
||||
LL | .intel_syntax noprefix
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
18
tests/ui/borrowck/copy-suggestion-region-vid.fixed
Normal file
18
tests/ui/borrowck/copy-suggestion-region-vid.fixed
Normal 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() {}
|
|
@ -1,4 +1,4 @@
|
|||
//@run-rustfix
|
||||
// run-rustfix
|
||||
pub struct DataStruct();
|
||||
|
||||
pub struct HelperStruct<'n> {
|
||||
|
|
|
@ -9,9 +9,4 @@ LL | FOO => todo!(),
|
|||
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-89088.rs:5:10
|
||||
|
|
||||
LL | #![allow(indirect_structural_match)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | type H = <dyn Fn(u8) -> (u8)>::Output;
|
||||
| ++++ +
|
||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #[deny(bare_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
|
||||
| +++
|
||||
|
@ -24,7 +24,7 @@ LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
|
||||
| +++
|
||||
|
@ -37,7 +37,7 @@ LL | let _x: &SomeTrait = todo!();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let _x: &dyn SomeTrait = todo!();
|
||||
| +++
|
||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![deny(bare_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | <dyn fmt::Debug>::fmt(self, f)
|
||||
| +++
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | fn ice() -> impl AsRef<Fn(&())> {
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn ice() -> impl AsRef<dyn Fn(&())> {
|
||||
| +++
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
|
||||
| ++++ +
|
||||
|
@ -35,7 +35,7 @@ LL | let g = BitXor::bitor;
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let g = <dyn BitXor>::bitor;
|
||||
| ++++ +
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | Trait::nonexistent(());
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | <dyn Trait>::nonexistent(());
|
||||
| ++++ +
|
||||
|
|
|
@ -21,7 +21,7 @@ LL | eq::<dyn, Foo>
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | eq::<dyn, dyn Foo>
|
||||
| +++
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | let _: Dyn::Ty;
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let _: <dyn Dyn>::Ty;
|
||||
| ++++ +
|
||||
|
@ -26,7 +26,7 @@ LL | Dyn::func();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | <dyn Dyn>::func();
|
||||
| ++++ +
|
||||
|
@ -39,7 +39,7 @@ LL | ::Dyn::func();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | <dyn (::Dyn)>::func();
|
||||
| ++++++ ++
|
||||
|
@ -52,7 +52,7 @@ LL | Dyn::CONST;
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | <dyn Dyn>::CONST;
|
||||
| ++++ +
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: requested on the command line with `--force-warn bare-trait-objects`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||
| +++
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: requested on the command line with `--force-warn bare-trait-objects`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||
| +++
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
|||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||
| +++
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
|||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||
| +++
|
||||
|
|
|
@ -8,7 +8,7 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
|
|||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
|
||||
= help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | pub fn function(_x: Box<dyn SomeTrait>) {}
|
||||
| +++
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
|
||||
{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":" let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
|
||||
--> $DIR/future-incompat-json-test.rs:9:9
|
||||
|
|
||||
LL | let x = 1;
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
|
||||
= note: `-A unused-variables` implied by `-A unused`
|
||||
= help: to override `-A unused` add `#[allow(unused_variables)]`
|
||||
|
||||
"}}]}
|
||||
|
|
|
@ -4,7 +4,4 @@ warning: unused variable: `x`
|
|||
|
|
||||
LL | let x = 1;
|
||||
| ^ help: if this is intentional, prefix it with an underscore: `_x`
|
||||
|
|
||||
= note: `-A unused-variables` implied by `-A unused`
|
||||
= help: to override `-A unused` add `#[allow(unused_variables)]`
|
||||
|
||||
|
|
|
@ -60,11 +60,6 @@ LL | foo!(first)
|
|||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
= note: macro invocations at the end of a block are treated as expressions
|
||||
= note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
|
||||
note: the lint level is defined here
|
||||
--> $DIR/semicolon-in-expressions-from-macros.rs:24:13
|
||||
|
|
||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
|
@ -79,11 +74,6 @@ LL | let _ = foo!(second);
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/semicolon-in-expressions-from-macros.rs:29:13
|
||||
|
|
||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
|
@ -98,11 +88,6 @@ LL | let _ = foo!(third);
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/semicolon-in-expressions-from-macros.rs:32:13
|
||||
|
|
||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
|
@ -117,11 +102,6 @@ LL | let _ = foo!(fourth);
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/semicolon-in-expressions-from-macros.rs:37:13
|
||||
|
|
||||
LL | #[allow(semicolon_in_expressions_from_macros)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize {
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn id<F>(f: dyn Copy) -> usize {
|
||||
| +++
|
||||
|
@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize {
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn id<F>(f: dyn Copy) -> usize {
|
||||
| +++
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; }
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait B { fn f(a: dyn A) -> A; }
|
||||
| +++
|
||||
|
@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; }
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait B { fn f(a: A) -> dyn A; }
|
||||
| +++
|
||||
|
@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; }
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait A { fn g(b: dyn B) -> B; }
|
||||
| +++
|
||||
|
@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; }
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait A { fn g(b: B) -> dyn B; }
|
||||
| +++
|
||||
|
@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; }
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait B { fn f(a: dyn A) -> A; }
|
||||
| +++
|
||||
|
@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; }
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | trait A { fn g(b: dyn B) -> B; }
|
||||
| +++
|
||||
|
|
|
@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
|
||||
| +++
|
||||
|
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![deny(bare_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn ord_prefer_dot(s: String) -> dyn Ord {
|
||||
| +++
|
||||
|
|
|
@ -25,7 +25,7 @@ LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
|
||||
| +++
|
||||
|
@ -49,7 +49,7 @@ LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
|
||||
| +++
|
||||
|
@ -73,7 +73,7 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
|
||||
| +++
|
||||
|
|
|
@ -20,10 +20,4 @@ LL | if let CONSTANT = &&MyType {
|
|||
= note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
|
||||
= note: the traits must be derived, manual `impl`s are not sufficient
|
||||
= note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
|
||||
note: the lint level is defined here
|
||||
--> $DIR/const-partial_eq-fallback-ice.rs:1:10
|
||||
|
|
||||
LL | #![allow(warnings)]
|
||||
| ^^^^^^^^
|
||||
= note: `#[allow(indirect_structural_match)]` implied by `#[allow(warnings)]`
|
||||
|
||||
|
|
|
@ -139,11 +139,6 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/generate-mod.rs:30:10
|
||||
|
|
||||
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
Future breakage diagnostic:
|
||||
|
@ -155,10 +150,5 @@ LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #83583 <https://github.com/rust-lang/rust/issues/83583>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/generate-mod.rs:30:10
|
||||
|
|
||||
LL | #[derive(generate_mod::CheckDeriveLint)] // OK, lint is suppressed
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: this warning originates in the derive macro `generate_mod::CheckDeriveLint` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
|
|
23
tests/ui/suggestions/issue-116434-2015.rs
Normal file
23
tests/ui/suggestions/issue-116434-2015.rs
Normal 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() {}
|
81
tests/ui/suggestions/issue-116434-2015.stderr
Normal file
81
tests/ui/suggestions/issue-116434-2015.stderr
Normal 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`.
|
17
tests/ui/suggestions/issue-116434-2021.rs
Normal file
17
tests/ui/suggestions/issue-116434-2021.rs
Normal 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() {}
|
26
tests/ui/suggestions/issue-116434-2021.stderr
Normal file
26
tests/ui/suggestions/issue-116434-2021.stderr
Normal 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`.
|
|
@ -11,7 +11,7 @@ note: the lint level is defined here
|
|||
|
|
||||
LL | #![deny(bare_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | bar: Box<dyn Bar>,
|
||||
| +++
|
||||
|
@ -24,7 +24,7 @@ LL | pub struct Foo {
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | dyn pub struct Foo {
|
||||
| +++
|
||||
|
|
|
@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
|
||||
| +++
|
||||
|
|
20
tests/ui/trait-bounds/suggest-maybe-sized-bound.rs
Normal file
20
tests/ui/trait-bounds/suggest-maybe-sized-bound.rs
Normal 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]
|
||||
}
|
||||
}
|
37
tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr
Normal file
37
tests/ui/trait-bounds/suggest-maybe-sized-bound.stderr
Normal 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`.
|
|
@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) {
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | fn foo(_x: dyn Foo + Send) {
|
||||
| +++
|
||||
|
|
|
@ -36,8 +36,8 @@ LL | pub trait Bar: Foo<Assoc=()> + Sized {
|
|||
| +++++++
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | pub trait Foo<RHS=Self: ?Sized> {
|
||||
| ++++++++
|
||||
LL | pub trait Foo<RHS: ?Sized=Self> {
|
||||
| ++++++++
|
||||
|
||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||
--> $DIR/issue-28576.rs:5:16
|
||||
|
@ -56,8 +56,8 @@ LL | ) where Self: Sized;
|
|||
| +++++++++++++++++
|
||||
help: consider relaxing the implicit `Sized` restriction
|
||||
|
|
||||
LL | pub trait Foo<RHS=Self: ?Sized> {
|
||||
| ++++++++
|
||||
LL | pub trait Foo<RHS: ?Sized=Self> {
|
||||
| ++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
|
|
@ -77,9 +77,4 @@ LL | impl Trait0 for dyn Send {}
|
|||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #56484 <https://github.com/rust-lang/rust/issues/56484>
|
||||
note: the lint level is defined here
|
||||
--> $DIR/issue-33140-hack-boundaries.rs:2:10
|
||||
|
|
||||
LL | #![allow(order_dependent_trait_objects)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ LL | let a = Foo::lol();
|
|||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
= note: `#[warn(bare_trait_objects)]` on by default
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let a = <dyn Foo>::lol();
|
||||
| ++++ +
|
||||
|
@ -26,7 +26,7 @@ LL | let b = Foo::<_>::lol();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let b = <dyn Foo::<_>>::lol();
|
||||
| ++++ +
|
||||
|
@ -45,7 +45,7 @@ LL | let c = Bar::lol();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let c = <dyn Bar>::lol();
|
||||
| ++++ +
|
||||
|
@ -64,7 +64,7 @@ LL | let d = Bar::<usize, _>::lol();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let d = <dyn Bar::<usize, _>>::lol();
|
||||
| ++++ +
|
||||
|
@ -83,7 +83,7 @@ LL | let e = Bar::<usize>::lol();
|
|||
|
|
||||
= warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
|
||||
help: use `dyn`
|
||||
help: if this is an object-safe trait, use `dyn`
|
||||
|
|
||||
LL | let e = <dyn Bar::<usize>>::lol();
|
||||
| ++++ +
|
||||
|
|
Loading…
Add table
Reference in a new issue