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:
commit
2805e1dc4c
117 changed files with 740 additions and 1367 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(',');
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()),
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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![];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
8
src/doc/unstable-book/README.md
Normal file
8
src/doc/unstable-book/README.md
Normal 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.
|
||||
|
|
@ -0,0 +1 @@
|
|||
# Compiler environment variables
|
||||
|
|
@ -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?
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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, ()))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)?;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ trait Bar {
|
|||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -18,5 +18,4 @@ fn main() {
|
|||
let mut thing = Thing;
|
||||
let test: &mut dyn Bar = &mut thing;
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -17,5 +17,4 @@ impl Foo for Bar {}
|
|||
fn main() {
|
||||
let b: Box<dyn Foo> = Box::new(Bar);
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ trait Bar
|
|||
fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ trait Bar: Sized {
|
|||
fn make_bar<T: Bar>(t: &T) -> &dyn Bar {
|
||||
//~^ ERROR E0038
|
||||
t
|
||||
//~^ ERROR E0038
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -17,6 +17,5 @@ fn main() {
|
|||
let mut thing = Thing;
|
||||
let test: &dyn Bar = &mut thing;
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
foo(test);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -15,6 +15,5 @@ struct Bar {
|
|||
const FOO : Foo = Foo;
|
||||
const BAR : Bar = Bar { foos: &[&FOO]};
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ fn b() {
|
|||
let y = &x;
|
||||
let z = &x as &dyn Foo;
|
||||
//~^ ERROR E0038
|
||||
//~| ERROR E0038
|
||||
}
|
||||
|
||||
fn main() { }
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
|
|||
15
tests/ui/lint/unused/unused-braces-attrs-issue-141549.fixed
Normal file
15
tests/ui/lint/unused/unused-braces-attrs-issue-141549.fixed
Normal 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() {}
|
||||
15
tests/ui/lint/unused/unused-braces-attrs-issue-141549.rs
Normal file
15
tests/ui/lint/unused/unused-braces-attrs-issue-141549.rs
Normal 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() {}
|
||||
19
tests/ui/lint/unused/unused-braces-attrs-issue-141549.stderr
Normal file
19
tests/ui/lint/unused/unused-braces-attrs-issue-141549.stderr
Normal 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
|
||||
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue