Auto merge of #137295 - matthiaskrgr:rollup-tdu3t39, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #135296 (interpret: adjust vtable validity check for higher-ranked types) - #137106 (Add customized compare for Link in rustdoc) - #137253 (Restrict `bevy_ecs` `ParamSet` hack) - #137262 (Make fewer crates depend on `rustc_ast_ir`) - #137263 (Register `USAGE_OF_TYPE_IR_INHERENT`, remove inherent usages) - #137266 (MIR visitor tweaks) - #137269 (Pattern Migration 2024: properly label `&` patterns whose subpatterns are from macro expansions) - #137277 (stabilize `inherent_str_constructors`) - #137281 (Tweak "expected ident" parse error to avoid talking about doc comments) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
6d3c050de8
@ -3748,7 +3748,6 @@ dependencies = [
|
||||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
"rustc_attr_parsing",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
@ -3813,7 +3812,6 @@ dependencies = [
|
||||
name = "rustc_infer"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
@ -4004,7 +4002,6 @@ dependencies = [
|
||||
"rustc_apfloat",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
"rustc_attr_parsing",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_messages",
|
||||
@ -4134,7 +4131,6 @@ name = "rustc_next_trait_solver"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"derive-where",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_index",
|
||||
"rustc_macros",
|
||||
@ -4454,7 +4450,6 @@ dependencies = [
|
||||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast",
|
||||
"rustc_ast_ir",
|
||||
"rustc_attr_parsing",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
@ -4493,7 +4488,6 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_hir",
|
||||
"rustc_infer",
|
||||
@ -4509,7 +4503,6 @@ version = "0.0.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"rustc_abi",
|
||||
"rustc_ast_ir",
|
||||
"rustc_data_structures",
|
||||
"rustc_errors",
|
||||
"rustc_fluent_macro",
|
||||
|
@ -1,3 +1,10 @@
|
||||
//! Common utilities shared by both `rustc_ast` and `rustc_type_ir`.
|
||||
//!
|
||||
//! Don't depend on this crate directly; both of those crates should re-export
|
||||
//! the functionality. Additionally, if you're in scope of `rustc_middle`, then
|
||||
//! prefer imports via that too, to avoid needing to directly depend on (e.g.)
|
||||
//! `rustc_type_ir` for a single import.
|
||||
|
||||
// tidy-alphabetical-start
|
||||
#![cfg_attr(feature = "nightly", allow(internal_features))]
|
||||
#![cfg_attr(feature = "nightly", feature(never_type))]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{self, Body, Local, Location};
|
||||
use rustc_middle::ty::{RegionVid, TyCtxt};
|
||||
|
||||
@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
|
||||
|
||||
let block_data = &self.body[p.block];
|
||||
|
||||
match self.def_use(p, block_data.visitable(p.statement_index)) {
|
||||
let mut visitor = DefUseVisitor {
|
||||
body: self.body,
|
||||
tcx: self.tcx,
|
||||
region_vid: self.region_vid,
|
||||
def_use_result: None,
|
||||
};
|
||||
|
||||
let is_statement = p.statement_index < block_data.statements.len();
|
||||
|
||||
if is_statement {
|
||||
visitor.visit_statement(&block_data.statements[p.statement_index], p);
|
||||
} else {
|
||||
visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p);
|
||||
}
|
||||
|
||||
match visitor.def_use_result {
|
||||
Some(DefUseResult::Def) => {}
|
||||
|
||||
Some(DefUseResult::UseLive { local }) => {
|
||||
@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
None => {
|
||||
if p.statement_index < block_data.statements.len() {
|
||||
if is_statement {
|
||||
queue.push_back(p.successor_within_block());
|
||||
} else {
|
||||
queue.extend(
|
||||
@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option<DefUseResult> {
|
||||
let mut visitor = DefUseVisitor {
|
||||
body: self.body,
|
||||
tcx: self.tcx,
|
||||
region_vid: self.region_vid,
|
||||
def_use_result: None,
|
||||
};
|
||||
|
||||
thing.apply(location, &mut visitor);
|
||||
|
||||
visitor.def_use_result
|
||||
}
|
||||
}
|
||||
|
||||
struct DefUseVisitor<'a, 'tcx> {
|
||||
|
@ -430,10 +430,12 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
};
|
||||
let erased_trait_ref =
|
||||
ty::ExistentialTraitRef::erase_self_ty(*self.tcx, upcast_trait_ref);
|
||||
assert!(data_b.principal().is_some_and(|b| self.eq_in_param_env(
|
||||
erased_trait_ref,
|
||||
self.tcx.instantiate_bound_regions_with_erased(b)
|
||||
)));
|
||||
assert_eq!(
|
||||
data_b.principal().map(|b| {
|
||||
self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b)
|
||||
}),
|
||||
Some(erased_trait_ref),
|
||||
);
|
||||
} else {
|
||||
// In this case codegen would keep using the old vtable. We don't want to do
|
||||
// that as it has the wrong trait. The reason codegen can do this is that
|
||||
|
@ -4,9 +4,6 @@ use either::{Left, Right};
|
||||
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout};
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::infer::at::ToTrace;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
use rustc_middle::ty::layout::{
|
||||
@ -17,8 +14,7 @@ use rustc_middle::{mir, span_bug};
|
||||
use rustc_session::Limit;
|
||||
use rustc_span::Span;
|
||||
use rustc_target::callconv::FnAbi;
|
||||
use rustc_trait_selection::traits::ObligationCtxt;
|
||||
use tracing::{debug, instrument, trace};
|
||||
use tracing::{debug, trace};
|
||||
|
||||
use super::{
|
||||
Frame, FrameInfo, GlobalId, InterpErrorInfo, InterpErrorKind, InterpResult, MPlaceTy, Machine,
|
||||
@ -320,40 +316,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the two things are equal in the current param_env, using an infcx to get proper
|
||||
/// equality checks.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
pub(super) fn eq_in_param_env<T>(&self, a: T, b: T) -> bool
|
||||
where
|
||||
T: PartialEq + TypeFoldable<TyCtxt<'tcx>> + ToTrace<'tcx>,
|
||||
{
|
||||
// Fast path: compare directly.
|
||||
if a == b {
|
||||
return true;
|
||||
}
|
||||
// Slow path: spin up an inference context to check if these traits are sufficiently equal.
|
||||
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = ObligationCause::dummy_with_span(self.cur_span());
|
||||
// equate the two trait refs after normalization
|
||||
let a = ocx.normalize(&cause, param_env, a);
|
||||
let b = ocx.normalize(&cause, param_env, b);
|
||||
|
||||
if let Err(terr) = ocx.eq(&cause, param_env, a, b) {
|
||||
trace!(?terr);
|
||||
return false;
|
||||
}
|
||||
|
||||
let errors = ocx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
trace!(?errors);
|
||||
return false;
|
||||
}
|
||||
|
||||
// All good.
|
||||
true
|
||||
}
|
||||
|
||||
/// Walks up the callstack from the intrinsic's callsite, searching for the first callsite in a
|
||||
/// frame which is not `#[track_caller]`. This matches the `caller_location` intrinsic,
|
||||
/// and is primarily intended for the panic machinery.
|
||||
|
@ -86,21 +86,15 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
|
||||
}
|
||||
|
||||
// This checks whether there is a subtyping relation between the predicates in either direction.
|
||||
// For example:
|
||||
// - casting between `dyn for<'a> Trait<fn(&'a u8)>` and `dyn Trait<fn(&'static u8)>` is OK
|
||||
// - casting between `dyn Trait<for<'a> fn(&'a u8)>` and either of the above is UB
|
||||
for (a_pred, b_pred) in std::iter::zip(sorted_vtable, sorted_expected) {
|
||||
let is_eq = match (a_pred.skip_binder(), b_pred.skip_binder()) {
|
||||
(
|
||||
ty::ExistentialPredicate::Trait(a_data),
|
||||
ty::ExistentialPredicate::Trait(b_data),
|
||||
) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)),
|
||||
let a_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, a_pred);
|
||||
let b_pred = self.tcx.normalize_erasing_late_bound_regions(self.typing_env, b_pred);
|
||||
|
||||
(
|
||||
ty::ExistentialPredicate::Projection(a_data),
|
||||
ty::ExistentialPredicate::Projection(b_data),
|
||||
) => self.eq_in_param_env(a_pred.rebind(a_data), b_pred.rebind(b_data)),
|
||||
|
||||
_ => false,
|
||||
};
|
||||
if !is_eq {
|
||||
if a_pred != b_pred {
|
||||
throw_ub!(InvalidVTableTrait { vtable_dyn_type, expected_dyn_type });
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ use rustc_lint_defs::builtin::SUPERTRAIT_ITEM_SHADOWING_DEFINITION;
|
||||
use rustc_macros::LintDiagnostic;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::ty::print::with_no_trimmed_paths;
|
||||
use rustc_middle::ty::trait_def::TraitSpecializationKind;
|
||||
use rustc_middle::ty::{
|
||||
self, AdtKind, GenericArgKind, GenericArgs, GenericParamDefKind, Ty, TyCtxt, TypeFoldable,
|
||||
@ -143,33 +142,7 @@ where
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let is_bevy = 'is_bevy: {
|
||||
// We don't want to emit this for dependents of Bevy, for now.
|
||||
// See #119956
|
||||
let is_bevy_paramset = |def: ty::AdtDef<'_>| {
|
||||
let adt_did = with_no_trimmed_paths!(infcx.tcx.def_path_str(def.0.did));
|
||||
adt_did.contains("ParamSet")
|
||||
};
|
||||
for ty in assumed_wf_types.iter() {
|
||||
match ty.kind() {
|
||||
ty::Adt(def, _) => {
|
||||
if is_bevy_paramset(*def) {
|
||||
break 'is_bevy true;
|
||||
}
|
||||
}
|
||||
ty::Ref(_, ty, _) => match ty.kind() {
|
||||
ty::Adt(def, _) => {
|
||||
if is_bevy_paramset(*def) {
|
||||
break 'is_bevy true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
false
|
||||
};
|
||||
let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break();
|
||||
|
||||
// If we have set `no_implied_bounds_compat`, then do not attempt compatibility.
|
||||
// We could also just always enter if `is_bevy`, and call `implied_bounds_tys`,
|
||||
@ -194,6 +167,31 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
struct ContainsBevyParamSet<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> {
|
||||
type Result = ControlFlow<()>;
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
|
||||
// We only care to match `ParamSet<T>` or `&ParamSet<T>`.
|
||||
match t.kind() {
|
||||
ty::Adt(def, _) => {
|
||||
if self.tcx.item_name(def.did()) == sym::ParamSet
|
||||
&& self.tcx.crate_name(def.did().krate) == sym::bevy_ecs
|
||||
{
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
}
|
||||
ty::Ref(_, ty, _) => ty.visit_with(self)?,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
}
|
||||
|
||||
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
let node = tcx.hir_node_by_def_id(def_id);
|
||||
let mut res = match node {
|
||||
|
@ -8,7 +8,6 @@ edition = "2021"
|
||||
itertools = "0.12"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
|
@ -847,20 +847,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat,
|
||||
ident.span,
|
||||
't', // last char of `mut`
|
||||
def_br_mutbl,
|
||||
);
|
||||
BindingMode(ByRef::No, Mutability::Mut)
|
||||
}
|
||||
}
|
||||
BindingMode(ByRef::No, mutbl) => BindingMode(def_br, mutbl),
|
||||
BindingMode(ByRef::Yes(_), _) => {
|
||||
BindingMode(ByRef::Yes(user_br_mutbl), _) => {
|
||||
if let ByRef::Yes(def_br_mutbl) = def_br {
|
||||
// `ref`/`ref mut` overrides the binding mode on edition <= 2021
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat,
|
||||
ident.span,
|
||||
match user_br_mutbl {
|
||||
Mutability::Not => 'f', // last char of `ref`
|
||||
Mutability::Mut => 't', // last char of `ref mut`
|
||||
},
|
||||
def_br_mutbl,
|
||||
);
|
||||
}
|
||||
@ -2440,7 +2443,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.add_rust_2024_migration_desugared_pat(
|
||||
pat_info.top_info.hir_id,
|
||||
pat,
|
||||
inner.span,
|
||||
match pat_mutbl {
|
||||
Mutability::Not => '&', // last char of `&`
|
||||
Mutability::Mut => 't', // last char of `&mut`
|
||||
},
|
||||
inh_mut,
|
||||
)
|
||||
}
|
||||
@ -2832,18 +2838,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
&self,
|
||||
pat_id: HirId,
|
||||
subpat: &'tcx Pat<'tcx>,
|
||||
cutoff_span: Span,
|
||||
final_char: char,
|
||||
def_br_mutbl: Mutability,
|
||||
) {
|
||||
// Try to trim the span we're labeling to just the `&` or binding mode that's an issue.
|
||||
// If the subpattern's span is is from an expansion, the emitted label will not be trimmed.
|
||||
let source_map = self.tcx.sess.source_map();
|
||||
let cutoff_span = source_map
|
||||
.span_extend_prev_while(cutoff_span, |c| c.is_whitespace() || c == '(')
|
||||
.unwrap_or(cutoff_span);
|
||||
// Ensure we use the syntax context and thus edition of `subpat.span`; this will be a hard
|
||||
// error if the subpattern is of edition >= 2024.
|
||||
let trimmed_span = subpat.span.until(cutoff_span).with_ctxt(subpat.span.ctxt());
|
||||
let from_expansion = subpat.span.from_expansion();
|
||||
let trimmed_span = if from_expansion {
|
||||
// If the subpattern is from an expansion, highlight the whole macro call instead.
|
||||
subpat.span
|
||||
} else {
|
||||
let trimmed = self.tcx.sess.source_map().span_through_char(subpat.span, final_char);
|
||||
// The edition of the trimmed span should be the same as `subpat.span`; this will be a
|
||||
// a hard error if the subpattern is of edition >= 2024. We set it manually to be sure:
|
||||
trimmed.with_ctxt(subpat.span.ctxt())
|
||||
};
|
||||
|
||||
let mut typeck_results = self.typeck_results.borrow_mut();
|
||||
let mut table = typeck_results.rust_2024_migration_desugared_pats_mut();
|
||||
@ -2877,7 +2885,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
};
|
||||
// Only provide a detailed label if the problematic subpattern isn't from an expansion.
|
||||
// In the case that it's from a macro, we'll add a more detailed note in the emitter.
|
||||
let from_expansion = subpat.span.from_expansion();
|
||||
let primary_label = if from_expansion {
|
||||
// We can't suggest eliding modifiers within expansions.
|
||||
info.suggest_eliding_modes = false;
|
||||
|
@ -8,7 +8,6 @@ doctest = false
|
||||
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
|
@ -1,8 +1,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor};
|
||||
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor, try_visit};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use crate::traits;
|
||||
|
@ -641,6 +641,7 @@ fn register_internals(store: &mut LintStore) {
|
||||
LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
|
||||
LintId::of(USAGE_OF_QUALIFIED_TY),
|
||||
LintId::of(NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT),
|
||||
LintId::of(USAGE_OF_TYPE_IR_INHERENT),
|
||||
LintId::of(BAD_OPT_ACCESS),
|
||||
LintId::of(SPAN_USE_EQ_CTXT),
|
||||
],
|
||||
|
@ -36,12 +36,12 @@ pub(super) fn type_visitable_derive(
|
||||
s.add_bounds(synstructure::AddBounds::Generics);
|
||||
let body_visit = s.each(|bind| {
|
||||
quote! {
|
||||
match ::rustc_ast_ir::visit::VisitorResult::branch(
|
||||
match ::rustc_middle::ty::visit::VisitorResult::branch(
|
||||
::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)
|
||||
) {
|
||||
::core::ops::ControlFlow::Continue(()) => {},
|
||||
::core::ops::ControlFlow::Break(r) => {
|
||||
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
|
||||
return ::rustc_middle::ty::visit::VisitorResult::from_residual(r);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -56,7 +56,7 @@ pub(super) fn type_visitable_derive(
|
||||
__visitor: &mut __V
|
||||
) -> __V::Result {
|
||||
match *self { #body_visit }
|
||||
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
|
||||
<__V::Result as ::rustc_middle::ty::visit::VisitorResult>::output()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -14,7 +14,6 @@ rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_apfloat = "0.2.0"
|
||||
rustc_arena = { path = "../rustc_arena" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links
|
||||
|
@ -83,7 +83,7 @@ macro_rules! TrivialTypeTraversalImpls {
|
||||
_: &mut F)
|
||||
-> F::Result
|
||||
{
|
||||
<F::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
|
||||
<F::Result as ::rustc_middle::ty::visit::VisitorResult>::output()
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
@ -5,7 +5,6 @@ use std::{convert, fmt, mem, ops};
|
||||
|
||||
use either::Either;
|
||||
use rustc_abi::{Align, Size, VariantIdx, WrappingRange};
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_errors::{DiagArgName, DiagArgValue, DiagMessage, ErrorGuaranteed, IntoDiagArg};
|
||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
||||
@ -16,7 +15,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
|
||||
use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar};
|
||||
use crate::error;
|
||||
use crate::mir::{ConstAlloc, ConstValue};
|
||||
use crate::ty::{self, Ty, TyCtxt, ValTree, layout, tls};
|
||||
use crate::ty::{self, Mutability, Ty, TyCtxt, ValTree, layout, tls};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, TyEncodable, TyDecodable)]
|
||||
pub enum ErrorHandled {
|
||||
|
@ -32,7 +32,6 @@ use tracing::{debug, trace};
|
||||
pub use self::query::*;
|
||||
use self::visit::TyContext;
|
||||
use crate::mir::interpret::{AllocRange, Scalar};
|
||||
use crate::mir::visit::MirVisitable;
|
||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||
use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
|
||||
use crate::ty::visit::TypeVisitableExt;
|
||||
@ -1364,10 +1363,6 @@ impl<'tcx> BasicBlockData<'tcx> {
|
||||
self.terminator.as_mut().expect("invalid terminator state")
|
||||
}
|
||||
|
||||
pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> {
|
||||
if index < self.statements.len() { &self.statements[index] } else { &self.terminator }
|
||||
}
|
||||
|
||||
/// Does the block have no statements and an unreachable terminator?
|
||||
#[inline]
|
||||
pub fn is_empty_unreachable(&self) -> bool {
|
||||
|
@ -270,10 +270,12 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
fn visit_local(
|
||||
&mut self,
|
||||
_local: $(& $mutability)? Local,
|
||||
_context: PlaceContext,
|
||||
_location: Location,
|
||||
) {}
|
||||
local: $(& $mutability)? Local,
|
||||
context: PlaceContext,
|
||||
location: Location,
|
||||
) {
|
||||
self.super_local(local, context, location)
|
||||
}
|
||||
|
||||
fn visit_source_scope(
|
||||
&mut self,
|
||||
@ -292,9 +294,11 @@ macro_rules! make_mir_visitor {
|
||||
super_body!(self, body, $($mutability, true)?);
|
||||
}
|
||||
|
||||
fn super_basic_block_data(&mut self,
|
||||
block: BasicBlock,
|
||||
data: & $($mutability)? BasicBlockData<'tcx>) {
|
||||
fn super_basic_block_data(
|
||||
&mut self,
|
||||
block: BasicBlock,
|
||||
data: & $($mutability)? BasicBlockData<'tcx>)
|
||||
{
|
||||
let BasicBlockData {
|
||||
statements,
|
||||
terminator,
|
||||
@ -339,24 +343,24 @@ macro_rules! make_mir_visitor {
|
||||
match callee_def {
|
||||
ty::InstanceKind::Item(_def_id) => {}
|
||||
|
||||
ty::InstanceKind::Intrinsic(_def_id) |
|
||||
ty::InstanceKind::VTableShim(_def_id) |
|
||||
ty::InstanceKind::ReifyShim(_def_id, _) |
|
||||
ty::InstanceKind::Virtual(_def_id, _) |
|
||||
ty::InstanceKind::ThreadLocalShim(_def_id) |
|
||||
ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
|
||||
ty::InstanceKind::ConstructCoroutineInClosureShim {
|
||||
ty::InstanceKind::Intrinsic(_def_id)
|
||||
| ty::InstanceKind::VTableShim(_def_id)
|
||||
| ty::InstanceKind::ReifyShim(_def_id, _)
|
||||
| ty::InstanceKind::Virtual(_def_id, _)
|
||||
| ty::InstanceKind::ThreadLocalShim(_def_id)
|
||||
| ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ }
|
||||
| ty::InstanceKind::ConstructCoroutineInClosureShim {
|
||||
coroutine_closure_def_id: _def_id,
|
||||
receiver_by_ref: _,
|
||||
} |
|
||||
ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) |
|
||||
ty::InstanceKind::DropGlue(_def_id, None) => {}
|
||||
}
|
||||
| ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None)
|
||||
| ty::InstanceKind::DropGlue(_def_id, None) => {}
|
||||
|
||||
ty::InstanceKind::FnPtrShim(_def_id, ty) |
|
||||
ty::InstanceKind::DropGlue(_def_id, Some(ty)) |
|
||||
ty::InstanceKind::CloneShim(_def_id, ty) |
|
||||
ty::InstanceKind::FnPtrAddrShim(_def_id, ty) |
|
||||
ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
|
||||
ty::InstanceKind::FnPtrShim(_def_id, ty)
|
||||
| ty::InstanceKind::DropGlue(_def_id, Some(ty))
|
||||
| ty::InstanceKind::CloneShim(_def_id, ty)
|
||||
| ty::InstanceKind::FnPtrAddrShim(_def_id, ty)
|
||||
| ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => {
|
||||
// FIXME(eddyb) use a better `TyContext` here.
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
@ -368,19 +372,16 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_statement(&mut self,
|
||||
statement: & $($mutability)? Statement<'tcx>,
|
||||
location: Location) {
|
||||
let Statement {
|
||||
source_info,
|
||||
kind,
|
||||
} = statement;
|
||||
fn super_statement(
|
||||
&mut self,
|
||||
statement: & $($mutability)? Statement<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
let Statement { source_info, kind } = statement;
|
||||
|
||||
self.visit_source_info(source_info);
|
||||
match kind {
|
||||
StatementKind::Assign(
|
||||
box (place, rvalue)
|
||||
) => {
|
||||
StatementKind::Assign(box (place, rvalue)) => {
|
||||
self.visit_assign(place, rvalue, location);
|
||||
}
|
||||
StatementKind::FakeRead(box (_, place)) => {
|
||||
@ -428,11 +429,13 @@ macro_rules! make_mir_visitor {
|
||||
location
|
||||
);
|
||||
}
|
||||
StatementKind::AscribeUserType(
|
||||
box (place, user_ty),
|
||||
variance
|
||||
) => {
|
||||
self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location);
|
||||
StatementKind::AscribeUserType(box (place, user_ty), variance) => {
|
||||
self.visit_ascribe_user_ty(
|
||||
place,
|
||||
$(& $mutability)? *variance,
|
||||
user_ty,
|
||||
location
|
||||
);
|
||||
}
|
||||
StatementKind::Coverage(coverage) => {
|
||||
self.visit_coverage(
|
||||
@ -443,7 +446,11 @@ macro_rules! make_mir_visitor {
|
||||
StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => {
|
||||
match intrinsic {
|
||||
NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location),
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => {
|
||||
NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
|
||||
src,
|
||||
dst,
|
||||
count
|
||||
}) => {
|
||||
self.visit_operand(src, location);
|
||||
self.visit_operand(dst, location);
|
||||
self.visit_operand(count, location);
|
||||
@ -456,10 +463,12 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_assign(&mut self,
|
||||
place: &$($mutability)? Place<'tcx>,
|
||||
rvalue: &$($mutability)? Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
fn super_assign(
|
||||
&mut self,
|
||||
place: &$($mutability)? Place<'tcx>,
|
||||
rvalue: &$($mutability)? Rvalue<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
self.visit_place(
|
||||
place,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
@ -468,20 +477,22 @@ macro_rules! make_mir_visitor {
|
||||
self.visit_rvalue(rvalue, location);
|
||||
}
|
||||
|
||||
fn super_terminator(&mut self,
|
||||
terminator: &$($mutability)? Terminator<'tcx>,
|
||||
location: Location) {
|
||||
fn super_terminator(
|
||||
&mut self,
|
||||
terminator: &$($mutability)? Terminator<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
let Terminator { source_info, kind } = terminator;
|
||||
|
||||
self.visit_source_info(source_info);
|
||||
match kind {
|
||||
TerminatorKind::Goto { .. } |
|
||||
TerminatorKind::UnwindResume |
|
||||
TerminatorKind::UnwindTerminate(_) |
|
||||
TerminatorKind::CoroutineDrop |
|
||||
TerminatorKind::Unreachable |
|
||||
TerminatorKind::FalseEdge { .. } |
|
||||
TerminatorKind::FalseUnwind { .. } => {}
|
||||
TerminatorKind::Goto { .. }
|
||||
| TerminatorKind::UnwindResume
|
||||
| TerminatorKind::UnwindTerminate(_)
|
||||
| TerminatorKind::CoroutineDrop
|
||||
| TerminatorKind::Unreachable
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
| TerminatorKind::FalseUnwind { .. } => {}
|
||||
|
||||
TerminatorKind::Return => {
|
||||
// `return` logically moves from the return place `_0`. Note that the place
|
||||
@ -500,19 +511,11 @@ macro_rules! make_mir_visitor {
|
||||
);
|
||||
}
|
||||
|
||||
TerminatorKind::SwitchInt {
|
||||
discr,
|
||||
targets: _
|
||||
} => {
|
||||
TerminatorKind::SwitchInt { discr, targets: _ } => {
|
||||
self.visit_operand(discr, location);
|
||||
}
|
||||
|
||||
TerminatorKind::Drop {
|
||||
place,
|
||||
target: _,
|
||||
unwind: _,
|
||||
replace: _,
|
||||
} => {
|
||||
TerminatorKind::Drop { place, target: _, unwind: _, replace: _ } => {
|
||||
self.visit_place(
|
||||
place,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Drop),
|
||||
@ -541,11 +544,7 @@ macro_rules! make_mir_visitor {
|
||||
);
|
||||
}
|
||||
|
||||
TerminatorKind::TailCall {
|
||||
func,
|
||||
args,
|
||||
fn_span,
|
||||
} => {
|
||||
TerminatorKind::TailCall { func, args, fn_span } => {
|
||||
self.visit_span($(& $mutability)? *fn_span);
|
||||
self.visit_operand(func, location);
|
||||
for arg in args {
|
||||
@ -553,23 +552,12 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
},
|
||||
|
||||
TerminatorKind::Assert {
|
||||
cond,
|
||||
expected: _,
|
||||
msg,
|
||||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => {
|
||||
self.visit_operand(cond, location);
|
||||
self.visit_assert_message(msg, location);
|
||||
}
|
||||
|
||||
TerminatorKind::Yield {
|
||||
value,
|
||||
resume: _,
|
||||
resume_arg,
|
||||
drop: _,
|
||||
} => {
|
||||
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
|
||||
self.visit_operand(value, location);
|
||||
self.visit_place(
|
||||
resume_arg,
|
||||
@ -622,9 +610,11 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_assert_message(&mut self,
|
||||
msg: & $($mutability)? AssertMessage<'tcx>,
|
||||
location: Location) {
|
||||
fn super_assert_message(
|
||||
&mut self,
|
||||
msg: & $($mutability)? AssertMessage<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
use crate::mir::AssertKind::*;
|
||||
match msg {
|
||||
BoundsCheck { len, index } => {
|
||||
@ -648,9 +638,11 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_rvalue(&mut self,
|
||||
rvalue: & $($mutability)? Rvalue<'tcx>,
|
||||
location: Location) {
|
||||
fn super_rvalue(
|
||||
&mut self,
|
||||
rvalue: & $($mutability)? Rvalue<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
match rvalue {
|
||||
Rvalue::Use(operand) => {
|
||||
self.visit_operand(operand, location);
|
||||
@ -677,6 +669,7 @@ macro_rules! make_mir_visitor {
|
||||
};
|
||||
self.visit_place(path, ctx, location);
|
||||
}
|
||||
|
||||
Rvalue::CopyForDeref(place) => {
|
||||
self.visit_place(
|
||||
place,
|
||||
@ -740,8 +733,7 @@ macro_rules! make_mir_visitor {
|
||||
AggregateKind::Array(ty) => {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
AggregateKind::Tuple => {
|
||||
}
|
||||
AggregateKind::Tuple => {}
|
||||
AggregateKind::Adt(
|
||||
_adt_def,
|
||||
_variant_index,
|
||||
@ -751,22 +743,13 @@ macro_rules! make_mir_visitor {
|
||||
) => {
|
||||
self.visit_args(args, location);
|
||||
}
|
||||
AggregateKind::Closure(
|
||||
_,
|
||||
closure_args
|
||||
) => {
|
||||
AggregateKind::Closure(_, closure_args) => {
|
||||
self.visit_args(closure_args, location);
|
||||
}
|
||||
AggregateKind::Coroutine(
|
||||
_,
|
||||
coroutine_args,
|
||||
) => {
|
||||
AggregateKind::Coroutine(_, coroutine_args) => {
|
||||
self.visit_args(coroutine_args, location);
|
||||
}
|
||||
AggregateKind::CoroutineClosure(
|
||||
_,
|
||||
coroutine_closure_args,
|
||||
) => {
|
||||
AggregateKind::CoroutineClosure(_, coroutine_closure_args) => {
|
||||
self.visit_args(coroutine_closure_args, location);
|
||||
}
|
||||
AggregateKind::RawPtr(ty, _) => {
|
||||
@ -791,9 +774,11 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_operand(&mut self,
|
||||
operand: & $($mutability)? Operand<'tcx>,
|
||||
location: Location) {
|
||||
fn super_operand(
|
||||
&mut self,
|
||||
operand: & $($mutability)? Operand<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
match operand {
|
||||
Operand::Copy(place) => {
|
||||
self.visit_place(
|
||||
@ -815,28 +800,36 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_ascribe_user_ty(&mut self,
|
||||
place: & $($mutability)? Place<'tcx>,
|
||||
variance: $(& $mutability)? ty::Variance,
|
||||
user_ty: & $($mutability)? UserTypeProjection,
|
||||
location: Location) {
|
||||
fn super_ascribe_user_ty(
|
||||
&mut self,
|
||||
place: & $($mutability)? Place<'tcx>,
|
||||
variance: $(& $mutability)? ty::Variance,
|
||||
user_ty: & $($mutability)? UserTypeProjection,
|
||||
location: Location)
|
||||
{
|
||||
self.visit_place(
|
||||
place,
|
||||
PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)),
|
||||
PlaceContext::NonUse(
|
||||
NonUseContext::AscribeUserTy($(* &$mutability *)? variance)
|
||||
),
|
||||
location
|
||||
);
|
||||
self.visit_user_type_projection(user_ty);
|
||||
}
|
||||
|
||||
fn super_coverage(&mut self,
|
||||
_kind: & $($mutability)? coverage::CoverageKind,
|
||||
_location: Location) {
|
||||
fn super_coverage(
|
||||
&mut self,
|
||||
_kind: & $($mutability)? coverage::CoverageKind,
|
||||
_location: Location
|
||||
) {
|
||||
}
|
||||
|
||||
fn super_retag(&mut self,
|
||||
_kind: $(& $mutability)? RetagKind,
|
||||
place: & $($mutability)? Place<'tcx>,
|
||||
location: Location) {
|
||||
fn super_retag(
|
||||
&mut self,
|
||||
_kind: $(& $mutability)? RetagKind,
|
||||
place: & $($mutability)? Place<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
self.visit_place(
|
||||
place,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Retag),
|
||||
@ -844,9 +837,11 @@ macro_rules! make_mir_visitor {
|
||||
);
|
||||
}
|
||||
|
||||
fn super_local_decl(&mut self,
|
||||
local: Local,
|
||||
local_decl: & $($mutability)? LocalDecl<'tcx>) {
|
||||
fn super_local_decl(
|
||||
&mut self,
|
||||
local: Local,
|
||||
local_decl: & $($mutability)? LocalDecl<'tcx>
|
||||
) {
|
||||
let LocalDecl {
|
||||
mutability: _,
|
||||
ty,
|
||||
@ -868,6 +863,14 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_local(
|
||||
&mut self,
|
||||
_local: $(& $mutability)? Local,
|
||||
_context: PlaceContext,
|
||||
_location: Location,
|
||||
) {
|
||||
}
|
||||
|
||||
fn super_var_debug_info(
|
||||
&mut self,
|
||||
var_debug_info: & $($mutability)? VarDebugInfo<'tcx>
|
||||
@ -882,7 +885,10 @@ macro_rules! make_mir_visitor {
|
||||
|
||||
self.visit_source_info(source_info);
|
||||
let location = Location::START;
|
||||
if let Some(box VarDebugInfoFragment { ref $($mutability)? ty, ref $($mutability)? projection }) = composite {
|
||||
if let Some(box VarDebugInfoFragment {
|
||||
ref $($mutability)? ty,
|
||||
ref $($mutability)? projection
|
||||
}) = composite {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
for elem in projection {
|
||||
let ProjectionElem::Field(_, ty) = elem else { bug!() };
|
||||
@ -900,10 +906,7 @@ macro_rules! make_mir_visitor {
|
||||
}
|
||||
}
|
||||
|
||||
fn super_source_scope(
|
||||
&mut self,
|
||||
_scope: $(& $mutability)? SourceScope
|
||||
) {}
|
||||
fn super_source_scope(&mut self, _scope: $(& $mutability)? SourceScope) {}
|
||||
|
||||
fn super_const_operand(
|
||||
&mut self,
|
||||
@ -919,8 +922,12 @@ macro_rules! make_mir_visitor {
|
||||
self.visit_span($(& $mutability)? *span);
|
||||
match const_ {
|
||||
Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location),
|
||||
Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||
Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
|
||||
Const::Val(_, ty) => {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
Const::Unevaluated(_, ty) => {
|
||||
self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -929,27 +936,18 @@ macro_rules! make_mir_visitor {
|
||||
_ct: $(& $mutability)? ty::Const<'tcx>,
|
||||
_location: Location,
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
fn super_span(&mut self, _span: $(& $mutability)? Span) {
|
||||
}
|
||||
fn super_span(&mut self, _span: $(& $mutability)? Span) {}
|
||||
|
||||
fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) {
|
||||
let SourceInfo {
|
||||
span,
|
||||
scope,
|
||||
} = source_info;
|
||||
let SourceInfo { span, scope } = source_info;
|
||||
|
||||
self.visit_span($(& $mutability)? *span);
|
||||
self.visit_source_scope($(& $mutability)? *scope);
|
||||
}
|
||||
|
||||
fn super_user_type_projection(
|
||||
&mut self,
|
||||
_ty: & $($mutability)? UserTypeProjection,
|
||||
) {
|
||||
}
|
||||
fn super_user_type_projection(&mut self, _ty: & $($mutability)? UserTypeProjection) {}
|
||||
|
||||
fn super_user_type_annotation(
|
||||
&mut self,
|
||||
@ -960,14 +958,11 @@ macro_rules! make_mir_visitor {
|
||||
self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span));
|
||||
}
|
||||
|
||||
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {
|
||||
}
|
||||
fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {}
|
||||
|
||||
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {
|
||||
}
|
||||
fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {}
|
||||
|
||||
fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {
|
||||
}
|
||||
fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {}
|
||||
|
||||
// Convenience methods
|
||||
|
||||
@ -976,7 +971,8 @@ macro_rules! make_mir_visitor {
|
||||
body: &$($mutability)? Body<'tcx>,
|
||||
location: Location
|
||||
) {
|
||||
let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block];
|
||||
let basic_block =
|
||||
& $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block];
|
||||
if basic_block.statements.len() == location.statement_index {
|
||||
if let Some(ref $($mutability)? terminator) = basic_block.terminator {
|
||||
self.visit_terminator(terminator, location)
|
||||
@ -1255,28 +1251,6 @@ macro_rules! visit_place_fns {
|
||||
make_mir_visitor!(Visitor,);
|
||||
make_mir_visitor!(MutVisitor, mut);
|
||||
|
||||
pub trait MirVisitable<'tcx> {
|
||||
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>);
|
||||
}
|
||||
|
||||
impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> {
|
||||
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
||||
visitor.visit_statement(self, location)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> {
|
||||
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
||||
visitor.visit_terminator(self, location)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> {
|
||||
fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) {
|
||||
visitor.visit_terminator(self.as_ref().unwrap(), location)
|
||||
}
|
||||
}
|
||||
|
||||
/// Extra information passed to `visit_ty` and friends to give context
|
||||
/// about where the type etc appears.
|
||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||
|
@ -1,9 +1,9 @@
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_type_ir as ir;
|
||||
pub use rustc_type_ir::solve::*;
|
||||
|
||||
use crate::ty::visit::try_visit;
|
||||
use crate::ty::{
|
||||
self, FallibleTypeFolder, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
|
||||
};
|
||||
|
@ -6,8 +6,6 @@ use std::mem;
|
||||
use std::num::NonZero;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_ast_ir::walk_visitable_list;
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_errors::{DiagArgValue, IntoDiagArg};
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -18,7 +16,7 @@ use smallvec::SmallVec;
|
||||
|
||||
use crate::ty::codec::{TyDecoder, TyEncoder};
|
||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
|
||||
use crate::ty::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::ty::visit::{TypeVisitable, TypeVisitor, VisitorResult, walk_visitable_list};
|
||||
use crate::ty::{
|
||||
self, ClosureArgs, CoroutineArgs, CoroutineClosureArgs, InlineConstArgs, Lift, List, Ty, TyCtxt,
|
||||
};
|
||||
|
@ -27,7 +27,6 @@ pub use intrinsic::IntrinsicDef;
|
||||
use rustc_abi::{Align, FieldIdx, Integer, IntegerType, ReprFlags, ReprOptions, VariantIdx};
|
||||
use rustc_ast::expand::StrippedCfgItem;
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
pub use rustc_ast_ir::{Movability, Mutability, try_visit};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
|
||||
use rustc_data_structures::intern::Interned;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
@ -48,7 +47,7 @@ pub use rustc_session::lint::RegisteredTools;
|
||||
use rustc_span::hygiene::MacroKind;
|
||||
use rustc_span::{ExpnId, ExpnKind, Ident, Span, Symbol, kw, sym};
|
||||
pub use rustc_type_ir::relate::VarianceDiagInfo;
|
||||
pub use rustc_type_ir::*;
|
||||
pub use rustc_type_ir::{Movability, Mutability, *};
|
||||
use tracing::{debug, instrument};
|
||||
pub use vtable::*;
|
||||
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
|
||||
|
@ -7,13 +7,12 @@ use std::fmt::{self, Debug};
|
||||
|
||||
use rustc_abi::TyAndLayout;
|
||||
use rustc_ast::InlineAsmTemplatePiece;
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::source_map::Spanned;
|
||||
use rustc_type_ir::ConstKind;
|
||||
use rustc_type_ir::visit::{VisitorResult, try_visit};
|
||||
|
||||
use super::print::PrettyPrinter;
|
||||
use super::{GenericArg, GenericArgKind, Pattern, Region};
|
||||
|
@ -2,7 +2,7 @@ use std::ops::ControlFlow;
|
||||
|
||||
use rustc_data_structures::fx::FxIndexSet;
|
||||
use rustc_type_ir::fold::TypeFoldable;
|
||||
pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
|
||||
pub use rustc_type_ir::visit::*;
|
||||
|
||||
use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
//! This module ensures that if a function's ABI requires a particular target feature,
|
||||
//! that target feature is enabled both on the callee and all callers.
|
||||
use rustc_abi::{BackendRepr, RegKind};
|
||||
use rustc_abi::{BackendRepr, ExternAbi, RegKind};
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_middle::mir::{self, traversal};
|
||||
use rustc_middle::ty::inherent::*;
|
||||
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
|
||||
use rustc_session::lint::builtin::ABI_UNSUPPORTED_VECTOR_TYPES;
|
||||
use rustc_span::def_id::DefId;
|
||||
@ -97,7 +96,7 @@ fn check_call_site_abi<'tcx>(
|
||||
span: Span,
|
||||
caller: InstanceKind<'tcx>,
|
||||
) {
|
||||
if callee.fn_sig(tcx).abi().is_rust() {
|
||||
if callee.fn_sig(tcx).abi() == ExternAbi::Rust {
|
||||
// "Rust" ABI never passes arguments in vector registers.
|
||||
return;
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ edition = "2021"
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
derive-where = "1.2.7"
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false }
|
||||
rustc_data_structures = { path = "../rustc_data_structures", optional = true }
|
||||
rustc_index = { path = "../rustc_index", default-features = false }
|
||||
rustc_macros = { path = "../rustc_macros", optional = true }
|
||||
@ -22,7 +21,6 @@ nightly = [
|
||||
"dep:rustc_data_structures",
|
||||
"dep:rustc_macros",
|
||||
"dep:rustc_serialize",
|
||||
"rustc_ast_ir/nightly",
|
||||
"rustc_index/nightly",
|
||||
"rustc_type_ir/nightly",
|
||||
]
|
||||
|
@ -2,12 +2,11 @@
|
||||
//! traits, `Copy`/`Clone`.
|
||||
|
||||
use derive_where::derive_where;
|
||||
use rustc_ast_ir::{Movability, Mutability};
|
||||
use rustc_type_ir::data_structures::HashMap;
|
||||
use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
|
||||
use rustc_type_ir::{self as ty, Interner, Movability, Mutability, Upcast as _, elaborate};
|
||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
||||
use tracing::instrument;
|
||||
|
||||
|
@ -1,13 +1,14 @@
|
||||
//! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
|
||||
|
||||
use rustc_ast_ir::Movability;
|
||||
use rustc_type_ir::data_structures::IndexSet;
|
||||
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::solve::CanonicalResponse;
|
||||
use rustc_type_ir::visit::TypeVisitableExt as _;
|
||||
use rustc_type_ir::{self as ty, Interner, TraitPredicate, TypingMode, Upcast as _, elaborate};
|
||||
use rustc_type_ir::{
|
||||
self as ty, Interner, Movability, TraitPredicate, TypingMode, Upcast as _, elaborate,
|
||||
};
|
||||
use tracing::{instrument, trace};
|
||||
|
||||
use crate::delegate::SolverDelegate;
|
||||
|
@ -301,13 +301,6 @@ impl<'a> Parser<'a> {
|
||||
&mut self,
|
||||
recover: bool,
|
||||
) -> PResult<'a, (Ident, IdentIsRaw)> {
|
||||
if let TokenKind::DocComment(..) = self.prev_token.kind {
|
||||
return Err(self.dcx().create_err(DocCommentDoesNotDocumentAnything {
|
||||
span: self.prev_token.span,
|
||||
missing_comma: None,
|
||||
}));
|
||||
}
|
||||
|
||||
let valid_follow = &[
|
||||
TokenKind::Eq,
|
||||
TokenKind::Colon,
|
||||
@ -319,6 +312,15 @@ impl<'a> Parser<'a> {
|
||||
TokenKind::CloseDelim(Delimiter::Brace),
|
||||
TokenKind::CloseDelim(Delimiter::Parenthesis),
|
||||
];
|
||||
if let TokenKind::DocComment(..) = self.prev_token.kind
|
||||
&& valid_follow.contains(&self.token.kind)
|
||||
{
|
||||
let err = self.dcx().create_err(DocCommentDoesNotDocumentAnything {
|
||||
span: self.prev_token.span,
|
||||
missing_comma: None,
|
||||
});
|
||||
return Err(err);
|
||||
}
|
||||
|
||||
let mut recovered_ident = None;
|
||||
// we take this here so that the correct original token is retained in
|
||||
|
@ -289,6 +289,7 @@ symbols! {
|
||||
OsString,
|
||||
Output,
|
||||
Param,
|
||||
ParamSet,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
Path,
|
||||
@ -520,6 +521,7 @@ symbols! {
|
||||
bang,
|
||||
begin_panic,
|
||||
bench,
|
||||
bevy_ecs,
|
||||
bikeshed_guaranteed_no_drop,
|
||||
bin,
|
||||
binaryheap_iter,
|
||||
|
@ -8,7 +8,6 @@ edition = "2021"
|
||||
itertools = "0.12"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
|
@ -18,7 +18,6 @@ use rustc_middle::ty::{
|
||||
TypeFoldable, TypeFolder, TypeSuperFoldable, TypeckResults,
|
||||
};
|
||||
use rustc_span::{BytePos, DUMMY_SP, FileName, Ident, Span, sym};
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::visit::TypeVisitableExt;
|
||||
use tracing::{debug, instrument, warn};
|
||||
|
||||
@ -217,7 +216,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ClosureEraser<'a, 'tcx> {
|
||||
// `_` because then we'd end up with `Vec<_, _>`, instead of
|
||||
// `Vec<_>`.
|
||||
arg
|
||||
} else if let GenericArgKind::Type(_) = arg.kind() {
|
||||
} else if let GenericArgKind::Type(_) = arg.unpack() {
|
||||
// We don't replace lifetime or const params, only type params.
|
||||
self.new_infer().into()
|
||||
} else {
|
||||
|
@ -11,12 +11,11 @@
|
||||
|
||||
use std::assert_matches::assert_matches;
|
||||
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, NoSolution, QueryResult};
|
||||
use rustc_middle::ty::visit::{VisitorResult, try_visit};
|
||||
use rustc_middle::ty::{TyCtxt, TypeFoldable};
|
||||
use rustc_middle::{bug, ty};
|
||||
use rustc_next_trait_solver::resolve::EagerResolver;
|
||||
|
@ -6,7 +6,6 @@ edition = "2021"
|
||||
[dependencies]
|
||||
# tidy-alphabetical-start
|
||||
rustc_abi = { path = "../rustc_abi", optional = true }
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir", optional = true }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_hir = { path = "../rustc_hir", optional = true }
|
||||
rustc_infer = { path = "../rustc_infer", optional = true }
|
||||
@ -19,7 +18,6 @@ tracing = "0.1"
|
||||
[features]
|
||||
rustc = [
|
||||
"dep:rustc_abi",
|
||||
"dep:rustc_ast_ir",
|
||||
"dep:rustc_hir",
|
||||
"dep:rustc_infer",
|
||||
"dep:rustc_macros",
|
||||
|
@ -7,7 +7,6 @@ edition = "2021"
|
||||
# tidy-alphabetical-start
|
||||
itertools = "0.12"
|
||||
rustc_abi = { path = "../rustc_abi" }
|
||||
rustc_ast_ir = { path = "../rustc_ast_ir" }
|
||||
rustc_data_structures = { path = "../rustc_data_structures" }
|
||||
rustc_errors = { path = "../rustc_errors" }
|
||||
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
|
||||
|
@ -1,11 +1,10 @@
|
||||
//! This module contains helpers for walking all types of
|
||||
//! a signature, while preserving spans as much as possible
|
||||
|
||||
use rustc_ast_ir::try_visit;
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_middle::span_bug;
|
||||
use rustc_middle::ty::visit::{VisitorResult, try_visit};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::visit::TypeVisitable;
|
||||
|
@ -74,6 +74,7 @@ pub use opaque_ty::*;
|
||||
pub use predicate::*;
|
||||
pub use predicate_kind::*;
|
||||
pub use region_kind::*;
|
||||
pub use rustc_ast_ir::{Movability, Mutability, Pinnedness};
|
||||
pub use ty_info::*;
|
||||
pub use ty_kind::*;
|
||||
pub use upcast::*;
|
||||
|
@ -45,8 +45,8 @@ use std::fmt;
|
||||
use std::ops::ControlFlow;
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_ast_ir::visit::VisitorResult;
|
||||
use rustc_ast_ir::{try_visit, walk_visitable_list};
|
||||
pub use rustc_ast_ir::visit::VisitorResult;
|
||||
pub use rustc_ast_ir::{try_visit, walk_visitable_list};
|
||||
use rustc_index::{Idx, IndexVec};
|
||||
use smallvec::SmallVec;
|
||||
use thin_vec::ThinVec;
|
||||
@ -224,6 +224,13 @@ impl<I: Interner, T: TypeVisitable<I>, Ix: Idx> TypeVisitable<I> for IndexVec<Ix
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, T: TypeVisitable<I>, S> TypeVisitable<I> for indexmap::IndexSet<T, S> {
|
||||
fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result {
|
||||
walk_visitable_list!(visitor, self.iter());
|
||||
V::Result::output()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Flags {
|
||||
fn flags(&self) -> TypeFlags;
|
||||
fn outer_exclusive_binder(&self) -> ty::DebruijnIndex;
|
||||
|
@ -45,12 +45,12 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok
|
||||
s.add_bounds(synstructure::AddBounds::Fields);
|
||||
let body_visit = s.each(|bind| {
|
||||
quote! {
|
||||
match ::rustc_ast_ir::visit::VisitorResult::branch(
|
||||
match ::rustc_type_ir::visit::VisitorResult::branch(
|
||||
::rustc_type_ir::visit::TypeVisitable::visit_with(#bind, __visitor)
|
||||
) {
|
||||
::core::ops::ControlFlow::Continue(()) => {},
|
||||
::core::ops::ControlFlow::Break(r) => {
|
||||
return ::rustc_ast_ir::visit::VisitorResult::from_residual(r);
|
||||
return ::rustc_type_ir::visit::VisitorResult::from_residual(r);
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -65,7 +65,7 @@ fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::Tok
|
||||
__visitor: &mut __V
|
||||
) -> __V::Result {
|
||||
match *self { #body_visit }
|
||||
<__V::Result as ::rustc_ast_ir::visit::VisitorResult>::output()
|
||||
<__V::Result as ::rustc_type_ir::visit::VisitorResult>::output()
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -198,8 +198,6 @@ impl str {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // some bytes, in a vector
|
||||
/// let sparkle_heart = vec![240, 159, 146, 150];
|
||||
///
|
||||
@ -213,8 +211,6 @@ impl str {
|
||||
/// Incorrect bytes:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // some invalid bytes, in a vector
|
||||
/// let sparkle_heart = vec![0, 159, 146, 150];
|
||||
///
|
||||
@ -227,8 +223,6 @@ impl str {
|
||||
/// A "stack allocated string":
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // some bytes, in a stack-allocated array
|
||||
/// let sparkle_heart = [240, 159, 146, 150];
|
||||
///
|
||||
@ -237,7 +231,8 @@ impl str {
|
||||
///
|
||||
/// assert_eq!("💖", sparkle_heart);
|
||||
/// ```
|
||||
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
|
||||
#[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_diagnostic_item = "str_inherent_from_utf8"]
|
||||
pub const fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
|
||||
converts::from_utf8(v)
|
||||
@ -250,8 +245,6 @@ impl str {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // "Hello, Rust!" as a mutable vector
|
||||
/// let mut hellorust = vec![72, 101, 108, 108, 111, 44, 32, 82, 117, 115, 116, 33];
|
||||
///
|
||||
@ -264,8 +257,6 @@ impl str {
|
||||
/// Incorrect bytes:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // Some invalid bytes in a mutable vector
|
||||
/// let mut invalid = vec![128, 223];
|
||||
///
|
||||
@ -273,7 +264,7 @@ impl str {
|
||||
/// ```
|
||||
/// See the docs for [`Utf8Error`] for more details on the kinds of
|
||||
/// errors that can be returned.
|
||||
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
|
||||
#[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_unstable(feature = "const_str_from_utf8", issue = "91006")]
|
||||
#[rustc_diagnostic_item = "str_inherent_from_utf8_mut"]
|
||||
pub const fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> {
|
||||
@ -294,8 +285,6 @@ impl str {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// // some bytes, in a vector
|
||||
/// let sparkle_heart = vec![240, 159, 146, 150];
|
||||
///
|
||||
@ -307,7 +296,8 @@ impl str {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
|
||||
#[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked"]
|
||||
pub const unsafe fn from_utf8_unchecked(v: &[u8]) -> &str {
|
||||
// SAFETY: converts::from_utf8_unchecked has the same safety requirements as this function.
|
||||
@ -324,8 +314,6 @@ impl str {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(inherent_str_constructors)]
|
||||
///
|
||||
/// let mut heart = vec![240, 159, 146, 150];
|
||||
/// let heart = unsafe { str::from_utf8_unchecked_mut(&mut heart) };
|
||||
///
|
||||
@ -333,7 +321,8 @@ impl str {
|
||||
/// ```
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "inherent_str_constructors", issue = "131114")]
|
||||
#[stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "inherent_str_constructors", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_diagnostic_item = "str_inherent_from_utf8_unchecked_mut"]
|
||||
pub const unsafe fn from_utf8_unchecked_mut(v: &mut [u8]) -> &mut str {
|
||||
// SAFETY: converts::from_utf8_unchecked_mut has the same safety requirements as this function.
|
||||
|
@ -1,4 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use rinja::Template;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
@ -12,6 +13,7 @@ use crate::clean;
|
||||
use crate::formats::Impl;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::markdown::{IdMap, MarkdownWithToc};
|
||||
use crate::html::render::print_item::compare_names;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(crate) enum ModuleLike {
|
||||
@ -77,7 +79,7 @@ impl<'a> LinkBlock<'a> {
|
||||
}
|
||||
|
||||
/// A link to an item. Content should not be escaped.
|
||||
#[derive(PartialOrd, Ord, PartialEq, Eq, Hash, Clone)]
|
||||
#[derive(Ord, PartialEq, Eq, Hash, Clone)]
|
||||
pub(crate) struct Link<'a> {
|
||||
/// The content for the anchor tag and title attr
|
||||
name: Cow<'a, str>,
|
||||
@ -89,6 +91,20 @@ pub(crate) struct Link<'a> {
|
||||
children: Vec<Link<'a>>,
|
||||
}
|
||||
|
||||
impl PartialOrd for Link<'_> {
|
||||
fn partial_cmp(&self, other: &Link<'_>) -> Option<Ordering> {
|
||||
match compare_names(&self.name, &other.name) {
|
||||
Ordering::Equal => (),
|
||||
result => return Some(result),
|
||||
}
|
||||
(&self.name_html, &self.href, &self.children).partial_cmp(&(
|
||||
&other.name_html,
|
||||
&other.href,
|
||||
&other.children,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Link<'a> {
|
||||
pub fn new(href: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>) -> Self {
|
||||
Self { href: href.into(), name: name.into(), children: vec![], name_html: None }
|
||||
|
@ -0,0 +1,30 @@
|
||||
// Test that transmuting from `&dyn Trait<fn(&'static ())>` to `&dyn Trait<for<'a> fn(&'a ())>` is UB.
|
||||
//
|
||||
// The vtable of `() as Trait<fn(&'static ())>` and `() as Trait<for<'a> fn(&'a ())>` can have
|
||||
// different entries and, because in the former the entry for `foo` is vacant, this test will
|
||||
// segfault at runtime.
|
||||
|
||||
trait Trait<U> {
|
||||
fn foo(&self)
|
||||
where
|
||||
U: HigherRanked,
|
||||
{
|
||||
}
|
||||
}
|
||||
impl<T, U> Trait<U> for T {}
|
||||
|
||||
trait HigherRanked {}
|
||||
impl HigherRanked for for<'a> fn(&'a ()) {}
|
||||
|
||||
// 2nd candidate is required so that selecting `(): Trait<fn(&'static ())>` will
|
||||
// evaluate the candidates and fail the leak check instead of returning the
|
||||
// only applicable candidate.
|
||||
trait Unsatisfied {}
|
||||
impl<T: Unsatisfied> HigherRanked for T {}
|
||||
|
||||
fn main() {
|
||||
let x: &dyn Trait<fn(&'static ())> = &();
|
||||
let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
|
||||
//~^ ERROR: wrong trait in wide pointer vtable
|
||||
y.foo();
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
error: Undefined Behavior: constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>`
|
||||
--> tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC
|
||||
|
|
||||
LL | let y: &dyn Trait<for<'a> fn(&'a ())> = unsafe { std::mem::transmute(x) };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: wrong trait in wide pointer vtable: expected `Trait<for<'a> fn(&'a ())>`, but encountered `Trait<fn(&())>`
|
||||
|
|
||||
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
|
||||
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
|
||||
= note: BACKTRACE:
|
||||
= note: inside `main` at tests/fail/validity/dyn-transmute-inner-binder.rs:LL:CC
|
||||
|
||||
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -9,6 +9,7 @@ fn main() {
|
||||
drop_principal();
|
||||
modulo_binder();
|
||||
modulo_assoc();
|
||||
bidirectional_subtyping();
|
||||
}
|
||||
|
||||
fn vtable_nop_cast() {
|
||||
@ -531,3 +532,32 @@ fn modulo_assoc() {
|
||||
|
||||
(&() as &dyn Trait as &dyn Middle<()>).say_hello(&0);
|
||||
}
|
||||
|
||||
fn bidirectional_subtyping() {
|
||||
// Test that transmuting between subtypes of dyn traits is fine, even in the
|
||||
// "wrong direction", i.e. going from a lower-ranked to a higher-ranked dyn trait.
|
||||
// Note that compared to the `dyn-transmute-inner-binder` test, the `for` is on the
|
||||
// *outside* here!
|
||||
|
||||
trait Trait<U: ?Sized> {}
|
||||
impl<T, U: ?Sized> Trait<U> for T {}
|
||||
|
||||
struct Wrapper<T: ?Sized>(T);
|
||||
|
||||
let x: &dyn Trait<fn(&'static ())> = &();
|
||||
let _y: &dyn for<'a> Trait<fn(&'a ())> = unsafe { std::mem::transmute(x) };
|
||||
|
||||
let x: &dyn for<'a> Trait<fn(&'a ())> = &();
|
||||
let _y: &dyn Trait<fn(&'static ())> = unsafe { std::mem::transmute(x) };
|
||||
|
||||
let x: &dyn Trait<dyn Trait<fn(&'static ())>> = &();
|
||||
let _y: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = unsafe { std::mem::transmute(x) };
|
||||
|
||||
let x: &dyn for<'a> Trait<dyn Trait<fn(&'a ())>> = &();
|
||||
let _y: &dyn Trait<dyn Trait<fn(&'static ())>> = unsafe { std::mem::transmute(x) };
|
||||
|
||||
// This lowers to a ptr-to-ptr cast (which behaves like a transmute)
|
||||
// and not an unsizing coercion:
|
||||
let x: *const dyn for<'a> Trait<&'a ()> = &();
|
||||
let _y: *const Wrapper<dyn Trait<&'static ()>> = x as _;
|
||||
}
|
||||
|
15
tests/rustdoc-gui/sidebar-foreign-impl-sort.goml
Normal file
15
tests/rustdoc-gui/sidebar-foreign-impl-sort.goml
Normal file
@ -0,0 +1,15 @@
|
||||
// Checks sidebar resizing close the Settings popover
|
||||
go-to: "file://" + |DOC_PATH| + "/test_docs/SidebarSort/trait.Sort.html#foreign-impls"
|
||||
|
||||
// Check that the sidebar contains the expected foreign implementations
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(1)", "&'a str")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(2)", "AtomicBool")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(3)", "AtomicU8")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(4)", "AtomicU16")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(5)", "AtomicU32")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(6)", "Cell<u8>")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(7)", "Cell<u16>")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(8)", "u8")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(9)", "u16")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(10)", "u32")
|
||||
assert-text: (".sidebar-elems section ul > li:nth-child(11)", "usize")
|
@ -713,3 +713,21 @@ pub trait ItemsTrait {
|
||||
/// blablala
|
||||
fn bar();
|
||||
}
|
||||
|
||||
pub mod SidebarSort {
|
||||
use std::cell::Cell;
|
||||
use std::sync::atomic::*;
|
||||
pub trait Sort {}
|
||||
|
||||
impl Sort for u32 {}
|
||||
impl Sort for u8 {}
|
||||
impl Sort for u16 {}
|
||||
impl Sort for usize {}
|
||||
impl Sort for AtomicU32 {}
|
||||
impl Sort for AtomicU16 {}
|
||||
impl Sort for AtomicU8 {}
|
||||
impl Sort for AtomicBool {}
|
||||
impl Sort for Cell<u16> {}
|
||||
impl Sort for Cell<u8> {}
|
||||
impl<'a> Sort for &'a str {}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#![crate_name = "bevy_ecs"]
|
||||
|
||||
//@ check-pass
|
||||
|
||||
// We currently special case bevy from erroring on incorrect implied bounds
|
||||
|
@ -1,7 +1,6 @@
|
||||
//@ check-pass
|
||||
|
||||
#![feature(concat_bytes)]
|
||||
#![feature(inherent_str_constructors)]
|
||||
#![warn(invalid_from_utf8_unchecked)]
|
||||
#![warn(invalid_from_utf8)]
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:22:9
|
||||
--> $DIR/invalid_from_utf8.rs:21:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -7,13 +7,13 @@ LL | std::str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/invalid_from_utf8.rs:5:9
|
||||
--> $DIR/invalid_from_utf8.rs:4:9
|
||||
|
|
||||
LL | #![warn(invalid_from_utf8_unchecked)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:24:9
|
||||
--> $DIR/invalid_from_utf8.rs:23:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -21,7 +21,7 @@ LL | str::from_utf8_unchecked_mut(&mut [99, 108, 130, 105, 112, 112, 121
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:26:9
|
||||
--> $DIR/invalid_from_utf8.rs:25:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -29,7 +29,7 @@ LL | std::str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i',
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked_mut` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:28:9
|
||||
--> $DIR/invalid_from_utf8.rs:27:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -37,7 +37,7 @@ LL | str::from_utf8_unchecked_mut(&mut [b'c', b'l', b'\x82', b'i', b'p',
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:50:9
|
||||
--> $DIR/invalid_from_utf8.rs:49:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -45,7 +45,7 @@ LL | std::str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:52:9
|
||||
--> $DIR/invalid_from_utf8.rs:51:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -53,7 +53,7 @@ LL | str::from_utf8_unchecked(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:54:9
|
||||
--> $DIR/invalid_from_utf8.rs:53:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -61,7 +61,7 @@ LL | std::str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:56:9
|
||||
--> $DIR/invalid_from_utf8.rs:55:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -69,7 +69,7 @@ LL | str::from_utf8_unchecked(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:58:9
|
||||
--> $DIR/invalid_from_utf8.rs:57:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked(b"cl\x82ippy");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^
|
||||
@ -77,7 +77,7 @@ LL | std::str::from_utf8_unchecked(b"cl\x82ippy");
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:60:9
|
||||
--> $DIR/invalid_from_utf8.rs:59:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked(b"cl\x82ippy");
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^-------------^
|
||||
@ -85,7 +85,7 @@ LL | str::from_utf8_unchecked(b"cl\x82ippy");
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:62:9
|
||||
--> $DIR/invalid_from_utf8.rs:61:9
|
||||
|
|
||||
LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^
|
||||
@ -93,7 +93,7 @@ LL | std::str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_unchecked` with an invalid literal are undefined behavior
|
||||
--> $DIR/invalid_from_utf8.rs:64:9
|
||||
--> $DIR/invalid_from_utf8.rs:63:9
|
||||
|
|
||||
LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------^
|
||||
@ -101,7 +101,7 @@ LL | str::from_utf8_unchecked(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:84:9
|
||||
--> $DIR/invalid_from_utf8.rs:83:9
|
||||
|
|
||||
LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -109,13 +109,13 @@ LL | std::str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/invalid_from_utf8.rs:6:9
|
||||
--> $DIR/invalid_from_utf8.rs:5:9
|
||||
|
|
||||
LL | #![warn(invalid_from_utf8)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:86:9
|
||||
--> $DIR/invalid_from_utf8.rs:85:9
|
||||
|
|
||||
LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -123,7 +123,7 @@ LL | str::from_utf8_mut(&mut [99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:88:9
|
||||
--> $DIR/invalid_from_utf8.rs:87:9
|
||||
|
|
||||
LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -131,7 +131,7 @@ LL | std::str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p'
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:90:9
|
||||
--> $DIR/invalid_from_utf8.rs:89:9
|
||||
|
|
||||
LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -139,7 +139,7 @@ LL | str::from_utf8_mut(&mut [b'c', b'l', b'\x82', b'i', b'p', b'p', b'y
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:112:9
|
||||
--> $DIR/invalid_from_utf8.rs:111:9
|
||||
|
|
||||
LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -147,7 +147,7 @@ LL | std::str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:114:9
|
||||
--> $DIR/invalid_from_utf8.rs:113:9
|
||||
|
|
||||
LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| ^^^^^^^^^^^^^^^^----------------------------------^
|
||||
@ -155,7 +155,7 @@ LL | str::from_utf8(&[99, 108, 130, 105, 112, 112, 121]);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:116:9
|
||||
--> $DIR/invalid_from_utf8.rs:115:9
|
||||
|
|
||||
LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -163,7 +163,7 @@ LL | std::str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y'])
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:118:9
|
||||
--> $DIR/invalid_from_utf8.rs:117:9
|
||||
|
|
||||
LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| ^^^^^^^^^^^^^^^^---------------------------------------------^
|
||||
@ -171,7 +171,7 @@ LL | str::from_utf8(&[b'c', b'l', b'\x82', b'i', b'p', b'p', b'y']);
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:120:9
|
||||
--> $DIR/invalid_from_utf8.rs:119:9
|
||||
|
|
||||
LL | std::str::from_utf8(b"cl\x82ippy");
|
||||
| ^^^^^^^^^^^^^^^^^^^^-------------^
|
||||
@ -179,7 +179,7 @@ LL | std::str::from_utf8(b"cl\x82ippy");
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:122:9
|
||||
--> $DIR/invalid_from_utf8.rs:121:9
|
||||
|
|
||||
LL | str::from_utf8(b"cl\x82ippy");
|
||||
| ^^^^^^^^^^^^^^^-------------^
|
||||
@ -187,7 +187,7 @@ LL | str::from_utf8(b"cl\x82ippy");
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:124:9
|
||||
--> $DIR/invalid_from_utf8.rs:123:9
|
||||
|
|
||||
LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| ^^^^^^^^^^^^^^^^^^^^---------------------------------^
|
||||
@ -195,7 +195,7 @@ LL | std::str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:126:9
|
||||
--> $DIR/invalid_from_utf8.rs:125:9
|
||||
|
|
||||
LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| ^^^^^^^^^^^^^^^---------------------------------^
|
||||
@ -203,7 +203,7 @@ LL | str::from_utf8(concat_bytes!(b"cl", b"\x82ippy"));
|
||||
| the literal was valid UTF-8 up to the 2 bytes
|
||||
|
||||
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:133:5
|
||||
--> $DIR/invalid_from_utf8.rs:132:5
|
||||
|
|
||||
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -211,7 +211,7 @@ LL | std::str::from_utf8_mut(&mut a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:135:5
|
||||
--> $DIR/invalid_from_utf8.rs:134:5
|
||||
|
|
||||
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -220,7 +220,7 @@ LL | str::from_utf8_mut(&mut a);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:139:5
|
||||
--> $DIR/invalid_from_utf8.rs:138:5
|
||||
|
|
||||
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -229,7 +229,7 @@ LL | std::str::from_utf8_mut(c);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8_mut` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:141:5
|
||||
--> $DIR/invalid_from_utf8.rs:140:5
|
||||
|
|
||||
LL | let mut a = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -238,7 +238,7 @@ LL | str::from_utf8_mut(c);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:144:5
|
||||
--> $DIR/invalid_from_utf8.rs:143:5
|
||||
|
|
||||
LL | let mut c = &[99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -246,7 +246,7 @@ LL | std::str::from_utf8(c);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:146:5
|
||||
--> $DIR/invalid_from_utf8.rs:145:5
|
||||
|
|
||||
LL | let mut c = &[99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -255,7 +255,7 @@ LL | str::from_utf8(c);
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:149:5
|
||||
--> $DIR/invalid_from_utf8.rs:148:5
|
||||
|
|
||||
LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -263,7 +263,7 @@ LL | std::str::from_utf8(&INVALID_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:151:5
|
||||
--> $DIR/invalid_from_utf8.rs:150:5
|
||||
|
|
||||
LL | const INVALID_1: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -272,7 +272,7 @@ LL | str::from_utf8(&INVALID_1);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:154:5
|
||||
--> $DIR/invalid_from_utf8.rs:153:5
|
||||
|
|
||||
LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -280,7 +280,7 @@ LL | std::str::from_utf8(&INVALID_2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:156:5
|
||||
--> $DIR/invalid_from_utf8.rs:155:5
|
||||
|
|
||||
LL | static INVALID_2: [u8; 7] = [99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -289,7 +289,7 @@ LL | str::from_utf8(&INVALID_2);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:159:5
|
||||
--> $DIR/invalid_from_utf8.rs:158:5
|
||||
|
|
||||
LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -297,7 +297,7 @@ LL | std::str::from_utf8(INVALID_3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:161:5
|
||||
--> $DIR/invalid_from_utf8.rs:160:5
|
||||
|
|
||||
LL | const INVALID_3: &'static [u8; 7] = &[99, 108, 130, 105, 112, 112, 121];
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -306,7 +306,7 @@ LL | str::from_utf8(INVALID_3);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `std::str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:164:5
|
||||
--> $DIR/invalid_from_utf8.rs:163:5
|
||||
|
|
||||
LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] };
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
@ -314,7 +314,7 @@ LL | std::str::from_utf8(INVALID_4);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: calls to `str::from_utf8` with an invalid literal always return an error
|
||||
--> $DIR/invalid_from_utf8.rs:166:5
|
||||
--> $DIR/invalid_from_utf8.rs:165:5
|
||||
|
|
||||
LL | const INVALID_4: &'static [u8; 7] = { &[99, 108, 130, 105, 112, 112, 121] };
|
||||
| ---------------------------------- the literal was valid UTF-8 up to the 2 bytes
|
||||
|
6
tests/ui/parser/doc-before-bad-variant.rs
Normal file
6
tests/ui/parser/doc-before-bad-variant.rs
Normal file
@ -0,0 +1,6 @@
|
||||
enum TestEnum {
|
||||
Works,
|
||||
/// Some documentation
|
||||
Self, //~ ERROR expected identifier, found keyword `Self`
|
||||
//~^ HELP enum variants can be
|
||||
}
|
13
tests/ui/parser/doc-before-bad-variant.stderr
Normal file
13
tests/ui/parser/doc-before-bad-variant.stderr
Normal file
@ -0,0 +1,13 @@
|
||||
error: expected identifier, found keyword `Self`
|
||||
--> $DIR/doc-before-bad-variant.rs:4:5
|
||||
|
|
||||
LL | enum TestEnum {
|
||||
| -------- while parsing this enum
|
||||
...
|
||||
LL | Self,
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
|
||||
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
2
tests/ui/parser/doc-before-syntax-error.rs
Normal file
2
tests/ui/parser/doc-before-syntax-error.rs
Normal file
@ -0,0 +1,2 @@
|
||||
/// Some documentation
|
||||
<> //~ ERROR expected identifier
|
8
tests/ui/parser/doc-before-syntax-error.stderr
Normal file
8
tests/ui/parser/doc-before-syntax-error.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: expected identifier, found `<`
|
||||
--> $DIR/doc-before-syntax-error.rs:2:1
|
||||
|
|
||||
LL | <>
|
||||
| ^ expected identifier
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -244,4 +244,10 @@ fn main() {
|
||||
let &[migration_lint_macros::bind_ref!(a)] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
// Test that we use the correct span when labeling a `&` whose subpattern is from an expansion.
|
||||
let &[&migration_lint_macros::bind_ref!(a)] = &[&0];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
}
|
||||
|
@ -244,4 +244,10 @@ fn main() {
|
||||
let [migration_lint_macros::bind_ref!(a)] = &[0];
|
||||
//~^ ERROR: binding modifiers may only be written when the default binding mode is `move`
|
||||
assert_type_eq(a, &0u32);
|
||||
|
||||
// Test that we use the correct span when labeling a `&` whose subpattern is from an expansion.
|
||||
let [&migration_lint_macros::bind_ref!(a)] = &[&0];
|
||||
//~^ ERROR: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
//~| WARN: this changes meaning in Rust 2024
|
||||
assert_type_eq(a, &0u32);
|
||||
}
|
||||
|
@ -580,5 +580,23 @@ help: make the implied reference pattern explicit
|
||||
LL | let &[migration_lint_macros::bind_ref!(a)] = &[0];
|
||||
| +
|
||||
|
||||
error: aborting due to 30 previous errors
|
||||
error: reference patterns may only be written when the default binding mode is `move` in Rust 2024
|
||||
--> $DIR/migration_lint.rs:249:10
|
||||
|
|
||||
LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0];
|
||||
| ^ reference pattern not allowed under `ref` default binding mode
|
||||
|
|
||||
= warning: this changes meaning in Rust 2024
|
||||
= note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/match-ergonomics.html>
|
||||
note: matching on a reference type with a non-reference pattern changes the default binding mode
|
||||
--> $DIR/migration_lint.rs:249:9
|
||||
|
|
||||
LL | let [&migration_lint_macros::bind_ref!(a)] = &[&0];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this matches on type `&_`
|
||||
help: make the implied reference pattern explicit
|
||||
|
|
||||
LL | let &[&migration_lint_macros::bind_ref!(a)] = &[&0];
|
||||
| +
|
||||
|
||||
error: aborting due to 31 previous errors
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user