Auto merge of #109941 - compiler-errors:rollup-5lsst2u, r=compiler-errors
Rollup of 9 pull requests Successful merges: - #109723 (Pull some tuple variant fields out into their own struct) - #109838 (Fix `non_exhaustive_omitted_patterns` lint span) - #109901 (Enforce VarDebugInfo::Place in MIR validation.) - #109913 (Doc-comment `IndexVec::from_elem` and use it in a few more places) - #109914 (Emit feature error for parenthesized generics in associated type bounds) - #109919 (rustdoc: escape GAT args in more cases) - #109937 (Don't collect return-position impl traits for documentation) - #109938 (Move a const-prop-lint specific hack from mir interpret to const-prop-lint and make it fallible) - #109940 (Add regression test for #93911) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
540a50df0f
@ -2890,6 +2890,20 @@ pub struct Fn {
|
||||
pub body: Option<P<Block>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct StaticItem {
|
||||
pub ty: P<Ty>,
|
||||
pub mutability: Mutability,
|
||||
pub expr: Option<P<Expr>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct ConstItem {
|
||||
pub defaultness: Defaultness,
|
||||
pub ty: P<Ty>,
|
||||
pub expr: Option<P<Expr>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub enum ItemKind {
|
||||
/// An `extern crate` item, with the optional *original* crate name if the crate was renamed.
|
||||
@ -2903,11 +2917,11 @@ pub enum ItemKind {
|
||||
/// A static item (`static`).
|
||||
///
|
||||
/// E.g., `static FOO: i32 = 42;` or `static FOO: &'static str = "bar";`.
|
||||
Static(P<Ty>, Mutability, Option<P<Expr>>),
|
||||
Static(Box<StaticItem>),
|
||||
/// A constant item (`const`).
|
||||
///
|
||||
/// E.g., `const FOO: i32 = 42;`.
|
||||
Const(Defaultness, P<Ty>, Option<P<Expr>>),
|
||||
Const(Box<ConstItem>),
|
||||
/// A function declaration (`fn`).
|
||||
///
|
||||
/// E.g., `fn foo(bar: usize) -> usize { .. }`.
|
||||
@ -3023,7 +3037,7 @@ pub type AssocItem = Item<AssocItemKind>;
|
||||
pub enum AssocItemKind {
|
||||
/// An associated constant, `const $ident: $ty $def?;` where `def ::= "=" $expr? ;`.
|
||||
/// If `def` is parsed, then the constant is provided, and otherwise required.
|
||||
Const(Defaultness, P<Ty>, Option<P<Expr>>),
|
||||
Const(Box<ConstItem>),
|
||||
/// An associated function.
|
||||
Fn(Box<Fn>),
|
||||
/// An associated type.
|
||||
@ -3035,7 +3049,7 @@ pub enum AssocItemKind {
|
||||
impl AssocItemKind {
|
||||
pub fn defaultness(&self) -> Defaultness {
|
||||
match *self {
|
||||
Self::Const(defaultness, ..)
|
||||
Self::Const(box ConstItem { defaultness, .. })
|
||||
| Self::Fn(box Fn { defaultness, .. })
|
||||
| Self::Type(box TyAlias { defaultness, .. }) => defaultness,
|
||||
Self::MacCall(..) => Defaultness::Final,
|
||||
@ -3046,7 +3060,7 @@ impl AssocItemKind {
|
||||
impl From<AssocItemKind> for ItemKind {
|
||||
fn from(assoc_item_kind: AssocItemKind) -> ItemKind {
|
||||
match assoc_item_kind {
|
||||
AssocItemKind::Const(a, b, c) => ItemKind::Const(a, b, c),
|
||||
AssocItemKind::Const(item) => ItemKind::Const(item),
|
||||
AssocItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
|
||||
AssocItemKind::Type(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
|
||||
AssocItemKind::MacCall(a) => ItemKind::MacCall(a),
|
||||
@ -3059,7 +3073,7 @@ impl TryFrom<ItemKind> for AssocItemKind {
|
||||
|
||||
fn try_from(item_kind: ItemKind) -> Result<AssocItemKind, ItemKind> {
|
||||
Ok(match item_kind {
|
||||
ItemKind::Const(a, b, c) => AssocItemKind::Const(a, b, c),
|
||||
ItemKind::Const(item) => AssocItemKind::Const(item),
|
||||
ItemKind::Fn(fn_kind) => AssocItemKind::Fn(fn_kind),
|
||||
ItemKind::TyAlias(ty_kind) => AssocItemKind::Type(ty_kind),
|
||||
ItemKind::MacCall(a) => AssocItemKind::MacCall(a),
|
||||
@ -3084,7 +3098,9 @@ pub enum ForeignItemKind {
|
||||
impl From<ForeignItemKind> for ItemKind {
|
||||
fn from(foreign_item_kind: ForeignItemKind) -> ItemKind {
|
||||
match foreign_item_kind {
|
||||
ForeignItemKind::Static(a, b, c) => ItemKind::Static(a, b, c),
|
||||
ForeignItemKind::Static(a, b, c) => {
|
||||
ItemKind::Static(StaticItem { ty: a, mutability: b, expr: c }.into())
|
||||
}
|
||||
ForeignItemKind::Fn(fn_kind) => ItemKind::Fn(fn_kind),
|
||||
ForeignItemKind::TyAlias(ty_alias_kind) => ItemKind::TyAlias(ty_alias_kind),
|
||||
ForeignItemKind::MacCall(a) => ItemKind::MacCall(a),
|
||||
@ -3097,7 +3113,9 @@ impl TryFrom<ItemKind> for ForeignItemKind {
|
||||
|
||||
fn try_from(item_kind: ItemKind) -> Result<ForeignItemKind, ItemKind> {
|
||||
Ok(match item_kind {
|
||||
ItemKind::Static(a, b, c) => ForeignItemKind::Static(a, b, c),
|
||||
ItemKind::Static(box StaticItem { ty: a, mutability: b, expr: c }) => {
|
||||
ForeignItemKind::Static(a, b, c)
|
||||
}
|
||||
ItemKind::Fn(fn_kind) => ForeignItemKind::Fn(fn_kind),
|
||||
ItemKind::TyAlias(ty_alias_kind) => ForeignItemKind::TyAlias(ty_alias_kind),
|
||||
ItemKind::MacCall(a) => ForeignItemKind::MacCall(a),
|
||||
@ -3114,8 +3132,8 @@ mod size_asserts {
|
||||
use super::*;
|
||||
use rustc_data_structures::static_assert_size;
|
||||
// tidy-alphabetical-start
|
||||
static_assert_size!(AssocItem, 104);
|
||||
static_assert_size!(AssocItemKind, 32);
|
||||
static_assert_size!(AssocItem, 88);
|
||||
static_assert_size!(AssocItemKind, 16);
|
||||
static_assert_size!(Attribute, 32);
|
||||
static_assert_size!(Block, 32);
|
||||
static_assert_size!(Expr, 72);
|
||||
|
@ -7,10 +7,10 @@
|
||||
//! a `MutVisitor` renaming item names in a module will miss all of those
|
||||
//! that are created by the expansion of a macro.
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::ptr::P;
|
||||
use crate::token::{self, Token};
|
||||
use crate::tokenstream::*;
|
||||
use crate::{ast::*, StaticItem};
|
||||
|
||||
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
@ -1030,14 +1030,12 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
match kind {
|
||||
ItemKind::ExternCrate(_orig_name) => {}
|
||||
ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
|
||||
ItemKind::Static(ty, _, expr) => {
|
||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
|
||||
vis.visit_ty(ty);
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
}
|
||||
ItemKind::Const(defaultness, ty, expr) => {
|
||||
visit_defaultness(defaultness, vis);
|
||||
vis.visit_ty(ty);
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
ItemKind::Const(item) => {
|
||||
visit_const_item(item, vis);
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
|
||||
visit_defaultness(defaultness, vis);
|
||||
@ -1120,10 +1118,8 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
|
||||
visitor.visit_vis(vis);
|
||||
visit_attrs(attrs, visitor);
|
||||
match kind {
|
||||
AssocItemKind::Const(defaultness, ty, expr) => {
|
||||
visit_defaultness(defaultness, visitor);
|
||||
visitor.visit_ty(ty);
|
||||
visit_opt(expr, |expr| visitor.visit_expr(expr));
|
||||
AssocItemKind::Const(item) => {
|
||||
visit_const_item(item, visitor);
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { defaultness, generics, sig, body }) => {
|
||||
visit_defaultness(defaultness, visitor);
|
||||
@ -1153,6 +1149,15 @@ pub fn noop_flat_map_assoc_item<T: MutVisitor>(
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
fn visit_const_item<T: MutVisitor>(
|
||||
ConstItem { defaultness, ty, expr }: &mut ConstItem,
|
||||
visitor: &mut T,
|
||||
) {
|
||||
visit_defaultness(defaultness, visitor);
|
||||
visitor.visit_ty(ty);
|
||||
visit_opt(expr, |expr| visitor.visit_expr(expr));
|
||||
}
|
||||
|
||||
pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
|
||||
let FnHeader { unsafety, asyncness, constness, ext: _ } = header;
|
||||
visit_constness(constness, vis);
|
||||
|
@ -13,7 +13,7 @@
|
||||
//! instance, a walker looking for item names in a module will miss all of
|
||||
//! those that are created by the expansion of a macro.
|
||||
|
||||
use crate::ast::*;
|
||||
use crate::{ast::*, StaticItem};
|
||||
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::Span;
|
||||
@ -305,8 +305,9 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
match &item.kind {
|
||||
ItemKind::ExternCrate(_) => {}
|
||||
ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false),
|
||||
ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => {
|
||||
visitor.visit_ty(typ);
|
||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr })
|
||||
| ItemKind::Const(box ConstItem { ty, expr, .. }) => {
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => {
|
||||
@ -674,7 +675,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem,
|
||||
visitor.visit_ident(ident);
|
||||
walk_list!(visitor, visit_attribute, attrs);
|
||||
match kind {
|
||||
AssocItemKind::Const(_, ty, expr) => {
|
||||
AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
|
||||
visitor.visit_ty(ty);
|
||||
walk_list!(visitor, visit_expr, expr);
|
||||
}
|
||||
|
@ -229,12 +229,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
|
||||
self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs)
|
||||
}
|
||||
ItemKind::Static(t, m, e) => {
|
||||
ItemKind::Static(box ast::StaticItem { ty: t, mutability: m, expr: e }) => {
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
hir::ItemKind::Static(ty, *m, body_id)
|
||||
}
|
||||
ItemKind::Const(_, t, e) => {
|
||||
let (ty, body_id) = self.lower_const_item(t, span, e.as_deref());
|
||||
ItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
|
||||
let (ty, body_id) = self.lower_const_item(ty, span, expr.as_deref());
|
||||
hir::ItemKind::Const(ty, body_id)
|
||||
}
|
||||
ItemKind::Fn(box Fn {
|
||||
@ -708,10 +708,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
let trait_item_def_id = hir_id.expect_owner();
|
||||
|
||||
let (generics, kind, has_default) = match &i.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
|
||||
let ty =
|
||||
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
|
||||
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
|
||||
let body = expr.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
|
||||
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { sig, generics, body: None, .. }) => {
|
||||
@ -809,7 +809,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
self.lower_attrs(hir_id, &i.attrs);
|
||||
|
||||
let (generics, kind) = match &i.kind {
|
||||
AssocItemKind::Const(_, ty, expr) => {
|
||||
AssocItemKind::Const(box ConstItem { ty, expr, .. }) => {
|
||||
let ty =
|
||||
self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
|
||||
(
|
||||
|
@ -9,8 +9,8 @@
|
||||
use itertools::{Either, Itertools};
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::walk_list;
|
||||
use rustc_ast::*;
|
||||
use rustc_ast::{walk_list, StaticItem};
|
||||
use rustc_ast_pretty::pprust::{self, State};
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_macros::Subdiagnostic;
|
||||
@ -983,14 +983,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
self.err_handler().emit_err(errors::FieldlessUnion { span: item.span });
|
||||
}
|
||||
}
|
||||
ItemKind::Const(def, .., None) => {
|
||||
self.check_defaultness(item.span, *def);
|
||||
ItemKind::Const(box ConstItem { defaultness, expr: None, .. }) => {
|
||||
self.check_defaultness(item.span, *defaultness);
|
||||
self.session.emit_err(errors::ConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
ItemKind::Static(.., None) => {
|
||||
ItemKind::Static(box StaticItem { expr: None, .. }) => {
|
||||
self.session.emit_err(errors::StaticWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
@ -1259,13 +1259,11 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
||||
if ctxt == AssocCtxt::Impl {
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, _, body) => {
|
||||
if body.is_none() {
|
||||
self.session.emit_err(errors::AssocConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
AssocItemKind::Const(box ConstItem { expr: None, .. }) => {
|
||||
self.session.emit_err(errors::AssocConstWithoutBody {
|
||||
span: item.span,
|
||||
replace_span: self.ending_semi_or_hi(item.span),
|
||||
});
|
||||
}
|
||||
AssocItemKind::Fn(box Fn { body, .. }) => {
|
||||
if body.is_none() {
|
||||
|
@ -485,17 +485,10 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
if let Some(args) = constraint.gen_args.as_ref()
|
||||
&& matches!(
|
||||
args,
|
||||
ast::GenericArgs::ReturnTypeNotation(..) | ast::GenericArgs::Parenthesized(..)
|
||||
ast::GenericArgs::ReturnTypeNotation(..)
|
||||
)
|
||||
{
|
||||
// RTN is gated elsewhere, and parenthesized args will turn into
|
||||
// another error.
|
||||
if matches!(args, ast::GenericArgs::Parenthesized(..)) {
|
||||
self.sess.delay_span_bug(
|
||||
constraint.span,
|
||||
"should have emitted a parenthesized generics error",
|
||||
);
|
||||
}
|
||||
// RTN is gated below with a `gate_all`.
|
||||
} else {
|
||||
gate_feature_post!(
|
||||
&self,
|
||||
|
@ -2,6 +2,7 @@ use crate::pp::Breaks::Inconsistent;
|
||||
use crate::pprust::state::delimited::IterDelimited;
|
||||
use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT};
|
||||
|
||||
use ast::StaticItem;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::GenericBound;
|
||||
use rustc_ast::ModKind;
|
||||
@ -156,7 +157,7 @@ impl<'a> State<'a> {
|
||||
self.print_use_tree(tree);
|
||||
self.word(";");
|
||||
}
|
||||
ast::ItemKind::Static(ty, mutbl, body) => {
|
||||
ast::ItemKind::Static(box StaticItem { ty, mutability: mutbl, expr: body }) => {
|
||||
let def = ast::Defaultness::Final;
|
||||
self.print_item_const(
|
||||
item.ident,
|
||||
@ -167,8 +168,15 @@ impl<'a> State<'a> {
|
||||
def,
|
||||
);
|
||||
}
|
||||
ast::ItemKind::Const(def, ty, body) => {
|
||||
self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def);
|
||||
ast::ItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => {
|
||||
self.print_item_const(
|
||||
item.ident,
|
||||
None,
|
||||
ty,
|
||||
expr.as_deref(),
|
||||
&item.vis,
|
||||
*defaultness,
|
||||
);
|
||||
}
|
||||
ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
|
||||
self.print_fn_full(
|
||||
@ -507,8 +515,8 @@ impl<'a> State<'a> {
|
||||
ast::AssocItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => {
|
||||
self.print_fn_full(sig, ident, generics, vis, *defaultness, body.as_deref(), attrs);
|
||||
}
|
||||
ast::AssocItemKind::Const(def, ty, body) => {
|
||||
self.print_item_const(ident, None, ty, body.as_deref(), vis, *def);
|
||||
ast::AssocItemKind::Const(box ast::ConstItem { defaultness, ty, expr }) => {
|
||||
self.print_item_const(ident, None, ty, expr.as_deref(), vis, *defaultness);
|
||||
}
|
||||
ast::AssocItemKind::Type(box ast::TyAlias {
|
||||
defaultness,
|
||||
|
@ -63,7 +63,7 @@ impl LocalUseMap {
|
||||
elements: &RegionValueElements,
|
||||
body: &Body<'_>,
|
||||
) -> Self {
|
||||
let nones = IndexVec::from_elem_n(None, body.local_decls.len());
|
||||
let nones = IndexVec::from_elem(None, &body.local_decls);
|
||||
let mut local_use_map = LocalUseMap {
|
||||
first_def_at: nones.clone(),
|
||||
first_use_at: nones.clone(),
|
||||
@ -76,7 +76,7 @@ impl LocalUseMap {
|
||||
}
|
||||
|
||||
let mut locals_with_use_data: IndexVec<Local, bool> =
|
||||
IndexVec::from_elem_n(false, body.local_decls.len());
|
||||
IndexVec::from_elem(false, &body.local_decls);
|
||||
live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
|
||||
|
||||
LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
|
||||
|
@ -25,12 +25,12 @@ pub fn expand(
|
||||
// FIXME - if we get deref patterns, use them to reduce duplication here
|
||||
let (item, is_stmt, ty_span) =
|
||||
if let Annotatable::Item(item) = &item
|
||||
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||
&& let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind
|
||||
{
|
||||
(item, false, ecx.with_def_site_ctxt(ty.span))
|
||||
} else if let Annotatable::Stmt(stmt) = &item
|
||||
&& let StmtKind::Item(item) = &stmt.kind
|
||||
&& let ItemKind::Static(ty, ..) = &item.kind
|
||||
&& let ItemKind::Static(box ast::StaticItem { ty, ..}) = &item.kind
|
||||
{
|
||||
(item, true, ecx.with_def_site_ctxt(ty.span))
|
||||
} else {
|
||||
|
@ -254,25 +254,27 @@ pub fn expand_test_or_bench(
|
||||
|
||||
let location_info = get_location_info(cx, &item);
|
||||
|
||||
let mut test_const = cx.item(
|
||||
sp,
|
||||
Ident::new(item.ident.name, sp),
|
||||
thin_vec![
|
||||
// #[cfg(test)]
|
||||
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
|
||||
// #[rustc_test_marker = "test_case_sort_key"]
|
||||
cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
|
||||
],
|
||||
// const $ident: test::TestDescAndFn =
|
||||
ast::ItemKind::Const(
|
||||
ast::Defaultness::Final,
|
||||
cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
// test::TestDescAndFn {
|
||||
Some(
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDescAndFn"),
|
||||
thin_vec![
|
||||
let mut test_const =
|
||||
cx.item(
|
||||
sp,
|
||||
Ident::new(item.ident.name, sp),
|
||||
thin_vec![
|
||||
// #[cfg(test)]
|
||||
cx.attr_nested_word(sym::cfg, sym::test, attr_sp),
|
||||
// #[rustc_test_marker = "test_case_sort_key"]
|
||||
cx.attr_name_value_str(sym::rustc_test_marker, test_path_symbol, attr_sp),
|
||||
],
|
||||
// const $ident: test::TestDescAndFn =
|
||||
ast::ItemKind::Const(
|
||||
ast::ConstItem {
|
||||
defaultness: ast::Defaultness::Final,
|
||||
ty: cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))),
|
||||
// test::TestDescAndFn {
|
||||
expr: Some(
|
||||
cx.expr_struct(
|
||||
sp,
|
||||
test_path("TestDescAndFn"),
|
||||
thin_vec![
|
||||
// desc: test::TestDesc {
|
||||
field(
|
||||
"desc",
|
||||
@ -359,10 +361,12 @@ pub fn expand_test_or_bench(
|
||||
// testfn: test::StaticTestFn(...) | test::StaticBenchFn(...)
|
||||
field("testfn", test_fn), // }
|
||||
],
|
||||
), // }
|
||||
), // }
|
||||
),
|
||||
}
|
||||
.into(),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
test_const = test_const.map(|mut tc| {
|
||||
tc.vis.kind = ast::VisibilityKind::Public;
|
||||
tc
|
||||
|
@ -165,11 +165,15 @@ fn calculate_debuginfo_offset<
|
||||
mir::ProjectionElem::Downcast(_, variant) => {
|
||||
place = place.downcast(bx, variant);
|
||||
}
|
||||
_ => span_bug!(
|
||||
var.source_info.span,
|
||||
"unsupported var debuginfo place `{:?}`",
|
||||
mir::Place { local, projection: var.projection },
|
||||
),
|
||||
_ => {
|
||||
// Sanity check for `can_use_in_debuginfo`.
|
||||
debug_assert!(!elem.can_use_in_debuginfo());
|
||||
span_bug!(
|
||||
var.source_info.span,
|
||||
"unsupported var debuginfo place `{:?}`",
|
||||
mir::Place { local, projection: var.projection },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,14 +612,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
span: Option<Span>,
|
||||
layout: Option<TyAndLayout<'tcx>>,
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
// FIXME(const_prop): normalization needed b/c const prop lint in
|
||||
// `mir_drops_elaborated_and_const_checked`, which happens before
|
||||
// optimized MIR. Only after optimizing the MIR can we guarantee
|
||||
// that the `RevealAll` pass has happened and that the body's consts
|
||||
// are normalized, so any call to resolve before that needs to be
|
||||
// manually normalized.
|
||||
let val = self.tcx.normalize_erasing_regions(self.param_env, *val);
|
||||
match val {
|
||||
match *val {
|
||||
mir::ConstantKind::Ty(ct) => {
|
||||
let ty = ct.ty();
|
||||
let valtree = self.eval_ty_constant(ct, span)?;
|
||||
|
@ -5,13 +5,12 @@ use rustc_index::bit_set::BitSet;
|
||||
use rustc_index::vec::IndexVec;
|
||||
use rustc_infer::traits::Reveal;
|
||||
use rustc_middle::mir::interpret::Scalar;
|
||||
use rustc_middle::mir::visit::NonUseContext::VarDebugInfo;
|
||||
use rustc_middle::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
|
||||
use rustc_middle::mir::{
|
||||
traversal, BasicBlock, BinOp, Body, BorrowKind, CastKind, CopyNonOverlapping, Local, Location,
|
||||
MirPass, MirPhase, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
|
||||
RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
|
||||
TerminatorKind, UnOp, START_BLOCK,
|
||||
TerminatorKind, UnOp, VarDebugInfo, VarDebugInfoContents, START_BLOCK,
|
||||
};
|
||||
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt};
|
||||
use rustc_mir_dataflow::impls::MaybeStorageLive;
|
||||
@ -419,13 +418,49 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
self.super_projection_elem(local, proj_base, elem, context, location);
|
||||
}
|
||||
|
||||
fn visit_var_debug_info(&mut self, debuginfo: &VarDebugInfo<'tcx>) {
|
||||
let check_place = |place: Place<'_>| {
|
||||
if place.projection.iter().any(|p| !p.can_use_in_debuginfo()) {
|
||||
self.fail(
|
||||
START_BLOCK.start_location(),
|
||||
format!("illegal place {:?} in debuginfo for {:?}", place, debuginfo.name),
|
||||
);
|
||||
}
|
||||
};
|
||||
match debuginfo.value {
|
||||
VarDebugInfoContents::Const(_) => {}
|
||||
VarDebugInfoContents::Place(place) => check_place(place),
|
||||
VarDebugInfoContents::Composite { ty, ref fragments } => {
|
||||
for f in fragments {
|
||||
check_place(f.contents);
|
||||
if ty.is_union() || ty.is_enum() {
|
||||
self.fail(
|
||||
START_BLOCK.start_location(),
|
||||
format!("invalid type {:?} for composite debuginfo", ty),
|
||||
);
|
||||
}
|
||||
if f.projection.iter().any(|p| !matches!(p, PlaceElem::Field(..))) {
|
||||
self.fail(
|
||||
START_BLOCK.start_location(),
|
||||
format!(
|
||||
"illegal projection {:?} in debuginfo for {:?}",
|
||||
f.projection, debuginfo.name
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.super_var_debug_info(debuginfo);
|
||||
}
|
||||
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, cntxt: PlaceContext, location: Location) {
|
||||
// Set off any `bug!`s in the type computation code
|
||||
let _ = place.ty(&self.body.local_decls, self.tcx);
|
||||
|
||||
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial)
|
||||
&& place.projection.len() > 1
|
||||
&& cntxt != PlaceContext::NonUse(VarDebugInfo)
|
||||
&& cntxt != PlaceContext::NonUse(NonUseContext::VarDebugInfo)
|
||||
&& place.projection[1..].contains(&ProjectionElem::Deref)
|
||||
{
|
||||
self.fail(location, format!("{:?}, has deref at the wrong place", place));
|
||||
|
@ -620,10 +620,15 @@ impl<'a> ExtCtxt<'a> {
|
||||
span: Span,
|
||||
name: Ident,
|
||||
ty: P<ast::Ty>,
|
||||
mutbl: ast::Mutability,
|
||||
mutability: ast::Mutability,
|
||||
expr: P<ast::Expr>,
|
||||
) -> P<ast::Item> {
|
||||
self.item(span, name, AttrVec::new(), ast::ItemKind::Static(ty, mutbl, Some(expr)))
|
||||
self.item(
|
||||
span,
|
||||
name,
|
||||
AttrVec::new(),
|
||||
ast::ItemKind::Static(ast::StaticItem { ty, mutability, expr: Some(expr) }.into()),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn item_const(
|
||||
@ -633,8 +638,13 @@ impl<'a> ExtCtxt<'a> {
|
||||
ty: P<ast::Ty>,
|
||||
expr: P<ast::Expr>,
|
||||
) -> P<ast::Item> {
|
||||
let def = ast::Defaultness::Final;
|
||||
self.item(span, name, AttrVec::new(), ast::ItemKind::Const(def, ty, Some(expr)))
|
||||
let defaultness = ast::Defaultness::Final;
|
||||
self.item(
|
||||
span,
|
||||
name,
|
||||
AttrVec::new(),
|
||||
ast::ItemKind::Const(ast::ConstItem { defaultness, ty, expr: Some(expr) }.into()),
|
||||
)
|
||||
}
|
||||
|
||||
// Builds `#[name]`.
|
||||
|
@ -129,6 +129,17 @@ impl<I: Idx, T> IndexVec<I, T> {
|
||||
IndexVec { raw: Vec::with_capacity(capacity), _marker: PhantomData }
|
||||
}
|
||||
|
||||
/// Creates a new vector with a copy of `elem` for each index in `universe`.
|
||||
///
|
||||
/// Thus `IndexVec::from_elem(elem, &universe)` is equivalent to
|
||||
/// `IndexVec::<I, _>::from_elem_n(elem, universe.len())`. That can help
|
||||
/// type inference as it ensures that the resulting vector uses the same
|
||||
/// index type as `universe`, rather than something potentially surprising.
|
||||
///
|
||||
/// For example, if you want to store data for each local in a MIR body,
|
||||
/// using `let mut uses = IndexVec::from_elem(vec![], &body.local_decls);`
|
||||
/// ensures that `uses` is an `IndexVec<Local, _>`, and thus can give
|
||||
/// better error messages later if one accidentally mismatches indices.
|
||||
#[inline]
|
||||
pub fn from_elem<S>(elem: T, universe: &IndexSlice<I, S>) -> Self
|
||||
where
|
||||
|
@ -203,7 +203,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
|
||||
|
||||
// Tracks the `VarSubVar` constraints generated for each region vid. We
|
||||
// later use this to expand across vids.
|
||||
let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len());
|
||||
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
|
||||
// Tracks the changed region vids.
|
||||
let mut changes = Vec::new();
|
||||
for constraint in self.data.constraints.keys() {
|
||||
|
@ -805,7 +805,9 @@ trait UnusedDelimLint {
|
||||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
||||
use ast::ItemKind::*;
|
||||
|
||||
if let Const(.., Some(expr)) | Static(.., Some(expr)) = &item.kind {
|
||||
if let Const(box ast::ConstItem { expr: Some(expr), .. })
|
||||
| Static(box ast::StaticItem { expr: Some(expr), .. }) = &item.kind
|
||||
{
|
||||
self.check_unused_delims_expr(
|
||||
cx,
|
||||
expr,
|
||||
|
@ -1036,8 +1036,7 @@ impl<'tcx> LocalDecl<'tcx> {
|
||||
|
||||
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub enum VarDebugInfoContents<'tcx> {
|
||||
/// NOTE(eddyb) There's an unenforced invariant that this `Place` is
|
||||
/// based on a `Local`, not a `Static`, and contains no indexing.
|
||||
/// This `Place` only contains projection which satisfy `can_use_in_debuginfo`.
|
||||
Place(Place<'tcx>),
|
||||
Const(Constant<'tcx>),
|
||||
/// The user variable's data is split across several fragments,
|
||||
@ -1047,6 +1046,7 @@ pub enum VarDebugInfoContents<'tcx> {
|
||||
/// the underlying debuginfo feature this relies on.
|
||||
Composite {
|
||||
/// Type of the original user variable.
|
||||
/// This cannot contain a union or an enum.
|
||||
ty: Ty<'tcx>,
|
||||
/// All the parts of the original user variable, which ended
|
||||
/// up in disjoint places, due to optimizations.
|
||||
@ -1075,17 +1075,16 @@ pub struct VarDebugInfoFragment<'tcx> {
|
||||
/// Where in the composite user variable this fragment is,
|
||||
/// represented as a "projection" into the composite variable.
|
||||
/// At lower levels, this corresponds to a byte/bit range.
|
||||
// NOTE(eddyb) there's an unenforced invariant that this contains
|
||||
// only `Field`s, and not into `enum` variants or `union`s.
|
||||
// FIXME(eddyb) support this for `enum`s by either using DWARF's
|
||||
///
|
||||
/// This can only contain `PlaceElem::Field`.
|
||||
// FIXME support this for `enum`s by either using DWARF's
|
||||
// more advanced control-flow features (unsupported by LLVM?)
|
||||
// to match on the discriminant, or by using custom type debuginfo
|
||||
// with non-overlapping variants for the composite variable.
|
||||
pub projection: Vec<PlaceElem<'tcx>>,
|
||||
|
||||
/// Where the data for this fragment can be found.
|
||||
// NOTE(eddyb) There's an unenforced invariant that this `Place` is
|
||||
// contains no indexing (with a non-constant index).
|
||||
/// This `Place` only contains projection which satisfy `can_use_in_debuginfo`.
|
||||
pub contents: Place<'tcx>,
|
||||
}
|
||||
|
||||
@ -1538,6 +1537,17 @@ impl<V, T> ProjectionElem<V, T> {
|
||||
pub fn is_field_to(&self, f: FieldIdx) -> bool {
|
||||
matches!(*self, Self::Field(x, _) if x == f)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is accepted inside `VarDebugInfoContents::Place`.
|
||||
pub fn can_use_in_debuginfo(&self) -> bool {
|
||||
match self {
|
||||
Self::Deref | Self::Downcast(_, _) | Self::Field(_, _) => true,
|
||||
Self::ConstantIndex { .. }
|
||||
| Self::Index(_)
|
||||
| Self::OpaqueCast(_)
|
||||
| Self::Subslice { .. } => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Alias for projections as they appear in `UserTypeProjection`, where we
|
||||
|
@ -193,9 +193,9 @@ impl<'tcx> NormalizeAfterErasingRegionsFolder<'tcx> {
|
||||
let arg = self.param_env.and(arg);
|
||||
|
||||
self.tcx.try_normalize_generic_arg_after_erasing_regions(arg).unwrap_or_else(|_| bug!(
|
||||
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
|
||||
arg.value
|
||||
))
|
||||
"Failed to normalize {:?}, maybe try to call `try_normalize_erasing_regions` instead",
|
||||
arg.value
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1154,8 +1154,9 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
||||
fn wildcards_from_tys(
|
||||
cx: &MatchCheckCtxt<'p, 'tcx>,
|
||||
tys: impl IntoIterator<Item = Ty<'tcx>>,
|
||||
span: Span,
|
||||
) -> Self {
|
||||
Fields::from_iter(cx, tys.into_iter().map(DeconstructedPat::wildcard))
|
||||
Fields::from_iter(cx, tys.into_iter().map(|ty| DeconstructedPat::wildcard(ty, span)))
|
||||
}
|
||||
|
||||
// In the cases of either a `#[non_exhaustive]` field list or a non-public field, we hide
|
||||
@ -1191,18 +1192,18 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
||||
pub(super) fn wildcards(pcx: &PatCtxt<'_, 'p, 'tcx>, constructor: &Constructor<'tcx>) -> Self {
|
||||
let ret = match constructor {
|
||||
Single | Variant(_) => match pcx.ty.kind() {
|
||||
ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter()),
|
||||
ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty)),
|
||||
ty::Tuple(fs) => Fields::wildcards_from_tys(pcx.cx, fs.iter(), pcx.span),
|
||||
ty::Ref(_, rty, _) => Fields::wildcards_from_tys(pcx.cx, once(*rty), pcx.span),
|
||||
ty::Adt(adt, substs) => {
|
||||
if adt.is_box() {
|
||||
// The only legal patterns of type `Box` (outside `std`) are `_` and box
|
||||
// patterns. If we're here we can assume this is a box pattern.
|
||||
Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)))
|
||||
Fields::wildcards_from_tys(pcx.cx, once(substs.type_at(0)), pcx.span)
|
||||
} else {
|
||||
let variant = &adt.variant(constructor.variant_index_for_adt(*adt));
|
||||
let tys = Fields::list_variant_nonhidden_fields(pcx.cx, pcx.ty, variant)
|
||||
.map(|(_, ty)| ty);
|
||||
Fields::wildcards_from_tys(pcx.cx, tys)
|
||||
Fields::wildcards_from_tys(pcx.cx, tys, pcx.span)
|
||||
}
|
||||
}
|
||||
_ => bug!("Unexpected type for `Single` constructor: {:?}", pcx),
|
||||
@ -1210,7 +1211,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> {
|
||||
Slice(slice) => match *pcx.ty.kind() {
|
||||
ty::Slice(ty) | ty::Array(ty, _) => {
|
||||
let arity = slice.arity();
|
||||
Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty))
|
||||
Fields::wildcards_from_tys(pcx.cx, (0..arity).map(|_| ty), pcx.span)
|
||||
}
|
||||
_ => bug!("bad slice pattern {:?} {:?}", constructor, pcx),
|
||||
},
|
||||
@ -1251,8 +1252,8 @@ pub(crate) struct DeconstructedPat<'p, 'tcx> {
|
||||
}
|
||||
|
||||
impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
pub(super) fn wildcard(ty: Ty<'tcx>) -> Self {
|
||||
Self::new(Wildcard, Fields::empty(), ty, DUMMY_SP)
|
||||
pub(super) fn wildcard(ty: Ty<'tcx>, span: Span) -> Self {
|
||||
Self::new(Wildcard, Fields::empty(), ty, span)
|
||||
}
|
||||
|
||||
pub(super) fn new(
|
||||
@ -1269,7 +1270,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
/// `Some(_)`.
|
||||
pub(super) fn wild_from_ctor(pcx: &PatCtxt<'_, 'p, 'tcx>, ctor: Constructor<'tcx>) -> Self {
|
||||
let fields = Fields::wildcards(pcx, &ctor);
|
||||
DeconstructedPat::new(ctor, fields, pcx.ty, DUMMY_SP)
|
||||
DeconstructedPat::new(ctor, fields, pcx.ty, pcx.span)
|
||||
}
|
||||
|
||||
/// Clone this value. This method emphasizes that cloning loses reachability information and
|
||||
@ -1298,7 +1299,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
ty::Tuple(fs) => {
|
||||
ctor = Single;
|
||||
let mut wilds: SmallVec<[_; 2]> =
|
||||
fs.iter().map(DeconstructedPat::wildcard).collect();
|
||||
fs.iter().map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect();
|
||||
for pat in subpatterns {
|
||||
wilds[pat.field.index()] = mkpat(&pat.pattern);
|
||||
}
|
||||
@ -1317,11 +1318,11 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
// normally or through box-patterns. We'll have to figure out a proper
|
||||
// solution when we introduce generalized deref patterns. Also need to
|
||||
// prevent mixing of those two options.
|
||||
let pat = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
|
||||
let pat = if let Some(pat) = pat {
|
||||
let pattern = subpatterns.into_iter().find(|pat| pat.field.index() == 0);
|
||||
let pat = if let Some(pat) = pattern {
|
||||
mkpat(&pat.pattern)
|
||||
} else {
|
||||
DeconstructedPat::wildcard(substs.type_at(0))
|
||||
DeconstructedPat::wildcard(substs.type_at(0), pat.span)
|
||||
};
|
||||
ctor = Single;
|
||||
fields = Fields::singleton(cx, pat);
|
||||
@ -1343,7 +1344,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
ty
|
||||
});
|
||||
let mut wilds: SmallVec<[_; 2]> =
|
||||
tys.map(DeconstructedPat::wildcard).collect();
|
||||
tys.map(|ty| DeconstructedPat::wildcard(ty, pat.span)).collect();
|
||||
for pat in subpatterns {
|
||||
if let Some(i) = field_id_to_id[pat.field.index()] {
|
||||
wilds[i] = mkpat(&pat.pattern);
|
||||
@ -1566,8 +1567,10 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
|
||||
};
|
||||
let prefix = &self.fields.fields[..prefix];
|
||||
let suffix = &self.fields.fields[self_slice.arity() - suffix..];
|
||||
let wildcard: &_ =
|
||||
pcx.cx.pattern_arena.alloc(DeconstructedPat::wildcard(inner_ty));
|
||||
let wildcard: &_ = pcx
|
||||
.cx
|
||||
.pattern_arena
|
||||
.alloc(DeconstructedPat::wildcard(inner_ty, pcx.span));
|
||||
let extra_wildcards = other_slice.arity() - self_slice.arity();
|
||||
let extra_wildcards = (0..extra_wildcards).map(|_| wildcard);
|
||||
prefix.iter().chain(extra_wildcards).chain(suffix).collect()
|
||||
|
@ -604,7 +604,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
|
||||
let new_patterns = if pcx.is_non_exhaustive {
|
||||
// Here we don't want the user to try to list all variants, we want them to add
|
||||
// a wildcard, so we only suggest that.
|
||||
vec![DeconstructedPat::wildcard(pcx.ty)]
|
||||
vec![DeconstructedPat::wildcard(pcx.ty, pcx.span)]
|
||||
} else {
|
||||
let mut split_wildcard = SplitWildcard::new(pcx);
|
||||
split_wildcard.split(pcx, matrix.heads().map(DeconstructedPat::ctor));
|
||||
@ -631,7 +631,7 @@ impl<'p, 'tcx> Usefulness<'p, 'tcx> {
|
||||
.collect();
|
||||
|
||||
if hide_variant_show_wild {
|
||||
new.push(DeconstructedPat::wildcard(pcx.ty));
|
||||
new.push(DeconstructedPat::wildcard(pcx.ty, pcx.span));
|
||||
}
|
||||
|
||||
new
|
||||
@ -734,7 +734,7 @@ impl<'p, 'tcx> Witness<'p, 'tcx> {
|
||||
let arity = ctor.arity(pcx);
|
||||
let pats = self.0.drain((len - arity)..).rev();
|
||||
let fields = Fields::from_iter(pcx.cx, pats);
|
||||
DeconstructedPat::new(ctor.clone(), fields, pcx.ty, DUMMY_SP)
|
||||
DeconstructedPat::new(ctor.clone(), fields, pcx.ty, pcx.span)
|
||||
};
|
||||
|
||||
self.0.push(pat);
|
||||
@ -977,7 +977,7 @@ pub(crate) fn compute_match_usefulness<'p, 'tcx>(
|
||||
})
|
||||
.collect();
|
||||
|
||||
let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty));
|
||||
let wild_pattern = cx.pattern_arena.alloc(DeconstructedPat::wildcard(scrut_ty, DUMMY_SP));
|
||||
let v = PatStack::from_pattern(wild_pattern);
|
||||
let usefulness = is_useful(cx, &matrix, &v, FakeExtraWildcard, scrut_hir_id, false, true);
|
||||
let non_exhaustiveness_witnesses = match usefulness {
|
||||
|
@ -284,7 +284,15 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||
return None;
|
||||
}
|
||||
|
||||
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&c.literal, Some(c.span), None))
|
||||
// Normalization needed b/c const prop lint runs in
|
||||
// `mir_drops_elaborated_and_const_checked`, which happens before
|
||||
// optimized MIR. Only after optimizing the MIR can we guarantee
|
||||
// that the `RevealAll` pass has happened and that the body's consts
|
||||
// are normalized, so any call to resolve before that needs to be
|
||||
// manually normalized.
|
||||
let val = self.tcx.try_normalize_erasing_regions(self.param_env, c.literal).ok()?;
|
||||
|
||||
self.use_ecx(source_info, |this| this.ecx.eval_mir_constant(&val, Some(c.span), None))
|
||||
}
|
||||
|
||||
/// Returns the value, if any, of evaluating `place`.
|
||||
|
@ -37,8 +37,7 @@ impl CoverageGraph {
|
||||
// `SwitchInt` to have multiple targets to the same destination `BasicBlock`, so
|
||||
// de-duplication is required. This is done without reordering the successors.
|
||||
|
||||
let bcbs_len = bcbs.len();
|
||||
let mut seen = IndexVec::from_elem_n(false, bcbs_len);
|
||||
let mut seen = IndexVec::from_elem(false, &bcbs);
|
||||
let successors = IndexVec::from_fn_n(
|
||||
|bcb| {
|
||||
for b in seen.iter_mut() {
|
||||
@ -60,7 +59,7 @@ impl CoverageGraph {
|
||||
bcbs.len(),
|
||||
);
|
||||
|
||||
let mut predecessors = IndexVec::from_elem_n(Vec::new(), bcbs.len());
|
||||
let mut predecessors = IndexVec::from_elem(Vec::new(), &bcbs);
|
||||
for (bcb, bcb_successors) in successors.iter_enumerated() {
|
||||
for &successor in bcb_successors {
|
||||
predecessors[successor].push(bcb);
|
||||
|
@ -3,6 +3,7 @@ use crate::errors;
|
||||
use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
|
||||
use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
|
||||
use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
|
||||
use ast::StaticItem;
|
||||
use rustc_ast::ast::*;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::token::{self, Delimiter, TokenKind};
|
||||
@ -227,7 +228,7 @@ impl<'a> Parser<'a> {
|
||||
self.bump(); // `static`
|
||||
let m = self.parse_mutability();
|
||||
let (ident, ty, expr) = self.parse_item_global(Some(m))?;
|
||||
(ident, ItemKind::Static(ty, m, expr))
|
||||
(ident, ItemKind::Static(Box::new(StaticItem { ty, mutability: m, expr })))
|
||||
} else if let Const::Yes(const_span) = self.parse_constness(Case::Sensitive) {
|
||||
// CONST ITEM
|
||||
if self.token.is_keyword(kw::Impl) {
|
||||
@ -236,7 +237,7 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
self.recover_const_mut(const_span);
|
||||
let (ident, ty, expr) = self.parse_item_global(None)?;
|
||||
(ident, ItemKind::Const(def_(), ty, expr))
|
||||
(ident, ItemKind::Const(Box::new(ConstItem { defaultness: def_(), ty, expr })))
|
||||
}
|
||||
} else if self.check_keyword(kw::Trait) || self.check_auto_or_unsafe_trait_item() {
|
||||
// TRAIT ITEM
|
||||
@ -862,9 +863,13 @@ impl<'a> Parser<'a> {
|
||||
let kind = match AssocItemKind::try_from(kind) {
|
||||
Ok(kind) => kind,
|
||||
Err(kind) => match kind {
|
||||
ItemKind::Static(a, _, b) => {
|
||||
ItemKind::Static(box StaticItem { ty, mutability: _, expr }) => {
|
||||
self.sess.emit_err(errors::AssociatedStaticItemNotAllowed { span });
|
||||
AssocItemKind::Const(Defaultness::Final, a, b)
|
||||
AssocItemKind::Const(Box::new(ConstItem {
|
||||
defaultness: Defaultness::Final,
|
||||
ty,
|
||||
expr,
|
||||
}))
|
||||
}
|
||||
_ => return self.error_bad_item_kind(span, &kind, "`trait`s or `impl`s"),
|
||||
},
|
||||
@ -1114,12 +1119,12 @@ impl<'a> Parser<'a> {
|
||||
let kind = match ForeignItemKind::try_from(kind) {
|
||||
Ok(kind) => kind,
|
||||
Err(kind) => match kind {
|
||||
ItemKind::Const(_, a, b) => {
|
||||
ItemKind::Const(box ConstItem { ty, expr, .. }) => {
|
||||
self.sess.emit_err(errors::ExternItemCannotBeConst {
|
||||
ident_span: ident.span,
|
||||
const_span: span.with_hi(ident.span.lo()),
|
||||
});
|
||||
ForeignItemKind::Static(a, Mutability::Not, b)
|
||||
ForeignItemKind::Static(ty, Mutability::Not, expr)
|
||||
}
|
||||
_ => return self.error_bad_item_kind(span, &kind, "`extern` blocks"),
|
||||
},
|
||||
|
@ -688,8 +688,8 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
||||
}
|
||||
|
||||
// These items live in the value namespace.
|
||||
ItemKind::Static(_, mt, _) => {
|
||||
let res = Res::Def(DefKind::Static(mt), def_id);
|
||||
ItemKind::Static(box ast::StaticItem { mutability, .. }) => {
|
||||
let res = Res::Def(DefKind::Static(mutability), def_id);
|
||||
self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion));
|
||||
}
|
||||
ItemKind::Const(..) => {
|
||||
|
@ -2346,7 +2346,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
});
|
||||
}
|
||||
|
||||
ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(_, ref ty, ref expr) => {
|
||||
ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. })
|
||||
| ItemKind::Const(box ast::ConstItem { ref ty, ref expr, .. }) => {
|
||||
self.with_static_rib(|this| {
|
||||
this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
|
||||
this.visit_ty(ty);
|
||||
@ -2624,11 +2625,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
for item in trait_items {
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
|
||||
self.visit_ty(ty);
|
||||
// Only impose the restrictions of `ConstRibKind` for an
|
||||
// actual constant expression in a provided default.
|
||||
if let Some(expr) = default {
|
||||
if let Some(expr) = expr {
|
||||
// We allow arbitrary const expressions inside of associated consts,
|
||||
// even if they are potentially not const evaluatable.
|
||||
//
|
||||
@ -2799,7 +2800,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
use crate::ResolutionError::*;
|
||||
self.resolve_doc_links(&item.attrs, MaybeExported::ImplItem(trait_id.ok_or(&item.vis)));
|
||||
match &item.kind {
|
||||
AssocItemKind::Const(_, ty, default) => {
|
||||
AssocItemKind::Const(box ast::ConstItem { ty, expr, .. }) => {
|
||||
debug!("resolve_implementation AssocItemKind::Const");
|
||||
// If this is a trait impl, ensure the const
|
||||
// exists in trait
|
||||
@ -2814,7 +2815,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
|
||||
);
|
||||
|
||||
self.visit_ty(ty);
|
||||
if let Some(expr) = default {
|
||||
if let Some(expr) = expr {
|
||||
// We allow arbitrary const expressions inside of associated consts,
|
||||
// even if they are potentially not const evaluatable.
|
||||
//
|
||||
|
@ -522,7 +522,7 @@ fn generator_saved_local_eligibility(
|
||||
use SavedLocalEligibility::*;
|
||||
|
||||
let mut assignments: IndexVec<GeneratorSavedLocal, SavedLocalEligibility> =
|
||||
IndexVec::from_elem_n(Unassigned, info.field_tys.len());
|
||||
IndexVec::from_elem(Unassigned, &info.field_tys);
|
||||
|
||||
// The saved locals not eligible for overlap. These will get
|
||||
// "promoted" to the prefix of our generator.
|
||||
|
@ -1142,22 +1142,21 @@ fn fmt_type<'cx>(
|
||||
// the ugliness comes from inlining across crates where
|
||||
// everything comes in as a fully resolved QPath (hard to
|
||||
// look at).
|
||||
match href(trait_.def_id(), cx) {
|
||||
Ok((ref url, _, ref path)) if !f.alternate() => {
|
||||
write!(
|
||||
f,
|
||||
"<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
|
||||
title=\"type {path}::{name}\">{name}</a>{args}",
|
||||
url = url,
|
||||
shortty = ItemType::AssocType,
|
||||
name = assoc.name,
|
||||
path = join_with_double_colon(path),
|
||||
args = assoc.args.print(cx),
|
||||
)?;
|
||||
}
|
||||
_ => write!(f, "{}{:#}", assoc.name, assoc.args.print(cx))?,
|
||||
}
|
||||
Ok(())
|
||||
if !f.alternate() && let Ok((url, _, path)) = href(trait_.def_id(), cx) {
|
||||
write!(
|
||||
f,
|
||||
"<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
|
||||
title=\"type {path}::{name}\">{name}</a>",
|
||||
shortty = ItemType::AssocType,
|
||||
name = assoc.name,
|
||||
path = join_with_double_colon(&path),
|
||||
)
|
||||
} else {
|
||||
write!(f, "{}", assoc.name)
|
||||
}?;
|
||||
|
||||
// Carry `f.alternate()` into this display w/o branching manually.
|
||||
fmt::Display::fmt(&assoc.args.print(cx), f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -421,12 +421,20 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
| hir::ItemKind::Struct(..)
|
||||
| hir::ItemKind::Union(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::OpaqueTy(..)
|
||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias, ..
|
||||
})
|
||||
| hir::ItemKind::Static(..)
|
||||
| hir::ItemKind::Trait(..)
|
||||
| hir::ItemKind::TraitAlias(..) => {
|
||||
self.add_to_current_mod(item, renamed, import_id);
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::AsyncFn(_) | hir::OpaqueTyOrigin::FnReturn(_),
|
||||
..
|
||||
}) => {
|
||||
// return-position impl traits are never nameable, and should never be documented.
|
||||
}
|
||||
hir::ItemKind::Const(..) => {
|
||||
// Underscore constants do not correspond to a nameable item and
|
||||
// so are never useful in documentation.
|
||||
|
@ -1,7 +1,7 @@
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::source::snippet;
|
||||
use rustc_ast::ast::{Item, ItemKind, Ty, TyKind};
|
||||
use rustc_ast::ast::{Item, ItemKind, Ty, TyKind, StaticItem, ConstItem};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_lint::{EarlyContext, EarlyLintPass};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
@ -100,13 +100,13 @@ impl EarlyLintPass for RedundantStaticLifetimes {
|
||||
}
|
||||
|
||||
if !item.span.from_expansion() {
|
||||
if let ItemKind::Const(_, ref var_type, _) = item.kind {
|
||||
if let ItemKind::Const(box ConstItem { ty: ref var_type, .. }) = item.kind {
|
||||
Self::visit_type(var_type, cx, "constants have by default a `'static` lifetime");
|
||||
// Don't check associated consts because `'static` cannot be elided on those (issue
|
||||
// #2438)
|
||||
}
|
||||
|
||||
if let ItemKind::Static(ref var_type, _, _) = item.kind {
|
||||
if let ItemKind::Static(box StaticItem { ty: ref var_type,.. }) = item.kind {
|
||||
Self::visit_type(var_type, cx, "statics have by default a `'static` lifetime");
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +286,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
||||
match (l, r) {
|
||||
(ExternCrate(l), ExternCrate(r)) => l == r,
|
||||
(Use(l), Use(r)) => eq_use_tree(l, r),
|
||||
(Static(lt, lm, le), Static(rt, rm, re)) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(Static(box ast::StaticItem { ty: lt, mutability: lm, expr: le}), Static(box ast::StaticItem { ty: rt, mutability: rm, expr: re})) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re} )) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(
|
||||
Fn(box ast::Fn {
|
||||
defaultness: ld,
|
||||
@ -451,7 +451,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
|
||||
pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
|
||||
use AssocItemKind::*;
|
||||
match (l, r) {
|
||||
(Const(ld, lt, le), Const(rd, rt, re)) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(Const(box ast::ConstItem { defaultness: ld, ty: lt, expr: le}), Const(box ast::ConstItem { defaultness: rd, ty: rt, expr: re})) => eq_defaultness(*ld, *rd) && eq_ty(lt, rt) && eq_expr_opt(le, re),
|
||||
(
|
||||
Fn(box ast::Fn {
|
||||
defaultness: ld,
|
||||
|
@ -1804,13 +1804,15 @@ pub(crate) struct StaticParts<'a> {
|
||||
|
||||
impl<'a> StaticParts<'a> {
|
||||
pub(crate) fn from_item(item: &'a ast::Item) -> Self {
|
||||
let (defaultness, prefix, ty, mutability, expr) = match item.kind {
|
||||
ast::ItemKind::Static(ref ty, mutability, ref expr) => {
|
||||
(None, "static", ty, mutability, expr)
|
||||
}
|
||||
ast::ItemKind::Const(defaultness, ref ty, ref expr) => {
|
||||
(Some(defaultness), "const", ty, ast::Mutability::Not, expr)
|
||||
}
|
||||
let (defaultness, prefix, ty, mutability, expr) = match &item.kind {
|
||||
ast::ItemKind::Static(s) => (None, "static", &s.ty, s.mutability, &s.expr),
|
||||
ast::ItemKind::Const(c) => (
|
||||
Some(c.defaultness),
|
||||
"const",
|
||||
&c.ty,
|
||||
ast::Mutability::Not,
|
||||
&c.expr,
|
||||
),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
StaticParts {
|
||||
@ -1826,10 +1828,8 @@ impl<'a> StaticParts<'a> {
|
||||
}
|
||||
|
||||
pub(crate) fn from_trait_item(ti: &'a ast::AssocItem) -> Self {
|
||||
let (defaultness, ty, expr_opt) = match ti.kind {
|
||||
ast::AssocItemKind::Const(defaultness, ref ty, ref expr_opt) => {
|
||||
(defaultness, ty, expr_opt)
|
||||
}
|
||||
let (defaultness, ty, expr_opt) = match &ti.kind {
|
||||
ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
StaticParts {
|
||||
@ -1845,8 +1845,8 @@ impl<'a> StaticParts<'a> {
|
||||
}
|
||||
|
||||
pub(crate) fn from_impl_item(ii: &'a ast::AssocItem) -> Self {
|
||||
let (defaultness, ty, expr) = match ii.kind {
|
||||
ast::AssocItemKind::Const(defaultness, ref ty, ref expr) => (defaultness, ty, expr),
|
||||
let (defaultness, ty, expr) = match &ii.kind {
|
||||
ast::AssocItemKind::Const(c) => (c.defaultness, &c.ty, &c.expr),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
StaticParts {
|
||||
|
15
tests/rustdoc/async-fn-opaque-item.rs
Normal file
15
tests/rustdoc/async-fn-opaque-item.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// compile-flags: --document-private-items --crate-type=lib
|
||||
// edition: 2021
|
||||
|
||||
// Issue 109931 -- test against accidentally documenting the `impl Future`
|
||||
// that comes from an async fn desugaring.
|
||||
|
||||
// Check that we don't document an unnamed opaque type
|
||||
// @!has async_fn_opaque_item/opaque..html
|
||||
|
||||
// Checking there is only a "Functions" header and no "Opaque types".
|
||||
// @has async_fn_opaque_item/index.html
|
||||
// @count - '//*[@class="small-section-header"]' 1
|
||||
// @has - '//*[@class="small-section-header"]' 'Functions'
|
||||
|
||||
pub async fn test() {}
|
18
tests/rustdoc/generic-associated-types/issue-109488.rs
Normal file
18
tests/rustdoc/generic-associated-types/issue-109488.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// Make sure that we escape the arguments of the GAT projection even if we fail to compute
|
||||
// the href of the corresponding trait (in this case it is private).
|
||||
// Further, test that we also linkify the GAT arguments.
|
||||
|
||||
// @has 'issue_109488/type.A.html'
|
||||
// @has - '//pre[@class="rust item-decl"]' '<S as Tr>::P<Option<i32>>'
|
||||
// @has - '//pre[@class="rust item-decl"]//a[@class="enum"]/@href' '{{channel}}/core/option/enum.Option.html'
|
||||
pub type A = <S as Tr>::P<Option<i32>>;
|
||||
|
||||
/*private*/ trait Tr {
|
||||
type P<T>;
|
||||
}
|
||||
|
||||
pub struct S;
|
||||
|
||||
impl Tr for S {
|
||||
type P<T> = ();
|
||||
}
|
@ -10,11 +10,13 @@ trait Trait {
|
||||
|
||||
fn foo<T: Trait<method(i32): Send>>() {}
|
||||
//~^ ERROR argument types not allowed with return type notation
|
||||
//~| ERROR associated type bounds are unstable
|
||||
|
||||
fn bar<T: Trait<method(..) -> (): Send>>() {}
|
||||
//~^ ERROR return type not allowed with return type notation
|
||||
|
||||
fn baz<T: Trait<method(): Send>>() {}
|
||||
//~^ ERROR return type notation arguments must be elided with `..`
|
||||
//~| ERROR associated type bounds are unstable
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,9 +1,27 @@
|
||||
error: return type not allowed with return type notation
|
||||
--> $DIR/bad-inputs-and-output.rs:14:28
|
||||
--> $DIR/bad-inputs-and-output.rs:15:28
|
||||
|
|
||||
LL | fn bar<T: Trait<method(..) -> (): Send>>() {}
|
||||
| ^^^^^ help: remove the return type
|
||||
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/bad-inputs-and-output.rs:11:17
|
||||
|
|
||||
LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/bad-inputs-and-output.rs:18:17
|
||||
|
|
||||
LL | fn baz<T: Trait<method(): Send>>() {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/bad-inputs-and-output.rs:3:12
|
||||
|
|
||||
@ -28,10 +46,11 @@ LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||
| ^^^^^ help: remove the input types: `(..)`
|
||||
|
||||
error: return type notation arguments must be elided with `..`
|
||||
--> $DIR/bad-inputs-and-output.rs:17:23
|
||||
--> $DIR/bad-inputs-and-output.rs:18:23
|
||||
|
|
||||
LL | fn baz<T: Trait<method(): Send>>() {}
|
||||
| ^^ help: add `..`: `(..)`
|
||||
|
||||
error: aborting due to 3 previous errors; 2 warnings emitted
|
||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -0,0 +1,11 @@
|
||||
// edition: 2021
|
||||
// compile-flags: -Zunpretty=expanded
|
||||
|
||||
trait Trait {
|
||||
async fn method() {}
|
||||
}
|
||||
|
||||
fn foo<T: Trait<method(i32): Send>>() {}
|
||||
//~^ ERROR associated type bounds are unstable
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,12 @@
|
||||
error[E0658]: associated type bounds are unstable
|
||||
--> $DIR/unpretty-parenthesized.rs:8:17
|
||||
|
|
||||
LL | fn foo<T: Trait<method(i32): Send>>() {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
|
||||
= help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -0,0 +1,15 @@
|
||||
#![feature(prelude_import)]
|
||||
#[prelude_import]
|
||||
use std::prelude::rust_2021::*;
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
// edition: 2021
|
||||
// compile-flags: -Zunpretty=expanded
|
||||
|
||||
trait Trait {
|
||||
async fn method() {}
|
||||
}
|
||||
|
||||
fn foo<T: Trait<method(i32) : Send>>() {}
|
||||
|
||||
fn main() {}
|
18
tests/ui/lifetimes/issue-93911.rs
Normal file
18
tests/ui/lifetimes/issue-93911.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
|
||||
#![allow(dead_code)]
|
||||
|
||||
struct Foo<'a>(&'a u32);
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
async fn foo() {
|
||||
struct Bar<'b>(&'b u32);
|
||||
|
||||
impl<'b> Bar<'b> {
|
||||
async fn bar() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
51
tests/ui/mir/issue-109743.rs
Normal file
51
tests/ui/mir/issue-109743.rs
Normal file
@ -0,0 +1,51 @@
|
||||
// build-pass
|
||||
// compile-flags: --crate-type=lib
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait StreamOnce {
|
||||
type Token;
|
||||
}
|
||||
|
||||
impl StreamOnce for &str {
|
||||
type Token = ();
|
||||
}
|
||||
|
||||
pub trait Parser<Input: StreamOnce> {
|
||||
type PartialState: Default;
|
||||
fn parse_mode(&self, _state: &Self::PartialState) {}
|
||||
fn parse_mode_impl() {}
|
||||
}
|
||||
|
||||
pub fn parse_bool<'a>() -> impl Parser<&'a str> {
|
||||
pub struct TokensCmp<C, Input>
|
||||
where
|
||||
Input: StreamOnce,
|
||||
{
|
||||
_cmp: C,
|
||||
_marker: PhantomData<Input>,
|
||||
}
|
||||
|
||||
impl<Input, C> Parser<Input> for TokensCmp<C, Input>
|
||||
where
|
||||
C: FnMut(Input::Token),
|
||||
Input: StreamOnce,
|
||||
{
|
||||
type PartialState = ();
|
||||
}
|
||||
|
||||
TokensCmp { _cmp: |_| (), _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub struct ParseBool;
|
||||
|
||||
impl<'a> Parser<&'a str> for ParseBool
|
||||
where
|
||||
&'a str: StreamOnce,
|
||||
{
|
||||
type PartialState = ();
|
||||
|
||||
fn parse_mode_impl() {
|
||||
parse_bool().parse_mode(&Default::default())
|
||||
}
|
||||
}
|
@ -194,6 +194,14 @@ fn main() {
|
||||
let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit;
|
||||
//~^ refutable pattern in local binding
|
||||
|
||||
// Check that matching on a reference results in a correctly spanned diagnostic
|
||||
#[deny(non_exhaustive_omitted_patterns)]
|
||||
match &non_enum {
|
||||
NonExhaustiveEnum::Unit => {}
|
||||
NonExhaustiveEnum::Tuple(_) => {}
|
||||
_ => {}
|
||||
}
|
||||
//~^^ some variants are not matched explicitly
|
||||
}
|
||||
|
||||
#[deny(non_exhaustive_omitted_patterns)]
|
||||
|
@ -198,6 +198,20 @@ help: you might want to use `let else` to handle the variant that isn't matched
|
||||
LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() };
|
||||
| ++++++++++++++++
|
||||
|
||||
error: aborting due to 9 previous errors; 6 warnings emitted
|
||||
error: some variants are not matched explicitly
|
||||
--> $DIR/omitted-patterns.rs:202:9
|
||||
|
|
||||
LL | _ => {}
|
||||
| ^ pattern `NonExhaustiveEnum::Struct { .. }` not covered
|
||||
|
|
||||
= help: ensure that all variants are matched explicitly by adding the suggested match arms
|
||||
= note: the matched value is of type `NonExhaustiveEnum` and the `non_exhaustive_omitted_patterns` attribute was found
|
||||
note: the lint level is defined here
|
||||
--> $DIR/omitted-patterns.rs:198:12
|
||||
|
|
||||
LL | #[deny(non_exhaustive_omitted_patterns)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 10 previous errors; 6 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0005`.
|
||||
|
@ -15,45 +15,45 @@ ast-stats-1 Arm 96 ( 1.5%) 2 48
|
||||
ast-stats-1 ForeignItem 96 ( 1.5%) 1 96
|
||||
ast-stats-1 - Fn 96 ( 1.5%) 1
|
||||
ast-stats-1 FnDecl 120 ( 1.8%) 5 24
|
||||
ast-stats-1 FieldDef 160 ( 2.4%) 2 80
|
||||
ast-stats-1 Stmt 160 ( 2.4%) 5 32
|
||||
ast-stats-1 FieldDef 160 ( 2.5%) 2 80
|
||||
ast-stats-1 Stmt 160 ( 2.5%) 5 32
|
||||
ast-stats-1 - Local 32 ( 0.5%) 1
|
||||
ast-stats-1 - MacCall 32 ( 0.5%) 1
|
||||
ast-stats-1 - Expr 96 ( 1.5%) 3
|
||||
ast-stats-1 Param 160 ( 2.4%) 4 40
|
||||
ast-stats-1 Block 192 ( 2.9%) 6 32
|
||||
ast-stats-1 Param 160 ( 2.5%) 4 40
|
||||
ast-stats-1 Block 192 ( 3.0%) 6 32
|
||||
ast-stats-1 Variant 208 ( 3.2%) 2 104
|
||||
ast-stats-1 GenericBound 224 ( 3.4%) 4 56
|
||||
ast-stats-1 - Trait 224 ( 3.4%) 4
|
||||
ast-stats-1 AssocItem 416 ( 6.3%) 4 104
|
||||
ast-stats-1 - Type 208 ( 3.2%) 2
|
||||
ast-stats-1 - Fn 208 ( 3.2%) 2
|
||||
ast-stats-1 GenericParam 480 ( 7.3%) 5 96
|
||||
ast-stats-1 Pat 504 ( 7.7%) 7 72
|
||||
ast-stats-1 GenericBound 224 ( 3.5%) 4 56
|
||||
ast-stats-1 - Trait 224 ( 3.5%) 4
|
||||
ast-stats-1 AssocItem 352 ( 5.4%) 4 88
|
||||
ast-stats-1 - Type 176 ( 2.7%) 2
|
||||
ast-stats-1 - Fn 176 ( 2.7%) 2
|
||||
ast-stats-1 GenericParam 480 ( 7.4%) 5 96
|
||||
ast-stats-1 Pat 504 ( 7.8%) 7 72
|
||||
ast-stats-1 - Struct 72 ( 1.1%) 1
|
||||
ast-stats-1 - Wild 72 ( 1.1%) 1
|
||||
ast-stats-1 - Ident 360 ( 5.5%) 5
|
||||
ast-stats-1 Expr 576 ( 8.8%) 8 72
|
||||
ast-stats-1 Expr 576 ( 8.9%) 8 72
|
||||
ast-stats-1 - Path 72 ( 1.1%) 1
|
||||
ast-stats-1 - Match 72 ( 1.1%) 1
|
||||
ast-stats-1 - Struct 72 ( 1.1%) 1
|
||||
ast-stats-1 - Lit 144 ( 2.2%) 2
|
||||
ast-stats-1 - Block 216 ( 3.3%) 3
|
||||
ast-stats-1 PathSegment 720 (11.0%) 30 24
|
||||
ast-stats-1 Ty 896 (13.7%) 14 64
|
||||
ast-stats-1 PathSegment 720 (11.1%) 30 24
|
||||
ast-stats-1 Ty 896 (13.8%) 14 64
|
||||
ast-stats-1 - Ptr 64 ( 1.0%) 1
|
||||
ast-stats-1 - Ref 64 ( 1.0%) 1
|
||||
ast-stats-1 - ImplicitSelf 128 ( 2.0%) 2
|
||||
ast-stats-1 - Path 640 ( 9.8%) 10
|
||||
ast-stats-1 Item 1_224 (18.7%) 9 136
|
||||
ast-stats-1 - Path 640 ( 9.9%) 10
|
||||
ast-stats-1 Item 1_224 (18.9%) 9 136
|
||||
ast-stats-1 - Trait 136 ( 2.1%) 1
|
||||
ast-stats-1 - Enum 136 ( 2.1%) 1
|
||||
ast-stats-1 - ForeignMod 136 ( 2.1%) 1
|
||||
ast-stats-1 - Impl 136 ( 2.1%) 1
|
||||
ast-stats-1 - Fn 272 ( 4.2%) 2
|
||||
ast-stats-1 - Use 408 ( 6.2%) 3
|
||||
ast-stats-1 - Use 408 ( 6.3%) 3
|
||||
ast-stats-1 ----------------------------------------------------------------
|
||||
ast-stats-1 Total 6_552
|
||||
ast-stats-1 Total 6_488
|
||||
ast-stats-1
|
||||
ast-stats-2 POST EXPANSION AST STATS
|
||||
ast-stats-2 Name Accumulated Size Count Item Size
|
||||
@ -65,32 +65,32 @@ ast-stats-2 ExprField 48 ( 0.7%) 1 48
|
||||
ast-stats-2 WherePredicate 56 ( 0.8%) 1 56
|
||||
ast-stats-2 - BoundPredicate 56 ( 0.8%) 1
|
||||
ast-stats-2 Local 72 ( 1.0%) 1 72
|
||||
ast-stats-2 Arm 96 ( 1.3%) 2 48
|
||||
ast-stats-2 ForeignItem 96 ( 1.3%) 1 96
|
||||
ast-stats-2 - Fn 96 ( 1.3%) 1
|
||||
ast-stats-2 Arm 96 ( 1.4%) 2 48
|
||||
ast-stats-2 ForeignItem 96 ( 1.4%) 1 96
|
||||
ast-stats-2 - Fn 96 ( 1.4%) 1
|
||||
ast-stats-2 InlineAsm 120 ( 1.7%) 1 120
|
||||
ast-stats-2 FnDecl 120 ( 1.7%) 5 24
|
||||
ast-stats-2 Attribute 128 ( 1.8%) 4 32
|
||||
ast-stats-2 - DocComment 32 ( 0.4%) 1
|
||||
ast-stats-2 - Normal 96 ( 1.3%) 3
|
||||
ast-stats-2 FieldDef 160 ( 2.2%) 2 80
|
||||
ast-stats-2 Stmt 160 ( 2.2%) 5 32
|
||||
ast-stats-2 - Local 32 ( 0.4%) 1
|
||||
ast-stats-2 - Semi 32 ( 0.4%) 1
|
||||
ast-stats-2 - Expr 96 ( 1.3%) 3
|
||||
ast-stats-2 Param 160 ( 2.2%) 4 40
|
||||
ast-stats-2 - DocComment 32 ( 0.5%) 1
|
||||
ast-stats-2 - Normal 96 ( 1.4%) 3
|
||||
ast-stats-2 FieldDef 160 ( 2.3%) 2 80
|
||||
ast-stats-2 Stmt 160 ( 2.3%) 5 32
|
||||
ast-stats-2 - Local 32 ( 0.5%) 1
|
||||
ast-stats-2 - Semi 32 ( 0.5%) 1
|
||||
ast-stats-2 - Expr 96 ( 1.4%) 3
|
||||
ast-stats-2 Param 160 ( 2.3%) 4 40
|
||||
ast-stats-2 Block 192 ( 2.7%) 6 32
|
||||
ast-stats-2 Variant 208 ( 2.9%) 2 104
|
||||
ast-stats-2 GenericBound 224 ( 3.1%) 4 56
|
||||
ast-stats-2 - Trait 224 ( 3.1%) 4
|
||||
ast-stats-2 AssocItem 416 ( 5.8%) 4 104
|
||||
ast-stats-2 - Type 208 ( 2.9%) 2
|
||||
ast-stats-2 - Fn 208 ( 2.9%) 2
|
||||
ast-stats-2 GenericParam 480 ( 6.7%) 5 96
|
||||
ast-stats-2 Pat 504 ( 7.0%) 7 72
|
||||
ast-stats-2 GenericBound 224 ( 3.2%) 4 56
|
||||
ast-stats-2 - Trait 224 ( 3.2%) 4
|
||||
ast-stats-2 AssocItem 352 ( 5.0%) 4 88
|
||||
ast-stats-2 - Type 176 ( 2.5%) 2
|
||||
ast-stats-2 - Fn 176 ( 2.5%) 2
|
||||
ast-stats-2 GenericParam 480 ( 6.8%) 5 96
|
||||
ast-stats-2 Pat 504 ( 7.1%) 7 72
|
||||
ast-stats-2 - Struct 72 ( 1.0%) 1
|
||||
ast-stats-2 - Wild 72 ( 1.0%) 1
|
||||
ast-stats-2 - Ident 360 ( 5.0%) 5
|
||||
ast-stats-2 - Ident 360 ( 5.1%) 5
|
||||
ast-stats-2 Expr 648 ( 9.1%) 9 72
|
||||
ast-stats-2 - Path 72 ( 1.0%) 1
|
||||
ast-stats-2 - Match 72 ( 1.0%) 1
|
||||
@ -98,22 +98,22 @@ ast-stats-2 - Struct 72 ( 1.0%) 1
|
||||
ast-stats-2 - InlineAsm 72 ( 1.0%) 1
|
||||
ast-stats-2 - Lit 144 ( 2.0%) 2
|
||||
ast-stats-2 - Block 216 ( 3.0%) 3
|
||||
ast-stats-2 PathSegment 792 (11.1%) 33 24
|
||||
ast-stats-2 Ty 896 (12.5%) 14 64
|
||||
ast-stats-2 PathSegment 792 (11.2%) 33 24
|
||||
ast-stats-2 Ty 896 (12.6%) 14 64
|
||||
ast-stats-2 - Ptr 64 ( 0.9%) 1
|
||||
ast-stats-2 - Ref 64 ( 0.9%) 1
|
||||
ast-stats-2 - ImplicitSelf 128 ( 1.8%) 2
|
||||
ast-stats-2 - Path 640 ( 8.9%) 10
|
||||
ast-stats-2 Item 1_496 (20.9%) 11 136
|
||||
ast-stats-2 - Path 640 ( 9.0%) 10
|
||||
ast-stats-2 Item 1_496 (21.1%) 11 136
|
||||
ast-stats-2 - Trait 136 ( 1.9%) 1
|
||||
ast-stats-2 - Enum 136 ( 1.9%) 1
|
||||
ast-stats-2 - ExternCrate 136 ( 1.9%) 1
|
||||
ast-stats-2 - ForeignMod 136 ( 1.9%) 1
|
||||
ast-stats-2 - Impl 136 ( 1.9%) 1
|
||||
ast-stats-2 - Fn 272 ( 3.8%) 2
|
||||
ast-stats-2 - Use 544 ( 7.6%) 4
|
||||
ast-stats-2 - Use 544 ( 7.7%) 4
|
||||
ast-stats-2 ----------------------------------------------------------------
|
||||
ast-stats-2 Total 7_152
|
||||
ast-stats-2 Total 7_088
|
||||
ast-stats-2
|
||||
hir-stats HIR STATS
|
||||
hir-stats Name Accumulated Size Count Item Size
|
||||
|
Loading…
x
Reference in New Issue
Block a user