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:
bors 2025-02-20 02:39:28 +00:00
commit 6d3c050de8
55 changed files with 506 additions and 405 deletions

View File

@ -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",

View File

@ -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))]

View File

@ -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> {

View File

@ -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

View File

@ -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.

View File

@ -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 });
}
}

View File

@ -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 {

View File

@ -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" }

View File

@ -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;

View File

@ -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" }

View File

@ -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;

View File

@ -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),
],

View File

@ -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()
}
},
)

View File

@ -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

View File

@ -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()
}
}
)+

View File

@ -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 {

View File

@ -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 {

View File

@ -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)]

View File

@ -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,
};

View File

@ -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,
};

View File

@ -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};

View File

@ -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};

View File

@ -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};

View File

@ -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;
}

View File

@ -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",
]

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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" }

View File

@ -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 {

View File

@ -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;

View File

@ -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",

View File

@ -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" }

View File

@ -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;

View File

@ -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::*;

View File

@ -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;

View File

@ -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()
}
},
)

View File

@ -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.

View File

@ -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 }

View File

@ -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();
}

View File

@ -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

View File

@ -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 _;
}

View 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")

View File

@ -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 {}
}

View File

@ -1,3 +1,5 @@
#![crate_name = "bevy_ecs"]
//@ check-pass
// We currently special case bevy from erroring on incorrect implied bounds

View File

@ -1,7 +1,6 @@
//@ check-pass
#![feature(concat_bytes)]
#![feature(inherent_str_constructors)]
#![warn(invalid_from_utf8_unchecked)]
#![warn(invalid_from_utf8)]

View File

@ -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

View File

@ -0,0 +1,6 @@
enum TestEnum {
Works,
/// Some documentation
Self, //~ ERROR expected identifier, found keyword `Self`
//~^ HELP enum variants can be
}

View 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

View File

@ -0,0 +1,2 @@
/// Some documentation
<> //~ ERROR expected identifier

View 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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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