Auto merge of #141605 - jieyouxu:rollup-3gjqh5l, r=jieyouxu

Rollup of 10 pull requests

Successful merges:

 - rust-lang/rust#140898 (minor improvements on running miri)
 - rust-lang/rust#141392 (Avoid obligation construction dance with query region constraints)
 - rust-lang/rust#141431 (Emit dummy open drop for unsafe binder)
 - rust-lang/rust#141433 (Properly analyze captures from unsafe binders)
 - rust-lang/rust#141439 (Deduplicate dyn compatibility violations due to coercion)
 - rust-lang/rust#141449 (further deduplicate ast visitor code)
 - rust-lang/rust#141513 (interpret: add allocation parameters to `AllocBytes`)
 - rust-lang/rust#141516 (speed up charsearcher for ascii chars)
 - rust-lang/rust#141526 (add a dedicated section for compiler environment variables in the unstable book)
 - rust-lang/rust#141550 (Fix `unused_braces` lint suggestion when encountering attributes)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2025-05-26 20:30:06 +00:00
commit 2805e1dc4c
117 changed files with 740 additions and 1367 deletions

View file

@ -20,7 +20,7 @@ use thin_vec::ThinVec;
use crate::ast::*;
use crate::ptr::P;
use crate::tokenstream::*;
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit};
use crate::visit::{AssocCtxt, BoundKind, FnCtxt, try_visit, visit_opt, walk_list};
pub trait ExpectOne<A: Array> {
fn expect_one(self, err: &'static str) -> A::Item;
@ -33,18 +33,6 @@ impl<A: Array> ExpectOne<A> for SmallVec<A> {
}
}
pub trait WalkItemKind {
type Ctxt;
fn walk(
&mut self,
span: Span,
id: NodeId,
visibility: &mut Visibility,
ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
);
}
pub trait MutVisitor: Sized {
// Methods in this trait have one of three forms:
//
@ -451,11 +439,6 @@ fn visit_thin_exprs<T: MutVisitor>(vis: &mut T, exprs: &mut ThinVec<P<Expr>>) {
exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_bounds<T: MutVisitor>(vis: &mut T, bounds: &mut GenericBounds, ctxt: BoundKind) {
visit_vec(bounds, |bound| vis.visit_param_bound(bound, ctxt));
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_attr_args<T: MutVisitor>(vis: &mut T, args: &mut AttrArgs) {
match args {
@ -610,12 +593,6 @@ pub fn walk_ty_pat<T: MutVisitor>(vis: &mut T, ty: &mut P<TyPat>) {
vis.visit_span(span);
}
fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
visit_safety(vis, safety);
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
visitor.visit_id(id);
@ -771,22 +748,6 @@ pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> Smal
smallvec![param]
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_defaultness<T: MutVisitor>(vis: &mut T, defaultness: &mut Defaultness) {
match defaultness {
Defaultness::Default(span) => vis.visit_span(span),
Defaultness::Final => {}
}
}
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
fn visit_polarity<T: MutVisitor>(vis: &mut T, polarity: &mut ImplPolarity) {
match polarity {
ImplPolarity::Positive => {}
ImplPolarity::Negative(span) => vis.visit_span(span),
}
}
fn walk_closure_binder<T: MutVisitor>(vis: &mut T, binder: &mut ClosureBinder) {
match binder {
ClosureBinder::NotPresent => {}
@ -1080,169 +1041,15 @@ pub fn walk_item_kind<K: WalkItemKind>(
kind.walk(span, id, visibility, ctxt, vis)
}
impl WalkItemKind for ItemKind {
type Ctxt = ();
fn walk(
&mut self,
span: Span,
id: NodeId,
visibility: &mut Visibility,
_ctxt: Self::Ctxt,
vis: &mut impl MutVisitor,
) {
match self {
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
ItemKind::Static(box StaticItem {
ident,
ty,
safety: _,
mutability: _,
expr,
define_opaque,
}) => {
vis.visit_ident(ident);
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
walk_define_opaques(vis, define_opaque);
}
ItemKind::Const(item) => {
walk_const_item(vis, item);
}
ItemKind::Fn(func) => {
vis.visit_fn(FnKind::Fn(FnCtxt::Free, visibility, &mut *func), span, id);
}
ItemKind::Mod(safety, ident, mod_kind) => {
visit_safety(vis, safety);
vis.visit_ident(ident);
match mod_kind {
ModKind::Loaded(
items,
_inline,
ModSpans { inner_span, inject_use_span },
_,
) => {
items.flat_map_in_place(|item| vis.flat_map_item(item));
vis.visit_span(inner_span);
vis.visit_span(inject_use_span);
}
ModKind::Unloaded => {}
}
}
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
where_clauses,
bounds,
ty,
}) => {
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
visit_opt(ty, |ty| vis.visit_ty(ty));
walk_ty_alias_where_clauses(vis, where_clauses);
}
ItemKind::Enum(ident, EnumDef { variants }, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
}
ItemKind::Struct(ident, variant_data, generics)
| ItemKind::Union(ident, variant_data, generics) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
vis.visit_variant_data(variant_data);
}
ItemKind::Impl(box Impl {
defaultness,
safety,
generics,
constness,
polarity,
of_trait,
self_ty,
items,
}) => {
visit_defaultness(vis, defaultness);
visit_safety(vis, safety);
vis.visit_generics(generics);
visit_constness(vis, constness);
visit_polarity(vis, polarity);
visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref));
vis.visit_ty(self_ty);
items.flat_map_in_place(|item| {
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
});
}
ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
visit_safety(vis, safety);
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
items.flat_map_in_place(|item| vis.flat_map_assoc_item(item, AssocCtxt::Trait));
}
ItemKind::TraitAlias(ident, generics, bounds) => {
vis.visit_ident(ident);
vis.visit_generics(generics);
visit_bounds(vis, bounds, BoundKind::Bound);
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(ident, def) => {
vis.visit_ident(ident);
vis.visit_macro_def(def)
}
ItemKind::Delegation(box Delegation {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
}) => {
vis.visit_id(id);
vis.visit_qself(qself);
vis.visit_path(path);
vis.visit_ident(ident);
if let Some(rename) = rename {
vis.visit_ident(rename);
}
if let Some(body) = body {
vis.visit_block(body);
}
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
vis.visit_qself(qself);
vis.visit_path(prefix);
if let Some(suffixes) = suffixes {
for (ident, rename) in suffixes {
vis.visit_ident(ident);
if let Some(rename) = rename {
vis.visit_ident(rename);
}
}
}
if let Some(body) = body {
vis.visit_block(body);
}
}
}
}
}
impl WalkItemKind for AssocItemKind {
type Ctxt = AssocCtxt;
fn walk(
fn walk<V: MutVisitor>(
&mut self,
span: Span,
id: NodeId,
visibility: &mut Visibility,
ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
visitor: &mut V,
) {
match self {
AssocItemKind::Const(item) => {
@ -1306,16 +1113,6 @@ impl WalkItemKind for AssocItemKind {
}
}
fn walk_const_item<T: MutVisitor>(vis: &mut T, item: &mut ConstItem) {
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
visit_defaultness(vis, defaultness);
vis.visit_ident(ident);
vis.visit_generics(generics);
vis.visit_ty(ty);
visit_opt(expr, |expr| vis.visit_expr(expr));
walk_define_opaques(vis, define_opaque);
}
pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
let Crate { attrs, items, spans, id, is_placeholder: _ } = krate;
vis.visit_id(id);
@ -1334,19 +1131,6 @@ pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, c
walk_item_ctxt(visitor, item, ctxt)
}
fn walk_item_ctxt<K: WalkItemKind>(
visitor: &mut impl MutVisitor,
item: &mut P<Item<K>>,
ctxt: K::Ctxt,
) {
let Item { attrs, id, kind, vis, span, tokens: _ } = item.deref_mut();
visitor.visit_id(id);
visit_attrs(visitor, attrs);
visitor.visit_vis(vis);
kind.walk(*span, *id, vis, ctxt, visitor);
visitor.visit_span(span);
}
pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
vis.visit_item(&mut item);
smallvec![item]
@ -1371,13 +1155,13 @@ pub fn walk_flat_map_assoc_item(
impl WalkItemKind for ForeignItemKind {
type Ctxt = ();
fn walk(
fn walk<V: MutVisitor>(
&mut self,
span: Span,
id: NodeId,
visibility: &mut Visibility,
_ctxt: Self::Ctxt,
visitor: &mut impl MutVisitor,
visitor: &mut V,
) {
match self {
ForeignItemKind::Static(box StaticItem {
@ -1786,18 +1570,6 @@ fn walk_capture_by<T: MutVisitor>(vis: &mut T, capture_by: &mut CaptureBy) {
}
}
fn walk_define_opaques<T: MutVisitor>(
vis: &mut T,
define_opaque: &mut Option<ThinVec<(NodeId, Path)>>,
) {
if let Some(define_opaque) = define_opaque {
for (id, path) in define_opaque {
vis.visit_id(id);
vis.visit_path(path)
}
}
}
/// Some value for the AST node that is valid but possibly meaningless. Similar
/// to `Default` but not intended for wide use. The value will never be used
/// meaningfully, it exists just to support unwinding in `visit_clobber` in the

View file

@ -112,18 +112,6 @@ pub enum LifetimeCtxt {
GenericArg,
}
pub trait WalkItemKind {
type Ctxt;
fn walk<'a, V: Visitor<'a>>(
&'a self,
span: Span,
id: NodeId,
visibility: &'a Visibility,
ctxt: Self::Ctxt,
visitor: &mut V,
) -> V::Result;
}
/// Each method of the `Visitor` trait is a hook to be potentially
/// overridden. Each method's default implementation recursively visits
/// the substructure of the input via the corresponding `walk` method;
@ -141,6 +129,9 @@ pub trait Visitor<'ast>: Sized {
fn visit_ident(&mut self, _ident: &'ast Ident) -> Self::Result {
Self::Result::output()
}
fn visit_foreign_mod(&mut self, nm: &'ast ForeignMod) -> Self::Result {
walk_foreign_mod(self, nm)
}
fn visit_foreign_item(&mut self, i: &'ast ForeignItem) -> Self::Result {
walk_item(self, i)
}
@ -242,7 +233,7 @@ pub trait Visitor<'ast>: Sized {
fn visit_mac_call(&mut self, mac: &'ast MacCall) -> Self::Result {
walk_mac(self, mac)
}
fn visit_mac_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result {
fn visit_macro_def(&mut self, _mac: &'ast MacroDef, _id: NodeId) -> Self::Result {
Self::Result::output()
}
fn visit_path(&mut self, path: &'ast Path, _id: NodeId) -> Self::Result {
@ -318,6 +309,18 @@ pub trait Visitor<'ast>: Sized {
#[macro_export]
macro_rules! common_visitor_and_walkers {
($(($mut: ident))? $Visitor:ident$(<$lt:lifetime>)?) => {
pub trait WalkItemKind {
type Ctxt;
fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
&$($lt)? $($mut)? self,
span: Span,
id: NodeId,
visibility: &$($lt)? $($mut)? Visibility,
ctxt: Self::Ctxt,
visitor: &mut V,
) $(-> <V as Visitor<$lt>>::Result)?;
}
// this is only used by the MutVisitor. We include this symmetry here to make writing other functions easier
$(${ignore($lt)}
#[expect(unused, rustc::pass_by_value)]
@ -325,7 +328,7 @@ macro_rules! common_visitor_and_walkers {
)?
fn visit_span<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, span: &$($lt)? $($mut)? Span) $(-> <V as Visitor<$lt>>::Result)? {
$(
let _ = stringify!($mut);
${ignore($mut)}
visitor.visit_span(span);
)?
$(${ignore($lt)}V::Result::output())?
@ -338,7 +341,7 @@ macro_rules! common_visitor_and_walkers {
)?
fn visit_id<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, id: &$($lt)? $($mut)? NodeId) $(-> <V as Visitor<$lt>>::Result)? {
$(
let _ = stringify!($mut);
${ignore($mut)}
visitor.visit_id(id);
)?
$(${ignore($lt)}V::Result::output())?
@ -362,6 +365,27 @@ macro_rules! common_visitor_and_walkers {
}
}
fn visit_defaultness<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, defaultness: &$($lt)? $($mut)? Defaultness) $(-> <V as Visitor<$lt>>::Result)? {
match defaultness {
Defaultness::Default(span) => visit_span(vis, span),
Defaultness::Final => {
$(<V as Visitor<$lt>>::Result::output())?
}
}
}
fn visit_polarity<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, polarity: &$($lt)? $($mut)? ImplPolarity) $(-> <V as Visitor<$lt>>::Result)? {
match polarity {
ImplPolarity::Positive => { $(<V as Visitor<$lt>>::Result::output())? }
ImplPolarity::Negative(span) => visit_span(vis, span),
}
}
fn visit_bounds<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, bounds: &$($lt)? $($mut)? GenericBounds, ctxt: BoundKind) $(-> <V as Visitor<$lt>>::Result)? {
walk_list!(visitor, visit_param_bound, bounds, ctxt);
$(<V as Visitor<$lt>>::Result::output())?
}
pub fn walk_label<$($lt,)? V: $Visitor$(<$lt>)?>(visitor: &mut V, Label { ident }: &$($lt)? $($mut)? Label) $(-> <V as Visitor<$lt>>::Result)? {
visitor.visit_ident(ident)
}
@ -379,6 +403,246 @@ macro_rules! common_visitor_and_walkers {
try_visit!(visit_id(visitor, id));
visitor.visit_ident(ident)
}
fn walk_item_ctxt<$($lt,)? V: $Visitor$(<$lt>)?, K: WalkItemKind>(
visitor: &mut V,
item: &$($mut P<Item<K>>)? $($lt Item<K>)?,
ctxt: K::Ctxt,
) $(-> <V as Visitor<$lt>>::Result)? {
let Item { attrs, id, kind, vis, span, tokens: _ } = &$($mut *)? *item;
try_visit!(visit_id(visitor, id));
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
visit_span(visitor, span)
}
impl WalkItemKind for ItemKind {
type Ctxt = ();
fn walk<$($lt,)? V: $Visitor$(<$lt>)?>(
&$($lt)? $($mut)? self,
span: Span,
id: NodeId,
visibility: &$($lt)? $($mut)? Visibility,
_ctxt: Self::Ctxt,
vis: &mut V,
) $(-> <V as Visitor<$lt>>::Result)? {
match self {
ItemKind::ExternCrate(_orig_name, ident) => vis.visit_ident(ident),
// FIXME(fee1-dead): look into this weird assymetry
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree$(${ignore($lt)}, id, false)?),
ItemKind::Static(box StaticItem {
ident,
ty,
safety: _,
mutability: _,
expr,
define_opaque,
}) => {
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_ty(ty));
visit_opt!(vis, visit_expr, expr);
walk_define_opaques(vis, define_opaque)
}
ItemKind::Const(item) => {
walk_const_item(vis, item)
}
ItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Free, visibility, &$($mut)? *func);
vis.visit_fn(kind, span, id)
}
ItemKind::Mod(safety, ident, mod_kind) => {
try_visit!(visit_safety(vis, safety));
try_visit!(vis.visit_ident(ident));
match mod_kind {
ModKind::Loaded(
items,
_inline,
ModSpans { inner_span, inject_use_span },
_,
) => {
$(${ignore($mut)}
items.flat_map_in_place(|item| vis.flat_map_item(item));
)?
$(${ignore($lt)}
walk_list!(vis, visit_item, items);
)?
try_visit!(visit_span(vis, inner_span));
try_visit!(visit_span(vis, inject_use_span));
}
ModKind::Unloaded => {}
}
$(<V as Visitor<$lt>>::Result::output())?
}
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
ItemKind::TyAlias(box TyAlias {
defaultness,
ident,
generics,
$(${ignore($lt)} #[expect(unused)])?
where_clauses,
bounds,
ty,
}) => {
try_visit!(visit_defaultness(vis, defaultness));
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
visit_opt!(vis, visit_ty, ty);
$(${ignore($mut)}
walk_ty_alias_where_clauses(vis, where_clauses);
)?
$(<V as Visitor<$lt>>::Result::output())?
}
ItemKind::Enum(ident, enum_definition, generics) => {
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
$(${ignore($mut)}
enum_definition.variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
)?
$(${ignore($lt)}vis.visit_enum_def(enum_definition))?
}
ItemKind::Struct(ident, variant_data, generics)
| ItemKind::Union(ident, variant_data, generics) => {
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
vis.visit_variant_data(variant_data)
}
ItemKind::Impl(box Impl {
defaultness,
safety,
generics,
constness,
polarity,
of_trait,
self_ty,
items,
}) => {
try_visit!(visit_defaultness(vis, defaultness));
try_visit!(visit_safety(vis, safety));
try_visit!(vis.visit_generics(generics));
try_visit!(visit_constness(vis, constness));
try_visit!(visit_polarity(vis, polarity));
visit_opt!(vis, visit_trait_ref, of_trait);
try_visit!(vis.visit_ty(self_ty));
$(${ignore($mut)}
items.flat_map_in_place(|item| {
vis.flat_map_assoc_item(item, AssocCtxt::Impl { of_trait: of_trait.is_some() })
});
)?
$(${ignore($lt)}
walk_list!(
vis,
visit_assoc_item,
items,
AssocCtxt::Impl { of_trait: of_trait.is_some() }
);
<V as Visitor<$lt>>::Result::output()
)?
}
ItemKind::Trait(box Trait { safety, is_auto: _, ident, generics, bounds, items }) => {
try_visit!(visit_safety(vis, safety));
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
try_visit!(visit_bounds(vis, bounds, BoundKind::Bound));
$(${ignore($mut)}
items.flat_map_in_place(|item| {
vis.flat_map_assoc_item(item, AssocCtxt::Trait)
});
)?
$(${ignore($lt)}
walk_list!(vis, visit_assoc_item, items, AssocCtxt::Trait);
<V as Visitor<$lt>>::Result::output()
)?
}
ItemKind::TraitAlias(ident, generics, bounds) => {
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
visit_bounds(vis, bounds, BoundKind::Bound)
}
ItemKind::MacCall(m) => vis.visit_mac_call(m),
ItemKind::MacroDef(ident, def) => {
try_visit!(vis.visit_ident(ident));
// FIXME(fee1-dead) assymetry
vis.visit_macro_def(def$(${ignore($lt)}, id)?)
}
ItemKind::Delegation(box Delegation {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
}) => {
try_visit!(visit_id(vis, id));
try_visit!(vis.visit_qself(qself));
try_visit!(vis.visit_path(path$(${ignore($lt)}, *id)?));
try_visit!(vis.visit_ident(ident));
if let Some(rename) = rename {
try_visit!(vis.visit_ident(rename));
}
if let Some(body) = body {
try_visit!(vis.visit_block(body));
}
$(<V as Visitor<$lt>>::Result::output())?
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
try_visit!(vis.visit_qself(qself));
try_visit!(vis.visit_path(prefix$(${ignore($lt)}, id)?));
if let Some(suffixes) = suffixes {
for (ident, rename) in suffixes {
try_visit!(vis.visit_ident(ident));
if let Some(rename) = rename {
try_visit!(vis.visit_ident(rename));
}
}
}
if let Some(body) = body {
try_visit!(vis.visit_block(body));
}
$(<V as Visitor<$lt>>::Result::output())?
}
}
}
}
fn walk_const_item<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, item: &$($lt)? $($mut)? ConstItem) $(-> <V as Visitor<$lt>>::Result)? {
let ConstItem { defaultness, ident, generics, ty, expr, define_opaque } = item;
try_visit!(visit_defaultness(vis, defaultness));
try_visit!(vis.visit_ident(ident));
try_visit!(vis.visit_generics(generics));
try_visit!(vis.visit_ty(ty));
visit_opt!(vis, visit_expr, expr);
walk_define_opaques(vis, define_opaque)
}
fn walk_foreign_mod<$($lt,)? V: $Visitor$(<$lt>)?>(vis: &mut V, foreign_mod: &$($lt)? $($mut)? ForeignMod) $(-> <V as Visitor<$lt>>::Result)? {
let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
try_visit!(visit_safety(vis, safety));
$(${ignore($mut)}
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
)?
$(
walk_list!(vis, visit_foreign_item, items);
<V as Visitor<$lt>>::Result::output()
)?
}
fn walk_define_opaques<$($lt,)? V: $Visitor$(<$lt>)?>(
visitor: &mut V,
define_opaque: &$($lt)? $($mut)? Option<ThinVec<(NodeId, Path)>>,
) $(-> <V as Visitor<$lt>>::Result)? {
if let Some(define_opaque) = define_opaque {
for (id, path) in define_opaque {
try_visit!(visit_id(visitor, id));
// FIXME(fee1-dead): look into this weird assymetry
try_visit!(visitor.visit_path(path$(${ignore($lt)}, *id)?));
}
}
$(<V as Visitor<$lt>>::Result::output())?
}
};
}
@ -417,163 +681,6 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR
visitor.visit_path(path, *ref_id)
}
impl WalkItemKind for ItemKind {
type Ctxt = ();
fn walk<'a, V: Visitor<'a>>(
&'a self,
span: Span,
id: NodeId,
vis: &'a Visibility,
_ctxt: Self::Ctxt,
visitor: &mut V,
) -> V::Result {
match self {
ItemKind::ExternCrate(_rename, ident) => try_visit!(visitor.visit_ident(ident)),
ItemKind::Use(use_tree) => try_visit!(visitor.visit_use_tree(use_tree, id, false)),
ItemKind::Static(box StaticItem {
ident,
ty,
safety: _,
mutability: _,
expr,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
ItemKind::Const(box ConstItem {
defaultness: _,
ident,
generics,
ty,
expr,
define_opaque,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_ty(ty));
visit_opt!(visitor, visit_expr, expr);
try_visit!(walk_define_opaques(visitor, define_opaque));
}
ItemKind::Fn(func) => {
let kind = FnKind::Fn(FnCtxt::Free, vis, &*func);
try_visit!(visitor.visit_fn(kind, span, id));
}
ItemKind::Mod(_unsafety, ident, mod_kind) => {
try_visit!(visitor.visit_ident(ident));
match mod_kind {
ModKind::Loaded(items, _inline, _inner_span, _) => {
walk_list!(visitor, visit_item, items);
}
ModKind::Unloaded => {}
}
}
ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
walk_list!(visitor, visit_foreign_item, items);
}
ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
ItemKind::TyAlias(box TyAlias {
generics,
ident,
bounds,
ty,
defaultness: _,
where_clauses: _,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
visit_opt!(visitor, visit_ty, ty);
}
ItemKind::Enum(ident, enum_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_enum_def(enum_definition));
}
ItemKind::Impl(box Impl {
defaultness: _,
safety: _,
generics,
constness: _,
polarity: _,
of_trait,
self_ty,
items,
}) => {
try_visit!(visitor.visit_generics(generics));
visit_opt!(visitor, visit_trait_ref, of_trait);
try_visit!(visitor.visit_ty(self_ty));
walk_list!(
visitor,
visit_assoc_item,
items,
AssocCtxt::Impl { of_trait: of_trait.is_some() }
);
}
ItemKind::Struct(ident, struct_definition, generics)
| ItemKind::Union(ident, struct_definition, generics) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
try_visit!(visitor.visit_variant_data(struct_definition));
}
ItemKind::Trait(box Trait {
safety: _,
is_auto: _,
ident,
generics,
bounds,
items,
}) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits);
walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait);
}
ItemKind::TraitAlias(ident, generics, bounds) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound);
}
ItemKind::MacCall(mac) => try_visit!(visitor.visit_mac_call(mac)),
ItemKind::MacroDef(ident, ts) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_mac_def(ts, id))
}
ItemKind::Delegation(box Delegation {
id,
qself,
path,
ident,
rename,
body,
from_glob: _,
}) => {
try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(path, *id));
try_visit!(visitor.visit_ident(ident));
visit_opt!(visitor, visit_ident, rename);
visit_opt!(visitor, visit_block, body);
}
ItemKind::DelegationMac(box DelegationMac { qself, prefix, suffixes, body }) => {
try_visit!(visitor.visit_qself(qself));
try_visit!(visitor.visit_path(prefix, id));
if let Some(suffixes) = suffixes {
for (ident, rename) in suffixes {
visitor.visit_ident(ident);
if let Some(rename) = rename {
visitor.visit_ident(rename);
}
}
}
visit_opt!(visitor, visit_block, body);
}
}
V::Result::output()
}
}
pub fn walk_enum_def<'a, V: Visitor<'a>>(
visitor: &mut V,
EnumDef { variants }: &'a EnumDef,
@ -1121,18 +1228,6 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(
walk_item_ctxt(visitor, item, ctxt)
}
fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
visitor: &mut V,
item: &'a Item<K>,
ctxt: K::Ctxt,
) -> V::Result {
let Item { id, span, vis, attrs, kind, tokens: _ } = item;
walk_list!(visitor, visit_attribute, attrs);
try_visit!(visitor.visit_vis(vis));
try_visit!(kind.walk(*span, *id, vis, ctxt, visitor));
V::Result::output()
}
pub fn walk_struct_def<'a, V: Visitor<'a>>(
visitor: &mut V,
struct_definition: &'a VariantData,
@ -1455,15 +1550,3 @@ pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) -
}
V::Result::output()
}
fn walk_define_opaques<'a, V: Visitor<'a>>(
visitor: &mut V,
define_opaque: &'a Option<ThinVec<(NodeId, Path)>>,
) -> V::Result {
if let Some(define_opaque) = define_opaque {
for (id, path) in define_opaque {
try_visit!(visitor.visit_path(path, *id));
}
}
V::Result::output()
}

View file

@ -197,4 +197,9 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
) -> &'a mut Vec<interpret::Frame<'tcx, Self::Provenance, Self::FrameExtra>> {
unimplemented!()
}
fn get_default_alloc_params(
&self,
) -> <Self::Bytes as rustc_middle::mir::interpret::AllocBytes>::AllocParams {
}
}

View file

@ -735,6 +735,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
Cow::Owned(compute_range())
}
}
fn get_default_alloc_params(&self) -> <Self::Bytes as mir::interpret::AllocBytes>::AllocParams {
}
}
// Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups

View file

@ -26,7 +26,7 @@ use crate::fluent_generated as fluent;
/// Directly returns an `Allocation` containing an absolute path representation of the given type.
pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> {
let path = crate::util::type_name(tcx, ty);
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes());
let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes(), ());
tcx.mk_const_alloc(alloc)
}

View file

@ -626,6 +626,10 @@ pub trait Machine<'tcx>: Sized {
// Default to no caching.
Cow::Owned(compute_range())
}
/// Compute the value passed to the constructors of the `AllocBytes` type for
/// abstract machine allocations.
fn get_default_alloc_params(&self) -> <Self::Bytes as AllocBytes>::AllocParams;
}
/// A lot of the flexibility above is just needed for `Miri`, but all "compile-time" machines

View file

@ -233,10 +233,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
kind: MemoryKind<M::MemoryKind>,
init: AllocInit,
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
let params = self.machine.get_default_alloc_params();
let alloc = if M::PANIC_ON_ALLOC_FAIL {
Allocation::new(size, align, init)
Allocation::new(size, align, init, params)
} else {
Allocation::try_new(size, align, init)?
Allocation::try_new(size, align, init, params)?
};
self.insert_allocation(alloc, kind)
}
@ -248,7 +249,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
kind: MemoryKind<M::MemoryKind>,
mutability: Mutability,
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
let alloc = Allocation::from_bytes(bytes, align, mutability);
let params = self.machine.get_default_alloc_params();
let alloc = Allocation::from_bytes(bytes, align, mutability, params);
self.insert_allocation(alloc, kind)
}

View file

@ -38,7 +38,7 @@ pub(crate) fn create_static_alloc<'tcx>(
static_def_id: LocalDefId,
layout: TyAndLayout<'tcx>,
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit)?;
let alloc = Allocation::try_new(layout.size, layout.align.abi, AllocInit::Uninit, ())?;
let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id.into());
assert_eq!(ecx.machine.static_root_ids, None);
ecx.machine.static_root_ids = Some((alloc_id, static_def_id));

View file

@ -742,7 +742,7 @@ fn ty_known_to_outlive<'tcx>(
region: ty::Region<'tcx>,
) -> bool {
test_region_obligations(tcx, id, param_env, wf_tys, |infcx| {
infcx.register_region_obligation(infer::RegionObligation {
infcx.register_type_outlives_constraint_inner(infer::TypeOutlivesConstraint {
sub_region: region,
sup_type: ty,
origin: infer::RelateParamBound(DUMMY_SP, ty, None),

View file

@ -47,7 +47,7 @@ use rustc_infer::infer::relate::RelateResult;
use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
use rustc_infer::traits::{
IfExpressionCause, MatchExpressionArmCause, Obligation, PredicateObligation,
PredicateObligations,
PredicateObligations, SelectionError,
};
use rustc_middle::span_bug;
use rustc_middle::ty::adjustment::{
@ -677,7 +677,21 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
return Err(TypeError::Mismatch);
}
// Dyn-compatibility violations or miscellaneous.
Err(SelectionError::TraitDynIncompatible(_)) => {
// Dyn compatibility errors in coercion will *always* be due to the
// fact that the RHS of the coercion is a non-dyn compatible `dyn Trait`
// writen in source somewhere (otherwise we will never have lowered
// the dyn trait from HIR to middle).
//
// There's no reason to emit yet another dyn compatibility error,
// especially since the span will differ slightly and thus not be
// deduplicated at all!
self.fcx.set_tainted_by_errors(
self.fcx
.dcx()
.span_delayed_bug(self.cause.span, "dyn compatibility during coercion"),
);
}
Err(err) => {
let guar = self.err_ctxt().report_selection_error(
obligation.clone(),

View file

@ -13,6 +13,7 @@ use hir::Expr;
use hir::def::DefKind;
use hir::pat_util::EnumerateAndAdjustIterator as _;
use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
use rustc_ast::UnsafeBinderCastKind;
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def::{CtorOf, Res};
use rustc_hir::def_id::LocalDefId;
@ -1393,10 +1394,18 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
self.cat_res(expr.hir_id, expr.span, expr_ty, res)
}
// both type ascription and unsafe binder casts don't affect
// the place-ness of the subexpression.
// type ascription doesn't affect the place-ness of the subexpression.
hir::ExprKind::Type(e, _) => self.cat_expr(e),
hir::ExprKind::UnsafeBinderCast(_, e, _) => self.cat_expr(e),
hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Unwrap, e, _) => {
let base = self.cat_expr(e)?;
Ok(self.cat_projection(
expr.hir_id,
base,
expr_ty,
ProjectionKind::UnwrapUnsafeBinder,
))
}
hir::ExprKind::AddrOf(..)
| hir::ExprKind::Call(..)
@ -1427,6 +1436,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
| hir::ExprKind::Repeat(..)
| hir::ExprKind::InlineAsm(..)
| hir::ExprKind::OffsetOf(..)
| hir::ExprKind::UnsafeBinderCast(UnsafeBinderCastKind::Wrap, ..)
| hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr_ty)),
}
}

View file

@ -902,7 +902,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn is_field<'a>(p: &&Projection<'a>) -> bool {
match p.kind {
ProjectionKind::Field(_, _) => true,
ProjectionKind::Deref | ProjectionKind::OpaqueCast => false,
ProjectionKind::Deref
| ProjectionKind::OpaqueCast
| ProjectionKind::UnwrapUnsafeBinder => false,
p @ (ProjectionKind::Subslice | ProjectionKind::Index) => {
bug!("ProjectionKind {:?} was unexpected", p)
}
@ -2197,7 +2199,8 @@ fn restrict_capture_precision(
}
ProjectionKind::Deref => {}
ProjectionKind::OpaqueCast => {}
ProjectionKind::Field(..) => {} // ignore
ProjectionKind::Field(..) => {}
ProjectionKind::UnwrapUnsafeBinder => {}
}
}
@ -2268,6 +2271,7 @@ fn construct_place_string<'tcx>(tcx: TyCtxt<'_>, place: &Place<'tcx>) -> String
ProjectionKind::Index => String::from("Index"),
ProjectionKind::Subslice => String::from("Subslice"),
ProjectionKind::OpaqueCast => String::from("OpaqueCast"),
ProjectionKind::UnwrapUnsafeBinder => String::from("UnwrapUnsafeBinder"),
};
if i != 0 {
projections_str.push(',');

View file

@ -12,23 +12,20 @@ use std::iter;
use rustc_index::{Idx, IndexVec};
use rustc_middle::arena::ArenaAllocatable;
use rustc_middle::bug;
use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::{self, BoundVar, GenericArg, GenericArgKind, Ty, TyCtxt, TypeFoldable};
use rustc_middle::{bug, span_bug};
use tracing::{debug, instrument};
use crate::infer::canonical::instantiate::{CanonicalExt, instantiate_value};
use crate::infer::canonical::{
Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
QueryRegionConstraints, QueryResponse,
};
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::{DefineOpaqueTypes, InferCtxt, InferOk, InferResult, SubregionOrigin};
use crate::traits::query::NoSolution;
use crate::traits::{
Obligation, ObligationCause, PredicateObligation, PredicateObligations, ScrubbedTraitError,
TraitEngine,
};
use crate::traits::{ObligationCause, PredicateObligations, ScrubbedTraitError, TraitEngine};
impl<'tcx> InferCtxt<'tcx> {
/// This method is meant to be invoked as the final step of a canonical query
@ -169,15 +166,13 @@ impl<'tcx> InferCtxt<'tcx> {
where
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
{
let InferOk { value: result_args, mut obligations } =
let InferOk { value: result_args, obligations } =
self.query_response_instantiation(cause, param_env, original_values, query_response)?;
obligations.extend(self.query_outlives_constraints_into_obligations(
cause,
param_env,
&query_response.value.region_constraints.outlives,
&result_args,
));
for (predicate, _category) in &query_response.value.region_constraints.outlives {
let predicate = instantiate_value(self.tcx, &result_args, *predicate);
self.register_outlives_constraint(predicate, cause);
}
let user_result: R =
query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
@ -525,47 +520,6 @@ impl<'tcx> InferCtxt<'tcx> {
self.unify_canonical_vars(cause, param_env, original_values, instantiated_query_response)
}
/// Converts the region constraints resulting from a query into an
/// iterator of obligations.
fn query_outlives_constraints_into_obligations(
&self,
cause: &ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
uninstantiated_region_constraints: &[QueryOutlivesConstraint<'tcx>],
result_args: &CanonicalVarValues<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
uninstantiated_region_constraints.iter().map(move |&constraint| {
let predicate = instantiate_value(self.tcx, result_args, constraint);
self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env)
})
}
pub fn query_outlives_constraint_to_obligation(
&self,
(predicate, _): QueryOutlivesConstraint<'tcx>,
cause: ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> Obligation<'tcx, ty::Predicate<'tcx>> {
let ty::OutlivesPredicate(k1, r2) = predicate;
let atom = match k1.unpack() {
GenericArgKind::Lifetime(r1) => ty::PredicateKind::Clause(
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r1, r2)),
),
GenericArgKind::Type(t1) => ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(
ty::OutlivesPredicate(t1, r2),
)),
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
// encounter this branch.
span_bug!(cause.span, "unexpected const outlives {:?}", predicate);
}
};
let predicate = ty::Binder::dummy(atom);
Obligation::new(self.tcx, cause, param_env, predicate)
}
/// Given two sets of values for the same set of canonical variables, unify them.
/// The second set is produced lazily by supplying indices from the first set.
fn unify_canonical_vars(

View file

@ -265,7 +265,7 @@ impl<'tcx> rustc_type_ir::InferCtxtLike for InferCtxt<'tcx> {
}
fn register_ty_outlives(&self, ty: Ty<'tcx>, r: ty::Region<'tcx>, span: Span) {
self.register_region_obligation_with_cause(ty, r, &ObligationCause::dummy_with_span(span));
self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy_with_span(span));
}
type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;

View file

@ -150,7 +150,7 @@ pub struct InferCtxtInner<'tcx> {
/// for each body-id in this map, which will process the
/// obligations within. This is expected to be done 'late enough'
/// that all type inference variables have been bound and so forth.
region_obligations: Vec<RegionObligation<'tcx>>,
region_obligations: Vec<TypeOutlivesConstraint<'tcx>>,
/// Caches for opaque type inference.
opaque_type_storage: OpaqueTypeStorage<'tcx>,
@ -173,7 +173,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
}
#[inline]
pub fn region_obligations(&self) -> &[RegionObligation<'tcx>] {
pub fn region_obligations(&self) -> &[TypeOutlivesConstraint<'tcx>] {
&self.region_obligations
}
@ -488,7 +488,7 @@ impl fmt::Display for FixupError {
/// See the `region_obligations` field for more information.
#[derive(Clone, Debug)]
pub struct RegionObligation<'tcx> {
pub struct TypeOutlivesConstraint<'tcx> {
pub sub_region: ty::Region<'tcx>,
pub sup_type: Ty<'tcx>,
pub origin: SubregionOrigin<'tcx>,
@ -738,19 +738,6 @@ impl<'tcx> InferCtxt<'tcx> {
})
}
pub fn region_outlives_predicate(
&self,
cause: &traits::ObligationCause<'tcx>,
predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
) {
self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span, None)
});
self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
})
}
/// Number of type variables created so far.
pub fn num_ty_vars(&self) -> usize {
self.inner.borrow_mut().type_variables().num_vars()

View file

@ -76,23 +76,56 @@ use crate::infer::outlives::env::RegionBoundPairs;
use crate::infer::outlives::verify::VerifyBoundCx;
use crate::infer::resolve::OpportunisticRegionResolver;
use crate::infer::snapshot::undo_log::UndoLog;
use crate::infer::{self, GenericKind, InferCtxt, RegionObligation, SubregionOrigin, VerifyBound};
use crate::infer::{
self, GenericKind, InferCtxt, SubregionOrigin, TypeOutlivesConstraint, VerifyBound,
};
use crate::traits::{ObligationCause, ObligationCauseCode};
impl<'tcx> InferCtxt<'tcx> {
pub fn register_outlives_constraint(
&self,
ty::OutlivesPredicate(arg, r2): ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>,
cause: &ObligationCause<'tcx>,
) {
match arg.unpack() {
ty::GenericArgKind::Lifetime(r1) => {
self.register_region_outlives_constraint(ty::OutlivesPredicate(r1, r2), cause);
}
ty::GenericArgKind::Type(ty1) => {
self.register_type_outlives_constraint(ty1, r2, cause);
}
ty::GenericArgKind::Const(_) => unreachable!(),
}
}
pub fn register_region_outlives_constraint(
&self,
ty::OutlivesPredicate(r_a, r_b): ty::RegionOutlivesPredicate<'tcx>,
cause: &ObligationCause<'tcx>,
) {
let origin = SubregionOrigin::from_obligation_cause(cause, || {
SubregionOrigin::RelateRegionParamBound(cause.span, None)
});
// `'a: 'b` ==> `'b <= 'a`
self.sub_regions(origin, r_b, r_a);
}
/// Registers that the given region obligation must be resolved
/// from within the scope of `body_id`. These regions are enqueued
/// and later processed by regionck, when full type information is
/// available (see `region_obligations` field for more
/// information).
#[instrument(level = "debug", skip(self))]
pub fn register_region_obligation(&self, obligation: RegionObligation<'tcx>) {
pub fn register_type_outlives_constraint_inner(
&self,
obligation: TypeOutlivesConstraint<'tcx>,
) {
let mut inner = self.inner.borrow_mut();
inner.undo_log.push(UndoLog::PushRegionObligation);
inner.undo_log.push(UndoLog::PushTypeOutlivesConstraint);
inner.region_obligations.push(obligation);
}
pub fn register_region_obligation_with_cause(
pub fn register_type_outlives_constraint(
&self,
sup_type: Ty<'tcx>,
sub_region: Region<'tcx>,
@ -124,11 +157,15 @@ impl<'tcx> InferCtxt<'tcx> {
)
});
self.register_region_obligation(RegionObligation { sup_type, sub_region, origin });
self.register_type_outlives_constraint_inner(TypeOutlivesConstraint {
sup_type,
sub_region,
origin,
});
}
/// Trait queries just want to pass back type obligations "as is"
pub fn take_registered_region_obligations(&self) -> Vec<RegionObligation<'tcx>> {
pub fn take_registered_region_obligations(&self) -> Vec<TypeOutlivesConstraint<'tcx>> {
std::mem::take(&mut self.inner.borrow_mut().region_obligations)
}
@ -166,7 +203,7 @@ impl<'tcx> InferCtxt<'tcx> {
);
}
for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
for TypeOutlivesConstraint { sup_type, sub_region, origin } in my_region_obligations {
let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
let ty::OutlivesPredicate(sup_type, sub_region) =
deeply_normalize_ty(outlives, origin.clone())

View file

@ -26,7 +26,7 @@ pub(crate) enum UndoLog<'tcx> {
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
ProjectionCache(traits::UndoLog<'tcx>),
PushRegionObligation,
PushTypeOutlivesConstraint,
}
macro_rules! impl_from {
@ -72,7 +72,7 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
self.region_constraint_storage.as_mut().unwrap().unification_table.reverse(undo)
}
UndoLog::ProjectionCache(undo) => self.projection_cache.reverse(undo),
UndoLog::PushRegionObligation => {
UndoLog::PushTypeOutlivesConstraint => {
self.region_obligations.pop();
}
}

View file

@ -277,7 +277,7 @@ impl<'ast, 'ecx, 'tcx, T: EarlyLintPass> ast_visit::Visitor<'ast>
ast_visit::walk_attribute(self, attr);
}
fn visit_mac_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
fn visit_macro_def(&mut self, mac: &'ast ast::MacroDef, id: ast::NodeId) {
lint_callback!(self, check_mac_def, mac);
self.check_id(id);
}

View file

@ -1,8 +1,7 @@
use std::iter;
use rustc_ast as ast;
use rustc_ast::util::{classify, parser};
use rustc_ast::{ExprKind, StmtKind};
use rustc_ast::{self as ast, ExprKind, HasAttrs as _, StmtKind};
use rustc_errors::{MultiSpan, pluralize};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::DefId;
@ -780,26 +779,30 @@ trait UnusedDelimLint {
right_pos: Option<BytePos>,
is_kw: bool,
) {
let spans = match value.kind {
ast::ExprKind::Block(ref block, None) if let [stmt] = block.stmts.as_slice() => stmt
.span
.find_ancestor_inside(value.span)
.map(|span| (value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))),
let span_with_attrs = match value.kind {
ast::ExprKind::Block(ref block, None) if let [stmt] = block.stmts.as_slice() => {
// For the statements with attributes, like `{ #[allow()] println!("Hello!") }`,
// the span should contains the attributes, or the suggestion will remove them.
if let Some(attr_lo) = stmt.attrs().iter().map(|attr| attr.span.lo()).min() {
stmt.span.with_lo(attr_lo)
} else {
stmt.span
}
}
ast::ExprKind::Paren(ref expr) => {
// For the expr with attributes, like `let _ = (#[inline] || println!("Hello!"));`,
// the span should contains the attributes, or the suggestion will remove them.
let expr_span_with_attrs =
if let Some(attr_lo) = expr.attrs.iter().map(|attr| attr.span.lo()).min() {
expr.span.with_lo(attr_lo)
} else {
expr.span
};
expr_span_with_attrs.find_ancestor_inside(value.span).map(|expr_span| {
(value.span.with_hi(expr_span.lo()), value.span.with_lo(expr_span.hi()))
})
if let Some(attr_lo) = expr.attrs.iter().map(|attr| attr.span.lo()).min() {
expr.span.with_lo(attr_lo)
} else {
expr.span
}
}
_ => return,
};
let spans = span_with_attrs
.find_ancestor_inside(value.span)
.map(|span| (value.span.with_hi(span.lo()), value.span.with_lo(span.hi())));
let keep_space = (
left_pos.is_some_and(|s| s >= value.span.lo()),
right_pos.is_some_and(|s| s <= value.span.hi()),

View file

@ -43,6 +43,9 @@ pub enum ProjectionKind {
///
/// This is unused if `-Znext-solver` is enabled.
OpaqueCast,
/// `unwrap_binder!(expr)`
UnwrapUnsafeBinder,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]

View file

@ -27,12 +27,21 @@ use crate::ty;
/// Functionality required for the bytes of an `Allocation`.
pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Target = [u8]> {
/// The type of extra parameters passed in when creating an allocation.
/// Can be used by `interpret::Machine` instances to make runtime-configuration-dependent
/// decisions about the allocation strategy.
type AllocParams;
/// Create an `AllocBytes` from a slice of `u8`.
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self;
fn from_bytes<'a>(
slice: impl Into<Cow<'a, [u8]>>,
_align: Align,
_params: Self::AllocParams,
) -> Self;
/// Create a zeroed `AllocBytes` of the specified size and alignment.
/// Returns `None` if we ran out of memory on the host.
fn zeroed(size: Size, _align: Align) -> Option<Self>;
fn zeroed(size: Size, _align: Align, _params: Self::AllocParams) -> Option<Self>;
/// Gives direct access to the raw underlying storage.
///
@ -51,11 +60,13 @@ pub trait AllocBytes: Clone + fmt::Debug + Deref<Target = [u8]> + DerefMut<Targe
/// Default `bytes` for `Allocation` is a `Box<u8>`.
impl AllocBytes for Box<[u8]> {
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align) -> Self {
type AllocParams = ();
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, _align: Align, _params: ()) -> Self {
Box::<[u8]>::from(slice.into())
}
fn zeroed(size: Size, _align: Align) -> Option<Self> {
fn zeroed(size: Size, _align: Align, _params: ()) -> Option<Self> {
let bytes = Box::<[u8]>::try_new_zeroed_slice(size.bytes().try_into().ok()?).ok()?;
// SAFETY: the box was zero-allocated, which is a valid initial value for Box<[u8]>
let bytes = unsafe { bytes.assume_init() };
@ -172,9 +183,8 @@ fn all_zero(buf: &[u8]) -> bool {
}
/// Custom encoder for [`Allocation`] to more efficiently represent the case where all bytes are 0.
impl<Prov: Provenance, Extra, Bytes, E: Encoder> Encodable<E> for Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, E: Encoder> Encodable<E> for Allocation<Prov, Extra, Box<[u8]>>
where
Bytes: AllocBytes,
ProvenanceMap<Prov>: Encodable<E>,
Extra: Encodable<E>,
{
@ -192,9 +202,8 @@ where
}
}
impl<Prov: Provenance, Extra, Bytes, D: Decoder> Decodable<D> for Allocation<Prov, Extra, Bytes>
impl<Prov: Provenance, Extra, D: Decoder> Decodable<D> for Allocation<Prov, Extra, Box<[u8]>>
where
Bytes: AllocBytes,
ProvenanceMap<Prov>: Decodable<D>,
Extra: Decodable<D>,
{
@ -203,7 +212,7 @@ where
let len = decoder.read_usize();
let bytes = if all_zero { vec![0u8; len] } else { decoder.read_raw_bytes(len).to_vec() };
let bytes = Bytes::from_bytes(bytes, align);
let bytes = <Box<[u8]> as AllocBytes>::from_bytes(bytes, align, ());
let provenance = Decodable::decode(decoder);
let init_mask = Decodable::decode(decoder);
@ -395,8 +404,9 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
slice: impl Into<Cow<'a, [u8]>>,
align: Align,
mutability: Mutability,
params: <Bytes as AllocBytes>::AllocParams,
) -> Self {
let bytes = Bytes::from_bytes(slice, align);
let bytes = Bytes::from_bytes(slice, align, params);
let size = Size::from_bytes(bytes.len());
Self {
bytes,
@ -408,14 +418,18 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
}
}
pub fn from_bytes_byte_aligned_immutable<'a>(slice: impl Into<Cow<'a, [u8]>>) -> Self {
Allocation::from_bytes(slice, Align::ONE, Mutability::Not)
pub fn from_bytes_byte_aligned_immutable<'a>(
slice: impl Into<Cow<'a, [u8]>>,
params: <Bytes as AllocBytes>::AllocParams,
) -> Self {
Allocation::from_bytes(slice, Align::ONE, Mutability::Not, params)
}
fn new_inner<R>(
size: Size,
align: Align,
init: AllocInit,
params: <Bytes as AllocBytes>::AllocParams,
fail: impl FnOnce() -> R,
) -> Result<Self, R> {
// We raise an error if we cannot create the allocation on the host.
@ -424,7 +438,7 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
// deterministic. However, we can be non-deterministic here because all uses of const
// evaluation (including ConstProp!) will make compilation fail (via hard error
// or ICE) upon encountering a `MemoryExhausted` error.
let bytes = Bytes::zeroed(size, align).ok_or_else(fail)?;
let bytes = Bytes::zeroed(size, align, params).ok_or_else(fail)?;
Ok(Allocation {
bytes,
@ -444,8 +458,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
/// Try to create an Allocation of `size` bytes, failing if there is not enough memory
/// available to the compiler to do so.
pub fn try_new<'tcx>(size: Size, align: Align, init: AllocInit) -> InterpResult<'tcx, Self> {
Self::new_inner(size, align, init, || {
pub fn try_new<'tcx>(
size: Size,
align: Align,
init: AllocInit,
params: <Bytes as AllocBytes>::AllocParams,
) -> InterpResult<'tcx, Self> {
Self::new_inner(size, align, init, params, || {
ty::tls::with(|tcx| tcx.dcx().delayed_bug("exhausted memory during interpretation"));
InterpErrorKind::ResourceExhaustion(ResourceExhaustionInfo::MemoryExhausted)
})
@ -457,8 +476,13 @@ impl<Prov: Provenance, Bytes: AllocBytes> Allocation<Prov, (), Bytes> {
///
/// Example use case: To obtain an Allocation filled with specific data,
/// first call this function and then call write_scalar to fill in the right data.
pub fn new(size: Size, align: Align, init: AllocInit) -> Self {
match Self::new_inner(size, align, init, || {
pub fn new(
size: Size,
align: Align,
init: AllocInit,
params: <Bytes as AllocBytes>::AllocParams,
) -> Self {
match Self::new_inner(size, align, init, params, || {
panic!(
"interpreter ran out of memory: cannot create allocation of {} bytes",
size.bytes()

View file

@ -1582,7 +1582,7 @@ impl<'tcx> TyCtxt<'tcx> {
/// Returns the same `AllocId` if called again with the same bytes.
pub fn allocate_bytes_dedup(self, bytes: &[u8], salt: usize) -> interpret::AllocId {
// Create an allocation that just contains these bytes.
let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes);
let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes, ());
let alloc = self.mk_const_alloc(alloc);
self.reserve_and_set_memory_dedup(alloc, salt)
}

View file

@ -110,7 +110,7 @@ pub(super) fn vtable_allocation_provider<'tcx>(
let ptr_align = tcx.data_layout.pointer_align.abi;
let vtable_size = ptr_size * u64::try_from(vtable_entries.len()).unwrap();
let mut vtable = Allocation::new(vtable_size, ptr_align, AllocInit::Uninit);
let mut vtable = Allocation::new(vtable_size, ptr_align, AllocInit::Uninit, ());
// No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by

View file

@ -121,14 +121,14 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>
let value = match (lit, lit_ty.kind()) {
(ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => {
let s = s.as_str();
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes());
let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes(), ());
let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}
(ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _))
if matches!(inner_ty.kind(), ty::Slice(_)) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8], ());
let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}
@ -138,7 +138,7 @@ fn lit_to_mir_constant<'tcx>(tcx: TyCtxt<'tcx>, lit_input: LitToConstInput<'tcx>
}
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::CStr)) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8], ());
let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, meta: allocation.inner().size().bytes() }
}

View file

@ -240,6 +240,9 @@ fn strip_prefix<'tcx>(
HirProjectionKind::OpaqueCast => {
assert_matches!(iter.next(), Some(ProjectionElem::OpaqueCast(..)));
}
HirProjectionKind::UnwrapUnsafeBinder => {
assert_matches!(iter.next(), Some(ProjectionElem::UnwrapUnsafeBinder(..)));
}
HirProjectionKind::Index | HirProjectionKind::Subslice => {
bug!("unexpected projection kind: {:?}", projection);
}

View file

@ -1220,6 +1220,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
HirProjectionKind::OpaqueCast => {
ExprKind::Use { source: self.thir.exprs.push(captured_place_expr) }
}
HirProjectionKind::UnwrapUnsafeBinder => ExprKind::PlaceUnwrapUnsafeBinder {
source: self.thir.exprs.push(captured_place_expr),
},
HirProjectionKind::Index | HirProjectionKind::Subslice => {
// We don't capture these projections, so we can ignore them here
continue;

View file

@ -1278,6 +1278,23 @@ where
}
ty::Slice(ety) => self.drop_loop_trio_for_slice(*ety),
ty::UnsafeBinder(_) => {
// Unsafe binders may elaborate drops if their inner type isn't copy.
// This is enforced in typeck, so this should never happen.
self.tcx().dcx().span_delayed_bug(
self.source_info.span,
"open drop for unsafe binder shouldn't be encountered",
);
self.elaborator.patch().new_block(BasicBlockData {
statements: vec![],
terminator: Some(Terminator {
source_info: self.source_info,
kind: TerminatorKind::Unreachable,
}),
is_cleanup: self.unwind.is_cleanup(),
})
}
_ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty),
}
}

View file

@ -241,6 +241,7 @@ impl EnumSizeOpt {
data,
tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi,
Mutability::Not,
(),
);
let alloc = tcx.reserve_and_set_memory_alloc(tcx.mk_const_alloc(alloc));
Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc)))

View file

@ -1101,7 +1101,7 @@ where
}
pub(super) fn register_region_outlives(&self, a: I::Region, b: I::Region) {
// `b : a` ==> `a <= b`
// `'a: 'b` ==> `'b <= 'a`
self.delegate.sub_regions(b, a, self.origin_span);
}

View file

@ -48,6 +48,7 @@ pub(crate) fn try_new_allocation<'tcx>(
size,
layout.align.abi,
AllocInit::Uninit,
(),
);
allocation
.write_scalar(&tables.tcx, alloc_range(Size::ZERO, size), scalar)
@ -65,6 +66,7 @@ pub(crate) fn try_new_allocation<'tcx>(
layout.size,
layout.align.abi,
AllocInit::Uninit,
(),
);
allocation
.write_scalar(

View file

@ -76,7 +76,7 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
Some(HasChanged::No)
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(outlives)) => {
self.0.register_region_obligation_with_cause(
self.0.register_type_outlives_constraint(
outlives.0,
outlives.1,
&ObligationCause::dummy_with_span(span),

View file

@ -726,7 +726,9 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
selcx.infcx.region_outlives_predicate(&dummy_cause, binder)
selcx.infcx.enter_forall(binder, |pred| {
selcx.infcx.register_region_outlives_constraint(pred, &dummy_cause);
});
}
ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
@ -735,14 +737,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
binder.map_bound_ref(|pred| pred.0).no_bound_vars(),
) {
(None, Some(t_a)) => {
selcx.infcx.register_region_obligation_with_cause(
selcx.infcx.register_type_outlives_constraint(
t_a,
selcx.infcx.tcx.lifetimes.re_static,
&dummy_cause,
);
}
(Some(ty::OutlivesPredicate(t_a, r_b)), _) => {
selcx.infcx.register_region_obligation_with_cause(
selcx.infcx.register_type_outlives_constraint(
t_a,
r_b,
&dummy_cause,

View file

@ -428,7 +428,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
if infcx.considering_regions {
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
infcx.register_region_outlives_constraint(data, &obligation.cause);
}
ProcessResult::Changed(Default::default())
@ -439,7 +439,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
r_b,
))) => {
if infcx.considering_regions {
infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause);
infcx.register_type_outlives_constraint(t_a, r_b, &obligation.cause);
}
ProcessResult::Changed(Default::default())
}

View file

@ -9,7 +9,7 @@ use rustc_span::def_id::LocalDefId;
use tracing::instrument;
use crate::infer::InferCtxt;
use crate::traits::{ObligationCause, ObligationCtxt};
use crate::traits::ObligationCause;
/// Implied bounds are region relationships that we deduce
/// automatically. The idea is that (e.g.) a caller must check that a
@ -79,24 +79,9 @@ fn implied_outlives_bounds<'a, 'tcx>(
if !constraints.is_empty() {
let QueryRegionConstraints { outlives } = constraints;
// Instantiation may have produced new inference variables and constraints on those
// variables. Process these constraints.
let ocx = ObligationCtxt::new(infcx);
let cause = ObligationCause::misc(span, body_id);
for &constraint in &outlives {
ocx.register_obligation(infcx.query_outlives_constraint_to_obligation(
constraint,
cause.clone(),
param_env,
));
}
let errors = ocx.select_all_or_error();
if !errors.is_empty() {
infcx.dcx().span_bug(
span,
"implied_outlives_bounds failed to solve obligations from instantiation",
);
for &(predicate, _) in &outlives {
infcx.register_outlives_constraint(predicate, &cause);
}
};

View file

@ -1,6 +1,6 @@
use std::ops::ControlFlow;
use rustc_infer::infer::RegionObligation;
use rustc_infer::infer::TypeOutlivesConstraint;
use rustc_infer::infer::canonical::CanonicalQueryInput;
use rustc_infer::traits::query::OutlivesBound;
use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
@ -141,7 +141,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
&& !ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat
&& ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
{
for RegionObligation { sup_type, sub_region, .. } in
for TypeOutlivesConstraint { sup_type, sub_region, .. } in
ocx.infcx.take_registered_region_obligations()
{
let mut components = smallvec![];

View file

@ -656,7 +656,7 @@ impl<'a, P: Pattern> SplitInternal<'a, P> {
None
}
#[inline]
#[inline(always)]
fn next(&mut self) -> Option<&'a str> {
if self.finished {
return None;

View file

@ -429,8 +429,23 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> {
SearchStep::Done
}
}
#[inline]
#[inline(always)]
fn next_match(&mut self) -> Option<(usize, usize)> {
if self.utf8_size == 1 {
return match self
.haystack
.as_bytes()
.get(self.finger..self.finger_back)?
.iter()
.position(|x| *x == self.utf8_encoded[0])
{
Some(x) => {
self.finger += x + 1;
Some((self.finger - 1, self.finger))
}
None => None,
};
}
loop {
// get the haystack after the last character found
let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?;
@ -498,6 +513,21 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> {
}
#[inline]
fn next_match_back(&mut self) -> Option<(usize, usize)> {
if self.utf8_size == 1 {
return match self
.haystack
.get(self.finger..self.finger_back)?
.as_bytes()
.iter()
.rposition(|&x| x == self.utf8_encoded[0])
{
Some(x) => {
self.finger_back = self.finger + x;
Some((self.finger_back, self.finger_back + 1))
}
None => None,
};
}
let haystack = self.haystack.as_bytes();
loop {
// get the haystack up to but not including the last character searched

View file

@ -118,15 +118,25 @@ impl Step for Miri {
fn run(self, builder: &Builder<'_>) {
let host = builder.build.build;
let target = self.target;
let stage = builder.top_stage;
// `x run` uses stage 0 by default but miri does not work well with stage 0.
// Change the stage to 1 if it's not set explicitly.
let stage = if builder.config.is_explicit_stage() || builder.top_stage >= 1 {
builder.top_stage
} else {
1
};
if stage == 0 {
eprintln!("miri cannot be run at stage 0");
std::process::exit(1);
}
// This compiler runs on the host, we'll just use it for the target.
let target_compiler = builder.compiler(stage, host);
let host_compiler = tool::get_tool_rustc_compiler(builder, target_compiler);
let target_compiler = builder.compiler(stage, target);
let miri_build = builder.ensure(tool::Miri { compiler: target_compiler, target });
// Rustc tools are off by one stage, so use the build compiler to run miri.
let host_compiler = miri_build.build_compiler;
// Get a target sysroot for Miri.
let miri_sysroot = test::Miri::build_miri_sysroot(builder, target_compiler, target);

View file

@ -0,0 +1,8 @@
# Unstable Book
These are the sources for <https://doc.rust-lang.org/nightly/unstable-book/>.
To generate them, run `./x doc unstable-book`, which will generate HTML files in `build/host/doc/unstable-book` using `src/tools/rustbook`.
If you need to change the overall structure, modify `src/tools/unstable-book-gen/src/SUMMARY.md`.
Note that most of this book is autogenerated by `unstable-book-gen`, with the exception of `compiler-flags` and `compiler-environment-variables`.
As a result, it does not integrate well with `mdbook`. Use `./x doc` instead.

View file

@ -0,0 +1 @@
# Compiler environment variables

View file

@ -14,7 +14,7 @@ Cargo disallows setting `cargo::rustc-env=RUSTC_BOOTSTRAP` in build scripts.
Build systems can limit the features they enable with [`-Z allow-features=feature1,feature2`][Z-allow-features].
Crates can fully opt out of unstable features by using [`#![forbid(unstable_features)]`][unstable-features] at the crate root (or any other way of enabling lints, such as `-F unstable-features`).
[Z-allow-features]: ./allow-features.html
[Z-allow-features]: ../compiler-flags/allow-features.html
[unstable-features]: ../../rustc/lints/listing/allowed-by-default.html#unstable-features
## Why does this environment variable exist?

View file

@ -11,4 +11,4 @@ Features are comma-separated, for example `-Z allow-features=ffi_pure,f16`.
If the flag is present, any feature listed will be allowed and any feature not listed will be disallowed.
Any unrecognized feature is ignored.
[`RUSTC_BOOTSTRAP`]: ./rustc-bootstrap.html
[`RUSTC_BOOTSTRAP`]: ../compiler-environment-variables/RUSTC_BOOTSTRAP.html

View file

@ -941,6 +941,8 @@ impl<'tcx> Delegate<'tcx> for DerefDelegate<'_, 'tcx> {
ProjectionKind::Subslice |
// Doesn't have surface syntax. Only occurs in patterns.
ProjectionKind::OpaqueCast => (),
// Only occurs in closure captures.
ProjectionKind::UnwrapUnsafeBinder => (),
ProjectionKind::Deref => {
// Explicit derefs are typically handled later on, but
// some items do not need explicit deref, such as array accesses,

View file

@ -139,7 +139,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
AllocKind::LiveData => {
if memory_kind == MiriMemoryKind::Global.into() {
// For new global allocations, we always pre-allocate the memory to be able use the machine address directly.
let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align)
let prepared_bytes = MiriAllocBytes::zeroed(info.size, info.align, ())
.unwrap_or_else(|| {
panic!("Miri ran out of memory: cannot create allocation of {size:?} bytes", size = info.size)
});
@ -159,7 +159,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
AllocKind::Function | AllocKind::VTable => {
// Allocate some dummy memory to get a unique address for this function/vtable.
let alloc_bytes =
MiriAllocBytes::from_bytes(&[0u8; 1], Align::from_bytes(1).unwrap());
MiriAllocBytes::from_bytes(&[0u8; 1], Align::from_bytes(1).unwrap(), ());
let ptr = alloc_bytes.as_ptr();
// Leak the underlying memory to ensure it remains unique.
std::mem::forget(alloc_bytes);
@ -429,7 +429,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
prepared_alloc_bytes.copy_from_slice(bytes);
interp_ok(prepared_alloc_bytes)
} else {
interp_ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align))
interp_ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align, ()))
}
}

View file

@ -24,7 +24,7 @@ impl Clone for MiriAllocBytes {
fn clone(&self) -> Self {
let bytes: Cow<'_, [u8]> = Cow::Borrowed(self);
let align = Align::from_bytes(self.layout.align().to_u64()).unwrap();
MiriAllocBytes::from_bytes(bytes, align)
MiriAllocBytes::from_bytes(bytes, align, ())
}
}
@ -86,7 +86,10 @@ impl MiriAllocBytes {
}
impl AllocBytes for MiriAllocBytes {
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align) -> Self {
/// Placeholder!
type AllocParams = ();
fn from_bytes<'a>(slice: impl Into<Cow<'a, [u8]>>, align: Align, _params: ()) -> Self {
let slice = slice.into();
let size = slice.len();
let align = align.bytes();
@ -102,7 +105,7 @@ impl AllocBytes for MiriAllocBytes {
alloc_bytes
}
fn zeroed(size: Size, align: Align) -> Option<Self> {
fn zeroed(size: Size, align: Align, _params: ()) -> Option<Self> {
let size = size.bytes();
let align = align.bytes();
// SAFETY: `alloc_fn` will only be used with `size != 0`.

View file

@ -902,7 +902,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
let mut alloc = alloc.inner().adjust_from_tcx(
&this.tcx,
|bytes, align| {
interp_ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align))
interp_ok(MiriAllocBytes::from_bytes(std::borrow::Cow::Borrowed(bytes), align, ()))
},
|ptr| this.global_root_pointer(ptr),
)?;

View file

@ -1803,6 +1803,9 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
) -> Cow<'e, RangeSet> {
Cow::Borrowed(ecx.machine.union_data_ranges.entry(ty).or_insert_with(compute_range))
}
/// Placeholder!
fn get_default_alloc_params(&self) -> <Self::Bytes as AllocBytes>::AllocParams { () }
}
/// Trait for callbacks handling asynchronous machine operations.

View file

@ -1,5 +1,7 @@
[The Unstable Book](the-unstable-book.md)
- [Compiler environment variables](compiler-environment-variables.md)
{compiler_env_vars}
- [Compiler flags](compiler-flags.md)
{compiler_flags}
- [Language features](language-features.md)

View file

@ -35,8 +35,12 @@ fn set_to_summary_str(set: &BTreeSet<String>, dir: &str) -> String {
fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Features) {
let compiler_flags = collect_unstable_book_section_file_names(&path.join("src/compiler-flags"));
let compiler_env_vars =
collect_unstable_book_section_file_names(&path.join("src/compiler-environment-variables"));
let compiler_flags_str = set_to_summary_str(&compiler_flags, "compiler-flags");
let compiler_env_vars_str =
set_to_summary_str(&compiler_env_vars, "compiler-environment-variables");
let unstable_lang_features = collect_unstable_feature_names(&lang_features);
let unstable_lib_features = collect_unstable_feature_names(&lib_features);
@ -47,6 +51,7 @@ fn generate_summary(path: &Path, lang_features: &Features, lib_features: &Featur
let summary_path = path.join("src/SUMMARY.md");
let content = format!(
include_str!("SUMMARY.md"),
compiler_env_vars = compiler_env_vars_str,
compiler_flags = compiler_flags_str,
language_features = lang_features_str,
library_features = lib_features_str

View file

@ -24,24 +24,6 @@ LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/mut-is-pointer-like.rs:35:56
|
LL | let x: Pin<&mut dyn AsyncTrait<Output = ()>> = f;
| ^ `AsyncTrait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/mut-is-pointer-like.rs:16:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
...
LL | async fn async_dispatch(self: Pin<&mut Self>) -> Self::Output;
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
= note: required for the cast from `Pin<&mut {async block@$DIR/mut-is-pointer-like.rs:32:32: 32:37}>` to `Pin<&mut dyn AsyncTrait<Output = ()>>`
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0038`.

View file

@ -7,24 +7,6 @@ LL | #![feature(async_fn_in_dyn_trait)]
= note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/works.rs:27:34
|
LL | let x: &dyn AsyncTrait = &"hello, world!";
| ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/works.rs:14:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
LL | async fn async_dispatch(&self);
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
= note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/works.rs:27:16
|
@ -42,6 +24,6 @@ LL | async fn async_dispatch(&self);
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0038`.

View file

@ -7,24 +7,6 @@ LL | #![feature(async_fn_in_dyn_trait)]
= note: see issue #133119 <https://github.com/rust-lang/rust/issues/133119> for more information
= note: `#[warn(incomplete_features)]` on by default
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/wrong-size.rs:21:30
|
LL | let x: &dyn AsyncTrait = &"hello, world!";
| ^^^^^^^^^^^^^^^^ `AsyncTrait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/wrong-size.rs:9:14
|
LL | trait AsyncTrait {
| ---------- this trait is not dyn compatible...
LL | async fn async_dispatch(&self);
| ^^^^^^^^^^^^^^ ...because method `async_dispatch` is `async`
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
= note: required for the cast from `&&'static str` to `&dyn AsyncTrait`
error[E0038]: the trait `AsyncTrait` is not dyn compatible
--> $DIR/wrong-size.rs:21:12
|
@ -42,6 +24,6 @@ LL | async fn async_dispatch(&self);
= help: consider moving `async_dispatch` to another trait
= help: only type `&'static str` implements `AsyncTrait`; consider using it directly instead.
error: aborting due to 2 previous errors; 1 warning emitted
error: aborting due to 1 previous error; 1 warning emitted
For more information about this error, try `rustc --explain E0038`.

View file

@ -6,7 +6,6 @@ use std::marker::PhantomData;
fn transmute<T, U>(t: T) -> U {
(&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
}
struct ActuallySuper;

View file

@ -1,12 +1,12 @@
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/almost-supertrait-associated-type.rs:21:20
--> $DIR/almost-supertrait-associated-type.rs:20:20
|
LL | impl<T, U> Dyn for dyn Foo<T, U> + '_ {
| ^^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/almost-supertrait-associated-type.rs:33:34
--> $DIR/almost-supertrait-associated-type.rs:32:34
|
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
| --- this trait is not dyn compatible...
@ -23,7 +23,7 @@ LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/almost-supertrait-associated-type.rs:33:34
--> $DIR/almost-supertrait-associated-type.rs:32:34
|
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
| --- this trait is not dyn compatible...
@ -32,24 +32,6 @@ LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type
= help: consider moving `transmute` to another trait
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/almost-supertrait-associated-type.rs:7:6
|
LL | (&PhantomData::<T> as &dyn Foo<T, U>).transmute(t)
| ^^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/almost-supertrait-associated-type.rs:33:34
|
LL | trait Foo<T, U>: Super<ActuallySuper, Assoc = T>
| --- this trait is not dyn compatible...
...
LL | fn transmute(&self, t: T) -> <Self as Super<NotActuallySuper>>::Assoc;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...because method `transmute` references the `Self` type in its return type
= help: consider moving `transmute` to another trait
= note: required for the cast from `&PhantomData<T>` to `&dyn Foo<T, U>`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -8,7 +8,6 @@ trait Bar {
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn main() {

View file

@ -14,23 +14,6 @@ LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/associated-consts.rs:10:5
|
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/associated-consts.rs:5:11
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | const X: usize;
| ^ ...because it contains this associated `const`
= help: consider moving `X` to another trait
= note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,14 +15,12 @@ trait Quux {
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t as &dyn Bar
//~^ ERROR E0038
//~| ERROR E0038
}
fn make_quux<T:Quux>(t: &T) -> &dyn Quux {

View file

@ -15,7 +15,7 @@ LL | fn bar<T>(&self, t: T);
= help: consider moving `bar` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:21:40
--> $DIR/generics.rs:20:40
|
LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
| ^^^^^^^ `Bar` is not dyn compatible
@ -31,24 +31,7 @@ LL | fn bar<T>(&self, t: T);
= help: consider moving `bar` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:17:5
|
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/generics.rs:7:8
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
= note: required for the cast from `&T` to `&dyn Bar`
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:23:10
--> $DIR/generics.rs:22:10
|
LL | t as &dyn Bar
| ^^^^^^^^ `Bar` is not dyn compatible
@ -63,23 +46,6 @@ LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/generics.rs:23:5
|
LL | t as &dyn Bar
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/generics.rs:7:8
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | fn bar<T>(&self, t: T);
| ^^^ ...because method `bar` has generic type parameters
= help: consider moving `bar` to another trait
= note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to 5 previous errors
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -18,5 +18,4 @@ fn main() {
let mut thing = Thing;
let test: &mut dyn Bar = &mut thing;
//~^ ERROR E0038
//~| ERROR E0038
}

View file

@ -1,22 +1,3 @@
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/mention-correct-dyn-incompatible-trait.rs:19:30
|
LL | let test: &mut dyn Bar = &mut thing;
| ^^^^^^^^^^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/mention-correct-dyn-incompatible-trait.rs:4:8
|
LL | fn foo<T>(&self, val: T);
| ^^^ ...because method `foo` has generic type parameters
...
LL | trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
= help: only type `Thing` implements `Bar`; consider using it directly instead.
= note: required for the cast from `&mut Thing` to `&mut dyn Bar`
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/mention-correct-dyn-incompatible-trait.rs:19:15
|
@ -35,6 +16,6 @@ LL | trait Bar: Foo { }
= help: consider moving `foo` to another trait
= help: only type `Thing` implements `Bar`; consider using it directly instead.
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -18,13 +18,11 @@ trait Quux {
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn make_quux<T:Quux>(t: &T) -> &dyn Quux {

View file

@ -15,7 +15,7 @@ LL | fn bar(&self, x: &Self);
= help: consider moving `bar` to another trait
error[E0038]: the trait `Baz` is not dyn compatible
--> $DIR/mentions-Self.rs:24:31
--> $DIR/mentions-Self.rs:23:31
|
LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
| ^^^^^^^ `Baz` is not dyn compatible
@ -30,40 +30,6 @@ LL | fn baz(&self) -> Self;
| ^^^^ ...because method `baz` references the `Self` type in its return type
= help: consider moving `baz` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/mentions-Self.rs:20:5
|
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/mentions-Self.rs:7:22
|
LL | trait Bar {
| --- this trait is not dyn compatible...
LL | fn bar(&self, x: &Self);
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
= help: consider moving `bar` to another trait
= note: required for the cast from `&T` to `&dyn Bar`
error[E0038]: the trait `Baz` is not dyn compatible
--> $DIR/mentions-Self.rs:26:5
|
LL | t
| ^ `Baz` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/mentions-Self.rs:11:22
|
LL | trait Baz {
| --- this trait is not dyn compatible...
LL | fn baz(&self) -> Self;
| ^^^^ ...because method `baz` references the `Self` type in its return type
= help: consider moving `baz` to another trait
= note: required for the cast from `&T` to `&dyn Baz`
error: aborting due to 4 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -17,5 +17,4 @@ impl Foo for Bar {}
fn main() {
let b: Box<dyn Foo> = Box::new(Bar);
//~^ ERROR E0038
//~| ERROR E0038
}

View file

@ -46,31 +46,6 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
LL | fn foo() where Self: Sized {}
| +++++++++++++++++
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/no-static.rs:18:27
|
LL | let b: Box<dyn Foo> = Box::new(Bar);
| ^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/no-static.rs:5:8
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn foo() {}
| ^^^ ...because associated function `foo` has no `self` parameter
= help: only type `Bar` implements `Foo`; consider using it directly instead.
= note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self) {}
| +++++
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
LL | fn foo() where Self: Sized {}
| +++++++++++++++++
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -10,7 +10,6 @@ trait Bar
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn main() {

View file

@ -13,22 +13,6 @@ LL | trait Bar
LL | where Self : Sized
| ^^^^^ ...because it requires `Self: Sized`
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/sized-2.rs:12:5
|
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/sized-2.rs:5:18
|
LL | trait Bar
| --- this trait is not dyn compatible...
LL | where Self : Sized
| ^^^^^ ...because it requires `Self: Sized`
= note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -8,7 +8,6 @@ trait Bar: Sized {
fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
//~^ ERROR E0038
t
//~^ ERROR E0038
}
fn main() {}

View file

@ -13,22 +13,6 @@ LL | trait Bar: Sized {
| |
| this trait is not dyn compatible...
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/sized.rs:10:5
|
LL | t
| ^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/sized.rs:4:12
|
LL | trait Bar: Sized {
| --- ^^^^^ ...because it requires `Self: Sized`
| |
| this trait is not dyn compatible...
= note: required for the cast from `&T` to `&dyn Bar`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -7,6 +7,5 @@ trait Qux {
static FOO: &(dyn Qux + Sync) = "desc";
//~^ ERROR the trait `Qux` is not dyn compatible
//~| ERROR the trait `Qux` is not dyn compatible
//~| ERROR the trait `Qux` is not dyn compatible
fn main() {}

View file

@ -21,30 +21,6 @@ help: alternatively, consider constraining `bar` so it does not apply to trait o
LL | fn bar() where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `Qux` is not dyn compatible
--> $DIR/taint-const-eval.rs:7:33
|
LL | static FOO: &(dyn Qux + Sync) = "desc";
| ^^^^^^ `Qux` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/taint-const-eval.rs:4:8
|
LL | trait Qux {
| --- this trait is not dyn compatible...
LL | fn bar();
| ^^^ ...because associated function `bar` has no `self` parameter
= note: required for the cast from `&'static str` to `&'static (dyn Qux + Sync + 'static)`
help: consider turning `bar` into a method by giving it a `&self` argument
|
LL | fn bar(&self);
| +++++
help: alternatively, consider constraining `bar` so it does not apply to trait objects
|
LL | fn bar() where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `Qux` is not dyn compatible
--> $DIR/taint-const-eval.rs:7:15
|
@ -69,6 +45,6 @@ help: alternatively, consider constraining `bar` so it does not apply to trait o
LL | fn bar() where Self: Sized;
| +++++++++++++++++
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -31,5 +31,4 @@ impl Trait for i32 {
fn main() {
Ptr(Box::new(4)) as Ptr<dyn Trait>;
//~^ ERROR the trait `Trait` is not dyn compatible
//~^^ ERROR the trait `Trait` is not dyn compatible
}

View file

@ -17,26 +17,6 @@ LL | fn ptr(self: Ptr<Self>);
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on
= help: only type `i32` implements `Trait`; consider using it directly instead.
error[E0038]: the trait `Trait` is not dyn compatible
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:32:5
|
LL | fn ptr(self: Ptr<Self>);
| --------- help: consider changing method `ptr`'s `self` parameter to be `&self`: `&Self`
...
LL | Ptr(Box::new(4)) as Ptr<dyn Trait>;
| ^^^^^^^^^^^^^^^^ `Trait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:25:18
|
LL | trait Trait {
| ----- this trait is not dyn compatible...
LL | fn ptr(self: Ptr<Self>);
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on
= help: only type `i32` implements `Trait`; consider using it directly instead.
= note: required for the cast from `Ptr<{integer}>` to `Ptr<dyn Trait>`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -26,5 +26,4 @@ fn main() {
let foo = Fooer(5);
f(Box::new(foo));
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
}

View file

@ -30,23 +30,6 @@ LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/gat-in-trait-path.rs:27:5
|
LL | f(Box::new(foo));
| ^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/gat-in-trait-path.rs:6:10
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | type A<'a> where Self: 'a;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
= note: required for the cast from `Box<Fooer<{integer}>>` to `Box<(dyn Foo<A<'a> = &'a ()> + 'static)>`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -18,6 +18,5 @@ fn main() {
Holder {
inner: Box::new(()),
//~^ ERROR: the trait `Provider` is not dyn compatible
//~| ERROR: the trait `Provider` is not dyn compatible
};
}

View file

@ -82,25 +82,7 @@ LL | type A<'a>;
= help: consider moving `A` to another trait
= help: only type `()` implements `Provider`; consider using it directly instead.
error[E0038]: the trait `Provider` is not dyn compatible
--> $DIR/issue-71176.rs:19:16
|
LL | inner: Box::new(()),
| ^^^^^^^^^^^^ `Provider` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-71176.rs:2:10
|
LL | trait Provider {
| -------- this trait is not dyn compatible...
LL | type A<'a>;
| ^ ...because it contains the generic associated type `A`
= help: consider moving `A` to another trait
= help: only type `()` implements `Provider`; consider using it directly instead.
= note: required for the cast from `Box<()>` to `Box<(dyn Provider<A<'_> = _> + 'static), {type error}>`
error: aborting due to 6 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.

View file

@ -33,6 +33,5 @@ impl SuperTrait for SuperStruct {
fn main() {
let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
//~^ ERROR missing generics for associated type
//~^^ ERROR the trait
//~| ERROR the trait
}

View file

@ -32,26 +32,7 @@ LL | type SubType<'a>: SubTrait where Self: 'a;
= help: only type `SuperStruct` implements `SuperTrait` within this crate; consider using it directly instead.
= note: `SuperTrait` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type
error[E0038]: the trait `SuperTrait` is not dyn compatible
--> $DIR/issue-76535.rs:34:57
|
LL | let sub: Box<dyn SuperTrait<SubType = SubStruct>> = Box::new(SuperStruct::new(0));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SuperTrait` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-76535.rs:4:10
|
LL | pub trait SuperTrait {
| ---------- this trait is not dyn compatible...
LL | type SubType<'a>: SubTrait where Self: 'a;
| ^^^^^^^ ...because it contains the generic associated type `SubType`
= help: consider moving `SubType` to another trait
= help: only type `SuperStruct` implements `SuperTrait` within this crate; consider using it directly instead.
= note: `SuperTrait` may be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type
= note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType<'_> = SubStruct<'_>>>`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.

View file

@ -15,12 +15,17 @@ impl<'a, T> RefCont<'a, T> for Box<T> {
}
trait MapLike<K, V> {
type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
type VRefCont<'a>: RefCont<'a, V>
where
Self: 'a;
fn get<'a>(&'a self, key: &K) -> Option<Self::VRefCont<'a>>;
}
impl<K: Ord, V: 'static> MapLike<K, V> for std::collections::BTreeMap<K, V> {
type VRefCont<'a> = &'a V where Self: 'a;
type VRefCont<'a>
= &'a V
where
Self: 'a;
fn get<'a>(&'a self, key: &K) -> Option<&'a V> {
std::collections::BTreeMap::get(self, key)
}
@ -37,8 +42,7 @@ impl<K, V: Default> MapLike<K, V> for Source {
fn main() {
let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
//~^ ERROR the trait
as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
//~^ ERROR missing generics for associated type
//~| ERROR the trait
//~^ ERROR the trait
//~| ERROR missing generics for associated type
}

View file

@ -1,5 +1,5 @@
error[E0107]: missing generics for associated type `MapLike::VRefCont`
--> $DIR/issue-79422.rs:41:36
--> $DIR/issue-79422.rs:45:36
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^ expected 1 lifetime argument
@ -7,7 +7,7 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
note: associated type defined here, with 1 lifetime parameter: `'a`
--> $DIR/issue-79422.rs:18:10
|
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
LL | type VRefCont<'a>: RefCont<'a, V>
| ^^^^^^^^ --
help: add missing lifetime argument
|
@ -15,7 +15,7 @@ LL | as Box<dyn MapLike<u8, u8, VRefCont<'a> = dyn RefCont<'_, u8>>>;
| ++++
error[E0038]: the trait `MapLike` is not dyn compatible
--> $DIR/issue-79422.rs:41:12
--> $DIR/issue-79422.rs:45:12
|
LL | as Box<dyn MapLike<u8, u8, VRefCont = dyn RefCont<'_, u8>>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible
@ -26,28 +26,11 @@ note: for a trait to be dyn compatible it needs to allow building a vtable
|
LL | trait MapLike<K, V> {
| ------- this trait is not dyn compatible...
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
LL | type VRefCont<'a>: RefCont<'a, V>
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait
error[E0038]: the trait `MapLike` is not dyn compatible
--> $DIR/issue-79422.rs:39:13
|
LL | let m = Box::new(std::collections::BTreeMap::<u8, u8>::new())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `MapLike` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-79422.rs:18:10
|
LL | trait MapLike<K, V> {
| ------- this trait is not dyn compatible...
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
= help: consider moving `VRefCont` to another trait
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont<'_> = (dyn RefCont<'_, u8> + 'static)>>`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0107.
For more information about an error, try `rustc --explain E0038`.

View file

@ -13,7 +13,6 @@ fn needs_bar(_: *mut Type2) {}
fn main() {
let x: &dyn Foo = &();
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
needs_bar(x);
//~^ ERROR mismatched types

View file

@ -1,19 +1,3 @@
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/span-bug-issue-121597.rs:14:23
|
LL | let x: &dyn Foo = &();
| ^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/span-bug-issue-121597.rs:4:12
|
LL | trait Foo: for<T> Bar<T> {}
| --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables
| |
| this trait is not dyn compatible...
= note: required for the cast from `&()` to `&dyn Foo`
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/span-bug-issue-121597.rs:14:12
|
@ -30,7 +14,7 @@ LL | trait Foo: for<T> Bar<T> {}
| this trait is not dyn compatible...
error[E0308]: mismatched types
--> $DIR/span-bug-issue-121597.rs:18:15
--> $DIR/span-bug-issue-121597.rs:17:15
|
LL | needs_bar(x);
| --------- ^ types differ in mutability
@ -45,7 +29,7 @@ note: function defined here
LL | fn needs_bar(_: *mut Type2) {}
| ^^^^^^^^^ -------------
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0308.
For more information about an error, try `rustc --explain E0038`.

View file

@ -29,9 +29,9 @@ fn car() -> dyn DynIncompatible { //~ ERROR the trait `DynIncompatible` is not d
fn cat() -> Box<dyn DynIncompatible> { //~ ERROR the trait `DynIncompatible` is not dyn compatible
if true {
return Box::new(A); //~ ERROR is not dyn compatible
return Box::new(A);
}
Box::new(B) //~ ERROR is not dyn compatible
Box::new(B)
}
fn main() {}

View file

@ -75,65 +75,7 @@ help: alternatively, consider constraining `foo` so it does not apply to trait o
LL | fn foo() -> Self where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `DynIncompatible` is not dyn compatible
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:32:16
|
LL | return Box::new(A);
| ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
|
LL | trait DynIncompatible {
| --------------- this trait is not dyn compatible...
LL | fn foo() -> Self;
| ^^^ ...because associated function `foo` has no `self` parameter
= help: the following types implement `DynIncompatible`:
A
B
consider defining an enum where each variant holds one of these types,
implementing `DynIncompatible` for this new enum and using it instead
= note: required for the cast from `Box<A>` to `Box<(dyn DynIncompatible + 'static)>`
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self) -> Self;
| +++++
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
LL | fn foo() -> Self where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `DynIncompatible` is not dyn compatible
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:34:5
|
LL | Box::new(B)
| ^^^^^^^^^^^ `DynIncompatible` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/dyn-incompatible-trait-in-return-position-dyn-trait.rs:4:8
|
LL | trait DynIncompatible {
| --------------- this trait is not dyn compatible...
LL | fn foo() -> Self;
| ^^^ ...because associated function `foo` has no `self` parameter
= help: the following types implement `DynIncompatible`:
A
B
consider defining an enum where each variant holds one of these types,
implementing `DynIncompatible` for this new enum and using it instead
= note: required for the cast from `Box<B>` to `Box<(dyn DynIncompatible + 'static)>`
help: consider turning `foo` into a method by giving it a `&self` argument
|
LL | fn foo(&self) -> Self;
| +++++
help: alternatively, consider constraining `foo` so it does not apply to trait objects
|
LL | fn foo() -> Self where Self: Sized;
| +++++++++++++++++
error: aborting due to 5 previous errors
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0038, E0746.
For more information about an error, try `rustc --explain E0038`.

View file

@ -13,6 +13,5 @@ impl Foo for u32 {
fn main() {
let i = Box::new(42_u32) as Box<dyn Foo>;
//~^ ERROR the trait `Foo` is not dyn compatible
//~| ERROR the trait `Foo` is not dyn compatible
let s = i.baz();
}

View file

@ -15,24 +15,6 @@ LL | fn baz(&self) -> impl Debug;
= help: consider moving `baz` to another trait
= help: only type `u32` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/dyn-compatibility.rs:14:13
|
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
| ^^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/dyn-compatibility.rs:4:22
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn baz(&self) -> impl Debug;
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
= help: consider moving `baz` to another trait
= help: only type `u32` implements `Foo`; consider using it directly instead.
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

View file

@ -17,6 +17,5 @@ fn main() {
let mut thing = Thing;
let test: &dyn Bar = &mut thing;
//~^ ERROR E0038
//~| ERROR E0038
foo(test);
}

View file

@ -14,23 +14,6 @@ LL | pub trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-18959.rs:18:26
|
LL | let test: &dyn Bar = &mut thing;
| ^^^^^^^^^^ `Bar` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-18959.rs:1:20
|
LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
| ^^^ ...because method `foo` has generic type parameters
LL | pub trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
= note: required for the cast from `&mut Thing` to `&dyn Bar`
error[E0038]: the trait `Bar` is not dyn compatible
--> $DIR/issue-18959.rs:18:15
|
@ -47,6 +30,6 @@ LL | pub trait Bar: Foo { }
| --- this trait is not dyn compatible...
= help: consider moving `foo` to another trait
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,6 +15,5 @@ struct Bar {
const FOO : Foo = Foo;
const BAR : Bar = Bar { foos: &[&FOO]};
//~^ ERROR E0038
//~| ERROR E0038
fn main() { }

View file

@ -22,31 +22,6 @@ help: alternatively, consider constraining `qiz` so it does not apply to trait o
LL | fn qiz() where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `Qiz` is not dyn compatible
--> $DIR/issue-19380.rs:16:33
|
LL | const BAR : Bar = Bar { foos: &[&FOO]};
| ^^^^ `Qiz` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-19380.rs:2:6
|
LL | trait Qiz {
| --- this trait is not dyn compatible...
LL | fn qiz();
| ^^^ ...because associated function `qiz` has no `self` parameter
= help: only type `Foo` implements `Qiz`; consider using it directly instead.
= note: required for the cast from `&Foo` to `&'static (dyn Qiz + 'static)`
help: consider turning `qiz` into a method by giving it a `&self` argument
|
LL | fn qiz(&self);
| +++++
help: alternatively, consider constraining `qiz` so it does not apply to trait objects
|
LL | fn qiz() where Self: Sized;
| +++++++++++++++++
error[E0038]: the trait `Qiz` is not dyn compatible
--> $DIR/issue-19380.rs:16:31
|
@ -71,6 +46,6 @@ help: alternatively, consider constraining `qiz` so it does not apply to trait o
LL | fn qiz() where Self: Sized;
| +++++++++++++++++
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -15,5 +15,4 @@ pub fn main() {
// Check that this does not segfault.
<dyn X as X>::foo(&());
//~^ ERROR the trait `X` is not dyn compatible
//~| ERROR the trait `X` is not dyn compatible
}

View file

@ -15,24 +15,6 @@ LL | fn foo(&self) where Self: Trait;
= help: consider moving `foo` to another trait
= help: only type `()` implements `X`; consider using it directly instead.
error[E0038]: the trait `X` is not dyn compatible
--> $DIR/issue-50781.rs:16:23
|
LL | <dyn X as X>::foo(&());
| ^^^ `X` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/issue-50781.rs:4:8
|
LL | trait X {
| - this trait is not dyn compatible...
LL | fn foo(&self) where Self: Trait;
| ^^^ ...because method `foo` references the `Self` type in its `where` clause
= help: consider moving `foo` to another trait
= help: only type `()` implements `X`; consider using it directly instead.
= note: required for the cast from `&()` to `&dyn X`
error[E0038]: the trait `X` is not dyn compatible
--> $DIR/issue-50781.rs:16:6
|
@ -50,6 +32,6 @@ LL | fn foo(&self) where Self: Trait;
= help: consider moving `foo` to another trait
= help: only type `()` implements `X`; consider using it directly instead.
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0038`.

View file

@ -22,7 +22,6 @@ fn b() {
let y = &x;
let z = &x as &dyn Foo;
//~^ ERROR E0038
//~| ERROR E0038
}
fn main() { }

View file

@ -34,23 +34,7 @@ LL | trait Foo : Copy {
| |
| this trait is not dyn compatible...
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/kindck-inherited-copy-bound.rs:23:13
|
LL | let z = &x as &dyn Foo;
| ^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/kindck-inherited-copy-bound.rs:6:13
|
LL | trait Foo : Copy {
| --- ^^^^ ...because it requires `Self: Sized`
| |
| this trait is not dyn compatible...
= note: required for the cast from `&Box<{integer}>` to `&dyn Foo`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0038, E0277.
For more information about an error, try `rustc --explain E0038`.

View file

@ -0,0 +1,15 @@
//@ check-pass
//@ run-rustfix
#![allow(dead_code)]
#![warn(unused_braces)]
use std::cmp::Ordering;
#[rustfmt::skip]
fn ptr_cmp<T: ?Sized>(p1: *const T, p2: *const T) -> Ordering {
#[expect(ambiguous_wide_pointer_comparisons)] p1.cmp(&p2)
//~^ WARN unnecessary braces around block return value
}
fn main() {}

View file

@ -0,0 +1,15 @@
//@ check-pass
//@ run-rustfix
#![allow(dead_code)]
#![warn(unused_braces)]
use std::cmp::Ordering;
#[rustfmt::skip]
fn ptr_cmp<T: ?Sized>(p1: *const T, p2: *const T) -> Ordering {
{ #[expect(ambiguous_wide_pointer_comparisons)] p1.cmp(&p2) }
//~^ WARN unnecessary braces around block return value
}
fn main() {}

View file

@ -0,0 +1,19 @@
warning: unnecessary braces around block return value
--> $DIR/unused-braces-attrs-issue-141549.rs:11:5
|
LL | { #[expect(ambiguous_wide_pointer_comparisons)] p1.cmp(&p2) }
| ^^ ^^
|
note: the lint level is defined here
--> $DIR/unused-braces-attrs-issue-141549.rs:5:9
|
LL | #![warn(unused_braces)]
| ^^^^^^^^^^^^^
help: remove these braces
|
LL - { #[expect(ambiguous_wide_pointer_comparisons)] p1.cmp(&p2) }
LL + #[expect(ambiguous_wide_pointer_comparisons)] p1.cmp(&p2)
|
warning: 1 warning emitted

View file

@ -28,7 +28,6 @@ impl Bar for usize {
fn make_foo() {
let x = Rc::new(5usize) as Rc<dyn Foo>;
//~^ ERROR E0038
//~| ERROR E0038
}
fn make_bar() {

View file

@ -17,26 +17,6 @@ LL | fn foo(self: &Rc<Self>) -> usize;
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
= help: only type `usize` implements `Foo`; consider using it directly instead.
error[E0038]: the trait `Foo` is not dyn compatible
--> $DIR/arbitrary-self-types-dyn-incompatible.rs:29:13
|
LL | fn foo(self: &Rc<Self>) -> usize;
| --------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
...
LL | let x = Rc::new(5usize) as Rc<dyn Foo>;
| ^^^^^^^^^^^^^^^ `Foo` is not dyn compatible
|
note: for a trait to be dyn compatible it needs to allow building a vtable
for more information, visit <https://doc.rust-lang.org/reference/items/traits.html#dyn-compatibility>
--> $DIR/arbitrary-self-types-dyn-incompatible.rs:4:18
|
LL | trait Foo {
| --- this trait is not dyn compatible...
LL | fn foo(self: &Rc<Self>) -> usize;
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
= help: only type `usize` implements `Foo`; consider using it directly instead.
= note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>`
error: aborting due to 2 previous errors
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0038`.

Some files were not shown because too many files have changed in this diff Show more