diff options
102 files changed, 954 insertions, 573 deletions
diff --git a/Cargo.lock b/Cargo.lock index ad6dac97a0a..8c9b12028f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2060,9 +2060,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] @@ -3471,6 +3471,7 @@ dependencies = [ name = "rustc_ast_pretty" version = "0.0.0" dependencies = [ + "itertools", "rustc_ast", "rustc_span", "thin-vec", @@ -3523,7 +3524,6 @@ dependencies = [ "rustc_macros", "rustc_middle", "rustc_mir_dataflow", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", @@ -3934,7 +3934,6 @@ dependencies = [ "rustc_lint", "rustc_macros", "rustc_middle", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", @@ -3997,7 +3996,6 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", - "rustc_serialize", "rustc_span", "rustc_target", "smallvec", @@ -4215,7 +4213,6 @@ dependencies = [ "rustc_infer", "rustc_macros", "rustc_middle", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", @@ -4239,7 +4236,6 @@ dependencies = [ "rustc_index", "rustc_macros", "rustc_middle", - "rustc_serialize", "rustc_span", "rustc_target", "smallvec", @@ -4266,7 +4262,6 @@ dependencies = [ "rustc_middle", "rustc_mir_build", "rustc_mir_dataflow", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", @@ -4340,7 +4335,6 @@ dependencies = [ "rustc_lexer", "rustc_macros", "rustc_middle", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", @@ -4564,7 +4558,6 @@ dependencies = [ "rustc_middle", "rustc_parse_format", "rustc_query_system", - "rustc_serialize", "rustc_session", "rustc_span", "rustc_target", diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index c85ff6f5c44..83fe95f16f9 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2574,7 +2574,7 @@ pub enum AttrStyle { } rustc_index::newtype_index! { - #[custom_encodable] + #[orderable] #[debug_format = "AttrId({})"] pub struct AttrId {} } diff --git a/compiler/rustc_ast/src/node_id.rs b/compiler/rustc_ast/src/node_id.rs index d16741757d1..1cd24495309 100644 --- a/compiler/rustc_ast/src/node_id.rs +++ b/compiler/rustc_ast/src/node_id.rs @@ -8,6 +8,8 @@ rustc_index::newtype_index! { /// This is later turned into [`DefId`] and `HirId` for the HIR. /// /// [`DefId`]: rustc_span::def_id::DefId + #[encodable] + #[orderable] #[debug_format = "NodeId({})"] pub struct NodeId { /// The [`NodeId`] used to represent the root of the crate. diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 0001394c8d3..99e79f65fb4 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -itertools = "0.10.1" +itertools = "0.11" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index af1524c8baa..12a08f06558 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +itertools = "0.11" rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } thin-vec = "0.2.12" diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs index 9e4ffd8dd6a..670f2a45835 100644 --- a/compiler/rustc_ast_pretty/src/lib.rs +++ b/compiler/rustc_ast_pretty/src/lib.rs @@ -3,9 +3,7 @@ #![doc(rust_logo)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] -#![feature(associated_type_bounds)] #![feature(box_patterns)] -#![feature(with_negative_coherence)] #![recursion_limit = "256"] mod helpers; diff --git a/compiler/rustc_ast_pretty/src/pp.rs b/compiler/rustc_ast_pretty/src/pp.rs index 7ab8c3eaba2..96f5eff6890 100644 --- a/compiler/rustc_ast_pretty/src/pp.rs +++ b/compiler/rustc_ast_pretty/src/pp.rs @@ -165,20 +165,20 @@ enum IndentStyle { } #[derive(Clone, Copy, Default, PartialEq)] -pub struct BreakToken { +pub(crate) struct BreakToken { offset: isize, blank_space: isize, pre_break: Option<char>, } #[derive(Clone, Copy, PartialEq)] -pub struct BeginToken { +pub(crate) struct BeginToken { indent: IndentStyle, breaks: Breaks, } -#[derive(Clone, PartialEq)] -pub enum Token { +#[derive(PartialEq)] +pub(crate) enum Token { // In practice a string token contains either a `&'static str` or a // `String`. `Cow` is overkill for this because we never modify the data, // but it's more convenient than rolling our own more specialized type. @@ -229,7 +229,6 @@ pub struct Printer { last_printed: Option<Token>, } -#[derive(Clone)] struct BufEntry { token: Token, size: isize, @@ -251,16 +250,16 @@ impl Printer { } } - pub fn last_token(&self) -> Option<&Token> { + pub(crate) fn last_token(&self) -> Option<&Token> { self.last_token_still_buffered().or_else(|| self.last_printed.as_ref()) } - pub fn last_token_still_buffered(&self) -> Option<&Token> { + pub(crate) fn last_token_still_buffered(&self) -> Option<&Token> { self.buf.last().map(|last| &last.token) } /// Be very careful with this! - pub fn replace_last_token_still_buffered(&mut self, token: Token) { + pub(crate) fn replace_last_token_still_buffered(&mut self, token: Token) { self.buf.last_mut().unwrap().token = token; } @@ -314,7 +313,7 @@ impl Printer { } } - pub fn offset(&mut self, offset: isize) { + pub(crate) fn offset(&mut self, offset: isize) { if let Some(BufEntry { token: Token::Break(token), .. }) = &mut self.buf.last_mut() { token.offset += offset; } diff --git a/compiler/rustc_ast_pretty/src/pp/convenience.rs b/compiler/rustc_ast_pretty/src/pp/convenience.rs index 93310dd45c5..c4c4fdce7fe 100644 --- a/compiler/rustc_ast_pretty/src/pp/convenience.rs +++ b/compiler/rustc_ast_pretty/src/pp/convenience.rs @@ -66,7 +66,7 @@ impl Printer { } } - pub fn hardbreak_tok_offset(off: isize) -> Token { + pub(crate) fn hardbreak_tok_offset(off: isize) -> Token { Token::Break(BreakToken { offset: off, blank_space: SIZE_INFINITY, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index e486ab8e3b8..da91c3c8a19 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -1,4 +1,7 @@ -mod delimited; +//! AST pretty printing. +//! +//! Note that HIR pretty printing is layered on top of this crate. + mod expr; mod item; @@ -23,8 +26,6 @@ use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use std::borrow::Cow; use thin_vec::ThinVec; -pub use self::delimited::IterDelimited; - pub enum MacHeader<'a> { Path(&'a ast::Path), Keyword(&'static str), @@ -46,8 +47,7 @@ pub trait PpAnn { fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {} } -#[derive(Copy, Clone)] -pub struct NoAnn; +struct NoAnn; impl PpAnn for NoAnn {} @@ -64,11 +64,11 @@ impl<'a> Comments<'a> { } // FIXME: This shouldn't probably clone lmao - pub fn next(&self) -> Option<Comment> { + fn next(&self) -> Option<Comment> { self.comments.get(self.current).cloned() } - pub fn trailing_comment( + fn trailing_comment( &self, span: rustc_span::Span, next_pos: Option<BytePos>, @@ -95,7 +95,7 @@ pub struct State<'a> { ann: &'a (dyn PpAnn + 'a), } -pub(crate) const INDENT_UNIT: isize = 4; +const INDENT_UNIT: isize = 4; /// Requires you to pass an input filename and reader so that /// it can scan the input text for comments to copy forward. @@ -220,7 +220,7 @@ fn doc_comment_to_string( } } -pub fn literal_to_string(lit: token::Lit) -> String { +fn literal_to_string(lit: token::Lit) -> String { let token::Lit { kind, symbol, suffix } = lit; let mut out = match kind { token::Byte => format!("b'{symbol}'"), @@ -260,11 +260,17 @@ impl std::ops::DerefMut for State<'_> { } } +/// This trait is used for both AST and HIR pretty-printing. pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::DerefMut { fn comments(&mut self) -> &mut Option<Comments<'a>>; - fn print_ident(&mut self, ident: Ident); + fn ann_post(&mut self, ident: Ident); fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool); + fn print_ident(&mut self, ident: Ident) { + self.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); + self.ann_post(ident) + } + fn strsep<T, F>( &mut self, sep: &'static str, @@ -401,15 +407,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere } } - fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) { - self.print_token_literal(lit.as_token_lit(), lit.span) - } - - fn print_token_literal(&mut self, token_lit: token::Lit, span: Span) { - self.maybe_print_comment(span.lo()); - self.word(token_lit.to_string()) - } - fn print_string(&mut self, st: &str, style: ast::StrStyle) { let st = match style { ast::StrStyle::Cooked => format!("\"{}\"", st.escape_debug()), @@ -420,30 +417,14 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.word(st) } - fn print_symbol(&mut self, sym: Symbol, style: ast::StrStyle) { - self.print_string(sym.as_str(), style); - } - fn print_inner_attributes(&mut self, attrs: &[ast::Attribute]) -> bool { self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true) } - fn print_inner_attributes_no_trailing_hardbreak(&mut self, attrs: &[ast::Attribute]) -> bool { - self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false) - } - fn print_outer_attributes(&mut self, attrs: &[ast::Attribute]) -> bool { self.print_either_attributes(attrs, ast::AttrStyle::Outer, false, true) } - fn print_inner_attributes_inline(&mut self, attrs: &[ast::Attribute]) -> bool { - self.print_either_attributes(attrs, ast::AttrStyle::Inner, true, true) - } - - fn print_outer_attributes_inline(&mut self, attrs: &[ast::Attribute]) -> bool { - self.print_either_attributes(attrs, ast::AttrStyle::Outer, true, true) - } - fn print_either_attributes( &mut self, attrs: &[ast::Attribute], @@ -467,10 +448,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere printed } - fn print_attribute(&mut self, attr: &ast::Attribute) { - self.print_attribute_inline(attr, false) - } - fn print_attribute_inline(&mut self, attr: &ast::Attribute, is_inline: bool) { if !is_inline { self.hardbreak_if_not_bol(); @@ -525,33 +502,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.end(); } - fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { - match item { - ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi), - ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit), - } - } - - fn print_meta_item(&mut self, item: &ast::MetaItem) { - self.ibox(INDENT_UNIT); - match &item.kind { - ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), - ast::MetaItemKind::NameValue(value) => { - self.print_path(&item.path, false, 0); - self.space(); - self.word_space("="); - self.print_meta_item_lit(value); - } - ast::MetaItemKind::List(items) => { - self.print_path(&item.path, false, 0); - self.popen(); - self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i)); - self.pclose(); - } - } - self.end(); - } - /// This doesn't deserve to be called "pretty" printing, but it should be /// meaning-preserving. A quick hack that might help would be to look at the /// spans embedded in the TTs to decide where to put spaces and newlines. @@ -843,17 +793,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Self::to_string(|s| s.print_type(ty)) } - fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String { - Self::to_string(|s| s.print_type_bounds(bounds)) - } - - fn where_bound_predicate_to_string( - &self, - where_bound_predicate: &ast::WhereBoundPredicate, - ) -> String { - Self::to_string(|s| s.print_where_bound_predicate(where_bound_predicate)) - } - fn pat_to_string(&self, pat: &ast::Pat) -> String { Self::to_string(|s| s.print_pat(pat)) } @@ -866,14 +805,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Self::to_string(|s| s.print_meta_item_lit(lit)) } - fn tt_to_string(&self, tt: &TokenTree) -> String { - Self::to_string(|s| s.print_tt(tt, false)) - } - - fn tts_to_string(&self, tokens: &TokenStream) -> String { - Self::to_string(|s| s.print_tts(tokens, false)) - } - fn stmt_to_string(&self, stmt: &ast::Stmt) -> String { Self::to_string(|s| s.print_stmt(stmt)) } @@ -882,26 +813,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Self::to_string(|s| s.print_item(i)) } - fn assoc_item_to_string(&self, i: &ast::AssocItem) -> String { - Self::to_string(|s| s.print_assoc_item(i)) - } - - fn foreign_item_to_string(&self, i: &ast::ForeignItem) -> String { - Self::to_string(|s| s.print_foreign_item(i)) - } - - fn generic_params_to_string(&self, generic_params: &[ast::GenericParam]) -> String { - Self::to_string(|s| s.print_generic_params(generic_params)) - } - fn path_to_string(&self, p: &ast::Path) -> String { Self::to_string(|s| s.print_path(p, false, 0)) } - fn path_segment_to_string(&self, p: &ast::PathSegment) -> String { - Self::to_string(|s| s.print_path_segment(p, false)) - } - fn vis_to_string(&self, v: &ast::Visibility) -> String { Self::to_string(|s| s.print_visibility(v)) } @@ -916,22 +831,10 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere }) } - fn meta_list_item_to_string(&self, li: &ast::NestedMetaItem) -> String { - Self::to_string(|s| s.print_meta_list_item(li)) - } - fn attr_item_to_string(&self, ai: &ast::AttrItem) -> String { Self::to_string(|s| s.print_attr_item(ai, ai.path.span)) } - fn attribute_to_string(&self, attr: &ast::Attribute) -> String { - Self::to_string(|s| s.print_attribute(attr)) - } - - fn param_to_string(&self, arg: &ast::Param) -> String { - Self::to_string(|s| s.print_param(arg, false)) - } - fn to_string(f: impl FnOnce(&mut State<'_>)) -> String { let mut printer = State::new(); f(&mut printer); @@ -944,9 +847,8 @@ impl<'a> PrintState<'a> for State<'a> { &mut self.comments } - fn print_ident(&mut self, ident: Ident) { - self.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); - self.ann.post(self, AnnNode::Ident(&ident)) + fn ann_post(&mut self, ident: Ident) { + self.ann.post(self, AnnNode::Ident(&ident)); } fn print_generic_args(&mut self, args: &ast::GenericArgs, colons_before_params: bool) { @@ -979,13 +881,8 @@ impl<'a> State<'a> { State { s: pp::Printer::new(), comments: None, ann: &NoAnn } } - pub(crate) fn commasep_cmnt<T, F, G>( - &mut self, - b: Breaks, - elts: &[T], - mut op: F, - mut get_span: G, - ) where + fn commasep_cmnt<T, F, G>(&mut self, b: Breaks, elts: &[T], mut op: F, mut get_span: G) + where F: FnMut(&mut State<'_>, &T), G: FnMut(&T) -> rustc_span::Span, { @@ -1005,7 +902,7 @@ impl<'a> State<'a> { self.end(); } - pub(crate) fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) { + fn commasep_exprs(&mut self, b: Breaks, exprs: &[P<ast::Expr>]) { self.commasep_cmnt(b, exprs, |s, e| s.print_expr(e), |e| e.span) } @@ -1156,7 +1053,7 @@ impl<'a> State<'a> { self.print_trait_ref(&t.trait_ref) } - pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { + fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); match &st.kind { ast::StmtKind::Local(loc) => { @@ -1211,19 +1108,19 @@ impl<'a> State<'a> { self.maybe_print_trailing_comment(st.span, None) } - pub(crate) fn print_block(&mut self, blk: &ast::Block) { + fn print_block(&mut self, blk: &ast::Block) { self.print_block_with_attrs(blk, &[]) } - pub(crate) fn print_block_unclosed_indent(&mut self, blk: &ast::Block) { + fn print_block_unclosed_indent(&mut self, blk: &ast::Block) { self.print_block_maybe_unclosed(blk, &[], false) } - pub(crate) fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) { + fn print_block_with_attrs(&mut self, blk: &ast::Block, attrs: &[ast::Attribute]) { self.print_block_maybe_unclosed(blk, attrs, true) } - pub(crate) fn print_block_maybe_unclosed( + fn print_block_maybe_unclosed( &mut self, blk: &ast::Block, attrs: &[ast::Attribute], @@ -1257,7 +1154,7 @@ impl<'a> State<'a> { } /// Print a `let pat = expr` expression. - pub(crate) fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) { + fn print_let(&mut self, pat: &ast::Pat, expr: &ast::Expr) { self.word("let "); self.print_pat(pat); self.space(); @@ -1266,7 +1163,7 @@ impl<'a> State<'a> { self.print_expr_cond_paren(expr, Self::cond_needs_par(expr) || npals()) } - pub(crate) fn print_mac(&mut self, m: &ast::MacCall) { + fn print_mac(&mut self, m: &ast::MacCall) { self.print_mac_common( Some(MacHeader::Path(&m.path)), true, @@ -1407,7 +1304,7 @@ impl<'a> State<'a> { self.pclose(); } - pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) { + fn print_local_decl(&mut self, loc: &ast::Local) { self.print_pat(&loc.pat); if let Some(ty) = &loc.ty { self.word_space(":"); @@ -1415,7 +1312,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_name(&mut self, name: Symbol) { + fn print_name(&mut self, name: Symbol) { self.word(name.to_string()); self.ann.post(self, AnnNode::Name(&name)) } @@ -1439,7 +1336,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_pat(&mut self, pat: &ast::Pat) { + fn print_pat(&mut self, pat: &ast::Pat) { self.maybe_print_comment(pat.span.lo()); self.ann.pre(self, AnnNode::Pat(pat)); /* Pat isn't normalized, but the beauty of it @@ -1592,7 +1489,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_asyncness(&mut self, asyncness: ast::Async) { + fn print_asyncness(&mut self, asyncness: ast::Async) { if asyncness.is_async() { self.word_nbsp("async"); } @@ -1637,11 +1534,11 @@ impl<'a> State<'a> { } } - pub(crate) fn print_lifetime(&mut self, lifetime: ast::Lifetime) { + fn print_lifetime(&mut self, lifetime: ast::Lifetime) { self.print_name(lifetime.ident.name) } - pub(crate) fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) { + fn print_lifetime_bounds(&mut self, bounds: &ast::GenericBounds) { for (i, bound) in bounds.iter().enumerate() { if i != 0 { self.word(" + "); @@ -1653,7 +1550,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) { + fn print_generic_params(&mut self, generic_params: &[ast::GenericParam]) { if generic_params.is_empty() { return; } @@ -1717,12 +1614,12 @@ impl<'a> State<'a> { } } - pub(crate) fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { + fn print_mt(&mut self, mt: &ast::MutTy, print_const: bool) { self.print_mutability(mt.mutbl, print_const); self.print_type(&mt.ty) } - pub(crate) fn print_param(&mut self, input: &ast::Param, is_closure: bool) { + fn print_param(&mut self, input: &ast::Param, is_closure: bool) { self.ibox(INDENT_UNIT); self.print_outer_attributes_inline(&input.attrs); @@ -1750,7 +1647,7 @@ impl<'a> State<'a> { self.end(); } - pub(crate) fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) { + fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) { if let ast::FnRetTy::Ty(ty) = fn_ret_ty { self.space_if_not_bol(); self.ibox(INDENT_UNIT); @@ -1761,7 +1658,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_ty_fn( + fn print_ty_fn( &mut self, ext: ast::Extern, unsafety: ast::Unsafe, @@ -1785,7 +1682,7 @@ impl<'a> State<'a> { self.end(); } - pub(crate) fn print_fn_header_info(&mut self, header: ast::FnHeader) { + fn print_fn_header_info(&mut self, header: ast::FnHeader) { self.print_constness(header.constness); self.print_asyncness(header.asyncness); self.print_unsafety(header.unsafety); @@ -1805,24 +1702,107 @@ impl<'a> State<'a> { self.word("fn") } - pub(crate) fn print_unsafety(&mut self, s: ast::Unsafe) { + fn print_unsafety(&mut self, s: ast::Unsafe) { match s { ast::Unsafe::No => {} ast::Unsafe::Yes(_) => self.word_nbsp("unsafe"), } } - pub(crate) fn print_constness(&mut self, s: ast::Const) { + fn print_constness(&mut self, s: ast::Const) { match s { ast::Const::No => {} ast::Const::Yes(_) => self.word_nbsp("const"), } } - pub(crate) fn print_is_auto(&mut self, s: ast::IsAuto) { + fn print_is_auto(&mut self, s: ast::IsAuto) { match s { ast::IsAuto::Yes => self.word_nbsp("auto"), ast::IsAuto::No => {} } } + + fn print_meta_item_lit(&mut self, lit: &ast::MetaItemLit) { + self.print_token_literal(lit.as_token_lit(), lit.span) + } + + fn print_token_literal(&mut self, token_lit: token::Lit, span: Span) { + self.maybe_print_comment(span.lo()); + self.word(token_lit.to_string()) + } + + fn print_symbol(&mut self, sym: Symbol, style: ast::StrStyle) { + self.print_string(sym.as_str(), style); + } + + fn print_inner_attributes_no_trailing_hardbreak(&mut self, attrs: &[ast::Attribute]) -> bool { + self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, false) + } + + fn print_outer_attributes_inline(&mut self, attrs: &[ast::Attribute]) -> bool { + self.print_either_attributes(attrs, ast::AttrStyle::Outer, true, true) + } + + fn print_attribute(&mut self, attr: &ast::Attribute) { + self.print_attribute_inline(attr, false) + } + + fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { + match item { + ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi), + ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit), + } + } + + fn print_meta_item(&mut self, item: &ast::MetaItem) { + self.ibox(INDENT_UNIT); + match &item.kind { + ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), + ast::MetaItemKind::NameValue(value) => { + self.print_path(&item.path, false, 0); + self.space(); + self.word_space("="); + self.print_meta_item_lit(value); + } + ast::MetaItemKind::List(items) => { + self.print_path(&item.path, false, 0); + self.popen(); + self.commasep(Consistent, items, |s, i| s.print_meta_list_item(i)); + self.pclose(); + } + } + self.end(); + } + + pub(crate) fn bounds_to_string(&self, bounds: &[ast::GenericBound]) -> String { + Self::to_string(|s| s.print_type_bounds(bounds)) + } + + pub(crate) fn where_bound_predicate_to_string( + &self, + where_bound_predicate: &ast::WhereBoundPredicate, + ) -> String { + Self::to_string(|s| s.print_where_bound_predicate(where_bound_predicate)) + } + + pub(crate) fn tt_to_string(&self, tt: &TokenTree) -> String { + Self::to_string(|s| s.print_tt(tt, false)) + } + + pub(crate) fn tts_to_string(&self, tokens: &TokenStream) -> String { + Self::to_string(|s| s.print_tts(tokens, false)) + } + + pub(crate) fn path_segment_to_string(&self, p: &ast::PathSegment) -> String { + Self::to_string(|s| s.print_path_segment(p, false)) + } + + pub(crate) fn meta_list_item_to_string(&self, li: &ast::NestedMetaItem) -> String { + Self::to_string(|s| s.print_meta_list_item(li)) + } + + pub(crate) fn attribute_to_string(&self, attr: &ast::Attribute) -> String { + Self::to_string(|s| s.print_attribute(attr)) + } } diff --git a/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs b/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs deleted file mode 100644 index fe0640baaa1..00000000000 --- a/compiler/rustc_ast_pretty/src/pprust/state/delimited.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::iter::Peekable; -use std::mem; -use std::ops::Deref; - -pub struct Delimited<I: Iterator> { - is_first: bool, - iter: Peekable<I>, -} - -pub trait IterDelimited: Iterator + Sized { - fn delimited(self) -> Delimited<Self> { - Delimited { is_first: true, iter: self.peekable() } - } -} - -impl<I: Iterator> IterDelimited for I {} - -pub struct IteratorItem<T> { - value: T, - pub is_first: bool, - pub is_last: bool, -} - -impl<I: Iterator> Iterator for Delimited<I> { - type Item = IteratorItem<I::Item>; - - fn next(&mut self) -> Option<Self::Item> { - let value = self.iter.next()?; - let is_first = mem::replace(&mut self.is_first, false); - let is_last = self.iter.peek().is_none(); - Some(IteratorItem { value, is_first, is_last }) - } -} - -impl<T> Deref for IteratorItem<T> { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.value - } -} diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index edbc3500373..ed9b68a1d5a 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -1,6 +1,6 @@ use crate::pp::Breaks::Inconsistent; -use crate::pprust::state::{AnnNode, IterDelimited, PrintState, State, INDENT_UNIT}; - +use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; +use itertools::{Itertools, Position}; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::util::literal::escape_byte_str_symbol; @@ -149,10 +149,12 @@ impl<'a> State<'a> { return; } self.cbox(0); - for field in fields.iter().delimited() { + for (pos, field) in fields.iter().with_position() { + let is_first = matches!(pos, Position::First | Position::Only); + let is_last = matches!(pos, Position::Last | Position::Only); self.maybe_print_comment(field.span.hi()); self.print_outer_attributes(&field.attrs); - if field.is_first { + if is_first { self.space_if_not_bol(); } if !field.is_shorthand { @@ -160,7 +162,7 @@ impl<'a> State<'a> { self.word_nbsp(":"); } self.print_expr(&field.expr); - if !field.is_last || has_rest { + if !is_last || has_rest { self.word_space(","); } else { self.trailing_comma_or_space(); @@ -279,7 +281,7 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(expr, parser::PREC_PREFIX) } - pub fn print_expr(&mut self, expr: &ast::Expr) { + pub(super) fn print_expr(&mut self, expr: &ast::Expr) { self.print_expr_outer_attr_style(expr, true) } @@ -679,7 +681,7 @@ impl<'a> State<'a> { } } -pub fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> String { +fn reconstruct_format_args_template_string(pieces: &[FormatArgsPiece]) -> String { let mut template = "\"".to_string(); for piece in pieces { match piece { diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index e94bfd81658..fd5b529b1d4 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -1,8 +1,8 @@ use crate::pp::Breaks::Inconsistent; -use crate::pprust::state::delimited::IterDelimited; use crate::pprust::state::{AnnNode, PrintState, State, INDENT_UNIT}; use ast::StaticItem; +use itertools::{Itertools, Position}; use rustc_ast as ast; use rustc_ast::GenericBound; use rustc_ast::ModKind; @@ -20,7 +20,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_foreign_item(&mut self, item: &ast::ForeignItem) { + fn print_foreign_item(&mut self, item: &ast::ForeignItem) { let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; self.ann.pre(self, AnnNode::SubItem(id)); self.hardbreak_if_not_bol(); @@ -518,7 +518,7 @@ impl<'a> State<'a> { } } - pub(crate) fn print_assoc_item(&mut self, item: &ast::AssocItem) { + fn print_assoc_item(&mut self, item: &ast::AssocItem) { let ast::Item { id, span, ident, ref attrs, ref kind, ref vis, tokens: _ } = *item; self.ann.pre(self, AnnNode::SubItem(id)); self.hardbreak_if_not_bol(); @@ -621,7 +621,7 @@ impl<'a> State<'a> { self.print_where_clause_parts(where_clause.has_where_token, &where_clause.predicates); } - pub(crate) fn print_where_clause_parts( + fn print_where_clause_parts( &mut self, has_where_token: bool, predicates: &[ast::WherePredicate], @@ -668,7 +668,7 @@ impl<'a> State<'a> { } } - pub fn print_where_bound_predicate( + pub(crate) fn print_where_bound_predicate( &mut self, where_bound_predicate: &ast::WhereBoundPredicate, ) { @@ -712,9 +712,10 @@ impl<'a> State<'a> { self.word("{"); self.zerobreak(); self.ibox(0); - for use_tree in items.iter().delimited() { + for (pos, use_tree) in items.iter().with_position() { + let is_last = matches!(pos, Position::Last | Position::Only); self.print_use_tree(&use_tree.0); - if !use_tree.is_last { + if !is_last { self.word(","); if let ast::UseTreeKind::Nested(_) = use_tree.0.kind { self.hardbreak(); diff --git a/compiler/rustc_borrowck/Cargo.toml b/compiler/rustc_borrowck/Cargo.toml index 636817a7ce1..714f46270f9 100644 --- a/compiler/rustc_borrowck/Cargo.toml +++ b/compiler/rustc_borrowck/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start either = "1.5.0" -itertools = "0.10.1" +itertools = "0.11" polonius-engine = "0.13.0" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } @@ -19,7 +19,6 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 315886bbe29..041ac75ec01 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -122,6 +122,7 @@ rustc_index::newtype_index! { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "ConstraintSccIndex({})"] pub struct ConstraintSccIndex {} } diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs index 8676d2ba7c4..27b558be3b7 100644 --- a/compiler/rustc_borrowck/src/dataflow.rs +++ b/compiler/rustc_borrowck/src/dataflow.rs @@ -109,6 +109,7 @@ impl_visitable! { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "bw{}"] pub struct BorrowIndex {} } diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs index 0e669abfd14..6f09393169f 100644 --- a/compiler/rustc_borrowck/src/location.rs +++ b/compiler/rustc_borrowck/src/location.rs @@ -20,6 +20,7 @@ pub struct LocationTable { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "LocationIndex({})"] pub struct LocationIndex {} } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 38452df32e9..96b3a4e6d18 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -90,6 +90,7 @@ impl RegionValueElements { rustc_index::newtype_index! { /// A single integer representing a `Location` in the MIR control-flow /// graph. Constructed efficiently from `RegionValueElements`. + #[orderable] #[debug_format = "PointIndex({})"] pub struct PointIndex {} } diff --git a/compiler/rustc_codegen_llvm/Cargo.toml b/compiler/rustc_codegen_llvm/Cargo.toml index 1d309eb908e..580ef9b06e7 100644 --- a/compiler/rustc_codegen_llvm/Cargo.toml +++ b/compiler/rustc_codegen_llvm/Cargo.toml @@ -10,7 +10,7 @@ test = false # tidy-alphabetical-start bitflags = "1.0" cstr = "0.2" -itertools = "0.10.5" +itertools = "0.11" libc = "0.2" measureme = "10.0.0" object = { version = "0.32.0", default-features = false, features = ["std", "read"] } diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 4f540de7ae0..f2be6f27ff6 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -189,8 +189,6 @@ impl GlobalFileTable { } rustc_index::newtype_index! { - // Tell the newtype macro to not generate `Encode`/`Decode` impls. - #[custom_encodable] struct LocalFileId {} } diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml index d385d367f39..0ca19e5fe4a 100644 --- a/compiler/rustc_codegen_ssa/Cargo.toml +++ b/compiler/rustc_codegen_ssa/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" ar_archive_writer = "0.1.5" bitflags = "1.2.1" cc = "1.0.69" -itertools = "0.10.1" +itertools = "0.11" jobserver = "0.1.22" pathdiff = "0.2.0" regex = "1.4" diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 8d91c4c4376..77d9e491748 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -10,7 +10,7 @@ bitflags = "1.2.1" elsa = "=1.7.1" ena = "0.14.2" indexmap = { version = "2.0.0" } -itertools = "0.10.1" +itertools = "0.11" jobserver_crate = { version = "0.1.13", package = "jobserver" } libc = "0.2" measureme = "10.0.0" diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 5dd414cfd41..4b819e1cbd6 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -23,6 +23,7 @@ struct PreOrderFrame<Iter> { } rustc_index::newtype_index! { + #[orderable] struct PreorderIndex {} } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 7b741e8882d..d339075c171 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -154,6 +154,8 @@ rustc_index::newtype_index! { /// an "item-like" to something else can be implemented by a `Vec` instead of a /// tree or hash map. #[derive(HashStable_Generic)] + #[encodable] + #[orderable] pub struct ItemLocalId {} } diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs index 7205b7a21a8..3f8c0db8752 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs @@ -198,7 +198,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> { // entire graph when there are many connected regions. rustc_index::newtype_index! { - #[custom_encodable] + #[orderable] pub struct RegionId {} } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 0148c71dbb5..8df01b6555c 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1,3 +1,6 @@ +//! HIR pretty-printing is layered on top of AST pretty-printing. A number of +//! the definitions in this file have equivalents in `rustc_ast_pretty`. + #![recursion_limit = "256"] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -12,7 +15,7 @@ use rustc_hir::LifetimeParamKind; use rustc_hir::{BindingAnnotation, ByRef, GenericArg, GenericParam, GenericParamKind, Node, Term}; use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use rustc_span::source_map::SourceMap; -use rustc_span::symbol::{kw, Ident, IdentPrinter, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{self, FileName}; use rustc_target::spec::abi::Abi; @@ -49,8 +52,8 @@ pub trait PpAnn { } pub struct NoAnn; + impl PpAnn for NoAnn {} -pub const NO_ANN: &dyn PpAnn = &NoAnn; impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { fn nested(&self, state: &mut State<'_>, nested: Nested) { @@ -136,9 +139,8 @@ impl<'a> PrintState<'a> for State<'a> { &mut self.comments } - fn print_ident(&mut self, ident: Ident) { - self.word(IdentPrinter::for_ast_ident(ident, ident.is_raw_guess()).to_string()); - self.ann.post(self, AnnNode::Name(&ident.name)) + fn ann_post(&mut self, ident: Ident) { + self.ann.post(self, AnnNode::Name(&ident.name)); } fn print_generic_args(&mut self, _: &ast::GenericArgs, _colons_before_params: bool) { @@ -183,15 +185,15 @@ where } pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { - to_string(NO_ANN, |s| s.print_type(ty)) + to_string(&NoAnn, |s| s.print_type(ty)) } pub fn qpath_to_string(segment: &hir::QPath<'_>) -> String { - to_string(NO_ANN, |s| s.print_qpath(segment, false)) + to_string(&NoAnn, |s| s.print_qpath(segment, false)) } pub fn pat_to_string(pat: &hir::Pat<'_>) -> String { - to_string(NO_ANN, |s| s.print_pat(pat)) + to_string(&NoAnn, |s| s.print_pat(pat)) } impl<'a> State<'a> { diff --git a/compiler/rustc_hir_typeck/Cargo.toml b/compiler/rustc_hir_typeck/Cargo.toml index 0062889d244..b0c60304424 100644 --- a/compiler/rustc_hir_typeck/Cargo.toml +++ b/compiler/rustc_hir_typeck/Cargo.toml @@ -19,7 +19,6 @@ rustc_infer = { path = "../rustc_infer" } rustc_lint = { path = "../rustc_lint" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index f74000571ac..a9f67f984da 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3063,7 +3063,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return None; }; - self.commit_if_ok(|_| { + self.commit_if_ok(|snapshot| { + let outer_universe = self.universe(); + let ocx = ObligationCtxt::new(self); let impl_args = self.fresh_args_for_item(base_expr.span, impl_def_id); let impl_trait_ref = @@ -3073,7 +3075,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Match the impl self type against the base ty. If this fails, // we just skip this impl, since it's not particularly useful. let impl_trait_ref = ocx.normalize(&cause, self.param_env, impl_trait_ref); - ocx.eq(&cause, self.param_env, impl_trait_ref.self_ty(), base_ty)?; + ocx.eq(&cause, self.param_env, base_ty, impl_trait_ref.self_ty())?; // Register the impl's predicates. One of these predicates // must be unsatisfied, or else we wouldn't have gotten here @@ -3109,11 +3111,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ty::new_projection(self.tcx, index_trait_output_def_id, impl_trait_ref.args), ); - let errors = ocx.select_where_possible(); + let true_errors = ocx.select_where_possible(); + + // Do a leak check -- we can't really report report a useful error here, + // but it at least avoids an ICE when the error has to do with higher-ranked + // lifetimes. + self.leak_check(outer_universe, Some(snapshot))?; + + // Bail if we have ambiguity errors, which we can't report in a useful way. + let ambiguity_errors = ocx.select_all_or_error(); + if true_errors.is_empty() && !ambiguity_errors.is_empty() { + return Err(NoSolution); + } + // There should be at least one error reported. If not, we // will still delay a span bug in `report_fulfillment_errors`. Ok::<_, NoSolution>(( - self.err_ctxt().report_fulfillment_errors(errors), + self.err_ctxt().report_fulfillment_errors(true_errors), impl_trait_ref.args.type_at(1), element_ty, )) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs index 7aadb95d939..566d407d23c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/arg_matrix.rs @@ -4,11 +4,13 @@ use rustc_middle::ty::error::TypeError; use std::cmp; rustc_index::newtype_index! { + #[orderable] #[debug_format = "ExpectedIdx({})"] pub(crate) struct ExpectedIdx {} } rustc_index::newtype_index! { + #[orderable] #[debug_format = "ProvidedIdx({})"] pub(crate) struct ProvidedIdx {} } diff --git a/compiler/rustc_index/src/vec/tests.rs b/compiler/rustc_index/src/vec/tests.rs index 1959f4e07b7..381d79c24fc 100644 --- a/compiler/rustc_index/src/vec/tests.rs +++ b/compiler/rustc_index/src/vec/tests.rs @@ -2,6 +2,7 @@ use crate as rustc_index; crate::newtype_index! { + #[orderable] #[max = 0xFFFF_FFFA] struct MyIdx {} } diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs index f6a6175374a..13500949a22 100644 --- a/compiler/rustc_index_macros/src/lib.rs +++ b/compiler/rustc_index_macros/src/lib.rs @@ -18,8 +18,19 @@ mod newtype; /// to create/return a value. /// /// Internally, the index uses a u32, so the index must not exceed -/// `u32::MAX`. You can also customize things like the `Debug` impl, -/// what traits are derived, and so forth via the macro. +/// `u32::MAX`. +/// +/// The impls provided by default are Clone, Copy, PartialEq, Eq, and Hash. +/// +/// Accepted attributes for customization: +/// - #[derive(HashStable_Generic)]/#[derive(HashStable)]: derives +/// `HashStable`, as normal. +/// - #[encodable]: derives `Encodable`/`Decodable`. +/// - #[orderable]: derives `PartialOrd`/`Ord`, plus step-related methods. +/// - #[debug_format = "Foo({})"]: derives `Debug` with particular output. +/// - #[max = 0xFFFF_FFFD]: specifies the max value, which allows niche +/// optimizations. The default max value is 0xFFFF_FF00. +/// - #[gate_rustc_only]: makes parts of the generated code nightly-only. #[proc_macro] #[cfg_attr( feature = "nightly", diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs index 2a974fd2628..df1318c835e 100644 --- a/compiler/rustc_index_macros/src/newtype.rs +++ b/compiler/rustc_index_macros/src/newtype.rs @@ -22,8 +22,8 @@ impl Parse for Newtype { let mut debug_format: Option<Lit> = None; let mut max = None; let mut consts = Vec::new(); - let mut encodable = true; - let mut ord = true; + let mut encodable = false; + let mut ord = false; let mut gate_rustc_only = quote! {}; let mut gate_rustc_only_cfg = quote! { all() }; @@ -34,12 +34,12 @@ impl Parse for Newtype { gate_rustc_only_cfg = quote! { feature = "nightly" }; false } - "custom_encodable" => { - encodable = false; + "encodable" => { + encodable = true; false } - "no_ord_impl" => { - ord = false; + "orderable" => { + ord = true; false } "max" => { diff --git a/compiler/rustc_infer/Cargo.toml b/compiler/rustc_infer/Cargo.toml index 00251a19226..73a02a431df 100644 --- a/compiler/rustc_infer/Cargo.toml +++ b/compiler/rustc_infer/Cargo.toml @@ -15,7 +15,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index 479343c3ec2..e06596df7b9 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -341,11 +341,13 @@ impl<'tcx> SccUniverse<'tcx> { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "LeakCheckNode({})"] struct LeakCheckNode {} } rustc_index::newtype_index! { + #[orderable] #[debug_format = "LeakCheckScc({})"] struct LeakCheckScc {} } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 5250dbc7906..99bea647bd5 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -114,7 +114,7 @@ impl LintStoreExpand for LintStoreExpandImpl<'_> { } } -/// Runs the "early phases" of the compiler: initial `cfg` processing, loading compiler plugins, +/// Runs the "early phases" of the compiler: initial `cfg` processing, /// syntax expansion, secondary `cfg` expansion, synthesis of a test /// harness if one is to be provided, injection of a dependency on the /// standard library and prelude, and name resolution. diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index f427b77d65c..fbcb49b1df5 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -739,6 +739,8 @@ pub trait LintContext { } else { db.span_suggestion(name_span, "there is a config with a similar name", best_match, Applicability::MaybeIncorrect); } + } else if name == sym::feature && std::env::var_os("CARGO").is_some() { + db.help("consider defining some features in `Cargo.toml`"); } else if !possibilities.is_empty() { let mut possibilities = possibilities.iter() .map(Symbol::as_str) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 1281cc9f920..3fc4f092443 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -56,7 +56,6 @@ struct LintLevelSets { } rustc_index::newtype_index! { - #[custom_encodable] // we don't need encoding struct LintStackIndex { const COMMAND_LINE = 0; } diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 5a957d2c26d..ef5a1caadb7 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -23,6 +23,8 @@ use rustc_macros::HashStable; use rustc_type_ir::Canonical as IrCanonical; +use rustc_type_ir::CanonicalVarInfo as IrCanonicalVarInfo; +pub use rustc_type_ir::{CanonicalTyVarKind, CanonicalVarKind}; use smallvec::SmallVec; use std::ops::Index; @@ -33,6 +35,8 @@ use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt}; pub type Canonical<'tcx, V> = IrCanonical<TyCtxt<'tcx>, V>; +pub type CanonicalVarInfo<'tcx> = IrCanonicalVarInfo<TyCtxt<'tcx>>; + pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> { @@ -138,158 +142,6 @@ impl<'tcx> Default for OriginalQueryValues<'tcx> { } } -/// Information about a canonical variable that is included with the -/// canonical value. This is sufficient information for code to create -/// a copy of the canonical value in some other inference context, -/// with fresh inference variables replacing the canonical values. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] -pub struct CanonicalVarInfo<'tcx> { - pub kind: CanonicalVarKind<'tcx>, -} - -impl<'tcx> CanonicalVarInfo<'tcx> { - pub fn universe(&self) -> ty::UniverseIndex { - self.kind.universe() - } - - #[must_use] - pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarInfo<'tcx> { - CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) } - } - - pub fn is_existential(&self) -> bool { - match self.kind { - CanonicalVarKind::Ty(_) => true, - CanonicalVarKind::PlaceholderTy(_) => false, - CanonicalVarKind::Region(_) => true, - CanonicalVarKind::PlaceholderRegion(..) => false, - CanonicalVarKind::Const(..) => true, - CanonicalVarKind::PlaceholderConst(_, _) => false, - CanonicalVarKind::Effect => true, - } - } - - pub fn is_region(&self) -> bool { - match self.kind { - CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true, - CanonicalVarKind::Ty(_) - | CanonicalVarKind::PlaceholderTy(_) - | CanonicalVarKind::Const(_, _) - | CanonicalVarKind::PlaceholderConst(_, _) - | CanonicalVarKind::Effect => false, - } - } - - pub fn expect_placeholder_index(self) -> usize { - match self.kind { - CanonicalVarKind::Ty(_) - | CanonicalVarKind::Region(_) - | CanonicalVarKind::Const(_, _) - | CanonicalVarKind::Effect => bug!("expected placeholder: {self:?}"), - - CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.bound.var.as_usize(), - CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.bound.var.as_usize(), - CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.bound.as_usize(), - } - } -} - -/// Describes the "kind" of the canonical variable. This is a "kind" -/// in the type-theory sense of the term -- i.e., a "meta" type system -/// that analyzes type-like values. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -#[derive(TypeFoldable, TypeVisitable)] -pub enum CanonicalVarKind<'tcx> { - /// Some kind of type inference variable. - Ty(CanonicalTyVarKind), - - /// A "placeholder" that represents "any type". - PlaceholderTy(ty::PlaceholderType), - - /// Region variable `'?R`. - Region(ty::UniverseIndex), - - /// A "placeholder" that represents "any region". Created when you - /// are solving a goal like `for<'a> T: Foo<'a>` to represent the - /// bound region `'a`. - PlaceholderRegion(ty::PlaceholderRegion), - - /// Some kind of const inference variable. - Const(ty::UniverseIndex, Ty<'tcx>), - - /// Effect variable `'?E`. - Effect, - - /// A "placeholder" that represents "any const". - PlaceholderConst(ty::PlaceholderConst, Ty<'tcx>), -} - -impl<'tcx> CanonicalVarKind<'tcx> { - pub fn universe(self) -> ty::UniverseIndex { - match self { - CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => ui, - CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => { - ty::UniverseIndex::ROOT - } - CanonicalVarKind::Effect => ty::UniverseIndex::ROOT, - CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe, - CanonicalVarKind::Region(ui) => ui, - CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe, - CanonicalVarKind::Const(ui, _) => ui, - CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe, - } - } - - /// Replaces the universe of this canonical variable with `ui`. - /// - /// In case this is a float or int variable, this causes an ICE if - /// the updated universe is not the root. - pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarKind<'tcx> { - match self { - CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => { - CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) - } - CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) - | CanonicalVarKind::Effect => { - assert_eq!(ui, ty::UniverseIndex::ROOT); - self - } - CanonicalVarKind::PlaceholderTy(placeholder) => { - CanonicalVarKind::PlaceholderTy(ty::Placeholder { universe: ui, ..placeholder }) - } - CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui), - CanonicalVarKind::PlaceholderRegion(placeholder) => { - CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe: ui, ..placeholder }) - } - CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty), - CanonicalVarKind::PlaceholderConst(placeholder, ty) => { - CanonicalVarKind::PlaceholderConst( - ty::Placeholder { universe: ui, ..placeholder }, - ty, - ) - } - } - } -} - -/// Rust actually has more than one category of type variables; -/// notably, the type variables we create for literals (e.g., 22 or -/// 22.) can only be instantiated with integral/float types (e.g., -/// usize or f32). In order to faithfully reproduce a type, we need to -/// know what set of types a given type variable can be unified with. -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -pub enum CanonicalTyVarKind { - /// General type variable `?T` that can be unified with arbitrary types. - General(ty::UniverseIndex), - - /// Integral type variable `?I` (that can only be unified with integral types). - Int, - - /// Floating-point type variable `?F` (that can only be unified with float types). - Float, -} - /// After we execute a query with a canonicalized key, we get back a /// `Canonical<QueryResponse<..>>`. You can use /// `instantiate_query_result` to access the data in this result. @@ -366,7 +218,6 @@ pub type QueryOutlivesConstraint<'tcx> = TrivialTypeTraversalImpls! { crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalTyVarKind, } impl<'tcx> CanonicalVarValues<'tcx> { diff --git a/compiler/rustc_middle/src/middle/region.rs b/compiler/rustc_middle/src/middle/region.rs index 9d55295fb66..b8f04ed03dc 100644 --- a/compiler/rustc_middle/src/middle/region.rs +++ b/compiler/rustc_middle/src/middle/region.rs @@ -148,6 +148,8 @@ rustc_index::newtype_index! { /// * The subscope with `first_statement_index == 1` is scope of `c`, /// and thus does not include EXPR_2, but covers the `...`. #[derive(HashStable)] + #[encodable] + #[orderable] pub struct FirstStatementIndex {} } diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs index 08d377a8695..f15ee0082ce 100644 --- a/compiler/rustc_middle/src/mir/coverage.rs +++ b/compiler/rustc_middle/src/mir/coverage.rs @@ -17,6 +17,8 @@ rustc_index::newtype_index! { /// Note that LLVM handles counter IDs as `uint32_t`, so there is no need /// to use a larger representation on the Rust side. #[derive(HashStable)] + #[encodable] + #[orderable] #[max = 0xFFFF_FFFF] #[debug_format = "CounterId({})"] pub struct CounterId {} @@ -37,6 +39,8 @@ rustc_index::newtype_index! { /// Note that LLVM handles expression IDs as `uint32_t`, so there is no need /// to use a larger representation on the Rust side. #[derive(HashStable)] + #[encodable] + #[orderable] #[max = 0xFFFF_FFFF] #[debug_format = "ExpressionId({})"] pub struct ExpressionId {} diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index d4778cdccf3..1e5a7401c6f 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -736,6 +736,8 @@ impl SourceInfo { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "_{}"] pub struct Local { const RETURN_PLACE = 0; @@ -1171,6 +1173,8 @@ rustc_index::newtype_index! { /// [`CriticalCallEdges`]: ../../rustc_const_eval/transform/add_call_guards/enum.AddCallGuards.html#variant.CriticalCallEdges /// [guide-mir]: https://rustc-dev-guide.rust-lang.org/mir/ #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "bb{}"] pub struct BasicBlock { const START_BLOCK = 0; @@ -1305,6 +1309,7 @@ impl<'tcx> BasicBlockData<'tcx> { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] #[debug_format = "scope[{}]"] pub struct SourceScope { const OUTERMOST_SOURCE_SCOPE = 0; @@ -1533,6 +1538,8 @@ impl UserTypeProjection { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "promoted[{}]"] pub struct Promoted {} } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index b5dd3010d3a..4f98c302298 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -132,6 +132,7 @@ pub struct UnsafetyCheckResult { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] #[debug_format = "_{}"] pub struct CoroutineSavedLocal {} } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index c1bb03e99da..2e367df2c4f 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -956,13 +956,26 @@ pub enum CodegenObligationError { FulfillmentError, } +/// Defines the treatment of opaque types in a given inference context. +/// +/// This affects both what opaques are allowed to be defined, but also whether +/// opaques are replaced with inference vars eagerly in the old solver (e.g. +/// in projection, and in the signature during function type-checking). #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)] pub enum DefiningAnchor { - /// `DefId` of the item. + /// Define opaques which are in-scope of the `LocalDefId`. Also, eagerly + /// replace opaque types in `replace_opaque_types_with_inference_vars`. Bind(LocalDefId), - /// When opaque types are not resolved, we `Bubble` up, meaning - /// return the opaque/hidden type pair from query, for caller of query to handle it. + /// In contexts where we don't currently know what opaques are allowed to be + /// defined, such as (old solver) canonical queries, we will simply allow + /// opaques to be defined, but "bubble" them up in the canonical response or + /// otherwise treat them to be handled later. + /// + /// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`, + /// which may affect what predicates pass and fail in the old trait solver. Bubble, - /// Used to catch type mismatch errors when handling opaque types. + /// Do not allow any opaques to be defined. This is used to catch type mismatch + /// errors when handling opaque types, and also should be used when we would + /// otherwise reveal opaques (such as [`Reveal::All`] reveal mode). Error, } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f240a99c8ff..1d7abcf53ea 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -94,7 +94,7 @@ pub use self::parameterized::ParameterizedOverTcx; pub use self::rvalue_scopes::RvalueScopes; pub use self::sty::BoundRegionKind::*; pub use self::sty::{ - AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar, + AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind, CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs, @@ -1517,8 +1517,36 @@ pub struct Placeholder<T> { pub type PlaceholderRegion = Placeholder<BoundRegion>; +impl rustc_type_ir::Placeholder for PlaceholderRegion { + fn universe(&self) -> UniverseIndex { + self.universe + } + + fn var(&self) -> BoundVar { + self.bound.var + } + + fn with_updated_universe(self, ui: UniverseIndex) -> Self { + Placeholder { universe: ui, ..self } + } +} + pub type PlaceholderType = Placeholder<BoundTy>; +impl rustc_type_ir::Placeholder for PlaceholderType { + fn universe(&self) -> UniverseIndex { + self.universe + } + + fn var(&self) -> BoundVar { + self.bound.var + } + + fn with_updated_universe(self, ui: UniverseIndex) -> Self { + Placeholder { universe: ui, ..self } + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] #[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] pub struct BoundConst<'tcx> { @@ -1528,6 +1556,20 @@ pub struct BoundConst<'tcx> { pub type PlaceholderConst = Placeholder<BoundVar>; +impl rustc_type_ir::Placeholder for PlaceholderConst { + fn universe(&self) -> UniverseIndex { + self.universe + } + + fn var(&self) -> BoundVar { + self.bound + } + + fn with_updated_universe(self, ui: UniverseIndex) -> Self { + Placeholder { universe: ui, ..self } + } +} + /// When type checking, we use the `ParamEnv` to track /// details about the set of where-clauses that are in scope at this /// particular point. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index ff333b3f09a..f12a512da31 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -32,6 +32,7 @@ use std::fmt; use std::ops::{ControlFlow, Deref, Range}; use ty::util::IntTypeExt; +use rustc_type_ir::BoundVar; use rustc_type_ir::ClauseKind as IrClauseKind; use rustc_type_ir::CollectAndApply; use rustc_type_ir::ConstKind as IrConstKind; @@ -1611,6 +1612,8 @@ impl fmt::Debug for EarlyParamRegion { rustc_index::newtype_index! { /// A **region** (lifetime) **v**ariable **ID**. #[derive(HashStable)] + #[encodable] + #[orderable] #[debug_format = "'?{}"] pub struct RegionVid {} } @@ -1621,12 +1624,6 @@ impl Atom for RegionVid { } } -rustc_index::newtype_index! { - #[derive(HashStable)] - #[debug_format = "{}"] - pub struct BoundVar {} -} - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub struct BoundTy { diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 0331546cdd9..4a5c89411da 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -578,6 +578,7 @@ impl<'a, V> LocalTableInContextMut<'a, V> { rustc_index::newtype_index! { #[derive(HashStable)] + #[encodable] #[debug_format = "UserType({})"] pub struct UserTypeAnnotationIndex { const START_INDEX = 0; diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 6dceacd75a5..db542234052 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -17,7 +17,6 @@ rustc_index = { path = "../rustc_index" } rustc_infer = { path = "../rustc_infer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index d6ca873e992..993fee95895 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -186,6 +186,7 @@ pub(crate) enum BreakableTarget { } rustc_index::newtype_index! { + #[orderable] struct DropIdx {} } diff --git a/compiler/rustc_mir_dataflow/Cargo.toml b/compiler/rustc_mir_dataflow/Cargo.toml index 61664eb2a6f..7199db677c4 100644 --- a/compiler/rustc_mir_dataflow/Cargo.toml +++ b/compiler/rustc_mir_dataflow/Cargo.toml @@ -16,7 +16,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 7ab1a9ed069..22cf3999239 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -14,6 +14,7 @@ use self::abs_domain::{AbstractElem, Lift}; mod abs_domain; rustc_index::newtype_index! { + #[orderable] #[debug_format = "mp{}"] pub struct MovePathIndex {} } @@ -25,6 +26,7 @@ impl polonius_engine::Atom for MovePathIndex { } rustc_index::newtype_index! { + #[orderable] #[debug_format = "mo{}"] pub struct MoveOutIndex {} } diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 0448e9d276d..c2ca0a6bcb8 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start either = "1" -itertools = "0.10.1" +itertools = "0.11" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } @@ -20,7 +20,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_mir_build = { path = "../rustc_mir_build" } rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 7defc9ec148..0d807db404c 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -264,6 +264,7 @@ impl graph::WithPredecessors for CoverageGraph { rustc_index::newtype_index! { /// A node in the control-flow graph of CoverageGraph. + #[orderable] #[debug_format = "bcb{}"] pub(super) struct BasicCoverageBlock { const START_BCB = 0; diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index 40c3811e054..80e6c104bd4 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -itertools = "0.10.1" +itertools = "0.11" rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } @@ -19,7 +19,6 @@ rustc_index = { path = "../rustc_index" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index e97ef807204..a70f4138cfb 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -54,6 +54,7 @@ use std::marker::PhantomData; // unused so that we can store multiple index types in `CompressedHybridIndex`, // and use those bits to encode which index type it contains. rustc_index::newtype_index! { + #[encodable] #[max = 0x7FFF_FFFF] pub struct SerializedDepNodeIndex {} } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 8ab48c99007..2d2a3c3d665 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1443,9 +1443,8 @@ impl CheckCfg { let relocation_model_values = RelocModel::all(); // Unknown possible values: - // - `feature` // - `target_feature` - for name in [sym::feature, sym::target_feature] { + for name in [sym::target_feature] { self.expecteds.entry(name).or_insert(ExpectedValues::Any); } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 167a01ab799..2a9f0b42678 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -18,7 +18,10 @@ use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; use stable_mir::mir::mono::InstanceDef; -use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx}; +use stable_mir::mir::{ + Body, ConstOperand, CopyNonOverlapping, Statement, UserTypeProjection, VarDebugInfoFragment, + VariantIdx, +}; use stable_mir::ty::{ AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, @@ -69,15 +72,13 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn get_filename(&self, span: &Span) -> Filename { let tables = self.0.borrow(); - opaque( - &tables - .tcx - .sess - .source_map() - .span_to_filename(tables[*span]) - .display(rustc_span::FileNameDisplayPreference::Local) - .to_string(), - ) + tables + .tcx + .sess + .source_map() + .span_to_filename(tables[*span]) + .display(rustc_span::FileNameDisplayPreference::Local) + .to_string() } fn get_lines(&self, span: &Span) -> LineInfo { @@ -444,10 +445,24 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> { }) .collect(), self.arg_count, + self.var_debug_info.iter().map(|info| info.stable(tables)).collect(), ) } } +impl<'tcx> Stable<'tcx> for mir::VarDebugInfo<'tcx> { + type T = stable_mir::mir::VarDebugInfo; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::VarDebugInfo { + name: self.name.to_string(), + source_info: self.source_info.stable(tables), + composite: self.composite.as_ref().map(|composite| composite.stable(tables)), + value: self.value.stable(tables), + argument_index: self.argument_index, + } + } +} + impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { type T = stable_mir::mir::Statement; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { @@ -455,6 +470,42 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { } } +impl<'tcx> Stable<'tcx> for mir::SourceInfo { + type T = stable_mir::mir::SourceInfo; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + stable_mir::mir::SourceInfo { span: self.span.stable(tables), scope: self.scope.into() } + } +} + +impl<'tcx> Stable<'tcx> for mir::VarDebugInfoFragment<'tcx> { + type T = stable_mir::mir::VarDebugInfoFragment; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + VarDebugInfoFragment { + ty: self.ty.stable(tables), + projection: self.projection.iter().map(|e| e.stable(tables)).collect(), + } + } +} + +impl<'tcx> Stable<'tcx> for mir::VarDebugInfoContents<'tcx> { + type T = stable_mir::mir::VarDebugInfoContents; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + match self { + mir::VarDebugInfoContents::Place(place) => { + stable_mir::mir::VarDebugInfoContents::Place(place.stable(tables)) + } + mir::VarDebugInfoContents::Const(const_operand) => { + let op = ConstOperand { + span: const_operand.span.stable(tables), + user_ty: const_operand.user_ty.map(|index| index.as_usize()), + const_: const_operand.const_.stable(tables), + }; + stable_mir::mir::VarDebugInfoContents::Const(op) + } + } + } +} + impl<'tcx> Stable<'tcx> for mir::StatementKind<'tcx> { type T = stable_mir::mir::StatementKind; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs index 595babc26ae..4b5bd75d5b1 100644 --- a/compiler/rustc_span/src/def_id.rs +++ b/compiler/rustc_span/src/def_id.rs @@ -13,7 +13,7 @@ pub type StableCrateIdMap = indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>; rustc_index::newtype_index! { - #[custom_encodable] + #[orderable] #[debug_format = "crate{}"] pub struct CrateNum {} } @@ -213,7 +213,7 @@ rustc_index::newtype_index! { /// A DefIndex is an index into the hir-map for a crate, identifying a /// particular definition. It should really be considered an interned /// shorthand for a particular DefPath. - #[custom_encodable] // (only encodable in metadata) + #[orderable] #[debug_format = "DefIndex({})"] pub struct DefIndex { /// The crate root is always assigned index 0 by the AST Map code, @@ -222,6 +222,7 @@ rustc_index::newtype_index! { } } +// njn: I don't understand these impl<E: Encoder> Encodable<E> for DefIndex { default fn encode(&self, _: &mut E) { panic!("cannot encode `DefIndex` with `{}`", std::any::type_name::<E>()); diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 988ff57254c..b717229b68d 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -60,7 +60,7 @@ pub struct SyntaxContextData { rustc_index::newtype_index! { /// A unique ID associated with a macro invocation and expansion. - #[custom_encodable] + #[orderable] pub struct ExpnIndex {} } @@ -80,8 +80,6 @@ impl fmt::Debug for ExpnId { rustc_index::newtype_index! { /// A unique ID associated with a macro invocation and expansion. - #[custom_encodable] - #[no_ord_impl] #[debug_format = "expn{}"] pub struct LocalExpnId {} } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 2e3b5446405..ea80bc82bd1 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -2018,6 +2018,7 @@ impl fmt::Display for MacroRulesNormalizedIdent { pub struct Symbol(SymbolIndex); rustc_index::newtype_index! { + #[orderable] struct SymbolIndex {} } diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index b00567e87c6..a274790bffc 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -42,6 +42,8 @@ rustc_index::newtype_index! { /// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and /// `f` is `FieldIdx(1)` in `VariantIdx(0)`. #[derive(HashStable_Generic)] + #[encodable] + #[orderable] pub struct FieldIdx {} } @@ -57,6 +59,8 @@ rustc_index::newtype_index! { /// `struct`s, `tuples`, and `unions`s are considered to have a single variant /// with variant index zero, aka [`FIRST_VARIANT`]. #[derive(HashStable_Generic)] + #[encodable] + #[orderable] pub struct VariantIdx { /// Equivalent to `VariantIdx(0)`. const FIRST_VARIANT = 0; diff --git a/compiler/rustc_trait_selection/Cargo.toml b/compiler/rustc_trait_selection/Cargo.toml index 667ee3d4e1c..7d098180b93 100644 --- a/compiler/rustc_trait_selection/Cargo.toml +++ b/compiler/rustc_trait_selection/Cargo.toml @@ -17,7 +17,6 @@ rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_parse_format = { path = "../rustc_parse_format" } rustc_query_system = { path = "../rustc_query_system" } -rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_trait_selection/src/solve/search_graph.rs b/compiler/rustc_trait_selection/src/solve/search_graph.rs index 68f81a05536..71adebffc15 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph.rs @@ -13,6 +13,7 @@ use rustc_session::Limit; use std::collections::hash_map::Entry; rustc_index::newtype_index! { + #[orderable] pub struct StackDepth {} } diff --git a/compiler/rustc_transmute/Cargo.toml b/compiler/rustc_transmute/Cargo.toml index 07420985a85..066016231fa 100644 --- a/compiler/rustc_transmute/Cargo.toml +++ b/compiler/rustc_transmute/Cargo.toml @@ -27,5 +27,5 @@ rustc = [ [dev-dependencies] # tidy-alphabetical-start -itertools = "0.10.1" +itertools = "0.11" # tidy-alphabetical-end diff --git a/compiler/rustc_ty_utils/Cargo.toml b/compiler/rustc_ty_utils/Cargo.toml index 7e00f1e0c42..f8eb82da8f6 100644 --- a/compiler/rustc_ty_utils/Cargo.toml +++ b/compiler/rustc_ty_utils/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start -itertools = "0.10.1" +itertools = "0.11" rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_fluent_macro = { path = "../rustc_fluent_macro" } diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs index 9f170c5b4db..d2768703297 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -4,7 +4,7 @@ use std::ops::ControlFlow; use crate::fold::{FallibleTypeFolder, TypeFoldable}; use crate::visit::{TypeVisitable, TypeVisitor}; -use crate::{Interner, UniverseIndex}; +use crate::{Interner, Placeholder, UniverseIndex}; /// A "canonicalized" type `V` is one where all free inference /// variables have been rewritten to "canonical vars". These are @@ -113,3 +113,257 @@ where self.variables.visit_with(folder) } } + +/// Information about a canonical variable that is included with the +/// canonical value. This is sufficient information for code to create +/// a copy of the canonical value in some other inference context, +/// with fresh inference variables replacing the canonical values. +#[derive(derivative::Derivative)] +#[derivative( + Clone(bound = ""), + Hash(bound = ""), + Copy(bound = "CanonicalVarKind<I>: Copy"), + Debug(bound = "") +)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub struct CanonicalVarInfo<I: Interner> { + pub kind: CanonicalVarKind<I>, +} + +impl<I: Interner> PartialEq for CanonicalVarInfo<I> { + fn eq(&self, other: &Self) -> bool { + self.kind == other.kind + } +} + +impl<I: Interner> Eq for CanonicalVarInfo<I> {} + +impl<I: Interner> TypeVisitable<I> for CanonicalVarInfo<I> +where + I::Ty: TypeVisitable<I>, +{ + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + self.kind.visit_with(visitor) + } +} + +impl<I: Interner> TypeFoldable<I> for CanonicalVarInfo<I> +where + I::Ty: TypeFoldable<I>, +{ + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(CanonicalVarInfo { kind: self.kind.try_fold_with(folder)? }) + } +} + +impl<I: Interner> CanonicalVarInfo<I> { + pub fn universe(&self) -> UniverseIndex { + self.kind.universe() + } + + #[must_use] + pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarInfo<I> { + CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) } + } + + pub fn is_existential(&self) -> bool { + match self.kind { + CanonicalVarKind::Ty(_) => true, + CanonicalVarKind::PlaceholderTy(_) => false, + CanonicalVarKind::Region(_) => true, + CanonicalVarKind::PlaceholderRegion(..) => false, + CanonicalVarKind::Const(..) => true, + CanonicalVarKind::PlaceholderConst(_, _) => false, + CanonicalVarKind::Effect => true, + } + } + + pub fn is_region(&self) -> bool { + match self.kind { + CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true, + CanonicalVarKind::Ty(_) + | CanonicalVarKind::PlaceholderTy(_) + | CanonicalVarKind::Const(_, _) + | CanonicalVarKind::PlaceholderConst(_, _) + | CanonicalVarKind::Effect => false, + } + } + + pub fn expect_placeholder_index(self) -> usize { + match self.kind { + CanonicalVarKind::Ty(_) + | CanonicalVarKind::Region(_) + | CanonicalVarKind::Const(_, _) + | CanonicalVarKind::Effect => panic!("expected placeholder: {self:?}"), + + CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.var().as_usize(), + CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.var().as_usize(), + CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.var().as_usize(), + } + } +} + +/// Describes the "kind" of the canonical variable. This is a "kind" +/// in the type-theory sense of the term -- i.e., a "meta" type system +/// that analyzes type-like values. +#[derive(derivative::Derivative)] +#[derivative(Clone(bound = ""), Hash(bound = ""), Debug(bound = ""))] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum CanonicalVarKind<I: Interner> { + /// Some kind of type inference variable. + Ty(CanonicalTyVarKind), + + /// A "placeholder" that represents "any type". + PlaceholderTy(I::PlaceholderTy), + + /// Region variable `'?R`. + Region(UniverseIndex), + + /// A "placeholder" that represents "any region". Created when you + /// are solving a goal like `for<'a> T: Foo<'a>` to represent the + /// bound region `'a`. + PlaceholderRegion(I::PlaceholderRegion), + + /// Some kind of const inference variable. + Const(UniverseIndex, I::Ty), + + /// Effect variable `'?E`. + Effect, + + /// A "placeholder" that represents "any const". + PlaceholderConst(I::PlaceholderConst, I::Ty), +} + +impl<I: Interner> Copy for CanonicalVarKind<I> +where + I::PlaceholderTy: Copy, + I::PlaceholderRegion: Copy, + I::PlaceholderConst: Copy, + I::Ty: Copy, +{ +} + +impl<I: Interner> PartialEq for CanonicalVarKind<I> { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Ty(l0), Self::Ty(r0)) => l0 == r0, + (Self::PlaceholderTy(l0), Self::PlaceholderTy(r0)) => l0 == r0, + (Self::Region(l0), Self::Region(r0)) => l0 == r0, + (Self::PlaceholderRegion(l0), Self::PlaceholderRegion(r0)) => l0 == r0, + (Self::Const(l0, l1), Self::Const(r0, r1)) => l0 == r0 && l1 == r1, + (Self::PlaceholderConst(l0, l1), Self::PlaceholderConst(r0, r1)) => { + l0 == r0 && l1 == r1 + } + _ => std::mem::discriminant(self) == std::mem::discriminant(other), + } + } +} + +impl<I: Interner> Eq for CanonicalVarKind<I> {} + +impl<I: Interner> TypeVisitable<I> for CanonicalVarKind<I> +where + I::Ty: TypeVisitable<I>, +{ + fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + match self { + CanonicalVarKind::Ty(_) + | CanonicalVarKind::PlaceholderTy(_) + | CanonicalVarKind::Region(_) + | CanonicalVarKind::PlaceholderRegion(_) + | CanonicalVarKind::Effect => ControlFlow::Continue(()), + CanonicalVarKind::Const(_, ty) | CanonicalVarKind::PlaceholderConst(_, ty) => { + ty.visit_with(visitor) + } + } + } +} + +impl<I: Interner> TypeFoldable<I> for CanonicalVarKind<I> +where + I::Ty: TypeFoldable<I>, +{ + fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { + Ok(match self { + CanonicalVarKind::Ty(kind) => CanonicalVarKind::Ty(kind), + CanonicalVarKind::Region(kind) => CanonicalVarKind::Region(kind), + CanonicalVarKind::Const(kind, ty) => { + CanonicalVarKind::Const(kind, ty.try_fold_with(folder)?) + } + CanonicalVarKind::PlaceholderTy(placeholder) => { + CanonicalVarKind::PlaceholderTy(placeholder) + } + CanonicalVarKind::PlaceholderRegion(placeholder) => { + CanonicalVarKind::PlaceholderRegion(placeholder) + } + CanonicalVarKind::PlaceholderConst(placeholder, ty) => { + CanonicalVarKind::PlaceholderConst(placeholder, ty.try_fold_with(folder)?) + } + CanonicalVarKind::Effect => CanonicalVarKind::Effect, + }) + } +} + +impl<I: Interner> CanonicalVarKind<I> { + pub fn universe(&self) -> UniverseIndex { + match self { + CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) => *ui, + CanonicalVarKind::Region(ui) => *ui, + CanonicalVarKind::Const(ui, _) => *ui, + CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.universe(), + CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.universe(), + CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe(), + CanonicalVarKind::Ty(CanonicalTyVarKind::Float | CanonicalTyVarKind::Int) => { + UniverseIndex::ROOT + } + CanonicalVarKind::Effect => UniverseIndex::ROOT, + } + } + + /// Replaces the universe of this canonical variable with `ui`. + /// + /// In case this is a float or int variable, this causes an ICE if + /// the updated universe is not the root. + pub fn with_updated_universe(self, ui: UniverseIndex) -> CanonicalVarKind<I> { + match self { + CanonicalVarKind::Ty(CanonicalTyVarKind::General(_)) => { + CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) + } + CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui), + CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty), + + CanonicalVarKind::PlaceholderTy(placeholder) => { + CanonicalVarKind::PlaceholderTy(placeholder.with_updated_universe(ui)) + } + CanonicalVarKind::PlaceholderRegion(placeholder) => { + CanonicalVarKind::PlaceholderRegion(placeholder.with_updated_universe(ui)) + } + CanonicalVarKind::PlaceholderConst(placeholder, ty) => { + CanonicalVarKind::PlaceholderConst(placeholder.with_updated_universe(ui), ty) + } + CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) + | CanonicalVarKind::Effect => { + assert_eq!(ui, UniverseIndex::ROOT); + self + } + } + } +} + +/// Rust actually has more than one category of type variables; +/// notably, the type variables we create for literals (e.g., 22 or +/// 22.) can only be instantiated with integral/float types (e.g., +/// usize or f32). In order to faithfully reproduce a type, we need to +/// know what set of types a given type variable can be unified with. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] +pub enum CanonicalTyVarKind { + /// General type variable `?T` that can be unified with arbitrary types. + General(UniverseIndex), + + /// Integral type variable `?I` (that can only be unified with integral types). + Int, + + /// Floating-point type variable `?F` (that can only be unified with float types). + Float, +} diff --git a/compiler/rustc_type_ir/src/const_kind.rs b/compiler/rustc_type_ir/src/const_kind.rs index a5f90421de5..409033a2d8d 100644 --- a/compiler/rustc_type_ir/src/const_kind.rs +++ b/compiler/rustc_type_ir/src/const_kind.rs @@ -95,6 +95,8 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> { rustc_index::newtype_index! { /// A **`const`** **v**ariable **ID**. + #[encodable] + #[orderable] #[debug_format = "?{}c"] #[gate_rustc_only] pub struct ConstVid {} @@ -108,6 +110,8 @@ rustc_index::newtype_index! { /// relate an effect variable with a normal one, we would ICE, which can catch bugs /// where we are not correctly using the effect var for an effect param. Fallback /// is also implemented on top of having separate effect and normal const variables. + #[encodable] + #[orderable] #[debug_format = "?{}e"] #[gate_rustc_only] pub struct EffectVid {} diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs index 170a791fb54..16508c1a257 100644 --- a/compiler/rustc_type_ir/src/interner.rs +++ b/compiler/rustc_type_ir/src/interner.rs @@ -2,7 +2,7 @@ use smallvec::SmallVec; use std::fmt::Debug; use std::hash::Hash; -use crate::{DebugWithInfcx, Mutability}; +use crate::{BoundVar, DebugWithInfcx, Mutability, UniverseIndex}; pub trait Interner: Sized { type DefId: Clone + Debug + Hash + Ord; @@ -26,7 +26,7 @@ pub trait Interner: Sized { type AliasTy: Clone + DebugWithInfcx<Self> + Hash + Ord; type ParamTy: Clone + Debug + Hash + Ord; type BoundTy: Clone + Debug + Hash + Ord; - type PlaceholderTy: Clone + Debug + Hash + Ord; + type PlaceholderTy: Clone + Debug + Hash + Ord + Placeholder; // Things stored inside of tys type ErrorGuaranteed: Clone + Debug + Hash + Ord; @@ -37,7 +37,7 @@ pub trait Interner: Sized { // Kinds of consts type Const: Clone + DebugWithInfcx<Self> + Hash + Ord; type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord; - type PlaceholderConst: Clone + Debug + Hash + Ord; + type PlaceholderConst: Clone + Debug + Hash + Ord + Placeholder; type ParamConst: Clone + Debug + Hash + Ord; type BoundConst: Clone + Debug + Hash + Ord; type ValueConst: Clone + Debug + Hash + Ord; @@ -49,7 +49,7 @@ pub trait Interner: Sized { type BoundRegion: Clone + Debug + Hash + Ord; type LateParamRegion: Clone + Debug + Hash + Ord; type InferRegion: Clone + DebugWithInfcx<Self> + Hash + Ord; - type PlaceholderRegion: Clone + Debug + Hash + Ord; + type PlaceholderRegion: Clone + Debug + Hash + Ord + Placeholder; // Predicates type Predicate: Clone + Debug + Hash + Eq; @@ -64,6 +64,14 @@ pub trait Interner: Sized { fn ty_and_mut_to_parts(ty_and_mut: Self::TypeAndMut) -> (Self::Ty, Mutability); } +/// Common capabilities of placeholder kinds +pub trait Placeholder { + fn universe(&self) -> UniverseIndex; + fn var(&self) -> BoundVar; + + fn with_updated_universe(self, ui: UniverseIndex) -> Self; +} + /// Imagine you have a function `F: FnOnce(&[T]) -> R`, plus an iterator `iter` /// that produces `T` items. You could combine them with /// `f(&iter.collect::<Vec<_>>())`, but this requires allocating memory for the diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index acea7aa46f6..2aeb4230bb8 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -92,6 +92,8 @@ rustc_index::newtype_index! { /// /// [dbi]: https://en.wikipedia.org/wiki/De_Bruijn_index #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] + #[encodable] + #[orderable] #[debug_format = "DebruijnIndex({})"] #[gate_rustc_only] pub struct DebruijnIndex { @@ -293,6 +295,8 @@ rustc_index::newtype_index! { /// type -- an idealized representative of "types in general" that we /// use for checking generic functions. #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] + #[encodable] + #[orderable] #[debug_format = "U{}"] #[gate_rustc_only] pub struct UniverseIndex {} @@ -332,3 +336,12 @@ impl UniverseIndex { self.private < other.private } } + +rustc_index::newtype_index! { + #[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] + #[encodable] + #[orderable] + #[debug_format = "{}"] + #[gate_rustc_only] + pub struct BoundVar {} +} diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs index 494eeaf3dc8..3d4e7f77a4f 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -622,6 +622,8 @@ pub struct FloatVarValue(pub FloatTy); rustc_index::newtype_index! { /// A **ty**pe **v**ariable **ID**. + #[encodable] + #[orderable] #[debug_format = "?{}t"] #[gate_rustc_only] pub struct TyVid {} @@ -629,6 +631,8 @@ rustc_index::newtype_index! { rustc_index::newtype_index! { /// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. + #[encodable] + #[orderable] #[debug_format = "?{}i"] #[gate_rustc_only] pub struct IntVid {} @@ -636,6 +640,8 @@ rustc_index::newtype_index! { rustc_index::newtype_index! { /// A **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. + #[encodable] + #[orderable] #[debug_format = "?{}f"] #[gate_rustc_only] pub struct FloatVid {} diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 91f1066d720..5eb6a8a5e54 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -110,7 +110,7 @@ pub enum ItemKind { Const, } -pub type Filename = Opaque; +pub type Filename = String; /// Holds information about an item in the crate. #[derive(Copy, Clone, PartialEq, Eq, Debug)] diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index ac07246dfd3..8d237fc9f1d 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -2,7 +2,7 @@ use crate::mir::pretty::{function_body, pretty_statement}; use crate::ty::{ AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind, }; -use crate::{Error, Opaque, Span}; +use crate::{Error, Opaque, Span, Symbol}; use std::io; /// The SMIR representation of a single function. @@ -19,6 +19,9 @@ pub struct Body { // The number of arguments this function takes. pub(super) arg_count: usize, + + // Debug information pertaining to user variables, including captures. + pub(super) var_debug_info: Vec<VarDebugInfo>, } impl Body { @@ -26,14 +29,19 @@ impl Body { /// /// A constructor is required to build a `Body` from outside the crate /// because the `arg_count` and `locals` fields are private. - pub fn new(blocks: Vec<BasicBlock>, locals: LocalDecls, arg_count: usize) -> Self { + pub fn new( + blocks: Vec<BasicBlock>, + locals: LocalDecls, + arg_count: usize, + var_debug_info: Vec<VarDebugInfo>, + ) -> Self { // If locals doesn't contain enough entries, it can lead to panics in // `ret_local`, `arg_locals`, and `inner_locals`. assert!( locals.len() > arg_count, "A Body must contain at least a local for the return value and each of the function's arguments" ); - Self { blocks, locals, arg_count } + Self { blocks, locals, arg_count, var_debug_info } } /// Return local that holds this function's return value. @@ -427,6 +435,42 @@ pub struct Place { pub projection: Vec<ProjectionElem>, } +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VarDebugInfo { + pub name: Symbol, + pub source_info: SourceInfo, + pub composite: Option<VarDebugInfoFragment>, + pub value: VarDebugInfoContents, + pub argument_index: Option<u16>, +} + +pub type SourceScope = u32; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SourceInfo { + pub span: Span, + pub scope: SourceScope, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct VarDebugInfoFragment { + pub ty: Ty, + pub projection: Vec<ProjectionElem>, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum VarDebugInfoContents { + Place(Place), + Const(ConstOperand), +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct ConstOperand { + pub span: Span, + pub user_ty: Option<UserTypeAnnotationIndex>, + pub const_: Const, +} + // In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This // is so it can be used for both Places (for which the projection elements are of type // ProjectionElem<Local, Ty>) and user-provided type annotations (for which the projection elements diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index bc2d57eaa24..69bf6ca72b0 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -128,8 +128,12 @@ pub trait MirVisitor { self.super_assert_msg(msg, location) } + fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) { + self.super_var_debug_info(var_debug_info); + } + fn super_body(&mut self, body: &Body) { - let Body { blocks, locals: _, arg_count } = body; + let Body { blocks, locals: _, arg_count, var_debug_info } = body; for bb in blocks { self.visit_basic_block(bb); @@ -145,6 +149,10 @@ pub trait MirVisitor { for (idx, arg) in body.inner_locals().iter().enumerate() { self.visit_local_decl(idx + local_start, arg) } + + for info in var_debug_info.iter() { + self.visit_var_debug_info(info); + } } fn super_basic_block(&mut self, bb: &BasicBlock) { @@ -382,6 +390,24 @@ pub trait MirVisitor { let _ = args; } + fn super_var_debug_info(&mut self, var_debug_info: &VarDebugInfo) { + let VarDebugInfo { source_info, composite, value, name: _, argument_index: _ } = + var_debug_info; + self.visit_span(&source_info.span); + let location = Location(source_info.span); + if let Some(composite) = composite { + self.visit_ty(&composite.ty, location); + } + match value { + VarDebugInfoContents::Place(place) => { + self.visit_place(place, PlaceContext::NON_USE, location); + } + VarDebugInfoContents::Const(constant) => { + self.visit_const(&constant.const_, location); + } + } + } + fn super_assert_msg(&mut self, msg: &AssertMessage, location: Location) { match msg { AssertMessage::BoundsCheck { len, index } => { diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 070a2da6afb..af66cb3ffd7 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -114,7 +114,7 @@ fn main() { { cmd.arg("-Ztls-model=initial-exec"); } - } else { + } else if std::env::var("MIRI").is_err() { // Find any host flags that were passed by bootstrap. // The flags are stored in a RUSTC_HOST_FLAGS variable, separated by spaces. if let Ok(flags) = std::env::var("RUSTC_HOST_FLAGS") { diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index f3917b978df..e13e95ef708 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -9,7 +9,7 @@ path = "lib.rs" [dependencies] arrayvec = { version = "0.7", default-features = false } askama = { version = "0.12", default-features = false, features = ["config"] } -itertools = "0.10.1" +itertools = "0.11" indexmap = "2" minifier = "0.3.0" once_cell = "1.10.0" diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs index 22527876b76..5666751d1ce 100644 --- a/src/librustdoc/formats/item_type.rs +++ b/src/librustdoc/formats/item_type.rs @@ -16,6 +16,13 @@ use crate::clean; /// Consequently, every change to this type should be synchronized to /// the `itemTypes` mapping table in `html/static/js/search.js`. /// +/// The search engine in search.js also uses item type numbers as a tie breaker when +/// sorting results. Keywords and primitives are given first because we want them to be easily +/// found by new users who don't know about advanced features like type filters. The rest are +/// mostly in an arbitrary order, but it's easier to test the search engine when +/// it's deterministic, and these are strictly finer-grained than language namespaces, so +/// using the path and the item type together to sort ensures that search sorting is stable. +/// /// In addition, code in `html::render` uses this enum to generate CSS classes, page prefixes, and /// module headings. If you are adding to this enum and want to ensure that the sidebar also prints /// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an @@ -23,28 +30,28 @@ use crate::clean; #[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)] #[repr(u8)] pub(crate) enum ItemType { - Module = 0, - ExternCrate = 1, - Import = 2, - Struct = 3, - Enum = 4, - Function = 5, - TypeAlias = 6, - Static = 7, - Trait = 8, - Impl = 9, - TyMethod = 10, - Method = 11, - StructField = 12, - Variant = 13, - Macro = 14, - Primitive = 15, - AssocType = 16, - Constant = 17, - AssocConst = 18, - Union = 19, - ForeignType = 20, - Keyword = 21, + Keyword = 0, + Primitive = 1, + Module = 2, + ExternCrate = 3, + Import = 4, + Struct = 5, + Enum = 6, + Function = 7, + TypeAlias = 8, + Static = 9, + Trait = 10, + Impl = 11, + TyMethod = 12, + Method = 13, + StructField = 14, + Variant = 15, + Macro = 16, + AssocType = 17, + Constant = 18, + AssocConst = 19, + Union = 20, + ForeignType = 21, OpaqueTy = 22, ProcAttribute = 23, ProcDerive = 24, diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 22dcb870143..4822690fd04 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -18,28 +18,28 @@ if (!Array.prototype.toSpliced) { // This mapping table should match the discriminants of // `rustdoc::formats::item_type::ItemType` type in Rust. const itemTypes = [ + "keyword", + "primitive", "mod", "externcrate", "import", - "struct", + "struct", // 5 "enum", - "fn", // 5 + "fn", "type", "static", - "trait", + "trait", // 10 "impl", - "tymethod", // 10 + "tymethod", "method", "structfield", - "variant", + "variant", // 15 "macro", - "primitive", // 15 "associatedtype", "constant", "associatedconstant", - "union", - "foreigntype", // 20 - "keyword", + "union", // 20 + "foreigntype", "existential", "attr", "derive", @@ -48,6 +48,8 @@ const itemTypes = [ ]; const longItemTypes = [ + "keyword", + "primitive type", "module", "extern crate", "re-export", @@ -63,13 +65,11 @@ const longItemTypes = [ "struct field", "enum variant", "macro", - "primitive type", "assoc type", "constant", "assoc const", "union", "foreign type", - "keyword", "existential type", "attribute macro", "derive macro", @@ -77,8 +77,6 @@ const longItemTypes = [ ]; // used for special search precedence -const TY_PRIMITIVE = itemTypes.indexOf("primitive"); -const TY_KEYWORD = itemTypes.indexOf("keyword"); const TY_GENERIC = itemTypes.indexOf("generic"); const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../"; @@ -1317,16 +1315,6 @@ function initSearch(rawSearchIndex) { return (a > b ? +1 : -1); } - // special precedence for primitive and keyword pages - if ((aaa.item.ty === TY_PRIMITIVE && bbb.item.ty !== TY_KEYWORD) || - (aaa.item.ty === TY_KEYWORD && bbb.item.ty !== TY_PRIMITIVE)) { - return -1; - } - if ((bbb.item.ty === TY_PRIMITIVE && aaa.item.ty !== TY_PRIMITIVE) || - (bbb.item.ty === TY_KEYWORD && aaa.item.ty !== TY_KEYWORD)) { - return 1; - } - // sort by description (no description goes later) a = (aaa.item.desc === ""); b = (bbb.item.desc === ""); @@ -1840,26 +1828,16 @@ function initSearch(rawSearchIndex) { const length = path.length; const clength = contains.length; - if (clength > length) { - return maxEditDistance + 1; - } - for (let i = 0; i < length; ++i) { - if (i + clength > length) { - break; - } + pathiter: for (let i = length - clength; i >= 0; i -= 1) { let dist_total = 0; - let aborted = false; for (let x = 0; x < clength; ++x) { const dist = editDistance(path[i + x], contains[x], maxEditDistance); if (dist > maxEditDistance) { - aborted = true; - break; + continue pathiter; } dist_total += dist; } - if (!aborted) { - ret_dist = Math.min(ret_dist, Math.round(dist_total / clength)); - } + ret_dist = Math.min(ret_dist, Math.round(dist_total / clength)); } return ret_dist; } @@ -2953,7 +2931,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\ // https://mathiasbynens.be/notes/shapes-ics const crateRow = { crate: crate, - ty: 1, // == ExternCrate + ty: 3, // == ExternCrate name: crate, path: "", desc: crateCorpus.doc, diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml index 3b138b480b6..f6084a46272 100644 --- a/src/tools/clippy/Cargo.toml +++ b/src/tools/clippy/Cargo.toml @@ -37,7 +37,7 @@ toml = "0.7.3" walkdir = "2.3" # This is used by the `collect-metadata` alias. filetime = "0.2" -itertools = "0.10.1" +itertools = "0.11" # UI test dependencies clippy_utils = { path = "clippy_utils" } diff --git a/src/tools/clippy/clippy_dev/Cargo.toml b/src/tools/clippy/clippy_dev/Cargo.toml index c3f8a782d27..ce738e3f4ec 100644 --- a/src/tools/clippy/clippy_dev/Cargo.toml +++ b/src/tools/clippy/clippy_dev/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" aho-corasick = "0.7" clap = "4.1.4" indoc = "1.0" -itertools = "0.10.1" +itertools = "0.11" opener = "0.5" shell-escape = "0.1" walkdir = "2.3" diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml index 84246d285c0..a9375214be4 100644 --- a/src/tools/clippy/clippy_lints/Cargo.toml +++ b/src/tools/clippy/clippy_lints/Cargo.toml @@ -14,7 +14,7 @@ cargo_metadata = "0.15.3" clippy_config = { path = "../clippy_config" } clippy_utils = { path = "../clippy_utils" } declare_clippy_lint = { path = "../declare_clippy_lint" } -itertools = "0.10.1" +itertools = "0.11" quine-mc_cluskey = "0.2" regex-syntax = "0.7" serde = { version = "1.0", features = ["derive"] } diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml index d7053d3ff84..5d23326cec8 100644 --- a/src/tools/clippy/clippy_utils/Cargo.toml +++ b/src/tools/clippy/clippy_utils/Cargo.toml @@ -7,7 +7,7 @@ publish = false [dependencies] clippy_config = { path = "../clippy_config" } arrayvec = { version = "0.7", default-features = false } -itertools = "0.10.1" +itertools = "0.11" rustc-semver = "1.1" [features] diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml index 8c1150ed010..af123e107d5 100644 --- a/src/tools/clippy/declare_clippy_lint/Cargo.toml +++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml @@ -8,7 +8,7 @@ publish = false proc-macro = true [dependencies] -itertools = "0.10.1" +itertools = "0.11" quote = "1.0.21" syn = "2.0" diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml index 00e0ed37a84..032b9b54810 100644 --- a/src/tools/rustfmt/Cargo.toml +++ b/src/tools/rustfmt/Cargo.toml @@ -43,7 +43,7 @@ diff = "0.1" dirs = "4.0" getopts = "0.2" ignore = "0.4" -itertools = "0.10" +itertools = "0.11" lazy_static = "1.4" regex = "1.7" serde = { version = "1.0.160", features = ["derive"] } diff --git a/tests/rustdoc-js-std/keyword.js b/tests/rustdoc-js-std/keyword.js index b85ba34138b..1837b1e71f7 100644 --- a/tests/rustdoc-js-std/keyword.js +++ b/tests/rustdoc-js-std/keyword.js @@ -3,7 +3,7 @@ const EXPECTED = { 'query': 'fn', 'others': [ - { 'path': 'std', 'name': 'fn', ty: 15 }, // 15 is for primitive types - { 'path': 'std', 'name': 'fn', ty: 21 }, // 21 is for keywords + { 'path': 'std', 'name': 'fn', ty: 1 }, // 1 is for primitive types + { 'path': 'std', 'name': 'fn', ty: 0 }, // 0 is for keywords ], }; diff --git a/tests/rustdoc-js-std/macro-check.js b/tests/rustdoc-js-std/macro-check.js index c22b1753fd7..37d5e7dae62 100644 --- a/tests/rustdoc-js-std/macro-check.js +++ b/tests/rustdoc-js-std/macro-check.js @@ -3,7 +3,7 @@ const EXPECTED = { 'query': 'panic', 'others': [ - { 'path': 'std', 'name': 'panic', ty: 14 }, // 15 is for macros - { 'path': 'std', 'name': 'panic', ty: 0 }, // 0 is for modules + { 'path': 'std', 'name': 'panic', ty: 16 }, // 16 is for macros + { 'path': 'std', 'name': 'panic', ty: 2 }, // 2 is for modules ], }; diff --git a/tests/rustdoc-js-std/parser-bindings.js b/tests/rustdoc-js-std/parser-bindings.js index faf880c8116..c4909c6242d 100644 --- a/tests/rustdoc-js-std/parser-bindings.js +++ b/tests/rustdoc-js-std/parser-bindings.js @@ -81,7 +81,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "never", generics: [], - typeFilter: 15, + typeFilter: 1, }] ], ], @@ -112,7 +112,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "[]", generics: [], - typeFilter: 15, + typeFilter: 1, }] ], ], @@ -149,10 +149,10 @@ const PARSED = [ pathWithoutLast: [], pathLast: "never", generics: [], - typeFilter: 15, + typeFilter: 1, }, ], - typeFilter: 15, + typeFilter: 1, }] ], ], diff --git a/tests/rustdoc-js-std/parser-filter.js b/tests/rustdoc-js-std/parser-filter.js index 3b9cc5b1bf0..a1dd0ea3b5a 100644 --- a/tests/rustdoc-js-std/parser-filter.js +++ b/tests/rustdoc-js-std/parser-filter.js @@ -7,7 +7,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "foo", generics: [], - typeFilter: 5, + typeFilter: 7, }], foundElems: 1, original: "fn:foo", @@ -23,7 +23,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "foo", generics: [], - typeFilter: 4, + typeFilter: 6, }], foundElems: 1, original: "enum : foo", @@ -48,7 +48,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "macro", generics: [], - typeFilter: 14, + typeFilter: 16, }], foundElems: 1, original: "macro!", @@ -64,7 +64,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "mac", generics: [], - typeFilter: 14, + typeFilter: 16, }], foundElems: 1, original: "macro:mac!", @@ -80,7 +80,7 @@ const PARSED = [ pathWithoutLast: ["a"], pathLast: "mac", generics: [], - typeFilter: 14, + typeFilter: 16, }], foundElems: 1, original: "a::mac!", @@ -99,7 +99,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "foo", generics: [], - typeFilter: 5, + typeFilter: 7, }], userQuery: "-> fn:foo", error: null, @@ -121,10 +121,10 @@ const PARSED = [ pathWithoutLast: [], pathLast: "bar", generics: [], - typeFilter: 5, + typeFilter: 7, } ], - typeFilter: 5, + typeFilter: 7, }], userQuery: "-> fn:foo<fn:bar>", error: null, @@ -146,7 +146,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "bar", generics: [], - typeFilter: 5, + typeFilter: 7, }, { name: "baz::fuzz", @@ -154,10 +154,10 @@ const PARSED = [ pathWithoutLast: ["baz"], pathLast: "fuzz", generics: [], - typeFilter: 4, + typeFilter: 6, }, ], - typeFilter: 5, + typeFilter: 7, }], userQuery: "-> fn:foo<fn:bar, enum : baz::fuzz>", error: null, diff --git a/tests/rustdoc-js-std/parser-ident.js b/tests/rustdoc-js-std/parser-ident.js index f65a7ce6692..cc79c58f1da 100644 --- a/tests/rustdoc-js-std/parser-ident.js +++ b/tests/rustdoc-js-std/parser-ident.js @@ -13,7 +13,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "never", generics: [], - typeFilter: 15, + typeFilter: 1, }, ], typeFilter: -1, @@ -32,7 +32,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "never", generics: [], - typeFilter: 15, + typeFilter: 1, }], foundElems: 1, original: "!", @@ -48,7 +48,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "a", generics: [], - typeFilter: 14, + typeFilter: 16, }], foundElems: 1, original: "a!", diff --git a/tests/rustdoc-js-std/parser-returned.js b/tests/rustdoc-js-std/parser-returned.js index 6ea86609115..44e517c49b5 100644 --- a/tests/rustdoc-js-std/parser-returned.js +++ b/tests/rustdoc-js-std/parser-returned.js @@ -89,7 +89,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "never", generics: [], - typeFilter: 15, + typeFilter: 1, }], userQuery: "-> !", error: null, diff --git a/tests/rustdoc-js-std/parser-slice-array.js b/tests/rustdoc-js-std/parser-slice-array.js index c22b7870dbf..239391bed42 100644 --- a/tests/rustdoc-js-std/parser-slice-array.js +++ b/tests/rustdoc-js-std/parser-slice-array.js @@ -43,16 +43,16 @@ const PARSED = [ pathWithoutLast: [], pathLast: "[]", generics: [], - typeFilter: 15, + typeFilter: 1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, @@ -70,7 +70,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "[]", generics: [], - typeFilter: 15, + typeFilter: 1, }, { name: "u8", @@ -105,7 +105,7 @@ const PARSED = [ typeFilter: -1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, @@ -140,7 +140,7 @@ const PARSED = [ typeFilter: -1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, @@ -176,7 +176,7 @@ const PARSED = [ typeFilter: -1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, @@ -194,7 +194,7 @@ const PARSED = [ pathWithoutLast: [], pathLast: "[]", generics: [], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, @@ -284,7 +284,7 @@ const PARSED = [ typeFilter: -1, }, ], - typeFilter: 15, + typeFilter: 1, }, ], foundElems: 1, diff --git a/tests/ui/check-cfg/allow-same-level.stderr b/tests/ui/check-cfg/allow-same-level.stderr index b0c459fabf8..19d9443d477 100644 --- a/tests/ui/check-cfg/allow-same-level.stderr +++ b/tests/ui/check-cfg/allow-same-level.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `FALSE` LL | #[cfg(FALSE)] | ^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/cargo-feature.rs b/tests/ui/check-cfg/cargo-feature.rs new file mode 100644 index 00000000000..ea48c6ea201 --- /dev/null +++ b/tests/ui/check-cfg/cargo-feature.rs @@ -0,0 +1,14 @@ +// This test checks that when no features are passed by Cargo we +// suggest adding some in the Cargo.toml instead of vomitting a +// list of all the expected names +// +// check-pass +// rustc-env:CARGO=/usr/bin/cargo +// compile-flags: --check-cfg=cfg() -Z unstable-options +// error-pattern:Cargo.toml + +#[cfg(feature = "serde")] +//~^ WARNING unexpected `cfg` condition name +fn ser() {} + +fn main() {} diff --git a/tests/ui/check-cfg/cargo-feature.stderr b/tests/ui/check-cfg/cargo-feature.stderr new file mode 100644 index 00000000000..619410a28f3 --- /dev/null +++ b/tests/ui/check-cfg/cargo-feature.stderr @@ -0,0 +1,11 @@ +warning: unexpected `cfg` condition name: `feature` + --> $DIR/cargo-feature.rs:10:7 + | +LL | #[cfg(feature = "serde")] + | ^^^^^^^^^^^^^^^^^ + | + = help: consider defining some features in `Cargo.toml` + = note: `#[warn(unexpected_cfgs)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/check-cfg/compact-names.stderr b/tests/ui/check-cfg/compact-names.stderr index b0228774b75..ffde972a25e 100644 --- a/tests/ui/check-cfg/compact-names.stderr +++ b/tests/ui/check-cfg/compact-names.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `target_architecture` LL | #[cfg(target(os = "linux", architecture = "arm"))] | ^^^^^^^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr index 12a055d02a7..971abb1a21a 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_cfg.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key` LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -17,5 +17,17 @@ LL | #[cfg(test = "value")] | = note: no expected value for `test` -warning: 2 warnings emitted +warning: unexpected `cfg` condition name: `feature` + --> $DIR/exhaustive-names-values.rs:19:7 + | +LL | #[cfg(feature = "unk")] + | ^^^^^^^^^^^^^^^ + +warning: unexpected `cfg` condition name: `feature` + --> $DIR/exhaustive-names-values.rs:26:7 + | +LL | #[cfg(feature = "std")] + | ^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr b/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr index 12a055d02a7..971abb1a21a 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr +++ b/tests/ui/check-cfg/exhaustive-names-values.empty_names_values.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key` LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: unexpected `cfg` condition value: `value` @@ -17,5 +17,17 @@ LL | #[cfg(test = "value")] | = note: no expected value for `test` -warning: 2 warnings emitted +warning: unexpected `cfg` condition name: `feature` + --> $DIR/exhaustive-names-values.rs:19:7 + | +LL | #[cfg(feature = "unk")] + | ^^^^^^^^^^^^^^^ + +warning: unexpected `cfg` condition name: `feature` + --> $DIR/exhaustive-names-values.rs:26:7 + | +LL | #[cfg(feature = "std")] + | ^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted diff --git a/tests/ui/check-cfg/exhaustive-names-values.rs b/tests/ui/check-cfg/exhaustive-names-values.rs index ef1e458b249..ceb4831e22d 100644 --- a/tests/ui/check-cfg/exhaustive-names-values.rs +++ b/tests/ui/check-cfg/exhaustive-names-values.rs @@ -17,11 +17,15 @@ pub fn f() {} pub fn f() {} #[cfg(feature = "unk")] -//[feature]~^ WARNING unexpected `cfg` condition value -//[full]~^^ WARNING unexpected `cfg` condition value +//[empty_names_values]~^ WARNING unexpected `cfg` condition name +//[empty_cfg]~^^ WARNING unexpected `cfg` condition name +//[feature]~^^^ WARNING unexpected `cfg` condition value +//[full]~^^^^ WARNING unexpected `cfg` condition value pub fn feat() {} #[cfg(feature = "std")] +//[empty_names_values]~^ WARNING unexpected `cfg` condition name +//[empty_cfg]~^^ WARNING unexpected `cfg` condition name pub fn feat() {} #[cfg(windows)] diff --git a/tests/ui/check-cfg/exhaustive-names.empty_names.stderr b/tests/ui/check-cfg/exhaustive-names.empty_names.stderr index 6bc7845c832..7d01c73cc09 100644 --- a/tests/ui/check-cfg/exhaustive-names.empty_names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.empty_names.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key` LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr b/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr index 6bc7845c832..7d01c73cc09 100644 --- a/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr +++ b/tests/ui/check-cfg/exhaustive-names.exhaustive_names.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `unknown_key` LL | #[cfg(unknown_key = "value")] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/stmt-no-ice.stderr b/tests/ui/check-cfg/stmt-no-ice.stderr index 900ea4e4da0..3fb3ae27ec4 100644 --- a/tests/ui/check-cfg/stmt-no-ice.stderr +++ b/tests/ui/check-cfg/stmt-no-ice.stderr @@ -4,7 +4,7 @@ warning: unexpected `cfg` condition name: `crossbeam_loom` LL | #[cfg(crossbeam_loom)] | ^^^^^^^^^^^^^^ | - = help: expected names are: `debug_assertions`, `doc`, `doctest`, `feature`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` = note: `#[warn(unexpected_cfgs)]` on by default warning: 1 warning emitted diff --git a/tests/ui/check-cfg/well-known-names.rs b/tests/ui/check-cfg/well-known-names.rs index 1dcb419b4a7..32c14703d25 100644 --- a/tests/ui/check-cfg/well-known-names.rs +++ b/tests/ui/check-cfg/well-known-names.rs @@ -15,6 +15,7 @@ fn target_os() {} fn feature_misspell() {} #[cfg(feature = "foo")] +//~^ WARNING unexpected `cfg` condition name fn feature() {} #[cfg(uniw)] diff --git a/tests/ui/check-cfg/well-known-names.stderr b/tests/ui/check-cfg/well-known-names.stderr index 3001289b7e0..a986e61bcdc 100644 --- a/tests/ui/check-cfg/well-known-names.stderr +++ b/tests/ui/check-cfg/well-known-names.stderr @@ -14,15 +14,21 @@ warning: unexpected `cfg` condition name: `features` --> $DIR/well-known-names.rs:13:7 | LL | #[cfg(features = "foo")] - | --------^^^^^^^^ - | | - | help: there is a config with a similar name: `feature` + | ^^^^^^^^^^^^^^^^ + | + = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows` + +warning: unexpected `cfg` condition name: `feature` + --> $DIR/well-known-names.rs:17:7 + | +LL | #[cfg(feature = "foo")] + | ^^^^^^^^^^^^^^^ warning: unexpected `cfg` condition name: `uniw` - --> $DIR/well-known-names.rs:20:7 + --> $DIR/well-known-names.rs:21:7 | LL | #[cfg(uniw)] | ^^^^ help: there is a config with a similar name: `unix` -warning: 3 warnings emitted +warning: 4 warnings emitted diff --git a/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.rs b/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.rs new file mode 100644 index 00000000000..c8f6db7aef3 --- /dev/null +++ b/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.rs @@ -0,0 +1,29 @@ +// Test against ICE in #118111 + +use std::ops::Index; + +struct Map<T, F> { + f: F, + inner: T, +} + +impl<T, F, Idx> Index<Idx> for Map<T, F> +where + T: Index<Idx>, + F: FnOnce(&T, Idx) -> Idx, +{ + type Output = T::Output; + + fn index(&self, index: Idx) -> &Self::Output { + todo!() + } +} + +fn main() { + Map { inner: [0_usize], f: |_, i: usize| 1_usize }[0]; + //~^ ERROR cannot index into a value of type + // Problem here is that + // `f: |_, i: usize| ...` + // should be + // `f: |_: &_, i: usize| ...` +} diff --git a/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.stderr b/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.stderr new file mode 100644 index 00000000000..7c978430839 --- /dev/null +++ b/tests/ui/typeck/bad-index-modulo-higher-ranked-regions.stderr @@ -0,0 +1,9 @@ +error[E0608]: cannot index into a value of type `Map<[usize; 1], {closure@$DIR/bad-index-modulo-higher-ranked-regions.rs:23:32: 23:45}>` + --> $DIR/bad-index-modulo-higher-ranked-regions.rs:23:55 + | +LL | Map { inner: [0_usize], f: |_, i: usize| 1_usize }[0]; + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0608`. |
