diff options
| author | bors <bors@rust-lang.org> | 2023-02-26 17:17:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-02-26 17:17:25 +0000 |
| commit | 56ac6bfc87cce22feffc079c0540c8774b00a5ca (patch) | |
| tree | e430c91fb4e29070945f79df7a47639e5cf4f9b1 | |
| parent | ffd12f67cfa28891bbd1fa81d5e80a128f346ace (diff) | |
| parent | cb45103358c0fef99d7659e0949b3c65b3eabdd6 (diff) | |
| download | rust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.tar.gz rust-56ac6bfc87cce22feffc079c0540c8774b00a5ca.zip | |
Auto merge of #2803 - RalfJung:rustup, r=RalfJung
Rustup
1081 files changed, 12022 insertions, 8319 deletions
diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index d20f19e60e8..353bfcb6ac1 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,3 +1,5 @@ +# Use `git config blame.ignorerevsfile .git-blame-ignore-revs` to make `git blame` ignore the following commits. + # format the world a06baa56b95674fc626b3c3fd680d6a65357fe60 # format libcore diff --git a/Cargo.lock b/Cargo.lock index 6c17edd3020..9e5deedb66f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,15 +90,6 @@ dependencies = [ [[package]] name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "ansi_term" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" @@ -390,7 +381,6 @@ dependencies = [ "os_info", "pasetors", "pathdiff", - "percent-encoding", "pretty_env_logger", "rustc-workspace-hack", "rustfix", @@ -891,11 +881,11 @@ dependencies = [ "diff", "getopts", "glob", - "lazy_static", "lazycell", "libc", - "miow 0.3.7", + "miow 0.5.0", "miropt-test-tools", + "once_cell", "regex", "rustfix", "serde", @@ -1217,12 +1207,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "difference" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" - -[[package]] name = "digest" version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1379,6 +1363,15 @@ dependencies = [ ] [[package]] +name = "elsa" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f74077c3c3aedb99a2683919698285596662518ea13e5eedcf8bdd43b0d0453b" +dependencies = [ + "stable_deref_trait", +] + +[[package]] name = "ena" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1452,6 +1445,7 @@ name = "error_index_generator" version = "0.0.0" dependencies = [ "mdbook", + "rustc_error_codes", ] [[package]] @@ -1934,8 +1928,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ - "compiler_builtins", "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01" +dependencies = [ + "compiler_builtins", "rustc-std-workspace-alloc", "rustc-std-workspace-core", ] @@ -3184,14 +3186,14 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "pretty_assertions" -version = "0.6.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427" +checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755" dependencies = [ - "ansi_term 0.11.0", "ctor", - "difference", + "diff", "output_vt100", + "yansi", ] [[package]] @@ -3689,6 +3691,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", + "thin-vec", "tracing", ] @@ -3698,6 +3701,7 @@ version = "0.0.0" dependencies = [ "rustc_ast", "rustc_span", + "thin-vec", ] [[package]] @@ -3882,6 +3886,7 @@ dependencies = [ "arrayvec 0.7.0", "bitflags", "cfg-if", + "elsa", "ena", "indexmap", "jobserver", @@ -3918,26 +3923,47 @@ version = "0.0.0" dependencies = [ "libc", "rustc_ast", + "rustc_ast_lowering", + "rustc_ast_passes", "rustc_ast_pretty", + "rustc_attr", + "rustc_borrowck", + "rustc_builtin_macros", "rustc_codegen_ssa", + "rustc_const_eval", "rustc_data_structures", "rustc_error_codes", + "rustc_error_messages", "rustc_errors", + "rustc_expand", "rustc_feature", "rustc_hir", "rustc_hir_analysis", "rustc_hir_pretty", + "rustc_hir_typeck", + "rustc_incremental", + "rustc_infer", "rustc_interface", "rustc_lint", "rustc_log", "rustc_macros", "rustc_metadata", "rustc_middle", + "rustc_mir_build", + "rustc_mir_dataflow", + "rustc_monomorphize", "rustc_parse", + "rustc_passes", "rustc_plugin_impl", + "rustc_privacy", + "rustc_query_system", + "rustc_resolve", "rustc_session", "rustc_span", + "rustc_symbol_mangling", "rustc_target", + "rustc_trait_selection", + "rustc_ty_utils", "serde_json", "tracing", "winapi", @@ -4071,6 +4097,7 @@ dependencies = [ "rustc_trait_selection", "rustc_type_ir", "smallvec", + "thin-vec", "tracing", ] @@ -4127,6 +4154,7 @@ dependencies = [ "rustc_serialize", "rustc_session", "rustc_span", + "thin-vec", "tracing", ] @@ -4826,7 +4854,6 @@ dependencies = [ "serde_json", "smallvec", "tempfile", - "thin-vec", "tracing", "tracing-subscriber", "tracing-tree", @@ -5276,7 +5303,7 @@ dependencies = [ "dlmalloc", "fortanix-sgx-abi", "hashbrown 0.12.3", - "hermit-abi 0.2.6", + "hermit-abi 0.3.0", "libc", "miniz_oxide", "object 0.29.0", @@ -5471,10 +5498,8 @@ dependencies = [ name = "test" version = "0.0.0" dependencies = [ - "cfg-if", "core", "getopts", - "libc", "panic_abort", "panic_unwind", "proc_macro", @@ -5502,9 +5527,9 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thin-vec" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceb05e71730d396f960f8f3901cdb41be2d339b303e9d7d3a07c5ff0536e671b" +checksum = "aac81b6fd6beb5884b0cf3321b8117e6e5d47ecb6fc89f414cfdcca8b2fe2dd8" [[package]] name = "thiserror" @@ -5749,7 +5774,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245da694cc7fc4729f3f418b304cb57789f1bed2a78c575407ab8a23f53cb4d3" dependencies = [ - "ansi_term 0.12.1", + "ansi_term", "lazy_static", "matchers", "parking_lot 0.11.2", @@ -5768,7 +5793,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ce989c9962c7f61fe084dd4a230eec784649dfc2392467c790007c3a6e134e7" dependencies = [ - "ansi_term 0.12.1", + "ansi_term", "atty", "tracing-core", "tracing-log", diff --git a/compiler/rustc_ast/Cargo.toml b/compiler/rustc_ast/Cargo.toml index 10d7fa1db60..f0632ac92e9 100644 --- a/compiler/rustc_ast/Cargo.toml +++ b/compiler/rustc_ast/Cargo.toml @@ -15,5 +15,5 @@ rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index f2258fecfea..03c375c4666 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -209,7 +209,7 @@ pub struct AngleBracketedArgs { /// The overall span. pub span: Span, /// The comma separated parts in the `<...>`. - pub args: Vec<AngleBracketedArg>, + pub args: ThinVec<AngleBracketedArg>, } /// Either an argument for a parameter e.g., `'a`, `Vec<u8>`, `0`, @@ -253,7 +253,7 @@ pub struct ParenthesizedArgs { pub span: Span, /// `(A, B)` - pub inputs: Vec<P<Ty>>, + pub inputs: ThinVec<P<Ty>>, /// ```text /// Foo(A, B) -> C @@ -384,7 +384,7 @@ impl GenericParam { /// a function, enum, trait, etc. #[derive(Clone, Encodable, Decodable, Debug)] pub struct Generics { - pub params: Vec<GenericParam>, + pub params: ThinVec<GenericParam>, pub where_clause: WhereClause, pub span: Span, } @@ -392,7 +392,7 @@ pub struct Generics { impl Default for Generics { /// Creates an instance of `Generics`. fn default() -> Generics { - Generics { params: Vec::new(), where_clause: Default::default(), span: DUMMY_SP } + Generics { params: ThinVec::new(), where_clause: Default::default(), span: DUMMY_SP } } } @@ -403,13 +403,13 @@ pub struct WhereClause { /// if we parsed no predicates (e.g. `struct Foo where {}`). /// This allows us to pretty-print accurately. pub has_where_token: bool, - pub predicates: Vec<WherePredicate>, + pub predicates: ThinVec<WherePredicate>, pub span: Span, } impl Default for WhereClause { fn default() -> WhereClause { - WhereClause { has_where_token: false, predicates: Vec::new(), span: DUMMY_SP } + WhereClause { has_where_token: false, predicates: ThinVec::new(), span: DUMMY_SP } } } @@ -441,7 +441,7 @@ impl WherePredicate { pub struct WhereBoundPredicate { pub span: Span, /// Any generics from a `for` binding. - pub bound_generic_params: Vec<GenericParam>, + pub bound_generic_params: ThinVec<GenericParam>, /// The type being bounded. pub bounded_ty: P<Ty>, /// Trait and lifetime bounds (`Clone + Send + 'static`). @@ -471,7 +471,7 @@ pub struct WhereEqPredicate { #[derive(Clone, Encodable, Decodable, Debug)] pub struct Crate { pub attrs: AttrVec, - pub items: Vec<P<Item>>, + pub items: ThinVec<P<Item>>, pub spans: ModSpans, /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold /// expansion placeholders or an unassigned value (`DUMMY_NODE_ID`) before that. @@ -503,7 +503,7 @@ pub enum MetaItemKind { /// List meta item. /// /// E.g., `#[derive(..)]`, where the field represents the `..`. - List(Vec<NestedMetaItem>), + List(ThinVec<NestedMetaItem>), /// Name value meta item. /// @@ -531,7 +531,7 @@ pub enum NestedMetaItem { #[derive(Clone, Encodable, Decodable, Debug)] pub struct Block { /// The statements in the block. - pub stmts: Vec<Stmt>, + pub stmts: ThinVec<Stmt>, pub id: NodeId, /// Distinguishes between `unsafe { ... }` and `{ ... }`. pub rules: BlockCheckMode, @@ -581,7 +581,7 @@ impl Pat { // A tuple pattern `(P0, .., Pn)` can be reparsed as `(T0, .., Tn)` // assuming `T0` to `Tn` are all syntactically valid as types. PatKind::Tuple(pats) => { - let mut tys = Vec::with_capacity(pats.len()); + let mut tys = ThinVec::with_capacity(pats.len()); // FIXME(#48994) - could just be collected into an Option<Vec> for pat in pats { tys.push(pat.to_ty()?); @@ -722,14 +722,14 @@ pub enum PatKind { /// A struct or struct variant pattern (e.g., `Variant {x, y, ..}`). /// The `bool` is `true` in the presence of a `..`. - Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool), + Struct(Option<P<QSelf>>, Path, ThinVec<PatField>, /* recovered */ bool), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>), + TupleStruct(Option<P<QSelf>>, Path, ThinVec<P<Pat>>), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. - Or(Vec<P<Pat>>), + Or(ThinVec<P<Pat>>), /// A possibly qualified path pattern. /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants @@ -738,7 +738,7 @@ pub enum PatKind { Path(Option<P<QSelf>>, Path), /// A tuple pattern (`(a, b)`). - Tuple(Vec<P<Pat>>), + Tuple(ThinVec<P<Pat>>), /// A `box` pattern. Box(P<Pat>), @@ -753,7 +753,7 @@ pub enum PatKind { Range(Option<P<Expr>>, Option<P<Expr>>, Spanned<RangeEnd>), /// A slice pattern `[a, b, c]`. - Slice(Vec<P<Pat>>), + Slice(ThinVec<P<Pat>>), /// A rest pattern `..`. /// @@ -1169,7 +1169,7 @@ impl Expr { pub fn to_bound(&self) -> Option<GenericBound> { match &self.kind { ExprKind::Path(None, path) => Some(GenericBound::Trait( - PolyTraitRef::new(Vec::new(), path.clone(), self.span), + PolyTraitRef::new(ThinVec::new(), path.clone(), self.span), TraitBoundModifier::None, )), _ => None, @@ -1204,7 +1204,7 @@ impl Expr { ExprKind::Array(exprs) if exprs.len() == 1 => exprs[0].to_ty().map(TyKind::Slice)?, ExprKind::Tup(exprs) => { - let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<Vec<_>>>()?; + let tys = exprs.iter().map(|expr| expr.to_ty()).collect::<Option<ThinVec<_>>>()?; TyKind::Tup(tys) } @@ -1337,7 +1337,7 @@ pub struct MethodCall { /// The receiver, e.g. `x`. pub receiver: P<Expr>, /// The arguments, e.g. `a, b, c`. - pub args: Vec<P<Expr>>, + pub args: ThinVec<P<Expr>>, /// The span of the function, without the dot and receiver e.g. `foo::<Bar, /// Baz>(a, b, c)`. pub span: Span, @@ -1357,7 +1357,7 @@ pub enum StructRest { pub struct StructExpr { pub qself: Option<P<QSelf>>, pub path: Path, - pub fields: Vec<ExprField>, + pub fields: ThinVec<ExprField>, pub rest: StructRest, } @@ -1366,7 +1366,7 @@ pub enum ExprKind { /// A `box x` expression. Box(P<Expr>), /// An array (`[a, b, c, d]`) - Array(Vec<P<Expr>>), + Array(ThinVec<P<Expr>>), /// Allow anonymous constants from an inline `const` block ConstBlock(AnonConst), /// A function call @@ -1375,11 +1375,11 @@ pub enum ExprKind { /// and the second field is the list of arguments. /// This also represents calling the constructor of /// tuple-like ADTs such as tuple structs and enum variants. - Call(P<Expr>, Vec<P<Expr>>), + Call(P<Expr>, ThinVec<P<Expr>>), /// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`). MethodCall(Box<MethodCall>), /// A tuple (e.g., `(a, b, c, d)`). - Tup(Vec<P<Expr>>), + Tup(ThinVec<P<Expr>>), /// A binary operation (e.g., `a + b`, `a * b`). Binary(BinOp, P<Expr>, P<Expr>), /// A unary operation (e.g., `!x`, `*x`). @@ -1414,7 +1414,7 @@ pub enum ExprKind { /// `'label: loop { block }` Loop(P<Block>, Option<Label>, Span), /// A `match` block. - Match(P<Expr>, Vec<Arm>), + Match(P<Expr>, ThinVec<Arm>), /// A closure (e.g., `move |a, b, c| a + b + c`). Closure(Box<Closure>), /// A block (`'label: { ... }`). @@ -1574,7 +1574,7 @@ pub enum ClosureBinder { /// for<'a, 'b> |_: &'a (), _: &'b ()| { ... } /// ^^^^^^ -- this /// ``` - generic_params: P<[GenericParam]>, + generic_params: ThinVec<GenericParam>, }, } @@ -2056,7 +2056,7 @@ impl Ty { pub struct BareFnTy { pub unsafety: Unsafe, pub ext: Extern, - pub generic_params: Vec<GenericParam>, + pub generic_params: ThinVec<GenericParam>, pub decl: P<FnDecl>, /// Span of the `fn(...) -> ...` part. pub decl_span: Span, @@ -2078,7 +2078,7 @@ pub enum TyKind { /// The never type (`!`). Never, /// A tuple (`(A, B, C, D,...)`). - Tup(Vec<P<Ty>>), + Tup(ThinVec<P<Ty>>), /// A path (`module::module::...::Type`), optionally /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. /// @@ -2363,7 +2363,7 @@ impl Param { /// which contains metadata about function safety, asyncness, constness and ABI. #[derive(Clone, Encodable, Decodable, Debug)] pub struct FnDecl { - pub inputs: Vec<Param>, + pub inputs: ThinVec<Param>, pub output: FnRetTy, } @@ -2475,7 +2475,7 @@ pub enum ModKind { /// or with definition outlined to a separate file `mod foo;` and already loaded from it. /// The inner span is from the first token past `{` to the last token until `}`, /// or from the first to the last token in the loaded file. - Loaded(Vec<P<Item>>, Inline, ModSpans), + Loaded(ThinVec<P<Item>>, Inline, ModSpans), /// Module with definition outlined to a separate file `mod foo;` but not yet loaded from it. Unloaded, } @@ -2497,12 +2497,12 @@ pub struct ForeignMod { /// semantically by Rust. pub unsafety: Unsafe, pub abi: Option<StrLit>, - pub items: Vec<P<ForeignItem>>, + pub items: ThinVec<P<ForeignItem>>, } #[derive(Clone, Encodable, Decodable, Debug)] pub struct EnumDef { - pub variants: Vec<Variant>, + pub variants: ThinVec<Variant>, } /// Enum variant. #[derive(Clone, Encodable, Decodable, Debug)] @@ -2532,7 +2532,7 @@ pub enum UseTreeKind { /// `use prefix` or `use prefix as rename` Simple(Option<Ident>), /// `use prefix::{...}` - Nested(Vec<(UseTree, NodeId)>), + Nested(ThinVec<(UseTree, NodeId)>), /// `use prefix::*` Glob, } @@ -2636,7 +2636,7 @@ pub struct TraitRef { #[derive(Clone, Encodable, Decodable, Debug)] pub struct PolyTraitRef { /// The `'a` in `for<'a> Foo<&'a T>`. - pub bound_generic_params: Vec<GenericParam>, + pub bound_generic_params: ThinVec<GenericParam>, /// The `Foo<&'a T>` in `<'a> Foo<&'a T>`. pub trait_ref: TraitRef, @@ -2645,7 +2645,7 @@ pub struct PolyTraitRef { } impl PolyTraitRef { - pub fn new(generic_params: Vec<GenericParam>, path: Path, span: Span) -> Self { + pub fn new(generic_params: ThinVec<GenericParam>, path: Path, span: Span) -> Self { PolyTraitRef { bound_generic_params: generic_params, trait_ref: TraitRef { path, ref_id: DUMMY_NODE_ID }, @@ -2695,11 +2695,11 @@ pub enum VariantData { /// Struct variant. /// /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. - Struct(Vec<FieldDef>, bool), + Struct(ThinVec<FieldDef>, bool), /// Tuple variant. /// /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. - Tuple(Vec<FieldDef>, NodeId), + Tuple(ThinVec<FieldDef>, NodeId), /// Unit variant. /// /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`. @@ -2826,7 +2826,7 @@ pub struct Trait { pub is_auto: IsAuto, pub generics: Generics, pub bounds: GenericBounds, - pub items: Vec<P<AssocItem>>, + pub items: ThinVec<P<AssocItem>>, } /// The location of a where clause on a `TyAlias` (`Span`) and whether there was @@ -2874,7 +2874,7 @@ pub struct Impl { /// The trait being implemented, if any. pub of_trait: Option<TraitRef>, pub self_ty: P<Ty>, - pub items: Vec<P<AssocItem>>, + pub items: ThinVec<P<AssocItem>>, } #[derive(Clone, Encodable, Decodable, Debug)] @@ -3112,26 +3112,26 @@ mod size_asserts { static_assert_size!(AssocItem, 104); static_assert_size!(AssocItemKind, 32); static_assert_size!(Attribute, 32); - static_assert_size!(Block, 48); + static_assert_size!(Block, 32); static_assert_size!(Expr, 72); static_assert_size!(ExprKind, 40); - static_assert_size!(Fn, 184); + static_assert_size!(Fn, 152); static_assert_size!(ForeignItem, 96); static_assert_size!(ForeignItemKind, 24); static_assert_size!(GenericArg, 24); - static_assert_size!(GenericBound, 72); - static_assert_size!(Generics, 72); - static_assert_size!(Impl, 184); - static_assert_size!(Item, 184); - static_assert_size!(ItemKind, 112); + static_assert_size!(GenericBound, 56); + static_assert_size!(Generics, 40); + static_assert_size!(Impl, 136); + static_assert_size!(Item, 136); + static_assert_size!(ItemKind, 64); static_assert_size!(LitKind, 24); static_assert_size!(Local, 72); static_assert_size!(MetaItemLit, 40); static_assert_size!(Param, 40); - static_assert_size!(Pat, 88); + static_assert_size!(Pat, 72); static_assert_size!(Path, 24); static_assert_size!(PathSegment, 24); - static_assert_size!(PatKind, 64); + static_assert_size!(PatKind, 48); static_assert_size!(Stmt, 32); static_assert_size!(StmtKind, 16); static_assert_size!(Ty, 64); diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index e75d2f77dbb..2e83b3e623f 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -20,7 +20,7 @@ use std::iter; use std::ops::BitXor; #[cfg(debug_assertions)] use std::sync::atomic::{AtomicU32, Ordering}; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub struct MarkedAttrs(GrowableBitSet<AttrId>); @@ -135,7 +135,7 @@ impl Attribute { } } - pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> { + pub fn meta_item_list(&self) -> Option<ThinVec<NestedMetaItem>> { match &self.kind { AttrKind::Normal(normal) => normal.item.meta_item_list(), AttrKind::DocComment(..) => None, @@ -216,7 +216,7 @@ impl AttrItem { self.args.span().map_or(self.path.span, |args_span| self.path.span.to(args_span)) } - fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> { + fn meta_item_list(&self) -> Option<ThinVec<NestedMetaItem>> { match &self.args { AttrArgs::Delimited(args) if args.delim == MacDelimiter::Parenthesis => { MetaItemKind::list_from_tokens(args.tokens.clone()) @@ -375,9 +375,9 @@ impl MetaItemKind { } } - fn list_from_tokens(tokens: TokenStream) -> Option<Vec<NestedMetaItem>> { + fn list_from_tokens(tokens: TokenStream) -> Option<ThinVec<NestedMetaItem>> { let mut tokens = tokens.into_trees().peekable(); - let mut result = Vec::new(); + let mut result = ThinVec::new(); while tokens.peek().is_some() { let item = NestedMetaItem::from_tokens(&mut tokens)?; result.push(item); diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 1dd62626b8f..7dcb03b4c78 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -17,10 +17,10 @@ use rustc_data_structures::sync::Lrc; use rustc_span::source_map::Spanned; use rustc_span::symbol::Ident; use rustc_span::Span; - use smallvec::{smallvec, Array, SmallVec}; use std::ops::DerefMut; use std::{panic, ptr}; +use thin_vec::ThinVec; pub trait ExpectOne<A: Array> { fn expect_one(self, err: &'static str) -> A::Item; @@ -337,6 +337,17 @@ where // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. #[inline] +pub fn visit_thin_vec<T, F>(elems: &mut ThinVec<T>, mut visit_elem: F) +where + F: FnMut(&mut T), +{ + for elem in elems { + visit_elem(elem); + } +} + +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +#[inline] pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) where F: FnMut(&mut T), @@ -359,6 +370,11 @@ pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) { } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_thin_exprs<T: MutVisitor>(exprs: &mut ThinVec<P<Expr>>, vis: &mut T) { + exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr)) +} + +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) { visit_vec(bounds, |bound| vis.visit_param_bound(bound)); } @@ -474,7 +490,7 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) { vis.visit_fn_decl(decl); vis.visit_span(decl_span); } - TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)), + TyKind::Tup(tys) => visit_thin_vec(tys, |ty| vis.visit_ty(ty)), TyKind::Paren(ty) => vis.visit_ty(ty), TyKind::Path(qself, path) => { vis.visit_qself(qself); @@ -561,7 +577,7 @@ pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>( vis: &mut T, ) { let AngleBracketedArgs { args, span } = data; - visit_vec(args, |arg| match arg { + visit_thin_vec(args, |arg| match arg { AngleBracketedArg::Arg(arg) => vis.visit_generic_arg(arg), AngleBracketedArg::Constraint(constraint) => vis.visit_constraint(constraint), }); @@ -573,7 +589,7 @@ pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>( vis: &mut T, ) { let ParenthesizedArgs { inputs, output, span, .. } = args; - visit_vec(inputs, |input| vis.visit_ty(input)); + visit_thin_vec(inputs, |input| vis.visit_ty(input)); noop_visit_fn_ret_ty(output, vis); vis.visit_span(span); } @@ -636,7 +652,7 @@ pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) { let MetaItem { path: _, kind, span } = mi; match kind { MetaItemKind::Word => {} - MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)), + MetaItemKind::List(mis) => visit_thin_vec(mis, |mi| vis.visit_meta_list_item(mi)), MetaItemKind::NameValue(_s) => {} } vis.visit_span(span); @@ -839,9 +855,7 @@ pub fn noop_visit_closure_binder<T: MutVisitor>(binder: &mut ClosureBinder, vis: match binder { ClosureBinder::NotPresent => {} ClosureBinder::For { span: _, generic_params } => { - let mut vec = std::mem::take(generic_params).into_vec(); - vec.flat_map_in_place(|param| vis.flat_map_generic_param(param)); - *generic_params = P::from_vec(vec); + generic_params.flat_map_in_place(|param| vis.flat_map_generic_param(param)); } } } @@ -919,7 +933,7 @@ pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) { let WhereClause { has_where_token: _, predicates, span } = wc; - visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); + visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate)); vis.visit_span(span); } @@ -1227,7 +1241,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { PatKind::TupleStruct(qself, path, elems) => { vis.visit_qself(qself); vis.visit_path(path); - visit_vec(elems, |elem| vis.visit_pat(elem)); + visit_thin_vec(elems, |elem| vis.visit_pat(elem)); } PatKind::Path(qself, path) => { vis.visit_qself(qself); @@ -1246,7 +1260,7 @@ pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) { vis.visit_span(span); } PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { - visit_vec(elems, |elem| vis.visit_pat(elem)) + visit_thin_vec(elems, |elem| vis.visit_pat(elem)) } PatKind::Paren(inner) => vis.visit_pat(inner), PatKind::MacCall(mac) => vis.visit_mac_call(mac), @@ -1303,7 +1317,7 @@ pub fn noop_visit_expr<T: MutVisitor>( ) { match kind { ExprKind::Box(expr) => vis.visit_expr(expr), - ExprKind::Array(exprs) => visit_exprs(exprs, vis), + ExprKind::Array(exprs) => visit_thin_exprs(exprs, vis), ExprKind::ConstBlock(anon_const) => { vis.visit_anon_const(anon_const); } @@ -1311,10 +1325,10 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_expr(expr); vis.visit_anon_const(count); } - ExprKind::Tup(exprs) => visit_exprs(exprs, vis), + ExprKind::Tup(exprs) => visit_thin_exprs(exprs, vis), ExprKind::Call(f, args) => { vis.visit_expr(f); - visit_exprs(args, vis); + visit_thin_exprs(args, vis); } ExprKind::MethodCall(box MethodCall { seg: PathSegment { ident, id, args: seg_args }, @@ -1326,7 +1340,7 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_id(id); visit_opt(seg_args, |args| vis.visit_generic_args(args)); vis.visit_method_receiver_expr(receiver); - visit_exprs(call_args, vis); + visit_thin_exprs(call_args, vis); vis.visit_span(span); } ExprKind::Binary(_binop, lhs, rhs) => { diff --git a/compiler/rustc_ast_lowering/Cargo.toml b/compiler/rustc_ast_lowering/Cargo.toml index 6e76c349a4a..eb2e82d7988 100644 --- a/compiler/rustc_ast_lowering/Cargo.toml +++ b/compiler/rustc_ast_lowering/Cargo.toml @@ -19,5 +19,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl b/compiler/rustc_ast_lowering/locales/en-US.ftl index 03c88c6c0eb..a2837deafde 100644 --- a/compiler/rustc_error_messages/locales/en-US/ast_lowering.ftl +++ b/compiler/rustc_ast_lowering/locales/en-US.ftl @@ -19,6 +19,9 @@ ast_lowering_remove_parentheses = remove these parentheses ast_lowering_misplaced_impl_trait = `impl Trait` only allowed in function and inherent method return types, not in {$position} +ast_lowering_misplaced_assoc_ty_binding = + associated type bounds are only allowed in where clauses and function signatures, not in {$position} + ast_lowering_rustc_box_attribute_error = #[rustc_box] requires precisely one argument and no other attributes are allowed diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 21c6a2d26f4..def74c2adee 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -79,6 +79,14 @@ pub struct MisplacedImplTrait<'a> { pub position: DiagnosticArgFromDisplay<'a>, } +#[derive(Diagnostic)] +#[diag(ast_lowering_misplaced_assoc_ty_binding)] +pub struct MisplacedAssocTyBinding<'a> { + #[primary_span] + pub span: Span, + pub position: DiagnosticArgFromDisplay<'a>, +} + #[derive(Diagnostic, Clone, Copy)] #[diag(ast_lowering_rustc_box_attribute_error)] pub struct RustcBoxAttributeError { @@ -339,7 +347,7 @@ pub struct InclusiveRangeWithNoEnd { #[derive(Diagnostic, Clone, Copy)] #[diag(ast_lowering_trait_fn_async, code = "E0706")] #[note] -#[note(note2)] +#[note(ast_lowering_note2)] pub struct TraitFnAsync { #[primary_span] pub fn_span: Span, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index c4442b34fe4..d4fafe38638 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -18,7 +18,7 @@ use rustc_session::errors::report_lit_error; use rustc_span::source_map::{respan, DesugaringKind, Span, Spanned}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::DUMMY_SP; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; impl<'hir> LoweringContext<'_, 'hir> { fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] { @@ -88,8 +88,8 @@ impl<'hir> LoweringContext<'_, 'hir> { let kind = hir::ExprKind::Box(self.lower_expr(&inner)); return hir::Expr { hir_id, kind, span: self.lower_span(e.span) }; } else { - self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span }); - hir::ExprKind::Err + let guar = self.tcx.sess.emit_err(RustcBoxAttributeError { span: e.span }); + hir::ExprKind::Err(guar) } } else if let Some(legacy_args) = self.resolver.legacy_const_generic_args(f) { self.lower_legacy_const_generics((**f).clone(), args.clone(), &legacy_args) @@ -266,8 +266,8 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_expr_range(e.span, e1.as_deref(), e2.as_deref(), *lims) } ExprKind::Underscore => { - self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); - hir::ExprKind::Err + let guar = self.tcx.sess.emit_err(UnderscoreExprLhsAssign { span: e.span }); + hir::ExprKind::Err(guar) } ExprKind::Path(qself, path) => { let qpath = self.lower_qpath( @@ -299,8 +299,9 @@ impl<'hir> LoweringContext<'_, 'hir> { let rest = match &se.rest { StructRest::Base(e) => Some(self.lower_expr(e)), StructRest::Rest(sp) => { - self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp }); - Some(&*self.arena.alloc(self.expr_err(*sp))) + let guar = + self.tcx.sess.emit_err(BaseExpressionDoubleDot { span: *sp }); + Some(&*self.arena.alloc(self.expr_err(*sp, guar))) } StructRest::None => None, }; @@ -318,7 +319,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ) } ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()), - ExprKind::Err => hir::ExprKind::Err, + ExprKind::Err => hir::ExprKind::Err( + self.tcx.sess.delay_span_bug(e.span, "lowered ExprKind::Err"), + ), ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr), ExprKind::Paren(_) | ExprKind::ForLoop(..) => unreachable!("already handled"), @@ -367,7 +370,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_legacy_const_generics( &mut self, mut f: Expr, - args: Vec<AstP<Expr>>, + args: ThinVec<AstP<Expr>>, legacy_args_idx: &[usize], ) -> hir::ExprKind<'hir> { let ExprKind::Path(None, path) = &mut f.kind else { @@ -376,7 +379,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Split the arguments into const generics and normal arguments let mut real_args = vec![]; - let mut generic_args = vec![]; + let mut generic_args = ThinVec::new(); for (idx, arg) in args.into_iter().enumerate() { if legacy_args_idx.contains(&idx) { let parent_def_id = self.current_hir_id_owner; @@ -761,7 +764,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr_ident_mut(span, task_context_ident, task_context_hid) } else { // Use of `await` outside of an async context, we cannot use `task_context` here. - self.expr_err(span) + self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no task_context hir id")) }; let new_unchecked = self.expr_call_lang_item_fn_mut( span, diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index e7dd0b18a03..4095e225a80 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -102,7 +102,12 @@ fn make_count<'hir>( let value = ctx.arena.alloc_from_iter([ctx.expr_usize(sp, i)]); ctx.expr_call_mut(sp, count_param, value) } else { - ctx.expr(sp, hir::ExprKind::Err) + ctx.expr( + sp, + hir::ExprKind::Err( + ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count"), + ), + ) } } None => ctx.expr_lang_item_type_relative(sp, hir::LangItem::FormatCount, sym::Implied), @@ -135,7 +140,10 @@ fn make_format_spec<'hir>( argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait))); ctx.expr_usize(sp, i) } - Err(_) => ctx.expr(sp, hir::ExprKind::Err), + Err(_) => ctx.expr( + sp, + hir::ExprKind::Err(ctx.tcx.sess.delay_span_bug(sp, "lowered bad format_args count")), + ), }; let &FormatOptions { ref width, @@ -294,7 +302,12 @@ fn expand_format_args<'hir>( )); make_argument(ctx, sp, arg, ty) } else { - ctx.expr(macsp, hir::ExprKind::Err) + ctx.expr( + macsp, + hir::ExprKind::Err( + ctx.tcx.sess.delay_span_bug(macsp, format!("no arg at {arg_index}")), + ), + ) } })); let elements: Vec<_> = arguments diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 4a0e005b8b9..7325bce6055 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -7,6 +7,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; use rustc_data_structures::sorted_map::SortedMap; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; @@ -284,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .alloc_from_iter(fm.items.iter().map(|x| self.lower_foreign_item_ref(x))), }, ItemKind::GlobalAsm(asm) => hir::ItemKind::GlobalAsm(self.lower_inline_asm(span, asm)), - ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: Some(ty), .. }) => { + ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty, .. }) => { // We lower // // type Foo = impl Trait @@ -299,18 +300,16 @@ impl<'hir> LoweringContext<'_, 'hir> { &generics, id, &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - |this| this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy), - ); - hir::ItemKind::TyAlias(ty, generics) - } - ItemKind::TyAlias(box TyAlias { generics, where_clauses, ty: None, .. }) => { - let mut generics = generics.clone(); - add_ty_alias_where_clause(&mut generics, *where_clauses, true); - let (generics, ty) = self.lower_generics( - &generics, - id, - &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), - |this| this.arena.alloc(this.ty(span, hir::TyKind::Err)), + |this| match ty { + None => { + let guar = this.tcx.sess.delay_span_bug( + span, + "expected to lower type alias type, but it was missing", + ); + this.arena.alloc(this.ty(span, hir::TyKind::Err(guar))) + } + Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy), + }, ); hir::ItemKind::TyAlias(ty, generics) } @@ -798,8 +797,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } /// Construct `ExprKind::Err` for the given `span`. - pub(crate) fn expr_err(&mut self, span: Span) -> hir::Expr<'hir> { - self.expr(span, hir::ExprKind::Err) + pub(crate) fn expr_err(&mut self, span: Span, guar: ErrorGuaranteed) -> hir::Expr<'hir> { + self.expr(span, hir::ExprKind::Err(guar)) } fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { @@ -847,7 +846,11 @@ impl<'hir> LoweringContext<'_, 'hir> { &ImplTraitContext::Disallowed(ImplTraitPosition::Generic), |this| match ty { None => { - let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err)); + let guar = this.tcx.sess.delay_span_bug( + i.span, + "expected to lower associated type, but it was missing", + ); + let ty = this.arena.alloc(this.ty(i.span, hir::TyKind::Err(guar))); hir::ImplItemKind::Type(ty) } Some(ty) => { @@ -973,7 +976,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_block_expr_opt(&mut self, span: Span, block: Option<&Block>) -> hir::Expr<'hir> { match block { Some(block) => self.lower_block_expr(block), - None => self.expr_err(span), + None => self.expr_err(span, self.tcx.sess.delay_span_bug(span, "no block")), } } @@ -983,7 +986,7 @@ impl<'hir> LoweringContext<'_, 'hir> { &[], match expr { Some(expr) => this.lower_expr_mut(expr), - None => this.expr_err(span), + None => this.expr_err(span, this.tcx.sess.delay_span_bug(span, "no block")), }, ) }) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index b543be3be50..5d78d914b6d 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -52,23 +52,28 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::Lrc; -use rustc_errors::{DiagnosticArgFromDisplay, Handler, StashKey}; +use rustc_errors::{ + DiagnosticArgFromDisplay, DiagnosticMessage, Handler, StashKey, SubdiagnosticMessage, +}; use rustc_hir as hir; use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; use rustc_index::vec::{Idx, IndexVec}; -use rustc_middle::span_bug; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_macros::fluent_messages; +use rustc_middle::{ + span_bug, + ty::{ResolverAstLowering, TyCtxt}, +}; use rustc_session::parse::feature_err; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; - use smallvec::SmallVec; use std::collections::hash_map::Entry; +use thin_vec::ThinVec; macro_rules! arena_vec { ($this:expr; $($x:expr),*) => ( @@ -87,6 +92,8 @@ mod lifetime_collector; mod pat; mod path; +fluent_messages! { "../locales/en-US.ftl" } + struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, resolver: &'a mut ResolverAstLowering, @@ -281,31 +288,31 @@ enum ImplTraitPosition { impl std::fmt::Display for ImplTraitPosition { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let name = match self { - ImplTraitPosition::Path => "path", - ImplTraitPosition::Variable => "variable binding", - ImplTraitPosition::Trait => "trait", - ImplTraitPosition::AsyncBlock => "async block", - ImplTraitPosition::Bound => "bound", - ImplTraitPosition::Generic => "generic", - ImplTraitPosition::ExternFnParam => "`extern fn` param", - ImplTraitPosition::ClosureParam => "closure param", - ImplTraitPosition::PointerParam => "`fn` pointer param", - ImplTraitPosition::FnTraitParam => "`Fn` trait param", - ImplTraitPosition::TraitParam => "trait method param", - ImplTraitPosition::ImplParam => "`impl` method param", - ImplTraitPosition::ExternFnReturn => "`extern fn` return", - ImplTraitPosition::ClosureReturn => "closure return", - ImplTraitPosition::PointerReturn => "`fn` pointer return", - ImplTraitPosition::FnTraitReturn => "`Fn` trait return", - ImplTraitPosition::TraitReturn => "trait method return", - ImplTraitPosition::ImplReturn => "`impl` method return", - ImplTraitPosition::GenericDefault => "generic parameter default", - ImplTraitPosition::ConstTy => "const type", - ImplTraitPosition::StaticTy => "static type", - ImplTraitPosition::AssocTy => "associated type", - ImplTraitPosition::FieldTy => "field type", - ImplTraitPosition::Cast => "cast type", - ImplTraitPosition::ImplSelf => "impl header", + ImplTraitPosition::Path => "paths", + ImplTraitPosition::Variable => "variable bindings", + ImplTraitPosition::Trait => "traits", + ImplTraitPosition::AsyncBlock => "async blocks", + ImplTraitPosition::Bound => "bounds", + ImplTraitPosition::Generic => "generics", + ImplTraitPosition::ExternFnParam => "`extern fn` params", + ImplTraitPosition::ClosureParam => "closure params", + ImplTraitPosition::PointerParam => "`fn` pointer params", + ImplTraitPosition::FnTraitParam => "`Fn` trait params", + ImplTraitPosition::TraitParam => "trait method params", + ImplTraitPosition::ImplParam => "`impl` method params", + ImplTraitPosition::ExternFnReturn => "`extern fn` return types", + ImplTraitPosition::ClosureReturn => "closure return types", + ImplTraitPosition::PointerReturn => "`fn` pointer return types", + ImplTraitPosition::FnTraitReturn => "`Fn` trait return types", + ImplTraitPosition::TraitReturn => "trait method return types", + ImplTraitPosition::ImplReturn => "`impl` method return types", + ImplTraitPosition::GenericDefault => "generic parameter defaults", + ImplTraitPosition::ConstTy => "const types", + ImplTraitPosition::StaticTy => "static types", + ImplTraitPosition::AssocTy => "associated types", + ImplTraitPosition::FieldTy => "field types", + ImplTraitPosition::Cast => "cast types", + ImplTraitPosition::ImplSelf => "impl headers", }; write!(f, "{name}") @@ -995,8 +1002,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } else { self.arena.alloc(hir::GenericArgs::none()) }; - let itctx_tait = &ImplTraitContext::TypeAliasesOpaqueTy; - let kind = match &constraint.kind { AssocConstraintKind::Equality { term } => { let term = match term { @@ -1006,8 +1011,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { hir::TypeBindingKind::Equality { term } } AssocConstraintKind::Bound { bounds } => { + enum DesugarKind<'a> { + ImplTrait, + Error(&'a ImplTraitPosition), + Bound, + } + // Piggy-back on the `impl Trait` context to figure out the correct behavior. - let (desugar_to_impl_trait, itctx) = match itctx { + let desugar_kind = match itctx { // We are in the return position: // // fn foo() -> impl Iterator<Item: Debug> @@ -1016,7 +1027,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // // fn foo() -> impl Iterator<Item = impl Debug> ImplTraitContext::ReturnPositionOpaqueTy { .. } - | ImplTraitContext::TypeAliasesOpaqueTy { .. } => (true, itctx), + | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait, // We are in the argument position, but within a dyn type: // @@ -1025,15 +1036,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so desugar to // // fn foo(x: dyn Iterator<Item = impl Debug>) - ImplTraitContext::Universal if self.is_in_dyn_type => (true, itctx), + ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait, - // In `type Foo = dyn Iterator<Item: Debug>` we desugar to - // `type Foo = dyn Iterator<Item = impl Debug>` but we have to override the - // "impl trait context" to permit `impl Debug` in this position (it desugars - // then to an opaque type). - // - // FIXME: this is only needed until `impl Trait` is allowed in type aliases. - ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => (true, itctx_tait), + ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => { + DesugarKind::Error(position) + } // We are in the parameter position, but not within a dyn type: // @@ -1042,35 +1049,47 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // so we leave it as is and this gets expanded in astconv to a bound like // `<T as Iterator>::Item: Debug` where `T` is the type parameter for the // `impl Iterator`. - _ => (false, itctx), + _ => DesugarKind::Bound, }; - if desugar_to_impl_trait { - // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by - // constructing the HIR for `impl bounds...` and then lowering that. - - let impl_trait_node_id = self.next_node_id(); - - self.with_dyn_type_scope(false, |this| { - let node_id = this.next_node_id(); - let ty = this.lower_ty( - &Ty { - id: node_id, - kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), - span: this.lower_span(constraint.span), - tokens: None, - }, - itctx, - ); + match desugar_kind { + DesugarKind::ImplTrait => { + // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by + // constructing the HIR for `impl bounds...` and then lowering that. - hir::TypeBindingKind::Equality { term: ty.into() } - }) - } else { - // Desugar `AssocTy: Bounds` into a type binding where the - // later desugars into a trait predicate. - let bounds = self.lower_param_bounds(bounds, itctx); + let impl_trait_node_id = self.next_node_id(); - hir::TypeBindingKind::Constraint { bounds } + self.with_dyn_type_scope(false, |this| { + let node_id = this.next_node_id(); + let ty = this.lower_ty( + &Ty { + id: node_id, + kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), + span: this.lower_span(constraint.span), + tokens: None, + }, + itctx, + ); + + hir::TypeBindingKind::Equality { term: ty.into() } + }) + } + DesugarKind::Bound => { + // Desugar `AssocTy: Bounds` into a type binding where the + // later desugars into a trait predicate. + let bounds = self.lower_param_bounds(bounds, itctx); + + hir::TypeBindingKind::Constraint { bounds } + } + DesugarKind::Error(position) => { + let guar = self.tcx.sess.emit_err(errors::MisplacedAssocTyBinding { + span: constraint.span, + position: DiagnosticArgFromDisplay(position), + }); + let err_ty = + &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar))); + hir::TypeBindingKind::Equality { term: err_ty.into() } + } } } }; @@ -1207,7 +1226,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { let bound = this.lower_poly_trait_ref( &PolyTraitRef { - bound_generic_params: vec![], + bound_generic_params: ThinVec::new(), trait_ref: TraitRef { path: path.clone(), ref_id: t.id }, span: t.span }, @@ -1237,7 +1256,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> { let kind = match &t.kind { TyKind::Infer => hir::TyKind::Infer, - TyKind::Err => hir::TyKind::Err, + TyKind::Err => { + hir::TyKind::Err(self.tcx.sess.delay_span_bug(t.span, "TyKind::Err lowered")) + } TyKind::Slice(ty) => hir::TyKind::Slice(self.lower_ty(ty, itctx)), TyKind::Ptr(mt) => hir::TyKind::Ptr(self.lower_mt(mt, itctx)), TyKind::Ref(region, mt) => { @@ -1363,7 +1384,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { path } ImplTraitContext::FeatureGated(position, feature) => { - self.tcx + let guar = self + .tcx .sess .create_feature_err( MisplacedImplTrait { @@ -1373,24 +1395,24 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { *feature, ) .emit(); - hir::TyKind::Err + hir::TyKind::Err(guar) } ImplTraitContext::Disallowed(position) => { - self.tcx.sess.emit_err(MisplacedImplTrait { + let guar = self.tcx.sess.emit_err(MisplacedImplTrait { span: t.span, position: DiagnosticArgFromDisplay(position), }); - hir::TyKind::Err + hir::TyKind::Err(guar) } } } TyKind::MacCall(_) => panic!("`TyKind::MacCall` should have been expanded by now"), TyKind::CVarArgs => { - self.tcx.sess.delay_span_bug( + let guar = self.tcx.sess.delay_span_bug( t.span, "`TyKind::CVarArgs` should have been handled elsewhere", ); - hir::TyKind::Err + hir::TyKind::Err(guar) } }; diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index 06d885a45fb..2509b705639 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -330,8 +330,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ExprKind::Path(..) if allow_paths => {} ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {} _ => { - self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span }); - return self.arena.alloc(self.expr_err(expr.span)); + let guar = self.tcx.sess.emit_err(ArbitraryExpressionInPattern { span: expr.span }); + return self.arena.alloc(self.expr_err(expr.span, guar)); } } self.lower_expr(expr) diff --git a/compiler/rustc_ast_passes/Cargo.toml b/compiler/rustc_ast_passes/Cargo.toml index 37eff9207c1..8bd212073a6 100644 --- a/compiler/rustc_ast_passes/Cargo.toml +++ b/compiler/rustc_ast_passes/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] itertools = "0.10.1" -tracing = "0.1" +rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } @@ -16,4 +16,5 @@ rustc_parse = { path = "../rustc_parse" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -rustc_ast = { path = "../rustc_ast" } +thin-vec = "0.2.12" +tracing = "0.1" diff --git a/compiler/rustc_ast_passes/locales/en-US.ftl b/compiler/rustc_ast_passes/locales/en-US.ftl new file mode 100644 index 00000000000..747bd52b22c --- /dev/null +++ b/compiler/rustc_ast_passes/locales/en-US.ftl @@ -0,0 +1,236 @@ +ast_passes_forbidden_let = + `let` expressions are not supported here + .note = only supported directly in conditions of `if` and `while` expressions + .not_supported_or = `||` operators are not supported in let chain expressions + .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains + +ast_passes_forbidden_let_stable = + expected expression, found statement (`let`) + .note = variable declaration using `let` is a statement + +ast_passes_deprecated_where_clause_location = + where clause not allowed here + +ast_passes_keyword_lifetime = + lifetimes cannot use keyword names + +ast_passes_invalid_label = + invalid label name `{$name}` + +ast_passes_invalid_visibility = + unnecessary visibility qualifier + .implied = `pub` not permitted here because it's implied + .individual_impl_items = place qualifiers on individual impl items instead + .individual_foreign_items = place qualifiers on individual foreign items instead + +ast_passes_trait_fn_const = + functions in traits cannot be declared const + .label = functions in traits cannot be const + +ast_passes_forbidden_lifetime_bound = + lifetime bounds cannot be used in this context + +ast_passes_forbidden_non_lifetime_param = + only lifetime parameters can be used in this context + +ast_passes_fn_param_too_many = + function can not have more than {$max_num_args} arguments + +ast_passes_fn_param_c_var_args_only = + C-variadic function must be declared with at least one named argument + +ast_passes_fn_param_c_var_args_not_last = + `...` must be the last argument of a C-variadic function + +ast_passes_fn_param_doc_comment = + documentation comments cannot be applied to function parameters + .label = doc comments are not allowed here + +ast_passes_fn_param_forbidden_attr = + allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters + +ast_passes_fn_param_forbidden_self = + `self` parameter is only allowed in associated functions + .label = not semantically valid as function parameter + .note = associated functions are those in `impl` or `trait` definitions + +ast_passes_forbidden_default = + `default` is only allowed on items in trait impls + .label = `default` because of this + +ast_passes_assoc_const_without_body = + associated constant in `impl` without body + .suggestion = provide a definition for the constant + +ast_passes_assoc_fn_without_body = + associated function in `impl` without body + .suggestion = provide a definition for the function + +ast_passes_assoc_type_without_body = + associated type in `impl` without body + .suggestion = provide a definition for the type + +ast_passes_const_without_body = + free constant item without body + .suggestion = provide a definition for the constant + +ast_passes_static_without_body = + free static item without body + .suggestion = provide a definition for the static + +ast_passes_ty_alias_without_body = + free type alias without body + .suggestion = provide a definition for the type + +ast_passes_fn_without_body = + free function without a body + .suggestion = provide a definition for the function + +ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block + +ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect + +ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr} + .suggestion = remove the {$remove_descr} + .label = `extern` block begins here + +ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html + +ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block + .cannot_have = cannot have a body + .invalid = the invalid body + .existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body + +ast_passes_fn_body_extern = incorrect function inside `extern` block + .cannot_have = cannot have a body + .suggestion = remove the invalid body + .help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block + .label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body + +ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers + .label = in this `extern` block + .suggestion = remove the qualifiers + +ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers + .label = in this `extern` block + .note = this limitation may be lifted in the future; see issue #83942 <https://github.com/rust-lang/rust/issues/83942> for more information + +ast_passes_bad_c_variadic = only foreign or `unsafe extern "C"` functions may be C-variadic + +ast_passes_item_underscore = `{$kind}` items in this context need a name + .label = `_` is not a valid name for this `{$kind}` item + +ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier + +ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name + .help = consider using the `#[path]` attribute to specify filesystem path + +ast_passes_auto_generic = auto traits cannot have generic parameters + .label = auto trait cannot have generic parameters + .suggestion = remove the parameters + +ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds + .label = {ast_passes_auto_super_lifetime} + .suggestion = remove the super traits or lifetime bounds + +ast_passes_auto_items = auto traits cannot have associated items + .label = {ast_passes_auto_items} + .suggestion = remove these associated items + +ast_passes_generic_before_constraints = generic arguments must come before the first constraint + .constraints = {$constraint_len -> + [one] constraint + *[other] constraints + } + .args = generic {$args_len -> + [one] argument + *[other] arguments + } + .empty_string = {""}, + .suggestion = move the {$constraint_len -> + [one] constraint + *[other] constraints + } after the generic {$args_len -> + [one] argument + *[other] arguments + } + +ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types + +ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted + +ast_passes_impl_trait_path = `impl Trait` is not allowed in path parameters + +ast_passes_nested_impl_trait = nested `impl Trait` is not allowed + .outer = outer `impl Trait` + .inner = nested `impl Trait` here + +ast_passes_at_least_one_trait = at least one trait must be specified + +ast_passes_extern_without_abi = extern declarations without an explicit ABI are deprecated + +ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters + .suggestion = reorder the parameters: lifetimes, then consts and types + +ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax + .help = use `auto trait Trait {"{}"}` instead + +ast_passes_unsafe_negative_impl = negative impls cannot be unsafe + .negative = negative because of this + .unsafe = unsafe because of this + +ast_passes_inherent_cannot_be = inherent impls cannot be {$annotation} + .because = {$annotation} because of this + .type = inherent impl for this type + .only_trait = only trait implementations may be annotated with {$annotation} + +ast_passes_unsafe_item = {$kind} cannot be declared unsafe + +ast_passes_fieldless_union = unions cannot have zero fields + +ast_passes_where_after_type_alias = where clauses are not allowed after the type for type aliases + .note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information + +ast_passes_generic_default_trailing = generic parameters with a default must be trailing + +ast_passes_nested_lifetimes = nested quantification of lifetimes + +ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits + .note = traits are `?{$path_str}` by default + +ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types + +ast_passes_tilde_const_disallowed = `~const` is not allowed here + .trait = trait objects cannot have `~const` trait bounds + .closure = closures cannot have `~const` trait bounds + .function = this function is not `const`, so it cannot have `~const` trait bounds + +ast_passes_optional_const_exclusive = `~const` and `?` are mutually exclusive + +ast_passes_const_and_async = functions cannot be both `const` and `async` + .const = `const` because of this + .async = `async` because of this + .label = {""} + +ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations + .label = pattern not allowed in foreign function + +ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies + .label = pattern not allowed in function without body + +ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses + .label = not supported + .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax + .suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax + .note = see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information + +ast_passes_stability_outside_std = stability attributes may not be used outside of the standard library + +ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel + .suggestion = remove the attribute + .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable + +ast_passes_incompatbile_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed + .help = remove one of these features + +ast_passes_show_span = {$msg} diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index d1ae8c1fdbd..1c561375626 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -13,7 +13,6 @@ use rustc_ast::walk_list; use rustc_ast::*; use rustc_ast_pretty::pprust::{self, State}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability}; use rustc_macros::Subdiagnostic; use rustc_parse::validate_attr; use rustc_session::lint::builtin::{ @@ -27,11 +26,10 @@ use rustc_span::Span; use rustc_target::spec::abi; use std::mem; use std::ops::{Deref, DerefMut}; +use thin_vec::thin_vec; -use crate::errors::*; - -const MORE_EXTERN: &str = - "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html"; +use crate::errors; +use crate::fluent_generated as fluent; /// Is `self` allowed semantically as the first parameter in an `FnDecl`? enum SelfSemantic { @@ -69,10 +67,6 @@ struct AstValidator<'a> { /// or `Foo::Bar<impl Trait>` is_impl_trait_banned: bool, - /// Used to ban associated type bounds (i.e., `Type<AssocType: Bounds>`) in - /// certain positions. - is_assoc_ty_bound_banned: bool, - /// See [ForbiddenLetReason] forbidden_let_reason: Option<ForbiddenLetReason>, @@ -136,9 +130,9 @@ impl<'a> AstValidator<'a> { fn ban_let_expr(&self, expr: &'a Expr, forbidden_let_reason: ForbiddenLetReason) { let sess = &self.session; if sess.opts.unstable_features.is_nightly_build() { - sess.emit_err(ForbiddenLet { span: expr.span, reason: forbidden_let_reason }); + sess.emit_err(errors::ForbiddenLet { span: expr.span, reason: forbidden_let_reason }); } else { - sess.emit_err(ForbiddenLetStable { span: expr.span }); + sess.emit_err(errors::ForbiddenLetStable { span: expr.span }); } } @@ -178,30 +172,12 @@ impl<'a> AstValidator<'a> { } } - fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) { - let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true); - f(self); - self.is_assoc_ty_bound_banned = old; - } - fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.outer_impl_trait, outer); f(self); self.outer_impl_trait = old; } - fn visit_assoc_constraint_from_generic_args(&mut self, constraint: &'a AssocConstraint) { - match constraint.kind { - AssocConstraintKind::Equality { .. } => {} - AssocConstraintKind::Bound { .. } => { - if self.is_assoc_ty_bound_banned { - self.session.emit_err(ForbiddenAssocConstraint { span: constraint.span }); - } - } - } - self.visit_assoc_constraint(constraint); - } - // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { match &t.kind { @@ -254,22 +230,22 @@ impl<'a> AstValidator<'a> { fn check_lifetime(&self, ident: Ident) { let valid_names = [kw::UnderscoreLifetime, kw::StaticLifetime, kw::Empty]; if !valid_names.contains(&ident.name) && ident.without_first_quote().is_reserved() { - self.session.emit_err(KeywordLifetime { span: ident.span }); + self.session.emit_err(errors::KeywordLifetime { span: ident.span }); } } fn check_label(&self, ident: Ident) { if ident.without_first_quote().is_reserved() { - self.session.emit_err(InvalidLabel { span: ident.span, name: ident.name }); + self.session.emit_err(errors::InvalidLabel { span: ident.span, name: ident.name }); } } - fn invalid_visibility(&self, vis: &Visibility, note: Option<InvalidVisibilityNote>) { + fn invalid_visibility(&self, vis: &Visibility, note: Option<errors::InvalidVisibilityNote>) { if let VisibilityKind::Inherited = vis.kind { return; } - self.session.emit_err(InvalidVisibility { + self.session.emit_err(errors::InvalidVisibility { span: vis.span, implied: vis.kind.is_pub().then_some(vis.span), note, @@ -290,7 +266,7 @@ impl<'a> AstValidator<'a> { fn check_trait_fn_not_const(&self, constness: Const) { if let Const::Yes(span) = constness { - self.session.emit_err(TraitFnConst { span }); + self.session.emit_err(errors::TraitFnConst { span }); } } @@ -307,7 +283,7 @@ impl<'a> AstValidator<'a> { let max_num_args: usize = u16::MAX.into(); if fn_decl.inputs.len() > max_num_args { let Param { span, .. } = fn_decl.inputs[0]; - self.session.emit_fatal(FnParamTooMany { span, max_num_args }); + self.session.emit_fatal(errors::FnParamTooMany { span, max_num_args }); } } @@ -315,13 +291,13 @@ impl<'a> AstValidator<'a> { match &*fn_decl.inputs { [Param { ty, span, .. }] => { if let TyKind::CVarArgs = ty.kind { - self.session.emit_err(FnParamCVarArgsOnly { span: *span }); + self.session.emit_err(errors::FnParamCVarArgsOnly { span: *span }); } } [ps @ .., _] => { for Param { ty, span, .. } in ps { if let TyKind::CVarArgs = ty.kind { - self.session.emit_err(FnParamCVarArgsNotLast { span: *span }); + self.session.emit_err(errors::FnParamCVarArgsNotLast { span: *span }); } } } @@ -348,9 +324,9 @@ impl<'a> AstValidator<'a> { }) .for_each(|attr| { if attr.is_doc_comment() { - self.session.emit_err(FnParamDocComment { span: attr.span }); + self.session.emit_err(errors::FnParamDocComment { span: attr.span }); } else { - self.session.emit_err(FnParamForbiddenAttr { span: attr.span }); + self.session.emit_err(errors::FnParamForbiddenAttr { span: attr.span }); } }); } @@ -358,7 +334,7 @@ impl<'a> AstValidator<'a> { fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) { if let (SelfSemantic::No, [param, ..]) = (self_semantic, &*fn_decl.inputs) { if param.is_self() { - self.session.emit_err(FnParamForbiddenSelf { span: param.span }); + self.session.emit_err(errors::FnParamForbiddenSelf { span: param.span }); } } } @@ -366,7 +342,7 @@ impl<'a> AstValidator<'a> { fn check_defaultness(&self, span: Span, defaultness: Defaultness) { if let Defaultness::Default(def_span) = defaultness { let span = self.session.source_map().guess_head_span(span); - self.session.emit_err(ForbiddenDefault { span, def_span }); + self.session.emit_err(errors::ForbiddenDefault { span, def_span }); } } @@ -389,27 +365,17 @@ impl<'a> AstValidator<'a> { [b0] => b0.span(), [b0, .., bl] => b0.span().to(bl.span()), }; - self.err_handler() - .struct_span_err(span, &format!("bounds on `type`s in {} have no effect", ctx)) - .emit(); + self.err_handler().emit_err(errors::BoundInContext { span, ctx }); } fn check_foreign_ty_genericless(&self, generics: &Generics, where_span: Span) { let cannot_have = |span, descr, remove_descr| { - self.err_handler() - .struct_span_err( - span, - &format!("`type`s inside `extern` blocks cannot have {}", descr), - ) - .span_suggestion( - span, - &format!("remove the {}", remove_descr), - "", - Applicability::MaybeIncorrect, - ) - .span_label(self.current_extern_span(), "`extern` block begins here") - .note(MORE_EXTERN) - .emit(); + self.err_handler().emit_err(errors::ExternTypesCannotHave { + span, + descr, + remove_descr, + block_span: self.current_extern_span(), + }); }; if !generics.params.is_empty() { @@ -425,20 +391,12 @@ impl<'a> AstValidator<'a> { let Some(body) = body else { return; }; - self.err_handler() - .struct_span_err(ident.span, &format!("incorrect `{}` inside `extern` block", kind)) - .span_label(ident.span, "cannot have a body") - .span_label(body, "the invalid body") - .span_label( - self.current_extern_span(), - format!( - "`extern` blocks define existing foreign {0}s and {0}s \ - inside of them cannot have a body", - kind - ), - ) - .note(MORE_EXTERN) - .emit(); + self.err_handler().emit_err(errors::BodyInExtern { + span: ident.span, + body, + block: self.current_extern_span(), + kind, + }); } /// An `fn` in `extern { ... }` cannot have a body `{ ... }`. @@ -446,26 +404,11 @@ impl<'a> AstValidator<'a> { let Some(body) = body else { return; }; - self.err_handler() - .struct_span_err(ident.span, "incorrect function inside `extern` block") - .span_label(ident.span, "cannot have a body") - .span_suggestion( - body.span, - "remove the invalid body", - ";", - Applicability::MaybeIncorrect, - ) - .help( - "you might have meant to write a function accessible through FFI, \ - which can be done by writing `extern fn` outside of the `extern` block", - ) - .span_label( - self.current_extern_span(), - "`extern` blocks define existing foreign functions and functions \ - inside of them cannot have a body", - ) - .note(MORE_EXTERN) - .emit(); + self.err_handler().emit_err(errors::FnBodyInExtern { + span: ident.span, + body: body.span, + block: self.current_extern_span(), + }); } fn current_extern_span(&self) -> Span { @@ -475,34 +418,21 @@ impl<'a> AstValidator<'a> { /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`. fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) { if header.has_qualifiers() { - self.err_handler() - .struct_span_err(ident.span, "functions in `extern` blocks cannot have qualifiers") - .span_label(self.current_extern_span(), "in this `extern` block") - .span_suggestion_verbose( - span.until(ident.span.shrink_to_lo()), - "remove the qualifiers", - "fn ", - Applicability::MaybeIncorrect, - ) - .emit(); + self.err_handler().emit_err(errors::FnQualifierInExtern { + span: ident.span, + block: self.current_extern_span(), + sugg_span: span.until(ident.span.shrink_to_lo()), + }); } } /// An item in `extern { ... }` cannot use non-ascii identifier. fn check_foreign_item_ascii_only(&self, ident: Ident) { if !ident.as_str().is_ascii() { - let n = 83942; - self.err_handler() - .struct_span_err( - ident.span, - "items in `extern` blocks cannot use non-ascii identifiers", - ) - .span_label(self.current_extern_span(), "in this `extern` block") - .note(&format!( - "this limitation may be lifted in the future; see issue #{} <https://github.com/rust-lang/rust/issues/{}> for more information", - n, n, - )) - .emit(); + self.err_handler().emit_err(errors::ExternItemAscii { + span: ident.span, + block: self.current_extern_span(), + }); } } @@ -525,12 +455,7 @@ impl<'a> AstValidator<'a> { for Param { ty, span, .. } in &fk.decl().inputs { if let TyKind::CVarArgs = ty.kind { - self.err_handler() - .struct_span_err( - *span, - "only foreign or `unsafe extern \"C\"` functions may be C-variadic", - ) - .emit(); + self.err_handler().emit_err(errors::BadCVariadic { span: *span }); } } } @@ -539,75 +464,32 @@ impl<'a> AstValidator<'a> { if ident.name != kw::Underscore { return; } - self.err_handler() - .struct_span_err(ident.span, &format!("`{}` items in this context need a name", kind)) - .span_label(ident.span, format!("`_` is not a valid name for this `{}` item", kind)) - .emit(); + self.err_handler().emit_err(errors::ItemUnderscore { span: ident.span, kind }); } fn check_nomangle_item_asciionly(&self, ident: Ident, item_span: Span) { if ident.name.as_str().is_ascii() { return; } - let head_span = self.session.source_map().guess_head_span(item_span); - struct_span_err!( - self.session, - head_span, - E0754, - "`#[no_mangle]` requires ASCII identifier" - ) - .emit(); + let span = self.session.source_map().guess_head_span(item_span); + self.session.emit_err(errors::NoMangleAscii { span }); } fn check_mod_file_item_asciionly(&self, ident: Ident) { if ident.name.as_str().is_ascii() { return; } - struct_span_err!( - self.session, - ident.span, - E0754, - "trying to load file for module `{}` with non-ascii identifier name", - ident.name - ) - .help("consider using `#[path]` attribute to specify filesystem path") - .emit(); + self.session.emit_err(errors::ModuleNonAscii { span: ident.span, name: ident.name }); } - fn deny_generic_params(&self, generics: &Generics, ident_span: Span) { + fn deny_generic_params(&self, generics: &Generics, ident: Span) { if !generics.params.is_empty() { - struct_span_err!( - self.session, - generics.span, - E0567, - "auto traits cannot have generic parameters" - ) - .span_label(ident_span, "auto trait cannot have generic parameters") - .span_suggestion( - generics.span, - "remove the parameters", - "", - Applicability::MachineApplicable, - ) - .emit(); + self.session.emit_err(errors::AutoTraitGeneric { span: generics.span, ident }); } } - fn emit_e0568(&self, span: Span, ident_span: Span) { - struct_span_err!( - self.session, - span, - E0568, - "auto traits cannot have super traits or lifetime bounds" - ) - .span_label(ident_span, "auto trait cannot have super traits or lifetime bounds") - .span_suggestion( - span, - "remove the super traits or lifetime bounds", - "", - Applicability::MachineApplicable, - ) - .emit(); + fn emit_e0568(&self, span: Span, ident: Span) { + self.session.emit_err(errors::AutoTraitBounds { span, ident }); } fn deny_super_traits(&self, bounds: &GenericBounds, ident_span: Span) { @@ -623,24 +505,11 @@ impl<'a> AstValidator<'a> { } } - fn deny_items(&self, trait_items: &[P<AssocItem>], ident_span: Span) { + fn deny_items(&self, trait_items: &[P<AssocItem>], ident: Span) { if !trait_items.is_empty() { let spans: Vec<_> = trait_items.iter().map(|i| i.ident.span).collect(); - let total_span = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span); - struct_span_err!( - self.session, - spans, - E0380, - "auto traits cannot have associated items" - ) - .span_suggestion( - total_span, - "remove these associated items", - "", - Applicability::MachineApplicable, - ) - .span_label(ident_span, "auto trait cannot have associated items") - .emit(); + let total = trait_items.first().unwrap().span.to(trait_items.last().unwrap().span); + self.session.emit_err(errors::AutoTraitItems { spans, total, ident }); } } @@ -686,29 +555,17 @@ impl<'a> AstValidator<'a> { let args_len = arg_spans.len(); let constraint_len = constraint_spans.len(); // ...and then error: - self.err_handler() - .struct_span_err( - arg_spans.clone(), - "generic arguments must come before the first constraint", - ) - .span_label(constraint_spans[0], &format!("constraint{}", pluralize!(constraint_len))) - .span_label( - *arg_spans.iter().last().unwrap(), - &format!("generic argument{}", pluralize!(args_len)), - ) - .span_labels(constraint_spans, "") - .span_labels(arg_spans, "") - .span_suggestion_verbose( - data.span, - &format!( - "move the constraint{} after the generic argument{}", - pluralize!(constraint_len), - pluralize!(args_len) - ), - self.correct_generic_order_suggestion(&data), - Applicability::MachineApplicable, - ) - .emit(); + self.err_handler().emit_err(errors::ArgsBeforeConstraint { + arg_spans: arg_spans.clone(), + constraints: constraint_spans[0], + args: *arg_spans.iter().last().unwrap(), + data: data.span, + constraint_spans: errors::EmptyLabelManySpans(constraint_spans), + arg_spans2: errors::EmptyLabelManySpans(arg_spans), + suggestion: self.correct_generic_order_suggestion(&data), + constraint_len, + args_len, + }); } fn visit_ty_common(&mut self, ty: &'a Ty) { @@ -716,13 +573,7 @@ impl<'a> AstValidator<'a> { TyKind::BareFn(bfty) => { self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _, _| { - struct_span_err!( - self.session, - span, - E0561, - "patterns aren't allowed in function pointer types" - ) - .emit(); + self.session.emit_err(errors::PatternFnPointer { span }); }); if let Extern::Implicit(_) = bfty.ext { let sig_span = self.session.source_map().next_point(ty.span.shrink_to_lo()); @@ -734,13 +585,8 @@ impl<'a> AstValidator<'a> { for bound in bounds { if let GenericBound::Outlives(lifetime) = bound { if any_lifetime_bounds { - struct_span_err!( - self.session, - lifetime.ident.span, - E0226, - "only a single explicit lifetime bound is permitted" - ) - .emit(); + self.session + .emit_err(errors::TraitObjectBound { span: lifetime.ident.span }); break; } any_lifetime_bounds = true; @@ -749,29 +595,19 @@ impl<'a> AstValidator<'a> { } TyKind::ImplTrait(_, bounds) => { if self.is_impl_trait_banned { - struct_span_err!( - self.session, - ty.span, - E0667, - "`impl Trait` is not allowed in path parameters" - ) - .emit(); + self.session.emit_err(errors::ImplTraitPath { span: ty.span }); } if let Some(outer_impl_trait_sp) = self.outer_impl_trait { - struct_span_err!( - self.session, - ty.span, - E0666, - "nested `impl Trait` is not allowed" - ) - .span_label(outer_impl_trait_sp, "outer `impl Trait`") - .span_label(ty.span, "nested `impl Trait` here") - .emit(); + self.session.emit_err(errors::NestedImplTrait { + span: ty.span, + outer: outer_impl_trait_sp, + inner: ty.span, + }); } if !bounds.iter().any(|b| matches!(b, GenericBound::Trait(..))) { - self.err_handler().span_err(ty.span, "at least one trait must be specified"); + self.err_handler().emit_err(errors::AtLeastOneTrait { span: ty.span }); } } _ => {} @@ -792,7 +628,7 @@ impl<'a> AstValidator<'a> { MISSING_ABI, id, span, - "extern declarations without an explicit ABI are deprecated", + fluent::ast_passes_extern_without_abi, BuiltinLintDiagnostics::MissingAbi(span, abi::Abi::FALLBACK), ) } @@ -865,20 +701,13 @@ fn validate_generic_param_order( ordered_params += ">"; for (param_ord, (max_param, spans)) in &out_of_order { - let mut err = handler.struct_span_err( - spans.clone(), - &format!( - "{} parameters must be declared prior to {} parameters", - param_ord, max_param, - ), - ); - err.span_suggestion( - span, - "reorder the parameters: lifetimes, then consts and types", - &ordered_params, - Applicability::MachineApplicable, - ); - err.emit(); + handler.emit_err(errors::OutOfOrderParams { + spans: spans.clone(), + sugg_span: span, + param_ord, + max_param, + ordered_params: &ordered_params, + }); } } } @@ -992,25 +821,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.with_in_trait_impl(true, Some(*constness), |this| { this.invalid_visibility(&item.vis, None); if let TyKind::Err = self_ty.kind { - this.err_handler() - .struct_span_err( - item.span, - "`impl Trait for .. {}` is an obsolete syntax", - ) - .help("use `auto trait Trait {}` instead") - .emit(); + this.err_handler().emit_err(errors::ObsoleteAuto { span: item.span }); } if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity) { - struct_span_err!( - this.session, - sp.to(t.path.span), - E0198, - "negative impls cannot be unsafe" - ) - .span_label(sp, "negative because of this") - .span_label(span, "unsafe because of this") - .emit(); + this.session.emit_err(errors::UnsafeNegativeImpl { + span: sp.to(t.path.span), + negative: sp, + r#unsafe: span, + }); } this.visit_vis(&item.vis); @@ -1038,52 +857,54 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self_ty, items: _, }) => { - let error = |annotation_span, annotation| { - let mut err = self.err_handler().struct_span_err( - self_ty.span, - &format!("inherent impls cannot be {}", annotation), - ); - err.span_label(annotation_span, &format!("{} because of this", annotation)); - err.span_label(self_ty.span, "inherent impl for this type"); - err - }; + let error = + |annotation_span, annotation, only_trait: bool| errors::InherentImplCannot { + span: self_ty.span, + annotation_span, + annotation, + self_ty: self_ty.span, + only_trait: only_trait.then_some(()), + }; self.invalid_visibility( &item.vis, - Some(InvalidVisibilityNote::IndividualImplItems), + Some(errors::InvalidVisibilityNote::IndividualImplItems), ); if let &Unsafe::Yes(span) = unsafety { - error(span, "unsafe").code(error_code!(E0197)).emit(); + self.err_handler().emit_err(errors::InherentImplCannotUnsafe { + span: self_ty.span, + annotation_span: span, + annotation: "unsafe", + self_ty: self_ty.span, + }); } if let &ImplPolarity::Negative(span) = polarity { - error(span, "negative").emit(); + self.err_handler().emit_err(error(span, "negative", false)); } if let &Defaultness::Default(def_span) = defaultness { - error(def_span, "`default`") - .note("only trait implementations may be annotated with `default`") - .emit(); + self.err_handler().emit_err(error(def_span, "`default`", true)); } if let &Const::Yes(span) = constness { - error(span, "`const`") - .note("only trait implementations may be annotated with `const`") - .emit(); + self.err_handler().emit_err(error(span, "`const`", true)); } } ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => { self.check_defaultness(item.span, *defaultness); if body.is_none() { - self.session.emit_err(FnWithoutBody { + self.session.emit_err(errors::FnWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), extern_block_suggestion: match sig.header.ext { Extern::None => None, - Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit { - start_span, - end_span: item.span.shrink_to_hi(), - }), + Extern::Implicit(start_span) => { + Some(errors::ExternBlockSuggestion::Implicit { + start_span, + end_span: item.span.shrink_to_hi(), + }) + } Extern::Explicit(abi, start_span) => { - Some(ExternBlockSuggestion::Explicit { + Some(errors::ExternBlockSuggestion::Explicit { start_span, end_span: item.span.shrink_to_hi(), abi: abi.symbol_unescaped, @@ -1105,10 +926,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { let old_item = mem::replace(&mut self.extern_mod, Some(item)); self.invalid_visibility( &item.vis, - Some(InvalidVisibilityNote::IndividualForeignItems), + Some(errors::InvalidVisibilityNote::IndividualForeignItems), ); if let &Unsafe::Yes(span) = unsafety { - self.err_handler().span_err(span, "extern block cannot be declared unsafe"); + self.err_handler().emit_err(errors::UnsafeItem { span, kind: "extern block" }); } if abi.is_none() { self.maybe_lint_missing_abi(item.span, item.id); @@ -1148,7 +969,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Mod(unsafety, mod_kind) => { if let &Unsafe::Yes(span) = unsafety { - self.err_handler().span_err(span, "module cannot be declared unsafe"); + self.err_handler().emit_err(errors::UnsafeItem { span, kind: "module" }); } // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). if !matches!(mod_kind, ModKind::Loaded(_, Inline::Yes, _)) @@ -1159,18 +980,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ItemKind::Union(vdata, ..) => { if vdata.fields().is_empty() { - self.err_handler().span_err(item.span, "unions cannot have zero fields"); + self.err_handler().emit_err(errors::FieldlessUnion { span: item.span }); } } ItemKind::Const(def, .., None) => { self.check_defaultness(item.span, *def); - self.session.emit_err(ConstWithoutBody { + self.session.emit_err(errors::ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); } ItemKind::Static(.., None) => { - self.session.emit_err(StaticWithoutBody { + self.session.emit_err(errors::StaticWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); @@ -1178,21 +999,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => { self.check_defaultness(item.span, *defaultness); if ty.is_none() { - self.session.emit_err(TyAliasWithoutBody { + self.session.emit_err(errors::TyAliasWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); } self.check_type_no_bounds(bounds, "this context"); if where_clauses.1.0 { - let mut err = self.err_handler().struct_span_err( - where_clauses.1.1, - "where clauses are not allowed after the type for type aliases", - ); - err.note( - "see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information", - ); - err.emit(); + self.err_handler() + .emit_err(errors::WhereAfterTypeAlias { span: where_clauses.1.1 }); } } _ => {} @@ -1246,7 +1061,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // are allowed to contain nested `impl Trait`. AngleBracketedArg::Constraint(constraint) => { self.with_impl_trait(None, |this| { - this.visit_assoc_constraint_from_generic_args(constraint); + this.visit_assoc_constraint(constraint); }); } } @@ -1274,11 +1089,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } GenericParamKind::Type { .. } | GenericParamKind::Const { .. } => { if let Some(span) = prev_param_default { - let mut err = self.err_handler().struct_span_err( - span, - "generic parameters with a default must be trailing", - ); - err.emit(); + self.err_handler().emit_err(errors::GenericDefaultTrailing { span }); break; } } @@ -1306,13 +1117,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { match bound { GenericBound::Trait(t, _) => { if !t.bound_generic_params.is_empty() { - struct_span_err!( - self.err_handler(), - t.span, - E0316, - "nested quantification of lifetimes" - ) - .emit(); + self.err_handler() + .emit_err(errors::NestedLifetimes { span: t.span }); } } GenericBound::Outlives(_) => {} @@ -1337,32 +1143,27 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let GenericBound::Trait(poly, modify) = bound { match (ctxt, modify) { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { - let mut err = self - .err_handler() - .struct_span_err(poly.span, "`?Trait` is not permitted in supertraits"); - let path_str = pprust::path_to_string(&poly.trait_ref.path); - err.note(&format!("traits are `?{}` by default", path_str)); - err.emit(); + self.err_handler().emit_err(errors::OptionalTraitSupertrait { + span: poly.span, + path_str: pprust::path_to_string(&poly.trait_ref.path) + }); } (BoundKind::TraitObject, TraitBoundModifier::Maybe) => { - let mut err = self.err_handler().struct_span_err( - poly.span, - "`?Trait` is not permitted in trait object types", - ); - err.emit(); + self.err_handler().emit_err(errors::OptionalTraitObject {span: poly.span}); } (_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => { - let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here"); - match reason { - DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"), - DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"), - DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"), + let reason = match reason { + DisallowTildeConstContext::TraitObject => errors::TildeConstReason::TraitObject, + DisallowTildeConstContext::Fn(FnKind::Closure(..)) => errors::TildeConstReason::Closure, + DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => errors::TildeConstReason::Function { ident: ident.span }, }; - err.emit(); + self.err_handler().emit_err(errors::TildeConstDisallowed { + span: bound.span(), + reason + }); } (_, TraitBoundModifier::MaybeConstMaybe) => { - self.err_handler() - .span_err(bound.span(), "`~const` and `?` are mutually exclusive"); + self.err_handler().emit_err(errors::OptionalConstExclusive {span: bound.span()}); } _ => {} } @@ -1371,14 +1172,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_param_bound(self, bound) } - fn visit_variant_data(&mut self, s: &'a VariantData) { - self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s)) - } - - fn visit_enum_def(&mut self, enum_definition: &'a EnumDef) { - self.with_banned_assoc_ty_bound(|this| visit::walk_enum_def(this, enum_definition)) - } - fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) { // Only associated `fn`s can have `self` parameters. let self_semantic = match fk.ctxt() { @@ -1390,21 +1183,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_c_variadic_type(fk); // Functions cannot both be `const async` - if let Some(FnHeader { + if let Some(&FnHeader { constness: Const::Yes(cspan), asyncness: Async::Yes { span: aspan, .. }, .. }) = fk.header() { - self.err_handler() - .struct_span_err( - vec![*cspan, *aspan], - "functions cannot be both `const` and `async`", - ) - .span_label(*cspan, "`const` because of this") - .span_label(*aspan, "`async` because of this") - .span_label(span, "") // Point at the fn header. - .emit(); + self.err_handler().emit_err(errors::ConstAndAsync { + spans: vec![cspan, aspan], + cspan, + aspan, + span, + }); } if let FnKind::Fn( @@ -1422,20 +1212,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Functions without bodies cannot have patterns. if let FnKind::Fn(ctxt, _, sig, _, _, None) = fk { Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { - let (code, msg, label) = match ctxt { - FnCtxt::Foreign => ( - error_code!(E0130), - "patterns aren't allowed in foreign function declarations", - "pattern not allowed in foreign function", - ), - _ => ( - error_code!(E0642), - "patterns aren't allowed in functions without bodies", - "pattern not allowed in function without body", - ), - }; if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if let Some(ident) = ident { + let msg = match ctxt { + FnCtxt::Foreign => fluent::ast_passes_pattern_in_foreign, + _ => fluent::ast_passes_pattern_in_bodiless, + }; let diag = BuiltinLintDiagnostics::PatternsInFnsWithoutBody(span, ident); self.lint_buffer.buffer_lint_with_diagnostic( PATTERNS_IN_FNS_WITHOUT_BODY, @@ -1446,11 +1228,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ) } } else { - self.err_handler() - .struct_span_err(span, msg) - .span_label(span, label) - .code(code) - .emit(); + match ctxt { + FnCtxt::Foreign => { + self.err_handler().emit_err(errors::PatternInForeign { span }) + } + _ => self.err_handler().emit_err(errors::PatternInBodiless { span }), + }; } }); } @@ -1477,7 +1260,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { match &item.kind { AssocItemKind::Const(_, _, body) => { if body.is_none() { - self.session.emit_err(AssocConstWithoutBody { + self.session.emit_err(errors::AssocConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); @@ -1485,7 +1268,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } AssocItemKind::Fn(box Fn { body, .. }) => { if body.is_none() { - self.session.emit_err(AssocFnWithoutBody { + self.session.emit_err(errors::AssocFnWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); @@ -1500,7 +1283,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .. }) => { if ty.is_none() { - self.session.emit_err(AssocTypeWithoutBody { + self.session.emit_err(errors::AssocTypeWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), }); @@ -1572,11 +1355,7 @@ fn deny_equality_constraints( predicate: &WhereEqPredicate, generics: &Generics, ) { - let mut err = this.err_handler().struct_span_err( - predicate.span, - "equality constraints are not yet supported in `where` clauses", - ); - err.span_label(predicate.span, "not supported"); + let mut err = errors::EqualityInWhere { span: predicate.span, assoc: None, assoc2: None }; // Given `<A as Foo>::Bar = RhsTy`, suggest `A: Foo<Bar = RhsTy>`. if let TyKind::Path(Some(qself), full_path) = &predicate.lhs_ty.kind { @@ -1615,25 +1394,17 @@ fn deny_equality_constraints( empty_args => { *empty_args = AngleBracketedArgs { span: ident.span, - args: vec![arg], + args: thin_vec![arg], } .into(); } } - err.span_suggestion_verbose( - predicate.span, - &format!( - "if `{}` is an associated type you're trying to set, \ - use the associated type binding syntax", - ident - ), - format!( - "{}: {}", - param, - pprust::path_to_string(&assoc_path) - ), - Applicability::MaybeIncorrect, - ); + err.assoc = Some(errors::AssociatedSuggestion { + span: predicate.span, + ident: *ident, + param: *param, + path: pprust::path_to_string(&assoc_path), + }) } _ => {} }; @@ -1675,15 +1446,13 @@ fn deny_equality_constraints( trait_segment.span().shrink_to_hi(), ), }; - err.multipart_suggestion( - &format!( - "if `{}::{}` is an associated type you're trying to set, \ - use the associated type binding syntax", - trait_segment.ident, potential_assoc.ident, - ), - vec![(span, args), (predicate.span, String::new())], - Applicability::MaybeIncorrect, - ); + err.assoc2 = Some(errors::AssociatedSuggestion2 { + span, + args, + predicate: predicate.span, + trait_segment: trait_segment.ident, + potential_assoc: potential_assoc.ident, + }); } } } @@ -1691,10 +1460,7 @@ fn deny_equality_constraints( } } } - err.note( - "see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information", - ); - err.emit(); + this.err_handler().emit_err(err); } pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> bool { @@ -1707,7 +1473,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) -> outer_impl_trait: None, disallow_tilde_const: None, is_impl_trait_banned: false, - is_assoc_ty_bound_banned: false, forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden), lint_buffer: lints, }; @@ -1722,12 +1487,12 @@ pub(crate) enum ForbiddenLetReason { /// `let` is not valid and the source environment is not important GenericForbidden, /// A let chain with the `||` operator - #[note(not_supported_or)] + #[note(ast_passes_not_supported_or)] NotSupportedOr(#[primary_span] Span), /// A let chain with invalid parentheses /// /// For example, `let 1 = 1 && (expr && expr)` is allowed /// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not - #[note(not_supported_parentheses)] + #[note(ast_passes_not_supported_parentheses)] NotSupportedParentheses(#[primary_span] Span), } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 09e262452b1..d007097d918 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -1,9 +1,12 @@ //! Errors emitted by ast_passes. +use rustc_ast::ParamKindOrd; +use rustc_errors::AddToDiagnostic; use rustc_macros::{Diagnostic, Subdiagnostic}; -use rustc_span::{Span, Symbol}; +use rustc_span::{symbol::Ident, Span, Symbol}; use crate::ast_validation::ForbiddenLetReason; +use crate::fluent_generated as fluent; #[derive(Diagnostic)] #[diag(ast_passes_forbidden_let)] @@ -24,13 +27,6 @@ pub struct ForbiddenLetStable { } #[derive(Diagnostic)] -#[diag(ast_passes_forbidden_assoc_constraint)] -pub struct ForbiddenAssocConstraint { - #[primary_span] - pub span: Span, -} - -#[derive(Diagnostic)] #[diag(ast_passes_keyword_lifetime)] pub struct KeywordLifetime { #[primary_span] @@ -50,7 +46,7 @@ pub struct InvalidLabel { pub struct InvalidVisibility { #[primary_span] pub span: Span, - #[label(implied)] + #[label(ast_passes_implied)] pub implied: Option<Span>, #[subdiagnostic] pub note: Option<InvalidVisibilityNote>, @@ -58,9 +54,9 @@ pub struct InvalidVisibility { #[derive(Subdiagnostic)] pub enum InvalidVisibilityNote { - #[note(individual_impl_items)] + #[note(ast_passes_individual_impl_items)] IndividualImplItems, - #[note(individual_foreign_items)] + #[note(ast_passes_individual_foreign_items)] IndividualForeignItems, } @@ -224,3 +220,474 @@ pub enum ExternBlockSuggestion { abi: Symbol, }, } + +#[derive(Diagnostic)] +#[diag(ast_passes_bound_in_context)] +pub struct BoundInContext<'a> { + #[primary_span] + pub span: Span, + pub ctx: &'a str, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_extern_types_cannot)] +#[note(ast_passes_extern_keyword_link)] +pub struct ExternTypesCannotHave<'a> { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub span: Span, + pub descr: &'a str, + pub remove_descr: &'a str, + #[label] + pub block_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_body_in_extern)] +#[note(ast_passes_extern_keyword_link)] +pub struct BodyInExtern<'a> { + #[primary_span] + #[label(ast_passes_cannot_have)] + pub span: Span, + #[label(ast_passes_invalid)] + pub body: Span, + #[label(ast_passes_existing)] + pub block: Span, + pub kind: &'a str, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_fn_body_extern)] +#[help] +#[note(ast_passes_extern_keyword_link)] +pub struct FnBodyInExtern { + #[primary_span] + #[label(ast_passes_cannot_have)] + pub span: Span, + #[suggestion(code = ";", applicability = "maybe-incorrect")] + pub body: Span, + #[label] + pub block: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_extern_fn_qualifiers)] +pub struct FnQualifierInExtern { + #[primary_span] + pub span: Span, + #[label] + pub block: Span, + #[suggestion(code = "fn ", applicability = "maybe-incorrect", style = "verbose")] + pub sugg_span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_extern_item_ascii)] +#[note] +pub struct ExternItemAscii { + #[primary_span] + pub span: Span, + #[label] + pub block: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_bad_c_variadic)] +pub struct BadCVariadic { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_item_underscore)] +pub struct ItemUnderscore<'a> { + #[primary_span] + #[label] + pub span: Span, + pub kind: &'a str, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_nomangle_ascii, code = "E0754")] +pub struct NoMangleAscii { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_module_nonascii, code = "E0754")] +#[help] +pub struct ModuleNonAscii { + #[primary_span] + pub span: Span, + pub name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_auto_generic, code = "E0567")] +pub struct AutoTraitGeneric { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable")] + pub span: Span, + #[label] + pub ident: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_auto_super_lifetime, code = "E0568")] +pub struct AutoTraitBounds { + #[primary_span] + #[suggestion(code = "", applicability = "machine-applicable")] + pub span: Span, + #[label] + pub ident: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_auto_items, code = "E0380")] +pub struct AutoTraitItems { + #[primary_span] + pub spans: Vec<Span>, + #[suggestion(code = "", applicability = "machine-applicable")] + pub total: Span, + #[label] + pub ident: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_generic_before_constraints)] +pub struct ArgsBeforeConstraint { + #[primary_span] + pub arg_spans: Vec<Span>, + #[label(ast_passes_constraints)] + pub constraints: Span, + #[label(ast_passes_args)] + pub args: Span, + #[suggestion(code = "{suggestion}", applicability = "machine-applicable", style = "verbose")] + pub data: Span, + pub suggestion: String, + pub constraint_len: usize, + pub args_len: usize, + #[subdiagnostic] + pub constraint_spans: EmptyLabelManySpans, + #[subdiagnostic] + pub arg_spans2: EmptyLabelManySpans, +} + +pub struct EmptyLabelManySpans(pub Vec<Span>); + +// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each +impl AddToDiagnostic for EmptyLabelManySpans { + fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) + where + F: Fn( + &mut rustc_errors::Diagnostic, + rustc_errors::SubdiagnosticMessage, + ) -> rustc_errors::SubdiagnosticMessage, + { + diag.span_labels(self.0, ""); + } +} + +#[derive(Diagnostic)] +#[diag(ast_passes_pattern_in_fn_pointer, code = "E0561")] +pub struct PatternFnPointer { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_trait_object_single_bound, code = "E0226")] +pub struct TraitObjectBound { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_impl_trait_path, code = "E0667")] +pub struct ImplTraitPath { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_nested_impl_trait, code = "E0666")] +pub struct NestedImplTrait { + #[primary_span] + pub span: Span, + #[label(ast_passes_outer)] + pub outer: Span, + #[label(ast_passes_inner)] + pub inner: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_at_least_one_trait)] +pub struct AtLeastOneTrait { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_out_of_order_params)] +pub struct OutOfOrderParams<'a> { + #[primary_span] + pub spans: Vec<Span>, + #[suggestion(code = "{ordered_params}", applicability = "machine-applicable")] + pub sugg_span: Span, + pub param_ord: &'a ParamKindOrd, + pub max_param: &'a ParamKindOrd, + pub ordered_params: &'a str, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_obsolete_auto)] +#[help] +pub struct ObsoleteAuto { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_unsafe_negative_impl, code = "E0198")] +pub struct UnsafeNegativeImpl { + #[primary_span] + pub span: Span, + #[label(ast_passes_negative)] + pub negative: Span, + #[label(ast_passes_unsafe)] + pub r#unsafe: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_inherent_cannot_be)] +pub struct InherentImplCannot<'a> { + #[primary_span] + pub span: Span, + #[label(ast_passes_because)] + pub annotation_span: Span, + pub annotation: &'a str, + #[label(ast_passes_type)] + pub self_ty: Span, + #[note(ast_passes_only_trait)] + pub only_trait: Option<()>, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_inherent_cannot_be, code = "E0197")] +pub struct InherentImplCannotUnsafe<'a> { + #[primary_span] + pub span: Span, + #[label(ast_passes_because)] + pub annotation_span: Span, + pub annotation: &'a str, + #[label(ast_passes_type)] + pub self_ty: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_unsafe_item)] +pub struct UnsafeItem { + #[primary_span] + pub span: Span, + pub kind: &'static str, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_fieldless_union)] +pub struct FieldlessUnion { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_where_after_type_alias)] +#[note] +pub struct WhereAfterTypeAlias { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_generic_default_trailing)] +pub struct GenericDefaultTrailing { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_nested_lifetimes, code = "E0316")] +pub struct NestedLifetimes { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_optional_trait_supertrait)] +#[note] +pub struct OptionalTraitSupertrait { + #[primary_span] + pub span: Span, + pub path_str: String, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_optional_trait_object)] +pub struct OptionalTraitObject { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_tilde_const_disallowed)] +pub struct TildeConstDisallowed { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub reason: TildeConstReason, +} + +#[derive(Subdiagnostic)] +pub enum TildeConstReason { + #[note(ast_passes_trait)] + TraitObject, + #[note(ast_passes_closure)] + Closure, + #[note(ast_passes_function)] + Function { + #[primary_span] + ident: Span, + }, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_optional_const_exclusive)] +pub struct OptionalConstExclusive { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_const_and_async)] +pub struct ConstAndAsync { + #[primary_span] + pub spans: Vec<Span>, + #[label(ast_passes_const)] + pub cspan: Span, + #[label(ast_passes_async)] + pub aspan: Span, + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_pattern_in_foreign, code = "E0130")] +pub struct PatternInForeign { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_pattern_in_bodiless, code = "E0642")] +pub struct PatternInBodiless { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_equality_in_where)] +#[note] +pub struct EqualityInWhere { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub assoc: Option<AssociatedSuggestion>, + #[subdiagnostic] + pub assoc2: Option<AssociatedSuggestion2>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + ast_passes_suggestion, + code = "{param}: {path}", + style = "verbose", + applicability = "maybe-incorrect" +)] +pub struct AssociatedSuggestion { + #[primary_span] + pub span: Span, + pub ident: Ident, + pub param: Ident, + pub path: String, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion(ast_passes_suggestion_path, applicability = "maybe-incorrect")] +pub struct AssociatedSuggestion2 { + #[suggestion_part(code = "{args}")] + pub span: Span, + pub args: String, + #[suggestion_part(code = "")] + pub predicate: Span, + pub trait_segment: Ident, + pub potential_assoc: Ident, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_stability_outside_std, code = "E0734")] +pub struct StabilityOutsideStd { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_feature_on_non_nightly, code = "E0554")] +pub struct FeatureOnNonNightly { + #[primary_span] + pub span: Span, + pub channel: &'static str, + #[subdiagnostic] + pub stable_features: Vec<StableFeature>, + #[suggestion(code = "", applicability = "machine-applicable")] + pub sugg: Option<Span>, +} + +pub struct StableFeature { + pub name: Symbol, + pub since: Symbol, +} + +impl AddToDiagnostic for StableFeature { + fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) + where + F: Fn( + &mut rustc_errors::Diagnostic, + rustc_errors::SubdiagnosticMessage, + ) -> rustc_errors::SubdiagnosticMessage, + { + diag.set_arg("name", self.name); + diag.set_arg("since", self.since); + diag.help(fluent::ast_passes_stable_since); + } +} + +#[derive(Diagnostic)] +#[diag(ast_passes_incompatbile_features)] +#[help] +pub struct IncompatibleFeatures { + #[primary_span] + pub spans: Vec<Span>, + pub f1: Symbol, + pub f2: Symbol, +} + +#[derive(Diagnostic)] +#[diag(ast_passes_show_span)] +pub struct ShowSpan { + #[primary_span] + pub span: Span, + pub msg: &'static str, +} diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 3af2ef4e727..926b0da2ec6 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor}; use rustc_ast::{AssocConstraint, AssocConstraintKind, NodeId}; use rustc_ast::{PatKind, RangeEnd}; -use rustc_errors::{struct_span_err, Applicability, StashKey}; +use rustc_errors::{Applicability, StashKey}; use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::parse::{feature_err, feature_err_issue, feature_warn}; use rustc_session::Session; @@ -10,8 +10,10 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_target::spec::abi; +use thin_vec::ThinVec; +use tracing::debug; -use crate::errors::ForbiddenLifetimeBound; +use crate::errors; macro_rules! gate_feature_fn { ($visitor: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $help: expr) => {{ @@ -155,14 +157,14 @@ impl<'a> PostExpansionVisitor<'a> { &self.sess.parse_sess, sym::non_lifetime_binders, non_lt_param_spans, - rustc_errors::fluent::ast_passes_forbidden_non_lifetime_param, + crate::fluent_generated::ast_passes_forbidden_non_lifetime_param, ) .emit(); } for param in params { if !param.bounds.is_empty() { let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect(); - self.sess.emit_err(ForbiddenLifetimeBound { spans }); + self.sess.emit_err(errors::ForbiddenLifetimeBound { spans }); } } } @@ -216,13 +218,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { || attr.has_name(sym::rustc_const_stable) || attr.has_name(sym::rustc_default_body_unstable) { - struct_span_err!( - self.sess, - attr.span, - E0734, - "stability attributes may not be used outside of the standard library", - ) - .emit(); + self.sess.emit_err(errors::StabilityOutsideStd { span: attr.span }); } } } @@ -250,7 +246,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { ast::ItemKind::Struct(..) => { for attr in self.sess.filter_by_name(&i.attrs, sym::repr) { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(sym::simd) { gate_feature_post!( &self, @@ -633,13 +629,13 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { return; } for attr in krate.attrs.iter().filter(|attr| attr.has_name(sym::feature)) { - let mut err = struct_span_err!( - sess.parse_sess.span_diagnostic, - attr.span, - E0554, - "`#![feature]` may not be used on the {} release channel", - option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)") - ); + let mut err = errors::FeatureOnNonNightly { + span: attr.span, + channel: option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"), + stable_features: vec![], + sugg: None, + }; + let mut all_stable = true; for ident in attr.meta_item_list().into_iter().flatten().flat_map(|nested| nested.ident()) @@ -650,24 +646,15 @@ fn maybe_stage_features(sess: &Session, krate: &ast::Crate) { .flat_map(|&(feature, _, since)| if feature == name { since } else { None }) .next(); if let Some(since) = stable_since { - err.help(&format!( - "the feature `{}` has been stable since {} and no longer requires \ - an attribute to enable", - name, since - )); + err.stable_features.push(errors::StableFeature { name, since }); } else { all_stable = false; } } if all_stable { - err.span_suggestion( - attr.span, - "remove the attribute", - "", - Applicability::MachineApplicable, - ); + err.sugg = Some(attr.span); } - err.emit(); + sess.parse_sess.span_diagnostic.emit_err(err); } } } @@ -690,16 +677,7 @@ fn check_incompatible_features(sess: &Session) { if let Some((f2_name, f2_span)) = declared_features.clone().find(|(name, _)| name == f2) { let spans = vec![f1_span, f2_span]; - sess.struct_span_err( - spans, - &format!( - "features `{}` and `{}` are incompatible, using them at the same time \ - is not allowed", - f1_name, f2_name - ), - ) - .help("remove one of these features") - .emit(); + sess.emit_err(errors::IncompatibleFeatures { spans, f1: f1_name, f2: f2_name }); } } } diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs index f58fffc9172..b9dcaee2373 100644 --- a/compiler/rustc_ast_passes/src/lib.rs +++ b/compiler/rustc_ast_passes/src/lib.rs @@ -10,12 +10,16 @@ #![feature(iter_is_partitioned)] #![feature(let_chains)] #![recursion_limit = "256"] +#![deny(rustc::untranslatable_diagnostic)] +#![deny(rustc::diagnostic_outside_of_impl)] -#[macro_use] -extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; pub mod ast_validation; mod errors; pub mod feature_gate; pub mod node_count; pub mod show_span; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_ast_passes/src/show_span.rs b/compiler/rustc_ast_passes/src/show_span.rs index 27637e311f4..280cf3284c3 100644 --- a/compiler/rustc_ast_passes/src/show_span.rs +++ b/compiler/rustc_ast_passes/src/show_span.rs @@ -9,6 +9,8 @@ use rustc_ast as ast; use rustc_ast::visit; use rustc_ast::visit::Visitor; +use crate::errors; + enum Mode { Expression, Pattern, @@ -36,21 +38,21 @@ struct ShowSpanVisitor<'a> { impl<'a> Visitor<'a> for ShowSpanVisitor<'a> { fn visit_expr(&mut self, e: &'a ast::Expr) { if let Mode::Expression = self.mode { - self.span_diagnostic.span_warn(e.span, "expression"); + self.span_diagnostic.emit_warning(errors::ShowSpan { span: e.span, msg: "expression" }); } visit::walk_expr(self, e); } fn visit_pat(&mut self, p: &'a ast::Pat) { if let Mode::Pattern = self.mode { - self.span_diagnostic.span_warn(p.span, "pattern"); + self.span_diagnostic.emit_warning(errors::ShowSpan { span: p.span, msg: "pattern" }); } visit::walk_pat(self, p); } fn visit_ty(&mut self, t: &'a ast::Ty) { if let Mode::Type = self.mode { - self.span_diagnostic.span_warn(t.span, "type"); + self.span_diagnostic.emit_warning(errors::ShowSpan { span: t.span, msg: "type" }); } visit::walk_ty(self, t); } diff --git a/compiler/rustc_ast_pretty/Cargo.toml b/compiler/rustc_ast_pretty/Cargo.toml index d1513c114fe..980a8fa93a9 100644 --- a/compiler/rustc_ast_pretty/Cargo.toml +++ b/compiler/rustc_ast_pretty/Cargo.toml @@ -8,3 +8,4 @@ edition = "2021" [dependencies] rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } +thin-vec = "0.2.12" diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index cd621bc67a1..694d688bf1f 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -4,7 +4,7 @@ mod item; use crate::pp::Breaks::{Consistent, Inconsistent}; use crate::pp::{self, Breaks}; - +use rustc_ast::attr::AttrIdGenerator; use rustc_ast::ptr::P; use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; @@ -20,9 +20,8 @@ use rustc_span::edition::Edition; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Ident, IdentPrinter, Symbol}; use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; - -use rustc_ast::attr::AttrIdGenerator; use std::borrow::Cow; +use thin_vec::ThinVec; pub use self::delimited::IterDelimited; @@ -1722,10 +1721,10 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.print_formal_generic_params(generic_params); let generics = ast::Generics { - params: Vec::new(), + params: ThinVec::new(), where_clause: ast::WhereClause { has_where_token: false, - predicates: Vec::new(), + predicates: ThinVec::new(), span: DUMMY_SP, }, span: DUMMY_SP, diff --git a/compiler/rustc_ast_pretty/src/pprust/tests.rs b/compiler/rustc_ast_pretty/src/pprust/tests.rs index 6c8d42f33eb..3b2b60a86f0 100644 --- a/compiler/rustc_ast_pretty/src/pprust/tests.rs +++ b/compiler/rustc_ast_pretty/src/pprust/tests.rs @@ -3,6 +3,7 @@ use super::*; use rustc_ast as ast; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::Ident; +use thin_vec::ThinVec; fn fun_to_string( decl: &ast::FnDecl, @@ -27,8 +28,10 @@ fn test_fun_to_string() { create_default_session_globals_then(|| { let abba_ident = Ident::from_str("abba"); - let decl = - ast::FnDecl { inputs: Vec::new(), output: ast::FnRetTy::Default(rustc_span::DUMMY_SP) }; + let decl = ast::FnDecl { + inputs: ThinVec::new(), + output: ast::FnRetTy::Default(rustc_span::DUMMY_SP), + }; let generics = ast::Generics::default(); assert_eq!( fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics), diff --git a/compiler/rustc_error_messages/locales/en-US/attr.ftl b/compiler/rustc_attr/locales/en-US.ftl index a7f8c993d42..a7f8c993d42 100644 --- a/compiler/rustc_error_messages/locales/en-US/attr.ftl +++ b/compiler/rustc_attr/locales/en-US.ftl diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs index 4580ffcc6d8..5fede0a58ac 100644 --- a/compiler/rustc_attr/src/lib.rs +++ b/compiler/rustc_attr/src/lib.rs @@ -11,6 +11,9 @@ #[macro_use] extern crate rustc_macros; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + mod builtin; mod session_diagnostics; @@ -22,3 +25,5 @@ pub use StabilityLevel::*; pub use rustc_ast::attr::*; pub(crate) use rustc_ast::HashStableContext; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_attr/src/session_diagnostics.rs b/compiler/rustc_attr/src/session_diagnostics.rs index 3ba7a3c5336..ee79545e304 100644 --- a/compiler/rustc_attr/src/session_diagnostics.rs +++ b/compiler/rustc_attr/src/session_diagnostics.rs @@ -2,11 +2,12 @@ use std::num::IntErrorKind; use rustc_ast as ast; use rustc_errors::{ - error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, + error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, }; use rustc_macros::Diagnostic; use rustc_span::{Span, Symbol}; +use crate::fluent_generated as fluent; use crate::UnsupportedLiteralReason; #[derive(Diagnostic)] @@ -59,7 +60,7 @@ impl<'a> IntoDiagnostic<'a> for UnknownMetaItem<'_> { ); diag.set_arg("item", self.item); diag.set_arg("expected", expected.join(", ")); - diag.span_label(self.span, fluent::label); + diag.span_label(self.span, fluent::attr_label); diag } } @@ -99,31 +100,31 @@ pub(crate) struct InvalidIssueString { // translatable. #[derive(Subdiagnostic)] pub(crate) enum InvalidIssueStringCause { - #[label(must_not_be_zero)] + #[label(attr_must_not_be_zero)] MustNotBeZero { #[primary_span] span: Span, }, - #[label(empty)] + #[label(attr_empty)] Empty { #[primary_span] span: Span, }, - #[label(invalid_digit)] + #[label(attr_invalid_digit)] InvalidDigit { #[primary_span] span: Span, }, - #[label(pos_overflow)] + #[label(attr_pos_overflow)] PosOverflow { #[primary_span] span: Span, }, - #[label(neg_overflow)] + #[label(attr_neg_overflow)] NegOverflow { #[primary_span] span: Span, @@ -275,7 +276,7 @@ pub(crate) struct IncorrectReprFormatGeneric<'a> { #[derive(Subdiagnostic)] pub(crate) enum IncorrectReprFormatGenericCause<'a> { - #[suggestion(suggestion, code = "{name}({int})", applicability = "machine-applicable")] + #[suggestion(attr_suggestion, code = "{name}({int})", applicability = "machine-applicable")] Int { #[primary_span] span: Span, @@ -287,7 +288,7 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> { int: u128, }, - #[suggestion(suggestion, code = "{name}({symbol})", applicability = "machine-applicable")] + #[suggestion(attr_suggestion, code = "{name}({symbol})", applicability = "machine-applicable")] Symbol { #[primary_span] span: Span, diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_borrowck/locales/en-US.ftl index a3b6b5e8138..a3b6b5e8138 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_borrowck/locales/en-US.ftl diff --git a/compiler/rustc_borrowck/src/constraint_generation.rs b/compiler/rustc_borrowck/src/constraint_generation.rs index 11b31c3f140..1427f5cb31d 100644 --- a/compiler/rustc_borrowck/src/constraint_generation.rs +++ b/compiler/rustc_borrowck/src/constraint_generation.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, RegionVid, Ty}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt}; use crate::{ borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, nll::ToRegionVid, @@ -165,7 +165,7 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> { /// `location`. fn add_regular_live_constraint<T>(&mut self, live_ty: T, location: Location) where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { debug!("add_regular_live_constraint(live_ty={:?}, location={:?})", live_ty, location); diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index 1f0b8adeaf1..f370c02161b 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -17,7 +17,7 @@ pub(crate) mod graph; /// constraints of the form `R1: R2`. Each constraint is identified by /// a unique `OutlivesConstraintIndex` and you can index into the set /// (`constraint_set[i]`) to access the constraint details. -#[derive(Clone, Default)] +#[derive(Clone, Debug, Default)] pub(crate) struct OutlivesConstraintSet<'tcx> { outlives: IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>>, } diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index d51cc652bfd..68205fa4558 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -106,7 +106,7 @@ impl<'tcx> ToUniverseInfo<'tcx> } } -impl<'tcx, T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx> ToUniverseInfo<'tcx> +impl<'tcx, T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx> ToUniverseInfo<'tcx> for Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>> { fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> { @@ -258,7 +258,7 @@ struct NormalizeQuery<'tcx, T> { impl<'tcx, T> TypeOpInfo<'tcx> for NormalizeQuery<'tcx, T> where - T: Copy + fmt::Display + TypeFoldable<'tcx> + 'tcx, + T: Copy + fmt::Display + TypeFoldable<TyCtxt<'tcx>> + 'tcx, { fn fallback_error( &self, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index b2d72654a2a..7a1066f6b58 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1494,7 +1494,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { assert!(root_place.projection.is_empty()); let proper_span = self.body.local_decls[root_place.local].source_info.span; - let root_place_projection = self.infcx.tcx.intern_place_elems(root_place.projection); + let root_place_projection = self.infcx.tcx.mk_place_elems(root_place.projection); if self.access_place_error_reported.contains(&( Place { local: root_place.local, projection: root_place_projection }, @@ -2135,7 +2135,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { let tcx = self.infcx.tcx; - let (_, escapes_from) = tcx.article_and_description(self.mir_def_id().to_def_id()); + let escapes_from = tcx.def_descr(self.mir_def_id().to_def_id()); let mut err = borrowck_errors::borrowed_data_escapes_closure(tcx, escape_span, escapes_from); diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index a2fa3018234..4baf1b6aa87 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -660,10 +660,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let (_, escapes_from) = self - .infcx - .tcx - .article_and_description(self.regioncx.universal_regions().defining_ty.def_id()); + let escapes_from = + self.infcx.tcx.def_descr(self.regioncx.universal_regions().defining_ty.def_id()); // Revert to the normal error in these cases. // Assignments aren't "escapes" in function items. @@ -757,8 +755,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { .. } = errci; - let (_, mir_def_name) = - self.infcx.tcx.article_and_description(self.mir_def_id().to_def_id()); + let mir_def_name = self.infcx.tcx.def_descr(self.mir_def_id().to_def_id()); let err = LifetimeOutliveErr { span: *span }; let mut diag = self.infcx.tcx.sess.create_err(err); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 98103af779d..18d7bde60d7 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1,6 +1,7 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. #![allow(rustc::potential_query_instability)] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(let_chains)] #![feature(min_specialization)] @@ -20,12 +21,15 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::vec_map::VecMap; -use rustc_errors::{Diagnostic, DiagnosticBuilder}; +use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; use rustc_index::vec::IndexVec; -use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{ + DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, +}; +use rustc_macros::fluent_messages; use rustc_middle::mir::{ traversal, Body, ClearCrossCrate, Local, Location, Mutability, NonDivergingIntrinsic, Operand, Place, PlaceElem, PlaceRef, VarDebugInfoContents, @@ -43,6 +47,7 @@ use smallvec::SmallVec; use std::cell::OnceCell; use std::cell::RefCell; use std::collections::BTreeMap; +use std::ops::Deref; use std::rc::Rc; use rustc_mir_dataflow::impls::{ @@ -94,6 +99,9 @@ use nll::{PoloniusOutput, ToRegionVid}; use place_ext::PlaceExt; use places_conflict::{places_conflict, PlaceConflictBias}; use region_infer::RegionInferenceContext; +use renumber::RegionCtxt; + +fluent_messages! { "../locales/en-US.ftl" } // FIXME(eddyb) perhaps move this somewhere more centrally. #[derive(Debug)] @@ -167,10 +175,10 @@ fn do_mir_borrowck<'tcx>( return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { let def = input_body.source.with_opt_param().as_local().unwrap(); - debug!(?def); let tcx = infcx.tcx; + let infcx = BorrowckInferCtxt::new(infcx); let param_env = tcx.param_env(def.did); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); @@ -218,7 +226,7 @@ fn do_mir_borrowck<'tcx>( let mut body_owned = input_body.clone(); let mut promoted = input_promoted.clone(); let free_regions = - nll::replace_regions_in_mir(infcx, param_env, &mut body_owned, &mut promoted); + nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes let location_table_owned = LocationTable::new(body); @@ -256,7 +264,7 @@ fn do_mir_borrowck<'tcx>( opt_closure_req, nll_errors, } = nll::compute_regions( - infcx, + &infcx, free_regions, body, &promoted, @@ -271,12 +279,12 @@ fn do_mir_borrowck<'tcx>( // Dump MIR results into a file, if that is enabled. This let us // write unit-tests, as well as helping with debugging. - nll::dump_mir_results(infcx, &body, ®ioncx, &opt_closure_req); + nll::dump_mir_results(&infcx, &body, ®ioncx, &opt_closure_req); // We also have a `#[rustc_regions]` annotation that causes us to dump // information. nll::dump_annotation( - infcx, + &infcx, &body, ®ioncx, &opt_closure_req, @@ -320,7 +328,7 @@ fn do_mir_borrowck<'tcx>( if let Err((move_data, move_errors)) = move_data_results { let mut promoted_mbcx = MirBorrowckCtxt { - infcx, + infcx: &infcx, param_env, body: promoted_body, move_data: &move_data, @@ -349,7 +357,7 @@ fn do_mir_borrowck<'tcx>( } let mut mbcx = MirBorrowckCtxt { - infcx, + infcx: &infcx, param_env, body, move_data: &mdpe.move_data, @@ -481,8 +489,84 @@ pub struct BodyWithBorrowckFacts<'tcx> { pub location_table: LocationTable, } +pub struct BorrowckInferCtxt<'cx, 'tcx> { + pub(crate) infcx: &'cx InferCtxt<'tcx>, + pub(crate) reg_var_to_origin: RefCell<FxHashMap<ty::RegionVid, RegionCtxt>>, +} + +impl<'cx, 'tcx> BorrowckInferCtxt<'cx, 'tcx> { + pub(crate) fn new(infcx: &'cx InferCtxt<'tcx>) -> Self { + BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) } + } + + pub(crate) fn next_region_var<F>( + &self, + origin: RegionVariableOrigin, + get_ctxt_fn: F, + ) -> ty::Region<'tcx> + where + F: Fn() -> RegionCtxt, + { + let next_region = self.infcx.next_region_var(origin); + let vid = next_region + .as_var() + .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + + if cfg!(debug_assertions) { + debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); + let ctxt = get_ctxt_fn(); + let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); + let prev = var_to_origin.insert(vid, ctxt); + + // This only makes sense if not called in a canonicalization context. If this + // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin` + // or modify how we track nll region vars for that map. + assert!(matches!(prev, None)); + } + + next_region + } + + #[instrument(skip(self, get_ctxt_fn), level = "debug")] + pub(crate) fn next_nll_region_var<F>( + &self, + origin: NllRegionVariableOrigin, + get_ctxt_fn: F, + ) -> ty::Region<'tcx> + where + F: Fn() -> RegionCtxt, + { + let next_region = self.infcx.next_nll_region_var(origin.clone()); + let vid = next_region + .as_var() + .unwrap_or_else(|| bug!("expected RegionKind::RegionVar on {:?}", next_region)); + + if cfg!(debug_assertions) { + debug!("inserting vid {:?} with origin {:?} into var_to_origin", vid, origin); + let ctxt = get_ctxt_fn(); + let mut var_to_origin = self.reg_var_to_origin.borrow_mut(); + let prev = var_to_origin.insert(vid, ctxt); + + // This only makes sense if not called in a canonicalization context. If this + // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin` + // or modify how we track nll region vars for that map. + assert!(matches!(prev, None)); + } + + next_region + } +} + +impl<'cx, 'tcx> Deref for BorrowckInferCtxt<'cx, 'tcx> { + type Target = InferCtxt<'tcx>; + + fn deref(&self) -> &'cx Self::Target { + self.infcx + } +} + struct MirBorrowckCtxt<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, + infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, param_env: ParamEnv<'tcx>, body: &'cx Body<'tcx>, move_data: &'cx MoveData<'tcx>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index c71413e8e7c..e5dbb83dd07 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -5,7 +5,6 @@ use rustc_data_structures::vec_map::VecMap; use rustc_hir::def_id::LocalDefId; use rustc_index::vec::IndexVec; -use rustc_infer::infer::InferCtxt; use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere}; use rustc_middle::mir::{ BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, @@ -37,7 +36,7 @@ use crate::{ renumber, type_check::{self, MirTypeckRegionConstraints, MirTypeckResults}, universal_regions::UniversalRegions, - Upvar, + BorrowckInferCtxt, Upvar, }; pub type PoloniusOutput = Output<RustcFacts>; @@ -58,7 +57,7 @@ pub(crate) struct NllOutput<'tcx> { /// `compute_regions`. #[instrument(skip(infcx, param_env, body, promoted), level = "debug")] pub(crate) fn replace_regions_in_mir<'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexVec<Promoted, Body<'tcx>>, @@ -157,7 +156,7 @@ fn populate_polonius_move_facts( /// /// This may result in errors being reported. pub(crate) fn compute_regions<'cx, 'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, universal_regions: UniversalRegions<'tcx>, body: &Body<'tcx>, promoted: &IndexVec<Promoted, Body<'tcx>>, @@ -259,6 +258,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( ); let mut regioncx = RegionInferenceContext::new( + infcx, var_origins, universal_regions, placeholder_indices, @@ -322,7 +322,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( } pub(super) fn dump_mir_results<'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option<ClosureRegionRequirements<'_>>, @@ -372,7 +372,7 @@ pub(super) fn dump_mir_results<'tcx>( #[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::untranslatable_diagnostic)] pub(super) fn dump_annotation<'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, body: &Body<'tcx>, regioncx: &RegionInferenceContext<'tcx>, closure_region_requirements: &Option<ClosureRegionRequirements<'_>>, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 83fdb6066c6..941da2dd3b5 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::ObligationCause; use rustc_middle::traits::ObligationCauseCode; -use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_span::Span; use crate::{ @@ -34,6 +34,7 @@ use crate::{ }, type_check::{free_region_relations::UniversalRegionRelations, Locations}, universal_regions::UniversalRegions, + BorrowckInferCtxt, }; mod dump_mir; @@ -243,6 +244,70 @@ pub enum ExtraConstraintInfo { PlaceholderFromPredicate(Span), } +#[instrument(skip(infcx, sccs), level = "debug")] +fn sccs_info<'cx, 'tcx>( + infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, + sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>, +) { + use crate::renumber::RegionCtxt; + + let var_to_origin = infcx.reg_var_to_origin.borrow(); + + let mut var_to_origin_sorted = var_to_origin.clone().into_iter().collect::<Vec<_>>(); + var_to_origin_sorted.sort_by(|a, b| a.0.cmp(&b.0)); + let mut debug_str = "region variables to origins:\n".to_string(); + for (reg_var, origin) in var_to_origin_sorted.into_iter() { + debug_str.push_str(&format!("{:?}: {:?}\n", reg_var, origin)); + } + debug!(debug_str); + + let num_components = sccs.scc_data().ranges().len(); + let mut components = vec![FxHashSet::default(); num_components]; + + for (reg_var_idx, scc_idx) in sccs.scc_indices().iter().enumerate() { + let reg_var = ty::RegionVid::from_usize(reg_var_idx); + let origin = var_to_origin.get(®_var).unwrap_or_else(|| &RegionCtxt::Unknown); + components[scc_idx.as_usize()].insert((reg_var, *origin)); + } + + let mut components_str = "strongly connected components:".to_string(); + for (scc_idx, reg_vars_origins) in components.iter().enumerate() { + let regions_info = reg_vars_origins.clone().into_iter().collect::<Vec<_>>(); + components_str.push_str(&format!( + "{:?}: {:?})", + ConstraintSccIndex::from_usize(scc_idx), + regions_info, + )) + } + debug!(components_str); + + // calculate the best representative for each component + let components_representatives = components + .into_iter() + .enumerate() + .map(|(scc_idx, region_ctxts)| { + let repr = region_ctxts + .into_iter() + .map(|reg_var_origin| reg_var_origin.1) + .max_by(|x, y| x.preference_value().cmp(&y.preference_value())) + .unwrap(); + + (ConstraintSccIndex::from_usize(scc_idx), repr) + }) + .collect::<FxHashMap<_, _>>(); + + let mut scc_node_to_edges = FxHashMap::default(); + for (scc_idx, repr) in components_representatives.iter() { + let edges_range = sccs.scc_data().ranges()[*scc_idx].clone(); + let edges = &sccs.scc_data().all_successors()[edges_range]; + let edge_representatives = + edges.iter().map(|scc_idx| components_representatives[scc_idx]).collect::<Vec<_>>(); + scc_node_to_edges.insert((scc_idx, repr), edge_representatives); + } + + debug!("SCC edges {:#?}", scc_node_to_edges); +} + impl<'tcx> RegionInferenceContext<'tcx> { /// Creates a new region inference context with a total of /// `num_region_variables` valid inference variables; the first N @@ -251,7 +316,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// The `outlives_constraints` and `type_tests` are an initial set /// of constraints produced by the MIR type check. - pub(crate) fn new( + pub(crate) fn new<'cx>( + _infcx: &BorrowckInferCtxt<'cx, 'tcx>, var_infos: VarInfos, universal_regions: Rc<UniversalRegions<'tcx>>, placeholder_indices: Rc<PlaceholderIndices>, @@ -263,6 +329,11 @@ impl<'tcx> RegionInferenceContext<'tcx> { liveness_constraints: LivenessValues<RegionVid>, elements: &Rc<RegionValueElements>, ) -> Self { + debug!("universal_regions: {:#?}", universal_regions); + debug!("outlives constraints: {:#?}", outlives_constraints); + debug!("placeholder_indices: {:#?}", placeholder_indices); + debug!("type tests: {:#?}", type_tests); + // Create a RegionDefinition for each inference variable. let definitions: IndexVec<_, _> = var_infos .iter() @@ -274,6 +345,10 @@ impl<'tcx> RegionInferenceContext<'tcx> { let fr_static = universal_regions.fr_static; let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static)); + if cfg!(debug_assertions) { + sccs_info(_infcx, constraint_sccs.clone()); + } + let mut scc_values = RegionValues::new(elements, universal_regions.len(), &placeholder_indices); @@ -1291,7 +1366,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// we use this kind of hacky solution. fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { tcx.fold_regions(value, |r, _db| { let vid = self.to_region_vid(r); diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index bb42301828d..c550e37c63e 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,12 +1,13 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::vec_map::VecMap; +use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; use rustc_infer::infer::TyCtxtInferExt as _; use rustc_infer::infer::{DefiningAnchor, InferCtxt}; use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; @@ -149,13 +150,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { // once we convert the generic parameters to those of the opaque type. if let Some(prev) = result.get_mut(&opaque_type_key.def_id) { if prev.ty != ty { - if !ty.references_error() { + let guar = ty.error_reported().err().unwrap_or_else(|| { prev.report_mismatch( &OpaqueHiddenType { ty, span: concrete_type.span }, infcx.tcx, - ); - } - prev.ty = infcx.tcx.ty_error(); + ) + }); + prev.ty = infcx.tcx.ty_error(guar); } // Pick a better span if there is one. // FIXME(oli-obk): collect multiple spans for better diagnostics down the road. @@ -178,7 +179,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// region names in error messages. pub(crate) fn name_regions<T>(&self, tcx: TyCtxt<'tcx>, ty: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { tcx.fold_regions(ty, |region, _| match *region { ty::ReVar(vid) => { @@ -247,20 +248,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { origin: OpaqueTyOrigin, ) -> Ty<'tcx> { if let Some(e) = self.tainted_by_errors() { - return self.tcx.ty_error_with_guaranteed(e); + return self.tcx.ty_error(e); } let definition_ty = instantiated_ty .remap_generic_params_to_declaration_params(opaque_type_key, self.tcx, false) .ty; - if !check_opaque_type_parameter_valid( + if let Err(guar) = check_opaque_type_parameter_valid( self.tcx, opaque_type_key, origin, instantiated_ty.span, ) { - return self.tcx.ty_error(); + return self.tcx.ty_error(guar); } // Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs` @@ -273,7 +274,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely. let param_env = self.tcx.param_env(def_id); // HACK This bubble is required for this tests to pass: - // type-alias-impl-trait/issue-67844-nested-opaque.rs + // nested-return-type2-tait2.rs + // nested-return-type2-tait3.rs let infcx = self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).build(); let ocx = ObligationCtxt::new(&infcx); @@ -324,7 +326,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { definition_ty } else { let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } } } @@ -334,7 +336,7 @@ fn check_opaque_type_parameter_valid( opaque_type_key: OpaqueTypeKey<'_>, origin: OpaqueTyOrigin, span: Span, -) -> bool { +) -> Result<(), ErrorGuaranteed> { match origin { // No need to check return position impl trait (RPIT) // because for type and const parameters they are correct @@ -357,7 +359,7 @@ fn check_opaque_type_parameter_valid( // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>. // // which would error here on all of the `'static` args. - OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return true, + OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()), // Check these OpaqueTyOrigin::TyAlias => {} } @@ -378,13 +380,13 @@ fn check_opaque_type_parameter_valid( // Prevent `fn foo() -> Foo<u32>` from being defining. let opaque_param = opaque_generics.param_at(i, tcx); let kind = opaque_param.kind.descr(); - tcx.sess.emit_err(NonGenericOpaqueTypeParam { + + return Err(tcx.sess.emit_err(NonGenericOpaqueTypeParam { ty: arg, kind, span, param_span: tcx.def_span(opaque_param.def_id), - }); - return false; + })); } } @@ -395,12 +397,13 @@ fn check_opaque_type_parameter_valid( .into_iter() .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id)) .collect(); - tcx.sess + return Err(tcx + .sess .struct_span_err(span, "non-defining opaque type use in defining scope") .span_note(spans, &format!("{} used multiple times", descr)) - .emit(); - return false; + .emit()); } } - true + + Ok(()) } diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 6a3748fded5..c361357ca21 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -181,7 +181,7 @@ impl<N: Idx> LivenessValues<N> { /// Maps from `ty::PlaceholderRegion` values that are used in the rest of /// rustc to the internal `PlaceholderIndex` values that are used in /// NLL. -#[derive(Default)] +#[derive(Debug, Default)] pub(crate) struct PlaceholderIndices { indices: FxIndexSet<ty::PlaceholderRegion>, } diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 084754830bd..016f6f78dfa 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,18 +1,20 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +use crate::BorrowckInferCtxt; use rustc_index::vec::IndexVec; -use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; +use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::Constant; use rustc_middle::mir::{Body, Location, Promoted}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc_span::{Span, Symbol}; /// Replaces all free regions appearing in the MIR with fresh /// inference variables, returning the number of variables created. #[instrument(skip(infcx, body, promoted), level = "debug")] pub fn renumber_mir<'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexVec<Promoted, Body<'tcx>>, ) { @@ -29,27 +31,68 @@ pub fn renumber_mir<'tcx>( /// Replaces all regions appearing in `value` with fresh inference /// variables. -#[instrument(skip(infcx), level = "debug")] -pub fn renumber_regions<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> T +#[instrument(skip(infcx, get_ctxt_fn), level = "debug")] +pub(crate) fn renumber_regions<'tcx, T, F>( + infcx: &BorrowckInferCtxt<'_, 'tcx>, + value: T, + get_ctxt_fn: F, +) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, + F: Fn() -> RegionCtxt, { infcx.tcx.fold_regions(value, |_region, _depth| { let origin = NllRegionVariableOrigin::Existential { from_forall: false }; - infcx.next_nll_region_var(origin) + infcx.next_nll_region_var(origin, || get_ctxt_fn()) }) } +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub(crate) enum BoundRegionInfo { + Name(Symbol), + Span(Span), +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] +pub(crate) enum RegionCtxt { + Location(Location), + TyContext(TyContext), + Free(Symbol), + Bound(BoundRegionInfo), + LateBound(BoundRegionInfo), + Existential(Option<Symbol>), + Placeholder(BoundRegionInfo), + Unknown, +} + +impl RegionCtxt { + /// Used to determine the representative of a component in the strongly connected + /// constraint graph + pub(crate) fn preference_value(self) -> usize { + let _anon = Symbol::intern("anon"); + + match self { + RegionCtxt::Unknown => 1, + RegionCtxt::Existential(None) => 2, + RegionCtxt::Existential(Some(_anon)) | RegionCtxt::Free(_anon) => 2, + RegionCtxt::Location(_) => 3, + RegionCtxt::TyContext(_) => 4, + _ => 5, + } + } +} + struct NllVisitor<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, + infcx: &'a BorrowckInferCtxt<'a, 'tcx>, } impl<'a, 'tcx> NllVisitor<'a, 'tcx> { - fn renumber_regions<T>(&mut self, value: T) -> T + fn renumber_regions<T, F>(&mut self, value: T, region_ctxt_fn: F) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, + F: Fn() -> RegionCtxt, { - renumber_regions(self.infcx, value) + renumber_regions(self.infcx, value, region_ctxt_fn) } } @@ -60,14 +103,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) { - *ty = self.renumber_regions(*ty); + *ty = self.renumber_regions(*ty, || RegionCtxt::TyContext(ty_context)); debug!(?ty); } #[instrument(skip(self), level = "debug")] fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) { - *substs = self.renumber_regions(*substs); + *substs = self.renumber_regions(*substs, || RegionCtxt::Location(location)); debug!(?substs); } @@ -75,7 +118,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) { let old_region = *region; - *region = self.renumber_regions(old_region); + *region = self.renumber_regions(old_region, || RegionCtxt::Location(location)); debug!(?region); } @@ -83,7 +126,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NllVisitor<'a, 'tcx> { #[instrument(skip(self), level = "debug")] fn visit_constant(&mut self, constant: &mut Constant<'tcx>, _location: Location) { let literal = constant.literal; - constant.literal = self.renumber_regions(literal); + constant.literal = self.renumber_regions(literal, || RegionCtxt::Location(_location)); debug!("constant: {:#?}", constant); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index 13199d03852..a3678929099 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -55,7 +55,7 @@ pub(crate) struct VarNeedNotMut { #[derive(Diagnostic)] #[diag(borrowck_var_cannot_escape_closure)] #[note] -#[note(cannot_escape)] +#[note(borrowck_cannot_escape)] pub(crate) struct FnMutError { #[primary_span] pub span: Span, @@ -223,7 +223,7 @@ pub(crate) struct MoveBorrow<'a> { pub borrow_place: &'a str, pub value_place: &'a str, #[primary_span] - #[label(move_label)] + #[label(borrowck_move_label)] pub span: Span, #[label] pub borrow_span: Span, diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index 2b81a35052d..b27d5d20532 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -2,7 +2,7 @@ use std::fmt; use rustc_infer::infer::{canonical::Canonical, InferOk}; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeFoldable}; +use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; @@ -66,7 +66,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { canonical: &Canonical<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let old_universe = self.infcx.universe(); @@ -117,7 +117,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn prove_predicates( &mut self, - predicates: impl IntoIterator<Item = impl ToPredicate<'tcx> + std::fmt::Debug>, + predicates: impl IntoIterator<Item: ToPredicate<'tcx> + std::fmt::Debug>, locations: Locations, category: ConstraintCategory<'tcx>, ) { diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 1dc6c42fbf7..504633c6a5c 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -6,8 +6,8 @@ use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound}; use rustc_infer::infer::{self, InferCtxt, SubregionOrigin}; use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory}; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{TypeFoldable, TypeVisitableExt}; use rustc_span::{Span, DUMMY_SP}; use crate::{ @@ -171,7 +171,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { /// /// FIXME: This should get removed once higher ranked region obligations /// are dealt with during trait solving. - fn replace_placeholders_with_nll<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T { + fn replace_placeholders_with_nll<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T { if value.has_placeholders() { self.tcx.fold_regions(value, |r, _| match *r { ty::RePlaceholder(placeholder) => { diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 2dd24fe0340..e2f897a89e8 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -270,12 +270,13 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) .unwrap_or_else(|_| { - self.infcx + let guar = self + .infcx .tcx .sess .delay_span_bug(span, &format!("failed to normalize {:?}", ty)); TypeOpOutput { - output: self.infcx.tcx.ty_error(), + output: self.infcx.tcx.ty_error(guar), constraints: None, error_info: None, } diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 3ff5d188a3d..473c0596300 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -3,7 +3,7 @@ use rustc_index::bit_set::HybridBitSet; use rustc_index::interval::IntervalSet; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_middle::mir::{BasicBlock, Body, ConstraintCategory, Local, Location}; -use rustc_middle::ty::{Ty, TypeVisitable}; +use rustc_middle::ty::{Ty, TyCtxt, TypeVisitable, TypeVisitableExt}; use rustc_trait_selection::traits::query::dropck_outlives::DropckOutlivesResult; use rustc_trait_selection::traits::query::type_op::outlives::DropckOutlives; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -477,7 +477,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { /// points `live_at`. fn add_use_live_facts_for( &mut self, - value: impl TypeVisitable<'tcx>, + value: impl TypeVisitable<TyCtxt<'tcx>>, live_at: &IntervalSet<PointIndex>, ) { debug!("add_use_live_facts_for(value={:?})", value); @@ -542,7 +542,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { fn make_all_regions_live( elements: &RegionValueElements, typeck: &mut TypeChecker<'_, 'tcx>, - value: impl TypeVisitable<'tcx>, + value: impl TypeVisitable<TyCtxt<'tcx>>, live_at: &IntervalSet<PointIndex>, ) { debug!("make_all_regions_live(value={:?})", value); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 5e1334559f5..a49da3da6c0 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -30,7 +30,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, @@ -64,7 +64,7 @@ use crate::{ region_infer::TypeTest, type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, universal_regions::{DefiningTy, UniversalRegions}, - Upvar, + BorrowckInferCtxt, Upvar, }; macro_rules! span_mirbug { @@ -123,7 +123,7 @@ mod relate_tys; /// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis /// - `elements` -- MIR region map pub(crate) fn type_check<'mir, 'tcx>( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, promoted: &IndexVec<Promoted, Body<'tcx>>, @@ -239,7 +239,7 @@ pub(crate) fn type_check<'mir, 'tcx>( decl.hidden_type.span, &format!("could not resolve {:#?}", hidden_type.ty.kind()), ); - hidden_type.ty = infcx.tcx.ty_error_with_guaranteed(reported); + hidden_type.ty = infcx.tcx.ty_error(reported); } (opaque_type_key, (hidden_type, decl.origin)) @@ -529,9 +529,9 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { for elem in place.projection.iter() { if place_ty.variant_index.is_none() { - if place_ty.ty.references_error() { + if let Err(guar) = place_ty.ty.error_reported() { assert!(self.errors_reported); - return PlaceTy::from_ty(self.tcx().ty_error()); + return PlaceTy::from_ty(self.tcx().ty_error(guar)); } } place_ty = self.sanitize_projection(place_ty, elem, place, location, context); @@ -763,7 +763,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn error(&mut self) -> Ty<'tcx> { self.errors_reported = true; - self.tcx().ty_error() + self.tcx().ty_error_misc() } fn get_ambient_variance(&self, context: PlaceContext) -> ty::Variance { @@ -866,7 +866,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { /// way, it accrues region constraints -- these can later be used by /// NLL region checking. struct TypeChecker<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, + infcx: &'a BorrowckInferCtxt<'a, 'tcx>, param_env: ty::ParamEnv<'tcx>, last_span: Span, body: &'a Body<'tcx>, @@ -1019,7 +1019,7 @@ impl Locations { impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn new( - infcx: &'a InferCtxt<'tcx>, + infcx: &'a BorrowckInferCtxt<'a, 'tcx>, body: &'a Body<'tcx>, param_env: ty::ParamEnv<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, @@ -1356,11 +1356,34 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } }; let (sig, map) = tcx.replace_late_bound_regions(sig, |br| { - self.infcx.next_region_var(LateBoundRegion( - term.source_info.span, - br.kind, - LateBoundRegionConversionTime::FnCall, - )) + use crate::renumber::{BoundRegionInfo, RegionCtxt}; + use rustc_span::Symbol; + + let region_ctxt_fn = || { + let reg_info = match br.kind { + ty::BoundRegionKind::BrAnon(_, Some(span)) => { + BoundRegionInfo::Span(span) + } + ty::BoundRegionKind::BrAnon(..) => { + BoundRegionInfo::Name(Symbol::intern("anon")) + } + ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name), + ty::BoundRegionKind::BrEnv => { + BoundRegionInfo::Name(Symbol::intern("env")) + } + }; + + RegionCtxt::LateBound(reg_info) + }; + + self.infcx.next_region_var( + LateBoundRegion( + term.source_info.span, + br.kind, + LateBoundRegionConversionTime::FnCall, + ), + region_ctxt_fn, + ) }); debug!(?sig); // IMPORTANT: We have to prove well formed for the function signature before @@ -2610,7 +2633,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { DefKind::InlineConst => substs.as_inline_const().parent_substs(), other => bug!("unexpected item {:?}", other), }; - let parent_substs = tcx.intern_substs(parent_substs); + let parent_substs = tcx.mk_substs(parent_substs); assert_eq!(typeck_root_substs.len(), parent_substs.len()); if let Err(_) = self.eq_substs( diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 8dd06187877..d96372fb99b 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -4,11 +4,12 @@ use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Ty}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use rustc_trait_selection::traits::query::Fallible; use crate::constraints::OutlivesConstraint; use crate::diagnostics::UniverseInfo; +use crate::renumber::{BoundRegionInfo, RegionCtxt}; use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker}; impl<'a, 'tcx> TypeChecker<'a, 'tcx> { @@ -100,23 +101,65 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> universe } - fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> { + #[instrument(skip(self), level = "debug")] + fn next_existential_region_var( + &mut self, + from_forall: bool, + _name: Option<Symbol>, + ) -> ty::Region<'tcx> { let origin = NllRegionVariableOrigin::Existential { from_forall }; - self.type_checker.infcx.next_nll_region_var(origin) + + let reg_var = + self.type_checker.infcx.next_nll_region_var(origin, || RegionCtxt::Existential(_name)); + + reg_var } + #[instrument(skip(self), level = "debug")] fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { - self.type_checker + let reg = self + .type_checker .borrowck_context .constraints - .placeholder_region(self.type_checker.infcx, placeholder) + .placeholder_region(self.type_checker.infcx, placeholder); + + let reg_info = match placeholder.name { + ty::BoundRegionKind::BrAnon(_, Some(span)) => BoundRegionInfo::Span(span), + ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(Symbol::intern("anon")), + ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name), + ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(Symbol::intern("env")), + }; + + let reg_var = + reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg)); + let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); + let prev = var_to_origin.insert(reg_var, RegionCtxt::Placeholder(reg_info)); + assert!(matches!(prev, None)); + + reg } + #[instrument(skip(self), level = "debug")] fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { - self.type_checker.infcx.next_nll_region_var_in_universe( + let reg = self.type_checker.infcx.next_nll_region_var_in_universe( NllRegionVariableOrigin::Existential { from_forall: false }, universe, - ) + ); + + let reg_var = + reg.as_var().unwrap_or_else(|| bug!("expected region {:?} to be of kind ReVar", reg)); + + if cfg!(debug_assertions) { + let mut var_to_origin = self.type_checker.infcx.reg_var_to_origin.borrow_mut(); + let prev = var_to_origin.insert(reg_var, RegionCtxt::Existential(None)); + + // It only makes sense to track region vars in non-canonicalization contexts. If this + // ever changes we either want to get rid of `BorrowckInferContext::reg_var_to_origin` + // or modify how we track nll region vars for that map. + assert!(matches!(prev, None)); + } + + reg } fn push_outlives( diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index efa5a29c5dd..e058fe0db22 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -20,15 +20,18 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::lang_items::LangItem; use rustc_hir::{BodyOwnerKind, HirId}; use rustc_index::vec::{Idx, IndexVec}; -use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin}; +use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::{ self, DefIdTree, InlineConstSubsts, InlineConstSubstsParts, RegionVid, Ty, TyCtxt, }; use rustc_middle::ty::{InternalSubsts, SubstsRef}; +use rustc_span::Symbol; use std::iter; use crate::nll::ToRegionVid; +use crate::renumber::{BoundRegionInfo, RegionCtxt}; +use crate::BorrowckInferCtxt; #[derive(Debug)] pub struct UniversalRegions<'tcx> { @@ -224,7 +227,7 @@ impl<'tcx> UniversalRegions<'tcx> { /// signature. This will also compute the relationships that are /// known between those regions. pub fn new( - infcx: &InferCtxt<'tcx>, + infcx: &BorrowckInferCtxt<'_, 'tcx>, mir_def: ty::WithOptConstParam<LocalDefId>, param_env: ty::ParamEnv<'tcx>, ) -> Self { @@ -385,7 +388,7 @@ impl<'tcx> UniversalRegions<'tcx> { } struct UniversalRegionsBuilder<'cx, 'tcx> { - infcx: &'cx InferCtxt<'tcx>, + infcx: &'cx BorrowckInferCtxt<'cx, 'tcx>, mir_def: ty::WithOptConstParam<LocalDefId>, mir_hir_id: HirId, param_env: ty::ParamEnv<'tcx>, @@ -403,7 +406,10 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); // Create the "global" region that is always free in all contexts: 'static. - let fr_static = self.infcx.next_nll_region_var(FR).to_region_vid(); + let fr_static = self + .infcx + .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("static"))) + .to_region_vid(); // We've now added all the global regions. The next ones we // add will be external. @@ -435,7 +441,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { |r| { debug!(?r); if !indices.indices.contains_key(&r) { - let region_vid = self.infcx.next_nll_region_var(FR); + let region_vid = { + let name = match r.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + + self.infcx.next_nll_region_var(FR, || { + RegionCtxt::LateBound(BoundRegionInfo::Name(name)) + }) + }; + debug!(?region_vid); indices.insert_late_bound_region(r, region_vid.to_region_vid()); } @@ -463,7 +479,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def.did, |r| { debug!(?r); if !indices.indices.contains_key(&r) { - let region_vid = self.infcx.next_nll_region_var(FR); + let region_vid = { + let name = match r.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + + self.infcx.next_nll_region_var(FR, || { + RegionCtxt::LateBound(BoundRegionInfo::Name(name)) + }) + }; + debug!(?region_vid); indices.insert_late_bound_region(r, region_vid.to_region_vid()); } @@ -480,18 +506,27 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { LangItem::VaList, Some(self.infcx.tcx.def_span(self.mir_def.did)), ); - let region = - self.infcx.tcx.mk_re_var(self.infcx.next_nll_region_var(FR).to_region_vid()); + + let reg_vid = self + .infcx + .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("c-variadic"))) + .to_region_vid(); + + let region = self.infcx.tcx.mk_re_var(reg_vid); let va_list_ty = self.infcx.tcx.type_of(va_list_did).subst(self.infcx.tcx, &[region.into()]); - unnormalized_input_tys = self.infcx.tcx.mk_type_list( + unnormalized_input_tys = self.infcx.tcx.mk_type_list_from_iter( unnormalized_input_tys.iter().copied().chain(iter::once(va_list_ty)), ); } } - let fr_fn_body = self.infcx.next_nll_region_var(FR).to_region_vid(); + let fr_fn_body = self + .infcx + .next_nll_region_var(FR, || RegionCtxt::Free(Symbol::intern("fn_body"))) + .to_region_vid(); + let num_universals = self.infcx.num_region_vars(); debug!("build: global regions = {}..{}", FIRST_GLOBAL_INDEX, first_extern_index); @@ -621,7 +656,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(self.mir_def.did.to_def_id(), def_id); let closure_sig = substs.as_closure().sig(); let inputs_and_output = closure_sig.inputs_and_output(); - let bound_vars = tcx.mk_bound_variable_kinds( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( inputs_and_output .bound_vars() .iter() @@ -645,7 +680,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { }; ty::Binder::bind_with_vars( - tcx.mk_type_list( + tcx.mk_type_list_from_iter( iter::once(closure_ty).chain(inputs).chain(iter::once(output)), ), bound_vars, @@ -658,7 +693,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let output = substs.as_generator().return_ty(); let generator_ty = tcx.mk_generator(def_id, substs, movability); let inputs_and_output = - self.infcx.tcx.intern_type_list(&[generator_ty, resume_ty, output]); + self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]); ty::Binder::dummy(inputs_and_output) } @@ -674,13 +709,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { assert_eq!(self.mir_def.did.to_def_id(), def_id); let ty = tcx.type_of(self.mir_def.def_id_for_type_of()).subst_identity(); let ty = indices.fold_to_region_vids(tcx, ty); - ty::Binder::dummy(tcx.intern_type_list(&[ty])) + ty::Binder::dummy(tcx.mk_type_list(&[ty])) } DefiningTy::InlineConst(def_id, substs) => { assert_eq!(self.mir_def.did.to_def_id(), def_id); let ty = substs.as_inline_const().ty(); - ty::Binder::dummy(tcx.intern_type_list(&[ty])) + ty::Binder::dummy(tcx.mk_type_list(&[ty])) } } } @@ -693,7 +728,7 @@ trait InferCtxtExt<'tcx> { value: T, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable<TyCtxt<'tcx>>; fn replace_bound_regions_with_nll_infer_vars<T>( &self, @@ -703,7 +738,7 @@ trait InferCtxtExt<'tcx> { indices: &mut UniversalRegionIndices<'tcx>, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable<TyCtxt<'tcx>>; fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope( &self, @@ -718,16 +753,27 @@ trait InferCtxtExt<'tcx> { ); } -impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { +impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> { + #[instrument(skip(self), level = "debug")] fn replace_free_regions_with_nll_infer_vars<T>( &self, origin: NllRegionVariableOrigin, value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { - self.tcx.fold_regions(value, |_region, _depth| self.next_nll_region_var(origin)) + self.infcx.tcx.fold_regions(value, |region, _depth| { + let name = match region.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + debug!(?region, ?name); + + let reg_var = self.next_nll_region_var(origin, || RegionCtxt::Free(name)); + + reg_var + }) } #[instrument(level = "debug", skip(self, indices))] @@ -739,12 +785,20 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { indices: &mut UniversalRegionIndices<'tcx>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let (value, _map) = self.tcx.replace_late_bound_regions(value, |br| { debug!(?br); let liberated_region = self.tcx.mk_re_free(all_outlive_scope.to_def_id(), br.kind); - let region_vid = self.next_nll_region_var(origin); + let region_vid = { + let name = match br.kind.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + + self.next_nll_region_var(origin, || RegionCtxt::Bound(BoundRegionInfo::Name(name))) + }; + indices.insert_late_bound_region(liberated_region, region_vid.to_region_vid()); debug!(?liberated_region, ?region_vid); region_vid @@ -770,7 +824,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { for_each_late_bound_region_in_recursive_scope(self.tcx, mir_def_id, |r| { debug!(?r); if !indices.indices.contains_key(&r) { - let region_vid = self.next_nll_region_var(FR); + let region_vid = { + let name = match r.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + + self.next_nll_region_var(FR, || { + RegionCtxt::LateBound(BoundRegionInfo::Name(name)) + }) + }; + debug!(?region_vid); indices.insert_late_bound_region(r, region_vid.to_region_vid()); } @@ -786,8 +850,17 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { for_each_late_bound_region_in_item(self.tcx, mir_def_id, |r| { debug!(?r); if !indices.indices.contains_key(&r) { - let region_vid = self.next_nll_region_var(FR); - debug!(?region_vid); + let region_vid = { + let name = match r.get_name() { + Some(name) => name, + _ => Symbol::intern("anon"), + }; + + self.next_nll_region_var(FR, || { + RegionCtxt::LateBound(BoundRegionInfo::Name(name)) + }) + }; + indices.insert_late_bound_region(r, region_vid.to_region_vid()); } }); @@ -833,7 +906,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> { /// returned by `to_region_vid`. pub fn fold_to_region_vids<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { tcx.fold_regions(value, |region, _| tcx.mk_re_var(self.to_region_vid(region))) } diff --git a/compiler/rustc_builtin_macros/Cargo.toml b/compiler/rustc_builtin_macros/Cargo.toml index 467fa932a15..336e14ef966 100644 --- a/compiler/rustc_builtin_macros/Cargo.toml +++ b/compiler/rustc_builtin_macros/Cargo.toml @@ -23,5 +23,5 @@ rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_builtin_macros/locales/en-US.ftl index 4d088e27b36..4d088e27b36 100644 --- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl +++ b/compiler/rustc_builtin_macros/locales/en-US.ftl diff --git a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs index dcf500ddbd3..ac6697232cb 100644 --- a/compiler/rustc_builtin_macros/src/alloc_error_handler.rs +++ b/compiler/rustc_builtin_macros/src/alloc_error_handler.rs @@ -6,7 +6,7 @@ use rustc_ast::{Fn, ItemKind, Stmt, TyKind, Unsafe}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -39,10 +39,10 @@ pub fn expand( let span = ecx.with_def_site_ctxt(item.span); // Generate item statements for the allocator methods. - let stmts = vec![generate_handler(ecx, item.ident, span, sig_span)]; + let stmts = thin_vec![generate_handler(ecx, item.ident, span, sig_span)]; // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(sig_span, TyKind::Tup(Vec::new())); + let const_ty = ecx.ty(sig_span, TyKind::Tup(ThinVec::new())); let const_body = ecx.expr_block(ecx.block(span, stmts)); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { @@ -67,13 +67,16 @@ fn generate_handler(cx: &ExtCtxt<'_>, handler: Ident, span: Span, sig_span: Span let layout_new = cx.std_path(&[sym::alloc, sym::Layout, sym::from_size_align_unchecked]); let layout_new = cx.expr_path(cx.path(span, layout_new)); - let layout = - cx.expr_call(span, layout_new, vec![cx.expr_ident(span, size), cx.expr_ident(span, align)]); + let layout = cx.expr_call( + span, + layout_new, + thin_vec![cx.expr_ident(span, size), cx.expr_ident(span, align)], + ); - let call = cx.expr_call_ident(sig_span, handler, vec![layout]); + let call = cx.expr_call_ident(sig_span, handler, thin_vec![layout]); let never = ast::FnRetTy::Ty(cx.ty(span, TyKind::Never)); - let params = vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)]; + let params = thin_vec![cx.param(span, size, ty_usize.clone()), cx.param(span, align, ty_usize)]; let decl = cx.fn_decl(params, never); let header = FnHeader { unsafety: Unsafe::Yes(span), ..FnHeader::default() }; let sig = FnSig { decl, header, span: span }; diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 925392b500a..3fdbc971527 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -152,7 +152,7 @@ pub fn parse_asm_args<'a>( ast::InlineAsmOperand::InOut { reg, expr, late: true } } } else if p.eat_keyword(kw::Const) { - let anon_const = p.parse_anon_const_expr()?; + let anon_const = p.parse_expr_anon_const()?; ast::InlineAsmOperand::Const { anon_const } } else if p.eat_keyword(sym::sym) { let expr = p.parse_expr()?; diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 8555c3593b3..75af5e2b1fa 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -11,6 +11,7 @@ use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult}; use rustc_parse::parser::Parser; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use thin_vec::thin_vec; pub fn expand_assert<'cx>( cx: &'cx mut ExtCtxt<'_>, @@ -79,7 +80,7 @@ pub fn expand_assert<'cx>( let then = cx.expr_call_global( call_site_span, cx.std_path(&[sym::panicking, sym::panic]), - vec![cx.expr_str( + thin_vec![cx.expr_str( DUMMY_SP, Symbol::intern(&format!( "assertion failed: {}", diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index 342b1735661..b0b4dda16af 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -12,7 +12,7 @@ use rustc_span::{ symbol::{sym, Ident, Symbol}, Span, }; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub(super) struct Context<'cx, 'a> { // An optimization. @@ -83,12 +83,12 @@ impl<'cx, 'a> Context<'cx, 'a> { let Self { best_case_captures, capture_decls, cx, local_bind_decls, span, .. } = self; - let mut assert_then_stmts = Vec::with_capacity(2); + let mut assert_then_stmts = ThinVec::with_capacity(2); assert_then_stmts.extend(best_case_captures); assert_then_stmts.push(self.cx.stmt_expr(panic)); let assert_then = self.cx.block(span, assert_then_stmts); - let mut stmts = Vec::with_capacity(4); + let mut stmts = ThinVec::with_capacity(4); stmts.push(initial_imports); stmts.extend(capture_decls.into_iter().map(|c| c.decl)); stmts.extend(local_bind_decls); @@ -120,7 +120,7 @@ impl<'cx, 'a> Context<'cx, 'a> { thin_vec![self.cx.attr_nested_word(sym::allow, sym::unused_imports, self.span)], ItemKind::Use(UseTree { prefix: self.cx.path(self.span, self.cx.std_path(&[sym::asserting])), - kind: UseTreeKind::Nested(vec![ + kind: UseTreeKind::Nested(thin_vec![ nested_tree(self, sym::TryCaptureGeneric), nested_tree(self, sym::TryCapturePrintable), ]), @@ -136,7 +136,7 @@ impl<'cx, 'a> Context<'cx, 'a> { self.cx.expr_call( self.span, self.cx.expr_path(self.cx.path(self.span, unlikely_path)), - vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))], + thin_vec![self.cx.expr(self.span, ExprKind::Unary(UnOp::Not, cond_expr))], ) } @@ -339,7 +339,7 @@ impl<'cx, 'a> Context<'cx, 'a> { let init = self.cx.expr_call( self.span, self.cx.expr_path(self.cx.path(self.span, init_std_path)), - vec![], + ThinVec::new(), ); let capture = Capture { decl: self.cx.stmt_let(self.span, true, ident, init), ident }; self.capture_decls.push(capture); @@ -366,7 +366,7 @@ impl<'cx, 'a> Context<'cx, 'a> { self.cx.expr_path( self.cx.path(self.span, self.cx.std_path(&[sym::asserting, sym::Wrapper])), ), - vec![self.cx.expr_path(Path::from_ident(local_bind))], + thin_vec![self.cx.expr_path(Path::from_ident(local_bind))], ); let try_capture_call = self .cx @@ -378,7 +378,7 @@ impl<'cx, 'a> Context<'cx, 'a> { ident: Ident::new(sym::try_capture, self.span), }, expr_paren(self.cx, self.span, self.cx.expr_addr_of(self.span, wrapper)), - vec![expr_addr_of_mut( + thin_vec![expr_addr_of_mut( self.cx, self.span, self.cx.expr_path(Path::from_ident(capture)), @@ -389,7 +389,7 @@ impl<'cx, 'a> Context<'cx, 'a> { let local_bind_path = self.cx.expr_path(Path::from_ident(local_bind)); let rslt = if self.is_consumed { let ret = self.cx.stmt_expr(local_bind_path); - self.cx.expr_block(self.cx.block(self.span, vec![try_capture_call, ret])) + self.cx.expr_block(self.cx.block(self.span, thin_vec![try_capture_call, ret])) } else { self.best_case_captures.push(try_capture_call); local_bind_path @@ -441,7 +441,7 @@ fn expr_method_call( cx: &ExtCtxt<'_>, seg: PathSegment, receiver: P<Expr>, - args: Vec<P<Expr>>, + args: ThinVec<P<Expr>>, span: Span, ) -> P<Expr> { cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span }))) diff --git a/compiler/rustc_builtin_macros/src/deriving/clone.rs b/compiler/rustc_builtin_macros/src/deriving/clone.rs index 42f50d8ade2..dfee2d3ce77 100644 --- a/compiler/rustc_builtin_macros/src/deriving/clone.rs +++ b/compiler/rustc_builtin_macros/src/deriving/clone.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_clone( cx: &mut ExtCtxt<'_>, @@ -100,7 +100,7 @@ fn cs_clone_simple( substr: &Substructure<'_>, is_union: bool, ) -> BlockOrExpr { - let mut stmts = Vec::new(); + let mut stmts = ThinVec::new(); let mut seen_type_names = FxHashSet::default(); let mut process_variant = |variant: &VariantData| { for field in variant.fields() { @@ -162,7 +162,7 @@ fn cs_clone( let all_fields; let fn_path = cx.std_path(&[sym::clone, sym::Clone, sym::clone]); let subcall = |cx: &mut ExtCtxt<'_>, field: &FieldInfo| { - let args = vec![field.self_expr.clone()]; + let args = thin_vec![field.self_expr.clone()]; cx.expr_call_global(field.span, fn_path.clone(), args) }; @@ -200,7 +200,7 @@ fn cs_clone( let call = subcall(cx, field); cx.field_imm(field.span, ident, call) }) - .collect::<Vec<_>>(); + .collect::<ThinVec<_>>(); cx.expr_struct(trait_span, ctor_path, fields) } diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs index 424719f9795..af971958680 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/eq.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_eq( cx: &mut ExtCtxt<'_>, @@ -56,7 +56,7 @@ fn cs_total_eq_assert( trait_span: Span, substr: &Substructure<'_>, ) -> BlockOrExpr { - let mut stmts = Vec::new(); + let mut stmts = ThinVec::new(); let mut seen_type_names = FxHashSet::default(); let mut process_variant = |variant: &ast::VariantData| { for field in variant.fields() { diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs index 671f32550d2..cfd36f030a1 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/ord.rs @@ -64,14 +64,14 @@ pub fn cs_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_>) -> Bl let [other_expr] = &field.other_selflike_exprs[..] else { cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`"); }; - let args = vec![field.self_expr.clone(), other_expr.clone()]; + let args = thin_vec![field.self_expr.clone(), other_expr.clone()]; cx.expr_call_global(field.span, cmp_path.clone(), args) } CsFold::Combine(span, expr1, expr2) => { let eq_arm = cx.arm(span, cx.pat_path(span, equal_path.clone()), expr1); let neq_arm = cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id)); - cx.expr_match(span, expr2, vec![eq_arm, neq_arm]) + cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm]) } CsFold::Fieldless => cx.expr_path(equal_path.clone()), }, diff --git a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs index bcc90442eb7..9f46247908d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs +++ b/compiler/rustc_builtin_macros/src/deriving/cmp/partial_ord.rs @@ -98,7 +98,7 @@ fn cs_partial_cmp( let [other_expr] = &field.other_selflike_exprs[..] else { cx.span_bug(field.span, "not exactly 2 arguments in `derive(Ord)`"); }; - let args = vec![field.self_expr.clone(), other_expr.clone()]; + let args = thin_vec![field.self_expr.clone(), other_expr.clone()]; cx.expr_call_global(field.span, partial_cmp_path.clone(), args) } CsFold::Combine(span, mut expr1, expr2) => { @@ -143,7 +143,7 @@ fn cs_partial_cmp( cx.arm(span, cx.pat_some(span, cx.pat_path(span, equal_path.clone())), expr1); let neq_arm = cx.arm(span, cx.pat_ident(span, test_id), cx.expr_ident(span, test_id)); - cx.expr_match(span, expr2, vec![eq_arm, neq_arm]) + cx.expr_match(span, expr2, thin_vec![eq_arm, neq_arm]) } } CsFold::Fieldless => cx.expr_some(span, cx.expr_path(equal_path.clone())), diff --git a/compiler/rustc_builtin_macros/src/deriving/debug.rs b/compiler/rustc_builtin_macros/src/deriving/debug.rs index d30e8ba4b93..809f9838d20 100644 --- a/compiler/rustc_builtin_macros/src/deriving/debug.rs +++ b/compiler/rustc_builtin_macros/src/deriving/debug.rs @@ -7,6 +7,7 @@ use rustc_ast::{self as ast, MetaItem}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_debug( cx: &mut ExtCtxt<'_>, @@ -94,7 +95,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> if fields.is_empty() { // Special case for no fields. let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); - let expr = cx.expr_call_global(span, fn_path_write_str, vec![fmt, name]); + let expr = cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name]); BlockOrExpr::new_expr(expr) } else if fields.len() <= CUTOFF { // Few enough fields that we can use a specific-length method. @@ -105,7 +106,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> }; let fn_path_debug = cx.std_path(&[sym::fmt, sym::Formatter, Symbol::intern(&debug)]); - let mut args = Vec::with_capacity(2 + fields.len() * args_per_field); + let mut args = ThinVec::with_capacity(2 + fields.len() * args_per_field); args.extend([fmt, name]); for i in 0..fields.len() { let field = &fields[i]; @@ -121,8 +122,8 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> BlockOrExpr::new_expr(expr) } else { // Enough fields that we must use the any-length method. - let mut name_exprs = Vec::with_capacity(fields.len()); - let mut value_exprs = Vec::with_capacity(fields.len()); + let mut name_exprs = ThinVec::with_capacity(fields.len()); + let mut value_exprs = ThinVec::with_capacity(fields.len()); for i in 0..fields.len() { let field = &fields[i]; @@ -177,7 +178,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> }; let fn_path_debug_internal = cx.std_path(&[sym::fmt, sym::Formatter, sym_debug]); - let mut args = Vec::with_capacity(4); + let mut args = ThinVec::with_capacity(4); args.push(fmt); args.push(name); if is_struct { @@ -186,7 +187,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> args.push(cx.expr_ident(span, Ident::new(sym::values, span))); let expr = cx.expr_call_global(span, fn_path_debug_internal, args); - let mut stmts = Vec::with_capacity(3); + let mut stmts = ThinVec::with_capacity(2); if is_struct { stmts.push(names_let.unwrap()); } @@ -223,18 +224,18 @@ fn show_fieldless_enum( let pat = match &v.data { ast::VariantData::Tuple(fields, _) => { debug_assert!(fields.is_empty()); - cx.pat_tuple_struct(span, variant_path, vec![]) + cx.pat_tuple_struct(span, variant_path, ThinVec::new()) } ast::VariantData::Struct(fields, _) => { debug_assert!(fields.is_empty()); - cx.pat_struct(span, variant_path, vec![]) + cx.pat_struct(span, variant_path, ThinVec::new()) } ast::VariantData::Unit(_) => cx.pat_path(span, variant_path), }; cx.arm(span, pat, cx.expr_str(span, v.ident.name)) }) - .collect::<Vec<_>>(); + .collect::<ThinVec<_>>(); let name = cx.expr_match(span, cx.expr_self(span), arms); let fn_path_write_str = cx.std_path(&[sym::fmt, sym::Formatter, sym::write_str]); - BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, vec![fmt, name])) + BlockOrExpr::new_expr(cx.expr_call_global(span, fn_path_write_str, thin_vec![fmt, name])) } diff --git a/compiler/rustc_builtin_macros/src/deriving/decodable.rs b/compiler/rustc_builtin_macros/src/deriving/decodable.rs index c783e46eda9..3921533c84a 100644 --- a/compiler/rustc_builtin_macros/src/deriving/decodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/decodable.rs @@ -3,12 +3,12 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; - use rustc_ast::ptr::P; use rustc_ast::{self as ast, Expr, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_rustc_decodable( cx: &mut ExtCtxt<'_>, @@ -96,7 +96,7 @@ fn decodable_substructure( cx.expr_call_global( span, fn_read_struct_field_path.clone(), - vec![ + thin_vec![ blkdecoder.clone(), cx.expr_str(span, name), cx.expr_usize(span, field), @@ -112,7 +112,7 @@ fn decodable_substructure( cx.expr_call_global( trait_span, fn_read_struct_path, - vec![ + thin_vec![ decoder, cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, nfields), @@ -123,8 +123,8 @@ fn decodable_substructure( StaticEnum(_, fields) => { let variant = Ident::new(sym::i, trait_span); - let mut arms = Vec::with_capacity(fields.len() + 1); - let mut variants = Vec::with_capacity(fields.len()); + let mut arms = ThinVec::with_capacity(fields.len() + 1); + let mut variants = ThinVec::with_capacity(fields.len()); let fn_read_enum_variant_arg_path: Vec<_> = cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum_variant_arg]); @@ -141,7 +141,7 @@ fn decodable_substructure( cx.expr_call_global( span, fn_read_enum_variant_arg_path.clone(), - vec![blkdecoder.clone(), idx, exprdecode.clone()], + thin_vec![blkdecoder.clone(), idx, exprdecode.clone()], ), ) }); @@ -162,7 +162,7 @@ fn decodable_substructure( let result = cx.expr_call_global( trait_span, fn_read_enum_variant_path, - vec![blkdecoder, variant_array_ref, lambda], + thin_vec![blkdecoder, variant_array_ref, lambda], ); let fn_read_enum_path: Vec<_> = cx.def_site_path(&[sym::rustc_serialize, sym::Decoder, sym::read_enum]); @@ -170,7 +170,7 @@ fn decodable_substructure( cx.expr_call_global( trait_span, fn_read_enum_path, - vec![ + thin_vec![ decoder, cx.expr_str(trait_span, substr.type_ident.name), cx.lambda1(trait_span, result, blkarg), diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs index a6c8b111527..4d753a2ed80 100644 --- a/compiler/rustc_builtin_macros/src/deriving/default.rs +++ b/compiler/rustc_builtin_macros/src/deriving/default.rs @@ -8,7 +8,7 @@ use rustc_span::symbol::Ident; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use smallvec::SmallVec; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_default( cx: &mut ExtCtxt<'_>, @@ -60,7 +60,7 @@ fn default_struct_substructure( ) -> BlockOrExpr { // Note that `kw::Default` is "default" and `sym::Default` is "Default"! let default_ident = cx.std_path(&[kw::Default, sym::Default, kw::Default]); - let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new()); + let default_call = |span| cx.expr_call_global(span, default_ident.clone(), ThinVec::new()); let expr = match summary { Unnamed(_, false) => cx.expr_ident(trait_span, substr.type_ident), diff --git a/compiler/rustc_builtin_macros/src/deriving/encodable.rs b/compiler/rustc_builtin_macros/src/deriving/encodable.rs index a5e2b599df4..a3b11309d0c 100644 --- a/compiler/rustc_builtin_macros/src/deriving/encodable.rs +++ b/compiler/rustc_builtin_macros/src/deriving/encodable.rs @@ -88,11 +88,11 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::pathvec_std; - use rustc_ast::{AttrVec, ExprKind, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; +use thin_vec::{thin_vec, ThinVec}; pub fn expand_deriving_rustc_encodable( cx: &mut ExtCtxt<'_>, @@ -169,19 +169,20 @@ fn encodable_substructure( Struct(_, fields) => { let fn_emit_struct_field_path = cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_struct_field]); - let mut stmts = Vec::new(); + let mut stmts = ThinVec::new(); for (i, &FieldInfo { name, ref self_expr, span, .. }) in fields.iter().enumerate() { let name = match name { Some(id) => id.name, None => Symbol::intern(&format!("_field{}", i)), }; let self_ref = cx.expr_addr_of(span, self_expr.clone()); - let enc = cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]); + let enc = + cx.expr_call(span, fn_path.clone(), thin_vec![self_ref, blkencoder.clone()]); let lambda = cx.lambda1(span, enc, blkarg); let call = cx.expr_call_global( span, fn_emit_struct_field_path.clone(), - vec![ + thin_vec![ blkencoder.clone(), cx.expr_str(span, name), cx.expr_usize(span, i), @@ -203,7 +204,7 @@ fn encodable_substructure( // unit structs have no fields and need to return Ok() let blk = if stmts.is_empty() { - let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![])); + let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new())); cx.lambda1(trait_span, ok, blkarg) } else { cx.lambda_stmts_1(trait_span, stmts, blkarg) @@ -215,7 +216,7 @@ fn encodable_substructure( let expr = cx.expr_call_global( trait_span, fn_emit_struct_path, - vec![ + thin_vec![ encoder, cx.expr_str(trait_span, substr.type_ident.name), cx.expr_usize(trait_span, fields.len()), @@ -236,19 +237,22 @@ fn encodable_substructure( let fn_emit_enum_variant_arg_path: Vec<_> = cx.def_site_path(&[sym::rustc_serialize, sym::Encoder, sym::emit_enum_variant_arg]); - let mut stmts = Vec::new(); + let mut stmts = ThinVec::new(); if !fields.is_empty() { let last = fields.len() - 1; for (i, &FieldInfo { ref self_expr, span, .. }) in fields.iter().enumerate() { let self_ref = cx.expr_addr_of(span, self_expr.clone()); - let enc = - cx.expr_call(span, fn_path.clone(), vec![self_ref, blkencoder.clone()]); + let enc = cx.expr_call( + span, + fn_path.clone(), + thin_vec![self_ref, blkencoder.clone()], + ); let lambda = cx.lambda1(span, enc, blkarg); let call = cx.expr_call_global( span, fn_emit_enum_variant_arg_path.clone(), - vec![blkencoder.clone(), cx.expr_usize(span, i), lambda], + thin_vec![blkencoder.clone(), cx.expr_usize(span, i), lambda], ); let call = if i != last { cx.expr_try(span, call) @@ -258,7 +262,7 @@ fn encodable_substructure( stmts.push(cx.stmt_expr(call)); } } else { - let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, vec![])); + let ok = cx.expr_ok(trait_span, cx.expr_tuple(trait_span, ThinVec::new())); let ret_ok = cx.expr(trait_span, ExprKind::Ret(Some(ok))); stmts.push(cx.stmt_expr(ret_ok)); } @@ -272,7 +276,7 @@ fn encodable_substructure( let call = cx.expr_call_global( trait_span, fn_emit_enum_variant_path, - vec![ + thin_vec![ blkencoder, name, cx.expr_usize(trait_span, *idx), @@ -287,9 +291,9 @@ fn encodable_substructure( let expr = cx.expr_call_global( trait_span, fn_emit_enum_path, - vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk], + thin_vec![encoder, cx.expr_str(trait_span, substr.type_ident.name), blk], ); - BlockOrExpr::new_mixed(vec![me], Some(expr)) + BlockOrExpr::new_mixed(thin_vec![me], Some(expr)) } _ => cx.bug("expected Struct or EnumMatching in derive(Encodable)"), diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 38878ba7012..1f819beeb5d 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -177,7 +177,7 @@ use std::cell::RefCell; use std::iter; use std::ops::Not; use std::vec; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; use ty::{Bounds, Path, Ref, Self_, Ty}; pub mod ty; @@ -318,7 +318,7 @@ pub fn combine_substructure( } struct TypeParameter { - bound_generic_params: Vec<ast::GenericParam>, + bound_generic_params: ThinVec<ast::GenericParam>, ty: P<ast::Ty>, } @@ -328,18 +328,18 @@ struct TypeParameter { /// avoiding the insertion of any unnecessary blocks. /// /// The statements come before the expression. -pub struct BlockOrExpr(Vec<ast::Stmt>, Option<P<Expr>>); +pub struct BlockOrExpr(ThinVec<ast::Stmt>, Option<P<Expr>>); impl BlockOrExpr { - pub fn new_stmts(stmts: Vec<ast::Stmt>) -> BlockOrExpr { + pub fn new_stmts(stmts: ThinVec<ast::Stmt>) -> BlockOrExpr { BlockOrExpr(stmts, None) } pub fn new_expr(expr: P<Expr>) -> BlockOrExpr { - BlockOrExpr(vec![], Some(expr)) + BlockOrExpr(ThinVec::new(), Some(expr)) } - pub fn new_mixed(stmts: Vec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr { + pub fn new_mixed(stmts: ThinVec<ast::Stmt>, expr: Option<P<Expr>>) -> BlockOrExpr { BlockOrExpr(stmts, expr) } @@ -355,7 +355,7 @@ impl BlockOrExpr { fn into_expr(self, cx: &ExtCtxt<'_>, span: Span) -> P<Expr> { if self.0.is_empty() { match self.1 { - None => cx.expr_block(cx.block(span, vec![])), + None => cx.expr_block(cx.block(span, ThinVec::new())), Some(expr) => expr, } } else if self.0.len() == 1 @@ -385,7 +385,7 @@ fn find_type_parameters( struct Visitor<'a, 'b> { cx: &'a ExtCtxt<'b>, ty_param_names: &'a [Symbol], - bound_generic_params_stack: Vec<ast::GenericParam>, + bound_generic_params_stack: ThinVec<ast::GenericParam>, type_params: Vec<TypeParameter>, } @@ -422,7 +422,7 @@ fn find_type_parameters( let mut visitor = Visitor { cx, ty_param_names, - bound_generic_params_stack: Vec::new(), + bound_generic_params_stack: ThinVec::new(), type_params: Vec::new(), }; visit::Visitor::visit_ty(&mut visitor, ty); @@ -594,7 +594,7 @@ impl<'a> TraitDef<'a> { let span = generics.span.with_ctxt(ctxt); // Create the generic parameters - let params: Vec<_> = generics + let params: ThinVec<_> = generics .params .iter() .map(|param| match ¶m.kind { @@ -935,8 +935,8 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'_>, type_ident: Ident, generics: &Generics, - ) -> (Option<ast::ExplicitSelf>, Vec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) { - let mut selflike_args = Vec::new(); + ) -> (Option<ast::ExplicitSelf>, ThinVec<P<Expr>>, Vec<P<Expr>>, Vec<(Ident, P<ast::Ty>)>) { + let mut selflike_args = ThinVec::new(); let mut nonselflike_args = Vec::new(); let mut nonself_arg_tys = Vec::new(); let span = trait_.span; @@ -1133,7 +1133,7 @@ impl<'a> MethodDef<'a> { trait_: &TraitDef<'b>, enum_def: &'b EnumDef, type_ident: Ident, - selflike_args: Vec<P<Expr>>, + selflike_args: ThinVec<P<Expr>>, nonselflike_args: &[P<Expr>], ) -> BlockOrExpr { let span = trait_.span; @@ -1146,7 +1146,7 @@ impl<'a> MethodDef<'a> { // There is no sensible code to be generated for *any* deriving on a // zero-variant enum. So we just generate a failing expression. if variants.is_empty() { - return BlockOrExpr(vec![], Some(deriving::call_unreachable(cx, span))); + return BlockOrExpr(ThinVec::new(), Some(deriving::call_unreachable(cx, span))); } let prefixes = iter::once("__self".to_string()) @@ -1182,13 +1182,13 @@ impl<'a> MethodDef<'a> { let other_selflike_exprs = tag_exprs; let tag_field = FieldInfo { span, name: None, self_expr, other_selflike_exprs }; - let tag_let_stmts: Vec<_> = iter::zip(&tag_idents, &selflike_args) + let tag_let_stmts: ThinVec<_> = iter::zip(&tag_idents, &selflike_args) .map(|(&ident, selflike_arg)| { let variant_value = deriving::call_intrinsic( cx, span, sym::discriminant_value, - vec![selflike_arg.clone()], + thin_vec![selflike_arg.clone()], ); cx.stmt_let(span, false, ident, variant_value) }) @@ -1247,7 +1247,7 @@ impl<'a> MethodDef<'a> { // (Variant2, Variant2, ...) => Body2 // ... // where each tuple has length = selflike_args.len() - let mut match_arms: Vec<ast::Arm> = variants + let mut match_arms: ThinVec<ast::Arm> = variants .iter() .enumerate() .filter(|&(_, v)| !(unify_fieldless_variants && v.data.fields().is_empty())) @@ -1260,7 +1260,7 @@ impl<'a> MethodDef<'a> { let sp = variant.span.with_ctxt(trait_.span.ctxt()); let variant_path = cx.path(sp, vec![type_ident, variant.ident]); let by_ref = ByRef::No; // because enums can't be repr(packed) - let mut subpats: Vec<_> = trait_.create_struct_patterns( + let mut subpats = trait_.create_struct_patterns( cx, variant_path, &variant.data, @@ -1336,7 +1336,7 @@ impl<'a> MethodDef<'a> { // ... // _ => ::core::intrinsics::unreachable() // } - let get_match_expr = |mut selflike_args: Vec<P<Expr>>| { + let get_match_expr = |mut selflike_args: ThinVec<P<Expr>>| { let match_arg = if selflike_args.len() == 1 { selflike_args.pop().unwrap() } else { @@ -1362,7 +1362,7 @@ impl<'a> MethodDef<'a> { tag_let_stmts.append(&mut tag_check_plus_match.0); BlockOrExpr(tag_let_stmts, tag_check_plus_match.1) } else { - BlockOrExpr(vec![], Some(get_match_expr(selflike_args))) + BlockOrExpr(ThinVec::new(), Some(get_match_expr(selflike_args))) } } @@ -1427,7 +1427,7 @@ impl<'a> TraitDef<'a> { struct_def: &'a VariantData, prefixes: &[String], by_ref: ByRef, - ) -> Vec<P<ast::Pat>> { + ) -> ThinVec<P<ast::Pat>> { prefixes .iter() .map(|prefix| { @@ -1599,7 +1599,7 @@ impl<'a> TraitDef<'a> { } else { // Wrap the expression in `{...}`, causing a copy. field_expr = cx.expr_block( - cx.block(struct_field.span, vec![cx.stmt_expr(field_expr)]), + cx.block(struct_field.span, thin_vec![cx.stmt_expr(field_expr)]), ); } } diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index aabd5b1f773..26f91b714b4 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -9,6 +9,7 @@ use rustc_expand::base::ExtCtxt; use rustc_span::source_map::{respan, DUMMY_SP}; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::Span; +use thin_vec::ThinVec; /// A path, e.g., `::std::option::Option::<i32>` (global). Has support /// for type parameters. @@ -102,7 +103,7 @@ impl Ty { Path(p) => p.to_ty(cx, span, self_ty, self_generics), Self_ => cx.ty_path(self.to_path(cx, span, self_ty, self_generics)), Unit => { - let ty = ast::TyKind::Tup(vec![]); + let ty = ast::TyKind::Tup(ThinVec::new()); cx.ty(span, ty) } } @@ -185,7 +186,11 @@ impl Bounds { Generics { params, - where_clause: ast::WhereClause { has_where_token: false, predicates: Vec::new(), span }, + where_clause: ast::WhereClause { + has_where_token: false, + predicates: ThinVec::new(), + span, + }, span, } } diff --git a/compiler/rustc_builtin_macros/src/deriving/hash.rs b/compiler/rustc_builtin_macros/src/deriving/hash.rs index 5c2e89c5697..4eee573db42 100644 --- a/compiler/rustc_builtin_macros/src/deriving/hash.rs +++ b/compiler/rustc_builtin_macros/src/deriving/hash.rs @@ -1,11 +1,11 @@ use crate::deriving::generic::ty::*; use crate::deriving::generic::*; use crate::deriving::{path_std, pathvec_std}; - use rustc_ast::{AttrVec, MetaItem, Mutability}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; +use thin_vec::thin_vec; pub fn expand_deriving_hash( cx: &mut ExtCtxt<'_>, @@ -60,7 +60,7 @@ fn hash_substructure( cx.expr_path(cx.path_global(span, strs)) }; - let expr = cx.expr_call(span, hash_path, vec![expr, state_expr.clone()]); + let expr = cx.expr_call(span, hash_path, thin_vec![expr, state_expr.clone()]); cx.stmt_expr(expr) }; @@ -72,7 +72,7 @@ fn hash_substructure( } EnumTag(tag_field, match_expr) => { assert!(tag_field.other_selflike_exprs.is_empty()); - let stmts = vec![call_hash(tag_field.span, tag_field.self_expr.clone())]; + let stmts = thin_vec![call_hash(tag_field.span, tag_field.self_expr.clone())]; (stmts, match_expr.clone()) } _ => cx.span_bug(trait_span, "impossible substructure in `derive(Hash)`"), diff --git a/compiler/rustc_builtin_macros/src/deriving/mod.rs b/compiler/rustc_builtin_macros/src/deriving/mod.rs index de657e4e600..d34336e7679 100644 --- a/compiler/rustc_builtin_macros/src/deriving/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/mod.rs @@ -6,6 +6,7 @@ use rustc_ast::{GenericArg, Impl, ItemKind, MetaItem}; use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt, MultiItemModifier}; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; +use thin_vec::{thin_vec, ThinVec}; macro path_local($x:ident) { generic::ty::Path::new_local(sym::$x) @@ -92,7 +93,7 @@ fn call_intrinsic( cx: &ExtCtxt<'_>, span: Span, intrinsic: Symbol, - args: Vec<P<ast::Expr>>, + args: ThinVec<P<ast::Expr>>, ) -> P<ast::Expr> { let span = cx.with_def_site_ctxt(span); let path = cx.std_path(&[sym::intrinsics, intrinsic]); @@ -103,10 +104,10 @@ fn call_intrinsic( fn call_unreachable(cx: &ExtCtxt<'_>, span: Span) -> P<ast::Expr> { let span = cx.with_def_site_ctxt(span); let path = cx.std_path(&[sym::intrinsics, sym::unreachable]); - let call = cx.expr_call_global(span, path, vec![]); + let call = cx.expr_call_global(span, path, ThinVec::new()); cx.expr_block(P(ast::Block { - stmts: vec![cx.stmt_expr(call)], + stmts: thin_vec![cx.stmt_expr(call)], id: ast::DUMMY_NODE_ID, rules: ast::BlockCheckMode::Unsafe(ast::CompilerGenerated), span, @@ -202,7 +203,7 @@ fn inject_impl_of_structural_trait( generics, of_trait: Some(trait_ref), self_ty: self_type, - items: Vec::new(), + items: ThinVec::new(), })), ); @@ -211,7 +212,7 @@ fn inject_impl_of_structural_trait( fn assert_ty_bounds( cx: &mut ExtCtxt<'_>, - stmts: &mut Vec<ast::Stmt>, + stmts: &mut ThinVec<ast::Stmt>, ty: P<ast::Ty>, span: Span, assert_path: &[Symbol], diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs index e5a5e606930..6aa900f0201 100644 --- a/compiler/rustc_builtin_macros/src/env.rs +++ b/compiler/rustc_builtin_macros/src/env.rs @@ -8,8 +8,8 @@ use rustc_ast::{self as ast, GenericArg}; use rustc_expand::base::{self, *}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; - use std::env; +use thin_vec::thin_vec; pub fn expand_option_env<'cx>( cx: &'cx mut ExtCtxt<'_>, @@ -41,7 +41,7 @@ pub fn expand_option_env<'cx>( Some(value) => cx.expr_call_global( sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), - vec![cx.expr_str(sp, value)], + thin_vec![cx.expr_str(sp, value)], ), }; MacEager::expr(e) diff --git a/compiler/rustc_builtin_macros/src/global_allocator.rs b/compiler/rustc_builtin_macros/src/global_allocator.rs index f8761653bf5..41b51bae736 100644 --- a/compiler/rustc_builtin_macros/src/global_allocator.rs +++ b/compiler/rustc_builtin_macros/src/global_allocator.rs @@ -9,7 +9,7 @@ use rustc_ast::{Fn, ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; pub fn expand( ecx: &mut ExtCtxt<'_>, @@ -47,7 +47,7 @@ pub fn expand( let stmts = ALLOCATOR_METHODS.iter().map(|method| f.allocator_fn(method)).collect(); // Generate anonymous constant serving as container for the allocator methods. - let const_ty = ecx.ty(ty_span, TyKind::Tup(Vec::new())); + let const_ty = ecx.ty(ty_span, TyKind::Tup(ThinVec::new())); let const_body = ecx.expr_block(ecx.block(span, stmts)); let const_item = ecx.item_const(span, Ident::new(kw::Underscore, span), const_ty, const_body); let const_item = if is_stmt { @@ -70,7 +70,7 @@ struct AllocFnFactory<'a, 'b> { impl AllocFnFactory<'_, '_> { fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt { - let mut abi_args = Vec::new(); + let mut abi_args = ThinVec::new(); let mut i = 0; let mut mk = || { let name = Ident::from_str_and_span(&format!("arg{}", i), self.span); @@ -99,7 +99,7 @@ impl AllocFnFactory<'_, '_> { self.cx.stmt_item(self.ty_span, item) } - fn call_allocator(&self, method: Symbol, mut args: Vec<P<Expr>>) -> P<Expr> { + fn call_allocator(&self, method: Symbol, mut args: ThinVec<P<Expr>>) -> P<Expr> { let method = self.cx.std_path(&[sym::alloc, sym::GlobalAlloc, method]); let method = self.cx.expr_path(self.cx.path(self.ty_span, method)); let allocator = self.cx.path_ident(self.ty_span, self.global); @@ -117,7 +117,7 @@ impl AllocFnFactory<'_, '_> { fn arg_ty( &self, ty: &AllocatorTy, - args: &mut Vec<Param>, + args: &mut ThinVec<Param>, ident: &mut dyn FnMut() -> Ident, ) -> P<Expr> { match *ty { @@ -134,7 +134,7 @@ impl AllocFnFactory<'_, '_> { let layout_new = self.cx.expr_path(self.cx.path(self.span, layout_new)); let size = self.cx.expr_ident(self.span, size); let align = self.cx.expr_ident(self.span, align); - let layout = self.cx.expr_call(self.span, layout_new, vec![size, align]); + let layout = self.cx.expr_call(self.span, layout_new, thin_vec![size, align]); layout } @@ -168,7 +168,7 @@ impl AllocFnFactory<'_, '_> { (self.ptr_u8(), expr) } - AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr), + AllocatorTy::Unit => (self.cx.ty(self.span, TyKind::Tup(ThinVec::new())), expr), AllocatorTy::Layout | AllocatorTy::Usize | AllocatorTy::Ptr => { panic!("can't convert `AllocatorTy` to an output") diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 75cfac72384..8afb6e56069 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -21,8 +21,10 @@ extern crate tracing; use crate::deriving::*; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_expand::base::{MacroExpanderFn, ResolverExpand, SyntaxExtensionKind}; use rustc_expand::proc_macro::BangProcMacro; +use rustc_macros::fluent_messages; use rustc_span::symbol::sym; mod alloc_error_handler; @@ -54,6 +56,8 @@ pub mod proc_macro_harness; pub mod standard_library_imports; pub mod test_harness; +fluent_messages! { "../locales/en-US.ftl" } + pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { let mut register = |name, kind| resolver.register_builtin_macro(name, kind); macro register_bang($($name:ident: $f:expr,)*) { diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index 21c8caa658f..bc513607ddd 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -11,6 +11,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use smallvec::smallvec; use std::mem; +use thin_vec::{thin_vec, ThinVec}; struct ProcMacroDerive { id: NodeId, @@ -314,11 +315,14 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> { cx.expr_call( span, proc_macro_ty_method_path(cx, custom_derive), - vec![ + thin_vec![ cx.expr_str(span, cd.trait_name), cx.expr_array_ref( span, - cd.attrs.iter().map(|&s| cx.expr_str(span, s)).collect::<Vec<_>>(), + cd.attrs + .iter() + .map(|&s| cx.expr_str(span, s)) + .collect::<ThinVec<_>>(), ), local_path(cx, cd.function_name), ], @@ -335,7 +339,7 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> { cx.expr_call( span, proc_macro_ty_method_path(cx, ident), - vec![ + thin_vec![ cx.expr_str(span, ca.function_name.name), local_path(cx, ca.function_name), ], @@ -371,13 +375,13 @@ fn mk_decls(cx: &mut ExtCtxt<'_>, macros: &[ProcMacro]) -> P<ast::Item> { }); let block = cx.expr_block( - cx.block(span, vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), + cx.block(span, thin_vec![cx.stmt_item(span, krate), cx.stmt_item(span, decls_static)]), ); let anon_constant = cx.item_const( span, Ident::new(kw::Underscore, span), - cx.ty(span, ast::TyKind::Tup(Vec::new())), + cx.ty(span, ast::TyKind::Tup(ThinVec::new())), block, ); diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 729ae4071e2..e02c7e6c01b 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -10,7 +10,7 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use std::iter; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; /// #[test_case] is used by custom test authors to mark tests /// When building for test, it needs to make the item public and gensym the name @@ -179,19 +179,19 @@ pub fn expand_test_or_bench( cx.expr_call( sp, cx.expr_path(test_path("StaticBenchFn")), - vec![ + thin_vec![ // |b| self::test::assert_test_result( cx.lambda1( sp, cx.expr_call( sp, cx.expr_path(test_path("assert_test_result")), - vec![ + thin_vec![ // super::$test_fn(b) cx.expr_call( ret_ty_sp, cx.expr_path(cx.path(sp, vec![item.ident])), - vec![cx.expr_ident(sp, b)], + thin_vec![cx.expr_ident(sp, b)], ), ], ), @@ -203,7 +203,7 @@ pub fn expand_test_or_bench( cx.expr_call( sp, cx.expr_path(test_path("StaticTestFn")), - vec![ + thin_vec![ // || { cx.lambda0( sp, @@ -211,12 +211,12 @@ pub fn expand_test_or_bench( cx.expr_call( sp, cx.expr_path(test_path("assert_test_result")), - vec![ + thin_vec![ // $test_fn() cx.expr_call( ret_ty_sp, cx.expr_path(cx.path(sp, vec![item.ident])), - vec![], + ThinVec::new(), ), // ) ], ), // } @@ -249,21 +249,21 @@ pub fn expand_test_or_bench( cx.expr_struct( sp, test_path("TestDescAndFn"), - vec![ + thin_vec![ // desc: test::TestDesc { field( "desc", cx.expr_struct( sp, test_path("TestDesc"), - vec![ + thin_vec![ // name: "path::to::test" field( "name", cx.expr_call( sp, cx.expr_path(test_path("StaticTestName")), - vec![cx.expr_str(sp, test_path_symbol)], + thin_vec![cx.expr_str(sp, test_path_symbol)], ), ), // ignore: true | false @@ -300,7 +300,7 @@ pub fn expand_test_or_bench( ShouldPanic::Yes(Some(sym)) => cx.expr_call( sp, cx.expr_path(should_panic_path("YesWithMessage")), - vec![cx.expr_str(sp, sym)], + thin_vec![cx.expr_str(sp, sym)], ), }, ), diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index ad887108091..d8e3db9e8ee 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -14,7 +14,8 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; use rustc_target::spec::PanicStrategy; use smallvec::{smallvec, SmallVec}; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; +use tracing::debug; use std::{iter, mem}; @@ -299,7 +300,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { test_runner.span = sp; let test_main_path_expr = ecx.expr_path(test_runner); - let call_test_main = ecx.expr_call(sp, test_main_path_expr, vec![mk_tests_slice(cx, sp)]); + let call_test_main = ecx.expr_call(sp, test_main_path_expr, thin_vec![mk_tests_slice(cx, sp)]); let call_test_main = ecx.stmt_expr(call_test_main); // extern crate test @@ -312,16 +313,16 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> { let main_attr = ecx.attr_word(sym::rustc_main, sp); // pub fn main() { ... } - let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(vec![])); + let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new())); // If no test runner is provided we need to import the test crate let main_body = if cx.test_runner.is_none() { - ecx.block(sp, vec![test_extern_stmt, call_test_main]) + ecx.block(sp, thin_vec![test_extern_stmt, call_test_main]) } else { - ecx.block(sp, vec![call_test_main]) + ecx.block(sp, thin_vec![call_test_main]) }; - let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty)); + let decl = ecx.fn_decl(ThinVec::new(), ast::FnRetTy::Ty(main_ret_ty)); let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp }; let defaultness = ast::Defaultness::Final; let main = ast::ItemKind::Fn(Box::new(ast::Fn { diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 3c34585d419..74396a66f54 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -405,9 +405,9 @@ pub(crate) fn codegen_terminator_call<'tcx>( }; let extra_args = &args[fn_sig.inputs().skip_binder().len()..]; - let extra_args = fx - .tcx - .mk_type_list(extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx)))); + let extra_args = fx.tcx.mk_type_list_from_iter( + extra_args.iter().map(|op_arg| fx.monomorphize(op_arg.ty(fx.mir, fx.tcx))), + ); let fn_abi = if let Some(instance) = instance { RevealAllLayoutCx(fx.tcx).fn_abi_of_instance(instance, extra_args) } else { diff --git a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs index b4a2537b5ea..40bfe70771c 100644 --- a/compiler/rustc_codegen_cranelift/src/codegen_i128.rs +++ b/compiler/rustc_codegen_cranelift/src/codegen_i128.rs @@ -56,7 +56,7 @@ pub(crate) fn maybe_codegen<'tcx>( Some(fx.easy_call("__multi3", &[lhs, rhs], val_ty)) } } else { - let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let oflow = CPlace::new_stack_slot(fx, fx.layout_of(fx.tcx.types.i32)); let lhs = lhs.load_scalar(fx); let rhs = rhs.load_scalar(fx); @@ -78,7 +78,7 @@ pub(crate) fn maybe_codegen<'tcx>( } BinOp::Add | BinOp::Sub | BinOp::Mul => { assert!(checked); - let out_ty = fx.tcx.intern_tup(&[lhs.layout().ty, fx.tcx.types.bool]); + let out_ty = fx.tcx.mk_tup(&[lhs.layout().ty, fx.tcx.types.bool]); let out_place = CPlace::new_stack_slot(fx, fx.layout_of(out_ty)); let (param_types, args) = if fx.tcx.sess.target.is_like_windows { let (lhs_ptr, lhs_extra) = lhs.force_stack(fx); diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index a8be0d32cc8..722e2754e83 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -374,7 +374,7 @@ impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> { impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) fn monomorphize<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable<TyCtxt<'tcx>> + Copy, { self.instance.subst_mir_and_normalize_erasing_regions( self.tcx, diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index cbac2e66765..e5c4b244a1a 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -191,7 +191,7 @@ fn llvm_add_sub<'tcx>( // carry0 | carry1 -> carry or borrow respectively let cb_out = fx.bcx.ins().bor(cb0, cb1); - let layout = fx.layout_of(fx.tcx.intern_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); + let layout = fx.layout_of(fx.tcx.mk_tup(&[fx.tcx.types.u8, fx.tcx.types.u64])); let val = CValue::by_val_pair(cb_out, c, layout); ret.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index c7fe382bac4..80ce3dc9328 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { pub(crate) use rustc_middle::ty::layout::{self, LayoutOf, TyAndLayout}; pub(crate) use rustc_middle::ty::{ self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, - TypeFoldable, UintTy, + TypeFoldable, TypeVisitableExt, UintTy, }; pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; @@ -172,6 +172,11 @@ pub struct CraneliftCodegenBackend { } impl CodegenBackend for CraneliftCodegenBackend { + fn locale_resource(&self) -> &'static str { + // FIXME(rust-lang/rust#100717) - cranelift codegen backend is not yet translated + "" + } + fn init(&self, sess: &Session) { use rustc_session::config::Lto; match sess.lto() { diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index 26327107df4..be908df83e8 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -119,7 +119,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), report.def_id, - tcx.intern_substs(&[GenericArg::from(main_ret_ty)]), + tcx.mk_substs(&[GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap() @@ -146,7 +146,7 @@ pub(crate) fn maybe_create_entry_wrapper( tcx, ParamEnv::reveal_all(), start_def_id, - tcx.intern_substs(&[main_ret_ty.into()]), + tcx.mk_substs(&[main_ret_ty.into()]), ) .unwrap() .unwrap() diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs index 05905a7bcdf..c058ece96d8 100644 --- a/compiler/rustc_codegen_cranelift/src/num.rs +++ b/compiler/rustc_codegen_cranelift/src/num.rs @@ -289,7 +289,7 @@ pub(crate) fn codegen_checked_int_binop<'tcx>( _ => bug!("binop {:?} on checked int/uint lhs: {:?} rhs: {:?}", bin_op, in_lhs, in_rhs), }; - let out_layout = fx.layout_of(fx.tcx.intern_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); + let out_layout = fx.layout_of(fx.tcx.mk_tup(&[in_lhs.layout().ty, fx.tcx.types.bool])); CValue::by_val_pair(res, has_overflow, out_layout) } diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl b/compiler/rustc_codegen_gcc/locales/en-US.ftl index 6101b28ab0c..6101b28ab0c 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_gcc.ftl +++ b/compiler/rustc_codegen_gcc/locales/en-US.ftl diff --git a/compiler/rustc_codegen_gcc/src/callee.rs b/compiler/rustc_codegen_gcc/src/callee.rs index c1041125ecc..9e3a22ee05d 100644 --- a/compiler/rustc_codegen_gcc/src/callee.rs +++ b/compiler/rustc_codegen_gcc/src/callee.rs @@ -1,6 +1,6 @@ use gccjit::{FunctionType, RValue}; use rustc_codegen_ssa::traits::BaseTypeMethods; -use rustc_middle::ty::{self, Instance, TypeVisitable}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; use crate::abi::FnAbiGccExt; diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 4424b31c054..457006319af 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -383,7 +383,7 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { tcx, ty::ParamEnv::reveal_all(), def_id, - tcx.intern_substs(&[]), + ty::List::empty(), ) .unwrap().unwrap(), ), diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 5ab87feb98b..44538b41528 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -73,7 +73,8 @@ use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModul use rustc_codegen_ssa::target_features::supported_target_features; use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{ErrorGuaranteed, Handler}; +use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, Handler, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::TyCtxt; @@ -84,6 +85,8 @@ use rustc_span::Symbol; use rustc_span::fatal_error::FatalError; use tempfile::TempDir; +fluent_messages! { "../locales/en-US.ftl" } + pub struct PrintOnPanic<F: Fn() -> String>(pub F); impl<F: Fn() -> String> Drop for PrintOnPanic<F> { @@ -100,6 +103,10 @@ pub struct GccCodegenBackend { } impl CodegenBackend for GccCodegenBackend { + fn locale_resource(&self) -> &'static str { + crate::DEFAULT_LOCALE_RESOURCE + } + fn init(&self, sess: &Session) { if sess.lto() != Lto::No { sess.emit_warning(LTONotSupported {}); diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs index 9468a1ef4bb..a7c868354fb 100644 --- a/compiler/rustc_codegen_gcc/src/mono_item.rs +++ b/compiler/rustc_codegen_gcc/src/mono_item.rs @@ -1,7 +1,7 @@ use rustc_codegen_ssa::traits::PreDefineMethods; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir::mono::{Linkage, Visibility}; -use rustc_middle::ty::{self, Instance, TypeVisitable}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; use rustc_span::def_id::DefId; diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 1326af670cd..ea2ce765053 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -3,7 +3,7 @@ use std::fmt::Write; use gccjit::{Struct, Type}; use crate::rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods}; use rustc_middle::bug; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_target::abi::{self, Abi, F32, F64, FieldsShape, Int, Integer, Pointer, PointeeInfo, Size, TyAbiInterface, Variants}; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl b/compiler/rustc_codegen_llvm/locales/en-US.ftl index e5df417370b..e5df417370b 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_llvm.ftl +++ b/compiler/rustc_codegen_llvm/locales/en-US.ftl diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index f1d01a4602a..6ee2a05ffd7 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -13,7 +13,7 @@ use crate::value::Value; use rustc_codegen_ssa::traits::*; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt}; -use rustc_middle::ty::{self, Instance, TypeVisitable}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; /// Codegens a reference to a fn/method item, monomorphizing and /// inlining as it goes. diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 37ee0e14020..3d29968d5d6 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -520,14 +520,9 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { let tcx = self.tcx; let llfn = match tcx.lang_items().eh_personality() { Some(def_id) if !wants_msvc_seh(self.sess()) => self.get_fn_addr( - ty::Instance::resolve( - tcx, - ty::ParamEnv::reveal_all(), - def_id, - tcx.intern_substs(&[]), - ) - .unwrap() - .unwrap(), + ty::Instance::resolve(tcx, ty::ParamEnv::reveal_all(), def_id, ty::List::empty()) + .unwrap() + .unwrap(), ), _ => { let name = if wants_msvc_seh(self.sess()) { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index cef403b9f8b..5392534cfcb 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -27,7 +27,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::mir; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TypeVisitableExt}; use rustc_session::config::{self, DebugInfo}; use rustc_session::Session; use rustc_span::symbol::Symbol; diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 81072edc475..bae88d94293 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -2,9 +2,10 @@ use std::borrow::Cow; use std::ffi::CString; use std::path::Path; +use crate::fluent_generated as fluent; use rustc_data_structures::small_c_str::SmallCStr; use rustc_errors::{ - fluent, DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic, + DiagnosticBuilder, EmissionGuarantee, ErrorGuaranteed, Handler, IntoDiagnostic, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_span::Span; @@ -27,9 +28,9 @@ pub(crate) struct UnknownCTargetFeature<'a> { #[derive(Subdiagnostic)] pub(crate) enum PossibleFeature<'a> { - #[help(possible_feature)] + #[help(codegen_llvm_possible_feature)] Some { rust_feature: &'a str }, - #[help(consider_filing_feature_request)] + #[help(codegen_llvm_consider_filing_feature_request)] None, } diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 111d14b265c..c41e74c51a0 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -34,7 +34,8 @@ use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::ModuleCodegen; use rustc_codegen_ssa::{CodegenResults, CompiledModule}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{ErrorGuaranteed, FatalError, Handler}; +use rustc_errors::{DiagnosticMessage, ErrorGuaranteed, FatalError, Handler, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_metadata::EncodedMetadata; use rustc_middle::dep_graph::{WorkProduct, WorkProductId}; use rustc_middle::ty::query::Providers; @@ -83,6 +84,8 @@ mod type_of; mod va_arg; mod value; +fluent_messages! { "../locales/en-US.ftl" } + #[derive(Clone)] pub struct LlvmCodegenBackend(()); @@ -246,6 +249,10 @@ impl LlvmCodegenBackend { } impl CodegenBackend for LlvmCodegenBackend { + fn locale_resource(&self) -> &'static str { + crate::DEFAULT_LOCALE_RESOURCE + } + fn init(&self, sess: &Session) { llvm_util::init(sess); // Make sure llvm is inited } diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs index 76f692b2016..d0ae36349df 100644 --- a/compiler/rustc_codegen_llvm/src/mono_item.rs +++ b/compiler/rustc_codegen_llvm/src/mono_item.rs @@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LOCAL_CRATE}; pub use rustc_middle::mir::mono::MonoItem; use rustc_middle::mir::mono::{Linkage, Visibility}; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf}; -use rustc_middle::ty::{self, Instance, TypeVisitable}; +use rustc_middle::ty::{self, Instance, TypeVisitableExt}; use rustc_session::config::CrateType; use rustc_target::spec::RelocModel; diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 9cda24bab87..e264ce78f0d 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::*; use rustc_middle::bug; use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::abi::{Abi, Align, FieldsShape}; use rustc_target::abi::{Int, Pointer, F32, F64}; use rustc_target::abi::{PointeeInfo, Scalar, Size, TyAbiInterface, Variants}; diff --git a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl b/compiler/rustc_codegen_ssa/locales/en-US.ftl index 8fe5f8d50ab..8fe5f8d50ab 100644 --- a/compiler/rustc_error_messages/locales/en-US/codegen_ssa.ftl +++ b/compiler/rustc_codegen_ssa/locales/en-US.ftl diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index eaf1e9817c2..52c01b423a7 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -473,13 +473,13 @@ impl<'a> Linker for GccLinker<'a> { self.cmd.arg(path); } fn full_relro(&mut self) { - self.linker_args(&["-zrelro", "-znow"]); + self.linker_args(&["-z", "relro", "-z", "now"]); } fn partial_relro(&mut self) { - self.linker_arg("-zrelro"); + self.linker_args(&["-z", "relro"]); } fn no_relro(&mut self) { - self.linker_arg("-znorelro"); + self.linker_args(&["-z", "norelro"]); } fn link_rust_dylib(&mut self, lib: &str, _path: &Path) { @@ -758,7 +758,7 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.is_like_windows { self.linker_arg("--nxcompat"); } else if self.is_gnu { - self.linker_arg("-znoexecstack"); + self.linker_args(&["-z", "noexecstack"]); } } @@ -1364,16 +1364,16 @@ impl<'a> Linker for L4Bender<'a> { } fn full_relro(&mut self) { - self.cmd.arg("-zrelro"); - self.cmd.arg("-znow"); + self.cmd.arg("-z").arg("relro"); + self.cmd.arg("-z").arg("now"); } fn partial_relro(&mut self) { - self.cmd.arg("-zrelro"); + self.cmd.arg("-z").arg("relro"); } fn no_relro(&mut self) { - self.cmd.arg("-znorelro"); + self.cmd.arg("-z").arg("norelro"); } fn cmd(&mut self) -> &mut Command { diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 11bd47a8f0c..067a3e167fe 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -373,7 +373,7 @@ fn upstream_monomorphizations_provider( ExportedSymbol::Generic(def_id, substs) => (def_id, substs), ExportedSymbol::DropGlue(ty) => { if let Some(drop_in_place_fn_def_id) = drop_in_place_fn_def_id { - (drop_in_place_fn_def_id, tcx.intern_substs(&[ty.into()])) + (drop_in_place_fn_def_id, tcx.mk_substs(&[ty.into()])) } else { // `drop_in_place` in place does not exist, don't try // to use it. diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 4e13d4dbcb7..73179249bc4 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -476,7 +476,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx.tcx(), ty::ParamEnv::reveal_all(), start_def_id, - cx.tcx().intern_substs(&[main_ret_ty.into()]), + cx.tcx().mk_substs(&[main_ret_ty.into()]), ) .unwrap() .unwrap(), diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs index d81252653df..6dea7496fc3 100644 --- a/compiler/rustc_codegen_ssa/src/errors.rs +++ b/compiler/rustc_codegen_ssa/src/errors.rs @@ -1,8 +1,9 @@ //! Errors emitted by codegen_ssa use crate::back::command::Command; +use crate::fluent_generated as fluent; use rustc_errors::{ - fluent, DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, + DiagnosticArgValue, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, IntoDiagnosticArg, }; use rustc_macros::Diagnostic; @@ -388,7 +389,7 @@ pub struct LinkerNotFound { #[derive(Diagnostic)] #[diag(codegen_ssa_unable_to_exe_linker)] #[note] -#[note(command_note)] +#[note(codegen_ssa_command_note)] pub struct UnableToExeLinker { pub linker_path: PathBuf, pub error: Error, diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 7d51cee307e..ebe9e50ffe6 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -25,7 +25,9 @@ extern crate rustc_middle; use rustc_ast as ast; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::Lrc; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir::def_id::CrateNum; +use rustc_macros::fluent_messages; use rustc_middle::dep_graph::WorkProduct; use rustc_middle::middle::dependency_format::Dependencies; use rustc_middle::middle::exported_symbols::SymbolExportKind; @@ -54,6 +56,8 @@ pub mod mono_item; pub mod target_features; pub mod traits; +fluent_messages! { "../locales/en-US.ftl" } + pub struct ModuleCodegen<M> { /// The name of the module. When the crate may be saved between /// compilations, incremental compilation requires that name be diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index e105322a0b4..f6c1b7a98aa 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -16,7 +16,7 @@ use rustc_index::vec::Idx; use rustc_middle::mir::{self, AssertKind, SwitchTargets}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; -use rustc_middle::ty::{self, Instance, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Instance, Ty, TypeVisitableExt}; use rustc_session::config::OptLevel; use rustc_span::source_map::Span; use rustc_span::{sym, Symbol}; @@ -783,7 +783,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; let extra_args = &args[sig.inputs().skip_binder().len()..]; - let extra_args = bx.tcx().mk_type_list(extra_args.iter().map(|op_arg| { + let extra_args = bx.tcx().mk_type_list_from_iter(extra_args.iter().map(|op_arg| { let op_ty = op_arg.ty(self.mir, bx.tcx()); self.monomorphize(op_ty) })); @@ -1547,7 +1547,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { slot } else { let layout = cx.layout_of( - cx.tcx().intern_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]), + cx.tcx().mk_tup(&[cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().types.i32]), ); let slot = PlaceRef::alloca(bx, layout); self.personality_slot = Some(slot); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index eec91ffa44a..2ec9fdbf44f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -3,7 +3,7 @@ use crate::traits::*; use rustc_middle::mir; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, TyAndLayout}; -use rustc_middle::ty::{self, Instance, Ty, TypeFoldable}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_target::abi::call::{FnAbi, PassMode}; use std::iter; @@ -105,7 +105,7 @@ pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphize<T>(&self, value: T) -> T where - T: Copy + TypeFoldable<'tcx>, + T: Copy + TypeFoldable<TyCtxt<'tcx>>, { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.subst_mir_and_normalize_erasing_regions( diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 41cd1c09a4e..3d856986fb4 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -413,7 +413,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { lhs.layout.ty, ); let val_ty = op.ty(bx.tcx(), lhs.layout.ty, rhs.layout.ty); - let operand_ty = bx.tcx().intern_tup(&[val_ty, bx.tcx().types.bool]); + let operand_ty = bx.tcx().mk_tup(&[val_ty, bx.tcx().types.bool]); OperandRef { val: result, layout: bx.cx().layout_of(operand_ty) } } diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index 5c35070ea66..64bebe50ddb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -57,6 +57,10 @@ impl<'tcx, T> Backend<'tcx> for T where } pub trait CodegenBackend { + /// Locale resources for diagnostic messages - a string the content of the Fluent resource. + /// Called before `init` so that all other functions are able to emit translatable diagnostics. + fn locale_resource(&self) -> &'static str; + fn init(&self, _sess: &Session) {} fn print(&self, _req: PrintRequest, _sess: &Session) {} fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> { diff --git a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl b/compiler/rustc_const_eval/locales/en-US.ftl index 33bb116d6fa..33bb116d6fa 100644 --- a/compiler/rustc_error_messages/locales/en-US/const_eval.ftl +++ b/compiler/rustc_const_eval/locales/en-US.ftl diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index 45f7c756055..7564ba17b40 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -180,7 +180,7 @@ pub(super) fn op_to_const<'tcx>( (ecx.tcx.global_alloc(alloc_id).unwrap_memory(), offset.bytes()) } (None, _offset) => ( - ecx.tcx.intern_const_alloc(Allocation::from_bytes_byte_aligned_immutable( + ecx.tcx.mk_const_alloc(Allocation::from_bytes_byte_aligned_immutable( b"" as &[u8], )), 0, diff --git a/compiler/rustc_const_eval/src/errors.rs b/compiler/rustc_const_eval/src/errors.rs index 4b055076742..f8b7cc6d7e1 100644 --- a/compiler/rustc_const_eval/src/errors.rs +++ b/compiler/rustc_const_eval/src/errors.rs @@ -9,12 +9,12 @@ pub(crate) struct UnstableInStable { #[primary_span] pub span: Span, #[suggestion( - unstable_sugg, + const_eval_unstable_sugg, code = "#[rustc_const_unstable(feature = \"...\", issue = \"...\")]\n", applicability = "has-placeholders" )] #[suggestion( - bypass_sugg, + const_eval_bypass_sugg, code = "#[rustc_allow_const_fn_unstable({gate})]\n", applicability = "has-placeholders" )] @@ -35,15 +35,15 @@ pub(crate) struct StaticAccessErr { #[primary_span] pub span: Span, pub kind: ConstContext, - #[note(teach_note)] - #[help(teach_help)] + #[note(const_eval_teach_note)] + #[help(const_eval_teach_help)] pub teach: Option<()>, } #[derive(Diagnostic)] #[diag(const_eval_raw_ptr_to_int)] #[note] -#[note(note2)] +#[note(const_eval_note2)] pub(crate) struct RawPtrToIntErr { #[primary_span] pub span: Span, @@ -118,7 +118,7 @@ pub(crate) struct UnallowedMutableRefs { #[primary_span] pub span: Span, pub kind: ConstContext, - #[note(teach_note)] + #[note(const_eval_teach_note)] pub teach: Option<()>, } @@ -128,7 +128,7 @@ pub(crate) struct UnallowedMutableRefsRaw { #[primary_span] pub span: Span, pub kind: ConstContext, - #[note(teach_note)] + #[note(const_eval_teach_note)] pub teach: Option<()>, } #[derive(Diagnostic)] @@ -163,7 +163,7 @@ pub(crate) struct UnallowedHeapAllocations { #[label] pub span: Span, pub kind: ConstContext, - #[note(teach_note)] + #[note(const_eval_teach_note)] pub teach: Option<()>, } @@ -184,7 +184,7 @@ pub(crate) struct InteriorMutableDataRefer { #[help] pub opt_help: Option<()>, pub kind: ConstContext, - #[note(teach_note)] + #[note(const_eval_teach_note)] pub teach: Option<()>, } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 24b157054d3..3db102e484d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -489,7 +489,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Call this on things you got out of the MIR (so it is as generic as the current /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_current_frame_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>( + pub(super) fn subst_from_current_frame_and_normalize_erasing_regions< + T: TypeFoldable<TyCtxt<'tcx>>, + >( &self, value: T, ) -> Result<T, InterpError<'tcx>> { @@ -498,7 +500,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Call this on things you got out of the MIR (so it is as generic as the provided /// stack frame), to bring it into the proper environment for this interpreter. - pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<'tcx>>( + pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>( &self, frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>, value: T, diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs index 21ef1836188..b220d21f68b 100644 --- a/compiler/rustc_const_eval/src/interpret/intern.rs +++ b/compiler/rustc_const_eval/src/interpret/intern.rs @@ -135,7 +135,7 @@ fn intern_shallow<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx, const_eval: }; // link the alloc id to the actual allocation leftover_allocations.extend(alloc.provenance().ptrs().iter().map(|&(_, alloc_id)| alloc_id)); - let alloc = tcx.intern_const_alloc(alloc); + let alloc = tcx.mk_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); None } @@ -437,7 +437,7 @@ pub fn intern_const_alloc_recursive< alloc.mutability = Mutability::Not; } } - let alloc = tcx.intern_const_alloc(alloc); + let alloc = tcx.mk_const_alloc(alloc); tcx.set_alloc_id_memory(alloc_id, alloc); for &(_, alloc_id) in alloc.inner().provenance().ptrs().iter() { if leftover_allocations.insert(alloc_id) { @@ -479,6 +479,6 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>> f(self, &dest.into())?; let mut alloc = self.memory.alloc_map.remove(&dest.ptr.provenance.unwrap()).unwrap().1; alloc.mutability = Mutability::Not; - Ok(self.tcx.intern_const_alloc(alloc)) + Ok(self.tcx.mk_const_alloc(alloc)) } } diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index c5d558aeb6c..6e47646caed 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -45,7 +45,7 @@ fn numeric_intrinsic<Prov>(name: Symbol, bits: u128, kind: Primitive) -> Scalar< pub(crate) fn alloc_type_name<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ConstAllocation<'tcx> { let path = crate::util::type_name(tcx, ty); let alloc = Allocation::from_bytes_byte_aligned_immutable(path.into_bytes()); - tcx.intern_const_alloc(alloc) + tcx.mk_const_alloc(alloc) } /// The logic for all nullary intrinsics is implemented here. These intrinsics don't get evaluated diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index f6a3937870e..cf52299b7ba 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -96,7 +96,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let loc_ty = self .tcx .type_of(self.tcx.require_lang_item(LangItem::PanicLocation, None)) - .subst(*self.tcx, self.tcx.intern_substs(&[self.tcx.lifetimes.re_erased.into()])); + .subst(*self.tcx, self.tcx.mk_substs(&[self.tcx.lifetimes.re_erased.into()])); let loc_layout = self.layout_of(loc_ty).unwrap(); let location = self.allocate(loc_layout, MemoryKind::CallerLocation).unwrap(); diff --git a/compiler/rustc_const_eval/src/interpret/operator.rs b/compiler/rustc_const_eval/src/interpret/operator.rs index 422120084d3..4decfe863e6 100644 --- a/compiler/rustc_const_eval/src/interpret/operator.rs +++ b/compiler/rustc_const_eval/src/interpret/operator.rs @@ -19,7 +19,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) -> InterpResult<'tcx> { let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?; debug_assert_eq!( - self.tcx.intern_tup(&[ty, self.tcx.types.bool]), + self.tcx.mk_tup(&[ty, self.tcx.types.bool]), dest.layout.ty, "type mismatch for result of {:?}", op, diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index d934cfbbb84..2aea7c79b6d 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -73,7 +73,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let fn_sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, fn_sig_binder); let extra_args = &args[fn_sig.inputs().len()..]; - let extra_args = self.tcx.mk_type_list(extra_args.iter().map(|arg| arg.layout.ty)); + let extra_args = + self.tcx.mk_type_list_from_iter(extra_args.iter().map(|arg| arg.layout.ty)); let (fn_val, fn_abi, with_caller_location) = match *func.layout.ty.kind() { ty::FnPtr(_sig) => { diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs index 581cb6421f7..bf2b4ee69ab 100644 --- a/compiler/rustc_const_eval/src/interpret/util.rs +++ b/compiler/rustc_const_eval/src/interpret/util.rs @@ -1,5 +1,7 @@ use rustc_middle::mir::interpret::InterpResult; -use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, +}; use std::ops::ControlFlow; /// Checks whether a type contains generic parameters which require substitution. @@ -9,7 +11,7 @@ use std::ops::ControlFlow; /// case these parameters are unused. pub(crate) fn ensure_monomorphic_enough<'tcx, T>(tcx: TyCtxt<'tcx>, ty: T) -> InterpResult<'tcx> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { debug!("ensure_monomorphic_enough: ty={:?}", ty); if !ty.needs_subst() { diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 964efcc9062..fc6d61c79c2 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -34,10 +34,14 @@ pub mod interpret; pub mod transform; pub mod util; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_middle::ty; use rustc_middle::ty::query::Providers; use rustc_target::abi::InitKind; +fluent_messages! { "../locales/en-US.ftl" } + pub fn provide(providers: &mut Providers) { const_eval::provide(providers); providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index faf741de60a..e4366f655e4 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceC use rustc_middle::mir::*; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt}; -use rustc_middle::ty::{Binder, TraitRef, TypeVisitable}; +use rustc_middle::ty::{Binder, TraitRef, TypeVisitableExt}; use rustc_mir_dataflow::{self, Analysis}; use rustc_span::{sym, Span, Symbol}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 19367d708ee..3f3b66b0645 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -18,7 +18,7 @@ use rustc_middle::mir::traversal::ReversePostorderIter; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, List, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use rustc_index::vec::{Idx, IndexVec}; @@ -866,7 +866,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { let mut projection = vec![PlaceElem::Deref]; projection.extend(place.projection); - place.projection = tcx.intern_place_elems(&projection); + place.projection = tcx.mk_place_elems(&projection); // Create a temp to hold the promoted reference. // This is because `*r` requires `r` to be a local, diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 67dbf29da3b..068491646f4 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -13,7 +13,7 @@ use rustc_middle::mir::{ RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, }; -use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -315,7 +315,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } ProjectionElem::Field(f, ty) => { - let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; + let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) }; let parent_ty = parent.ty(&self.body.local_decls, self.tcx); let fail_out_of_bounds = |this: &Self, location| { this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty)); diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 0366fb0a148..decbb6519ba 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -29,8 +29,9 @@ smallvec = { version = "1.8.1", features = [ stable_deref_trait = "1.0.0" stacker = "0.1.15" tempfile = "3.2" -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" +elsa = "1.8" [dependencies.parking_lot] version = "0.11" diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index c8e66eb672c..c4b11951ab7 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -27,7 +27,7 @@ pub struct Sccs<N: Idx, S: Idx> { scc_data: SccData<S>, } -struct SccData<S: Idx> { +pub struct SccData<S: Idx> { /// For each SCC, the range of `all_successors` where its /// successors can be found. ranges: IndexVec<S, Range<usize>>, @@ -43,6 +43,14 @@ impl<N: Idx, S: Idx + Ord> Sccs<N, S> { SccsConstruction::construct(graph) } + pub fn scc_indices(&self) -> &IndexVec<N, S> { + &self.scc_indices + } + + pub fn scc_data(&self) -> &SccData<S> { + &self.scc_data + } + /// Returns the number of SCCs in the graph. pub fn num_sccs(&self) -> usize { self.scc_data.len() @@ -115,6 +123,14 @@ impl<S: Idx> SccData<S> { self.ranges.len() } + pub fn ranges(&self) -> &IndexVec<S, Range<usize>> { + &self.ranges + } + + pub fn all_successors(&self) -> &Vec<S> { + &self.all_successors + } + /// Returns the successors of the given SCC. fn successors(&self, scc: S) -> &[S] { // Annoyingly, `range` does not implement `Copy`, so we have diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index ad71dcdf9d9..31323c21df0 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -26,6 +26,10 @@ use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe}; pub use std::sync::atomic::Ordering; pub use std::sync::atomic::Ordering::SeqCst; +pub use vec::AppendOnlyVec; + +mod vec; + cfg_if! { if #[cfg(not(parallel_compiler))] { pub auto trait Send {} diff --git a/compiler/rustc_data_structures/src/sync/vec.rs b/compiler/rustc_data_structures/src/sync/vec.rs new file mode 100644 index 00000000000..cbea4f05999 --- /dev/null +++ b/compiler/rustc_data_structures/src/sync/vec.rs @@ -0,0 +1,41 @@ +use std::marker::PhantomData; + +use rustc_index::vec::Idx; + +pub struct AppendOnlyVec<I: Idx, T: Copy> { + #[cfg(not(parallel_compiler))] + vec: elsa::vec::FrozenVec<T>, + #[cfg(parallel_compiler)] + vec: elsa::sync::LockFreeFrozenVec<T>, + _marker: PhantomData<fn(&I)>, +} + +impl<I: Idx, T: Copy> AppendOnlyVec<I, T> { + pub fn new() -> Self { + Self { + #[cfg(not(parallel_compiler))] + vec: elsa::vec::FrozenVec::new(), + #[cfg(parallel_compiler)] + vec: elsa::sync::LockFreeFrozenVec::new(), + _marker: PhantomData, + } + } + + pub fn push(&self, val: T) -> I { + #[cfg(not(parallel_compiler))] + let i = self.vec.len(); + #[cfg(not(parallel_compiler))] + self.vec.push(val); + #[cfg(parallel_compiler)] + let i = self.vec.push(val); + I::new(i) + } + + pub fn get(&self, i: I) -> Option<T> { + let i = i.index(); + #[cfg(not(parallel_compiler))] + return self.vec.get_copy(i); + #[cfg(parallel_compiler)] + return self.vec.get(i); + } +} diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index cdec4f91277..7b59a52cffe 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -9,6 +9,27 @@ edition = "2021" tracing = { version = "0.1.35" } serde_json = "1.0.59" rustc_log = { path = "../rustc_log" } +rustc_ast_lowering = { path = "../rustc_ast_lowering" } +rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_attr = { path = "../rustc_attr" } +rustc_borrowck = { path = "../rustc_borrowck" } +rustc_builtin_macros = { path = "../rustc_builtin_macros" } +rustc_const_eval = { path = "../rustc_const_eval" } +rustc_error_messages = { path = "../rustc_error_messages" } +rustc_expand = { path = "../rustc_expand" } +rustc_hir_typeck = { path = "../rustc_hir_typeck" } +rustc_incremental = { path = "../rustc_incremental" } +rustc_infer = { path = "../rustc_infer" } +rustc_mir_build = { path = "../rustc_mir_build" } +rustc_mir_dataflow = { path = "../rustc_mir_dataflow" } +rustc_monomorphize = { path = "../rustc_monomorphize" } +rustc_passes = { path = "../rustc_passes" } +rustc_privacy = { path = "../rustc_privacy" } +rustc_query_system = { path = "../rustc_query_system" } +rustc_resolve = { path = "../rustc_resolve" } +rustc_symbol_mangling = { path = "../rustc_symbol_mangling" } +rustc_trait_selection = { path = "../rustc_trait_selection" } +rustc_ty_utils = { path = "../rustc_ty_utils" } rustc_middle = { path = "../rustc_middle" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_error_messages/locales/en-US/driver.ftl b/compiler/rustc_driver_impl/locales/en-US.ftl index f19b1ff6426..f19b1ff6426 100644 --- a/compiler/rustc_error_messages/locales/en-US/driver.ftl +++ b/compiler/rustc_driver_impl/locales/en-US.ftl diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index d7e9e00f3b6..464ddae476a 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -23,11 +23,14 @@ use rustc_codegen_ssa::{traits::CodegenBackend, CodegenErrors, CodegenResults}; use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry}; use rustc_data_structures::sync::SeqCst; use rustc_errors::registry::{InvalidErrorCode, Registry}; -use rustc_errors::{ErrorGuaranteed, PResult, TerminalUrl}; +use rustc_errors::{ + DiagnosticMessage, ErrorGuaranteed, PResult, SubdiagnosticMessage, TerminalUrl, +}; use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; +use rustc_macros::fluent_messages; use rustc_metadata::locator; use rustc_session::config::{nightly_options, CG_OPTIONS, Z_OPTIONS}; use rustc_session::config::{ErrorOutputType, Input, OutputType, PrintRequest, TrimmedDefPaths}; @@ -61,6 +64,44 @@ use crate::session_diagnostics::{ RLinkWrongFileType, RlinkNotAFile, RlinkUnableToRead, }; +fluent_messages! { "../locales/en-US.ftl" } + +pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ + // tidy-alphabetical-start + crate::DEFAULT_LOCALE_RESOURCE, + rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE, + rustc_ast_passes::DEFAULT_LOCALE_RESOURCE, + rustc_attr::DEFAULT_LOCALE_RESOURCE, + rustc_borrowck::DEFAULT_LOCALE_RESOURCE, + rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE, + rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE, + rustc_const_eval::DEFAULT_LOCALE_RESOURCE, + rustc_error_messages::DEFAULT_LOCALE_RESOURCE, + rustc_expand::DEFAULT_LOCALE_RESOURCE, + rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE, + rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE, + rustc_incremental::DEFAULT_LOCALE_RESOURCE, + rustc_infer::DEFAULT_LOCALE_RESOURCE, + rustc_interface::DEFAULT_LOCALE_RESOURCE, + rustc_lint::DEFAULT_LOCALE_RESOURCE, + rustc_metadata::DEFAULT_LOCALE_RESOURCE, + rustc_middle::DEFAULT_LOCALE_RESOURCE, + rustc_mir_build::DEFAULT_LOCALE_RESOURCE, + rustc_mir_dataflow::DEFAULT_LOCALE_RESOURCE, + rustc_monomorphize::DEFAULT_LOCALE_RESOURCE, + rustc_parse::DEFAULT_LOCALE_RESOURCE, + rustc_passes::DEFAULT_LOCALE_RESOURCE, + rustc_plugin_impl::DEFAULT_LOCALE_RESOURCE, + rustc_privacy::DEFAULT_LOCALE_RESOURCE, + rustc_query_system::DEFAULT_LOCALE_RESOURCE, + rustc_resolve::DEFAULT_LOCALE_RESOURCE, + rustc_session::DEFAULT_LOCALE_RESOURCE, + rustc_symbol_mangling::DEFAULT_LOCALE_RESOURCE, + rustc_trait_selection::DEFAULT_LOCALE_RESOURCE, + rustc_ty_utils::DEFAULT_LOCALE_RESOURCE, + // tidy-alphabetical-end +]; + /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -218,6 +259,7 @@ fn run_compiler( output_file: ofile, output_dir: odir, file_loader, + locale_resources: DEFAULT_LOCALE_RESOURCES, lint_caps: Default::default(), parse_sess_created: None, register_lints: None, @@ -443,7 +485,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { let normalised = if upper_cased_code.starts_with('E') { upper_cased_code } else { format!("E{code:0>4}") }; match registry.try_find_description(&normalised) { - Ok(Some(description)) => { + Ok(description) => { let mut is_in_code_block = false; let mut text = String::new(); // Slice off the leading newline and print. @@ -467,9 +509,6 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { print!("{text}"); } } - Ok(None) => { - early_error(output, &format!("no extended information for {code}")); - } Err(InvalidErrorCode) => { early_error(output, &format!("{code} is not a valid error code")); } @@ -1162,7 +1201,7 @@ static DEFAULT_HOOK: LazyLock<Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + /// hook. pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + rustc_errors::fallback_fluent_bundle(crate::DEFAULT_LOCALE_RESOURCES.to_vec(), false); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index 800f3c52177..df857be85ad 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -253,6 +253,7 @@ E0466: include_str!("./error_codes/E0466.md"), E0468: include_str!("./error_codes/E0468.md"), E0469: include_str!("./error_codes/E0469.md"), E0472: include_str!("./error_codes/E0472.md"), +E0476: include_str!("./error_codes/E0476.md"), E0477: include_str!("./error_codes/E0477.md"), E0478: include_str!("./error_codes/E0478.md"), E0482: include_str!("./error_codes/E0482.md"), @@ -512,7 +513,9 @@ E0790: include_str!("./error_codes/E0790.md"), E0791: include_str!("./error_codes/E0791.md"), E0792: include_str!("./error_codes/E0792.md"), E0793: include_str!("./error_codes/E0793.md"), -; +} + +// Undocumented removed error codes. Note that many removed error codes are documented. // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard // E0019, // merged into E0015 @@ -569,7 +572,7 @@ E0793: include_str!("./error_codes/E0793.md"), // E0246, // invalid recursive type // E0247, // E0248, // value used as a type, now reported earlier during resolution - // as E0412 +// // as E0412 // E0249, // E0257, // E0258, @@ -611,7 +614,6 @@ E0793: include_str!("./error_codes/E0793.md"), // E0473, // dereference of reference outside its lifetime // E0474, // captured variable `..` does not outlive the enclosing closure // E0475, // index of slice outside its lifetime - E0476, // lifetime of the source pointer does not outlive lifetime bound... // E0479, // the type `..` (provided as the value of a type parameter) is... // E0480, // lifetime of method receiver does not outlive the method call // E0481, // lifetime of function argument does not outlive the function call @@ -631,14 +633,14 @@ E0793: include_str!("./error_codes/E0793.md"), // E0558, // replaced with a generic attribute input check // E0563, // cannot determine a type for this `impl Trait` removed in 6383de15 // E0564, // only named lifetimes are allowed in `impl Trait`, - // but `{}` was found in the type `{}` +// // but `{}` was found in the type `{}` // E0598, // lifetime of {} is too short to guarantee its contents can be... // E0611, // merged into E0616 // E0612, // merged into E0609 // E0613, // Removed (merged with E0609) // E0629, // missing 'feature' (rustc_const_unstable) // E0630, // rustc_const_unstable attribute must be paired with stable/unstable - // attribute +// // attribute // E0645, // trait aliases not finished // E0694, // an unknown tool name found in scoped attributes // E0702, // replaced with a generic attribute input check @@ -647,4 +649,3 @@ E0793: include_str!("./error_codes/E0793.md"), // E0721, // `await` keyword // E0723, // unstable feature in `const` context // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. -} diff --git a/compiler/rustc_error_codes/src/error_codes/E0476.md b/compiler/rustc_error_codes/src/error_codes/E0476.md new file mode 100644 index 00000000000..fc141ba77f5 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0476.md @@ -0,0 +1,21 @@ +The coerced type does not outlive the value being coerced to. + +Example of erroneous code: + +```compile_fail,E0476 +#![feature(coerce_unsized)] +#![feature(unsize)] + +use std::marker::Unsize; +use std::ops::CoerceUnsized; + +// error: lifetime of the source pointer does not outlive lifetime bound of the +// object type +impl<'a, 'b, T, S> CoerceUnsized<&'a T> for &'b S where S: Unsize<T> {} +``` + +During a coercion, the "source pointer" (the coerced type) did not outlive the +"object type" (value being coerced to). In the above example, `'b` is not a +subtype of `'a`. This error can currently only be encountered with the unstable +`CoerceUnsized` trait which allows custom coercions of unsized types behind a +smart pointer to be implemented. diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs index bd424dd9d06..d6b120e4dfc 100644 --- a/compiler/rustc_error_codes/src/lib.rs +++ b/compiler/rustc_error_codes/src/lib.rs @@ -5,10 +5,9 @@ //! the goal being to make their maintenance easier. macro_rules! register_diagnostics { - ($($ecode:ident: $message:expr,)* ; $($code:ident,)*) => ( - pub static DIAGNOSTICS: &[(&str, Option<&str>)] = &[ - $( (stringify!($ecode), Some($message)), )* - $( (stringify!($code), None), )* + ($($ecode:ident: $message:expr,)*) => ( + pub static DIAGNOSTICS: &[(&str, &str)] = &[ + $( (stringify!($ecode), $message), )* ]; ) } diff --git a/compiler/rustc_error_messages/locales/en-US.ftl b/compiler/rustc_error_messages/locales/en-US.ftl new file mode 100644 index 00000000000..e6292374448 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US.ftl @@ -0,0 +1 @@ +# satisfy tidy lint by having a line in this file diff --git a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl b/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl deleted file mode 100644 index 5f28839f136..00000000000 --- a/compiler/rustc_error_messages/locales/en-US/ast_passes.ftl +++ /dev/null @@ -1,92 +0,0 @@ -ast_passes_forbidden_let = - `let` expressions are not supported here - .note = only supported directly in conditions of `if` and `while` expressions - .not_supported_or = `||` operators are not supported in let chain expressions - .not_supported_parentheses = `let`s wrapped in parentheses are not supported in a context with let chains - -ast_passes_forbidden_let_stable = - expected expression, found statement (`let`) - .note = variable declaration using `let` is a statement - -ast_passes_deprecated_where_clause_location = - where clause not allowed here - -ast_passes_forbidden_assoc_constraint = - associated type bounds are not allowed within structs, enums, or unions - -ast_passes_keyword_lifetime = - lifetimes cannot use keyword names - -ast_passes_invalid_label = - invalid label name `{$name}` - -ast_passes_invalid_visibility = - unnecessary visibility qualifier - .implied = `pub` not permitted here because it's implied - .individual_impl_items = place qualifiers on individual impl items instead - .individual_foreign_items = place qualifiers on individual foreign items instead - -ast_passes_trait_fn_const = - functions in traits cannot be declared const - .label = functions in traits cannot be const - -ast_passes_forbidden_lifetime_bound = - lifetime bounds cannot be used in this context - -ast_passes_forbidden_non_lifetime_param = - only lifetime parameters can be used in this context - -ast_passes_fn_param_too_many = - function can not have more than {$max_num_args} arguments - -ast_passes_fn_param_c_var_args_only = - C-variadic function must be declared with at least one named argument - -ast_passes_fn_param_c_var_args_not_last = - `...` must be the last argument of a C-variadic function - -ast_passes_fn_param_doc_comment = - documentation comments cannot be applied to function parameters - .label = doc comments are not allowed here - -ast_passes_fn_param_forbidden_attr = - allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters - -ast_passes_fn_param_forbidden_self = - `self` parameter is only allowed in associated functions - .label = not semantically valid as function parameter - .note = associated functions are those in `impl` or `trait` definitions - -ast_passes_forbidden_default = - `default` is only allowed on items in trait impls - .label = `default` because of this - -ast_passes_assoc_const_without_body = - associated constant in `impl` without body - .suggestion = provide a definition for the constant - -ast_passes_assoc_fn_without_body = - associated function in `impl` without body - .suggestion = provide a definition for the function - -ast_passes_assoc_type_without_body = - associated type in `impl` without body - .suggestion = provide a definition for the type - -ast_passes_const_without_body = - free constant item without body - .suggestion = provide a definition for the constant - -ast_passes_static_without_body = - free static item without body - .suggestion = provide a definition for the static - -ast_passes_ty_alias_without_body = - free type alias without body - .suggestion = provide a definition for the type - -ast_passes_fn_without_body = - free function without a body - .suggestion = provide a definition for the function - -ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block diff --git a/compiler/rustc_error_messages/locales/en-US/errors.ftl b/compiler/rustc_error_messages/locales/en-US/errors.ftl deleted file mode 100644 index 429bdd2777f..00000000000 --- a/compiler/rustc_error_messages/locales/en-US/errors.ftl +++ /dev/null @@ -1,13 +0,0 @@ -errors_target_invalid_address_space = invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err} - -errors_target_invalid_bits = invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err} - -errors_target_missing_alignment = missing alignment for `{$cause}` in "data-layout" - -errors_target_invalid_alignment = invalid alignment for `{$cause}` in "data-layout": {$err} - -errors_target_inconsistent_architecture = inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}` - -errors_target_inconsistent_pointer_width = inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}` - -errors_target_invalid_bits_size = {$err} diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 579466ed366..010e5f060bf 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -34,47 +34,7 @@ use intl_memoizer::IntlLangMemoizer; pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue}; pub use unic_langid::{langid, LanguageIdentifier}; -// Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. -fluent_messages! { - // tidy-alphabetical-start - ast_lowering => "../locales/en-US/ast_lowering.ftl", - ast_passes => "../locales/en-US/ast_passes.ftl", - attr => "../locales/en-US/attr.ftl", - borrowck => "../locales/en-US/borrowck.ftl", - builtin_macros => "../locales/en-US/builtin_macros.ftl", - codegen_gcc => "../locales/en-US/codegen_gcc.ftl", - codegen_llvm => "../locales/en-US/codegen_llvm.ftl", - codegen_ssa => "../locales/en-US/codegen_ssa.ftl", - compiletest => "../locales/en-US/compiletest.ftl", - const_eval => "../locales/en-US/const_eval.ftl", - driver => "../locales/en-US/driver.ftl", - errors => "../locales/en-US/errors.ftl", - expand => "../locales/en-US/expand.ftl", - hir_analysis => "../locales/en-US/hir_analysis.ftl", - hir_typeck => "../locales/en-US/hir_typeck.ftl", - incremental => "../locales/en-US/incremental.ftl", - infer => "../locales/en-US/infer.ftl", - interface => "../locales/en-US/interface.ftl", - lint => "../locales/en-US/lint.ftl", - metadata => "../locales/en-US/metadata.ftl", - middle => "../locales/en-US/middle.ftl", - mir_build => "../locales/en-US/mir_build.ftl", - mir_dataflow => "../locales/en-US/mir_dataflow.ftl", - monomorphize => "../locales/en-US/monomorphize.ftl", - parse => "../locales/en-US/parse.ftl", - passes => "../locales/en-US/passes.ftl", - plugin_impl => "../locales/en-US/plugin_impl.ftl", - privacy => "../locales/en-US/privacy.ftl", - query_system => "../locales/en-US/query_system.ftl", - resolve => "../locales/en-US/resolve.ftl", - session => "../locales/en-US/session.ftl", - symbol_mangling => "../locales/en-US/symbol_mangling.ftl", - trait_selection => "../locales/en-US/trait_selection.ftl", - ty_utils => "../locales/en-US/ty_utils.ftl", - // tidy-alphabetical-end -} - -pub use fluent_generated::{self as fluent, DEFAULT_LOCALE_RESOURCES}; +fluent_messages! { "../locales/en-US.ftl" } pub type FluentBundle = fluent_bundle::bundle::FluentBundle<FluentResource, IntlLangMemoizer>; @@ -175,7 +135,10 @@ pub fn fluent_bundle( let fallback_locale = langid!("en-US"); let requested_fallback_locale = requested_locale.as_ref() == Some(&fallback_locale); - + trace!(?requested_fallback_locale); + if requested_fallback_locale && additional_ftl_path.is_none() { + return Ok(None); + } // If there is only `-Z additional-ftl-path`, assume locale is "en-US", otherwise use user // provided locale. let locale = requested_locale.clone().unwrap_or(fallback_locale); @@ -193,7 +156,7 @@ pub fn fluent_bundle( bundle.set_use_isolating(with_directionality_markers); // If the user requests the default locale then don't try to load anything. - if !requested_fallback_locale && let Some(requested_locale) = requested_locale { + if let Some(requested_locale) = requested_locale { let mut found_resources = false; for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) { sysroot.push("share"); @@ -263,7 +226,7 @@ pub type LazyFallbackBundle = Lrc<Lazy<FluentBundle, impl FnOnce() -> FluentBund /// Return the default `FluentBundle` with standard "en-US" diagnostic messages. #[instrument(level = "trace")] pub fn fallback_fluent_bundle( - resources: &'static [&'static str], + resources: Vec<&'static str>, with_directionality_markers: bool, ) -> LazyFallbackBundle { Lrc::new(Lazy::new(move || { diff --git a/compiler/rustc_errors/locales/en-US.ftl b/compiler/rustc_errors/locales/en-US.ftl new file mode 100644 index 00000000000..dde1d6c0a81 --- /dev/null +++ b/compiler/rustc_errors/locales/en-US.ftl @@ -0,0 +1,19 @@ +errors_target_invalid_address_space = + invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err} + +errors_target_invalid_bits = + invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err} + +errors_target_missing_alignment = + missing alignment for `{$cause}` in "data-layout" + +errors_target_invalid_alignment = + invalid alignment for `{$cause}` in "data-layout": {$err} + +errors_target_inconsistent_architecture = + inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}` + +errors_target_inconsistent_pointer_width = + inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}` + +errors_target_invalid_bits_size = {$err} diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 5ada85d04b0..e82bad67b21 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -1,6 +1,5 @@ -use crate::{ - fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg, -}; +use crate::fluent_generated as fluent; +use crate::{DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg}; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_hir as hir; @@ -55,6 +54,7 @@ macro_rules! into_diagnostic_arg_using_display { } into_diagnostic_arg_using_display!( + ast::ParamKindOrd, i8, u8, i16, diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index e475fc725c3..f32d6b96b9b 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -580,7 +580,7 @@ impl DiagnosticCode { let je_result = je.registry.as_ref().map(|registry| registry.try_find_description(&s)).unwrap(); - DiagnosticCode { code: s, explanation: je_result.unwrap_or(None) } + DiagnosticCode { code: s, explanation: je_result.ok() } }) } } diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index f161532d3b7..671dc449eaa 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -46,7 +46,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); sm.new_source_file(Path::new("test.rs").to_owned().into(), code.to_owned()); let fallback_bundle = - crate::fallback_fluent_bundle(rustc_error_messages::DEFAULT_LOCALE_RESOURCES, false); + crate::fallback_fluent_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false); let output = Arc::new(Mutex::new(Vec::new())); let je = JsonEmitter::new( diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8c39feca88a..cbf595089cc 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -36,13 +36,13 @@ use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, + fallback_fluent_bundle, fluent_bundle, DelayDm, DiagnosticMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagnosticMessage, - DEFAULT_LOCALE_RESOURCES, }; pub use rustc_lint_defs::{pluralize, Applicability}; +use rustc_macros::fluent_messages; use rustc_span::source_map::SourceMap; -use rustc_span::HashStableContext; +pub use rustc_span::ErrorGuaranteed; use rustc_span::{Loc, Span}; use std::borrow::Cow; @@ -76,6 +76,8 @@ pub use snippet::Style; pub type PErr<'a> = DiagnosticBuilder<'a, ErrorGuaranteed>; pub type PResult<'a, T> = Result<T, PErr<'a>>; +fluent_messages! { "../locales/en-US.ftl" } + // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger. // (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.) #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] @@ -1475,9 +1477,7 @@ impl HandlerInner { .emitted_diagnostic_codes .iter() .filter_map(|x| match &x { - DiagnosticId::Error(s) - if registry.try_find_description(s).map_or(false, |o| o.is_some()) => - { + DiagnosticId::Error(s) if registry.try_find_description(s).is_ok() => { Some(s.clone()) } _ => None, @@ -1844,17 +1844,3 @@ pub enum TerminalUrl { Yes, Auto, } - -/// Useful type to use with `Result<>` indicate that an error has already -/// been reported to the user, so no need to continue checking. -#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)] -#[derive(HashStable_Generic)] -pub struct ErrorGuaranteed(()); - -impl ErrorGuaranteed { - /// To be used only if you really know what you are doing... ideally, we would find a way to - /// eliminate all calls to this method. - pub fn unchecked_claim_error_was_emitted() -> Self { - ErrorGuaranteed(()) - } -} diff --git a/compiler/rustc_errors/src/registry.rs b/compiler/rustc_errors/src/registry.rs index da764d993bb..f26d8e7ebdc 100644 --- a/compiler/rustc_errors/src/registry.rs +++ b/compiler/rustc_errors/src/registry.rs @@ -5,21 +5,17 @@ pub struct InvalidErrorCode; #[derive(Clone)] pub struct Registry { - long_descriptions: FxHashMap<&'static str, Option<&'static str>>, + long_descriptions: FxHashMap<&'static str, &'static str>, } impl Registry { - pub fn new(long_descriptions: &[(&'static str, Option<&'static str>)]) -> Registry { + pub fn new(long_descriptions: &[(&'static str, &'static str)]) -> Registry { Registry { long_descriptions: long_descriptions.iter().copied().collect() } } /// Returns `InvalidErrorCode` if the code requested does not exist in the - /// registry. Otherwise, returns an `Option` where `None` means the error - /// code is valid but has no extended information. - pub fn try_find_description( - &self, - code: &str, - ) -> Result<Option<&'static str>, InvalidErrorCode> { + /// registry. + pub fn try_find_description(&self, code: &str) -> Result<&'static str, InvalidErrorCode> { self.long_descriptions.get(code).copied().ok_or(InvalidErrorCode) } } diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index addfc9726ca..ed35eb1b6c4 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -1,9 +1,10 @@ -use crate::error::TranslateError; +use crate::error::{TranslateError, TranslateErrorKind}; use crate::snippet::Style; use crate::{DiagnosticArg, DiagnosticMessage, FluentBundle}; use rustc_data_structures::sync::Lrc; use rustc_error_messages::FluentArgs; use std::borrow::Cow; +use std::env; use std::error::Report; /// Convert diagnostic arguments (a rustc internal type that exists to implement @@ -94,12 +95,29 @@ pub trait Translate { // The primary bundle was present and translation succeeded Some(Ok(t)) => t, - // Always yeet out for errors on debug - Some(Err(primary)) if cfg!(debug_assertions) => do yeet primary, - // If `translate_with_bundle` returns `Err` with the primary bundle, this is likely - // just that the primary bundle doesn't contain the message being translated or - // something else went wrong) so proceed to the fallback bundle. + // just that the primary bundle doesn't contain the message being translated, so + // proceed to the fallback bundle. + Some(Err( + primary @ TranslateError::One { + kind: TranslateErrorKind::MessageMissing, .. + }, + )) => translate_with_bundle(self.fallback_fluent_bundle()) + .map_err(|fallback| primary.and(fallback))?, + + // Always yeet out for errors on debug (unless + // `RUSTC_TRANSLATION_NO_DEBUG_ASSERT` is set in the environment - this allows + // local runs of the test suites, of builds with debug assertions, to test the + // behaviour in a normal build). + Some(Err(primary)) + if cfg!(debug_assertions) + && env::var("RUSTC_TRANSLATION_NO_DEBUG_ASSERT").is_err() => + { + do yeet primary + } + + // ..otherwise, for end users, an error about this wouldn't be useful or actionable, so + // just hide it and try with the fallback bundle. Some(Err(primary)) => translate_with_bundle(self.fallback_fluent_bundle()) .map_err(|fallback| primary.and(fallback))?, diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 192f54171ce..c971714e05b 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -24,5 +24,5 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/expand.ftl b/compiler/rustc_expand/locales/en-US.ftl index dbd80954382..b475d285f6b 100644 --- a/compiler/rustc_error_messages/locales/en-US/expand.ftl +++ b/compiler/rustc_expand/locales/en-US.ftl @@ -129,3 +129,7 @@ expand_module_multiple_candidates = .help = delete or rename one of them to remove the ambiguity expand_trace_macro = trace_macro + +expand_proc_macro_panicked = + proc macro panicked + .help = message: {$message} diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 00c5fe791f9..22bc90f5cac 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -29,10 +29,11 @@ use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, FileName, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; - +use std::default::Default; use std::iter; use std::path::{Path, PathBuf}; use std::rc::Rc; +use thin_vec::ThinVec; pub(crate) use rustc_span::hygiene::MacroKind; @@ -554,7 +555,7 @@ impl DummyResult { pub fn raw_expr(sp: Span, is_error: bool) -> P<ast::Expr> { P(ast::Expr { id: ast::DUMMY_NODE_ID, - kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(Vec::new()) }, + kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(ThinVec::new()) }, span: sp, attrs: ast::AttrVec::new(), tokens: None, @@ -570,7 +571,7 @@ impl DummyResult { pub fn raw_ty(sp: Span, is_error: bool) -> P<ast::Ty> { P(ast::Ty { id: ast::DUMMY_NODE_ID, - kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(Vec::new()) }, + kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(ThinVec::new()) }, span: sp, tokens: None, }) diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index b4c12651e7a..8a78c3296f9 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -5,7 +5,7 @@ use rustc_ast::{attr, token, util::literal}; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; impl<'a> ExtCtxt<'a> { pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path { @@ -125,7 +125,7 @@ impl<'a> ExtCtxt<'a> { pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { - bound_generic_params: Vec::new(), + bound_generic_params: ThinVec::new(), trait_ref: self.trait_ref(path), span, } @@ -221,14 +221,14 @@ impl<'a> ExtCtxt<'a> { pub fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> { self.block( expr.span, - vec![ast::Stmt { + thin_vec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, kind: ast::StmtKind::Expr(expr), }], ) } - pub fn block(&self, span: Span, stmts: Vec<ast::Stmt>) -> P<ast::Block> { + pub fn block(&self, span: Span, stmts: ThinVec<ast::Stmt>) -> P<ast::Block> { P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, @@ -284,18 +284,23 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, expr: P<ast::Expr>, - args: Vec<P<ast::Expr>>, + args: ThinVec<P<ast::Expr>>, ) -> P<ast::Expr> { self.expr(span, ast::ExprKind::Call(expr, args)) } - pub fn expr_call_ident(&self, span: Span, id: Ident, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_call_ident( + &self, + span: Span, + id: Ident, + args: ThinVec<P<ast::Expr>>, + ) -> P<ast::Expr> { self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) } pub fn expr_call_global( &self, sp: Span, fn_path: Vec<Ident>, - args: Vec<P<ast::Expr>>, + args: ThinVec<P<ast::Expr>>, ) -> P<ast::Expr> { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) @@ -318,7 +323,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - fields: Vec<ast::ExprField>, + fields: ThinVec<ast::ExprField>, ) -> P<ast::Expr> { self.expr( span, @@ -334,7 +339,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, id: Ident, - fields: Vec<ast::ExprField>, + fields: ThinVec<ast::ExprField>, ) -> P<ast::Expr> { self.expr_struct(span, self.path_ident(span, id), fields) } @@ -372,12 +377,12 @@ impl<'a> ExtCtxt<'a> { } /// `[expr1, expr2, ...]` - pub fn expr_array(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_array(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr(sp, ast::ExprKind::Array(exprs)) } /// `&[expr1, expr2, ...]` - pub fn expr_array_ref(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_array_ref(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr_addr_of(sp, self.expr_array(sp, exprs)) } @@ -387,14 +392,14 @@ impl<'a> ExtCtxt<'a> { pub fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); - self.expr_call_global(sp, some, vec![expr]) + self.expr_call_global(sp, some, thin_vec![expr]) } pub fn expr_none(&self, sp: Span) -> P<ast::Expr> { let none = self.std_path(&[sym::option, sym::Option, sym::None]); self.expr_path(self.path_global(sp, none)) } - pub fn expr_tuple(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> { + pub fn expr_tuple(&self, sp: Span, exprs: ThinVec<P<ast::Expr>>) -> P<ast::Expr> { self.expr(sp, ast::ExprKind::Tup(exprs)) } @@ -402,7 +407,7 @@ impl<'a> ExtCtxt<'a> { self.expr_call_global( span, [sym::std, sym::rt, sym::begin_panic].iter().map(|s| Ident::new(*s, span)).collect(), - vec![self.expr_str(span, msg)], + thin_vec![self.expr_str(span, msg)], ) } @@ -412,7 +417,7 @@ impl<'a> ExtCtxt<'a> { pub fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); - self.expr_call_global(sp, ok, vec![expr]) + self.expr_call_global(sp, ok, thin_vec![expr]) } pub fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> { @@ -426,12 +431,12 @@ impl<'a> ExtCtxt<'a> { let binding_expr = self.expr_ident(sp, binding_variable); // `Ok(__try_var)` pattern - let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); + let ok_pat = self.pat_tuple_struct(sp, ok_path, thin_vec![binding_pat.clone()]); // `Err(__try_var)` (pattern and expression respectively) - let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); + let err_pat = self.pat_tuple_struct(sp, err_path.clone(), thin_vec![binding_pat]); let err_inner_expr = - self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); + self.expr_call(sp, self.expr_path(err_path), thin_vec![binding_expr.clone()]); // `return Err(__try_var)` let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); @@ -441,7 +446,7 @@ impl<'a> ExtCtxt<'a> { let err_arm = self.arm(sp, err_pat, err_expr); // `match head { Ok() => ..., Err() => ... }` - self.expr_match(sp, head, vec![ok_arm, err_arm]) + self.expr_match(sp, head, thin_vec![ok_arm, err_arm]) } pub fn pat(&self, span: Span, kind: PatKind) -> P<ast::Pat> { @@ -473,7 +478,7 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - subpats: Vec<P<ast::Pat>>, + subpats: ThinVec<P<ast::Pat>>, ) -> P<ast::Pat> { self.pat(span, PatKind::TupleStruct(None, path, subpats)) } @@ -481,18 +486,18 @@ impl<'a> ExtCtxt<'a> { &self, span: Span, path: ast::Path, - field_pats: Vec<ast::PatField>, + field_pats: ThinVec<ast::PatField>, ) -> P<ast::Pat> { self.pat(span, PatKind::Struct(None, path, field_pats, false)) } - pub fn pat_tuple(&self, span: Span, pats: Vec<P<ast::Pat>>) -> P<ast::Pat> { + pub fn pat_tuple(&self, span: Span, pats: ThinVec<P<ast::Pat>>) -> P<ast::Pat> { self.pat(span, PatKind::Tuple(pats)) } pub fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); let path = self.path_global(span, some); - self.pat_tuple_struct(span, path, vec![pat]) + self.pat_tuple_struct(span, path, thin_vec![pat]) } pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm { @@ -511,7 +516,7 @@ impl<'a> ExtCtxt<'a> { self.arm(span, self.pat_wild(span), self.expr_unreachable(span)) } - pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: Vec<ast::Arm>) -> P<Expr> { + pub fn expr_match(&self, span: Span, arg: P<ast::Expr>, arms: ThinVec<ast::Arm>) -> P<Expr> { self.expr(span, ast::ExprKind::Match(arg, arms)) } @@ -562,7 +567,12 @@ impl<'a> ExtCtxt<'a> { self.lambda(span, vec![ident], body) } - pub fn lambda_stmts_1(&self, span: Span, stmts: Vec<ast::Stmt>, ident: Ident) -> P<ast::Expr> { + pub fn lambda_stmts_1( + &self, + span: Span, + stmts: ThinVec<ast::Stmt>, + ident: Ident, + ) -> P<ast::Expr> { self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) } @@ -579,7 +589,7 @@ impl<'a> ExtCtxt<'a> { } // `self` is unused but keep it as method for the convenience use. - pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { + pub fn fn_decl(&self, inputs: ThinVec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> { P(ast::FnDecl { inputs, output }) } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 5c845ae6d0b..01500c2c77c 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -24,6 +24,7 @@ use rustc_session::Session; use rustc_span::edition::{Edition, ALL_EDITIONS}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use thin_vec::ThinVec; /// A folder that strips out items that do not belong in the current configuration. pub struct StripUnconfigured<'a> { @@ -206,7 +207,7 @@ pub fn features( None => { // The entire crate is unconfigured. krate.attrs = ast::AttrVec::new(); - krate.items = Vec::new(); + krate.items = ThinVec::new(); Features::default() } Some(attrs) => { diff --git a/compiler/rustc_expand/src/errors.rs b/compiler/rustc_expand/src/errors.rs index 9b9697ab13d..70ab222b484 100644 --- a/compiler/rustc_expand/src/errors.rs +++ b/compiler/rustc_expand/src/errors.rs @@ -65,7 +65,7 @@ pub(crate) struct MacroConstStability { #[primary_span] #[label] pub span: Span, - #[label(label2)] + #[label(expand_label2)] pub head_span: Span, } @@ -75,7 +75,7 @@ pub(crate) struct MacroBodyStability { #[primary_span] #[label] pub span: Span, - #[label(label2)] + #[label(expand_label2)] pub head_span: Span, } @@ -188,7 +188,7 @@ pub(crate) struct FeatureRemoved<'a> { } #[derive(Subdiagnostic)] -#[note(reason)] +#[note(expand_reason)] pub(crate) struct FeatureRemovedReason<'a> { pub reason: &'a str, } @@ -223,12 +223,12 @@ pub(crate) struct MalformedFeatureAttribute { #[derive(Subdiagnostic)] pub(crate) enum MalformedFeatureAttributeHelp { - #[label(expected)] + #[label(expand_expected)] Label { #[primary_span] span: Span, }, - #[suggestion(expected, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")] Suggestion { #[primary_span] span: Span, @@ -306,7 +306,7 @@ pub(crate) struct IncompleteParse<'a> { pub kind_name: &'a str, #[suggestion( - suggestion_add_semi, + expand_suggestion_add_semi, style = "verbose", code = ";", applicability = "maybe-incorrect" @@ -340,7 +340,7 @@ pub(crate) struct ModuleInBlock { } #[derive(Subdiagnostic)] -#[note(note)] +#[note(expand_note)] pub(crate) struct ModuleInBlockName { #[primary_span] pub span: Span, @@ -375,3 +375,18 @@ pub struct TraceMacro { #[primary_span] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(expand_proc_macro_panicked)] +pub(crate) struct ProcMacroPanicked { + #[primary_span] + pub span: Span, + #[subdiagnostic] + pub message: Option<ProcMacroPanickedHelp>, +} + +#[derive(Subdiagnostic)] +#[help(expand_help)] +pub(crate) struct ProcMacroPanickedHelp { + pub message: String, +} diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs index 89726856635..634e206e58a 100644 --- a/compiler/rustc_expand/src/lib.rs +++ b/compiler/rustc_expand/src/lib.rs @@ -20,6 +20,9 @@ extern crate tracing; extern crate proc_macro as pm; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + mod placeholders; mod proc_macro_server; @@ -60,3 +63,5 @@ mod tokenstream { mod mut_visit { mod tests; } + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_expand/src/module.rs b/compiler/rustc_expand/src/module.rs index 07f47a9c3a4..3779af19e12 100644 --- a/compiler/rustc_expand/src/module.rs +++ b/compiler/rustc_expand/src/module.rs @@ -12,8 +12,8 @@ use rustc_session::Session; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; use std::iter::once; - use std::path::{self, Path, PathBuf}; +use thin_vec::ThinVec; #[derive(Copy, Clone)] pub enum DirOwnership { @@ -31,7 +31,7 @@ pub struct ModulePathSuccess { } pub(crate) struct ParsedExternalMod { - pub items: Vec<P<Item>>, + pub items: ThinVec<P<Item>>, pub spans: ModSpans, pub file_path: PathBuf, pub dir_path: PathBuf, diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index 0726d922c84..8b37728b60f 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -18,7 +18,10 @@ use rustc_span::{BytePos, FileName, Pos, Span}; use std::path::PathBuf; fn sess() -> ParseSess { - ParseSess::new(FilePathMapping::empty()) + ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ) } /// Parses an item. diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index e9a69192068..cef64a10479 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -1,4 +1,5 @@ use crate::base::{self, *}; +use crate::errors; use crate::proc_macro_server; use rustc_ast as ast; @@ -60,11 +61,12 @@ impl base::BangProcMacro for BangProcMacro { let strategy = exec_strategy(ecx); let server = proc_macro_server::Rustc::new(ecx); self.client.run(&strategy, server, input, proc_macro_backtrace).map_err(|e| { - let mut err = ecx.struct_span_err(span, "proc macro panicked"); - if let Some(s) = e.as_str() { - err.help(&format!("message: {}", s)); - } - err.emit() + ecx.sess.emit_err(errors::ProcMacroPanicked { + span, + message: e + .as_str() + .map(|message| errors::ProcMacroPanickedHelp { message: message.into() }), + }) }) } } diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index f80141403bf..14918d3c190 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -34,7 +34,10 @@ where /// Maps a string to tts, using a made-up filename. pub(crate) fn string_to_stream(source_str: String) -> TokenStream { - let ps = ParseSess::new(FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); source_file_to_stream( &ps, ps.source_map().new_source_file(PathBuf::from("bogofile").into(), source_str), @@ -45,7 +48,10 @@ pub(crate) fn string_to_stream(source_str: String) -> TokenStream { /// Parses a string, returns a crate. pub(crate) fn string_to_crate(source_str: String) -> ast::Crate { - let ps = ParseSess::new(FilePathMapping::empty()); + let ps = ParseSess::new( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty(), + ); with_error_checking_parse(source_str, &ps, |p| p.parse_crate_mod()) } @@ -127,8 +133,10 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: & create_default_session_if_not_set_then(|_| { let output = Arc::new(Mutex::new(Vec::new())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + vec![crate::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE], + false, + ); let source_map = Lrc::new(SourceMap::new(FilePathMapping::empty())); source_map.new_source_file(Path::new("test.rs").to_owned().into(), file_text.to_owned()); diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 0599ae04a90..8c58129c800 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -124,6 +124,11 @@ pub enum DefKind { } impl DefKind { + /// Get an English description for the item's kind. + /// + /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or + /// `TyCtxt::def_kind_descr` instead, because they give better + /// information for generators and associated functions. pub fn descr(self, def_id: DefId) -> &'static str { match self { DefKind::Fn => "function", @@ -166,6 +171,10 @@ impl DefKind { } /// Gets an English article for the definition. + /// + /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or + /// `TyCtxt::def_kind_descr_article` instead, because they give better + /// information for generators and associated functions. pub fn article(&self) -> &'static str { match *self { DefKind::AssocTy diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index cd3c620cbb7..8ceb176491b 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -280,6 +280,8 @@ pub enum DefPathData { AnonConst, /// An `impl Trait` type node. ImplTrait, + /// `impl Trait` generated associated type node. + ImplTraitAssocTy, } impl Definitions { @@ -403,7 +405,7 @@ impl DefPathData { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait => None, + | ImplTrait | ImplTraitAssocTy => None, } } @@ -422,7 +424,7 @@ impl DefPathData { ClosureExpr => DefPathDataName::Anon { namespace: sym::closure }, Ctor => DefPathDataName::Anon { namespace: sym::constructor }, AnonConst => DefPathDataName::Anon { namespace: sym::constant }, - ImplTrait => DefPathDataName::Anon { namespace: sym::opaque }, + ImplTrait | ImplTraitAssocTy => DefPathDataName::Anon { namespace: sym::opaque }, } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 3f52f174cdf..72e9f7c1343 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -369,10 +369,10 @@ impl<'hir> GenericArgs<'hir> { pub fn has_err(&self) -> bool { self.args.iter().any(|arg| match arg { - GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err), + GenericArg::Type(ty) => matches!(ty.kind, TyKind::Err(_)), _ => false, }) || self.bindings.iter().any(|arg| match arg.kind { - TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err), + TypeBindingKind::Equality { term: Term::Ty(ty) } => matches!(ty.kind, TyKind::Err(_)), _ => false, }) } @@ -1688,7 +1688,7 @@ impl Expr<'_> { ExprKind::Struct(..) => ExprPrecedence::Struct, ExprKind::Repeat(..) => ExprPrecedence::Repeat, ExprKind::Yield(..) => ExprPrecedence::Yield, - ExprKind::Err => ExprPrecedence::Err, + ExprKind::Err(_) => ExprPrecedence::Err, } } @@ -1754,7 +1754,7 @@ impl Expr<'_> { | ExprKind::Yield(..) | ExprKind::Cast(..) | ExprKind::DropTemps(..) - | ExprKind::Err => false, + | ExprKind::Err(_) => false, } } @@ -1840,7 +1840,7 @@ impl Expr<'_> { | ExprKind::Binary(..) | ExprKind::Yield(..) | ExprKind::DropTemps(..) - | ExprKind::Err => true, + | ExprKind::Err(_) => true, } } @@ -2013,7 +2013,7 @@ pub enum ExprKind<'hir> { Yield(&'hir Expr<'hir>, YieldSource), /// A placeholder for an expression that wasn't syntactically well formed in some way. - Err, + Err(rustc_span::ErrorGuaranteed), } /// Represents an optionally `Self`-qualified value/type path or associated extension. @@ -2676,7 +2676,7 @@ pub enum TyKind<'hir> { /// specified. This can appear anywhere in a type. Infer, /// Placeholder for a type that has failed to be defined. - Err, + Err(rustc_span::ErrorGuaranteed), } #[derive(Debug, HashStable_Generic)] diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index f632babab0b..cc0f64017e4 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -790,7 +790,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::Yield(ref subexpression, _) => { visitor.visit_expr(subexpression); } - ExprKind::Lit(_) | ExprKind::Err => {} + ExprKind::Lit(_) | ExprKind::Err(_) => {} } } @@ -844,7 +844,7 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) { visitor.visit_lifetime(lifetime); } TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), - TyKind::Infer | TyKind::Err => {} + TyKind::Infer | TyKind::Err(_) => {} } } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 04546330915..60fa5a99e10 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -302,8 +302,6 @@ language_item_table! { Context, sym::Context, context, Target::Struct, GenericRequirement::None; FuturePoll, sym::poll, future_poll_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; - FromFrom, sym::from, from_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; - OptionSome, sym::Some, option_some_variant, Target::Variant, GenericRequirement::None; OptionNone, sym::None, option_none_variant, Target::Variant, GenericRequirement::None; diff --git a/compiler/rustc_hir_analysis/Cargo.toml b/compiler/rustc_hir_analysis/Cargo.toml index c939c8303bf..fab16b80fb5 100644 --- a/compiler/rustc_hir_analysis/Cargo.toml +++ b/compiler/rustc_hir_analysis/Cargo.toml @@ -9,7 +9,6 @@ doctest = false [dependencies] rustc_arena = { path = "../rustc_arena" } -tracing = "0.1" rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_attr = { path = "../rustc_attr" } @@ -27,3 +26,5 @@ rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_lint = { path = "../rustc_lint" } rustc_type_ir = { path = "../rustc_type_ir" } rustc_feature = { path = "../rustc_feature" } +thin-vec = "0.2.12" +tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_hir_analysis/locales/en-US.ftl index 41f458f6c17..50b0816889b 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_hir_analysis/locales/en-US.ftl @@ -33,20 +33,7 @@ hir_analysis_field_already_declared = .label = field already declared .previous_decl_label = `{$field_name}` first declared here -hir_analysis_copy_impl_on_type_with_dtor = - the trait `Copy` may not be implemented for this type; the type has a destructor - .label = `Copy` not allowed on types with destructors - -hir_analysis_multiple_relaxed_default_bounds = - type parameter has more than one relaxed default bound, only one is supported - -hir_analysis_copy_impl_on_non_adt = - the trait `Copy` may not be implemented for this type - .label = type is not a structure or enumeration - -hir_analysis_trait_object_declared_with_no_traits = - at least one trait is required for an object type - .alias_span = this alias does not contain a trait +hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` hir_analysis_ambiguous_lifetime_bound = ambiguous lifetime bound, explicit lifetime bound required @@ -68,6 +55,25 @@ hir_analysis_value_of_associated_struct_already_specified = hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same {$what} +hir_analysis_manual_implementation = + manual implementations of `{$trait_name}` are experimental + .label = manual implementations of `{$trait_name}` are experimental + .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable + +hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl + +hir_analysis_unused_extern_crate = + unused extern crate + .suggestion = remove it + +hir_analysis_extern_crate_not_idiomatic = + `extern crate` is not idiomatic in the new edition + .suggestion = convert it to a `{$msg_code}` + +hir_analysis_trait_object_declared_with_no_traits = + at least one trait is required for an object type + .alias_span = this alias does not contain a trait + hir_analysis_missing_type_params = the type {$parameterCount -> [one] parameter @@ -90,20 +96,16 @@ hir_analysis_missing_type_params = } to {$parameters} .note = because of the default `Self` reference, type parameters must be specified on object types -hir_analysis_manual_implementation = - manual implementations of `{$trait_name}` are experimental - .label = manual implementations of `{$trait_name}` are experimental - .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable - -hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl +hir_analysis_copy_impl_on_type_with_dtor = + the trait `Copy` may not be implemented for this type; the type has a destructor + .label = `Copy` not allowed on types with destructors -hir_analysis_unused_extern_crate = - unused extern crate - .suggestion = remove it +hir_analysis_multiple_relaxed_default_bounds = + type parameter has more than one relaxed default bound, only one is supported -hir_analysis_extern_crate_not_idiomatic = - `extern crate` is not idiomatic in the new edition - .suggestion = convert it to a `{$msg_code}` +hir_analysis_copy_impl_on_non_adt = + the trait `Copy` may not be implemented for this type + .label = type is not a structure or enumeration hir_analysis_const_impl_for_non_const_trait = const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]` @@ -124,3 +126,32 @@ hir_analysis_linkage_type = hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}` .label = deref recursion limit reached .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`) + +hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause + .label = `main` cannot have a `where` clause + +hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]` + .suggestion = remove this annotation + +hir_analysis_start_not_track_caller = `start` is not allowed to be `#[track_caller]` + .label = `start` is not allowed to be `#[track_caller]` + +hir_analysis_start_not_async = `start` is not allowed to be `async` + .label = `start` is not allowed to be `async` + +hir_analysis_start_function_where = start function is not allowed to have a `where` clause + .label = start function cannot have a `where` clause + +hir_analysis_start_function_parameters = start function is not allowed to have type parameters + .label = start function cannot have type parameters + +hir_analysis_main_function_return_type_generic = `main` function return type is not allowed to have generic parameters + +hir_analysis_main_function_async = `main` function is not allowed to be `async` + .label = `main` function is not allowed to be `async` + +hir_analysis_main_function_generic_parameters = `main` function is not allowed to have generic parameters + .label = `main` cannot have generic parameters + +hir_analysis_variadic_function_compatible_convention = C-variadic function must have a compatible calling convention, like {$conventions} + .label = C-variadic function must have a compatible calling convention diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index a68e0e0ac5b..c49e4d9d581 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -304,10 +304,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(did) = adt_did { err.span_label( tcx.def_span(did), - format!( - "associated item `{name}` not found for this {}", - tcx.def_kind(did).descr(did) - ), + format!("associated item `{name}` not found for this {}", tcx.def_descr(did)), ); } }; @@ -380,7 +377,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // `<Foo as Iterator>::Item = String`. let projection_ty = pred.skip_binder().projection_ty; - let substs_with_infer_self = tcx.mk_substs( + let substs_with_infer_self = tcx.mk_substs_from_iter( std::iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into()) .chain(projection_ty.substs.iter().skip(1)), ); diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs index 630becc09d2..7f6518ffd71 100644 --- a/compiler/rustc_hir_analysis/src/astconv/generics.rs +++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs @@ -370,7 +370,7 @@ pub fn create_substs_for_generic_args<'tcx, 'a>( } } - tcx.intern_substs(&substs) + tcx.mk_substs(&substs) } /// Checks that the correct number of generic arguments have been provided. diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index c0cd54cc916..a15cf454df7 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -35,7 +35,7 @@ use rustc_middle::middle::stability::AllowUnstable; use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef}; use rustc_middle::ty::DynKind; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Const, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; @@ -381,7 +381,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // here and so associated type bindings will be handled regardless of whether there are any // non-`Self` generic parameters. if generics.params.is_empty() { - return (tcx.intern_substs(parent_substs), arg_count); + return (tcx.mk_substs(parent_substs), arg_count); } struct SubstsForAstPathCtxt<'a, 'tcx> { @@ -429,7 +429,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) { self.inferred_params.push(ty.span); - tcx.ty_error().into() + tcx.ty_error_misc().into() } else { self.astconv.ast_ty_to_ty(ty).into() } @@ -502,14 +502,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { _ => false, }) { // Avoid ICE #86756 when type error recovery goes awry. - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } tcx.at(self.span).type_of(param.def_id).subst(tcx, substs).into() } else if infer_args { self.astconv.ty_infer(Some(param), self.span).into() } else { // We've already errored above about the mismatch. - tcx.ty_error().into() + tcx.ty_error_misc().into() } } GenericParamDefKind::Const { has_default } => { @@ -518,8 +518,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .type_of(param.def_id) .no_bound_vars() .expect("const parameter types cannot be generic"); - if ty.references_error() { - return tcx.const_error(ty).into(); + if let Err(guar) = ty.error_reported() { + return tcx.const_error_with_guaranteed(ty, guar).into(); } if !infer_args && has_default { tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into() @@ -1217,7 +1217,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { | (hir::def::DefKind::AssocConst, ty::TermKind::Const(_)) => (), (_, _) => { let got = if let Some(_) = term.ty() { "type" } else { "constant" }; - let expected = def_kind.descr(assoc_item_def_id); + let expected = tcx.def_descr(assoc_item_def_id); let mut err = tcx.sess.struct_span_err( binding.span, &format!("expected {expected} bound, found {got}"), @@ -1239,9 +1239,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } let reported = err.emit(); term = match def_kind { - hir::def::DefKind::AssocTy => { - tcx.ty_error_with_guaranteed(reported).into() - } + hir::def::DefKind::AssocTy => tcx.ty_error(reported).into(), hir::def::DefKind::AssocConst => tcx .const_error_with_guaranteed( tcx.type_of(assoc_item_def_id) @@ -1397,7 +1395,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .map(|trait_ref| tcx.def_span(trait_ref)); let reported = tcx.sess.emit_err(TraitObjectDeclaredWithNoTraits { span, trait_alias_span }); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); } // Check that there are no gross object safety violations; @@ -1414,7 +1412,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &object_safety_violations, ) .emit(); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); } } @@ -1523,15 +1521,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if arg == dummy_self.into() { let param = &generics.params[index]; missing_type_params.push(param.name); - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } else if arg.walk().any(|arg| arg == dummy_self.into()) { references_self = true; - return tcx.ty_error().into(); + return tcx.ty_error_misc().into(); } arg }) .collect(); - let substs = tcx.intern_substs(&substs[..]); + let substs = tcx.mk_substs(&substs); let span = i.bottom().1; let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| { @@ -1552,7 +1550,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { i.bottom().1, E0038, "the {} `{}` cannot be made into an object", - tcx.def_kind(def_id).descr(def_id), + tcx.def_descr(def_id), tcx.item_name(def_id), ); err.note( @@ -1579,7 +1577,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { false }); if references_self { - tcx.sess + let guar = tcx + .sess .delay_span_bug(span, "trait object projection bounds reference `Self`"); let substs: Vec<_> = b .projection_ty @@ -1587,12 +1586,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .iter() .map(|arg| { if arg.walk().any(|arg| arg == dummy_self.into()) { - return tcx.ty_error().into(); + return tcx.ty_error(guar).into(); } arg }) .collect(); - b.projection_ty.substs = tcx.intern_substs(&substs[..]); + b.projection_ty.substs = tcx.mk_substs(&substs); } ty::ExistentialProjection::erase_self_ty(tcx, b) @@ -1614,7 +1613,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .collect::<SmallVec<[_; 8]>>(); v.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); v.dedup(); - let existential_predicates = tcx.intern_poly_existential_predicates(&v); + let existential_predicates = tcx.mk_poly_existential_predicates(&v); // Use explicitly-specified region bound. let region_bound = if !lifetime.is_elided() { @@ -2174,7 +2173,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "`{}` could{} refer to the {} defined here", assoc_ident, also, - kind.descr(def_id) + tcx.def_kind_descr(kind, def_id) ); lint.span_note(tcx.def_span(def_id), ¬e_msg); }; @@ -2350,7 +2349,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let kind = DefKind::AssocTy; if !tcx.visibility(item).is_accessible_from(def_scope, tcx) { - let kind = kind.descr(item); + let kind = tcx.def_kind_descr(kind, item); let msg = format!("{kind} `{name}` is private"); let def_span = tcx.def_span(item); tcx.sess @@ -2473,7 +2472,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { &[path_str], item_segment.ident.name, ); - return tcx.ty_error_with_guaranteed(reported) + return tcx.ty_error(reported) }; debug!("qpath_to_ty: self_type={:?}", self_ty); @@ -2811,7 +2810,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { var: ty::BoundVar::from_u32(index), kind: ty::BoundTyKind::Param(def_id, name), }; - tcx.mk_ty(ty::Bound(debruijn, br)) + tcx.mk_bound(debruijn, br) } Some(rbv::ResolvedArg::EarlyBound(_)) => { let def_id = def_id.expect_local(); @@ -2820,7 +2819,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let index = generics.param_def_id_to_index[&def_id.to_def_id()]; tcx.mk_ty_param(index, tcx.hir().ty_param_name(def_id)) } - Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error_with_guaranteed(guar), + Some(rbv::ResolvedArg::Error(guar)) => tcx.ty_error(guar), arg => bug!("unexpected bound var resolution for {hir_id:?}: {arg:?}"), } } @@ -2932,7 +2931,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { err.span_note(impl_.self_ty.span, "not a concrete type"); } - tcx.ty_error_with_guaranteed(err.emit()) + tcx.ty_error(err.emit()) } else { ty } @@ -2985,7 +2984,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .sess .delay_span_bug(path.span, "path with `Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - self.tcx().ty_error_with_guaranteed(e) + self.tcx().ty_error(e) } _ => span_bug!(span, "unexpected resolution: {:?}", path.res), } @@ -3021,7 +3020,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl }) } hir::TyKind::Never => tcx.types.never, - hir::TyKind::Tup(fields) => tcx.mk_tup(fields.iter().map(|t| self.ast_ty_to_ty(t))), + hir::TyKind::Tup(fields) => { + tcx.mk_tup_from_iter(fields.iter().map(|t| self.ast_ty_to_ty(t))) + } hir::TyKind::BareFn(bf) => { require_c_abi_if_c_variadic(tcx, bf.decl, bf.abi, ast_ty.span); @@ -3064,7 +3065,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let ty = self.ast_ty_to_ty_inner(qself, false, true); self.associated_path_to_ty(ast_ty.hir_id, ast_ty.span, ty, qself, segment, false) .map(|(ty, _, _)| ty) - .unwrap_or_else(|_| tcx.ty_error()) + .unwrap_or_else(|guar| tcx.ty_error(guar)) } &hir::TyKind::Path(hir::QPath::LangItem(lang_item, span, _)) => { let def_id = tcx.require_lang_item(lang_item, Some(span)); @@ -3112,7 +3113,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // handled specially and will not descend into this routine. self.ty_infer(None, ast_ty.span) } - hir::TyKind::Err => tcx.ty_error(), + hir::TyKind::Err(guar) => tcx.ty_error(*guar), }; self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span); diff --git a/compiler/rustc_hir_analysis/src/autoderef.rs b/compiler/rustc_hir_analysis/src/autoderef.rs index a5c96a8b016..ba2d4319af6 100644 --- a/compiler/rustc_hir_analysis/src/autoderef.rs +++ b/compiler/rustc_hir_analysis/src/autoderef.rs @@ -3,7 +3,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::NormalizeExt; use crate::traits::{self, TraitEngine, TraitEngineExt}; use rustc_infer::infer::InferCtxt; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::Limit; use rustc_span::def_id::LocalDefId; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 04396c883d3..4ea471f8f05 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -23,6 +23,7 @@ use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; use rustc_middle::ty::{ self, AdtDef, DefIdTree, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, }; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; @@ -255,7 +256,7 @@ pub(super) fn check_opaque_for_inheriting_lifetimes( selftys: Vec<(Span, Option<String>)>, } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -1418,7 +1419,7 @@ fn opaque_type_cycle_error( opaques: Vec<DefId>, closures: Vec<DefId>, } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { match *t.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => { @@ -1460,7 +1461,7 @@ fn opaque_type_cycle_error( span, format!( "{} captures itself here", - tcx.def_kind(closure_def_id).descr(closure_def_id) + tcx.def_descr(closure_def_id) ), ); } diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index a9fcc8e6250..89b4e6227bd 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -16,7 +16,8 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::util::ExplicitSelf; use rustc_middle::ty::{ - self, ir::TypeFolder, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeSuperFoldable, + self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, }; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; @@ -195,7 +196,7 @@ fn compare_method_predicate_entailment<'tcx>( // the new hybrid bounds we computed. let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id); let param_env = ty::ParamEnv::new( - tcx.intern_predicates(&hybrid_preds.predicates), + tcx.mk_predicates(&hybrid_preds.predicates), Reveal::UserFacing, hir::Constness::NotConst, ); @@ -789,7 +790,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( return_span, format!("could not fully resolve: {ty} => {err:?}"), ); - collected_tys.insert(def_id, tcx.ty_error_with_guaranteed(reported)); + collected_tys.insert(def_id, tcx.ty_error(reported)); } } } @@ -1794,7 +1795,7 @@ fn compare_type_predicate_entailment<'tcx>( let impl_ty_span = tcx.def_span(impl_ty_def_id); let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id); let param_env = ty::ParamEnv::new( - tcx.intern_predicates(&hybrid_preds.predicates), + tcx.mk_predicates(&hybrid_preds.predicates), Reveal::UserFacing, hir::Constness::NotConst, ); @@ -1936,8 +1937,8 @@ pub(super) fn check_type_bounds<'tcx>( .into() } }); - let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); - let impl_ty_substs = tcx.intern_substs(&substs); + let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); + let impl_ty_substs = tcx.mk_substs(&substs); let container_id = impl_ty.container_id(tcx); let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); @@ -1977,11 +1978,7 @@ pub(super) fn check_type_bounds<'tcx>( .to_predicate(tcx), ), }; - ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - Reveal::UserFacing, - param_env.constness(), - ) + ty::ParamEnv::new(tcx.mk_predicates(&predicates), Reveal::UserFacing, param_env.constness()) }; debug!(?normalize_param_env); diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index c84e3461226..2bb724138f5 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -71,7 +71,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>( let drop_impl_span = tcx.def_span(drop_impl_did); let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); + let self_descr = tcx.def_descr(self_type_did); let mut err = struct_span_err!(tcx.sess, drop_impl_span, E0366, "`Drop` impls cannot be specialized"); match arg { @@ -217,7 +217,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>( if !assumptions_in_impl_context.iter().copied().any(predicate_matches_closure) { let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_kind(self_type_did).descr(self_type_did.to_def_id()); + let self_descr = tcx.def_descr(self_type_did.to_def_id()); let reported = struct_span_err!( tcx.sess, predicate_sp, diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs index 4720fea8ef4..054284cced5 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs @@ -137,7 +137,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { let intrinsic_name = tcx.item_name(intrinsic_id); let name_str = intrinsic_name.as_str(); - let bound_vars = tcx.intern_bound_variable_kinds(&[ + let bound_vars = tcx.mk_bound_variable_kinds(&[ ty::BoundVariableKind::Region(ty::BrAnon(0, None)), ty::BoundVariableKind::Region(ty::BrEnv), ]); @@ -165,7 +165,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { "cxchg" | "cxchgweak" => ( 1, vec![tcx.mk_mut_ptr(param(0)), param(0), param(0)], - tcx.intern_tup(&[param(0), tcx.types.bool]), + tcx.mk_tup(&[param(0), tcx.types.bool]), ), "load" => (1, vec![tcx.mk_imm_ptr(param(0))], param(0)), "store" => (1, vec![tcx.mk_mut_ptr(param(0)), param(0)], tcx.mk_unit()), @@ -317,7 +317,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { | sym::bitreverse => (1, vec![param(0)], param(0)), sym::add_with_overflow | sym::sub_with_overflow | sym::mul_with_overflow => { - (1, vec![param(0), param(0)], tcx.intern_tup(&[param(0), tcx.types.bool])) + (1, vec![param(0), param(0)], tcx.mk_tup(&[param(0), tcx.types.bool])) } sym::ptr_guaranteed_cmp => { @@ -372,7 +372,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) { ( 1, vec![tcx.mk_imm_ref(tcx.mk_re_late_bound(ty::INNERMOST, br), param(0))], - tcx.mk_projection(discriminant_def_id, tcx.intern_substs(&[param(0).into()])), + tcx.mk_projection(discriminant_def_id, tcx.mk_substs(&[param(0).into()])), ) } diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index b3e76010da3..b1d5a27be93 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -1,7 +1,7 @@ use rustc_ast::InlineAsmTemplatePiece; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitable, UintTy}; +use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableExt, UintTy}; use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, DUMMY_SP}; diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 5743f086f89..4cccdf30c5f 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -16,8 +16,8 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::query::Providers; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, ir::TypeVisitor, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, - TypeSuperVisitable, + self, AdtKind, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_middle::ty::{GenericArgKind, InternalSubsts}; use rustc_session::parse::feature_err; @@ -56,7 +56,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // `ObligationCtxt::normalize`, but provides a nice `ObligationCauseCode`. fn normalize<T>(&self, span: Span, loc: Option<WellFormedLoc>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.ocx.normalize( &ObligationCause::new(span, self.body_def_id, ObligationCauseCode::WellFormed(loc)), @@ -277,56 +277,6 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) { }; check_object_unsafe_self_trait_by_name(tcx, trait_item); check_associated_item(tcx, def_id, span, method_sig); - - let encl_trait_def_id = tcx.local_parent(def_id); - let encl_trait = tcx.hir().expect_item(encl_trait_def_id); - let encl_trait_def_id = encl_trait.owner_id.to_def_id(); - let fn_lang_item_name = if Some(encl_trait_def_id) == tcx.lang_items().fn_trait() { - Some("fn") - } else if Some(encl_trait_def_id) == tcx.lang_items().fn_mut_trait() { - Some("fn_mut") - } else { - None - }; - - if let (Some(fn_lang_item_name), "call") = - (fn_lang_item_name, trait_item.ident.name.to_ident_string().as_str()) - { - // We are looking at the `call` function of the `fn` or `fn_mut` lang item. - // Do some rudimentary sanity checking to avoid an ICE later (issue #83471). - if let Some(hir::FnSig { decl, span, .. }) = method_sig { - if let [self_ty, _] = decl.inputs { - if !matches!(self_ty.kind, hir::TyKind::Ref(_, _)) { - tcx.sess - .struct_span_err( - self_ty.span, - &format!( - "first argument of `call` in `{fn_lang_item_name}` lang item must be a reference", - ), - ) - .emit(); - } - } else { - tcx.sess - .struct_span_err( - *span, - &format!( - "`call` function in `{fn_lang_item_name}` lang item takes exactly two arguments", - ), - ) - .emit(); - } - } else { - tcx.sess - .struct_span_err( - trait_item.span, - &format!( - "`call` trait item in `{fn_lang_item_name}` lang item must be a function", - ), - ) - .emit(); - } - } } /// Require that the user writes where clauses on GATs for the implicit @@ -543,8 +493,9 @@ fn augment_param_env<'tcx>( return param_env; } - let bounds = - tcx.mk_predicates(param_env.caller_bounds().iter().chain(new_predicates.iter().cloned())); + let bounds = tcx.mk_predicates_from_iter( + param_env.caller_bounds().iter().chain(new_predicates.iter().cloned()), + ); // FIXME(compiler-errors): Perhaps there is a case where we need to normalize this // i.e. traits::normalize_param_env_or_error ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness()) @@ -560,7 +511,7 @@ fn augment_param_env<'tcx>( /// fn into_iter<'a>(&'a self) -> Self::Iter<'a>; /// } /// ``` -fn gather_gat_bounds<'tcx, T: TypeFoldable<'tcx>>( +fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, item_def_id: hir::OwnerId, @@ -758,7 +709,7 @@ struct GATSubstCollector<'tcx> { } impl<'tcx> GATSubstCollector<'tcx> { - fn visit<T: TypeFoldable<'tcx>>( + fn visit<T: TypeFoldable<TyCtxt<'tcx>>>( gat: DefId, t: T, ) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) { @@ -1432,7 +1383,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id struct CountParams { params: FxHashSet<u32>, } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for CountParams { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for CountParams { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -1526,7 +1477,7 @@ fn check_fn_or_method<'tcx>( |idx| hir_decl.inputs.get(idx).map_or(hir_decl.output.span(), |arg: &hir::Ty<'_>| arg.span); sig.inputs_and_output = - tcx.mk_type_list(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| { + tcx.mk_type_list_from_iter(sig.inputs_and_output.iter().enumerate().map(|(idx, ty)| { wfcx.normalize( arg_span(idx), Some(WellFormedLoc::Param { diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 51c5f297051..875c5f1fd00 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -11,7 +11,7 @@ use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::{self, RegionResolutionError}; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; -use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeVisitableExt}; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::misc::{ type_allowed_to_implement_copy, CopyImplementationError, InfringingFieldsReason, diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs index bbde59c953a..23490bc091c 100644 --- a/compiler/rustc_hir_analysis/src/coherence/mod.rs +++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs @@ -8,7 +8,7 @@ use rustc_errors::{error_code, struct_span_err}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use rustc_trait_selection::traits; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index f0a0e7e3e92..1f2de3f21f8 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -8,7 +8,8 @@ use rustc_hir as hir; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::{ - self, ir::TypeVisitor, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + TypeVisitor, }; use rustc_session::lint; use rustc_span::def_id::{DefId, LocalDefId}; @@ -531,7 +532,7 @@ fn lint_auto_trait_impl<'tcx>( }), |lint| { let item_span = tcx.def_span(self_type_did); - let self_descr = tcx.def_kind(self_type_did).descr(self_type_did); + let self_descr = tcx.def_descr(self_type_did); match arg { ty::util::NotUniqueParam::DuplicateParam(arg) => { lint.note(&format!("`{}` is mentioned multiple times", arg)); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index ed3d50bfafa..604d54cafb5 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -499,7 +499,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { } _ => {} } - self.tcx().ty_error_with_guaranteed(err.emit()) + self.tcx().ty_error(err.emit()) } } @@ -905,7 +905,7 @@ fn adt_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtDef<'_> { } _ => bug!(), }; - tcx.alloc_adt_def(def_id.to_def_id(), kind, variants, repr) + tcx.mk_adt_def(def_id.to_def_id(), kind, variants, repr) } fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index 8d479f1c3e3..9cf3ff65a91 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -103,7 +103,7 @@ pub(super) fn item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<&'_ ty::List<ty::Predicate<'_>>> { - let bounds = tcx.mk_predicates( + let bounds = tcx.mk_predicates_from_iter( util::elaborate_predicates( tcx, tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index c0c90e47a75..6c00b8ff7bd 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -17,7 +17,8 @@ use rustc_hir::{GenericArg, GenericParam, GenericParamKind, HirIdMap, LifetimeNa use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::resolve_bound_vars::*; -use rustc_middle::ty::{self, ir::TypeVisitor, DefIdTree, TyCtxt, TypeSuperVisitable}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt, TypeSuperVisitable, TypeVisitor}; +use rustc_session::lint; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -923,17 +924,16 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { origin, .. }) => { - let (bound_vars, binders): (FxIndexMap<LocalDefId, ResolvedArg>, Vec<_>) = bound_generic_params - .iter() - .enumerate() - .map(|(late_bound_idx, param)| { - let pair = ResolvedArg::late(late_bound_idx as u32, param); - let r = late_arg_as_bound_arg(this.tcx, &pair.1, param); - (pair, r) - }) - .unzip(); + .iter() + .enumerate() + .map(|(late_bound_idx, param)| { + let pair = ResolvedArg::late(late_bound_idx as u32, param); + let r = late_arg_as_bound_arg(this.tcx, &pair.1, param); + (pair, r) + }) + .unzip(); this.record_late_bound_vars(hir_id, binders.clone()); // Even if there are no lifetimes defined here, we still wrap it in a binder // scope. If there happens to be a nested poly trait ref (an error), that @@ -968,20 +968,22 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { continue; } this.insert_lifetime(lt, ResolvedArg::StaticLifetime); - this.tcx - .sess - .struct_span_warn( - lifetime.ident.span, - &format!( - "unnecessary lifetime parameter `{}`", + this.tcx.struct_span_lint_hir( + lint::builtin::UNUSED_LIFETIMES, + lifetime.hir_id, + lifetime.ident.span, + format!( + "unnecessary lifetime parameter `{}`", + lifetime.ident + ), + |lint| { + let help = &format!( + "you can use the `'static` lifetime directly, in place of `{}`", lifetime.ident, - ), - ) - .help(&format!( - "you can use the `'static` lifetime directly, in place of `{}`", - lifetime.ident, - )) - .emit(); + ); + lint.help(help) + }, + ); } } } diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index a3bc0082ef2..50073d94ea5 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{ - self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable, + self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_span::symbol::Ident; use rustc_span::{Span, DUMMY_SP}; @@ -319,8 +319,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::EarlyBinder<Ty<'_>> ItemKind::Impl(hir::Impl { self_ty, .. }) => { match self_ty.find_self_aliases() { spans if spans.len() > 0 => { - tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: (), }); - tcx.ty_error() + let guar = tcx.sess.emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () }); + tcx.ty_error(guar) }, _ => icx.to_ty(*self_ty), } @@ -599,8 +599,9 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T // // constant does not contain interior mutability. // ``` let tables = self.tcx.typeck(item_def_id); - if let Some(_) = tables.tainted_by_errors { - self.found = Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error() }); + if let Some(guar) = tables.tainted_by_errors { + self.found = + Some(ty::OpaqueHiddenType { span: DUMMY_SP, ty: self.tcx.ty_error(guar) }); return; } let Some(&typeck_hidden_ty) = tables.concrete_opaque_types.get(&self.def_id) else { @@ -618,8 +619,8 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T debug!(?concrete_type, "found constraint"); if let Some(prev) = &mut self.found { if concrete_type.ty != prev.ty && !(concrete_type, prev.ty).references_error() { - prev.report_mismatch(&concrete_type, self.tcx); - prev.ty = self.tcx.ty_error(); + let guar = prev.report_mismatch(&concrete_type, self.tcx); + prev.ty = self.tcx.ty_error(guar); } } else { self.found = Some(concrete_type); @@ -706,7 +707,7 @@ fn find_opaque_ty_constraints_for_tait(tcx: TyCtxt<'_>, def_id: LocalDefId) -> T _ => "item", }, }); - return tcx.ty_error_with_guaranteed(reported); + return tcx.ty_error(reported); }; // Only check against typeck if we didn't already error @@ -814,11 +815,11 @@ fn find_opaque_ty_constraints_for_rpit( concrete.map(|concrete| concrete.ty).unwrap_or_else(|| { let table = tcx.typeck(owner_def_id); - if let Some(_) = table.tainted_by_errors { + if let Some(guar) = table.tainted_by_errors { // Some error in the // owner fn prevented us from populating // the `concrete_opaque_types` table. - tcx.ty_error() + tcx.ty_error(guar) } else { table.concrete_opaque_types.get(&def_id).map(|ty| ty.ty).unwrap_or_else(|| { // We failed to resolve the opaque type or it diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs index 072676c400d..e18b0f08279 100644 --- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs +++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs @@ -1,5 +1,5 @@ use rustc_data_structures::fx::FxHashSet; -use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::source_map::Span; use std::ops::ControlFlow; @@ -43,7 +43,7 @@ pub fn parameters_for_impl<'tcx>( /// of parameters whose values are needed in order to constrain `ty` - these /// differ, with the latter being a superset, in the presence of projections. pub fn parameters_for<'tcx>( - t: &impl TypeVisitable<'tcx>, + t: &impl TypeVisitable<TyCtxt<'tcx>>, include_nonconstraining: bool, ) -> Vec<Parameter> { let mut collector = ParameterCollector { parameters: vec![], include_nonconstraining }; diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index 04f5f3f6276..a566e73912e 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -1,7 +1,10 @@ //! Errors emitted by `rustc_hir_analysis`. -use rustc_errors::{error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler}; -use rustc_errors::{IntoDiagnostic, MultiSpan}; +use crate::fluent_generated as fluent; +use rustc_errors::{ + error_code, Applicability, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, + MultiSpan, +}; use rustc_macros::{Diagnostic, LintDiagnostic}; use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span, Symbol}; @@ -41,11 +44,11 @@ pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, - #[label(generics_label)] + #[label(hir_analysis_generics_label)] pub generics_span: Option<Span>, - #[label(where_label)] + #[label(hir_analysis_where_label)] pub where_span: Option<Span>, - #[label(bounds_label)] + #[label(hir_analysis_bounds_label)] pub bounds_span: Vec<Span>, pub item_kind: &'static str, pub ident: Ident, @@ -57,7 +60,7 @@ pub struct AsyncTraitImplShouldBeAsync { #[primary_span] // #[label] pub span: Span, - #[label(trait_item_label)] + #[label(hir_analysis_trait_item_label)] pub trait_item_span: Option<Span>, pub method_name: Symbol, } @@ -77,7 +80,7 @@ pub struct FieldAlreadyDeclared { #[primary_span] #[label] pub span: Span, - #[label(previous_decl_label)] + #[label(hir_analysis_previous_decl_label)] pub prev_span: Span, } @@ -109,7 +112,7 @@ pub struct CopyImplOnNonAdt { pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, - #[label(alias_span)] + #[label(hir_analysis_alias_span)] pub trait_alias_span: Option<Span>, } @@ -145,7 +148,7 @@ pub struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] pub span: Span, - #[label(previous_bound_label)] + #[label(hir_analysis_previous_bound_label)] pub prev_span: Span, pub item_name: Ident, pub def_path: String, @@ -175,7 +178,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { let mut err = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::hir_analysis_missing_type_params, + fluent::hir_analysis_missing_type_params, error_code!(E0393), ); err.set_arg("parameterCount", self.missing_type_params.len()); @@ -188,7 +191,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { .join(", "), ); - err.span_label(self.def_span, rustc_errors::fluent::label); + err.span_label(self.def_span, fluent::hir_analysis_label); let mut suggested = false; // Don't suggest setting the type params if there are some already: the order is @@ -203,7 +206,7 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { // least we can clue them to the correct syntax `Iterator<Type>`. err.span_suggestion( self.span, - rustc_errors::fluent::suggestion, + fluent::hir_analysis_suggestion, format!( "{}<{}>", snippet, @@ -219,10 +222,10 @@ impl<'a> IntoDiagnostic<'a> for MissingTypeParams { } } if !suggested { - err.span_label(self.span, rustc_errors::fluent::no_suggestion_label); + err.span_label(self.span, fluent::hir_analysis_no_suggestion_label); } - err.note(rustc_errors::fluent::note); + err.note(fluent::hir_analysis_note); err } } @@ -274,7 +277,7 @@ pub struct ConstImplForNonConstTrait { pub local_trait_span: Option<Span>, #[note] pub marking: (), - #[note(adding)] + #[note(hir_analysis_adding)] pub adding: (), } @@ -312,3 +315,89 @@ pub struct AutoDerefReachedRecursionLimit<'a> { pub suggested_limit: rustc_session::Limit, pub crate_name: Symbol, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_where_clause_on_main, code = "E0646")] +pub(crate) struct WhereClauseOnMain { + #[primary_span] + pub span: Span, + #[label] + pub generics_span: Option<Span>, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_track_caller_on_main)] +pub(crate) struct TrackCallerOnMain { + #[primary_span] + #[suggestion(applicability = "maybe-incorrect", code = "")] + pub span: Span, + #[label(hir_analysis_track_caller_on_main)] + pub annotated: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_start_not_track_caller)] +pub(crate) struct StartTrackCaller { + #[primary_span] + pub span: Span, + #[label] + pub start: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_start_not_async, code = "E0752")] +pub(crate) struct StartAsync { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_start_function_where, code = "E0647")] +pub(crate) struct StartFunctionWhere { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_start_function_parameters, code = "E0132")] +pub(crate) struct StartFunctionParameters { + #[primary_span] + #[label] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_main_function_return_type_generic, code = "E0131")] +pub(crate) struct MainFunctionReturnTypeGeneric { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_main_function_async, code = "E0752")] +pub(crate) struct MainFunctionAsync { + #[primary_span] + pub span: Span, + #[label] + pub asyncness: Option<Span>, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_main_function_generic_parameters, code = "E0131")] +pub(crate) struct MainFunctionGenericParameters { + #[primary_span] + pub span: Span, + #[label] + pub label_span: Option<Span>, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_variadic_function_compatible_convention, code = "E0045")] +pub(crate) struct VariadicFunctionCompatibleConvention<'a> { + #[primary_span] + #[label] + pub span: Span, + pub conventions: &'a str, +} diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 8fc4610ae85..e330fcc7857 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, ir::TypeFolder, Region, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder}; use rustc_span::def_id::LocalDefId; use rustc_trait_selection::traits; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check.rs b/compiler/rustc_hir_analysis/src/impl_wf_check.rs index 8ab9964d810..82a96f8e674 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check.rs @@ -16,7 +16,7 @@ use rustc_errors::struct_span_err; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::{Span, Symbol}; mod min_specialization; diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 4741e4b095d..daa5d15704d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -76,7 +76,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use rustc_middle::ty::trait_def::TraitSpecializationKind; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _; diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index 11240cf22e4..33c132fd534 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -98,10 +98,12 @@ mod outlives; pub mod structured_errors; mod variance; -use rustc_errors::{struct_span_err, ErrorGuaranteed}; +use rustc_errors::ErrorGuaranteed; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir as hir; use rustc_hir::Node; use rustc_infer::infer::{InferOk, TyCtxtInferExt}; +use rustc_macros::fluent_messages; use rustc_middle::middle; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -118,8 +120,9 @@ use std::ops::Not; use astconv::AstConv; use bounds::Bounds; +fluent_messages! { "../locales/en-US.ftl" } + fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi, span: Span) { - const ERROR_HEAD: &str = "C-variadic function must have a compatible calling convention"; const CONVENTIONS_UNSTABLE: &str = "`C`, `cdecl`, `win64`, `sysv64` or `efiapi`"; const CONVENTIONS_STABLE: &str = "`C` or `cdecl`"; const UNSTABLE_EXPLAIN: &str = @@ -151,8 +154,7 @@ fn require_c_abi_if_c_variadic(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: Abi (true, false) => CONVENTIONS_UNSTABLE, }; - let mut err = struct_span_err!(tcx.sess, span, E0045, "{}, like {}", ERROR_HEAD, conventions); - err.span_label(span, ERROR_HEAD).emit(); + tcx.sess.emit_err(errors::VariadicFunctionCompatibleConvention { span, conventions }); } fn require_same_types<'tcx>( @@ -254,53 +256,30 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { let main_fn_predicates = tcx.predicates_of(main_def_id); if main_fn_generics.count() != 0 || !main_fnsig.bound_vars().is_empty() { let generics_param_span = main_fn_generics_params_span(tcx, main_def_id); - let msg = "`main` function is not allowed to have generic \ - parameters"; - let mut diag = - struct_span_err!(tcx.sess, generics_param_span.unwrap_or(main_span), E0131, "{}", msg); - if let Some(generics_param_span) = generics_param_span { - let label = "`main` cannot have generic parameters"; - diag.span_label(generics_param_span, label); - } - diag.emit(); + tcx.sess.emit_err(errors::MainFunctionGenericParameters { + span: generics_param_span.unwrap_or(main_span), + label_span: generics_param_span, + }); error = true; } else if !main_fn_predicates.predicates.is_empty() { // generics may bring in implicit predicates, so we skip this check if generics is present. let generics_where_clauses_span = main_fn_where_clauses_span(tcx, main_def_id); - let mut diag = struct_span_err!( - tcx.sess, - generics_where_clauses_span.unwrap_or(main_span), - E0646, - "`main` function is not allowed to have a `where` clause" - ); - if let Some(generics_where_clauses_span) = generics_where_clauses_span { - diag.span_label(generics_where_clauses_span, "`main` cannot have a `where` clause"); - } - diag.emit(); + tcx.sess.emit_err(errors::WhereClauseOnMain { + span: generics_where_clauses_span.unwrap_or(main_span), + generics_span: generics_where_clauses_span, + }); error = true; } let main_asyncness = tcx.asyncness(main_def_id); if let hir::IsAsync::Async = main_asyncness { - let mut diag = struct_span_err!( - tcx.sess, - main_span, - E0752, - "`main` function is not allowed to be `async`" - ); let asyncness_span = main_fn_asyncness_span(tcx, main_def_id); - if let Some(asyncness_span) = asyncness_span { - diag.span_label(asyncness_span, "`main` function is not allowed to be `async`"); - } - diag.emit(); + tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span }); error = true; } for attr in tcx.get_attrs(main_def_id, sym::track_caller) { - tcx.sess - .struct_span_err(attr.span, "`main` function is not allowed to be `#[track_caller]`") - .span_label(main_span, "`main` function is not allowed to be `#[track_caller]`") - .emit(); + tcx.sess.emit_err(errors::TrackCallerOnMain { span: attr.span, annotated: main_span }); error = true; } @@ -313,9 +292,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) { let return_ty = main_fnsig.output(); let return_ty_span = main_fn_return_type_span(tcx, main_def_id).unwrap_or(main_span); if !return_ty.bound_vars().is_empty() { - let msg = "`main` function return type is not allowed to have generic \ - parameters"; - struct_span_err!(tcx.sess, return_ty_span, E0131, "{}", msg).emit(); + tcx.sess.emit_err(errors::MainFunctionReturnTypeGeneric { span: return_ty_span }); error = true; } let return_ty = return_ty.skip_binder(); @@ -372,56 +349,28 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) { if let hir::ItemKind::Fn(sig, generics, _) = &it.kind { let mut error = false; if !generics.params.is_empty() { - struct_span_err!( - tcx.sess, - generics.span, - E0132, - "start function is not allowed to have type parameters" - ) - .span_label(generics.span, "start function cannot have type parameters") - .emit(); + tcx.sess.emit_err(errors::StartFunctionParameters { span: generics.span }); error = true; } if generics.has_where_clause_predicates { - struct_span_err!( - tcx.sess, - generics.where_clause_span, - E0647, - "start function is not allowed to have a `where` clause" - ) - .span_label( - generics.where_clause_span, - "start function cannot have a `where` clause", - ) - .emit(); + tcx.sess.emit_err(errors::StartFunctionWhere { + span: generics.where_clause_span, + }); error = true; } if let hir::IsAsync::Async = sig.header.asyncness { let span = tcx.def_span(it.owner_id); - struct_span_err!( - tcx.sess, - span, - E0752, - "`start` is not allowed to be `async`" - ) - .span_label(span, "`start` is not allowed to be `async`") - .emit(); + tcx.sess.emit_err(errors::StartAsync { span: span }); error = true; } let attrs = tcx.hir().attrs(start_id); for attr in attrs { if attr.has_name(sym::track_caller) { - tcx.sess - .struct_span_err( - attr.span, - "`start` is not allowed to be `#[track_caller]`", - ) - .span_label( - start_span, - "`start` is not allowed to be `#[track_caller]`", - ) - .emit(); + tcx.sess.emit_err(errors::StartTrackCaller { + span: attr.span, + start: start_span, + }); error = true; } } diff --git a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs index 324df313ef1..089491bef5e 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/missing_cast_for_variadic_arg.rs @@ -1,6 +1,6 @@ use crate::structured_errors::StructuredDiagnostic; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; -use rustc_middle::ty::{Ty, TypeVisitable}; +use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs index bb608805488..3b9fb367813 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/sized_unsized_cast.rs @@ -1,6 +1,6 @@ use crate::structured_errors::StructuredDiagnostic; use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorGuaranteed}; -use rustc_middle::ty::{Ty, TypeVisitable}; +use rustc_middle::ty::{Ty, TypeVisitableExt}; use rustc_session::Session; use rustc_span::Span; diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 560ffc620e0..cae884ae8fb 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -439,7 +439,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { fn create_error_message(&self) -> String { let def_path = self.tcx.def_path_str(self.def_id); - let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id); + let def_kind = self.tcx.def_descr(self.def_id); let (quantifier, bound) = self.get_quantifier_and_bound(); let kind = self.kind(); let provided_lt_args = self.num_provided_lifetime_args(); @@ -462,7 +462,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { if self.gen_args.span_ext().is_some() { format!( - "this {} takes {}{} {} argument{} but {} {} supplied", + "{} takes {}{} {} argument{} but {} {} supplied", def_kind, quantifier, bound, @@ -990,7 +990,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { }; let msg = { - let def_kind = self.tcx.def_kind(self.def_id).descr(self.def_id); + let def_kind = self.tcx.def_descr(self.def_id); let (quantifier, bound) = self.get_quantifier_and_bound(); let params = if bound == 0 { diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index fb63bf22474..5d5c8ca604a 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -7,10 +7,8 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -#[cfg(not(bootstrap))] -use rustc_middle::ty::TypeVisitable; use rustc_middle::ty::{self, CrateVariancesMap, SubstsRef, Ty, TyCtxt}; -use rustc_middle::ty::{DefIdTree, TypeSuperVisitable}; +use rustc_middle::ty::{DefIdTree, TypeSuperVisitable, TypeVisitable}; use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can @@ -101,7 +99,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc } } - impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> { + impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeLifetimeCollector<'tcx> { #[instrument(level = "trace", skip(self), ret)] fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 7dcf9d8299f..c021fca7133 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -358,7 +358,7 @@ impl<'a> State<'a> { self.print_anon_const(e); self.word(")"); } - hir::TyKind::Err => { + hir::TyKind::Err(_) => { self.popen(); self.word("/*ERROR*/"); self.pclose(); @@ -1559,7 +1559,7 @@ impl<'a> State<'a> { self.word_space("yield"); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } - hir::ExprKind::Err => { + hir::ExprKind::Err(_) => { self.popen(); self.word("/*ERROR*/"); self.pclose(); diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_hir_typeck/locales/en-US.ftl index 05ac8db0db8..adfcbc36a4d 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl +++ b/compiler/rustc_hir_typeck/locales/en-US.ftl @@ -1,17 +1,26 @@ -hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression -hir_typeck_fru_expr = this expression does not end in a comma... -hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax -hir_typeck_fru_suggestion = - to set the remaining fields{$expr -> - [NONE]{""} - *[other] {" "}from `{$expr}` - }, separate the last named field with a comma - hir_typeck_field_multiply_specified_in_initializer = field `{$ident}` specified more than once .label = used more than once .previous_use_label = first use of `{$ident}` +hir_typeck_copy_impl_on_type_with_dtor = + the trait `Copy` may not be implemented for this type; the type has a destructor + .label = `Copy` not allowed on types with destructors + +hir_typeck_multiple_relaxed_default_bounds = + type parameter has more than one relaxed default bound, only one is supported + +hir_typeck_copy_impl_on_non_adt = + the trait `Copy` may not be implemented for this type + .label = type is not a structure or enumeration + +hir_typeck_trait_object_declared_with_no_traits = + at least one trait is required for an object type + .alias_span = this alias does not contain a trait + +hir_typeck_functional_record_update_on_non_struct = + functional record update syntax requires a struct + hir_typeck_return_stmt_outside_of_fn_body = return statement outside of function body .encl_body_label = the return is part of this body... @@ -26,9 +35,6 @@ hir_typeck_struct_expr_non_exhaustive = hir_typeck_method_call_on_unknown_type = the type of this value must be known to call a method on a raw pointer on it -hir_typeck_functional_record_update_on_non_struct = - functional record update syntax requires a struct - hir_typeck_address_of_temporary_taken = cannot take address of a temporary .label = temporary value @@ -44,9 +50,6 @@ hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function -hir_typeck_op_trait_generic_params = - `{$method_name}` must not have any generic parameters - hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count} @@ -63,3 +66,14 @@ hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide hir_typeck_convert_to_str = try converting the passed type into a `&str` + +hir_typeck_op_trait_generic_params = `{$method_name}` must not have any generic parameters + +hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression +hir_typeck_fru_expr = this expression does not end in a comma... +hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax +hir_typeck_fru_suggestion = + to set the remaining fields{$expr -> + [NONE]{""} + *[other] {" "}from `{$expr}` + }, separate the last named field with a comma diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 089863a66e7..6a0d5c01109 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, }; use rustc_middle::ty::SubstsRef; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident}; use rustc_span::Span; @@ -232,7 +232,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some(trait_def_id) = opt_trait_def_id else { continue }; let opt_input_type = opt_arg_exprs.map(|arg_exprs| { - self.tcx.mk_tup(arg_exprs.iter().map(|e| { + self.tcx.mk_tup_from_iter(arg_exprs.iter().map(|e| { self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span: e.span, @@ -247,6 +247,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { adjusted_ty, opt_input_type.as_ref().map(slice::from_ref), ) { + // Check for `self` receiver on the method, otherwise we can't use this as a `Fn*` trait. + if !self.tcx.associated_item(ok.value.def_id).fn_has_self_parameter { + self.tcx.sess.delay_span_bug( + call_expr.span, + "input to overloaded call fn is not a self receiver", + ); + return None; + } + let method = self.register_infer_ok_obligations(ok); let mut autoref = None; if borrow { @@ -257,7 +266,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // caused an error elsewhere. self.tcx .sess - .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref?"); + .delay_span_bug(call_expr.span, "input to call/call_mut is not a ref"); return None; }; @@ -271,6 +280,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { target: method.sig.inputs()[0], }); } + return Some((autoref, method)); } } @@ -428,7 +438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let err = self.report_invalid_callee(call_expr, callee_expr, callee_ty, arg_exprs); - return self.tcx.ty_error_with_guaranteed(err); + return self.tcx.ty_error(err); } }; @@ -661,7 +671,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && !self.type_is_sized_modulo_regions(self.param_env, output_ty, callee_expr.span) { let descr = match maybe_def { - DefIdOrName::DefId(def_id) => self.tcx.def_kind(def_id).descr(def_id), + DefIdOrName::DefId(def_id) => self.tcx.def_descr(def_id), DefIdOrName::Name(name) => name, }; err.span_label( @@ -823,7 +833,7 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> { ); err.help( "make sure the `fn`/`fn_mut`/`fn_once` lang items are defined \ - and have associated `call`/`call_mut`/`call_once` functions", + and have correctly defined `call`/`call_mut`/`call_once` methods", ); err.emit(); } diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 8e21c084841..316c2a7eeeb 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -41,7 +41,7 @@ use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; use rustc_middle::ty::error::TypeError; -use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitable, VariantDef}; +use rustc_middle::ty::{self, Ty, TypeAndMut, TypeVisitableExt, VariantDef}; use rustc_session::lint; use rustc_session::Session; use rustc_span::def_id::{DefId, LOCAL_CRATE}; diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index cf296a7bf65..d84fabb7834 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -3,6 +3,7 @@ use super::{check_fn, Expectation, FnCtxt, GeneratorTypes}; use hir::def::DefKind; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_hir_analysis::astconv::AstConv; @@ -11,8 +12,8 @@ use rustc_infer::infer::LateBoundRegionConversionTime; use rustc_infer::infer::{InferOk, InferResult}; use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable}; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; use rustc_span::sym; @@ -126,7 +127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // the `closures` table. let sig = bound_sig.map_bound(|sig| { self.tcx.mk_fn_sig( - [self.tcx.intern_tup(sig.inputs())], + [self.tcx.mk_tup(sig.inputs())], sig.output(), sig.c_variadic, sig.unsafety, @@ -488,17 +489,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expected_span = expected_sig.cause_span.unwrap_or_else(|| self.tcx.def_span(expr_def_id)); - self.report_arg_count_mismatch( - expected_span, - closure_span, - expected_args, - found_args, - true, - closure_arg_span, - ) - .emit(); - - let error_sig = self.error_sig_of_closure(decl); + let guar = self + .report_arg_count_mismatch( + expected_span, + closure_span, + expected_args, + found_args, + true, + closure_arg_span, + ) + .emit(); + + let error_sig = self.error_sig_of_closure(decl, guar); self.closure_sigs(expr_def_id, body, error_sig) } @@ -561,8 +563,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { // Check that E' = S'. let cause = self.misc(hir_ty.span); - let InferOk { value: (), obligations } = - self.at(&cause, self.param_env).eq(*expected_ty, supplied_ty)?; + let InferOk { value: (), obligations } = self + .at(&cause, self.param_env) + .define_opaque_types(true) + .eq(*expected_ty, supplied_ty)?; all_obligations.extend(obligations); } @@ -574,6 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let cause = &self.misc(decl.output.span()); let InferOk { value: (), obligations } = self .at(cause, self.param_env) + .define_opaque_types(true) .eq(expected_sigs.liberated_sig.output(), supplied_output_ty)?; all_obligations.extend(obligations); @@ -789,13 +794,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// Converts the types that the user supplied, in case that doing /// so should yield an error, but returns back a signature where /// all parameters are of type `TyErr`. - fn error_sig_of_closure(&self, decl: &hir::FnDecl<'_>) -> ty::PolyFnSig<'tcx> { + fn error_sig_of_closure( + &self, + decl: &hir::FnDecl<'_>, + guar: ErrorGuaranteed, + ) -> ty::PolyFnSig<'tcx> { let astconv: &dyn AstConv<'_> = self; + let err_ty = self.tcx.ty_error(guar); let supplied_arguments = decl.inputs.iter().map(|a| { // Convert the types that the user supplied (if any), but ignore them. astconv.ast_ty_to_ty(a); - self.tcx.ty_error() + err_ty }); if let hir::FnRetTy::Return(ref output) = decl.output { @@ -804,7 +814,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = ty::Binder::dummy(self.tcx.mk_fn_sig( supplied_arguments, - self.tcx.ty_error(), + err_ty, decl.c_variadic, hir::Unsafety::Normal, Abi::RustCall, diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index ba503bf47e7..00b86890b33 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -54,7 +54,7 @@ use rustc_middle::ty::adjustment::{ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; @@ -143,11 +143,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { fn unify(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> InferResult<'tcx, Ty<'tcx>> { debug!("unify(a: {:?}, b: {:?}, use_lub: {})", a, b, self.use_lub); self.commit_if_ok(|_| { + let at = self.at(&self.cause, self.fcx.param_env).define_opaque_types(true); if self.use_lub { - self.at(&self.cause, self.fcx.param_env).lub(b, a) + at.lub(b, a) } else { - self.at(&self.cause, self.fcx.param_env) - .sup(b, a) + at.sup(b, a) .map(|InferOk { value: (), obligations }| InferOk { value: a, obligations }) } }) @@ -170,12 +170,14 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { debug!("Coerce.tys({:?} => {:?})", a, b); // Just ignore error types. - if a.references_error() || b.references_error() { + if let Err(guar) = (a, b).error_reported() { // Best-effort try to unify these types -- we're already on the error path, // so this will have the side-effect of making sure we have no ambiguities // due to `[type error]` and `_` not coercing together. - let _ = self.commit_if_ok(|_| self.at(&self.cause, self.param_env).eq(a, b)); - return success(vec![], self.fcx.tcx.ty_error(), vec![]); + let _ = self.commit_if_ok(|_| { + self.at(&self.cause, self.param_env).define_opaque_types(true).eq(a, b) + }); + return success(vec![], self.fcx.tcx.ty_error(guar), vec![]); } // Coercing from `!` to any type is allowed: @@ -995,7 +997,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (adjustments, _) = self.register_infer_ok_obligations(ok); self.apply_adjustments(expr, adjustments); - Ok(if expr_ty.references_error() { self.tcx.ty_error() } else { target }) + Ok(if let Err(guar) = expr_ty.error_reported() { self.tcx.ty_error(guar) } else { target }) } /// Same as `try_coerce()`, but without side-effects. @@ -1432,8 +1434,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // If we see any error types, just propagate that error // upwards. - if expression_ty.references_error() || self.merged_ty().references_error() { - self.final_ty = Some(fcx.tcx.ty_error()); + if let Err(guar) = (expression_ty, self.merged_ty()).error_reported() { + self.final_ty = Some(fcx.tcx.ty_error(guar)); return; } @@ -1484,6 +1486,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // Another example is `break` with no argument expression. assert!(expression_ty.is_unit(), "if let hack without unit type"); fcx.at(cause, fcx.param_env) + // needed for tests/ui/type-alias-impl-trait/issue-65679-inst-opaque-ty-from-val-twice.rs + .define_opaque_types(true) .eq_exp(label_expression_as_expected, expression_ty, self.merged_ty()) .map(|infer_ok| { fcx.register_infer_ok_obligations(infer_ok); @@ -1616,7 +1620,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let reported = err.emit_unless(unsized_return); - self.final_ty = Some(fcx.tcx.ty_error_with_guaranteed(reported)); + self.final_ty = Some(fcx.tcx.ty_error(reported)); } } } diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 879a64fc0fb..34d62987c3b 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::{BottomUpFolder, TypeFolder}; use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::relate::TypeRelation; -use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitable}; +use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span}; use rustc_trait_selection::infer::InferCtxtExt as _; @@ -113,7 +113,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { - match self.at(cause, self.param_env).sup(expected, actual) { + match self.at(cause, self.param_env).define_opaque_types(true).sup(expected, actual) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); None @@ -143,7 +143,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Ty<'tcx>, actual: Ty<'tcx>, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { - match self.at(cause, self.param_env).eq(expected, actual) { + match self.at(cause, self.param_env).define_opaque_types(true).eq(expected, actual) { Ok(InferOk { obligations, value: () }) => { self.register_predicates(obligations); None diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 2c8979402b6..3eee2278dca 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,4 +1,5 @@ //! Errors emitted by `rustc_hir_typeck`. +use crate::fluent_generated as fluent; use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; @@ -14,7 +15,7 @@ pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] pub span: Span, - #[label(previous_use_label)] + #[label(hir_typeck_previous_use_label)] pub prev_span: Span, pub ident: Ident, } @@ -24,9 +25,9 @@ pub struct FieldMultiplySpecifiedInInitializer { pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, - #[label(encl_body_label)] + #[label(hir_typeck_encl_body_label)] pub encl_body_span: Option<Span>, - #[label(encl_fn_label)] + #[label(hir_typeck_encl_fn_label)] pub encl_fn_span: Option<Span>, } @@ -157,20 +158,17 @@ impl AddToDiagnostic for TypeMismatchFruTypo { // Only explain that `a ..b` is a range if it's split up if self.expr_span.between(self.fru_span).is_empty() { - diag.span_note( - self.expr_span.to(self.fru_span), - rustc_errors::fluent::hir_typeck_fru_note, - ); + diag.span_note(self.expr_span.to(self.fru_span), fluent::hir_typeck_fru_note); } else { let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into(); - multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr); - multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2); - diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note); + multispan.push_span_label(self.expr_span, fluent::hir_typeck_fru_expr); + multispan.push_span_label(self.fru_span, fluent::hir_typeck_fru_expr2); + diag.span_note(multispan, fluent::hir_typeck_fru_note); } diag.span_suggestion( self.expr_span.shrink_to_hi(), - rustc_errors::fluent::hir_typeck_fru_suggestion, + fluent::hir_typeck_fru_suggestion, ", ", Applicability::MaybeIncorrect, ); diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 08cbfffdd17..7fc4ccb04ee 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -42,7 +42,7 @@ use rustc_middle::middle::stability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase}; use rustc_middle::ty::error::TypeError::FieldMisMatch; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitable}; +use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::parse::feature_err; use rustc_span::edit_distance::find_best_match_for_name; @@ -88,7 +88,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &adjustments[..] { target.to_owned() } else { - self.tcx().ty_error_with_guaranteed(reported) + self.tcx().ty_error(reported) }; } @@ -313,7 +313,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.types.never } else { // There was an error; make type-check fail. - tcx.ty_error() + tcx.ty_error_misc() } } ExprKind::Ret(ref expr_opt) => self.check_expr_return(expr_opt.as_deref(), expr), @@ -354,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Field(base, field) => self.check_field(expr, &base, field, expected), ExprKind::Index(base, idx) => self.check_expr_index(base, idx, expr), ExprKind::Yield(value, ref src) => self.check_expr_yield(value, expr, src), - hir::ExprKind::Err => tcx.ty_error(), + hir::ExprKind::Err(guar) => tcx.ty_error(guar), } } @@ -402,7 +402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); } - oprnd_t = tcx.ty_error_with_guaranteed(err.emit()); + oprnd_t = tcx.ty_error(err.emit()); } } hir::UnOp::Not => { @@ -452,7 +452,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tm = ty::TypeAndMut { ty, mutbl }; match kind { - _ if tm.ty.references_error() => self.tcx.ty_error(), + _ if tm.ty.references_error() => self.tcx.ty_error_misc(), hir::BorrowKind::Raw => { self.check_named_place_expr(oprnd); self.tcx.mk_ptr(tm) @@ -531,11 +531,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - tcx.ty_error_with_guaranteed(e) + tcx.ty_error(e) } Res::Def(DefKind::Variant, _) => { let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value"); - tcx.ty_error_with_guaranteed(e) + tcx.ty_error(e) } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, }; @@ -634,7 +634,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the loop context is not a `loop { }`, then break with // a value is illegal, and `opt_coerce_to` will be `None`. // Just set expectation to error in that case. - let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error()); + let coerce_to = opt_coerce_to.unwrap_or_else(|| tcx.ty_error_misc()); // Recurse without `enclosing_breakables` borrowed. e_ty = self.check_expr_with_hint(e, coerce_to); @@ -1033,7 +1033,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let result_ty = coerce.complete(self); - if cond_ty.references_error() { self.tcx.ty_error() } else { result_ty } + if let Err(guar) = cond_ty.error_reported() { self.tcx.ty_error(guar) } else { result_ty } } /// Type check assignment expression `expr` of form `lhs = rhs`. @@ -1109,7 +1109,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If the assignment expression itself is ill-formed, don't // bother emitting another error let reported = err.emit_unless(lhs_ty.references_error() || rhs_ty.references_error()); - return self.tcx.ty_error_with_guaranteed(reported); + return self.tcx.ty_error(reported); } let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); @@ -1155,8 +1155,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.require_type_is_sized(lhs_ty, lhs.span, traits::AssignmentLhsSized); - if lhs_ty.references_error() || rhs_ty.references_error() { - self.tcx.ty_error() + if let Err(guar) = (lhs_ty, rhs_ty).error_reported() { + self.tcx.ty_error(guar) } else { self.tcx.mk_unit() } @@ -1274,8 +1274,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let t_expr = self.resolve_vars_if_possible(t_expr); // Eagerly check for some obvious errors. - if t_expr.references_error() || t_cast.references_error() { - self.tcx.ty_error() + if let Err(guar) = (t_expr, t_cast).error_reported() { + self.tcx.ty_error(guar) } else { // Defer other checks until we're done type checking. let mut deferred_cast_checks = self.deferred_cast_checks.borrow_mut(); @@ -1296,7 +1296,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { deferred_cast_checks.push(cast_check); t_cast } - Err(_) => self.tcx.ty_error(), + Err(guar) => self.tcx.ty_error(guar), } } } @@ -1423,8 +1423,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; - if element_ty.references_error() { - return tcx.ty_error(); + if let Err(guar) = element_ty.error_reported() { + return tcx.ty_error(guar); } self.check_repeat_element_needs_copy_bound(element, count, element_ty); @@ -1492,9 +1492,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } _ => self.check_expr_with_expectation(&e, NoExpectation), }); - let tuple = self.tcx.mk_tup(elt_ts_iter); - if tuple.references_error() { - self.tcx.ty_error() + let tuple = self.tcx.mk_tup_from_iter(elt_ts_iter); + if let Err(guar) = tuple.error_reported() { + self.tcx.ty_error(guar) } else { self.require_type_is_sized(tuple, expr.span, traits::TupleInitializerSized); tuple @@ -1510,9 +1510,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base_expr: &'tcx Option<&'tcx hir::Expr<'tcx>>, ) -> Ty<'tcx> { // Find the relevant variant - let Some((variant, adt_ty)) = self.check_struct_path(qpath, expr.hir_id) else { - self.check_struct_fields_on_error(fields, base_expr); - return self.tcx.ty_error(); + let (variant, adt_ty) = match self.check_struct_path(qpath, expr.hir_id) { + Ok(data) => data, + Err(guar) => { + self.check_struct_fields_on_error(fields, base_expr); + return self.tcx.ty_error(guar); + } }; // Prohibit struct expressions when non-exhaustive flag is set. @@ -1594,12 +1597,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.field_ty(field.span, v_field, substs) } else { error_happened = true; - if let Some(prev_span) = seen_fields.get(&ident) { + let guar = if let Some(prev_span) = seen_fields.get(&ident) { tcx.sess.emit_err(FieldMultiplySpecifiedInInitializer { span: field.ident.span, prev_span: *prev_span, ident, - }); + }) } else { self.report_unknown_field( adt_ty, @@ -1608,10 +1611,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ast_fields, adt.variant_descr(), expr_span, - ); - } + ) + }; - tcx.ty_error() + tcx.ty_error(guar) }; // Make sure to give a type to the field even if there's @@ -1994,14 +1997,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { skip_fields: &[hir::ExprField<'_>], kind_name: &str, expr_span: Span, - ) { + ) -> ErrorGuaranteed { if variant.is_recovered() { - self.set_tainted_by_errors( - self.tcx - .sess - .delay_span_bug(expr_span, "parser recovered but no error was emitted"), - ); - return; + let guar = self + .tcx + .sess + .delay_span_bug(expr_span, "parser recovered but no error was emitted"); + self.set_tainted_by_errors(guar); + return guar; } let mut err = self.err_ctxt().type_error_struct_with_diag( field.ident.span, @@ -2115,7 +2118,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; } } - err.emit(); + err.emit() } // Return a hint about the closest match in field names @@ -2256,11 +2259,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // (#90483) apply adjustments to avoid ExprUseVisitor from // creating erroneous projection. self.apply_adjustments(base, adjustments); - self.ban_private_field_access(expr, base_ty, field, did, expected.only_has_type(self)); - return self.tcx().ty_error(); + let guar = self.ban_private_field_access( + expr, + base_ty, + field, + did, + expected.only_has_type(self), + ); + return self.tcx().ty_error(guar); } - if field.name == kw::Empty { + let guar = if field.name == kw::Empty { + self.tcx.sess.delay_span_bug(field.span, "field name with no name") } else if self.method_exists( field, base_ty, @@ -2268,9 +2278,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true, expected.only_has_type(self), ) { - self.ban_take_value_of_method(expr, base_ty, field); + self.ban_take_value_of_method(expr, base_ty, field) } else if !base_ty.is_primitive_ty() { - self.ban_nonexisting_field(field, base, expr, base_ty); + self.ban_nonexisting_field(field, base, expr, base_ty) } else { let field_name = field.to_string(); let mut err = type_error_struct!( @@ -2339,10 +2349,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - err.emit(); - } + err.emit() + }; - self.tcx().ty_error() + self.tcx().ty_error(guar) } fn suggest_await_on_field_access( @@ -2388,7 +2398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>, base_ty: Ty<'tcx>, - ) { + ) -> ErrorGuaranteed { debug!( "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}", ident, base, expr, base_ty @@ -2436,7 +2446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { HelpUseLatestEdition::new().add_to_diagnostic(&mut err); } - err.emit(); + err.emit() } fn ban_private_field_access( @@ -2446,9 +2456,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field: Ident, base_did: DefId, return_ty: Option<Ty<'tcx>>, - ) { + ) -> ErrorGuaranteed { let struct_path = self.tcx().def_path_str(base_did); - let kind_name = self.tcx().def_kind(base_did).descr(base_did); + let kind_name = self.tcx().def_descr(base_did); let mut err = struct_span_err!( self.tcx().sess, field.span, @@ -2469,10 +2479,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None, ); } - err.emit(); + err.emit() } - fn ban_take_value_of_method(&self, expr: &hir::Expr<'tcx>, expr_t: Ty<'tcx>, field: Ident) { + fn ban_take_value_of_method( + &self, + expr: &hir::Expr<'tcx>, + expr_t: Ty<'tcx>, + field: Ident, + ) -> ErrorGuaranteed { let mut err = type_error_struct!( self.tcx().sess, field.span, @@ -2544,7 +2559,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help("methods are immutable and cannot be assigned to"); } - err.emit(); + err.emit() } fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) { @@ -2829,7 +2844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } } } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c8cda0dc90c..b9a058d6bba 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -301,7 +301,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { hir::ExprKind::Continue(..) | hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) - | hir::ExprKind::Err => {} + | hir::ExprKind::Err(_) => {} hir::ExprKind::Loop(blk, ..) => { self.walk_block(blk); diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 943dc9b9646..b7ae621c685 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -104,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // type, `?T` is not considered unsolved, but `?I` is. The // same is true for float variables.) let fallback = match ty.kind() { - _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), + _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e), ty::Infer(ty::IntVar(_)) => self.tcx.types.i32, ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, _ => match diverging_fallback.get(&ty) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index b2f3a3abb4c..60e55c7b0cf 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -23,9 +23,9 @@ use rustc_infer::infer::InferResult; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, UserType, + self, AdtKind, CanonicalUserType, DefIdTree, GenericParamDefKind, Ty, TyCtxt, UserType, }; use rustc_middle::ty::{GenericArgKind, SubstsRef, UserSelfTy, UserSubsts}; use rustc_session::lint; @@ -315,7 +315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub(in super::super) fn normalize<T>(&self, span: Span, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.register_infer_ok_obligations( self.at(&self.misc(span), self.param_env).normalize(value), @@ -443,7 +443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // sufficiently enforced with erased regions. =) fn can_contain_user_lifetime_bounds<T>(t: T) -> bool where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { t.has_free_regions() || t.has_projections() || t.has_infer_types() } @@ -451,7 +451,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, - None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), + None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error(e), None => { bug!( "no type for node {} in fcx {}", @@ -465,7 +465,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), - None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)), + None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error(e)), None => None, } } @@ -701,7 +701,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } pub(in super::super) fn err_args(&self, len: usize) -> Vec<Ty<'tcx>> { - vec![self.tcx.ty_error(); len] + let ty_error = self.tcx.ty_error_misc(); + vec![ty_error; len] } /// Unifies the output type with the expected type early, for more coercions @@ -1161,7 +1162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - return (tcx.ty_error_with_guaranteed(reported), res); + return (tcx.ty_error(reported), res); } } } else { @@ -1417,7 +1418,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true) .emit() }); - let err = self.tcx.ty_error_with_guaranteed(e); + let err = self.tcx.ty_error(e); self.demand_suptype(sp, err, ty); err } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index 39e0ea98f96..d64492e503d 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -4,7 +4,7 @@ use rustc_hir::def::Res; use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCauseCode; use rustc_middle::ty::{ - self, ir::TypeVisitor, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + self, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_span::{self, Span}; use rustc_trait_selection::traits; @@ -243,7 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true } - fn find_ambiguous_parameter_in<T: TypeVisitable<'tcx>>( + fn find_ambiguous_parameter_in<T: TypeVisitable<TyCtxt<'tcx>>>( &self, item_def_id: DefId, t: T, diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 69a7235802b..2e62e13648c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -10,7 +10,9 @@ use crate::{ }; use rustc_ast as ast; use rustc_data_structures::fx::FxIndexSet; -use rustc_errors::{pluralize, Applicability, Diagnostic, DiagnosticId, MultiSpan}; +use rustc_errors::{ + pluralize, Applicability, Diagnostic, DiagnosticId, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; @@ -25,7 +27,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi use rustc_infer::infer::InferOk; use rustc_infer::infer::TypeTrace; use rustc_middle::ty::adjustment::AllowTwoPhase; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, DefIdTree, IsSuggestable, Ty}; use rustc_session::Session; use rustc_span::symbol::{kw, Ident}; @@ -72,7 +74,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); if ty.has_non_region_infer() { - self.tcx.ty_error() + self.tcx.ty_error_misc() } else { self.tcx.erase_regions(ty) } @@ -100,7 +102,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, - TupleArguments => vec![self.tcx.intern_tup(&err_inputs)], + TupleArguments => vec![self.tcx.mk_tup(&err_inputs)], }; self.check_argument_types( @@ -113,7 +115,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tuple_arguments, method.ok().map(|method| method.def_id), ); - return self.tcx.ty_error(); + return self.tcx.ty_error_misc(); } let method = method.unwrap(); @@ -533,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .typeck_results .borrow() .expr_ty_adjusted_opt(*expr) - .unwrap_or_else(|| tcx.ty_error()); + .unwrap_or_else(|| tcx.ty_error_misc()); (self.resolve_vars_if_possible(ty), normalize_span(expr.span)) }) .collect(); @@ -640,7 +642,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && provided_arg_tys.len() == formal_and_expected_inputs.len() - 1 + tys.len() { // Wrap up the N provided arguments starting at this position in a tuple. - let provided_as_tuple = tcx.mk_tup( + let provided_as_tuple = tcx.mk_tup_from_iter( provided_arg_tys.iter().map(|(ty, _)| *ty).skip(mismatch_idx).take(tys.len()), ); @@ -932,25 +934,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { labels .push((provided_span, format!("unexpected argument{}", provided_ty_name))); let mut span = provided_span; - if arg_idx.index() > 0 + if span.can_be_used_for_suggestions() { + if arg_idx.index() > 0 && let Some((_, prev)) = provided_arg_tys .get(ProvidedIdx::from_usize(arg_idx.index() - 1) ) { // Include previous comma - span = span.with_lo(prev.hi()); - } else if let Some((_, next)) = provided_arg_tys.get( - ProvidedIdx::from_usize(arg_idx.index() + 1), - ) { - // Include next comma - span = span.until(*next); + span = prev.shrink_to_hi().to(span); } - suggestions.push((span, String::new())); + suggestions.push((span, String::new())); - suggestion_text = match suggestion_text { - SuggestionText::None => SuggestionText::Remove(false), - SuggestionText::Remove(_) => SuggestionText::Remove(true), - _ => SuggestionText::DidYouMean, - }; + suggestion_text = match suggestion_text { + SuggestionText::None => SuggestionText::Remove(false), + SuggestionText::Remove(_) => SuggestionText::Remove(true), + _ => SuggestionText::DidYouMean, + }; + } } Error::Missing(expected_idx) => { // If there are multiple missing arguments adjacent to each other, @@ -1289,7 +1288,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { opt_ty.unwrap_or_else(|| self.next_float_var()) } ast::LitKind::Bool(_) => tcx.types.bool, - ast::LitKind::Err => tcx.ty_error(), + ast::LitKind::Err => tcx.ty_error_misc(), } } @@ -1297,15 +1296,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, qpath: &QPath<'_>, hir_id: hir::HirId, - ) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { + ) -> Result<(&'tcx ty::VariantDef, Ty<'tcx>), ErrorGuaranteed> { let path_span = qpath.span(); let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); let variant = match def { Res::Err => { - self.set_tainted_by_errors( - self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"), - ); - return None; + let guar = + self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"); + self.set_tainted_by_errors(guar); + return Err(guar); } Res::Def(DefKind::Variant, _) => match ty.normalized.ty_adt_def() { Some(adt) => { @@ -1333,28 +1332,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Check bounds on type arguments used in the path. self.add_required_obligations_for_hir(path_span, did, substs, hir_id); - Some((variant, ty.normalized)) + Ok((variant, ty.normalized)) } else { - match ty.normalized.kind() { - ty::Error(_) => { + Err(match *ty.normalized.kind() { + ty::Error(guar) => { // E0071 might be caused by a spelling error, which will have // already caused an error message and probably a suggestion // elsewhere. Refrain from emitting more unhelpful errors here // (issue #88844). + guar } - _ => { - struct_span_err!( - self.tcx.sess, - path_span, - E0071, - "expected struct, variant or union type, found {}", - ty.normalized.sort_string(self.tcx) - ) - .span_label(path_span, "not a struct") - .emit(); - } - } - None + _ => struct_span_err!( + self.tcx.sess, + path_span, + E0071, + "expected struct, variant or union type, found {}", + ty.normalized.sort_string(self.tcx) + ) + .span_label(path_span, "not a struct") + .emit(), + }) } } @@ -1718,9 +1715,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pat: &'tcx hir::Pat<'tcx>, ty: Ty<'tcx>, ) { - if ty.references_error() { + if let Err(guar) = ty.error_reported() { // Override the types everywhere with `err()` to avoid knock on errors. - let err = self.tcx.ty_error(); + let err = self.tcx.ty_error(guar); self.write_ty(hir_id, err); self.write_ty(pat.hir_id, err); let local_ty = LocalTy { decl_ty: err, revealed_ty: err }; @@ -1749,7 +1746,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let result = self .astconv() .associated_path_to_ty(hir_id, path_span, ty.raw, qself, segment, true); - let ty = result.map(|(ty, _, _)| ty).unwrap_or_else(|_| self.tcx().ty_error()); + let ty = + result.map(|(ty, _, _)| ty).unwrap_or_else(|guar| self.tcx().ty_error(guar)); let ty = self.handle_raw_ty(path_span, ty); let result = result.map(|(_, kind, def_id)| (kind, def_id)); @@ -1941,8 +1939,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { spans.push_span_label(param.span, ""); } - let def_kind = self.tcx.def_kind(def_id); - err.span_note(spans, &format!("{} defined here", def_kind.descr(def_id))); + err.span_note(spans, &format!("{} defined here", self.tcx.def_descr(def_id))); } else if let Some(hir::Node::Expr(e)) = self.tcx.hir().get_if_local(def_id) && let hir::ExprKind::Closure(hir::Closure { body, .. }) = &e.kind { @@ -1955,10 +1952,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; err.span_note(span, &format!("{} defined here", kind)); } else { - let def_kind = self.tcx.def_kind(def_id); err.span_note( self.tcx.def_span(def_id), - &format!("{} defined here", def_kind.descr(def_id)), + &format!("{} defined here", self.tcx.def_descr(def_id)), ); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 3814ddaf73f..1dea3e6f900 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::error_reporting::TypeErrCtxt; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt}; use rustc_session::Session; use rustc_span::symbol::Ident; use rustc_span::{self, Span, DUMMY_SP}; diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 3539202d1ca..c49621b7c24 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -1,9 +1,10 @@ use super::FnCtxt; use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel}; +use crate::fluent_generated as fluent; use crate::method::probe::{IsSuggestion, Mode, ProbeScope}; use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX}; -use rustc_errors::{fluent, Applicability, Diagnostic, MultiSpan}; +use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::lang_items::LangItem; @@ -16,7 +17,7 @@ use rustc_middle::lint::in_external_macro; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ self, suggest_constraining_type_params, Binder, DefIdTree, IsSuggestable, ToPredicate, Ty, - TypeVisitable, + TypeVisitableExt, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -120,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { DefIdOrName::DefId(def_id) => match self.tcx.def_kind(def_id) { DefKind::Ctor(CtorOf::Struct, _) => "construct this tuple struct".to_string(), DefKind::Ctor(CtorOf::Variant, _) => "construct this tuple variant".to_string(), - kind => format!("call this {}", kind.descr(def_id)), + kind => format!("call this {}", self.tcx.def_kind_descr(kind, def_id)), }, DefIdOrName::Name(name) => format!("call this {name}"), }; @@ -339,7 +340,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { CtorOf::Variant => "an enum variant", })); } else { - let descr = kind.descr(def_id); + let descr = self.tcx.def_kind_descr(kind, def_id); err.span_label(sp, format!("{descr} `{name}` defined here")); } return true; diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index b3dd3031db2..7c0402b1c7f 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -12,7 +12,7 @@ use rustc_index::vec::IndexVec; use rustc_infer::infer::InferCtxt; use rustc_middle::{ hir::map::Map, - ty::{ParamEnv, TyCtxt, TypeVisitable, TypeckResults}, + ty::{ParamEnv, TyCtxt, TypeVisitableExt, TypeckResults}, }; use std::mem::swap; @@ -219,7 +219,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { | ExprKind::Struct(..) | ExprKind::Repeat(..) | ExprKind::Yield(..) - | ExprKind::Err => (), + | ExprKind::Err(_) => (), } } @@ -483,7 +483,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> { | ExprKind::Closure { .. } | ExprKind::ConstBlock(..) | ExprKind::DropTemps(..) - | ExprKind::Err + | ExprKind::Err(_) | ExprKind::Field(..) | ExprKind::Index(..) | ExprKind::InlineAsm(..) diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs index ed3d8903157..fa3887362d9 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs @@ -9,7 +9,7 @@ use rustc_hir as hir; use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_middle::{ hir::place::{PlaceBase, Projection, ProjectionKind}, - ty::TypeVisitable, + ty::TypeVisitableExt, }; pub(super) fn find_consumed_and_borrowed<'a, 'tcx>( diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 14e3ba83b10..2e41c2041f8 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -16,7 +16,7 @@ use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind}; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData}; use rustc_middle::ty::fold::FnMutDelegate; -use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::Span; use smallvec::{smallvec, SmallVec}; @@ -311,8 +311,8 @@ pub fn resolve_interior<'a, 'tcx>( }; // Extract type components to build the witness type. - let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty)); - let bound_vars = fcx.tcx.intern_bound_variable_kinds(&bound_vars); + let type_list = fcx.tcx.mk_type_list_from_iter(type_causes.iter().map(|cause| cause.ty)); + let bound_vars = fcx.tcx.mk_bound_variable_kinds(&bound_vars); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind_with_vars(type_list, bound_vars.clone())); diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs index 87e54025330..26020382d81 100644 --- a/compiler/rustc_hir_typeck/src/inherited.rs +++ b/compiler/rustc_hir_typeck/src/inherited.rs @@ -6,7 +6,7 @@ use rustc_hir::def_id::LocalDefId; use rustc_hir::HirIdMap; use rustc_infer::infer; use rustc_infer::infer::{DefiningAnchor, InferCtxt, InferOk, TyCtxtInferExt}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::def_id::LocalDefIdMap; use rustc_span::{self, Span}; diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 2c76582f2ec..19d2befc438 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -3,7 +3,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_target::abi::{Pointer, VariantIdx}; use super::FnCtxt; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 0204beb6fb8..91fd8fad73c 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -53,7 +53,10 @@ use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; use crate::gather_locals::GatherLocalsVisitor; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ + struct_span_err, DiagnosticId, DiagnosticMessage, ErrorGuaranteed, MultiSpan, + SubdiagnosticMessage, +}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; @@ -61,13 +64,16 @@ use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::check_abi; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::config; use rustc_session::Session; use rustc_span::def_id::{DefId, LocalDefId}; -use rustc_span::Span; +use rustc_span::{sym, Span}; + +fluent_messages! { "../locales/en-US.ftl" } #[macro_export] macro_rules! type_error_struct { @@ -201,6 +207,11 @@ fn typeck_with_fallback<'tcx>( let typeck_results = Inherited::build(tcx, def_id).enter(|inh| { let param_env = tcx.param_env(def_id); + let param_env = if tcx.has_attr(def_id.to_def_id(), sym::rustc_do_not_const_check) { + param_env.without_const() + } else { + param_env + }; let mut fcx = FnCtxt::new(&inh, param_env, def_id); if let Some(hir::FnSig { header, decl, .. }) = fn_sig { diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 4b08832eddc..bcfc61bffb2 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -51,7 +51,7 @@ use rustc_middle::hir::place::*; use rustc_middle::ty::adjustment; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; @@ -126,7 +126,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { fn resolve_vars_if_possible<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.infcx.resolve_vars_if_possible(value) } @@ -383,7 +383,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | hir::ExprKind::Repeat(..) | hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) - | hir::ExprKind::Err => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), + | hir::ExprKind::Err(_) => Ok(self.cat_rvalue(expr.hir_id, expr.span, expr_ty)), } } diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index f7de55c989f..169f128e0a0 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; use rustc_middle::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::{self, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty, TyCtxt}; use rustc_middle::ty::{InternalSubsts, UserSubsts, UserType}; use rustc_span::{Span, DUMMY_SP}; use rustc_trait_selection::traits; @@ -635,7 +635,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn instantiate_binder_with_fresh_vars<T>(&self, value: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable<TyCtxt<'tcx>> + Copy, { self.fcx.instantiate_binder_with_fresh_vars(self.span, infer::FnCall, value) } diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index d5d10cf272a..0456dd56c34 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::{self, InferOk}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; -use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitable}; +use rustc_middle::ty::{self, GenericParamDefKind, Ty, TypeVisitableExt}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; @@ -380,6 +380,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); return None; }; + + if method_item.kind != ty::AssocKind::Fn { + self.tcx.sess.delay_span_bug(tcx.def_span(method_item.def_id), "not a method"); + return None; + } + let def_id = method_item.def_id; let generics = tcx.generics_of(def_id); diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 88af554483b..3bef5cfcd78 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -19,7 +19,7 @@ use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; use rustc_middle::ty::ToPredicate; -use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::lint; use rustc_span::def_id::DefId; @@ -1095,17 +1095,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } fn pick_core(&self) -> Option<PickResult<'tcx>> { - let pick = self.pick_all_method(Some(&mut vec![])); - - // In this case unstable picking is done by `pick_method`. - if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable { - return pick; - } - - if pick.is_none() { - return self.pick_all_method(None); - } - pick + // Pick stable methods only first, and consider unstable candidates if not found. + self.pick_all_method(Some(&mut vec![])).or_else(|| self.pick_all_method(None)) } fn pick_all_method( @@ -1244,54 +1235,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }) } - fn pick_method_with_unstable(&self, self_ty: Ty<'tcx>) -> Option<PickResult<'tcx>> { - debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty)); - - let mut possibly_unsatisfied_predicates = Vec::new(); - - for (kind, candidates) in - &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] - { - debug!("searching {} candidates", kind); - let res = self.consider_candidates( - self_ty, - candidates, - &mut possibly_unsatisfied_predicates, - Some(&mut vec![]), - ); - if res.is_some() { - return res; - } - } - - for (kind, candidates) in - &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] - { - debug!("searching unstable {kind} candidates"); - let res = self.consider_candidates( - self_ty, - candidates, - &mut possibly_unsatisfied_predicates, - None, - ); - if res.is_some() { - return res; - } - } - - self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates); - None - } - fn pick_method( &self, self_ty: Ty<'tcx>, mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option<PickResult<'tcx>> { - if !self.tcx.sess.opts.unstable_opts.pick_stable_methods_before_any_unstable { - return self.pick_method_with_unstable(self_ty); - } - debug!("pick_method(self_ty={})", self.ty_to_string(self_ty)); let mut possibly_unsatisfied_predicates = Vec::new(); @@ -1418,8 +1366,8 @@ impl<'tcx> Pick<'tcx> { span, format!( "{} {} with this name may be added to the standard library in the future", - def_kind.article(), - def_kind.descr(self.item.def_id), + tcx.def_kind_descr_article(def_kind, self.item.def_id), + tcx.def_kind_descr(def_kind, self.item.def_id), ), |lint| { match (self.item.kind, self.item.container) { @@ -1488,7 +1436,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { TraitCandidate(trait_ref) => self.probe(|_| { let _ = self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(candidate.xform_self_ty, self_ty); match self.select_trait_candidate(trait_ref) { Ok(Some(traits::ImplSource::UserDefined(ref impl_data))) => { @@ -1518,7 +1465,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // First check that the self type can be related. let sub_obligations = match self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(probe.xform_self_ty, self_ty) { Ok(InferOk { obligations, value: () }) => obligations, @@ -1735,7 +1681,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if let ProbeResult::Match = result && self .at(&ObligationCause::dummy(), self.param_env) - .define_opaque_types(false) .sup(return_ty, xform_ret_ty) .is_err() { @@ -1960,7 +1905,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// so forth. fn erase_late_bound_regions<T>(&self, value: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.erase_late_bound_regions(value) } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4f3dbe03c05..47a4d4e72df 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -27,7 +27,7 @@ use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::{with_crate_prefix, with_forced_trimmed_paths}; -use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -160,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => { - let kind = kind.descr(def_id); + let kind = self.tcx.def_kind_descr(kind, def_id); let mut err = struct_span_err!( self.tcx.sess, item_name.span, @@ -574,7 +574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // `<Foo as Iterator>::Item = String`. let projection_ty = pred.skip_binder().projection_ty; - let substs_with_infer_self = tcx.mk_substs( + let substs_with_infer_self = tcx.mk_substs_from_iter( iter::once(tcx.mk_ty_var(ty::TyVid::from_u32(0)).into()) .chain(projection_ty.substs.iter().skip(1)), ); @@ -1062,8 +1062,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, &format!( "there is {} {} with a similar name", - def_kind.article(), - def_kind.descr(similar_candidate.def_id), + self.tcx.def_kind_descr_article(def_kind, similar_candidate.def_id), + self.tcx.def_kind_descr(def_kind, similar_candidate.def_id) ), similar_candidate.name, Applicability::MaybeIncorrect, @@ -1172,7 +1172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path, ty, item.kind, - item.def_id, + self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id), sugg_span, idx, self.tcx.sess.source_map(), @@ -1208,7 +1208,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { path, rcvr_ty, item.kind, - item.def_id, + self.tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id), sugg_span, idx, self.tcx.sess.source_map(), @@ -1252,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Adt(def, substs) = target_ty.kind() { // If there are any inferred arguments, (`{integer}`), we should replace // them with underscores to allow the compiler to infer them - let infer_substs = self.tcx.mk_substs(substs.into_iter().map(|arg| { + let infer_substs = self.tcx.mk_substs_from_iter(substs.into_iter().map(|arg| { if !arg.is_suggestable(self.tcx, true) { has_unsuggestable_args = true; match arg.unpack() { @@ -2853,7 +2853,7 @@ fn print_disambiguation_help<'tcx>( trait_name: String, rcvr_ty: Ty<'_>, kind: ty::AssocKind, - def_id: DefId, + def_kind_descr: &'static str, span: Span, candidate: Option<usize>, source_map: &source_map::SourceMap, @@ -2886,7 +2886,7 @@ fn print_disambiguation_help<'tcx>( span, &format!( "disambiguate the {} for {}", - kind.as_def_kind().descr(def_id), + def_kind_descr, if let Some(candidate) = candidate { format!("candidate #{}", candidate) } else { diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index c8256e7ec08..a4b325a9b79 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::{ }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ - self, ir::TypeFolder, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeSuperFoldable, TypeVisitable, + self, DefIdTree, IsSuggestable, Ty, TyCtxt, TypeFolder, TypeSuperFoldable, TypeVisitableExt, }; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; @@ -297,7 +297,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method.sig.output() } // error types are considered "builtin" - Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => self.tcx.ty_error(), + Err(_) if lhs_ty.references_error() || rhs_ty.references_error() => { + self.tcx.ty_error_misc() + } Err(errors) => { let (_, trait_def_id) = lang_item_for_op(self.tcx, Op::Binary(op, is_assign), op.span); @@ -518,7 +520,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } let reported = err.emit(); - self.tcx.ty_error_with_guaranteed(reported) + self.tcx.ty_error(reported) } }; @@ -631,7 +633,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(errors) => { let actual = self.resolve_vars_if_possible(operand_ty); - if !actual.references_error() { + let guar = actual.error_reported().err().unwrap_or_else(|| { let mut err = struct_span_err!( self.tcx.sess, ex.span, @@ -701,9 +703,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } } - err.emit(); - } - self.tcx.ty_error() + err.emit() + }); + self.tcx.ty_error(guar) } } } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index ab6e76ef8aa..c36c75e4443 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -12,7 +12,7 @@ use rustc_hir::{HirId, Pat, PatKind}; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::middle::stability::EvalResult; -use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitableExt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; @@ -475,8 +475,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { // There exists a side that didn't meet our criteria that the end-point // be of a numeric or char type, as checked in `calc_side` above. - self.emit_err_pat_range(span, lhs, rhs); - return self.tcx.ty_error(); + let guar = self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.ty_error(guar); } // Unify each side with `expected`. @@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { demand_eqtype(&mut rhs, lhs); if let (Some((true, ..)), _) | (_, Some((true, ..))) = (lhs, rhs) { - return self.tcx.ty_error(); + return self.tcx.ty_error_misc(); } // Find the unified type and check if it's of numeric or char type again. @@ -511,8 +511,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some((ref mut fail, _, _)) = rhs { *fail = true; } - self.emit_err_pat_range(span, lhs, rhs); - return self.tcx.ty_error(); + let guar = self.emit_err_pat_range(span, lhs, rhs); + return self.tcx.ty_error(guar); } ty } @@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, lhs: Option<(bool, Ty<'tcx>, Span)>, rhs: Option<(bool, Ty<'tcx>, Span)>, - ) { + ) -> ErrorGuaranteed { let span = match (lhs, rhs) { (Some((true, ..)), Some((true, ..))) => span, (Some((true, _, sp)), _) => sp, @@ -573,7 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { type between two end-points, you can use a guard.", ); } - err.emit(); + err.emit() } fn check_pat_ident( @@ -807,29 +807,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn check_dereferenceable(&self, span: Span, expected: Ty<'tcx>, inner: &Pat<'_>) -> bool { + pub fn check_dereferenceable( + &self, + span: Span, + expected: Ty<'tcx>, + inner: &Pat<'_>, + ) -> Result<(), ErrorGuaranteed> { if let PatKind::Binding(..) = inner.kind && let Some(mt) = self.shallow_resolve(expected).builtin_deref(true) && let ty::Dynamic(..) = mt.ty.kind() { - // This is "x = SomeTrait" being reduced from - // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error. - let type_str = self.ty_to_string(expected); - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0033, - "type `{}` cannot be dereferenced", - type_str - ); - err.span_label(span, format!("type `{type_str}` cannot be dereferenced")); - if self.tcx.sess.teach(&err.get_code().unwrap()) { - err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ); - } - err.emit(); - return false; - } - true + // This is "x = SomeTrait" being reduced from + // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error. + let type_str = self.ty_to_string(expected); + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0033, + "type `{}` cannot be dereferenced", + type_str + ); + err.span_label(span, format!("type `{type_str}` cannot be dereferenced")); + if self.tcx.sess.teach(&err.get_code().unwrap()) { + err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ); + } + return Err(err.emit()); + } + Ok(()) } fn check_pat_struct( @@ -843,13 +847,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { // Resolve the path and check the definition for errors. - let Some((variant, pat_ty)) = self.check_struct_path(qpath, pat.hir_id) else { - let err = self.tcx.ty_error(); - for field in fields { - let ti = ti; - self.check_pat(field.pat, err, def_bm, ti); + let (variant, pat_ty) = match self.check_struct_path(qpath, pat.hir_id) { + Ok(data) => data, + Err(guar) => { + let err = self.tcx.ty_error(guar); + for field in fields { + let ti = ti; + self.check_pat(field.pat, err, def_bm, ti); + } + return err; } - return err; }; // Type-check the path. @@ -859,7 +866,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if self.check_struct_pat_fields(pat_ty, &pat, variant, fields, has_rest_pat, def_bm, ti) { pat_ty } else { - self.tcx.ty_error() + self.tcx.ty_error_misc() } } @@ -879,12 +886,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Res::Err => { let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => { let expected = "unit struct, unit variant or constant"; let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::SelfCtor(..) | Res::Def( @@ -1027,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; let on_error = |e| { for pat in subpats { - self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti); + self.check_pat(pat, tcx.ty_error(e), def_bm, ti); } }; let report_unexpected_res = |res: Res| { @@ -1044,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } // Type-check the path. @@ -1052,7 +1059,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id); if !pat_ty.is_fn() { let e = report_unexpected_res(res); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } let variant = match res { @@ -1060,11 +1067,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); self.set_tainted_by_errors(e); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { let e = report_unexpected_res(res); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res), _ => bug!("unexpected pattern resolution: {:?}", res), @@ -1105,7 +1112,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Pattern has wrong number of fields. let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); on_error(e); - return tcx.ty_error_with_guaranteed(e); + return tcx.ty_error(e); } pat_ty } @@ -1295,17 +1302,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span }, ) }); - let element_tys = tcx.mk_type_list(element_tys_iter); - let pat_ty = tcx.intern_tup(element_tys); + let element_tys = tcx.mk_type_list_from_iter(element_tys_iter); + let pat_ty = tcx.mk_tup(element_tys); if let Some(mut err) = self.demand_eqtype_pat_diag(span, expected, pat_ty, ti) { let reported = err.emit(); // Walk subpatterns with an expected type of `err` in this case to silence // further errors being emitted when using the bindings. #50333 - let element_tys_iter = (0..max_len).map(|_| tcx.ty_error_with_guaranteed(reported)); + let element_tys_iter = (0..max_len).map(|_| tcx.ty_error(reported)); for (_, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { - self.check_pat(elem, tcx.ty_error_with_guaranteed(reported), def_bm, ti); + self.check_pat(elem, tcx.ty_error(reported), def_bm, ti); } - tcx.mk_tup(element_tys_iter) + tcx.mk_tup_from_iter(element_tys_iter) } else { for (i, elem) in elements.iter().enumerate_and_adjust(max_len, ddpos) { self.check_pat(elem, element_tys[i], def_bm, ti); @@ -1349,9 +1356,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ident = tcx.adjust_ident(field.ident, variant.def_id); let field_ty = match used_fields.entry(ident) { Occupied(occupied) => { - self.error_field_already_bound(span, field.ident, *occupied.get()); no_field_errors = false; - tcx.ty_error() + let guar = self.error_field_already_bound(span, field.ident, *occupied.get()); + tcx.ty_error(guar) } Vacant(vacant) => { vacant.insert(span); @@ -1365,7 +1372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or_else(|| { inexistent_fields.push(field); no_field_errors = false; - tcx.ty_error() + tcx.ty_error_misc() }) } }; @@ -1536,7 +1543,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.emit(); } - fn error_field_already_bound(&self, span: Span, ident: Ident, other_field: Span) { + fn error_field_already_bound( + &self, + span: Span, + ident: Ident, + other_field: Span, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -1546,7 +1558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .span_label(span, format!("multiple uses of `{ident}` in pattern")) .span_label(other_field, format!("first use of `{ident}`")) - .emit(); + .emit() } fn error_inexistent_fields( @@ -1919,19 +1931,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let (box_ty, inner_ty) = if self.check_dereferenceable(span, expected, inner) { - // Here, `demand::subtype` is good enough, but I don't - // think any errors can be introduced by using `demand::eqtype`. - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); - let box_ty = tcx.mk_box(inner_ty); - self.demand_eqtype_pat(span, expected, box_ty, ti); - (box_ty, inner_ty) - } else { - let err = tcx.ty_error(); - (err, err) + let (box_ty, inner_ty) = match self.check_dereferenceable(span, expected, inner) { + Ok(()) => { + // Here, `demand::subtype` is good enough, but I don't + // think any errors can be introduced by using `demand::eqtype`. + let inner_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: inner.span, + }); + let box_ty = tcx.mk_box(inner_ty); + self.demand_eqtype_pat(span, expected, box_ty, ti); + (box_ty, inner_ty) + } + Err(guar) => { + let err = tcx.ty_error(guar); + (err, err) + } }; self.check_pat(inner, inner_ty, def_bm, ti); box_ty @@ -1949,37 +1964,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) -> Ty<'tcx> { let tcx = self.tcx; let expected = self.shallow_resolve(expected); - let (ref_ty, inner_ty) = if self.check_dereferenceable(pat.span, expected, inner) { - // `demand::subtype` would be good enough, but using `eqtype` turns - // out to be equally general. See (note_1) for details. - - // Take region, inner-type from expected type if we can, - // to avoid creating needless variables. This also helps with - // the bad interactions of the given hack detailed in (note_1). - debug!("check_pat_ref: expected={:?}", expected); - match *expected.kind() { - ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), - _ => { - let inner_ty = self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeInference, - span: inner.span, - }); - let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); - debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); - let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti); - - // Look for a case like `fn foo(&foo: u32)` and suggest - // `fn foo(foo: &u32)` - if let Some(mut err) = err { - self.borrow_pat_suggestion(&mut err, pat); - err.emit(); + let (ref_ty, inner_ty) = match self.check_dereferenceable(pat.span, expected, inner) { + Ok(()) => { + // `demand::subtype` would be good enough, but using `eqtype` turns + // out to be equally general. See (note_1) for details. + + // Take region, inner-type from expected type if we can, + // to avoid creating needless variables. This also helps with + // the bad interactions of the given hack detailed in (note_1). + debug!("check_pat_ref: expected={:?}", expected); + match *expected.kind() { + ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty), + _ => { + let inner_ty = self.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeInference, + span: inner.span, + }); + let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty); + debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty); + let err = self.demand_eqtype_pat_diag(pat.span, expected, ref_ty, ti); + + // Look for a case like `fn foo(&foo: u32)` and suggest + // `fn foo(foo: &u32)` + if let Some(mut err) = err { + self.borrow_pat_suggestion(&mut err, pat); + err.emit(); + } + (ref_ty, inner_ty) } - (ref_ty, inner_ty) } } - } else { - let err = tcx.ty_error(); - (err, err) + Err(guar) => { + let err = tcx.ty_error(guar); + (err, err) + } }; self.check_pat(inner, inner_ty, def_bm, ti); ref_ty @@ -2027,10 +2045,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Slice(element_ty) => (element_ty, Some(expected), expected), // The expected type must be an array or slice, but was neither, so error. _ => { - if !expected.references_error() { - self.error_expected_array_or_slice(span, expected, ti); - } - let err = self.tcx.ty_error(); + let guar = expected + .error_reported() + .err() + .unwrap_or_else(|| self.error_expected_array_or_slice(span, expected, ti)); + let err = self.tcx.ty_error(guar); (err, Some(err), err) } }; @@ -2063,7 +2082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { len: ty::Const<'tcx>, min_len: u64, ) -> (Option<Ty<'tcx>>, Ty<'tcx>) { - if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) { + let guar = if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) { // Now we know the length... if slice.is_none() { // ...and since there is no variable-length pattern, @@ -2073,7 +2092,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return (None, arr_ty); } - self.error_scrutinee_inconsistent_length(span, min_len, len); + self.error_scrutinee_inconsistent_length(span, min_len, len) } else if let Some(pat_len) = len.checked_sub(min_len) { // The variable-length pattern was there, // so it has an array type with the remaining elements left as its size... @@ -2081,7 +2100,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { // ...however, in this case, there were no remaining elements. // That is, the slice pattern requires more than the array type offers. - self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len); + self.error_scrutinee_with_rest_inconsistent_length(span, min_len, len) } } else if slice.is_none() { // We have a pattern with a fixed length, @@ -2093,14 +2112,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We have a variable-length pattern and don't know the array length. // This happens if we have e.g., // `let [a, b, ..] = arr` where `arr: [T; N]` where `const N: usize`. - self.error_scrutinee_unfixed_length(span); - } + self.error_scrutinee_unfixed_length(span) + }; // If we get here, we must have emitted an error. - (Some(self.tcx.ty_error()), arr_ty) + (Some(self.tcx.ty_error(guar)), arr_ty) } - fn error_scrutinee_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { + fn error_scrutinee_inconsistent_length( + &self, + span: Span, + min_len: u64, + size: u64, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -2111,10 +2135,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { size, ) .span_label(span, format!("expected {} element{}", size, pluralize!(size))) - .emit(); + .emit() } - fn error_scrutinee_with_rest_inconsistent_length(&self, span: Span, min_len: u64, size: u64) { + fn error_scrutinee_with_rest_inconsistent_length( + &self, + span: Span, + min_len: u64, + size: u64, + ) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, @@ -2128,20 +2157,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span, format!("pattern cannot match array of {} element{}", size, pluralize!(size),), ) - .emit(); + .emit() } - fn error_scrutinee_unfixed_length(&self, span: Span) { + fn error_scrutinee_unfixed_length(&self, span: Span) -> ErrorGuaranteed { struct_span_err!( self.tcx.sess, span, E0730, "cannot pattern-match on an array without a fixed length", ) - .emit(); + .emit() } - fn error_expected_array_or_slice(&self, span: Span, expected_ty: Ty<'tcx>, ti: TopInfo<'tcx>) { + fn error_expected_array_or_slice( + &self, + span: Span, + expected_ty: Ty<'tcx>, + ti: TopInfo<'tcx>, + ) -> ErrorGuaranteed { let mut err = struct_span_err!( self.tcx.sess, span, @@ -2185,7 +2219,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } err.span_label(span, format!("pattern cannot match with input type `{expected_ty}`")); - err.emit(); + err.emit() } fn is_slice_or_array_or_vector(&self, ty: Ty<'tcx>) -> (bool, Ty<'tcx>) { diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs index ae0df5aa8f1..8fcec3363c0 100644 --- a/compiler/rustc_hir_typeck/src/place_op.rs +++ b/compiler/rustc_hir_typeck/src/place_op.rs @@ -91,10 +91,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } let reported = err.emit(); - Some(( - self.tcx.ty_error_with_guaranteed(reported), - self.tcx.ty_error_with_guaranteed(reported), - )) + Some((self.tcx.ty_error(reported), self.tcx.ty_error(reported))) } /// To type-check `base_expr[index_expr]`, we progressively autoderef diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 7c8abb4186f..e94915c754e 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -301,7 +301,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Build a tuple (U0..Un) of the final upvar types U0..Un // and unify the upvar tuple type in the closure with it: - let final_tupled_upvars_type = self.tcx.intern_tup(&final_upvar_tys); + let final_tupled_upvars_type = self.tcx.mk_tup(&final_upvar_tys); self.demand_suptype(span, substs.tupled_upvars_ty(), final_tupled_upvars_type); let fake_reads = delegate @@ -315,8 +315,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().closure_size_eval.insert( closure_def_id, ClosureSizeProfileData { - before_feature_tys: self.tcx.intern_tup(&before_feature_tys), - after_feature_tys: self.tcx.intern_tup(&after_feature_tys), + before_feature_tys: self.tcx.mk_tup(&before_feature_tys), + after_feature_tys: self.tcx.mk_tup(&after_feature_tys), }, ); } diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index b6c9a88c82d..00348f3afdc 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -13,8 +13,8 @@ use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCast}; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; -use rustc_middle::ty::visit::TypeSuperVisitable; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::TypeckResults; use rustc_middle::ty::{self, ClosureSizeProfileData, Ty, TyCtxt}; use rustc_span::symbol::sym; @@ -561,7 +561,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { struct RecursionChecker { def_id: LocalDefId, } - impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker { + impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for RecursionChecker { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *t.kind() { @@ -685,7 +685,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { fn resolve<T>(&mut self, x: T, span: &dyn Locatable) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let mut resolver = Resolver::new(self.fcx, span, self.body); let x = x.fold_with(&mut resolver); @@ -797,7 +797,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); let e = self.report_error(t); self.replaced_with_error = Some(e); - self.interner().ty_error_with_guaranteed(e) + self.interner().ty_error(e) } } } diff --git a/compiler/rustc_incremental/Cargo.toml b/compiler/rustc_incremental/Cargo.toml index 179e85f32c9..ad89393956e 100644 --- a/compiler/rustc_incremental/Cargo.toml +++ b/compiler/rustc_incremental/Cargo.toml @@ -6,16 +6,17 @@ edition = "2021" [lib] [dependencies] -rustc_graphviz = { path = "../rustc_graphviz" } -tracing = "0.1" rand = "0.8.4" -rustc_middle = { path = "../rustc_middle" } +rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } +rustc_fs_util = { path = "../rustc_fs_util" } +rustc_graphviz = { path = "../rustc_graphviz" } rustc_hir = { path = "../rustc_hir" } -rustc_serialize = { path = "../rustc_serialize" } -rustc_ast = { path = "../rustc_ast" } rustc_macros = { path = "../rustc_macros" } -rustc_span = { path = "../rustc_span" } -rustc_fs_util = { path = "../rustc_fs_util" } +rustc_middle = { path = "../rustc_middle" } +rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } -rustc_errors = { path = "../rustc_errors" } +rustc_span = { path = "../rustc_span" } +thin-vec = "0.2.12" +tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/incremental.ftl b/compiler/rustc_incremental/locales/en-US.ftl index 4852ee0d959..4852ee0d959 100644 --- a/compiler/rustc_error_messages/locales/en-US/incremental.ftl +++ b/compiler/rustc_incremental/locales/en-US.ftl diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs index 2968a0e1203..b4b0ea00c50 100644 --- a/compiler/rustc_incremental/src/assert_module_sources.rs +++ b/compiler/rustc_incremental/src/assert_module_sources.rs @@ -30,6 +30,7 @@ use rustc_middle::mir::mono::CodegenUnitNameBuilder; use rustc_middle::ty::TyCtxt; use rustc_session::cgu_reuse_tracker::*; use rustc_span::symbol::{sym, Symbol}; +use thin_vec::ThinVec; #[allow(missing_docs)] pub fn assert_module_sources(tcx: TyCtxt<'_>) { @@ -138,7 +139,7 @@ impl<'tcx> AssertModuleSource<'tcx> { } fn field(&self, attr: &ast::Attribute, name: Symbol) -> Symbol { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(name) { if let Some(value) = item.value_str() { return value; diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index 3c58cfa38f2..511e466c2ae 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -31,3 +31,8 @@ pub use persist::save_dep_graph; pub use persist::save_work_product_index; pub use persist::LoadResult; pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture}; + +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index c6e63998c79..b839416c919 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -31,6 +31,8 @@ use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; +use std::iter::FromIterator; +use thin_vec::ThinVec; const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk; const EXCEPT: Symbol = sym::except; @@ -205,7 +207,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { /// `loaded_from_disk=` attribute value fn loaded_from_disk(&self, attr: &Attribute) -> Labels { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(LOADED_FROM_DISK) { let value = expect_associated_value(self.tcx, &item); return self.resolve_labels(&item, value); @@ -217,7 +219,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { /// `except=` attribute value fn except(&self, attr: &Attribute) -> Labels { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(EXCEPT) { let value = expect_associated_value(self.tcx, &item); return self.resolve_labels(&item, value); @@ -397,7 +399,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool { let config = &tcx.sess.parse_sess.config; debug!("check_config: config={:?}", config); let mut cfg = None; - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) { if item.has_name(CFG) { let value = expect_associated_value(tcx, &item); debug!("check_config: searching for cfg {:?}", value); diff --git a/compiler/rustc_error_messages/locales/en-US/infer.ftl b/compiler/rustc_infer/locales/en-US.ftl index c5b2b6c2d73..c5b2b6c2d73 100644 --- a/compiler/rustc_error_messages/locales/en-US/infer.ftl +++ b/compiler/rustc_infer/locales/en-US.ftl diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs index 0c2713fb1a7..7dccd0bb930 100644 --- a/compiler/rustc_infer/src/errors/mod.rs +++ b/compiler/rustc_infer/src/errors/mod.rs @@ -1,6 +1,6 @@ use hir::GenericParamKind; use rustc_errors::{ - fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, + AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage, }; use rustc_hir as hir; @@ -12,9 +12,10 @@ use rustc_span::symbol::kw; use rustc_span::Symbol; use rustc_span::{symbol::Ident, BytePos, Span}; -use crate::infer::error_reporting::nice_region_error::placeholder_error::Highlighted; +use crate::fluent_generated as fluent; use crate::infer::error_reporting::{ need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind}, + nice_region_error::placeholder_error::Highlighted, ObligationCauseAsDiagArg, }; @@ -26,9 +27,9 @@ pub struct OpaqueHiddenTypeDiag { #[primary_span] #[label] pub span: Span, - #[note(opaque_type)] + #[note(infer_opaque_type)] pub opaque_type: Span, - #[note(hidden_type)] + #[note(infer_hidden_type)] pub hidden_type: Span, } @@ -768,11 +769,11 @@ impl<'tcx> ActualImplExplNotes<'tcx> { pub struct TraitPlaceholderMismatch<'tcx> { #[primary_span] pub span: Span, - #[label(label_satisfy)] + #[label(infer_label_satisfy)] pub satisfy_span: Option<Span>, - #[label(label_where)] + #[label(infer_label_where)] pub where_span: Option<Span>, - #[label(label_dup)] + #[label(infer_label_dup)] pub dup_span: Option<Span>, pub def_id: String, pub trait_def_id: String, @@ -808,11 +809,11 @@ pub struct RelationshipHelp; #[diag(infer_trait_impl_diff)] pub struct TraitImplDiff { #[primary_span] - #[label(found)] + #[label(infer_found)] pub sp: Span, - #[label(expected)] + #[label(infer_expected)] pub trait_sp: Span, - #[note(expected_found)] + #[note(infer_expected_found)] pub note: (), #[subdiagnostic] pub param_help: ConsiderBorrowingParamHelp, @@ -852,10 +853,10 @@ impl AddToDiagnostic for DynTraitConstraintSuggestion { #[derive(Diagnostic)] #[diag(infer_but_calling_introduces, code = "E0772")] pub struct ButCallingIntroduces { - #[label(label1)] + #[label(infer_label1)] pub param_ty_span: Span, #[primary_span] - #[label(label2)] + #[label(infer_label2)] pub cause_span: Span, pub has_param_name: bool, @@ -913,15 +914,15 @@ impl AddToDiagnostic for MoreTargeted { pub struct ButNeedsToSatisfy { #[primary_span] pub sp: Span, - #[label(influencer)] + #[label(infer_influencer)] pub influencer_point: Span, - #[label(used_here)] + #[label(infer_used_here)] pub spans: Vec<Span>, - #[label(require)] + #[label(infer_require)] pub require_span_as_label: Option<Span>, - #[note(require)] + #[note(infer_require)] pub require_span_as_note: Option<Span>, - #[note(introduced_by_bound)] + #[note(infer_introduced_by_bound)] pub bound: Option<Span>, #[subdiagnostic] diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs index cb96aeec5f3..ef543b1fb93 100644 --- a/compiler/rustc_infer/src/errors/note_and_explain.rs +++ b/compiler/rustc_infer/src/errors/note_and_explain.rs @@ -1,7 +1,6 @@ +use crate::fluent_generated as fluent; use crate::infer::error_reporting::nice_region_error::find_anon_type; -use rustc_errors::{ - self, fluent, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage, -}; +use rustc_errors::{self, AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{symbol::kw, Span}; diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index d816a9ed3d7..c952ddc827a 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> { cause: &'a ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> At<'a, 'tcx> { - At { infcx: self, cause, param_env, define_opaque_types: true } + At { infcx: self, cause, param_env, define_opaque_types: false } } /// Forks the inference context, creating a new inference context with the same inference diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index b736a416e4a..7ffd39de781 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -10,9 +10,9 @@ use crate::infer::canonical::{ }; use crate::infer::InferCtxt; use rustc_middle::ty::flags::FlagComputation; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; +use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; use std::sync::atomic::Ordering; use rustc_data_structures::fx::FxHashMap; @@ -41,7 +41,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -100,7 +100,7 @@ impl<'tcx> InferCtxt<'tcx> { /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response<V>(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -114,7 +114,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn canonicalize_user_type_annotation<V>(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -136,7 +136,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -333,7 +333,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.binder_index.shift_in(1); let t = t.super_fold_with(self); @@ -530,7 +530,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::NEEDS_INFER | @@ -572,7 +572,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders()); let canonical_variables = - tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables()); + tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables()); let max_universe = canonical_variables .iter() diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 4552256545b..8c782a933a5 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -26,7 +26,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari use rustc_index::vec::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, List}; +use rustc_middle::ty::{self, List, TyCtxt}; use rustc_span::source_map::Span; pub use rustc_middle::infer::canonical::*; @@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { // For each universe that is referred to in the incoming // query, create a universe in our local inference context. In @@ -88,7 +88,7 @@ impl<'tcx> InferCtxt<'tcx> { universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> CanonicalVarValues<'tcx> { CanonicalVarValues { - var_values: self.tcx.mk_substs( + var_values: self.tcx.mk_substs_from_iter( variables .iter() .map(|info| self.instantiate_canonical_var(span, info, &universe_map)), diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index b9cb9732ca3..832af91a431 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -27,7 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::fmt::Debug; use std::iter; @@ -59,7 +59,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Fallible<CanonicalQueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; @@ -85,7 +85,7 @@ impl<'tcx> InferCtxt<'tcx> { answer: T, ) -> Canonical<'tcx, QueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, { self.canonicalize_response(QueryResponse { var_values: inference_vars, @@ -106,7 +106,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<QueryResponse<'tcx, T>, NoSolution> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, { let tcx = self.tcx; @@ -180,7 +180,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { let InferOk { value: result_subst, mut obligations } = self.query_response_substitution(cause, param_env, original_values, query_response)?; @@ -242,7 +242,7 @@ impl<'tcx> InferCtxt<'tcx> { output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { let InferOk { value: result_subst, mut obligations } = self .query_response_substitution_guess(cause, param_env, original_values, query_response)?; @@ -356,7 +356,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { debug!( "query_response_substitution(original_values={:#?}, query_response={:#?})", @@ -393,6 +393,7 @@ impl<'tcx> InferCtxt<'tcx> { /// will instantiate fresh inference variables for each canonical /// variable instead. Therefore, the result of this method must be /// properly unified + #[instrument(level = "debug", skip(self, cause, param_env))] fn query_response_substitution_guess<R>( &self, cause: &ObligationCause<'tcx>, @@ -401,13 +402,8 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { - debug!( - "query_response_substitution_guess(original_values={:#?}, query_response={:#?})", - original_values, query_response, - ); - // For each new universe created in the query result that did // not appear in the original query, create a local // superuniverse. @@ -478,8 +474,8 @@ impl<'tcx> InferCtxt<'tcx> { // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. let result_subst = CanonicalVarValues { - var_values: self.tcx.mk_substs(query_response.variables.iter().enumerate().map( - |(index, info)| { + var_values: self.tcx.mk_substs_from_iter( + query_response.variables.iter().enumerate().map(|(index, info)| { if info.is_existential() { match opt_values[BoundVar::new(index)] { Some(k) => k, @@ -492,8 +488,8 @@ impl<'tcx> InferCtxt<'tcx> { universe_map[u.as_usize()] }) } - }, - )), + }), + ), }; let mut obligations = vec![]; @@ -502,7 +498,9 @@ impl<'tcx> InferCtxt<'tcx> { for &(a, b) in &query_response.value.opaque_types { let a = substitute_value(self.tcx, &result_subst, a); let b = substitute_value(self.tcx, &result_subst, b); - obligations.extend(self.at(cause, param_env).eq(a, b)?.obligations); + debug!(?a, ?b, "constrain opaque type"); + obligations + .extend(self.at(cause, param_env).define_opaque_types(true).eq(a, b)?.obligations); } Ok(InferOk { value: result_subst, obligations }) @@ -523,7 +521,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, ()> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { // A closure that yields the result value for the given // canonical variable; this is taken from @@ -683,7 +681,11 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { self.infcx.create_next_universe() } - fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> { + fn next_existential_region_var( + &mut self, + from_forall: bool, + _name: Option<Symbol>, + ) -> ty::Region<'tcx> { let origin = NllRegionVariableOrigin::Existential { from_forall }; self.infcx.next_nll_region_var(origin) } diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index e77f2d37b7d..c5c6fc41b9e 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -16,7 +16,7 @@ pub(super) trait CanonicalExt<'tcx, V> { /// with the value given in `var_values`. fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>; + V: TypeFoldable<TyCtxt<'tcx>>; /// Allows one to apply a substitute to some subset of /// `self.value`. Invoke `projection_fn` with `self.value` to get @@ -31,13 +31,13 @@ pub(super) trait CanonicalExt<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable<TyCtxt<'tcx>>; } impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.substitute_projected(tcx, var_values, |value| value.clone()) } @@ -49,7 +49,7 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { assert_eq!(self.variables.len(), var_values.len()); let value = projection_fn(&self.value); @@ -66,7 +66,7 @@ pub(super) fn substitute_value<'tcx, T>( value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { if var_values.var_values.is_empty() { value diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index f5504b05dc4..33292e871b1 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -40,8 +40,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{ - self, ir::FallibleTypeFolder, AliasKind, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, + self, AliasKind, FallibleTypeFolder, InferConst, ToPredicate, Ty, TyCtxt, TypeFoldable, + TypeSuperFoldable, TypeVisitableExt, }; use rustc_middle::ty::{IntType, UintType}; use rustc_span::{Span, DUMMY_SP}; @@ -478,10 +478,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { self.obligations.extend(obligations.into_iter()); } - pub fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>, - ) { + pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) { self.obligations.extend(obligations.into_iter().map(|to_pred| { Obligation::new(self.infcx.tcx, self.trace.cause.clone(), self.param_env, to_pred) })) @@ -814,10 +811,7 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> { /// Register predicates that must hold in order for this relation to hold. Uses /// a default obligation cause, [`ObligationEmittingRelation::register_obligations`] should /// be used if control over the obligaton causes is required. - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ToPredicate<'tcx>>, - ); + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>); /// Register an obligation that both constants must be equal to each other. /// diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 742c01efff6..54a62326ef7 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -6,7 +6,7 @@ use super::Subtype; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::TyVar; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_hir::def_id::DefId; @@ -201,10 +201,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { } impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index bb7947e3141..79efc1ce7bf 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -72,7 +72,7 @@ use rustc_middle::ty::print::with_forced_trimmed_paths; use rustc_middle::ty::relate::{self, RelateResult, TypeRelation}; use rustc_middle::ty::{ self, error::TypeError, List, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, - TypeVisitable, + TypeVisitable, TypeVisitableExt, }; use rustc_span::{sym, symbol::kw, BytePos, DesugaringKind, Pos, Span}; use rustc_target::spec::abi; @@ -129,21 +129,16 @@ pub(super) fn note_and_explain_region<'tcx>( alt_span: Option<Span>, ) { let (description, span) = match *region { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReStatic => { - msg_span_from_free_region(tcx, region, alt_span) + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::RePlaceholder(_) | ty::ReStatic => { + msg_span_from_named_region(tcx, region, alt_span) } - ty::RePlaceholder(_) => return, - ty::ReError(_) => return, - // FIXME(#13998) RePlaceholder should probably print like - // ReFree rather than dumping Debug output on the user. - // // We shouldn't really be having unification failures with ReVar // and ReLateBound though. ty::ReVar(_) | ty::ReLateBound(..) | ty::ReErased => { - (format!("lifetime {:?}", region), alt_span) + (format!("lifetime `{region}`"), alt_span) } }; @@ -157,12 +152,12 @@ fn explain_free_region<'tcx>( region: ty::Region<'tcx>, suffix: &str, ) { - let (description, span) = msg_span_from_free_region(tcx, region, None); + let (description, span) = msg_span_from_named_region(tcx, region, None); label_msg_span(err, prefix, description, span, suffix); } -fn msg_span_from_free_region<'tcx>( +fn msg_span_from_named_region<'tcx>( tcx: TyCtxt<'tcx>, region: ty::Region<'tcx>, alt_span: Option<Span>, @@ -173,6 +168,18 @@ fn msg_span_from_free_region<'tcx>( (msg, Some(span)) } ty::ReStatic => ("the static lifetime".to_owned(), alt_span), + ty::RePlaceholder(ty::PlaceholderRegion { + name: ty::BoundRegionKind::BrNamed(def_id, name), + .. + }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))), + ty::RePlaceholder(ty::PlaceholderRegion { + name: ty::BoundRegionKind::BrAnon(_, Some(span)), + .. + }) => (format!("the anonymous lifetime defined here"), Some(span)), + ty::RePlaceholder(ty::PlaceholderRegion { + name: ty::BoundRegionKind::BrAnon(_, None), + .. + }) => (format!("an anonymous lifetime"), None), _ => bug!("{:?}", region), } } @@ -918,7 +925,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) -> Option<()> { // FIXME/HACK: Go back to `SubstsRef` to use its inherent methods, // ideally that shouldn't be necessary. - let sub = self.tcx.intern_substs(sub); + let sub = self.tcx.mk_substs(sub); for (i, ta) in sub.types().enumerate() { if ta == other_ty { self.highlight_outer(&mut t1_out, &mut t2_out, path, sub, i, other_ty); @@ -1443,8 +1450,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> OpaqueTypesVisitor<'tcx> { fn visit_expected_found( tcx: TyCtxt<'tcx>, - expected: impl TypeVisitable<'tcx>, - found: impl TypeVisitable<'tcx>, + expected: impl TypeVisitable<TyCtxt<'tcx>>, + found: impl TypeVisitable<TyCtxt<'tcx>>, ignore_span: Span, ) -> Self { let mut types_visitor = OpaqueTypesVisitor { @@ -1494,7 +1501,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for OpaqueTypesVisitor<'tcx> { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let Some((kind, def_id)) = TyCategory::from_ty(self.tcx, t) { let span = self.tcx.def_span(def_id); @@ -2199,7 +2206,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } /// Returns a string of the form "expected `{}`, found `{}`". - fn expected_found_str<T: fmt::Display + TypeFoldable<'tcx>>( + fn expected_found_str<T: fmt::Display + TypeFoldable<TyCtxt<'tcx>>>( &self, exp_found: ty::error::ExpectedFound<T>, ) -> Option<(DiagnosticStyledString, DiagnosticStyledString, Option<PathBuf>, Option<PathBuf>)> diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index cf2f6ef33be..e242900fd23 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -122,7 +122,7 @@ impl InferenceDiagnosticsParentData { tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string(); Some(InferenceDiagnosticsParentData { - prefix: tcx.def_kind(parent_def_id).descr(parent_def_id), + prefix: tcx.def_descr(parent_def_id), name: parent_name, }) } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 641477e907d..b06ff10d86e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -17,8 +17,7 @@ use rustc_hir::{ TyKind, }; use rustc_middle::ty::{ - self, ir::TypeVisitor, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, - TypeSuperVisitable, + self, AssocItemContainer, StaticLifetimeVisitor, Ty, TyCtxt, TypeSuperVisitable, TypeVisitor, }; use rustc_span::symbol::Ident; use rustc_span::Span; diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index d295881d5d7..2875448ee15 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -75,7 +75,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for HighlightBuilder<'tcx> { fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { if !r.has_name() && self.counter <= 3 { self.highlight.highlighting_region(r, self.counter); diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index ac4de2cc842..db4b8af4683 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -143,7 +143,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { fn includes_region( &self, - ty: Binder<'tcx, impl TypeVisitable<'tcx>>, + ty: Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>, region: ty::BoundRegionKind, ) -> bool { let late_bound_regions = self.tcx().collect_referenced_late_bound_regions(&ty); diff --git a/compiler/rustc_infer/src/infer/error_reporting/note.rs b/compiler/rustc_infer/src/infer/error_reporting/note.rs index e0e89158a58..7ffe1fd20b4 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/note.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/note.rs @@ -2,10 +2,11 @@ use crate::errors::{ note_and_explain, FullfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent, RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, }; +use crate::fluent_generated as fluent; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::{self, SubregionOrigin}; use rustc_errors::{ - fluent, AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, + AddToDiagnostic, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, }; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::traits::ObligationCauseCode; diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 18c5097a262..55dcfd05e0a 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -8,7 +8,7 @@ use rustc_middle::traits::{ StatementAsExpression, }; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitable}; +use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt}; use rustc_span::{sym, BytePos, Span}; use crate::errors::{ diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index 41bffdc684d..f09f93abf45 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -33,8 +33,8 @@ use super::InferCtxt; use rustc_data_structures::fx::FxHashMap; use rustc_middle::infer::unify_key::ToType; -use rustc_middle::ty::fold::ir::TypeFolder; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::fold::TypeFolder; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeVisitableExt}; use std::collections::hash_map::Entry; pub struct TypeFreshener<'a, 'tcx> { diff --git a/compiler/rustc_infer/src/infer/fudge.rs b/compiler/rustc_infer/src/infer/fudge.rs index cc2f19a5704..86c2c2be4a8 100644 --- a/compiler/rustc_infer/src/infer/fudge.rs +++ b/compiler/rustc_infer/src/infer/fudge.rs @@ -1,4 +1,4 @@ -use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::{self, ConstVid, FloatVid, IntVid, RegionVid, Ty, TyCtxt, TyVid}; use super::type_variable::TypeVariableOrigin; @@ -98,7 +98,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn fudge_inference_if_ok<T, E, F>(&self, f: F) -> Result<T, E> where F: FnOnce() -> Result<T, E>, - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let variable_lengths = self.variable_lengths(); let (mut fudger, value) = self.probe(|_| { diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 74abca7bbea..49df393d83b 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -7,7 +7,7 @@ use super::Subtype; use crate::traits::{ObligationCause, PredicateObligations}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; /// "Greatest lower bound" (common subtype) pub struct Glb<'combine, 'infcx, 'tcx> { @@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Glb<'combine, 'infcx, } impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index 82a1bb1fd16..d1897cf24b4 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -6,7 +6,7 @@ use super::{HigherRankedType, InferCtxt}; use crate::infer::CombinedSnapshot; use rustc_middle::ty::fold::FnMutDelegate; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Binder, TypeFoldable}; +use rustc_middle::ty::{self, Binder, TyCtxt, TypeFoldable}; impl<'a, 'tcx> CombineFields<'a, 'tcx> { /// Checks whether `for<..> sub <: for<..> sup` holds. @@ -72,7 +72,7 @@ impl<'tcx> InferCtxt<'tcx> { #[instrument(level = "debug", skip(self), ret)] pub fn instantiate_binder_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable<TyCtxt<'tcx>> + Copy, { if let Some(inner) = binder.no_bound_vars() { return inner; diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index ac203c4eb0b..335eb4c5406 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -1024,7 +1024,7 @@ impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> { impl<'tcx> LexicalRegionResolutions<'tcx> { fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { tcx.fold_regions(value, |r, _db| self.resolve_region(tcx, r)) } @@ -1046,7 +1046,7 @@ impl<'tcx> LexicalRegionResolutions<'tcx> { ty::ReVar(rid) => match self.values[rid] { VarValue::Empty(_) => r, VarValue::Value(r) => r, - VarValue::ErrorValue => tcx.mk_re_error_misc(), + VarValue::ErrorValue => tcx.lifetimes.re_static, }, _ => r, }; diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index f997171b97f..c871ccb21f8 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -7,7 +7,7 @@ use super::Subtype; use crate::traits::{ObligationCause, PredicateObligations}; use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; /// "Least upper bound" (common supertype) pub struct Lub<'combine, 'infcx, 'tcx> { @@ -148,10 +148,7 @@ impl<'combine, 'infcx, 'tcx> LatticeDir<'infcx, 'tcx> for Lub<'combine, 'infcx, } impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index aa316b2dadb..cf8007c964d 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -26,10 +26,10 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::traits::select; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BoundVarReplacerDelegate; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; pub use rustc_middle::ty::IntVarValue; use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid}; @@ -264,7 +264,7 @@ pub struct InferCtxt<'tcx> { /// short lived InferCtxt within queries. The opaque type obligations are forwarded /// to the outside until the end up in an `InferCtxt` for typeck or borrowck. /// - /// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that + /// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that /// might come up during inference or typeck. pub defining_use_anchor: DefiningAnchor, @@ -617,7 +617,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let infcx = self.build(); let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); @@ -697,7 +697,7 @@ impl<'tcx> InferCtxt<'tcx> { self.in_snapshot.get() } - pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T { + pub fn freshen<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) } @@ -1111,11 +1111,13 @@ impl<'tcx> InferCtxt<'tcx> { } /// Just a convenient wrapper of `next_region_var` for using during NLL. + #[instrument(skip(self), level = "debug")] pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> { self.next_region_var(RegionVariableOrigin::Nll(origin)) } /// Just a convenient wrapper of `next_region_var` for using during NLL. + #[instrument(skip(self), level = "debug")] pub fn next_nll_region_var_in_universe( &self, origin: NllRegionVariableOrigin, @@ -1369,7 +1371,7 @@ impl<'tcx> InferCtxt<'tcx> { /// will be resolving them as well, e.g. in a loop). pub fn shallow_resolve<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { value.fold_with(&mut ShallowResolver { infcx: self }) } @@ -1386,7 +1388,7 @@ impl<'tcx> InferCtxt<'tcx> { /// at will. pub fn resolve_vars_if_possible<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { if !value.has_non_region_infer() { return value; @@ -1397,7 +1399,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn resolve_numeric_literals_with_default<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { if !value.needs_infer() { return value; // Avoid duplicated subst-folding. @@ -1412,7 +1414,7 @@ impl<'tcx> InferCtxt<'tcx> { value: &T, ) -> Option<(ty::Term<'tcx>, Option<Span>)> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { value.visit_with(&mut resolve::UnresolvedTypeOrConstFinder::new(self)).break_value() } @@ -1427,7 +1429,7 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn fully_resolve<T: TypeFoldable<'tcx>>(&self, value: T) -> FixupResult<'tcx, T> { + pub fn fully_resolve<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> FixupResult<'tcx, T> { /*! * Attempts to resolve all type/region/const variables in * `value`. Region inference must have been run already (e.g., @@ -1460,7 +1462,7 @@ impl<'tcx> InferCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable<TyCtxt<'tcx>> + Copy, { if let Some(inner) = value.no_bound_vars() { return inner; diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 644774c93c2..6e413a7f412 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -29,9 +29,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; use rustc_middle::ty::{self, InferConst, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::fmt::Debug; use std::ops::ControlFlow; @@ -100,7 +100,11 @@ pub trait TypeRelatingDelegate<'tcx> { /// we will invoke this method to instantiate `'a` with an /// inference variable (though `'b` would be instantiated first, /// as a placeholder). - fn next_existential_region_var(&mut self, was_placeholder: bool) -> ty::Region<'tcx>; + fn next_existential_region_var( + &mut self, + was_placeholder: bool, + name: Option<Symbol>, + ) -> ty::Region<'tcx>; /// Creates a new region variable representing a /// higher-ranked region that is instantiated universally. @@ -188,7 +192,7 @@ where let placeholder = ty::PlaceholderRegion { universe, name: br.kind }; delegate.next_placeholder_region(placeholder) } else { - delegate.next_existential_region_var(true) + delegate.next_existential_region_var(true, br.kind.get_name()) } } }; @@ -759,10 +763,7 @@ impl<'tcx, D> ObligationEmittingRelation<'tcx> for TypeRelating<'_, 'tcx, D> where D: TypeRelatingDelegate<'tcx>, { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.delegate.register_obligations( obligations .into_iter() @@ -793,7 +794,7 @@ struct ScopeInstantiator<'me, 'tcx> { } impl<'me, 'tcx> TypeVisitor<TyCtxt<'tcx>> for ScopeInstantiator<'me, 'tcx> { - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index e783443502b..d5c824d4c41 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -12,8 +12,8 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{ - self, ir::TypeVisitor, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, - TypeSuperVisitable, TypeVisitable, + self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, }; use rustc_span::Span; @@ -45,7 +45,7 @@ pub struct OpaqueTypeDecl<'tcx> { impl<'tcx> InferCtxt<'tcx> { /// This is a backwards compatibility hack to prevent breaking changes from /// lazy TAIT around RPIT handling. - pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<'tcx>>( + pub fn replace_opaque_types_with_inference_vars<T: TypeFoldable<TyCtxt<'tcx>>>( &self, value: T, body_id: LocalDefId, @@ -427,7 +427,7 @@ impl<'tcx, OP> TypeVisitor<TyCtxt<'tcx>> for ConstrainOpaqueTypeRegionVisitor<'t where OP: FnMut(ty::Region<'tcx>), { - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -545,8 +545,11 @@ impl<'tcx> InferCtxt<'tcx> { origin, ); if let Some(prev) = prev { - obligations = - self.at(&cause, param_env).eq_exp(a_is_expected, prev, hidden_ty)?.obligations; + obligations = self + .at(&cause, param_env) + .define_opaque_types(true) + .eq_exp(a_is_expected, prev, hidden_ty)? + .obligations; } let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id()); diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index e3d95669171..ff23087fe8d 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -4,7 +4,7 @@ use rustc_data_structures::sso::SsoHashSet; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use smallvec::{smallvec, SmallVec}; #[derive(Debug)] diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs index 0194549a886..bbe7d4c63f7 100644 --- a/compiler/rustc_infer/src/infer/outlives/obligations.rs +++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs @@ -69,7 +69,7 @@ use crate::traits::{ObligationCause, ObligationCauseCode}; use rustc_data_structures::undo_log::UndoLogs; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Region, SubstsRef, Ty, TyCtxt, TypeVisitableExt}; use smallvec::smallvec; impl<'tcx> InferCtxt<'tcx> { diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index 10b474efd5a..3c6cc2b9001 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -1,7 +1,7 @@ use std::collections::hash_map::Entry; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{ self, error::TypeError, @@ -186,7 +186,8 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { #[instrument(skip(self), level = "debug")] fn tys(&mut self, pattern: Ty<'tcx>, value: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - if let ty::Error(_) = pattern.kind() { + // FIXME(non_lifetime_binders): What to do here? + if matches!(pattern.kind(), ty::Error(_) | ty::Bound(..)) { // Unlike normal `TypeRelation` rules, `ty::Error` does not equal any type. self.no_match() } else if pattern == value { diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 2c246a5787c..5bb35832930 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -1,11 +1,8 @@ use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use super::{FixupError, FixupResult, InferCtxt, Span}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::fold::{ - ir::{FallibleTypeFolder, TypeFolder}, - TypeSuperFoldable, -}; -use rustc_middle::ty::visit::{ir::TypeVisitor, TypeSuperVisitable}; +use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitableExt, TypeVisitor}; use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable}; use std::ops::ControlFlow; @@ -200,7 +197,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for UnresolvedTypeOrConstFinder<'a, 'tc /// then an `Err` result is returned. pub fn fully_resolve<'tcx, T>(infcx: &InferCtxt<'tcx>, value: T) -> FixupResult<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { value.try_fold_with(&mut FullTypeResolver { infcx }) } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index bf1b3441547..3e8c2052de8 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -3,7 +3,7 @@ use super::{ObligationEmittingRelation, SubregionOrigin}; use crate::traits::{Obligation, PredicateObligations}; use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::TyVar; use rustc_middle::ty::{self, Ty, TyCtxt}; use std::mem; @@ -126,7 +126,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { (&ty::Error(e), _) | (_, &ty::Error(e)) => { infcx.set_tainted_by_errors(e); - Ok(self.tcx().ty_error_with_guaranteed(e)) + Ok(self.tcx().ty_error(e)) } ( @@ -228,10 +228,7 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { } impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> { - fn register_predicates( - &mut self, - obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, - ) { + fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>) { self.fields.register_predicates(obligations); } diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs index 4c119a44355..bdc313c2141 100644 --- a/compiler/rustc_infer/src/lib.rs +++ b/compiler/rustc_infer/src/lib.rs @@ -13,6 +13,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(extend_one)] @@ -33,6 +34,11 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + mod errors; pub mod infer; pub mod traits; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_infer/src/traits/structural_impls.rs b/compiler/rustc_infer/src/traits/structural_impls.rs index 95df6cd62b9..3a5273b0359 100644 --- a/compiler/rustc_infer/src/traits/structural_impls.rs +++ b/compiler/rustc_infer/src/traits/structural_impls.rs @@ -2,7 +2,7 @@ use crate::traits; use crate::traits::project::Normalized; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable}; use rustc_middle::ty::visit::{TypeVisitable, TypeVisitor}; -use rustc_middle::ty::{self, ir, TyCtxt}; +use rustc_middle::ty::{self, TyCtxt}; use std::fmt; use std::ops::ControlFlow; @@ -61,8 +61,13 @@ impl<'tcx> fmt::Debug for traits::MismatchedProjectionTypes<'tcx> { /////////////////////////////////////////////////////////////////////////// // TypeFoldable implementations. -impl<'tcx, O: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx, O: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>> + for traits::Obligation<'tcx, O> +{ + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(traits::Obligation { cause: self.cause, recursion_depth: self.recursion_depth, @@ -72,8 +77,10 @@ impl<'tcx, O: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for traits::Obl } } -impl<'tcx, O: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for traits::Obligation<'tcx, O> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx, O: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> + for traits::Obligation<'tcx, O> +{ + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.predicate.visit_with(visitor)?; self.param_env.visit_with(visitor) } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index c1f0a6e9834..c07ff516579 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -116,11 +116,11 @@ pub fn elaborate_predicates_with_span<'tcx>( pub fn elaborate_obligations<'tcx>( tcx: TyCtxt<'tcx>, - mut obligations: Vec<PredicateObligation<'tcx>>, + obligations: Vec<PredicateObligation<'tcx>>, ) -> Elaborator<'tcx> { - let mut visited = PredicateSet::new(tcx); - obligations.retain(|obligation| visited.insert(obligation.predicate)); - Elaborator { stack: obligations, visited } + let mut elaborator = Elaborator { stack: Vec::new(), visited: PredicateSet::new(tcx) }; + elaborator.extend_deduped(obligations); + elaborator } fn predicate_obligation<'tcx>( @@ -132,6 +132,15 @@ fn predicate_obligation<'tcx>( } impl<'tcx> Elaborator<'tcx> { + fn extend_deduped(&mut self, obligations: impl IntoIterator<Item = PredicateObligation<'tcx>>) { + // Only keep those bounds that we haven't already seen. + // This is necessary to prevent infinite recursion in some + // cases. One common case is when people define + // `trait Sized: Sized { }` rather than `trait Sized { }`. + // let visited = &mut self.visited; + self.stack.extend(obligations.into_iter().filter(|o| self.visited.insert(o.predicate))); + } + pub fn filter_to_traits(self) -> FilterToTraits<Self> { FilterToTraits::new(self) } @@ -172,15 +181,7 @@ impl<'tcx> Elaborator<'tcx> { ) }); debug!(?data, ?obligations, "super_predicates"); - - // Only keep those bounds that we haven't already seen. - // This is necessary to prevent infinite recursion in some - // cases. One common case is when people define - // `trait Sized: Sized { }` rather than `trait Sized { }`. - let visited = &mut self.visited; - let obligations = obligations.filter(|o| visited.insert(o.predicate)); - - self.stack.extend(obligations); + self.extend_deduped(obligations); } ty::PredicateKind::WellFormed(..) => { // Currently, we do not elaborate WF predicates, @@ -237,10 +238,9 @@ impl<'tcx> Elaborator<'tcx> { return; } - let visited = &mut self.visited; let mut components = smallvec![]; push_outlives_components(tcx, ty_max, &mut components); - self.stack.extend( + self.extend_deduped( components .into_iter() .filter_map(|component| match component { @@ -280,7 +280,6 @@ impl<'tcx> Elaborator<'tcx> { .map(|predicate_kind| { bound_predicate.rebind(predicate_kind).to_predicate(tcx) }) - .filter(|&predicate| visited.insert(predicate)) .map(|predicate| { predicate_obligation( predicate, diff --git a/compiler/rustc_error_messages/locales/en-US/interface.ftl b/compiler/rustc_interface/locales/en-US.ftl index a7bc0e7af1f..da58492ccf2 100644 --- a/compiler/rustc_error_messages/locales/en-US/interface.ftl +++ b/compiler/rustc_interface/locales/en-US.ftl @@ -11,10 +11,6 @@ interface_mixed_bin_crate = interface_mixed_proc_macro_crate = cannot mix `proc-macro` crate type with others -interface_proc_macro_doc_without_arg = - Trying to document proc macro crate without passing '--crate-type proc-macro to rustdoc - .warn = The generated documentation may be incorrect - interface_error_writing_dependencies = error writing dependencies to `{$path}`: {$error} diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index 29543fe2f93..0eedee25026 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -32,10 +32,6 @@ pub struct MixedBinCrate; pub struct MixedProcMacroCrate; #[derive(Diagnostic)] -#[diag(interface_proc_macro_doc_without_arg)] -pub struct ProcMacroDocWithoutArg; - -#[derive(Diagnostic)] #[diag(interface_error_writing_dependencies)] pub struct ErrorWritingDependencies<'a> { pub path: &'a Path, diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index d504aea77d0..5e38ca034ac 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -222,6 +222,7 @@ pub struct Config { pub output_dir: Option<PathBuf>, pub output_file: Option<PathBuf>, pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>, + pub locale_resources: &'static [&'static str], pub lint_caps: FxHashMap<lint::LintId, lint::Level>, @@ -267,6 +268,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se config.opts, config.crate_cfg, config.crate_check_cfg, + config.locale_resources, config.file_loader, CompilerIO { input: config.input, diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 82bc4770b6b..1abbe8d4fab 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -12,6 +12,9 @@ #[macro_use] extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + mod callbacks; mod errors; pub mod interface; @@ -27,3 +30,5 @@ pub use queries::Queries; #[cfg(test)] mod tests; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index aa59654099a..81c1d665ef0 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -287,28 +287,18 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>) sess.emit_warning(errors::ProcMacroCratePanicAbort); } - // For backwards compatibility, we don't try to run proc macro injection - // if rustdoc is run on a proc macro crate without '--crate-type proc-macro' being - // specified. This should only affect users who manually invoke 'rustdoc', as - // 'cargo doc' will automatically pass the proper '--crate-type' flags. - // However, we do emit a warning, to let such users know that they should - // start passing '--crate-type proc-macro' - if has_proc_macro_decls && sess.opts.actually_rustdoc && !is_proc_macro_crate { - sess.emit_warning(errors::ProcMacroDocWithoutArg); - } else { - krate = sess.time("maybe_create_a_macro_crate", || { - let is_test_crate = sess.opts.test; - rustc_builtin_macros::proc_macro_harness::inject( - sess, - resolver, - krate, - is_proc_macro_crate, - has_proc_macro_decls, - is_test_crate, - sess.diagnostic(), - ) - }); - } + krate = sess.time("maybe_create_a_macro_crate", || { + let is_test_crate = sess.opts.test; + rustc_builtin_macros::proc_macro_harness::inject( + sess, + resolver, + krate, + is_proc_macro_crate, + has_proc_macro_decls, + is_test_crate, + sess.diagnostic(), + ) + }); // Done with macro expansion! diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index c957578b59e..a96cc95a384 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -7,11 +7,10 @@ use rustc_codegen_ssa::traits::CodegenBackend; use rustc_codegen_ssa::CodegenResults; use rustc_data_structures::steal::Steal; use rustc_data_structures::svh::Svh; -use rustc_data_structures::sync::{Lrc, OnceCell, RwLock, WorkerLocal}; +use rustc_data_structures::sync::{AppendOnlyVec, Lrc, OnceCell, RwLock, WorkerLocal}; use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::Definitions; use rustc_incremental::DepGraphFuture; -use rustc_index::vec::IndexVec; use rustc_lint::LintStore; use rustc_metadata::creader::CStore; use rustc_middle::arena::Arena; @@ -195,10 +194,9 @@ impl<'tcx> Queries<'tcx> { let cstore = RwLock::new(Box::new(CStore::new(sess)) as _); let definitions = RwLock::new(Definitions::new(sess.local_stable_crate_id())); - let mut source_span = IndexVec::default(); + let source_span = AppendOnlyVec::new(); let _id = source_span.push(krate.spans.inner_span); debug_assert_eq!(_id, CRATE_DEF_ID); - let source_span = RwLock::new(source_span); let untracked = Untracked { cstore, source_span, definitions }; let qcx = passes::create_global_ctxt( diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index ac32988d3ac..18d84a7023a 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -50,7 +50,7 @@ fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) { output_file: None, temps_dir, }; - let sess = build_session(sessopts, io, None, registry, Default::default(), None, None); + let sess = build_session(sessopts, io, None, registry, vec![], Default::default(), None, None); (sess, cfg) } @@ -756,6 +756,7 @@ fn test_unstable_options_tracking_hash() { tracked!(instrument_coverage, Some(InstrumentCoverage::All)); tracked!(instrument_mcount, true); tracked!(instrument_xray, Some(InstrumentXRay::default())); + tracked!(link_directives, false); tracked!(link_only, true); tracked!(llvm_plugins, vec![String::from("plugin_name")]); tracked!(location_detail, LocationDetail { file: true, line: false, column: false }); @@ -776,7 +777,6 @@ fn test_unstable_options_tracking_hash() { tracked!(packed_bundled_libs, true); tracked!(panic_abort_tests, true); tracked!(panic_in_drop, PanicStrategy::Abort); - tracked!(pick_stable_methods_before_any_unstable, false); tracked!(plt, Some(true)); tracked!(polonius, true); tracked!(precise_enum_drop_elaboration, false); diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 475d3601b52..e5d2fb2ea28 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -59,6 +59,7 @@ pub fn create_session( sopts: config::Options, cfg: FxHashSet<(String, Option<String>)>, check_cfg: CheckCfg, + locale_resources: &'static [&'static str], file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, io: CompilerIO, lint_caps: FxHashMap<lint::LintId, lint::Level>, @@ -89,11 +90,15 @@ pub fn create_session( } }; + let mut locale_resources = Vec::from(locale_resources); + locale_resources.push(codegen_backend.locale_resource()); + let mut sess = session::build_session( sopts, io, bundle, descriptions, + locale_resources, lint_caps, file_loader, target_override, diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_lint/locales/en-US.ftl index b1e7cc69a80..68e62c9789a 100644 --- a/compiler/rustc_error_messages/locales/en-US/lint.ftl +++ b/compiler/rustc_lint/locales/en-US.ftl @@ -24,6 +24,13 @@ lint_for_loops_over_fallibles = .use_while_let = to check pattern in a loop use `while let` .use_question_mark = consider unwrapping the `Result` with `?` to iterate over its contents +lint_map_unit_fn = `Iterator::map` call that discard the iterator's values + .note = `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated + .function_label = this function returns `()`, which is likely not what you wanted + .argument_label = called `Iterator::map` with callable that returns `()` + .map_label = after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items + .suggestion = you might have meant to use `Iterator::for_each` + lint_non_binding_let_on_sync_lock = non-binding let on a synchronization lock diff --git a/compiler/rustc_lint/src/array_into_iter.rs b/compiler/rustc_lint/src/array_into_iter.rs index 3593f141df6..bccb0a94e98 100644 --- a/compiler/rustc_lint/src/array_into_iter.rs +++ b/compiler/rustc_lint/src/array_into_iter.rs @@ -1,5 +1,7 @@ -use crate::lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub}; -use crate::{LateContext, LateLintPass, LintContext}; +use crate::{ + lints::{ArrayIntoIterDiag, ArrayIntoIterDiagSub}, + LateContext, LateLintPass, LintContext, +}; use rustc_hir as hir; use rustc_middle::ty; use rustc_middle::ty::adjustment::{Adjust, Adjustment}; diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 11fb1f80a11..59540aaf18f 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -20,6 +20,7 @@ //! If you define a new `LateLintPass`, you will also need to add it to the //! `late_lint_methods!` invocation in `lib.rs`. +use crate::fluent_generated as fluent; use crate::{ errors::BuiltinEllpisisInclusiveRangePatterns, lints::{ @@ -50,7 +51,7 @@ use rustc_ast::{self as ast, *}; use rustc_ast_pretty::pprust::{self, expr_to_string}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{fluent, Applicability, DecorateLint, MultiSpan}; +use rustc_errors::{Applicability, DecorateLint, MultiSpan}; use rustc_feature::{deprecated_attributes, AttributeGate, BuiltinAttribute, GateIssue, Stability}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -676,21 +677,21 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { return; } let def = cx.tcx.adt_def(item.owner_id); - (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) + (def, cx.tcx.mk_adt(def, ty::List::empty())) } hir::ItemKind::Union(_, ref ast_generics) => { if !ast_generics.params.is_empty() { return; } let def = cx.tcx.adt_def(item.owner_id); - (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) + (def, cx.tcx.mk_adt(def, ty::List::empty())) } hir::ItemKind::Enum(_, ref ast_generics) => { if !ast_generics.params.is_empty() { return; } let def = cx.tcx.adt_def(item.owner_id); - (def, cx.tcx.mk_adt(def, cx.tcx.intern_substs(&[]))) + (def, cx.tcx.mk_adt(def, ty::List::empty())) } _ => return, }; @@ -1583,7 +1584,7 @@ declare_lint_pass!( impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) { - use rustc_middle::ty::visit::TypeVisitable; + use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::Clause; use rustc_middle::ty::PredicateKind::*; @@ -2635,7 +2636,13 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { cx.emit_spanned_lint( INVALID_VALUE, expr.span, - BuiltinUnpermittedTypeInit { msg, ty: conjured_ty, label: expr.span, sub }, + BuiltinUnpermittedTypeInit { + msg, + ty: conjured_ty, + label: expr.span, + sub, + tcx: cx.tcx, + }, ); } } diff --git a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs index 73bd4173270..f1ba192f2bc 100644 --- a/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs +++ b/compiler/rustc_lint/src/enum_intrinsics_non_enums.rs @@ -4,7 +4,7 @@ use crate::{ LateContext, LateLintPass, }; use rustc_hir as hir; -use rustc_middle::ty::{visit::TypeVisitable, Ty}; +use rustc_middle::ty::{visit::TypeVisitableExt, Ty}; use rustc_span::{symbol::sym, Span}; declare_lint! { diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs index f3ae2609186..9af5284df1e 100644 --- a/compiler/rustc_lint/src/errors.rs +++ b/compiler/rustc_lint/src/errors.rs @@ -1,6 +1,6 @@ +use crate::fluent_generated as fluent; use rustc_errors::{ - fluent, AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic, - SubdiagnosticMessage, + AddToDiagnostic, Diagnostic, ErrorGuaranteed, Handler, IntoDiagnostic, SubdiagnosticMessage, }; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::lint::Level; @@ -116,7 +116,7 @@ impl IntoDiagnostic<'_> for CheckNameUnknown { let mut diag = handler.struct_err(fluent::lint_check_name_unknown); diag.code(rustc_errors::error_code!(E0602)); if let Some(suggestion) = self.suggestion { - diag.help(fluent::help); + diag.help(fluent::lint_help); diag.set_arg("suggestion", suggestion); } diag.set_arg("lint_name", self.lint_name); diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index cca36913dea..bc7488fab4a 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -1,13 +1,16 @@ -use crate::context::{CheckLintNameResult, LintStore}; -use crate::late::unerased_lint_store; -use crate::lints::{ - DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint, - RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion, +use crate::{ + context::{CheckLintNameResult, LintStore}, + fluent_generated as fluent, + late::unerased_lint_store, + lints::{ + DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, + RenamedOrRemovedLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion, + }, }; use rustc_ast as ast; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{fluent, DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan}; +use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan}; use rustc_hir as hir; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::HirId; @@ -983,7 +986,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> { fluent::lint_unknown_gated_lint, |lint| { lint.set_arg("name", lint_id.lint.name_lower()); - lint.note(fluent::note); + lint.note(fluent::lint_note); add_feature_diagnostics(lint, &self.sess.parse_sess, feature); lint }, diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 4ca37ef6850..35dc533e56c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -63,6 +63,7 @@ mod late; mod let_underscore; mod levels; mod lints; +mod map_unit_fn; mod methods; mod multiple_supertrait_upcastable; mod non_ascii_idents; @@ -80,8 +81,10 @@ mod unused; pub use array_into_iter::ARRAY_INTO_ITER; use rustc_ast as ast; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; +use rustc_macros::fluent_messages; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_session::lint::builtin::{ @@ -98,6 +101,7 @@ use for_loops_over_fallibles::*; use hidden_unicode_codepoints::*; use internal::*; use let_underscore::*; +use map_unit_fn::*; use methods::*; use multiple_supertrait_upcastable::*; use non_ascii_idents::*; @@ -122,6 +126,8 @@ pub use rustc_session::lint::Level::{self, *}; pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId}; pub use rustc_session::lint::{LintArray, LintPass}; +fluent_messages! { "../locales/en-US.ftl" } + pub fn provide(providers: &mut Providers) { levels::provide(providers); expect::provide(providers); @@ -235,6 +241,7 @@ late_lint_methods!( NamedAsmLabels: NamedAsmLabels, OpaqueHiddenInferredBound: OpaqueHiddenInferredBound, MultipleSupertraitUpcastable: MultipleSupertraitUpcastable, + MapUnitFn: MapUnitFn, ] ] ); @@ -294,7 +301,8 @@ fn register_builtins(store: &mut LintStore) { UNUSED_LABELS, UNUSED_PARENS, UNUSED_BRACES, - REDUNDANT_SEMICOLONS + REDUNDANT_SEMICOLONS, + MAP_UNIT_FN ); add_lint_group!("let_underscore", LET_UNDERSCORE_DROP, LET_UNDERSCORE_LOCK); diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 94a43ab0c46..20ab0af5856 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2,13 +2,16 @@ #![allow(rustc::diagnostic_outside_of_impl)] use std::num::NonZeroU32; +use crate::fluent_generated as fluent; use rustc_errors::{ - fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, - DiagnosticStyledString, SuggestionStyle, + AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString, + SuggestionStyle, }; use rustc_hir::def_id::DefId; use rustc_macros::{LintDiagnostic, Subdiagnostic}; -use rustc_middle::ty::{PolyExistentialTraitRef, Predicate, Ty, TyCtxt}; +use rustc_middle::ty::{ + inhabitedness::InhabitedPredicate, PolyExistentialTraitRef, Predicate, Ty, TyCtxt, +}; use rustc_session::parse::ParseSess; use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol}; @@ -21,7 +24,7 @@ use crate::{ #[diag(lint_array_into_iter)] pub struct ArrayIntoIterDiag<'a> { pub target: &'a str, - #[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")] + #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")] pub suggestion: Span, #[subdiagnostic] pub sub: Option<ArrayIntoIterDiagSub>, @@ -29,12 +32,15 @@ pub struct ArrayIntoIterDiag<'a> { #[derive(Subdiagnostic)] pub enum ArrayIntoIterDiagSub { - #[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")] + #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")] RemoveIntoIter { #[primary_span] span: Span, }, - #[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")] + #[multipart_suggestion( + lint_use_explicit_into_iter_suggestion, + applicability = "maybe-incorrect" + )] UseExplicitIntoIter { #[suggestion_part(code = "IntoIterator::into_iter(")] start_span: Span, @@ -161,13 +167,13 @@ pub struct BuiltinDeprecatedAttrLink<'a> { #[derive(Subdiagnostic)] pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> { - #[suggestion(msg_suggestion, code = "", applicability = "machine-applicable")] + #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")] Msg { #[primary_span] suggestion: Span, msg: &'a str, }, - #[suggestion(default_suggestion, code = "", applicability = "machine-applicable")] + #[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")] Default { #[primary_span] suggestion: Span, @@ -199,9 +205,9 @@ pub struct BuiltinUnusedDocComment<'a> { #[derive(Subdiagnostic)] pub enum BuiltinUnusedDocCommentSub { - #[help(plain_help)] + #[help(lint_plain_help)] PlainHelp, - #[help(block_help)] + #[help(lint_block_help)] BlockHelp, } @@ -240,7 +246,7 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> { self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { - diag.span_label(self.label, fluent::label); + diag.span_label(self.label, fluent::lint_label); rustc_session::parse::add_feature_diagnostics( diag, &self.parse_sess, @@ -335,7 +341,7 @@ impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion { ) -> rustc_errors::SubdiagnosticMessage, { diag.multipart_suggestion( - fluent::suggestion, + fluent::lint_suggestion, self.suggestions, Applicability::MachineApplicable, ); @@ -386,7 +392,7 @@ pub struct BuiltinExplicitOutlives { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion)] +#[multipart_suggestion(lint_suggestion)] pub struct BuiltinExplicitOutlivesSuggestion { #[suggestion_part(code = "")] pub spans: Vec<Span>, @@ -405,11 +411,11 @@ pub struct BuiltinIncompleteFeatures { } #[derive(Subdiagnostic)] -#[help(help)] +#[help(lint_help)] pub struct BuiltinIncompleteFeaturesHelp; #[derive(Subdiagnostic)] -#[note(note)] +#[note(lint_note)] pub struct BuiltinIncompleteFeaturesNote { pub n: NonZeroU32, } @@ -419,6 +425,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> { pub ty: Ty<'a>, pub label: Span, pub sub: BuiltinUnpermittedTypeInitSub, + pub tcx: TyCtxt<'a>, } impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> { @@ -428,7 +435,13 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> { ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { diag.set_arg("ty", self.ty); diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label); - diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label_suggestion); + if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) { + // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited. + diag.span_label( + self.label, + fluent::lint_builtin_unpermitted_type_init_label_suggestion, + ); + } self.sub.add_to_diagnostic(diag); diag } @@ -473,9 +486,9 @@ pub enum BuiltinClashingExtern<'a> { SameName { this: Symbol, orig: Symbol, - #[label(previous_decl_label)] + #[label(lint_previous_decl_label)] previous_decl_label: Span, - #[label(mismatch_label)] + #[label(lint_mismatch_label)] mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, @@ -484,9 +497,9 @@ pub enum BuiltinClashingExtern<'a> { DiffName { this: Symbol, orig: Symbol, - #[label(previous_decl_label)] + #[label(lint_previous_decl_label)] previous_decl_label: Span, - #[label(mismatch_label)] + #[label(lint_mismatch_label)] mismatch_label: Span, #[subdiagnostic] sub: BuiltinClashingExternSub<'a>, @@ -562,7 +575,7 @@ pub struct SupertraitAsDerefTarget<'a> { } #[derive(Subdiagnostic)] -#[label(label)] +#[label(lint_label)] pub struct SupertraitAsDerefTargetLabel { #[primary_span] pub label: Span, @@ -595,7 +608,7 @@ pub struct Expectation { } #[derive(Subdiagnostic)] -#[note(rationale)] +#[note(lint_rationale)] pub struct ExpectationNote { pub rationale: Symbol, } @@ -616,13 +629,13 @@ pub struct ForLoopsOverFalliblesDiag<'a> { #[derive(Subdiagnostic)] pub enum ForLoopsOverFalliblesLoopSub<'a> { - #[suggestion(remove_next, code = ".by_ref()", applicability = "maybe-incorrect")] + #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")] RemoveNext { #[primary_span] suggestion: Span, recv_snip: String, }, - #[multipart_suggestion(use_while_let, applicability = "maybe-incorrect")] + #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")] UseWhileLet { #[suggestion_part(code = "while let {var}(")] start_span: Span, @@ -633,14 +646,14 @@ pub enum ForLoopsOverFalliblesLoopSub<'a> { } #[derive(Subdiagnostic)] -#[suggestion(use_question_mark, code = "?", applicability = "maybe-incorrect")] +#[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")] pub struct ForLoopsOverFalliblesQuestionMark { #[primary_span] pub suggestion: Span, } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")] pub struct ForLoopsOverFalliblesSuggestion<'a> { pub var: &'a str, #[suggestion_part(code = "if let {var}(")] @@ -699,13 +712,13 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub { match self { HiddenUnicodeCodepointsDiagSub::Escape { spans } => { diag.multipart_suggestion_with_style( - fluent::suggestion_remove, + fluent::lint_suggestion_remove, spans.iter().map(|(_, span)| (*span, "".to_string())).collect(), Applicability::MachineApplicable, SuggestionStyle::HideCodeAlways, ); diag.multipart_suggestion( - fluent::suggestion_escape, + fluent::lint_suggestion_escape, spans .into_iter() .map(|(c, span)| { @@ -728,13 +741,29 @@ impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub { .collect::<Vec<String>>() .join(", "), ); - diag.note(fluent::suggestion_remove); - diag.note(fluent::no_suggestion_note_escape); + diag.note(fluent::lint_suggestion_remove); + diag.note(fluent::lint_no_suggestion_note_escape); } } } } +// map_unit_fn.rs +#[derive(LintDiagnostic)] +#[diag(lint_map_unit_fn)] +#[note] +pub struct MappingToUnit { + #[label(lint_function_label)] + pub function_label: Span, + #[label(lint_argument_label)] + pub argument_label: Span, + #[label(lint_map_label)] + pub map_label: Span, + #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")] + pub suggestion: Span, + pub replace: String, +} + // internal.rs #[derive(LintDiagnostic)] #[diag(lint_default_hash_types)] @@ -874,7 +903,7 @@ pub struct RenamedOrRemovedLint<'a> { } #[derive(Subdiagnostic)] -#[suggestion(suggestion, code = "{replace}", applicability = "machine-applicable")] +#[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")] pub struct RenamedOrRemovedLintSuggestion<'a> { #[primary_span] pub suggestion: Span, @@ -890,7 +919,7 @@ pub struct UnknownLint { } #[derive(Subdiagnostic)] -#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")] +#[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] pub struct UnknownLintSuggestion { #[primary_span] pub suggestion: Span, @@ -910,9 +939,9 @@ pub struct IgnoredUnlessCrateSpecified<'a> { #[note] #[help] pub struct CStringPtr { - #[label(as_ptr_label)] + #[label(lint_as_ptr_label)] pub as_ptr: Span, - #[label(unwrap_label)] + #[label(lint_unwrap_label)] pub unwrap: Span, } @@ -943,7 +972,7 @@ pub struct ConfusableIdentifierPair { #[derive(LintDiagnostic)] #[diag(lint_mixed_script_confusables)] -#[note(includes_note)] +#[note(lint_includes_note)] #[note] pub struct MixedScriptConfusables { pub set: String, @@ -963,17 +992,17 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused { diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { diag.set_arg("count", self.count); - diag.note(fluent::note); + diag.note(fluent::lint_note); if let Some(span) = self.suggestion { diag.span_suggestion( span.shrink_to_hi(), - fluent::add_args_suggestion, + fluent::lint_add_args_suggestion, ", ...", Applicability::HasPlaceholders, ); diag.span_suggestion( span.shrink_to_lo(), - fluent::add_fmt_suggestion, + fluent::lint_add_fmt_suggestion, "\"{}\", ", Applicability::MachineApplicable, ); @@ -1007,12 +1036,12 @@ pub struct NonCamelCaseType<'a> { #[derive(Subdiagnostic)] pub enum NonCamelCaseTypeSub { - #[label(label)] + #[label(lint_label)] Label { #[primary_span] span: Span, }, - #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")] + #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] Suggestion { #[primary_span] span: Span, @@ -1048,15 +1077,15 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub { { match self { NonSnakeCaseDiagSub::Label { span } => { - diag.span_label(span, fluent::label); + diag.span_label(span, fluent::lint_label); } NonSnakeCaseDiagSub::Help => { - diag.help(fluent::help); + diag.help(fluent::lint_help); } NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => { diag.span_suggestion( span, - fluent::convert_suggestion, + fluent::lint_convert_suggestion, suggestion, Applicability::MaybeIncorrect, ); @@ -1064,16 +1093,16 @@ impl AddToDiagnostic for NonSnakeCaseDiagSub { NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => { diag.span_suggestion( span, - fluent::rename_or_convert_suggestion, + fluent::lint_rename_or_convert_suggestion, suggestion, Applicability::MaybeIncorrect, ); } NonSnakeCaseDiagSub::SuggestionAndNote { span } => { - diag.note(fluent::cannot_convert_note); + diag.note(fluent::lint_cannot_convert_note); diag.span_suggestion( span, - fluent::rename_suggestion, + fluent::lint_rename_suggestion, "", Applicability::MaybeIncorrect, ); @@ -1093,12 +1122,12 @@ pub struct NonUpperCaseGlobal<'a> { #[derive(Subdiagnostic)] pub enum NonUpperCaseGlobalSub { - #[label(label)] + #[label(lint_label)] Label { #[primary_span] span: Span, }, - #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")] + #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")] Suggestion { #[primary_span] span: Span, @@ -1216,11 +1245,11 @@ impl AddToDiagnostic for OverflowingBinHexSign { { match self { OverflowingBinHexSign::Positive => { - diag.note(fluent::positive_note); + diag.note(fluent::lint_positive_note); } OverflowingBinHexSign::Negative => { - diag.note(fluent::negative_note); - diag.note(fluent::negative_becomes_note); + diag.note(fluent::lint_negative_note); + diag.note(fluent::lint_negative_becomes_note); } } } @@ -1229,7 +1258,7 @@ impl AddToDiagnostic for OverflowingBinHexSign { #[derive(Subdiagnostic)] pub enum OverflowingBinHexSub<'a> { #[suggestion( - suggestion, + lint_suggestion, code = "{sans_suffix}{suggestion_ty}", applicability = "machine-applicable" )] @@ -1239,7 +1268,7 @@ pub enum OverflowingBinHexSub<'a> { suggestion_ty: &'a str, sans_suffix: &'a str, }, - #[help(help)] + #[help(lint_help)] Help { suggestion_ty: &'a str }, } @@ -1256,7 +1285,7 @@ pub struct OverflowingInt<'a> { } #[derive(Subdiagnostic)] -#[help(help)] +#[help(lint_help)] pub struct OverflowingIntHelp<'a> { pub suggestion_ty: &'a str, } @@ -1308,13 +1337,13 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> { ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> { diag.set_arg("ty", self.ty); diag.set_arg("desc", self.desc); - diag.span_label(self.label, fluent::label); + diag.span_label(self.label, fluent::lint_label); if let Some(help) = self.help { diag.help(help); } diag.note(self.note); if let Some(note) = self.span_note { - diag.span_note(note, fluent::note); + diag.span_note(note, fluent::lint_note); } diag } @@ -1407,7 +1436,7 @@ pub struct UnusedDef<'a, 'b> { #[derive(Subdiagnostic)] pub enum UnusedDefSuggestion { #[suggestion( - suggestion, + lint_suggestion, style = "verbose", code = "let _ = ", applicability = "machine-applicable" @@ -1451,13 +1480,13 @@ pub struct PathStatementDrop { #[derive(Subdiagnostic)] pub enum PathStatementDropSub { - #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")] + #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")] Suggestion { #[primary_span] span: Span, snippet: String, }, - #[help(help)] + #[help(lint_help)] Help { #[primary_span] span: Span, @@ -1478,7 +1507,7 @@ pub struct UnusedDelim<'a> { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")] pub struct UnusedDelimSuggestion { #[suggestion_part(code = "{start_replace}")] pub start_span: Span, diff --git a/compiler/rustc_lint/src/map_unit_fn.rs b/compiler/rustc_lint/src/map_unit_fn.rs new file mode 100644 index 00000000000..62e8b4fe9e4 --- /dev/null +++ b/compiler/rustc_lint/src/map_unit_fn.rs @@ -0,0 +1,120 @@ +use crate::lints::MappingToUnit; +use crate::{LateContext, LateLintPass, LintContext}; + +use rustc_hir::{Expr, ExprKind, HirId, Stmt, StmtKind}; +use rustc_middle::{ + query::Key, + ty::{self, Ty}, +}; + +declare_lint! { + /// The `map_unit_fn` lint checks for `Iterator::map` receive + /// a callable that returns `()`. + /// + /// ### Example + /// + /// ```rust + /// fn foo(items: &mut Vec<u8>) { + /// items.sort(); + /// } + /// + /// fn main() { + /// let mut x: Vec<Vec<u8>> = vec![ + /// vec![0, 2, 1], + /// vec![5, 4, 3], + /// ]; + /// x.iter_mut().map(foo); + /// } + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// Mapping to `()` is almost always a mistake. + pub MAP_UNIT_FN, + Warn, + "`Iterator::map` call that discard the iterator's values" +} + +declare_lint_pass!(MapUnitFn => [MAP_UNIT_FN]); + +impl<'tcx> LateLintPass<'tcx> for MapUnitFn { + fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) { + if stmt.span.from_expansion() { + return; + } + + if let StmtKind::Semi(expr) = stmt.kind { + if let ExprKind::MethodCall(path, receiver, args, span) = expr.kind { + if path.ident.name.as_str() == "map" { + if receiver.span.from_expansion() + || args.iter().any(|e| e.span.from_expansion()) + || !is_impl_slice(cx, receiver) + || !is_diagnostic_name(cx, expr.hir_id, "IteratorMap") + { + return; + } + let arg_ty = cx.typeck_results().expr_ty(&args[0]); + if let ty::FnDef(id, _) = arg_ty.kind() { + let fn_ty = cx.tcx.fn_sig(id).skip_binder(); + let ret_ty = fn_ty.output().skip_binder(); + if is_unit_type(ret_ty) { + cx.emit_spanned_lint( + MAP_UNIT_FN, + span, + MappingToUnit { + function_label: cx.tcx.span_of_impl(*id).unwrap(), + argument_label: args[0].span, + map_label: arg_ty.default_span(cx.tcx), + suggestion: path.ident.span, + replace: "for_each".to_string(), + }, + ) + } + } else if let ty::Closure(id, subs) = arg_ty.kind() { + let cl_ty = subs.as_closure().sig(); + let ret_ty = cl_ty.output().skip_binder(); + if is_unit_type(ret_ty) { + cx.emit_spanned_lint( + MAP_UNIT_FN, + span, + MappingToUnit { + function_label: cx.tcx.span_of_impl(*id).unwrap(), + argument_label: args[0].span, + map_label: arg_ty.default_span(cx.tcx), + suggestion: path.ident.span, + replace: "for_each".to_string(), + }, + ) + } + } + } + } + } + } +} + +fn is_impl_slice(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { + if let Some(impl_id) = cx.tcx.impl_of_method(method_id) { + return cx.tcx.type_of(impl_id).skip_binder().is_slice(); + } + } + false +} + +fn is_unit_type(ty: Ty<'_>) -> bool { + ty.is_unit() || ty.is_never() +} + +fn is_diagnostic_name(cx: &LateContext<'_>, id: HirId, name: &str) -> bool { + if let Some(def_id) = cx.typeck_results().type_dependent_def_id(id) { + if let Some(item) = cx.tcx.get_diagnostic_name(def_id) { + if item.as_str() == name { + return true; + } + } + } + false +} diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 548f30ec972..5bb1abfd2ec 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -1,7 +1,7 @@ use crate::lints::{NonFmtPanicBraces, NonFmtPanicUnused}; -use crate::{LateContext, LateLintPass, LintContext}; +use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext}; use rustc_ast as ast; -use rustc_errors::{fluent, Applicability}; +use rustc_errors::Applicability; use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::lint::in_external_macro; @@ -122,18 +122,18 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc #[allow(rustc::diagnostic_outside_of_impl)] cx.struct_span_lint(NON_FMT_PANICS, arg_span, fluent::lint_non_fmt_panic, |lint| { lint.set_arg("name", symbol); - lint.note(fluent::note); - lint.note(fluent::more_info_note); + lint.note(fluent::lint_note); + lint.note(fluent::lint_more_info_note); if !is_arg_inside_call(arg_span, span) { // No clue where this argument is coming from. return lint; } if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) { // A case of `panic!(format!(..))`. - lint.note(fluent::supports_fmt_note); + lint.note(fluent::lint_supports_fmt_note); if let Some((open, close, _)) = find_delimiters(cx, arg_span) { lint.multipart_suggestion( - fluent::supports_fmt_suggestion, + fluent::lint_supports_fmt_suggestion, vec![ (arg_span.until(open.shrink_to_hi()), "".into()), (close.until(arg_span.shrink_to_hi()), "".into()), @@ -179,7 +179,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if suggest_display { lint.span_suggestion_verbose( arg_span.shrink_to_lo(), - fluent::display_suggestion, + fluent::lint_display_suggestion, "\"{}\", ", fmt_applicability, ); @@ -187,7 +187,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc lint.set_arg("ty", ty); lint.span_suggestion_verbose( arg_span.shrink_to_lo(), - fluent::debug_suggestion, + fluent::lint_debug_suggestion, "\"{:?}\", ", fmt_applicability, ); @@ -197,7 +197,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc if let Some((open, close, del)) = find_delimiters(cx, span) { lint.set_arg("already_suggested", suggest_display || suggest_debug); lint.multipart_suggestion( - fluent::panic_suggestion, + fluent::lint_panic_suggestion, if del == '(' { vec![(span.until(open), "std::panic::panic_any".into())] } else { diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 42442cfb190..883a56cb3ce 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -149,7 +149,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { struct OpaqueHiddenInferredBoundLint<'tcx> { ty: Ty<'tcx>, proj_ty: Ty<'tcx>, - #[label(specifically)] + #[label(lint_specifically)] assoc_pred_span: Span, #[subdiagnostic] add_bound: Option<AddBound<'tcx>>, diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b7fd6a254d8..85958c41705 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1,19 +1,24 @@ -use crate::lints::{ - AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, - InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, - OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt, - RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag, +use crate::{ + fluent_generated as fluent, + lints::{ + AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, + InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, + OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, + OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag, + }, }; use crate::{LateContext, LateLintPass, LintContext}; use rustc_ast as ast; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{fluent, DiagnosticMessage}; +use rustc_errors::DiagnosticMessage; use rustc_hir as hir; use rustc_hir::{is_range_literal, Expr, ExprKind, Node}; use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{ + self, AdtKind, DefIdTree, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, +}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map; use rustc_span::symbol::sym; @@ -1144,7 +1149,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { fn check_for_opaque_ty(&mut self, sp: Span, ty: Ty<'tcx>) -> bool { struct ProhibitOpaqueTypes; - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueTypes { type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 9d8ad9d9ed9..46ec1a2dca1 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4103,3 +4103,33 @@ declare_lint! { }; report_in_external_macro } + +declare_lint! { + /// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments. + /// + /// ### Example + /// + /// ```rust,compile_fail + /// #![deny(invalid_macro_export_arguments)] + /// + /// #[macro_export(invalid_parameter)] + /// macro_rules! myMacro { + /// () => { + /// // [...] + /// } + /// } + /// + /// #[macro_export(too, many, items)] + /// ``` + /// + /// {{produces}} + /// + /// ### Explanation + /// + /// The only valid argument is `#[macro_export(local_inner_macros)]` or no argument (`#[macro_export]`). + /// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`. + /// + pub INVALID_MACRO_EXPORT_ARGUMENTS, + Warn, + "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`", +} diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 9ff94486404..12a954258d1 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -57,7 +57,7 @@ impl<'a> DiagnosticDerive<'a> { } Some(slug) => { quote! { - let mut #diag = #handler.struct_diagnostic(rustc_errors::fluent::#slug); + let mut #diag = #handler.struct_diagnostic(crate::fluent_generated::#slug); } } }; @@ -149,7 +149,7 @@ impl<'a> LintDiagnosticDerive<'a> { } Some(slug) => { quote! { - rustc_errors::fluent::#slug.into() + crate::fluent_generated::#slug.into() } } } diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs index 12bcd939bd6..46068f8c868 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic_builder.rs @@ -452,7 +452,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { Ok(quote! { #diag.span_suggestions_with_style( #span_field, - rustc_errors::fluent::#slug, + crate::fluent_generated::#slug, #code_field, #applicability, #style @@ -476,7 +476,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { quote! { #diag.#fn_name( #field_binding, - rustc_errors::fluent::#fluent_attr_identifier + crate::fluent_generated::#fluent_attr_identifier ); } } @@ -486,7 +486,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> { fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream { let diag = &self.parent.diag; quote! { - #diag.#kind(rustc_errors::fluent::#fluent_attr_identifier); + #diag.#kind(crate::fluent_generated::#fluent_attr_identifier); } } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 08098c9bb2a..38c0f4895db 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -19,52 +19,9 @@ use std::{ io::Read, path::{Path, PathBuf}, }; -use syn::{ - parse::{Parse, ParseStream}, - parse_macro_input, - punctuated::Punctuated, - token, Ident, LitStr, Result, -}; +use syn::{parse_macro_input, Ident, LitStr}; use unic_langid::langid; -struct Resource { - krate: Ident, - #[allow(dead_code)] - fat_arrow_token: token::FatArrow, - resource_path: LitStr, -} - -impl Parse for Resource { - fn parse(input: ParseStream<'_>) -> Result<Self> { - Ok(Resource { - krate: input.parse()?, - fat_arrow_token: input.parse()?, - resource_path: input.parse()?, - }) - } -} - -struct Resources(Punctuated<Resource, token::Comma>); - -impl Parse for Resources { - fn parse(input: ParseStream<'_>) -> Result<Self> { - let mut resources = Punctuated::new(); - loop { - if input.is_empty() || input.peek(token::Brace) { - break; - } - let value = input.parse()?; - resources.push_value(value); - if !input.peek(token::Comma) { - break; - } - let punct = input.parse()?; - resources.push_punct(punct); - } - Ok(Resources(resources)) - } -} - /// Helper function for returning an absolute path for macro-invocation relative file paths. /// /// If the input is already absolute, then the input is returned. If the input is not absolute, @@ -84,251 +41,285 @@ fn invocation_relative_path_to_absolute(span: Span, path: &str) -> PathBuf { } } +/// Tokens to be returned when the macro cannot proceed. +fn failed(crate_name: &Ident) -> proc_macro::TokenStream { + quote! { + pub static DEFAULT_LOCALE_RESOURCE: &'static str = ""; + + #[allow(non_upper_case_globals)] + #[doc(hidden)] + pub(crate) mod fluent_generated { + pub mod #crate_name { + } + + pub mod _subdiag { + pub const help: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); + pub const note: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); + pub const warn: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); + pub const label: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); + pub const suggestion: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); + } + } + } + .into() +} + /// See [rustc_macros::fluent_messages]. pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let resources = parse_macro_input!(input as Resources); + let crate_name = std::env::var("CARGO_PKG_NAME") + // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use + // `no_crate`. + .unwrap_or_else(|_| "no_crate".to_string()) + .replace("rustc_", ""); // Cannot iterate over individual messages in a bundle, so do that using the // `FluentResource` instead. Construct a bundle anyway to find out if there are conflicting // messages in the resources. let mut bundle = FluentBundle::new(vec![langid!("en-US")]); - // Map of Fluent identifiers to the `Span` of the resource that defined them, used for better - // diagnostics. - let mut previous_defns = HashMap::new(); - // Set of Fluent attribute names already output, to avoid duplicate type errors - any given // constant created for a given attribute is the same. let mut previous_attrs = HashSet::new(); - let mut includes = TokenStream::new(); - let mut generated = TokenStream::new(); + let resource_str = parse_macro_input!(input as LitStr); + let resource_span = resource_str.span().unwrap(); + let relative_ftl_path = resource_str.value(); + let absolute_ftl_path = invocation_relative_path_to_absolute(resource_span, &relative_ftl_path); - for res in resources.0 { - let krate_span = res.krate.span().unwrap(); - let path_span = res.resource_path.span().unwrap(); + let crate_name = Ident::new(&crate_name, resource_str.span()); - let relative_ftl_path = res.resource_path.value(); - let absolute_ftl_path = - invocation_relative_path_to_absolute(krate_span, &relative_ftl_path); - // As this macro also outputs an `include_str!` for this file, the macro will always be - // re-executed when the file changes. - let mut resource_file = match File::open(absolute_ftl_path) { - Ok(resource_file) => resource_file, - Err(e) => { - Diagnostic::spanned(path_span, Level::Error, "could not open Fluent resource") - .note(e.to_string()) - .emit(); - continue; - } - }; - let mut resource_contents = String::new(); - if let Err(e) = resource_file.read_to_string(&mut resource_contents) { - Diagnostic::spanned(path_span, Level::Error, "could not read Fluent resource") + // As this macro also outputs an `include_str!` for this file, the macro will always be + // re-executed when the file changes. + let mut resource_file = match File::open(absolute_ftl_path) { + Ok(resource_file) => resource_file, + Err(e) => { + Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource") .note(e.to_string()) .emit(); - continue; + return failed(&crate_name); } - let resource = match FluentResource::try_new(resource_contents) { - Ok(resource) => resource, - Err((this, errs)) => { - Diagnostic::spanned(path_span, Level::Error, "could not parse Fluent resource") - .help("see additional errors emitted") - .emit(); - for ParserError { pos, slice: _, kind } in errs { - let mut err = kind.to_string(); - // Entirely unnecessary string modification so that the error message starts - // with a lowercase as rustc errors do. - err.replace_range( - 0..1, - &err.chars().next().unwrap().to_lowercase().to_string(), - ); + }; + let mut resource_contents = String::new(); + if let Err(e) = resource_file.read_to_string(&mut resource_contents) { + Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource") + .note(e.to_string()) + .emit(); + return failed(&crate_name); + } + + let resource = match FluentResource::try_new(resource_contents) { + Ok(resource) => resource, + Err((this, errs)) => { + Diagnostic::spanned(resource_span, Level::Error, "could not parse Fluent resource") + .help("see additional errors emitted") + .emit(); + for ParserError { pos, slice: _, kind } in errs { + let mut err = kind.to_string(); + // Entirely unnecessary string modification so that the error message starts + // with a lowercase as rustc errors do. + err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string()); - let line_starts: Vec<usize> = std::iter::once(0) - .chain( - this.source() - .char_indices() - .filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')), - ) - .collect(); - let line_start = line_starts - .iter() - .enumerate() - .map(|(line, idx)| (line + 1, idx)) - .filter(|(_, idx)| **idx <= pos.start) - .last() - .unwrap() - .0; + let line_starts: Vec<usize> = std::iter::once(0) + .chain( + this.source() + .char_indices() + .filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')), + ) + .collect(); + let line_start = line_starts + .iter() + .enumerate() + .map(|(line, idx)| (line + 1, idx)) + .filter(|(_, idx)| **idx <= pos.start) + .last() + .unwrap() + .0; - let snippet = Snippet { - title: Some(Annotation { - label: Some(&err), - id: None, + let snippet = Snippet { + title: Some(Annotation { + label: Some(&err), + id: None, + annotation_type: AnnotationType::Error, + }), + footer: vec![], + slices: vec![Slice { + source: this.source(), + line_start, + origin: Some(&relative_ftl_path), + fold: true, + annotations: vec![SourceAnnotation { + label: "", annotation_type: AnnotationType::Error, - }), - footer: vec![], - slices: vec![Slice { - source: this.source(), - line_start, - origin: Some(&relative_ftl_path), - fold: true, - annotations: vec![SourceAnnotation { - label: "", - annotation_type: AnnotationType::Error, - range: (pos.start, pos.end - 1), - }], + range: (pos.start, pos.end - 1), }], - opt: Default::default(), - }; - let dl = DisplayList::from(snippet); - eprintln!("{dl}\n"); - } - continue; + }], + opt: Default::default(), + }; + let dl = DisplayList::from(snippet); + eprintln!("{dl}\n"); } - }; - let mut constants = TokenStream::new(); - let mut messagerefs = Vec::new(); - for entry in resource.entries() { - let span = res.krate.span(); - if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = - entry - { - let _ = previous_defns.entry(name.to_string()).or_insert(path_span); + return failed(&crate_name); + } + }; - if name.contains('-') { - Diagnostic::spanned( - path_span, - Level::Error, - format!("name `{name}` contains a '-' character"), - ) - .help("replace any '-'s with '_'s") - .emit(); - } + let mut constants = TokenStream::new(); + let mut previous_defns = HashMap::new(); + let mut message_refs = Vec::new(); + for entry in resource.entries() { + if let Entry::Message(Message { id: Identifier { name }, attributes, value, .. }) = entry { + let _ = previous_defns.entry(name.to_string()).or_insert(resource_span); + if name.contains('-') { + Diagnostic::spanned( + resource_span, + Level::Error, + format!("name `{name}` contains a '-' character"), + ) + .help("replace any '-'s with '_'s") + .emit(); + } - if let Some(Pattern { elements }) = value { - for elt in elements { - if let PatternElement::Placeable { - expression: - Expression::Inline(InlineExpression::MessageReference { id, .. }), - } = elt - { - messagerefs.push((id.name, *name)); - } + if let Some(Pattern { elements }) = value { + for elt in elements { + if let PatternElement::Placeable { + expression: + Expression::Inline(InlineExpression::MessageReference { id, .. }), + } = elt + { + message_refs.push((id.name, *name)); } } + } - // Require that the message name starts with the crate name - // `hir_typeck_foo_bar` (in `hir_typeck.ftl`) - // `const_eval_baz` (in `const_eval.ftl`) - // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`) - // The last case we error about above, but we want to fall back gracefully - // so that only the error is being emitted and not also one about the macro - // failing. - let crate_prefix = format!("{}_", res.krate); + // `typeck_foo_bar` => `foo_bar` (in `typeck.ftl`) + // `const_eval_baz` => `baz` (in `const_eval.ftl`) + // `const-eval-hyphen-having` => `hyphen_having` (in `const_eval.ftl`) + // The last case we error about above, but we want to fall back gracefully + // so that only the error is being emitted and not also one about the macro + // failing. + let crate_prefix = format!("{crate_name}_"); - let snake_name = name.replace('-', "_"); - if !snake_name.starts_with(&crate_prefix) { + let snake_name = name.replace('-', "_"); + if !snake_name.starts_with(&crate_prefix) { + Diagnostic::spanned( + resource_span, + Level::Error, + format!("name `{name}` does not start with the crate name"), + ) + .help(format!( + "prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`" + )) + .emit(); + }; + let snake_name = Ident::new(&snake_name, resource_str.span()); + + if !previous_attrs.insert(snake_name.clone()) { + continue; + } + + let msg = format!("Constant referring to Fluent message `{name}` from `{crate_name}`"); + constants.extend(quote! { + #[doc = #msg] + pub const #snake_name: crate::DiagnosticMessage = + crate::DiagnosticMessage::FluentIdentifier( + std::borrow::Cow::Borrowed(#name), + None + ); + }); + + for Attribute { id: Identifier { name: attr_name }, .. } in attributes { + let snake_name = Ident::new( + &format!("{}{}", &crate_prefix, &attr_name.replace('-', "_")), + resource_str.span(), + ); + if !previous_attrs.insert(snake_name.clone()) { + continue; + } + + if attr_name.contains('-') { Diagnostic::spanned( - path_span, + resource_span, Level::Error, - format!("name `{name}` does not start with the crate name"), + format!("attribute `{attr_name}` contains a '-' character"), ) - .help(format!( - "prepend `{crate_prefix}` to the slug name: `{crate_prefix}{snake_name}`" - )) + .help("replace any '-'s with '_'s") .emit(); - }; - - let snake_name = Ident::new(&snake_name, span); + } + let msg = format!( + "Constant referring to Fluent message `{name}.{attr_name}` from `{crate_name}`" + ); constants.extend(quote! { - pub const #snake_name: crate::DiagnosticMessage = - crate::DiagnosticMessage::FluentIdentifier( - std::borrow::Cow::Borrowed(#name), - None + #[doc = #msg] + pub const #snake_name: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr( + std::borrow::Cow::Borrowed(#attr_name) ); }); - - for Attribute { id: Identifier { name: attr_name }, .. } in attributes { - let snake_name = Ident::new(&attr_name.replace('-', "_"), span); - if !previous_attrs.insert(snake_name.clone()) { - continue; - } - - if attr_name.contains('-') { - Diagnostic::spanned( - path_span, - Level::Error, - format!("attribute `{attr_name}` contains a '-' character"), - ) - .help("replace any '-'s with '_'s") - .emit(); - } - - constants.extend(quote! { - pub const #snake_name: crate::SubdiagnosticMessage = - crate::SubdiagnosticMessage::FluentAttr( - std::borrow::Cow::Borrowed(#attr_name) - ); - }); - } } } + } - for (mref, name) in messagerefs.into_iter() { - if !previous_defns.contains_key(mref) { - Diagnostic::spanned( - path_span, - Level::Error, - format!("referenced message `{mref}` does not exist (in message `{name}`)"), - ) - .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)")) - .emit(); - } + for (mref, name) in message_refs.into_iter() { + if !previous_defns.contains_key(mref) { + Diagnostic::spanned( + resource_span, + Level::Error, + format!("referenced message `{mref}` does not exist (in message `{name}`)"), + ) + .help(&format!("you may have meant to use a variable reference (`{{${mref}}}`)")) + .emit(); } + } - if let Err(errs) = bundle.add_resource(resource) { - for e in errs { - match e { - FluentError::Overriding { kind, id } => { - Diagnostic::spanned( - path_span, - Level::Error, - format!("overrides existing {kind}: `{id}`"), - ) - .span_help(previous_defns[&id], "previously defined in this resource") - .emit(); - } - FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(), + if let Err(errs) = bundle.add_resource(resource) { + for e in errs { + match e { + FluentError::Overriding { kind, id } => { + Diagnostic::spanned( + resource_span, + Level::Error, + format!("overrides existing {kind}: `{id}`"), + ) + .emit(); } + FluentError::ResolverError(_) | FluentError::ParserError(_) => unreachable!(), } } - - includes.extend(quote! { include_str!(#relative_ftl_path), }); - - generated.extend(constants); } quote! { + /// Raw content of Fluent resource for this crate, generated by `fluent_messages` macro, + /// imported by `rustc_driver` to include all crates' resources in one bundle. + pub static DEFAULT_LOCALE_RESOURCE: &'static str = include_str!(#relative_ftl_path); + #[allow(non_upper_case_globals)] #[doc(hidden)] - pub mod fluent_generated { - pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[ - #includes - ]; - - #generated + /// Auto-generated constants for type-checked references to Fluent messages. + pub(crate) mod fluent_generated { + #constants + /// Constants expected to exist by the diagnostic derive macros to use as default Fluent + /// identifiers for different subdiagnostic kinds. pub mod _subdiag { + /// Default for `#[help]` pub const help: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); + /// Default for `#[note]` pub const note: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); + /// Default for `#[warn]` pub const warn: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("warn")); + /// Default for `#[label]` pub const label: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); + /// Default for `#[suggestion]` pub const suggestion: crate::SubdiagnosticMessage = crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); } diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 906e4c0b0e1..90660fc1f93 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -512,7 +512,9 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> { let mut calls = TokenStream::new(); for (kind, slug) in kind_slugs { let message = format_ident!("__message"); - calls.extend(quote! { let #message = #f(#diag, rustc_errors::fluent::#slug.into()); }); + calls.extend( + quote! { let #message = #f(#diag, crate::fluent_generated::#slug.into()); }, + ); let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind); let call = match kind { diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index d2cb6ee9f71..737500cc257 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -61,9 +61,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream { /// For example, given the following invocation of the macro.. /// /// ```ignore (rust) -/// fluent_messages! { -/// typeck => "./typeck.ftl", -/// } +/// fluent_messages! { "./typeck.ftl" } /// ``` /// ..where `typeck.ftl` has the following contents.. /// @@ -77,9 +75,7 @@ pub fn newtype_index(input: TokenStream) -> TokenStream { /// will generate the following code: /// /// ```ignore (rust) -/// pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[ -/// include_str!("./typeck.ftl"), -/// ]; +/// pub static DEFAULT_LOCALE_RESOURCE: &'static [&'static str] = include_str!("./typeck.ftl"); /// /// mod fluent_generated { /// mod typeck { diff --git a/compiler/rustc_macros/src/type_foldable.rs b/compiler/rustc_macros/src/type_foldable.rs index 51729a377d9..388e254cd64 100644 --- a/compiler/rustc_macros/src/type_foldable.rs +++ b/compiler/rustc_macros/src/type_foldable.rs @@ -37,16 +37,16 @@ pub fn type_foldable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2:: bind.to_token_stream() } else { quote! { - ::rustc_middle::ty::fold::ir::TypeFoldable::try_fold_with(#bind, __folder)? + ::rustc_middle::ty::fold::TypeFoldable::try_fold_with(#bind, __folder)? } } }) }); s.bound_impl( - quote!(::rustc_middle::ty::fold::ir::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>), + quote!(::rustc_middle::ty::fold::TypeFoldable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { - fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<'tcx>>( + fn try_fold_with<__F: ::rustc_middle::ty::fold::FallibleTypeFolder<::rustc_middle::ty::TyCtxt<'tcx>>>( self, __folder: &mut __F ) -> Result<Self, __F::Error> { diff --git a/compiler/rustc_macros/src/type_visitable.rs b/compiler/rustc_macros/src/type_visitable.rs index 0a16a371fdc..f6f4c4779c3 100644 --- a/compiler/rustc_macros/src/type_visitable.rs +++ b/compiler/rustc_macros/src/type_visitable.rs @@ -30,15 +30,15 @@ pub fn type_visitable_derive(mut s: synstructure::Structure<'_>) -> proc_macro2: s.add_bounds(synstructure::AddBounds::Generics); let body_visit = s.each(|bind| { quote! { - ::rustc_middle::ty::visit::ir::TypeVisitable::visit_with(#bind, __visitor)?; + ::rustc_middle::ty::visit::TypeVisitable::visit_with(#bind, __visitor)?; } }); s.bind_with(|_| synstructure::BindStyle::Move); s.bound_impl( - quote!(::rustc_middle::ty::visit::ir::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>), + quote!(::rustc_middle::ty::visit::TypeVisitable<::rustc_middle::ty::TyCtxt<'tcx>>), quote! { - fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<'tcx>>( + fn visit_with<__V: ::rustc_middle::ty::visit::TypeVisitor<::rustc_middle::ty::TyCtxt<'tcx>>>( &self, __visitor: &mut __V ) -> ::std::ops::ControlFlow<__V::BreakTy> { diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_metadata/locales/en-US.ftl index 79b8b417257..79b8b417257 100644 --- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl +++ b/compiler/rustc_metadata/locales/en-US.ftl diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index c32686779fa..51b41b5f6a2 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -9,6 +9,7 @@ use rustc_session::config; use rustc_span::{sym, Span, Symbol}; use rustc_target::spec::{PanicStrategy, TargetTriple}; +use crate::fluent_generated as fluent; use crate::locator::CrateFlavor; #[derive(Diagnostic)] @@ -491,7 +492,7 @@ impl IntoDiagnostic<'_> for MultipleCandidates { self, handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(rustc_errors::fluent::metadata_multiple_candidates); + let mut diag = handler.struct_err(fluent::metadata_multiple_candidates); diag.set_arg("crate_name", self.crate_name); diag.set_arg("flavor", self.flavor); diag.code(error_code!(E0464)); @@ -590,7 +591,7 @@ impl IntoDiagnostic<'_> for InvalidMetadataFiles { self, handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(rustc_errors::fluent::metadata_invalid_meta_files); + let mut diag = handler.struct_err(fluent::metadata_invalid_meta_files); diag.set_arg("crate_name", self.crate_name); diag.set_arg("add_info", self.add_info); diag.code(error_code!(E0786)); @@ -619,7 +620,7 @@ impl IntoDiagnostic<'_> for CannotFindCrate { self, handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(rustc_errors::fluent::metadata_cannot_find_crate); + let mut diag = handler.struct_err(fluent::metadata_cannot_find_crate); diag.set_arg("crate_name", self.crate_name); diag.set_arg("current_crate", self.current_crate); diag.set_arg("add_info", self.add_info); @@ -630,32 +631,32 @@ impl IntoDiagnostic<'_> for CannotFindCrate { && self.locator_triple != TargetTriple::from_triple(config::host_triple()) { if self.missing_core { - diag.note(rustc_errors::fluent::metadata_target_not_installed); + diag.note(fluent::metadata_target_not_installed); } else { - diag.note(rustc_errors::fluent::metadata_target_no_std_support); + diag.note(fluent::metadata_target_no_std_support); } // NOTE: this suggests using rustup, even though the user may not have it installed. // That's because they could choose to install it; or this may give them a hint which // target they need to install from their distro. if self.missing_core { - diag.help(rustc_errors::fluent::metadata_consider_downloading_target); + diag.help(fluent::metadata_consider_downloading_target); } // Suggest using #![no_std]. #[no_core] is unstable and not really supported anyway. // NOTE: this is a dummy span if `extern crate std` was injected by the compiler. // If it's not a dummy, that means someone added `extern crate std` explicitly and // `#![no_std]` won't help. if !self.missing_core && self.span.is_dummy() { - diag.note(rustc_errors::fluent::metadata_std_required); + diag.note(fluent::metadata_std_required); } if self.is_nightly_build { - diag.help(rustc_errors::fluent::metadata_consider_building_std); + diag.help(fluent::metadata_consider_building_std); } } else if self.crate_name == self.profiler_runtime { - diag.note(rustc_errors::fluent::metadata_compiler_missing_profiler); + diag.note(fluent::metadata_compiler_missing_profiler); } else if self.crate_name.as_str().starts_with("rustc_") { - diag.help(rustc_errors::fluent::metadata_install_missing_components); + diag.help(fluent::metadata_install_missing_components); } - diag.span_label(self.span, rustc_errors::fluent::metadata_cant_find_crate); + diag.span_label(self.span, fluent::metadata_cant_find_crate); diag } } diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 1987f88e6b8..6f6d3731cea 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -30,6 +30,8 @@ extern crate rustc_data_structures; extern crate tracing; pub use rmeta::{provide, provide_extern}; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; mod dependency_format; mod foreign_modules; @@ -44,3 +46,5 @@ pub mod locator; pub use fs::{emit_wrapper_file, METADATA_FILENAME}; pub use native_libs::find_native_static_library; pub use rmeta::{encode_metadata, EncodedMetadata, METADATA_HEADER}; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index d823989bb02..d6f68b2e140 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -103,8 +103,13 @@ impl<'tcx> Collector<'tcx> { } // Process all of the #[link(..)]-style arguments - let sess = &self.tcx.sess; + let sess = self.tcx.sess; let features = self.tcx.features(); + + if !sess.opts.unstable_opts.link_directives { + return; + } + for m in self.tcx.hir().attrs(it.hir_id()).iter().filter(|a| a.has_name(sym::link)) { let Some(items) = m.meta_item_list() else { continue; @@ -502,7 +507,7 @@ impl<'tcx> Collector<'tcx> { .subst_identity() .fn_sig(self.tcx) .inputs() - .map_bound(|slice| self.tcx.intern_type_list(slice)), + .map_bound(|slice| self.tcx.mk_type_list(slice)), ); argument_types diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 3457e51f8e6..b1e59b0a470 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -910,7 +910,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { std::iter::once(self.get_variant(&kind, item_id, did)).collect() }; - tcx.alloc_adt_def(did, adt_kind, variants, repr) + tcx.mk_adt_def(did, adt_kind, variants, repr) } fn get_generics(self, item_id: DefIndex, sess: &Session) -> ty::Generics { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 60ea08a1647..83a0e833edc 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -254,6 +254,8 @@ provide! { tcx, def_id, other, cdata, .process_decoded(tcx, || panic!("{def_id:?} does not have trait_impl_trait_tys"))) } + associated_items_for_impl_trait_in_trait => { table_defaulted_array } + visibility => { cdata.get_visibility(def_id.index) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e941dd45688..f0dafe73c00 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1129,6 +1129,11 @@ fn should_encode_trait_impl_trait_tys(tcx: TyCtxt<'_>, def_id: DefId) -> bool { }) } +// Return `false` to avoid encoding impl trait in trait, while we don't use the query. +fn should_encode_fn_impl_trait_in_trait<'tcx>(_tcx: TyCtxt<'tcx>, _def_id: DefId) -> bool { + false +} + impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_attrs(&mut self, def_id: LocalDefId) { let tcx = self.tcx; @@ -1137,8 +1142,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { is_doc_hidden: false, }; let attr_iter = tcx - .hir() - .attrs(tcx.hir().local_def_id_to_hir_id(def_id)) + .opt_local_def_id_to_hir_id(def_id) + .map_or(Default::default(), |hir_id| tcx.hir().attrs(hir_id)) .iter() .filter(|attr| analyze_attr(attr, &mut state)); @@ -1211,6 +1216,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { { record!(self.tables.trait_impl_trait_tys[def_id] <- table); } + if should_encode_fn_impl_trait_in_trait(tcx, def_id) { + let table = tcx.associated_items_for_impl_trait_in_trait(def_id); + record_defaulted_array!(self.tables.associated_items_for_impl_trait_in_trait[def_id] <- table); + } } let inherent_impls = tcx.with_stable_hashing_context(|hcx| { diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 01691398ad0..a7ec2d790b7 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -354,6 +354,7 @@ define_tables! { explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Predicate<'static>, Span)>>, inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>, inherent_impls: Table<DefIndex, LazyArray<DefIndex>>, + associated_items_for_impl_trait_in_trait: Table<DefIndex, LazyArray<DefId>>, - optional: attributes: Table<DefIndex, LazyArray<ast::Attribute>>, diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 543bd56a20c..a2b78cc2985 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -34,7 +34,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" [features] diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_middle/locales/en-US.ftl index 4f4e5c6a2c9..4f4e5c6a2c9 100644 --- a/compiler/rustc_error_messages/locales/en-US/middle.ftl +++ b/compiler/rustc_middle/locales/en-US.ftl diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 2eafc356dc3..2df851a7857 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -849,6 +849,13 @@ impl<'hir> Map<'hir> { } } + pub fn get_fn_output(self, def_id: LocalDefId) -> Option<&'hir FnRetTy<'hir>> { + match self.tcx.hir_owner(OwnerId { def_id }) { + Some(Owner { node, .. }) => node.fn_decl().map(|fn_decl| &fn_decl.output), + _ => None, + } + } + pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> { match self.find(id) { Some(Node::Variant(variant)) => variant, diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index dc89f762b76..2e2ca6a2788 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -121,13 +121,13 @@ pub fn provide(providers: &mut Providers) { let node = owner.node(); Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }) }; - providers.local_def_id_to_hir_id = |tcx, id| { + providers.opt_local_def_id_to_hir_id = |tcx, id| { let owner = tcx.hir_crate(()).owners[id].map(|_| ()); - match owner { + Some(match owner { MaybeOwner::Owner(_) => HirId::make_owner(id), MaybeOwner::Phantom => bug!("No HirId for {:?}", id), MaybeOwner::NonOwner(hir_id) => hir_id, - } + }) }; providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id.def_id].map(|i| &i.nodes); providers.hir_owner_parent = |tcx, id| { diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index bb617e692cc..8712514a384 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -42,12 +42,12 @@ pub struct Canonical<'tcx, V> { pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; -impl<'tcx> ty::ir::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> { - fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>( +impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> { + fn try_fold_with<F: ty::FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v)) + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_canonical_var_infos(v)) } } @@ -342,7 +342,7 @@ impl<'tcx> CanonicalVarValues<'tcx> { infos: CanonicalVarInfos<'tcx>, ) -> CanonicalVarValues<'tcx> { CanonicalVarValues { - var_values: tcx.mk_substs(infos.iter().enumerate().map( + var_values: tcx.mk_substs_from_iter(infos.iter().enumerate().map( |(i, info)| -> ty::GenericArg<'tcx> { match info.kind { CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index e6cd38c0f15..c33b9d84eb0 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -73,6 +73,9 @@ extern crate tracing; #[macro_use] extern crate smallvec; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + #[cfg(test)] mod tests; @@ -105,3 +108,5 @@ pub mod util { // Allows macros to refer to this crate as `::rustc_middle` extern crate self as rustc_middle; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_middle/src/macros.rs b/compiler/rustc_middle/src/macros.rs index 57d66ac6a03..a8d71ce030c 100644 --- a/compiler/rustc_middle/src/macros.rs +++ b/compiler/rustc_middle/src/macros.rs @@ -69,8 +69,8 @@ macro_rules! CloneLiftImpls { macro_rules! TrivialTypeTraversalImpls { (for <$tcx:lifetime> { $($ty:ty,)+ }) => { $( - impl<$tcx> $crate::ty::fold::ir::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { - fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$tcx>>( + impl<$tcx> $crate::ty::fold::TypeFoldable<$crate::ty::TyCtxt<$tcx>> for $ty { + fn try_fold_with<F: $crate::ty::fold::FallibleTypeFolder<$crate::ty::TyCtxt<$tcx>>>( self, _: &mut F, ) -> ::std::result::Result<Self, F::Error> { @@ -78,7 +78,7 @@ macro_rules! TrivialTypeTraversalImpls { } #[inline] - fn fold_with<F: $crate::ty::fold::TypeFolder<$tcx>>( + fn fold_with<F: $crate::ty::fold::TypeFolder<$crate::ty::TyCtxt<$tcx>>>( self, _: &mut F, ) -> Self { @@ -86,9 +86,9 @@ macro_rules! TrivialTypeTraversalImpls { } } - impl<$tcx> $crate::ty::visit::ir::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty { + impl<$tcx> $crate::ty::visit::TypeVisitable<$crate::ty::TyCtxt<$tcx>> for $ty { #[inline] - fn visit_with<F: $crate::ty::visit::TypeVisitor<$tcx>>( + fn visit_with<F: $crate::ty::visit::TypeVisitor<$crate::ty::TyCtxt<$tcx>>>( &self, _: &mut F) -> ::std::ops::ControlFlow<F::BreakTy> diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 0836f236e24..354c84e2209 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -255,7 +255,7 @@ fn late_report_deprecation( let method_span = method_span.unwrap_or(span); tcx.struct_span_lint_hir(lint, hir_id, method_span, message, |diag| { if let hir::Node::Expr(_) = tcx.hir().get(hir_id) { - let kind = tcx.def_kind(def_id).descr(def_id); + let kind = tcx.def_descr(def_id); deprecation_suggestion(diag, kind, suggestion, method_span); } diag @@ -392,7 +392,7 @@ impl<'tcx> TyCtxt<'tcx> { let lint = deprecation_lint(is_in_effect); if self.lint_level_at_node(lint, id).0 != Level::Allow { let def_path = with_no_trimmed_paths!(self.def_path_str(def_id)); - let def_kind = self.def_kind(def_id).descr(def_id); + let def_kind = self.def_descr(def_id); late_report_deprecation( self, diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index b6c6e9d559c..856d821a5cf 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -2,7 +2,7 @@ use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId} use crate::mir; use crate::ty::subst::InternalSubsts; -use crate::ty::visit::TypeVisitable; +use crate::ty::visit::TypeVisitableExt; use crate::ty::{self, query::TyCtxtAt, query::TyCtxtEnsure, TyCtxt}; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 46184cddd51..0d78c6135b3 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -7,10 +7,10 @@ use crate::mir::interpret::{ }; use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{ir::TypeFoldable, FallibleTypeFolder}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer}; -use crate::ty::visit::{TypeVisitable, TypeVisitor}; -use crate::ty::{self, ir, DefIdTree, List, Ty, TyCtxt}; +use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; +use crate::ty::{self, DefIdTree, List, Ty, TyCtxt}; use crate::ty::{AdtDef, InstanceDef, ScalarInt, UserTypeAnnotationIndex}; use crate::ty::{GenericArg, InternalSubsts, SubstsRef}; @@ -1620,7 +1620,7 @@ impl<'tcx> Place<'tcx> { &v }; - Place { local: self.local, projection: tcx.intern_place_elems(new_projections) } + Place { local: self.local, projection: tcx.mk_place_elems(new_projections) } } } @@ -2530,13 +2530,14 @@ impl<'tcx> ConstantKind<'tcx> { { InternalSubsts::identity_for_item(tcx, parent_did.to_def_id()) } else { - tcx.intern_substs(&[]) + List::empty() }; debug!(?parent_substs); let did = def.did.to_def_id(); let child_substs = InternalSubsts::identity_for_item(tcx, did); - let substs = tcx.mk_substs(parent_substs.into_iter().chain(child_substs.into_iter())); + let substs = + tcx.mk_substs_from_iter(parent_substs.into_iter().chain(child_substs.into_iter())); debug!(?substs); let hir_id = tcx.hir().local_def_id_to_hir_id(def.did); @@ -2755,7 +2756,10 @@ impl UserTypeProjection { } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for UserTypeProjection { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(UserTypeProjection { base: self.base.try_fold_with(folder)?, projs: self.projs.try_fold_with(folder)?, @@ -2763,8 +2767,11 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for UserTypeProjection { } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for UserTypeProjection { - fn visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> ControlFlow<Vs::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for UserTypeProjection { + fn visit_with<Vs: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut Vs, + ) -> ControlFlow<Vs::BreakTy> { self.base.visit_with(visitor) // Note: there's nothing in `self.proj` to visit. } diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index aa9f170477b..0aa2c500f51 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -194,14 +194,16 @@ impl<'tcx> Rvalue<'tcx> { let lhs_ty = lhs.ty(local_decls, tcx); let rhs_ty = rhs.ty(local_decls, tcx); let ty = op.ty(tcx, lhs_ty, rhs_ty); - tcx.intern_tup(&[ty, tcx.types.bool]) + tcx.mk_tup(&[ty, tcx.types.bool]) } Rvalue::UnaryOp(UnOp::Not | UnOp::Neg, ref operand) => operand.ty(local_decls, tcx), Rvalue::Discriminant(ref place) => place.ty(local_decls, tcx).ty.discriminant_ty(tcx), Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => tcx.types.usize, Rvalue::Aggregate(ref ak, ref ops) => match **ak { AggregateKind::Array(ty) => tcx.mk_array(ty, ops.len() as u64), - AggregateKind::Tuple => tcx.mk_tup(ops.iter().map(|op| op.ty(local_decls, tcx))), + AggregateKind::Tuple => { + tcx.mk_tup_from_iter(ops.iter().map(|op| op.ty(local_decls, tcx))) + } AggregateKind::Adt(did, _, substs, _, _) => tcx.type_of(did).subst(tcx, substs), AggregateKind::Closure(did, substs) => tcx.mk_closure(did, substs), AggregateKind::Generator(did, substs, movability) => { diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index ce06a0ef060..9881583214e 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -31,19 +31,28 @@ TrivialTypeTraversalImpls! { } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [InlineAsmTemplatePiece] { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx [Span] { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<PlaceElem<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_place_elems(v)) + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_place_elems(v)) } } diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 443c1b2d261..5c056b29975 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -1045,7 +1045,7 @@ macro_rules! visit_place_fns { self.visit_local(&mut place.local, context, location); if let Some(new_projection) = self.process_projection(&place.projection, location) { - place.projection = self.tcx().intern_place_elems(&new_projection); + place.projection = self.tcx().mk_place_elems(&new_projection); } } @@ -1214,7 +1214,7 @@ impl<'tcx> MirVisitable<'tcx> for Option<Terminator<'tcx>> { /// Extra information passed to `visit_ty` and friends to give context /// about where the type etc appears. -#[derive(Debug)] +#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)] pub enum TyContext { LocalDecl { /// The index of the local variable we are visiting. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 3b559c7f8ad..6a34e5ede19 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -85,11 +85,10 @@ rustc_queries! { desc { |tcx| "getting HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } } - /// Gives access to the HIR ID for the given `LocalDefId` owner `key`. + /// Gives access to the HIR ID for the given `LocalDefId` owner `key` if any. /// - /// This can be conveniently accessed by methods on `tcx.hir()`. - /// Avoid calling this query directly. - query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId { + /// Definitions that were generated with no HIR, would be feeded to return `None`. + query opt_local_def_id_to_hir_id(key: LocalDefId) -> Option<hir::HirId>{ desc { |tcx| "getting HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } } @@ -767,6 +766,26 @@ rustc_queries! { desc { |tcx| "comparing impl items against trait for `{}`", tcx.def_path_str(impl_id) } } + /// Given `fn_def_id` of a trait or of an impl that implements a given trait: + /// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns + /// the associated items that correspond to each impl trait in return position for that trait. + /// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it + /// creates and returns the associated items that correspond to each impl trait in return position + /// of the implemented trait. + query associated_items_for_impl_trait_in_trait(fn_def_id: DefId) -> &'tcx [DefId] { + desc { |tcx| "creating associated items for impl trait in trait returned by `{}`", tcx.def_path_str(fn_def_id) } + cache_on_disk_if { fn_def_id.is_local() } + separate_provide_extern + } + + /// Given an impl trait in trait `opaque_ty_def_id`, create and return the corresponding + /// associated item. + query associated_item_for_impl_trait_in_trait(opaque_ty_def_id: LocalDefId) -> LocalDefId { + desc { |tcx| "creates the associated item corresponding to the opaque type `{}`", tcx.def_path_str(opaque_ty_def_id.to_def_id()) } + cache_on_disk_if { true } + separate_provide_extern + } + /// Given an `impl_id`, return the trait it implements. /// Return `None` if this is an inherent impl. query impl_trait_ref(impl_id: DefId) -> Option<ty::EarlyBinder<ty::TraitRef<'tcx>>> { diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index 615154a55e5..c4f8718754f 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -14,7 +14,7 @@ use rustc_span::source_map::Span; pub mod type_op { use crate::ty::fold::TypeFoldable; - use crate::ty::{Predicate, Ty, UserType}; + use crate::ty::{Predicate, Ty, TyCtxt, UserType}; use std::fmt; #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable, Lift)] @@ -64,7 +64,7 @@ pub mod type_op { impl<'tcx, T> Normalize<T> where - T: fmt::Debug + TypeFoldable<'tcx>, + T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>, { pub fn new(value: T) -> Self { Self { value } diff --git a/compiler/rustc_middle/src/traits/solve.rs b/compiler/rustc_middle/src/traits/solve.rs index bddf84880d2..c5bf9717f03 100644 --- a/compiler/rustc_middle/src/traits/solve.rs +++ b/compiler/rustc_middle/src/traits/solve.rs @@ -3,8 +3,7 @@ use std::ops::ControlFlow; use rustc_data_structures::intern::Interned; use crate::ty::{ - ir::{self, TypeFoldable, TypeVisitable}, - FallibleTypeFolder, Ty, TyCtxt, TypeFolder, TypeVisitor, + FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor, }; #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)] @@ -27,21 +26,22 @@ pub struct ExternalConstraintsData<'tcx> { } impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - Ok(ir::FallibleTypeFolder::interner(folder).intern_external_constraints( - ExternalConstraintsData { - regions: (), - opaque_types: self - .opaque_types - .iter() - .map(|opaque| opaque.try_fold_with(folder)) - .collect::<Result<_, F::Error>>()?, - }, - )) + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + Ok(FallibleTypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { + regions: (), + opaque_types: self + .opaque_types + .iter() + .map(|opaque| opaque.try_fold_with(folder)) + .collect::<Result<_, F::Error>>()?, + })) } - fn fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self { - ir::TypeFolder::interner(folder).intern_external_constraints(ExternalConstraintsData { + fn fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self { + TypeFolder::interner(folder).mk_external_constraints(ExternalConstraintsData { regions: (), opaque_types: self.opaque_types.iter().map(|opaque| opaque.fold_with(folder)).collect(), }) @@ -49,7 +49,7 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { } impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ExternalConstraints<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>( + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( &self, visitor: &mut V, ) -> std::ops::ControlFlow<V::BreakTy> { diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 4019cf8ceee..c016f722750 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -1,6 +1,6 @@ use crate::error::StrictCoherenceNeedsNegativeCoherence; use crate::ty::fast_reject::SimplifiedType; -use crate::ty::visit::TypeVisitable; +use crate::ty::visit::TypeVisitableExt; use crate::ty::{self, TyCtxt}; use rustc_data_structures::fx::FxIndexMap; use rustc_errors::ErrorGuaranteed; diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index b9c5a4e0d0d..df9aa765dc1 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -89,9 +89,7 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { Err(TypeError::Sorts(relate::expected_found(self, a, b))) } - (&ty::Error(guar), _) | (_, &ty::Error(guar)) => { - Ok(self.tcx().ty_error_with_guaranteed(guar)) - } + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(self.tcx().ty_error(guar)), _ => relate::super_relate_tys(self, a, b), } diff --git a/compiler/rustc_middle/src/ty/abstract_const.rs b/compiler/rustc_middle/src/ty/abstract_const.rs index b7f0a0be75e..f889ce82706 100644 --- a/compiler/rustc_middle/src/ty/abstract_const.rs +++ b/compiler/rustc_middle/src/ty/abstract_const.rs @@ -1,6 +1,7 @@ //! A subset of a mir body used for const evaluatability checking. use crate::ty::{ - self, ir::TypeFolder, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + self, Const, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeVisitableExt, }; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; @@ -47,7 +48,7 @@ impl<'tcx> TyCtxt<'tcx> { Ok(ac?.map(|ac| EarlyBinder(ac))) } - pub fn expand_abstract_consts<T: TypeFoldable<'tcx>>(self, ac: T) -> T { + pub fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, ac: T) -> T { struct Expander<'tcx> { tcx: TyCtxt<'tcx>, } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index f127b6275a2..ec21030b302 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -54,7 +54,7 @@ bitflags! { /// The definition of a user-defined type, e.g., a `struct`, `enum`, or `union`. /// -/// These are all interned (by `alloc_adt_def`) into the global arena. +/// These are all interned (by `mk_adt_def`) into the global arena. /// /// The initialism *ADT* stands for an [*algebraic data type (ADT)*][adt]. /// This is slightly wrong because `union`s are not ADTs. diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b9a1e23879c..3ce80e06ad9 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -207,7 +207,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Ty<'tcx> { }) } else { let tcx = decoder.interner(); - tcx.mk_ty(rustc_type_ir::TyKind::decode(decoder)) + tcx.mk_ty_from_kind(rustc_type_ir::TyKind::decode(decoder)) } } } @@ -244,7 +244,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for SubstsRef<'tcx> { fn decode(decoder: &mut D) -> Self { let len = decoder.read_usize(); let tcx = decoder.interner(); - tcx.mk_substs( + tcx.mk_substs_from_iter( (0..len).map::<ty::subst::GenericArg<'tcx>, _>(|_| Decodable::decode(decoder)), ) } @@ -254,7 +254,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for mir::Place<'tcx> { fn decode(decoder: &mut D) -> Self { let local: mir::Local = Decodable::decode(decoder); let len = decoder.read_usize(); - let projection = decoder.interner().mk_place_elems( + let projection = decoder.interner().mk_place_elems_from_iter( (0..len).map::<mir::PlaceElem<'tcx>, _>(|_| Decodable::decode(decoder)), ); mir::Place { local, projection } @@ -263,16 +263,16 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for mir::Place<'tcx> { impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::Region<'tcx> { fn decode(decoder: &mut D) -> Self { - decoder.interner().mk_region(Decodable::decode(decoder)) + decoder.interner().mk_region_from_kind(Decodable::decode(decoder)) } } impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for CanonicalVarInfos<'tcx> { fn decode(decoder: &mut D) -> Self { let len = decoder.read_usize(); - let interned: Vec<CanonicalVarInfo<'tcx>> = - (0..len).map(|_| Decodable::decode(decoder)).collect(); - decoder.interner().intern_canonical_var_infos(interned.as_slice()) + decoder.interner().mk_canonical_var_infos_from_iter( + (0..len).map::<CanonicalVarInfo<'tcx>, _>(|_| Decodable::decode(decoder)), + ) } } @@ -310,7 +310,9 @@ macro_rules! impl_decodable_via_ref { impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Ty<'tcx>> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); - decoder.interner().mk_type_list((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder))) + decoder + .interner() + .mk_type_list_from_iter((0..len).map::<Ty<'tcx>, _>(|_| Decodable::decode(decoder))) } } @@ -319,7 +321,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); - decoder.interner().mk_poly_existential_predicates( + decoder.interner().mk_poly_existential_predicates_from_iter( (0..len).map::<ty::Binder<'tcx, _>, _>(|_| Decodable::decode(decoder)), ) } @@ -342,13 +344,13 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [ty::ValTre impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ConstAllocation<'tcx> { fn decode(decoder: &mut D) -> Self { - decoder.interner().intern_const_alloc(Decodable::decode(decoder)) + decoder.interner().mk_const_alloc(Decodable::decode(decoder)) } } impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for AdtDef<'tcx> { fn decode(decoder: &mut D) -> Self { - decoder.interner().intern_adt_def(Decodable::decode(decoder)) + decoder.interner().mk_adt_def_from_data(Decodable::decode(decoder)) } } @@ -375,7 +377,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); - decoder.interner().mk_bound_variable_kinds( + decoder.interner().mk_bound_variable_kinds_from_iter( (0..len).map::<ty::BoundVariableKind, _>(|_| Decodable::decode(decoder)), ) } @@ -384,18 +386,18 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Const<'tcx>> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); - decoder - .interner() - .mk_const_list((0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder))) + decoder.interner().mk_const_list_from_iter( + (0..len).map::<ty::Const<'tcx>, _>(|_| Decodable::decode(decoder)), + ) } } impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<ty::Predicate<'tcx>> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); - let predicates: Vec<_> = - (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)).collect(); - decoder.interner().intern_predicates(&predicates) + decoder.interner().mk_predicates_from_iter( + (0..len).map::<ty::Predicate<'tcx>, _>(|_| Decodable::decode(decoder)), + ) } } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index 52f4414e37b..560caa041a7 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -4,7 +4,7 @@ use crate::mir::interpret::{AllocId, ConstValue, Scalar}; use crate::ty::abstract_const::CastKind; use crate::ty::subst::{InternalSubsts, SubstsRef}; use crate::ty::ParamEnv; -use crate::ty::{self, List, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, List, Ty, TyCtxt, TypeVisitableExt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index cf4836ded47..433c9ab9aa2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -6,7 +6,7 @@ pub mod tls; use crate::arena::Arena; use crate::dep_graph::{DepGraph, DepKindStruct}; -use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; +use crate::infer::canonical::CanonicalVarInfo; use crate::lint::struct_lint_level; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; @@ -177,7 +177,7 @@ impl<'tcx> CtxtInterners<'tcx> { } } - /// Interns a type. + /// Interns a type. (Use `mk_*` functions instead, where possible.) #[allow(rustc::usage_of_ty_tykind)] #[inline(never)] fn intern_ty(&self, kind: TyKind<'tcx>, sess: &Session, untracked: &Untracked) -> Ty<'tcx> { @@ -217,6 +217,7 @@ impl<'tcx> CtxtInterners<'tcx> { } } + /// Interns a predicate. (Use `mk_predicate` instead, where possible.) #[inline(never)] fn intern_predicate( &self, @@ -615,21 +616,21 @@ impl<'tcx> TyCtxt<'tcx> { self.arena.alloc(Steal::new(promoted)) } - pub fn alloc_adt_def( + pub fn mk_adt_def( self, did: DefId, kind: AdtKind, variants: IndexVec<VariantIdx, ty::VariantDef>, repr: ReprOptions, ) -> ty::AdtDef<'tcx> { - self.intern_adt_def(ty::AdtDefData::new(self, did, kind, variants, repr)) + self.mk_adt_def_from_data(ty::AdtDefData::new(self, did, kind, variants, repr)) } /// Allocates a read-only byte or string literal for `mir::interpret`. pub fn allocate_bytes(self, bytes: &[u8]) -> interpret::AllocId { // Create an allocation that just contains these bytes. let alloc = interpret::Allocation::from_bytes_byte_aligned_immutable(bytes); - let alloc = self.intern_const_alloc(alloc); + let alloc = self.mk_const_alloc(alloc); self.create_memory_alloc(alloc) } @@ -718,13 +719,13 @@ impl<'tcx> TyCtxt<'tcx> { /// Constructs a `TyKind::Error` type with current `ErrorGuaranteed` #[track_caller] - pub fn ty_error_with_guaranteed(self, reported: ErrorGuaranteed) -> Ty<'tcx> { - self.mk_ty(Error(reported)) + pub fn ty_error(self, reported: ErrorGuaranteed) -> Ty<'tcx> { + self.mk_ty_from_kind(Error(reported)) } /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] - pub fn ty_error(self) -> Ty<'tcx> { + pub fn ty_error_misc(self) -> Ty<'tcx> { self.ty_error_with_message(DUMMY_SP, "TyKind::Error constructed but no error reported") } @@ -733,7 +734,7 @@ impl<'tcx> TyCtxt<'tcx> { #[track_caller] pub fn ty_error_with_message<S: Into<MultiSpan>>(self, span: S, msg: &str) -> Ty<'tcx> { let reported = self.sess.delay_span_bug(span, msg); - self.mk_ty(Error(reported)) + self.mk_ty_from_kind(Error(reported)) } /// Constructs a `RegionKind::ReError` lifetime. @@ -1011,6 +1012,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Note that this is *untracked* and should only be used within the query /// system if the result is otherwise tracked through queries + #[inline] pub fn cstore_untracked(self) -> MappedReadGuard<'tcx, CrateStoreDyn> { ReadGuard::map(self.untracked.cstore.read(), |c| &**c) } @@ -1030,7 +1032,7 @@ impl<'tcx> TyCtxt<'tcx> { /// system if the result is otherwise tracked through queries #[inline] pub fn source_span_untracked(self, def_id: LocalDefId) -> Span { - self.untracked.source_span.read().get(def_id).copied().unwrap_or(DUMMY_SP) + self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) } #[inline(always)] @@ -1194,19 +1196,14 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_imm_ref( self.lifetimes.re_static, self.type_of(self.require_lang_item(LangItem::PanicLocation, None)) - .subst(self, self.intern_substs(&[self.lifetimes.re_static.into()])), + .subst(self, self.mk_substs(&[self.lifetimes.re_static.into()])), ) } /// Returns a displayable description and article for the given `def_id` (e.g. `("a", "struct")`). pub fn article_and_description(self, def_id: DefId) -> (&'static str, &'static str) { - match self.def_kind(def_id) { - DefKind::Generator => match self.generator_kind(def_id).unwrap() { - rustc_hir::GeneratorKind::Async(..) => ("an", "async closure"), - rustc_hir::GeneratorKind::Gen => ("a", "generator"), - }, - def_kind => (def_kind.article(), def_kind.descr(def_id)), - } + let kind = self.def_kind(def_id); + (self.def_kind_descr_article(kind, def_id), self.def_kind_descr(kind, def_id)) } pub fn type_length_limit(self) -> Limit { @@ -1281,7 +1278,7 @@ macro_rules! nop_lift { // Can't use the macros as we have reuse the `substs` here. // -// See `intern_type_list` for more info. +// See `mk_type_list` for more info. impl<'a, 'tcx> Lift<'tcx> for &'a List<Ty<'a>> { type Lifted = &'tcx List<Ty<'tcx>>; fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { @@ -1522,7 +1519,7 @@ impl<'tcx, T: Hash> Hash for InternedInSet<'tcx, List<T>> { } macro_rules! direct_interners { - ($($name:ident: $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => { + ($($name:ident: $vis:vis $method:ident($ty:ty): $ret_ctor:ident -> $ret_ty:ty,)+) => { $(impl<'tcx> Borrow<$ty> for InternedInSet<'tcx, $ty> { fn borrow<'a>(&'a self) -> &'a $ty { &self.0 @@ -1548,7 +1545,7 @@ macro_rules! direct_interners { } impl<'tcx> TyCtxt<'tcx> { - pub fn $method(self, v: $ty) -> $ret_ty { + $vis fn $method(self, v: $ty) -> $ret_ty { $ret_ctor(Interned::new_unchecked(self.interners.$name.intern(v, |v| { InternedInSet(self.interners.arena.alloc(v)) }).0)) @@ -1557,37 +1554,47 @@ macro_rules! direct_interners { } } +// Functions with a `mk_` prefix are intended for use outside this file and +// crate. Functions with an `intern_` prefix are intended for use within this +// file only, and have a corresponding `mk_` function. direct_interners! { region: intern_region(RegionKind<'tcx>): Region -> Region<'tcx>, - const_: mk_const_internal(ConstData<'tcx>): Const -> Const<'tcx>, - const_allocation: intern_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, - layout: intern_layout(LayoutS): Layout -> Layout<'tcx>, - adt_def: intern_adt_def(AdtDefData): AdtDef -> AdtDef<'tcx>, - external_constraints: intern_external_constraints(ExternalConstraintsData<'tcx>): ExternalConstraints -> ExternalConstraints<'tcx>, + const_: intern_const(ConstData<'tcx>): Const -> Const<'tcx>, + const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>, + layout: pub mk_layout(LayoutS): Layout -> Layout<'tcx>, + adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>, + external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>): + ExternalConstraints -> ExternalConstraints<'tcx>, } macro_rules! slice_interners { - ($($field:ident: $method:ident($ty:ty)),+ $(,)?) => ( + ($($field:ident: $vis:vis $method:ident($ty:ty)),+ $(,)?) => ( impl<'tcx> TyCtxt<'tcx> { - $(pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { - self.interners.$field.intern_ref(v, || { - InternedInSet(List::from_arena(&*self.arena, v)) - }).0 + $($vis fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { + if v.is_empty() { + List::empty() + } else { + self.interners.$field.intern_ref(v, || { + InternedInSet(List::from_arena(&*self.arena, v)) + }).0 + } })+ } ); } +// These functions intern slices. They all have a corresponding +// `mk_foo_from_iter` function that interns an iterator. The slice version +// should be used when possible, because it's faster. slice_interners!( - const_lists: _intern_const_list(Const<'tcx>), - substs: _intern_substs(GenericArg<'tcx>), - canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), - poly_existential_predicates: - _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>), - predicates: _intern_predicates(Predicate<'tcx>), - projs: _intern_projs(ProjectionKind), - place_elems: _intern_place_elems(PlaceElem<'tcx>), - bound_variable_kinds: _intern_bound_variable_kinds(ty::BoundVariableKind), + const_lists: pub mk_const_list(Const<'tcx>), + substs: pub mk_substs(GenericArg<'tcx>), + canonical_var_infos: pub mk_canonical_var_infos(CanonicalVarInfo<'tcx>), + poly_existential_predicates: intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>), + predicates: intern_predicates(Predicate<'tcx>), + projs: pub mk_projs(ProjectionKind), + place_elems: pub mk_place_elems(PlaceElem<'tcx>), + bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind), ); impl<'tcx> TyCtxt<'tcx> { @@ -1675,7 +1682,7 @@ impl<'tcx> TyCtxt<'tcx> { // Avoid this in favour of more specific `mk_*` methods, where possible. #[allow(rustc::usage_of_ty_tykind)] #[inline] - pub fn mk_ty(self, st: TyKind<'tcx>) -> Ty<'tcx> { + pub fn mk_ty_from_kind(self, st: TyKind<'tcx>) -> Ty<'tcx> { self.interners.intern_ty( st, self.sess, @@ -1740,12 +1747,12 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_adt(self, def: AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> Ty<'tcx> { // Take a copy of substs so that we own the vectors inside. - self.mk_ty(Adt(def, substs)) + self.mk_ty_from_kind(Adt(def, substs)) } #[inline] pub fn mk_foreign(self, def_id: DefId) -> Ty<'tcx> { - self.mk_ty(Foreign(def_id)) + self.mk_ty_from_kind(Foreign(def_id)) } fn mk_generic_adt(self, wrapper_def_id: DefId, ty_param: Ty<'tcx>) -> Ty<'tcx> { @@ -1762,7 +1769,7 @@ impl<'tcx> TyCtxt<'tcx> { } } }); - self.mk_ty(Adt(adt_def, substs)) + self.mk_ty_from_kind(Adt(adt_def, substs)) } #[inline] @@ -1791,12 +1798,12 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_ptr(self, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { - self.mk_ty(RawPtr(tm)) + self.mk_ty_from_kind(RawPtr(tm)) } #[inline] pub fn mk_ref(self, r: Region<'tcx>, tm: TypeAndMut<'tcx>) -> Ty<'tcx> { - self.mk_ty(Ref(r, tm.ty, tm.mutbl)) + self.mk_ty_from_kind(Ref(r, tm.ty, tm.mutbl)) } #[inline] @@ -1821,30 +1828,34 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> { - self.mk_ty(Array(ty, ty::Const::from_target_usize(self, n))) + self.mk_ty_from_kind(Array(ty, ty::Const::from_target_usize(self, n))) } #[inline] pub fn mk_array_with_const_len(self, ty: Ty<'tcx>, ct: Const<'tcx>) -> Ty<'tcx> { - self.mk_ty(Array(ty, ct)) + self.mk_ty_from_kind(Array(ty, ct)) } #[inline] pub fn mk_slice(self, ty: Ty<'tcx>) -> Ty<'tcx> { - self.mk_ty(Slice(ty)) + self.mk_ty_from_kind(Slice(ty)) } #[inline] - pub fn intern_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { - if ts.is_empty() { self.types.unit } else { self.mk_ty(Tuple(self.intern_type_list(&ts))) } + pub fn mk_tup(self, ts: &[Ty<'tcx>]) -> Ty<'tcx> { + if ts.is_empty() { + self.types.unit + } else { + self.mk_ty_from_kind(Tuple(self.mk_type_list(&ts))) + } } - pub fn mk_tup<I, T>(self, iter: I) -> T::Output + pub fn mk_tup_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<Ty<'tcx>, Ty<'tcx>>, { - T::collect_and_apply(iter, |ts| self.intern_tup(ts)) + T::collect_and_apply(iter, |ts| self.mk_tup(ts)) } #[inline] @@ -1861,17 +1872,17 @@ impl<'tcx> TyCtxt<'tcx> { pub fn mk_fn_def( self, def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx> { - let substs = self.check_substs(def_id, substs); - self.mk_ty(FnDef(def_id, substs)) + let substs = self.check_and_mk_substs(def_id, substs); + self.mk_ty_from_kind(FnDef(def_id, substs)) } #[inline(always)] - fn check_substs( + fn check_and_mk_substs( self, _def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> SubstsRef<'tcx> { let substs = substs.into_iter().map(Into::into); #[cfg(debug_assertions)] @@ -1884,12 +1895,12 @@ impl<'tcx> TyCtxt<'tcx> { substs.collect::<Vec<_>>(), ); } - self.mk_substs(substs) + self.mk_substs_from_iter(substs) } #[inline] pub fn mk_fn_ptr(self, fty: PolyFnSig<'tcx>) -> Ty<'tcx> { - self.mk_ty(FnPtr(fty)) + self.mk_ty_from_kind(FnPtr(fty)) } #[inline] @@ -1899,21 +1910,21 @@ impl<'tcx> TyCtxt<'tcx> { reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx> { - self.mk_ty(Dynamic(obj, reg, repr)) + self.mk_ty_from_kind(Dynamic(obj, reg, repr)) } #[inline] pub fn mk_projection( self, item_def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> Ty<'tcx> { self.mk_alias(ty::Projection, self.mk_alias_ty(item_def_id, substs)) } #[inline] pub fn mk_closure(self, closure_id: DefId, closure_substs: SubstsRef<'tcx>) -> Ty<'tcx> { - self.mk_ty(Closure(closure_id, closure_substs)) + self.mk_ty_from_kind(Closure(closure_id, closure_substs)) } #[inline] @@ -1923,47 +1934,51 @@ impl<'tcx> TyCtxt<'tcx> { generator_substs: SubstsRef<'tcx>, movability: hir::Movability, ) -> Ty<'tcx> { - self.mk_ty(Generator(id, generator_substs, movability)) + self.mk_ty_from_kind(Generator(id, generator_substs, movability)) } #[inline] pub fn mk_generator_witness(self, types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>) -> Ty<'tcx> { - self.mk_ty(GeneratorWitness(types)) + self.mk_ty_from_kind(GeneratorWitness(types)) } /// Creates a `&mut Context<'_>` [`Ty`] with erased lifetimes. pub fn mk_task_context(self) -> Ty<'tcx> { let context_did = self.require_lang_item(LangItem::Context, None); let context_adt_ref = self.adt_def(context_did); - let context_substs = self.intern_substs(&[self.lifetimes.re_erased.into()]); + let context_substs = self.mk_substs(&[self.lifetimes.re_erased.into()]); let context_ty = self.mk_adt(context_adt_ref, context_substs); self.mk_mut_ref(self.lifetimes.re_erased, context_ty) } #[inline] pub fn mk_generator_witness_mir(self, id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { - self.mk_ty(GeneratorWitnessMIR(id, substs)) + self.mk_ty_from_kind(GeneratorWitnessMIR(id, substs)) } #[inline] pub fn mk_const(self, kind: impl Into<ty::ConstKind<'tcx>>, ty: Ty<'tcx>) -> Const<'tcx> { - self.mk_const_internal(ty::ConstData { kind: kind.into(), ty }) + self.intern_const(ty::ConstData { kind: kind.into(), ty }) } #[inline] pub fn mk_ty_var(self, v: TyVid) -> Ty<'tcx> { // Use a pre-interned one when possible. - self.types.ty_vars.get(v.as_usize()).copied().unwrap_or_else(|| self.mk_ty(Infer(TyVar(v)))) + self.types + .ty_vars + .get(v.as_usize()) + .copied() + .unwrap_or_else(|| self.mk_ty_from_kind(Infer(TyVar(v)))) } #[inline] pub fn mk_int_var(self, v: IntVid) -> Ty<'tcx> { - self.mk_ty(Infer(IntVar(v))) + self.mk_ty_from_kind(Infer(IntVar(v))) } #[inline] pub fn mk_float_var(self, v: FloatVid) -> Ty<'tcx> { - self.mk_ty(Infer(FloatVar(v))) + self.mk_ty_from_kind(Infer(FloatVar(v))) } #[inline] @@ -1973,7 +1988,7 @@ impl<'tcx> TyCtxt<'tcx> { .fresh_tys .get(n as usize) .copied() - .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshTy(n)))) + .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshTy(n)))) } #[inline] @@ -1983,7 +1998,7 @@ impl<'tcx> TyCtxt<'tcx> { .fresh_int_tys .get(n as usize) .copied() - .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshIntTy(n)))) + .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshIntTy(n)))) } #[inline] @@ -1993,12 +2008,12 @@ impl<'tcx> TyCtxt<'tcx> { .fresh_float_tys .get(n as usize) .copied() - .unwrap_or_else(|| self.mk_ty(Infer(ty::FreshFloatTy(n)))) + .unwrap_or_else(|| self.mk_ty_from_kind(Infer(ty::FreshFloatTy(n)))) } #[inline] pub fn mk_ty_param(self, index: u32, name: Symbol) -> Ty<'tcx> { - self.mk_ty(Param(ParamTy { index, name })) + self.mk_ty_from_kind(Param(ParamTy { index, name })) } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { @@ -2020,17 +2035,17 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_bound(self, index: ty::DebruijnIndex, bound_ty: ty::BoundTy) -> Ty<'tcx> { - self.mk_ty(Bound(index, bound_ty)) + self.mk_ty_from_kind(Bound(index, bound_ty)) } #[inline] pub fn mk_placeholder(self, placeholder: ty::PlaceholderType) -> Ty<'tcx> { - self.mk_ty(Placeholder(placeholder)) + self.mk_ty_from_kind(Placeholder(placeholder)) } #[inline] pub fn mk_alias(self, kind: ty::AliasKind, alias_ty: ty::AliasTy<'tcx>) -> Ty<'tcx> { - self.mk_ty(Alias(kind, alias_ty)) + self.mk_ty_from_kind(Alias(kind, alias_ty)) } #[inline] @@ -2083,7 +2098,7 @@ impl<'tcx> TyCtxt<'tcx> { // Avoid this in favour of more specific `mk_re_*` methods, where possible, // to avoid the cost of the `match`. - pub fn mk_region(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> { + pub fn mk_region_from_kind(self, kind: ty::RegionKind<'tcx>) -> Region<'tcx> { match kind { ty::ReEarlyBound(region) => self.mk_re_early_bound(region), ty::ReLateBound(debruijn, region) => self.mk_re_late_bound(debruijn, region), @@ -2137,10 +2152,10 @@ impl<'tcx> TyCtxt<'tcx> { let mut projection = place.projection.to_vec(); projection.push(elem); - Place { local: place.local, projection: self.intern_place_elems(&projection) } + Place { local: place.local, projection: self.mk_place_elems(&projection) } } - pub fn intern_poly_existential_predicates( + pub fn mk_poly_existential_predicates( self, eps: &[PolyExistentialPredicate<'tcx>], ) -> &'tcx List<PolyExistentialPredicate<'tcx>> { @@ -2150,80 +2165,40 @@ impl<'tcx> TyCtxt<'tcx> { .all(|[a, b]| a.skip_binder().stable_cmp(self, &b.skip_binder()) != Ordering::Greater) ); - self._intern_poly_existential_predicates(eps) + self.intern_poly_existential_predicates(eps) } - pub fn intern_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> { + pub fn mk_predicates(self, preds: &[Predicate<'tcx>]) -> &'tcx List<Predicate<'tcx>> { // FIXME consider asking the input slice to be sorted to avoid // re-interning permutations, in which case that would be asserted // here. - if preds.is_empty() { - // The macro-generated method below asserts we don't intern an empty slice. - List::empty() - } else { - self._intern_predicates(preds) - } + self.intern_predicates(preds) } - pub fn mk_const_list<I, T>(self, iter: I) -> T::Output + pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<ty::Const<'tcx>, &'tcx List<ty::Const<'tcx>>>, { - T::collect_and_apply(iter, |xs| self.intern_const_list(xs)) - } - - pub fn intern_const_list(self, cs: &[ty::Const<'tcx>]) -> &'tcx List<ty::Const<'tcx>> { - if cs.is_empty() { List::empty() } else { self._intern_const_list(cs) } - } - - pub fn intern_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> { - if ts.is_empty() { - List::empty() - } else { - // Actually intern type lists as lists of `GenericArg`s. - // - // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound - // as explained in ty_slice_as_generic_arg`. With this, - // we guarantee that even when transmuting between `List<Ty<'tcx>>` - // and `List<GenericArg<'tcx>>`, the uniqueness requirement for - // lists is upheld. - let substs = self._intern_substs(ty::subst::ty_slice_as_generic_args(ts)); - substs.try_as_type_list().unwrap() - } + T::collect_and_apply(iter, |xs| self.mk_const_list(xs)) } - pub fn intern_substs(self, ts: &[GenericArg<'tcx>]) -> &'tcx List<GenericArg<'tcx>> { - if ts.is_empty() { List::empty() } else { self._intern_substs(ts) } - } - - pub fn intern_projs(self, ps: &[ProjectionKind]) -> &'tcx List<ProjectionKind> { - if ps.is_empty() { List::empty() } else { self._intern_projs(ps) } - } - - pub fn intern_place_elems(self, ts: &[PlaceElem<'tcx>]) -> &'tcx List<PlaceElem<'tcx>> { - if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) } - } - - pub fn intern_canonical_var_infos( - self, - ts: &[CanonicalVarInfo<'tcx>], - ) -> CanonicalVarInfos<'tcx> { - if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } - } - - pub fn intern_bound_variable_kinds( - self, - ts: &[ty::BoundVariableKind], - ) -> &'tcx List<ty::BoundVariableKind> { - if ts.is_empty() { List::empty() } else { self._intern_bound_variable_kinds(ts) } - } - - // Unlike various other `mk_*` functions, this one uses `I: IntoIterator` - // instead of `I: Iterator`. Unlike those other functions, this one doesn't - // have a `intern_fn_sig` variant that can be used for cases where `I` is - // something like a `Vec`. That's because of the need to combine `inputs` - // and `output`. + pub fn mk_type_list(self, ts: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> { + // Actually intern type lists as lists of `GenericArg`s. + // + // Transmuting from `Ty<'tcx>` to `GenericArg<'tcx>` is sound + // as explained in ty_slice_as_generic_arg`. With this, + // we guarantee that even when transmuting between `List<Ty<'tcx>>` + // and `List<GenericArg<'tcx>>`, the uniqueness requirement for + // lists is upheld. + let substs = self.mk_substs(ty::subst::ty_slice_as_generic_args(ts)); + substs.try_as_type_list().unwrap() + } + + // Unlike various other `mk_*_from_iter` functions, this one uses `I: + // IntoIterator` instead of `I: Iterator`, and it doesn't have a slice + // variant, because of the need to combine `inputs` and `output`. This + // explains the lack of `_from_iter` suffix. pub fn mk_fn_sig<I, T>( self, inputs: I, @@ -2237,14 +2212,14 @@ impl<'tcx> TyCtxt<'tcx> { T: CollectAndApply<Ty<'tcx>, ty::FnSig<'tcx>>, { T::collect_and_apply(inputs.into_iter().chain(iter::once(output)), |xs| ty::FnSig { - inputs_and_output: self.intern_type_list(xs), + inputs_and_output: self.mk_type_list(xs), c_variadic, unsafety, abi, }) } - pub fn mk_poly_existential_predicates<I, T>(self, iter: I) -> T::Output + pub fn mk_poly_existential_predicates_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply< @@ -2252,39 +2227,47 @@ impl<'tcx> TyCtxt<'tcx> { &'tcx List<PolyExistentialPredicate<'tcx>>, >, { - T::collect_and_apply(iter, |xs| self.intern_poly_existential_predicates(xs)) + T::collect_and_apply(iter, |xs| self.mk_poly_existential_predicates(xs)) } - pub fn mk_predicates<I, T>(self, iter: I) -> T::Output + pub fn mk_predicates_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>, { - T::collect_and_apply(iter, |xs| self.intern_predicates(xs)) + T::collect_and_apply(iter, |xs| self.mk_predicates(xs)) } - pub fn mk_type_list<I, T>(self, iter: I) -> T::Output + pub fn mk_type_list_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>, { - T::collect_and_apply(iter, |xs| self.intern_type_list(xs)) + T::collect_and_apply(iter, |xs| self.mk_type_list(xs)) } - pub fn mk_substs<I, T>(self, iter: I) -> T::Output + pub fn mk_substs_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>, { - T::collect_and_apply(iter, |xs| self.intern_substs(xs)) + T::collect_and_apply(iter, |xs| self.mk_substs(xs)) } - pub fn mk_place_elems<I, T>(self, iter: I) -> T::Output + pub fn mk_canonical_var_infos_from_iter<I, T>(self, iter: I) -> T::Output + where + I: Iterator<Item = T>, + T: CollectAndApply<CanonicalVarInfo<'tcx>, &'tcx List<CanonicalVarInfo<'tcx>>>, + { + T::collect_and_apply(iter, |xs| self.mk_canonical_var_infos(xs)) + } + + pub fn mk_place_elems_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>, { - T::collect_and_apply(iter, |xs| self.intern_place_elems(xs)) + T::collect_and_apply(iter, |xs| self.mk_place_elems(xs)) } pub fn mk_substs_trait( @@ -2292,33 +2275,33 @@ impl<'tcx> TyCtxt<'tcx> { self_ty: Ty<'tcx>, rest: impl IntoIterator<Item = GenericArg<'tcx>>, ) -> SubstsRef<'tcx> { - self.mk_substs(iter::once(self_ty.into()).chain(rest)) + self.mk_substs_from_iter(iter::once(self_ty.into()).chain(rest)) } pub fn mk_trait_ref( self, trait_def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ty::TraitRef<'tcx> { - let substs = self.check_substs(trait_def_id, substs); + let substs = self.check_and_mk_substs(trait_def_id, substs); ty::TraitRef { def_id: trait_def_id, substs, _use_mk_trait_ref_instead: () } } pub fn mk_alias_ty( self, def_id: DefId, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ty::AliasTy<'tcx> { - let substs = self.check_substs(def_id, substs); + let substs = self.check_and_mk_substs(def_id, substs); ty::AliasTy { def_id, substs, _use_mk_alias_ty_instead: () } } - pub fn mk_bound_variable_kinds<I, T>(self, iter: I) -> T::Output + pub fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output where I: Iterator<Item = T>, T: CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>, { - T::collect_and_apply(iter, |xs| self.intern_bound_variable_kinds(xs)) + T::collect_and_apply(iter, |xs| self.mk_bound_variable_kinds(xs)) } /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`, @@ -2403,7 +2386,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> { - self.intern_bound_variable_kinds( + self.mk_bound_variable_kinds( &self .late_bound_vars_map(id.owner) .and_then(|map| map.get(&id.local_id).cloned()) @@ -2451,6 +2434,10 @@ impl<'tcx> TyCtxt<'tcx> { ) } + pub fn local_def_id_to_hir_id(self, local_def_id: LocalDefId) -> HirId { + self.opt_local_def_id_to_hir_id(local_def_id).unwrap() + } + pub fn trait_solver_next(self) -> bool { self.sess.opts.unstable_opts.trait_solver == rustc_session::config::TraitSolver::Next } @@ -2459,7 +2446,7 @@ impl<'tcx> TyCtxt<'tcx> { impl<'tcx> TyCtxtAt<'tcx> { /// Constructs a `TyKind::Error` type and registers a `delay_span_bug` to ensure it gets used. #[track_caller] - pub fn ty_error(self) -> Ty<'tcx> { + pub fn ty_error_misc(self) -> Ty<'tcx> { self.tcx.ty_error_with_message(self.span, "TyKind::Error constructed but no error reported") } @@ -2473,7 +2460,7 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn mk_trait_ref( self, trait_lang_item: LangItem, - substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>, ) -> ty::TraitRef<'tcx> { let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span)); self.tcx.mk_trait_ref(trait_def_id, substs) @@ -2521,6 +2508,5 @@ pub fn provide(providers: &mut ty::query::Providers) { // We want to check if the panic handler was defined in this crate tcx.lang_items().panic_impl().map_or(false, |did| did.is_local()) }; - providers.source_span = - |tcx, def_id| tcx.untracked.source_span.read().get(def_id).copied().unwrap_or(DUMMY_SP); + providers.source_span = |tcx, def_id| tcx.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP); } diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index a029c1b209d..e894e1aaf36 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -3,10 +3,9 @@ use std::ops::ControlFlow; use crate::ty::{ - ir::{FallibleTypeFolder, TypeVisitor}, - visit::TypeVisitable, - AliasTy, Const, ConstKind, DefIdTree, InferConst, InferTy, Opaque, PolyTraitPredicate, - Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, + AliasTy, Const, ConstKind, DefIdTree, FallibleTypeFolder, InferConst, InferTy, Opaque, + PolyTraitPredicate, Projection, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_data_structures::fx::FxHashMap; @@ -95,7 +94,7 @@ pub trait IsSuggestable<'tcx>: Sized { impl<'tcx, T> IsSuggestable<'tcx> for T where - T: TypeVisitable<'tcx> + TypeFoldable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>> + TypeFoldable<TyCtxt<'tcx>>, { fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool { self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue() @@ -612,3 +611,11 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> { c.try_super_fold_with(self) } } + +#[derive(Diagnostic)] +#[diag(middle_const_not_used_in_type_alias)] +pub(super) struct ConstNotUsedTraitAlias { + pub ct: String, + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_middle/src/ty/erase_regions.rs b/compiler/rustc_middle/src/ty/erase_regions.rs index d3b031bf875..38377324832 100644 --- a/compiler/rustc_middle/src/ty/erase_regions.rs +++ b/compiler/rustc_middle/src/ty/erase_regions.rs @@ -1,5 +1,5 @@ -use crate::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; -use crate::ty::{self, Ty, TyCtxt, TypeFlags}; +use crate::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use crate::ty::{self, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; pub(super) fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { erase_regions_ty, ..*providers }; @@ -17,7 +17,7 @@ impl<'tcx> TyCtxt<'tcx> { /// subtyping, but they are anonymized and normalized as well).. pub fn erase_regions<T>(self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { // If there's nothing to erase avoid performing the query at all if !value.has_type_flags(TypeFlags::HAS_LATE_BOUND | TypeFlags::HAS_FREE_REGIONS) { @@ -45,7 +45,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RegionEraserVisitor<'tcx> { fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let u = self.tcx.anonymize_bound_vars(t); u.super_fold_with(self) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 106ce9990e1..59deade0a07 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -1,6 +1,6 @@ use crate::mir::Mutability; use crate::ty::subst::GenericArgKind; -use crate::ty::{self, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_hir::def_id::DefId; use std::fmt::Debug; use std::hash::Hash; diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs index ee36e60bff1..d66f436f947 100644 --- a/compiler/rustc_middle/src/ty/fold.rs +++ b/compiler/rustc_middle/src/ty/fold.rs @@ -1,19 +1,10 @@ -use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, Binder, BoundTy, Ty, TyCtxt, TypeVisitableExt}; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::DefId; use std::collections::BTreeMap; -pub trait TypeFoldable<'tcx> = ir::TypeFoldable<TyCtxt<'tcx>> + TypeVisitable<'tcx>; -pub trait TypeSuperFoldable<'tcx> = ir::TypeSuperFoldable<TyCtxt<'tcx>>; -pub trait TypeFolder<'tcx> = ir::TypeFolder<TyCtxt<'tcx>>; -pub trait FallibleTypeFolder<'tcx> = ir::FallibleTypeFolder<TyCtxt<'tcx>>; - -pub mod ir { - pub use rustc_type_ir::fold::{ - FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable, - }; -} +pub use rustc_type_ir::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; /////////////////////////////////////////////////////////////////////////// // Some sample folders @@ -30,7 +21,7 @@ where pub ct_op: H, } -impl<'tcx, F, G, H> ir::TypeFolder<TyCtxt<'tcx>> for BottomUpFolder<'tcx, F, G, H> +impl<'tcx, F, G, H> TypeFolder<TyCtxt<'tcx>> for BottomUpFolder<'tcx, F, G, H> where F: FnMut(Ty<'tcx>) -> Ty<'tcx>, G: FnMut(ty::Region<'tcx>) -> ty::Region<'tcx>, @@ -69,7 +60,7 @@ impl<'tcx> TyCtxt<'tcx> { mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { value.fold_with(&mut RegionFolder::new(self, &mut f)) } @@ -80,7 +71,7 @@ impl<'tcx> TyCtxt<'tcx> { mut f: impl FnMut(ty::Region<'tcx>, ty::DebruijnIndex) -> ty::Region<'tcx>, ) -> T where - T: TypeSuperFoldable<'tcx>, + T: TypeSuperFoldable<TyCtxt<'tcx>>, { value.super_fold_with(&mut RegionFolder::new(self, &mut f)) } @@ -120,12 +111,12 @@ impl<'a, 'tcx> RegionFolder<'a, 'tcx> { } } -impl<'a, 'tcx> ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -194,7 +185,7 @@ impl<'tcx, D: BoundVarReplacerDelegate<'tcx>> BoundVarReplacer<'tcx, D> { } } -impl<'tcx, D> ir::TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D> +impl<'tcx, D> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'tcx, D> where D: BoundVarReplacerDelegate<'tcx>, { @@ -202,7 +193,7 @@ where self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -280,7 +271,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>) where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let mut region_map = BTreeMap::new(); let real_fld_r = |br: ty::BoundRegion| *region_map.entry(br).or_insert_with(|| fld_r(br)); @@ -295,7 +286,7 @@ impl<'tcx> TyCtxt<'tcx> { ) -> T where F: FnMut(ty::BoundRegion) -> ty::Region<'tcx>, - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let value = value.skip_binder(); if !value.has_escaping_bound_vars() { @@ -314,7 +305,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces all escaping bound vars. The `fld_r` closure replaces escaping /// bound regions; the `fld_t` closure replaces escaping bound types and the `fld_c` /// closure replaces escaping bound consts. - pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<'tcx>>( + pub fn replace_escaping_bound_vars_uncached<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: T, delegate: impl BoundVarReplacerDelegate<'tcx>, @@ -330,7 +321,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Replaces all types or regions bound by the given `Binder`. The `fld_r` /// closure replaces bound regions, the `fld_t` closure replaces bound /// types, and `fld_c` replaces bound constants. - pub fn replace_bound_vars_uncached<T: TypeFoldable<'tcx>>( + pub fn replace_bound_vars_uncached<T: TypeFoldable<TyCtxt<'tcx>>>( self, value: Binder<'tcx, T>, delegate: impl BoundVarReplacerDelegate<'tcx>, @@ -346,7 +337,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.replace_late_bound_regions_uncached(value, |br| { self.mk_re_free(all_outlive_scope, br.kind) @@ -355,7 +346,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn shift_bound_var_indices<T>(self, bound_vars: usize, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let shift_bv = |bv: ty::BoundVar| ty::BoundVar::from_usize(bv.as_usize() + bound_vars); self.replace_escaping_bound_vars_uncached( @@ -381,7 +372,7 @@ impl<'tcx> TyCtxt<'tcx> { /// method lookup and a few other places where precise region relationships are not required. pub fn erase_late_bound_regions<T>(self, value: Binder<'tcx, T>) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.replace_late_bound_regions(value, |_| self.lifetimes.re_erased).0 } @@ -389,7 +380,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Anonymize all bound variables in `value`, this is mostly used to improve caching. pub fn anonymize_bound_vars<T>(self, value: Binder<'tcx, T>) -> Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { struct Anonymize<'a, 'tcx> { tcx: TyCtxt<'tcx>, @@ -431,7 +422,7 @@ impl<'tcx> TyCtxt<'tcx> { let mut map = Default::default(); let delegate = Anonymize { tcx: self, map: &mut map }; let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate); - let bound_vars = self.mk_bound_variable_kinds(map.into_values()); + let bound_vars = self.mk_bound_variable_kinds_from_iter(map.into_values()); Binder::bind_with_vars(inner, bound_vars) } } @@ -457,12 +448,12 @@ impl<'tcx> Shifter<'tcx> { } } -impl<'tcx> ir::TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> { +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Shifter<'tcx> { fn interner(&self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -525,7 +516,7 @@ pub fn shift_region<'tcx>( pub fn shift_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: T, amount: u32) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!("shift_vars(value={:?}, amount={})", value, amount); diff --git a/compiler/rustc_middle/src/ty/generics.rs b/compiler/rustc_middle/src/ty/generics.rs index 35c036fef2d..baef4ffeda7 100644 --- a/compiler/rustc_middle/src/ty/generics.rs +++ b/compiler/rustc_middle/src/ty/generics.rs @@ -101,7 +101,7 @@ impl GenericParamDef { ) -> ty::GenericArg<'tcx> { match &self.kind { ty::GenericParamDefKind::Lifetime => tcx.mk_re_error_misc().into(), - ty::GenericParamDefKind::Type { .. } => tcx.ty_error().into(), + ty::GenericParamDefKind::Type { .. } => tcx.ty_error_misc().into(), ty::GenericParamDefKind::Const { .. } => { tcx.const_error(tcx.type_of(self.def_id).subst(tcx, preceding_substs)).into() } diff --git a/compiler/rustc_middle/src/ty/impls_ty.rs b/compiler/rustc_middle/src/ty/impls_ty.rs index 3e59c0b967c..4c7822acdf7 100644 --- a/compiler/rustc_middle/src/ty/impls_ty.rs +++ b/compiler/rustc_middle/src/ty/impls_ty.rs @@ -79,7 +79,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ty::subst::GenericArgKin // WARNING: We dedup cache the `HashStable` results for `List` // while ignoring types and freely transmute // between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. - // See `fn intern_type_list` for more details. + // See `fn mk_type_list` for more details. // // We therefore hash types without adding a hash for their discriminant. // diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index c68a344e92c..f4028a5a9f6 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -1,7 +1,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; -use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef}; +use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef, TypeVisitableExt}; use rustc_errors::ErrorGuaranteed; use rustc_hir::def::Namespace; use rustc_hir::def_id::{CrateNum, DefId}; @@ -540,7 +540,7 @@ impl<'tcx> Instance<'tcx> { pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> { let def_id = tcx.require_lang_item(LangItem::DropInPlace, None); - let substs = tcx.intern_substs(&[ty.into()]); + let substs = tcx.mk_substs(&[ty.into()]); Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs) } @@ -589,7 +589,7 @@ impl<'tcx> Instance<'tcx> { pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: &T) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable<TyCtxt<'tcx>> + Copy, { if let Some(substs) = self.substs_for_mir_body() { EarlyBinder(*v).subst(tcx, substs) @@ -606,7 +606,7 @@ impl<'tcx> Instance<'tcx> { v: T, ) -> T where - T: TypeFoldable<'tcx> + Clone, + T: TypeFoldable<TyCtxt<'tcx>> + Clone, { if let Some(substs) = self.substs_for_mir_body() { tcx.subst_and_normalize_erasing_regions(substs, param_env, v) @@ -623,7 +623,7 @@ impl<'tcx> Instance<'tcx> { v: T, ) -> Result<T, NormalizationError<'tcx>> where - T: TypeFoldable<'tcx> + Clone, + T: TypeFoldable<TyCtxt<'tcx>> + Clone, { if let Some(substs) = self.substs_for_mir_body() { tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v) @@ -674,7 +674,7 @@ fn polymorphize<'tcx>( tcx: TyCtxt<'tcx>, } - impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> { + impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for PolymorphizationFolder<'tcx> { fn interner(&self) -> TyCtxt<'tcx> { self.tcx } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 993191ee96a..6c59cde86e3 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1,6 +1,7 @@ +use crate::fluent_generated as fluent; use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::ty::normalize_erasing_regions::NormalizationError; -use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitable}; +use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -182,16 +183,16 @@ impl IntoDiagnostic<'_, !> for LayoutError<'_> { match self { LayoutError::Unknown(ty) => { diag.set_arg("ty", ty); - diag.set_primary_message(rustc_errors::fluent::middle_unknown_layout); + diag.set_primary_message(fluent::middle_unknown_layout); } LayoutError::SizeOverflow(ty) => { diag.set_arg("ty", ty); - diag.set_primary_message(rustc_errors::fluent::middle_values_too_big); + diag.set_primary_message(fluent::middle_values_too_big); } LayoutError::NormalizationFailure(ty, e) => { diag.set_arg("ty", ty); diag.set_arg("failure_ty", e.get_type_for_failure()); - diag.set_primary_message(rustc_errors::fluent::middle_cannot_be_normalized); + diag.set_primary_message(fluent::middle_cannot_be_normalized); } } diag @@ -595,7 +596,7 @@ where ty::Adt(def, _) => def.variant(variant_index).fields.len(), _ => bug!(), }; - tcx.intern_layout(LayoutS { + tcx.mk_layout(LayoutS { variants: Variants::Single { index: variant_index }, fields: match NonZeroUsize::new(fields) { Some(fields) => FieldsShape::Union(fields), @@ -608,7 +609,7 @@ where }) } - Variants::Multiple { ref variants, .. } => cx.tcx().intern_layout(variants[variant_index].clone()), + Variants::Multiple { ref variants, .. } => cx.tcx().mk_layout(variants[variant_index].clone()), }; assert_eq!(*layout.variants(), Variants::Single { index: variant_index }); @@ -630,7 +631,7 @@ where let tcx = cx.tcx(); let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> { TyAndLayout { - layout: tcx.intern_layout(LayoutS::scalar(cx, tag)), + layout: tcx.mk_layout(LayoutS::scalar(cx, tag)), ty: tag.primitive().to_ty(tcx), } }; @@ -686,7 +687,7 @@ where Increase this counter if you tried to implement this but failed to do it without duplicating a lot of code from other places in the compiler: 2 - tcx.intern_tup(&[ + tcx.mk_tup(&[ tcx.mk_array(tcx.types.usize, 3), tcx.mk_array(Option<fn()>), ]) @@ -1120,13 +1121,6 @@ impl From<call::AdjustForForeignAbiError> for FnAbiError<'_> { impl<'tcx> fmt::Display for FnAbiError<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - #[cfg(bootstrap)] - match self { - Self::Layout(err) => fmt::Display::fmt(err, f), - Self::AdjustForForeignAbi(err) => fmt::Display::fmt(err, f), - } - - #[cfg(not(bootstrap))] match self { Self::Layout(err) => err.fmt(f), Self::AdjustForForeignAbi(err) => err.fmt(f), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index f61fe707ac9..17262a0be24 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -12,7 +12,7 @@ #![allow(rustc::usage_of_ty_tykind)] pub use self::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; -pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +pub use self::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; pub use self::AssocItemContainer::*; pub use self::BorrowKind::*; pub use self::IntVarValue::*; @@ -35,6 +35,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::tagged_ptr::CopyTaggedPtr; +use rustc_errors::ErrorGuaranteed; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap}; @@ -145,10 +146,6 @@ mod structural_impls; mod sty; mod typeck_results; -pub mod ir { - pub use super::{fold::ir::*, visit::ir::*}; -} - // Data types pub type RegisteredTools = FxHashSet<Ident>; @@ -760,7 +757,7 @@ impl<'tcx> Predicate<'tcx> { let new = EarlyBinder(shifted_pred).subst(tcx, trait_ref.skip_binder().substs); // 3) ['x] + ['b] -> ['x, 'b] let bound_vars = - tcx.mk_bound_variable_kinds(trait_bound_vars.iter().chain(pred_bound_vars)); + tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(pred_bound_vars)); tcx.reuse_or_mk_predicate(self, ty::Binder::bind_with_vars(new, bound_vars)) } } @@ -921,14 +918,17 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Term<'tcx> { } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Term<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self.unpack().try_fold_with(folder)?.pack()) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Term<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.unpack().visit_with(visitor) } } @@ -1359,7 +1359,7 @@ pub struct OpaqueHiddenType<'tcx> { } impl<'tcx> OpaqueHiddenType<'tcx> { - pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) { + pub fn report_mismatch(&self, other: &Self, tcx: TyCtxt<'tcx>) -> ErrorGuaranteed { // Found different concrete types for the opaque type. let sub_diag = if self.span == other.span { TypeMismatchReason::ConflictType { span: self.span } @@ -1371,7 +1371,7 @@ impl<'tcx> OpaqueHiddenType<'tcx> { other_ty: other.ty, other_span: other.span, sub: sub_diag, - }); + }) } #[instrument(level = "debug", skip(tcx), ret)] @@ -1626,8 +1626,8 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> { } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> { - fn try_fold_with<F: ty::fold::FallibleTypeFolder<'tcx>>( +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> { + fn try_fold_with<F: ty::fold::FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { @@ -1639,8 +1639,8 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> { } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ParamEnv<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.caller_bounds().visit_with(visitor)?; self.reveal().visit_with(visitor) } @@ -1765,7 +1765,7 @@ impl<'tcx> ParamEnv<'tcx> { /// `where Box<u32>: Copy`, which are clearly never /// satisfiable. We generally want to behave as if they were true, /// although the surrounding function is never reachable. - pub fn and<T: TypeVisitable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> { + pub fn and<T: TypeVisitable<TyCtxt<'tcx>>>(self, value: T) -> ParamEnvAnd<'tcx, T> { match self.reveal() { Reveal::UserFacing => ParamEnvAnd { param_env: self, value }, diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs index 825e5fbe232..57c8f3075b0 100644 --- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs +++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs @@ -9,11 +9,8 @@ use crate::mir; use crate::traits::query::NoSolution; -use crate::ty::fold::{ - ir::{FallibleTypeFolder, TypeFolder}, - TypeFoldable, -}; -use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; +use crate::ty::{self, EarlyBinder, SubstsRef, Ty, TyCtxt, TypeVisitableExt}; #[derive(Debug, Copy, Clone, HashStable, TyEncodable, TyDecodable)] pub enum NormalizationError<'tcx> { @@ -41,7 +38,7 @@ impl<'tcx> TyCtxt<'tcx> { #[tracing::instrument(level = "debug", skip(self, param_env))] pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!( "normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", @@ -73,7 +70,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> Result<T, NormalizationError<'tcx>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!( "try_normalize_erasing_regions::<{}>(value={:?}, param_env={:?})", @@ -110,7 +107,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let value = self.erase_late_bound_regions(value); self.normalize_erasing_regions(param_env, value) @@ -130,7 +127,7 @@ impl<'tcx> TyCtxt<'tcx> { value: ty::Binder<'tcx, T>, ) -> Result<T, NormalizationError<'tcx>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let value = self.erase_late_bound_regions(value); self.try_normalize_erasing_regions(param_env, value) @@ -148,7 +145,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!( "subst_and_normalize_erasing_regions(\ @@ -172,7 +169,7 @@ impl<'tcx> TyCtxt<'tcx> { value: T, ) -> Result<T, NormalizationError<'tcx>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!( "subst_and_normalize_erasing_regions(\ diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index 8aeef4684b3..751f3066c9c 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -1,9 +1,7 @@ use crate::error::ConstNotUsedTraitAlias; -use crate::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; +use crate::ty::fold::{TypeFolder, TypeSuperFoldable}; use crate::ty::subst::{GenericArg, GenericArgKind}; -#[cfg(not(bootstrap))] -use crate::ty::TypeFoldable; -use crate::ty::{self, Ty, TyCtxt}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashMap; use rustc_span::def_id::DefId; use rustc_span::Span; @@ -81,7 +79,7 @@ impl<'tcx> ReverseMapper<'tcx> { // during codegen. let generics = self.tcx.generics_of(def_id); - self.tcx.mk_substs(substs.iter().enumerate().map(|(index, kind)| { + self.tcx.mk_substs_from_iter(substs.iter().enumerate().map(|(index, kind)| { if index < generics.parent_count { // Accommodate missing regions in the parent kinds... self.fold_kind_no_missing_regions_error(kind) @@ -188,7 +186,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> { .emit(); } - self.interner().ty_error() + self.interner().ty_error_misc() } } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index a101127104d..6a053c368d8 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1,7 +1,7 @@ use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar}; use crate::ty::{ self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, TermKind, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, }; use crate::ty::{GenericArg, GenericArgKind}; use rustc_apfloat::ieee::{Double, Single}; @@ -225,7 +225,7 @@ pub trait PrettyPrinter<'tcx>: fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error> where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, { value.as_ref().skip_binder().print(self) } @@ -236,7 +236,7 @@ pub trait PrettyPrinter<'tcx>: f: F, ) -> Result<Self, Self::Error> where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, { f(value.as_ref().skip_binder(), self) } @@ -2033,7 +2033,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { fn in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, Self::Error> where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, { self.pretty_in_binder(value) } @@ -2044,7 +2044,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { f: C, ) -> Result<Self, Self::Error> where - T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<TyCtxt<'tcx>>, { self.pretty_wrap_binder(value, f) } @@ -2224,12 +2224,12 @@ struct RegionFolder<'a, 'tcx> { ), } -impl<'a, 'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { +impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> { fn interner(&self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -2289,7 +2289,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { value: &ty::Binder<'tcx, T>, ) -> Result<(Self, T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error> where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, { fn name_by_region_index( index: usize, @@ -2452,7 +2452,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { pub fn pretty_in_binder<T>(self, value: &ty::Binder<'tcx, T>) -> Result<Self, fmt::Error> where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, { let old_region_index = self.region_index; let (new, new_value, _) = self.name_all_regions(value)?; @@ -2468,7 +2468,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { f: C, ) -> Result<Self, fmt::Error> where - T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<TyCtxt<'tcx>>, { let old_region_index = self.region_index; let (new, new_value, _) = self.name_all_regions(value)?; @@ -2480,7 +2480,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { fn prepare_region_info<T>(&mut self, value: &ty::Binder<'tcx, T>) where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { struct RegionNameCollector<'tcx> { used_region_names: FxHashSet<Symbol>, @@ -2496,7 +2496,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { } } - impl<'tcx> ty::visit::ir::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> { + impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for RegionNameCollector<'tcx> { type BreakTy = (); fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -2533,7 +2533,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<'tcx, T> where - T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>, + T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<TyCtxt<'tcx>>, { type Output = P; type Error = P::Error; diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 5b3f3870429..3d9a5075d4a 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -328,8 +328,9 @@ macro_rules! define_callbacks { Providers { $($name: |_, key| bug!( - "`tcx.{}({:?})` is not supported for {} crate;\n - hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.\n + "`tcx.{}({:?})` is not supported for {} crate;\n\ + hint: Queries can be either made to the local crate, or the external crate. \ + This error means you tried to use it for one that's not supported.\n\ If that's not the case, {} was likely never assigned to a provider function.\n", stringify!($name), key, diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 2ba25e8bfad..3fc5f5bed8f 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -105,7 +105,7 @@ pub trait TypeRelation<'tcx>: Sized { T: Relate<'tcx>; } -pub trait Relate<'tcx>: TypeFoldable<'tcx> + PartialEq + Copy { +pub trait Relate<'tcx>: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy { fn relate<R: TypeRelation<'tcx>>( relation: &mut R, a: Self, @@ -144,7 +144,7 @@ pub fn relate_substs<'tcx, R: TypeRelation<'tcx>>( a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { - relation.tcx().mk_substs(iter::zip(a_subst, b_subst).map(|(a, b)| { + relation.tcx().mk_substs_from_iter(iter::zip(a_subst, b_subst).map(|(a, b)| { relation.relate_with_variance(ty::Invariant, ty::VarianceDiagInfo::default(), a, b) })) } @@ -171,7 +171,7 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( relation.relate_with_variance(variance, variance_info, a, b) }); - tcx.mk_substs(params) + tcx.mk_substs_from_iter(params) } impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { @@ -222,7 +222,7 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> { r => r, }); Ok(ty::FnSig { - inputs_and_output: tcx.mk_type_list(inputs_and_output)?, + inputs_and_output: tcx.mk_type_list_from_iter(inputs_and_output)?, c_variadic: a.c_variadic, unsafety, abi, @@ -352,7 +352,8 @@ impl<'tcx> Relate<'tcx> for GeneratorWitness<'tcx> { ) -> RelateResult<'tcx, GeneratorWitness<'tcx>> { assert_eq!(a.0.len(), b.0.len()); let tcx = relation.tcx(); - let types = tcx.mk_type_list(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?; + let types = + tcx.mk_type_list_from_iter(iter::zip(a.0, b.0).map(|(a, b)| relation.relate(a, b)))?; Ok(GeneratorWitness(types)) } } @@ -412,7 +413,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( bug!("bound types encountered in super_relate_tys") } - (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error_with_guaranteed(guar)), + (&ty::Error(guar), _) | (_, &ty::Error(guar)) => Ok(tcx.ty_error(guar)), (&ty::Never, _) | (&ty::Char, _) @@ -528,7 +529,7 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( (&ty::Tuple(as_), &ty::Tuple(bs)) => { if as_.len() == bs.len() { - Ok(tcx.mk_tup(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?) + Ok(tcx.mk_tup_from_iter(iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)))?) } else if !(as_.is_empty() || bs.is_empty()) { Err(TypeError::TupleSize(expected_found(relation, as_.len(), bs.len()))) } else { @@ -673,7 +674,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( for (a_arg, b_arg) in aa.iter().zip(ba.iter()) { related_args.push(r.consts(a_arg, b_arg)?); } - let related_args = tcx.intern_const_list(&related_args); + let related_args = tcx.mk_const_list(&related_args); Expr::FunctionCall(func, related_args) } _ => return Err(TypeError::ConstMismatch(expected_found(r, a, b))), @@ -720,7 +721,7 @@ impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { _ => Err(TypeError::ExistentialMismatch(expected_found(relation, a, b))), } }); - tcx.mk_poly_existential_predicates(v) + tcx.mk_poly_existential_predicates_from_iter(v) } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 573105fd8c0..1d4d76da572 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -5,10 +5,10 @@ use crate::mir::interpret; use crate::mir::{Field, ProjectionKind}; -use crate::ty::fold::{ir::TypeSuperFoldable, FallibleTypeFolder, TypeFoldable}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; -use crate::ty::visit::{ir::TypeSuperVisitable, TypeVisitable, TypeVisitor}; -use crate::ty::{self, ir, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; +use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt}; use rustc_hir::def::Namespace; use rustc_index::vec::{Idx, IndexVec}; use rustc_target::abi::TyAndLayout; @@ -372,32 +372,41 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> { // Traversal implementations. /// AdtDefs are basically the same as a DefId. -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::AdtDef<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + _visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } -impl<'tcx, T: TypeFoldable<'tcx>> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { folder.try_fold_binder(self) } } -impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_binder(self) } } -impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( +impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { + fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { @@ -405,44 +414,61 @@ impl<'tcx, T: TypeFoldable<'tcx>> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Binder } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Binder<'tcx, T> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeSuperVisitable<TyCtxt<'tcx>> + for ty::Binder<'tcx, T> +{ + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { self.as_ref().skip_binder().visit_with(visitor) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_poly_existential_predicates(v)) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_const_list(v)) +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Const<'tcx>> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_const_list(v)) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ProjectionKind> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_projs(v)) +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ProjectionKind> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_projs(v)) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for Ty<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { folder.try_fold_ty(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for Ty<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_ty(*self) } } impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> { - fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( + fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { @@ -487,12 +513,15 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> { | ty::Foreign(..) => return Ok(self), }; - Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty(kind) }) + Ok(if *self.kind() == kind { self } else { folder.interner().mk_ty_from_kind(kind) }) } } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { match self.kind() { ty::RawPtr(ref tm) => tm.visit_with(visitor), ty::Array(typ, sz) => { @@ -535,20 +564,23 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> { } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { folder.try_fold_region(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_region(*self) } } impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( + fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, _folder: &mut F, ) -> Result<Self, F::Error> { @@ -557,25 +589,31 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Region<'tcx> { } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Region<'tcx> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + _visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { folder.try_fold_predicate(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_predicate(*self) } } impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { - fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( + fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { @@ -585,31 +623,40 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Predicate<'tcx> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { self.kind().visit_with(visitor) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_predicates(v)) +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<ty::Predicate<'tcx>> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_predicates(v)) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { folder.try_fold_const(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_const(*self) } } impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { - fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>( + fn try_super_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { @@ -624,32 +671,44 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> { } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { self.ty().visit_with(visitor)?; self.kind().visit_with(visitor) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, _folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for InferConst<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + _folder: &mut F, + ) -> Result<Self, F::Error> { Ok(self) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for InferConst<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + _visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { ControlFlow::Continue(()) } } impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> { - fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>( + &self, + visitor: &mut V, + ) -> ControlFlow<V::BreakTy> { self.substs.visit_with(visitor) } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for TyAndLayout<'tcx, Ty<'tcx>> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { visitor.visit_ty(self.ty) } } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index f8d17433cf7..ba714541c9e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -7,10 +7,8 @@ use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use crate::ty::visit::ValidateBoundVars; use crate::ty::InferTy::*; use crate::ty::{ - self, - ir::{FallibleTypeFolder, TypeVisitor}, - AdtDef, DefIdTree, Discr, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, + self, AdtDef, DefIdTree, Discr, FallibleTypeFolder, Term, Ty, TyCtxt, TypeFlags, TypeFoldable, + TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, }; use crate::ty::{List, ParamEnv}; use hir::def::DefKind; @@ -252,7 +250,7 @@ impl<'tcx> ClosureSubsts<'tcx> { parts: ClosureSubstsParts<'tcx, Ty<'tcx>>, ) -> ClosureSubsts<'tcx> { ClosureSubsts { - substs: tcx.mk_substs( + substs: tcx.mk_substs_from_iter( parts.parent_substs.iter().copied().chain( [parts.closure_kind_ty, parts.closure_sig_as_fn_ptr_ty, parts.tupled_upvars_ty] .iter() @@ -379,7 +377,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { parts: GeneratorSubstsParts<'tcx, Ty<'tcx>>, ) -> GeneratorSubsts<'tcx> { GeneratorSubsts { - substs: tcx.mk_substs( + substs: tcx.mk_substs_from_iter( parts.parent_substs.iter().copied().chain( [ parts.resume_ty, @@ -570,7 +568,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { self, def_id: DefId, tcx: TyCtxt<'tcx>, - ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> { + ) -> impl Iterator<Item: Iterator<Item = Ty<'tcx>> + Captures<'tcx>> { let layout = tcx.generator_layout(def_id).unwrap(); layout.variant_fields.iter().map(move |variant| { variant.iter().map(move |field| { @@ -657,7 +655,7 @@ impl<'tcx> InlineConstSubsts<'tcx> { parts: InlineConstSubstsParts<'tcx, Ty<'tcx>>, ) -> InlineConstSubsts<'tcx> { InlineConstSubsts { - substs: tcx.mk_substs( + substs: tcx.mk_substs_from_iter( parts.parent_substs.iter().copied().chain(std::iter::once(parts.ty.into())), ), } @@ -855,7 +853,7 @@ impl<'tcx> TraitRef<'tcx> { substs: SubstsRef<'tcx>, ) -> ty::TraitRef<'tcx> { let defs = tcx.generics_of(trait_id); - tcx.mk_trait_ref(trait_id, tcx.intern_substs(&substs[..defs.params.len()])) + tcx.mk_trait_ref(trait_id, tcx.mk_substs(&substs[..defs.params.len()])) } } @@ -901,7 +899,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { ty::ExistentialTraitRef { def_id: trait_ref.def_id, - substs: tcx.intern_substs(&trait_ref.substs[1..]), + substs: tcx.mk_substs(&trait_ref.substs[1..]), } } @@ -985,7 +983,7 @@ pub struct Binder<'tcx, T>(T, &'tcx List<BoundVariableKind>); impl<'tcx, T> Binder<'tcx, T> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { /// Wraps `value` in a binder, asserting that `value` does not /// contain any bound vars that would be bound by the @@ -1053,14 +1051,14 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(value, self.1) } - pub fn map_bound_ref<F, U: TypeVisitable<'tcx>>(&self, f: F) -> Binder<'tcx, U> + pub fn map_bound_ref<F, U: TypeVisitable<TyCtxt<'tcx>>>(&self, f: F) -> Binder<'tcx, U> where F: FnOnce(&T) -> U, { self.as_ref().map_bound(f) } - pub fn map_bound<F, U: TypeVisitable<'tcx>>(self, f: F) -> Binder<'tcx, U> + pub fn map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>>(self, f: F) -> Binder<'tcx, U> where F: FnOnce(T) -> U, { @@ -1072,7 +1070,10 @@ impl<'tcx, T> Binder<'tcx, T> { Binder(value, self.1) } - pub fn try_map_bound<F, U: TypeVisitable<'tcx>, E>(self, f: F) -> Result<Binder<'tcx, U>, E> + pub fn try_map_bound<F, U: TypeVisitable<TyCtxt<'tcx>>, E>( + self, + f: F, + ) -> Result<Binder<'tcx, U>, E> where F: FnOnce(T) -> Result<U, E>, { @@ -1095,7 +1096,7 @@ impl<'tcx, T> Binder<'tcx, T> { /// in `bind`. This may be (debug) asserted in the future. pub fn rebind<U>(&self, value: U) -> Binder<'tcx, U> where - U: TypeVisitable<'tcx>, + U: TypeVisitable<TyCtxt<'tcx>>, { if cfg!(debug_assertions) { let mut validator = ValidateBoundVars::new(self.bound_vars()); @@ -1116,7 +1117,7 @@ impl<'tcx, T> Binder<'tcx, T> { /// would not be that useful.) pub fn no_bound_vars(self) -> Option<T> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { if self.0.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) } } @@ -1164,7 +1165,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for SkipBindersAt<'tcx> { fn try_fold_binder<T>(&mut self, t: Binder<'tcx, T>) -> Result<Binder<'tcx, T>, Self::Error> where - T: ty::TypeFoldable<'tcx>, + T: ty::TypeFoldable<TyCtxt<'tcx>>, { self.index.shift_in(1); let value = t.try_map_bound(|t| t.try_fold_with(self)); @@ -1550,7 +1551,7 @@ impl<'tcx> ExistentialProjection<'tcx> { pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { let def_id = tcx.parent(self.def_id); let subst_count = tcx.generics_of(def_id).count() - 1; - let substs = tcx.intern_substs(&self.substs[..subst_count]); + let substs = tcx.mk_substs(&self.substs[..subst_count]); ty::ExistentialTraitRef { def_id, substs } } @@ -1578,7 +1579,7 @@ impl<'tcx> ExistentialProjection<'tcx> { Self { def_id: projection_predicate.projection_ty.def_id, - substs: tcx.intern_substs(&projection_predicate.projection_ty.substs[1..]), + substs: tcx.mk_substs(&projection_predicate.projection_ty.substs[1..]), term: projection_predicate.term, } } @@ -1751,6 +1752,13 @@ impl<'tcx> Region<'tcx> { pub fn is_var(self) -> bool { matches!(self.kind(), ty::ReVar(_)) } + + pub fn as_var(self) -> Option<RegionVid> { + match self.kind() { + ty::ReVar(vid) => Some(vid), + _ => None, + } + } } /// Type utilities @@ -2201,7 +2209,7 @@ impl<'tcx> Ty<'tcx> { let assoc_items = tcx.associated_item_def_ids( tcx.require_lang_item(hir::LangItem::DiscriminantKind, None), ); - tcx.mk_projection(assoc_items[0], tcx.intern_substs(&[self.into()])) + tcx.mk_projection(assoc_items[0], tcx.mk_substs(&[self.into()])) } ty::Bool diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 6b4a6a17aef..b090bd9d807 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -1,10 +1,10 @@ // Type substitutions. use crate::ty::codec::{TyDecoder, TyEncoder}; -use crate::ty::fold::{ir::TypeFolder, FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; +use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; -use crate::ty::visit::{TypeVisitable, TypeVisitor}; -use crate::ty::{self, ir, Lift, List, ParamConst, Ty, TyCtxt}; +use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; +use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg}; @@ -71,7 +71,7 @@ impl<'tcx> List<Ty<'tcx>> { /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. /// /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have - /// be interned together, see `intern_type_list` for more details. + /// be interned together, see `mk_type_list` for more details. #[inline] pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> { assert_eq!(TYPE_TAG, 0); @@ -227,8 +227,11 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), @@ -237,8 +240,8 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> { } } -impl<'tcx> ir::TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), @@ -316,7 +319,7 @@ impl<'tcx> InternalSubsts<'tcx> { let count = defs.count(); let mut substs = SmallVec::with_capacity(count); Self::fill_item(&mut substs, tcx, defs, &mut mk_kind); - tcx.intern_substs(&substs) + tcx.mk_substs(&substs) } pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx> @@ -465,29 +468,32 @@ impl<'tcx> InternalSubsts<'tcx> { target_substs: SubstsRef<'tcx>, ) -> SubstsRef<'tcx> { let defs = tcx.generics_of(source_ancestor); - tcx.mk_substs(target_substs.iter().chain(self.iter().skip(defs.params.len()))) + tcx.mk_substs_from_iter(target_substs.iter().chain(self.iter().skip(defs.params.len()))) } pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> { - tcx.mk_substs(self.iter().take(generics.count())) + tcx.mk_substs_from_iter(self.iter().take(generics.count())) } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // The match arms are in order of frequency. The 1, 2, and 0 cases are // typically hit in 90--99.99% of cases. When folding doesn't change // the substs, it's faster to reuse the existing substs rather than - // calling `intern_substs`. + // calling `mk_substs`. match self.len() { 1 => { let param0 = self[0].try_fold_with(folder)?; if param0 == self[0] { Ok(self) } else { - Ok(folder.interner().intern_substs(&[param0])) + Ok(folder.interner().mk_substs(&[param0])) } } 2 => { @@ -496,17 +502,20 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.interner().intern_substs(&[param0, param1])) + Ok(folder.interner().mk_substs(&[param0, param1])) } } 0 => Ok(self), - _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_substs(v)), + _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_substs(v)), } } } -impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // This code is fairly hot, though not as hot as `SubstsRef`. // // When compiling stage 2, I get the following results: @@ -529,17 +538,17 @@ impl<'tcx> ir::TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.interner().intern_type_list(&[param0, param1])) + Ok(folder.interner().mk_type_list(&[param0, param1])) } } - _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)), + _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)), } } } -impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> { +impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> { #[inline] - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -555,8 +564,8 @@ impl<'tcx, T: TypeVisitable<'tcx>> ir::TypeVisitable<TyCtxt<'tcx>> for &'tcx ty: pub struct EarlyBinder<T>(pub T); /// For early binders, you should first call `subst` before using any visitors. -impl<'tcx, T> !ir::TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} -impl<'tcx, T> !ir::TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} +impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} +impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} impl<T> EarlyBinder<T> { pub fn as_ref(&self) -> EarlyBinder<&T> { @@ -617,7 +626,7 @@ impl<T, U> EarlyBinder<(T, U)> { impl<'tcx, 's, I: IntoIterator> EarlyBinder<I> where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { pub fn subst_iter( self, @@ -636,7 +645,7 @@ pub struct SubstIter<'s, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I> where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { type Item = I::Item; @@ -652,7 +661,7 @@ where impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { fn next_back(&mut self) -> Option<Self::Item> { Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs)) @@ -662,14 +671,14 @@ where impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { } impl<'tcx, 's, I: IntoIterator> EarlyBinder<I> where I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { pub fn subst_iter_copied( self, @@ -689,7 +698,7 @@ pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I> where I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { type Item = <I::Item as Deref>::Target; @@ -706,7 +715,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { fn next_back(&mut self) -> Option<Self::Item> { Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs)) @@ -717,7 +726,7 @@ impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { } @@ -743,7 +752,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> { } } -impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder<T> { +impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> { pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; self.0.fold_with(&mut folder) @@ -784,7 +793,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -977,7 +986,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. - fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T { + fn shift_vars_through_binders<T: TypeFoldable<TyCtxt<'tcx>>>(&self, val: T) -> T { debug!( "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", val, diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index a4a82bf247d..233c0df2d3c 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -1,6 +1,6 @@ use crate::traits::specialization_graph; use crate::ty::fast_reject::{self, SimplifiedType, TreatParams}; -use crate::ty::visit::TypeVisitable; +use crate::ty::visit::TypeVisitableExt; use crate::ty::{Ident, Ty, TyCtxt}; use hir::def_id::LOCAL_CRATE; use rustc_hir as hir; diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index ca46cf29919..90270e0ee9d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -4,8 +4,8 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::mir; use crate::ty::layout::IntegerExt; use crate::ty::{ - self, ir::TypeFolder, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, - TypeSuperFoldable, + self, DefIdTree, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, }; use crate::ty::{GenericArgKind, SubstsRef}; use rustc_apfloat::Float as _; @@ -761,6 +761,40 @@ impl<'tcx> TyCtxt<'tcx> { } (generator_layout, generator_saved_local_names) } + + /// Query and get an English description for the item's kind. + pub fn def_descr(self, def_id: DefId) -> &'static str { + self.def_kind_descr(self.def_kind(def_id), def_id) + } + + /// Get an English description for the item's kind. + pub fn def_kind_descr(self, def_kind: DefKind, def_id: DefId) -> &'static str { + match def_kind { + DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "method", + DefKind::Generator => match self.generator_kind(def_id).unwrap() { + rustc_hir::GeneratorKind::Async(..) => "async closure", + rustc_hir::GeneratorKind::Gen => "generator", + }, + _ => def_kind.descr(def_id), + } + } + + /// Gets an English article for the [`TyCtxt::def_descr`]. + pub fn def_descr_article(self, def_id: DefId) -> &'static str { + self.def_kind_descr_article(self.def_kind(def_id), def_id) + } + + /// Gets an English article for the [`TyCtxt::def_kind_descr`]. + pub fn def_kind_descr_article(self, def_kind: DefKind, def_id: DefId) -> &'static str { + match def_kind { + DefKind::AssocFn if self.associated_item(def_id).fn_has_self_parameter => "a", + DefKind::Generator => match self.generator_kind(def_id).unwrap() { + rustc_hir::GeneratorKind::Async(..) => "an", + rustc_hir::GeneratorKind::Gen => "a", + }, + _ => def_kind.article(), + } + } } struct OpaqueTypeExpander<'tcx> { @@ -1349,8 +1383,8 @@ pub fn fold_list<'tcx, F, T>( intern: impl FnOnce(TyCtxt<'tcx>, &[T]) -> &'tcx ty::List<T>, ) -> Result<&'tcx ty::List<T>, F::Error> where - F: FallibleTypeFolder<'tcx>, - T: TypeFoldable<'tcx> + PartialEq + Copy, + F: FallibleTypeFolder<TyCtxt<'tcx>>, + T: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy, { let mut iter = list.iter(); // Look for the first element that changed diff --git a/compiler/rustc_middle/src/ty/visit.rs b/compiler/rustc_middle/src/ty/visit.rs index 8a93b59900e..6814cadb9a8 100644 --- a/compiler/rustc_middle/src/ty/visit.rs +++ b/compiler/rustc_middle/src/ty/visit.rs @@ -5,15 +5,9 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sso::SsoHashSet; use std::ops::ControlFlow; -pub trait TypeVisitable<'tcx> = ir::TypeVisitable<TyCtxt<'tcx>> + TypeVisitableExt<'tcx>; -pub trait TypeSuperVisitable<'tcx> = ir::TypeSuperVisitable<TyCtxt<'tcx>>; -pub trait TypeVisitor<'tcx> = ir::TypeVisitor<TyCtxt<'tcx>>; +pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -pub mod ir { - pub use rustc_type_ir::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; -} - -pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<TyCtxt<'tcx>> { +pub trait TypeVisitableExt<'tcx>: TypeVisitable<TyCtxt<'tcx>> { /// Returns `true` if `self` has any late-bound regions that are either /// bound by `binder` or bound by some binder outside of `binder`. /// If `binder` is `ty::INNERMOST`, this indicates whether @@ -135,7 +129,7 @@ pub trait TypeVisitableExt<'tcx>: ir::TypeVisitable<TyCtxt<'tcx>> { } } -impl<'tcx, T: ir::TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {} +impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitableExt<'tcx> for T {} /////////////////////////////////////////////////////////////////////////// // Region folder @@ -144,7 +138,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Invoke `callback` on every region appearing free in `value`. pub fn for_each_free_region( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable<TyCtxt<'tcx>>, mut callback: impl FnMut(ty::Region<'tcx>), ) { self.any_free_region_meets(value, |r| { @@ -156,7 +150,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if `callback` returns true for every region appearing free in `value`. pub fn all_free_regions_meet( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable<TyCtxt<'tcx>>, mut callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { !self.any_free_region_meets(value, |r| !callback(r)) @@ -165,7 +159,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if `callback` returns true for some region appearing free in `value`. pub fn any_free_region_meets( self, - value: &impl TypeVisitable<'tcx>, + value: &impl TypeVisitable<TyCtxt<'tcx>>, callback: impl FnMut(ty::Region<'tcx>) -> bool, ) -> bool { struct RegionVisitor<F> { @@ -190,13 +184,13 @@ impl<'tcx> TyCtxt<'tcx> { callback: F, } - impl<'tcx, F> ir::TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F> + impl<'tcx, F> TypeVisitor<TyCtxt<'tcx>> for RegionVisitor<F> where F: FnMut(ty::Region<'tcx>) -> bool, { type BreakTy = (); - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -243,7 +237,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &Binder<'tcx, T>, ) -> FxHashSet<ty::BoundRegionKind> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { self.collect_late_bound_regions(value, true) } @@ -254,7 +248,7 @@ impl<'tcx> TyCtxt<'tcx> { value: &Binder<'tcx, T>, ) -> FxHashSet<ty::BoundRegionKind> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { self.collect_late_bound_regions(value, false) } @@ -265,7 +259,7 @@ impl<'tcx> TyCtxt<'tcx> { just_constraint: bool, ) -> FxHashSet<ty::BoundRegionKind> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { let mut collector = LateBoundRegionsCollector::new(just_constraint); let result = value.as_ref().skip_binder().visit_with(&mut collector); @@ -292,10 +286,10 @@ impl<'tcx> ValidateBoundVars<'tcx> { } } -impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ValidateBoundVars<'tcx> { type BreakTy = (); - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -404,10 +398,10 @@ struct HasEscapingVarsVisitor { outer_index: ty::DebruijnIndex, } -impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasEscapingVarsVisitor { type BreakTy = FoundEscapingVars; - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -481,7 +475,7 @@ impl std::fmt::Debug for HasTypeFlagsVisitor { } } -impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasTypeFlagsVisitor { type BreakTy = FoundFlags; #[inline] @@ -551,8 +545,8 @@ impl LateBoundRegionsCollector { } } -impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector { - fn visit_binder<T: TypeVisitable<'tcx>>( +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for LateBoundRegionsCollector { + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -613,7 +607,7 @@ impl MaxUniverse { } } -impl<'tcx> ir::TypeVisitor<TyCtxt<'tcx>> for MaxUniverse { +impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxUniverse { fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { if let ty::Placeholder(placeholder) = t.kind() { self.max_universe = ty::UniverseIndex::from_u32( diff --git a/compiler/rustc_middle/src/ty/vtable.rs b/compiler/rustc_middle/src/ty/vtable.rs index f77bd9f0c6f..b9b1cd73a8b 100644 --- a/compiler/rustc_middle/src/ty/vtable.rs +++ b/compiler/rustc_middle/src/ty/vtable.rs @@ -112,5 +112,5 @@ pub(super) fn vtable_allocation_provider<'tcx>( } vtable.mutability = Mutability::Not; - tcx.create_memory_alloc(tcx.intern_const_alloc(vtable)) + tcx.create_memory_alloc(tcx.mk_const_alloc(vtable)) } diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs index 34e8a559784..c4f526dbdc8 100644 --- a/compiler/rustc_middle/src/values.rs +++ b/compiler/rustc_middle/src/values.rs @@ -2,7 +2,7 @@ use crate::dep_graph::DepKind; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{DefKind, Res}; use rustc_middle::ty::Representability; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt}; use rustc_query_system::query::QueryInfo; @@ -16,7 +16,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for Ty<'_> { fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &[QueryInfo<DepKind>]) -> Self { // SAFETY: This is never called when `Self` is not `Ty<'tcx>`. // FIXME: Represent the above fact in the trait system somehow. - unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error()) } + unsafe { std::mem::transmute::<Ty<'tcx>, Ty<'_>>(tcx.ty_error_misc()) } } } @@ -34,7 +34,7 @@ impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::SymbolName<'_> { impl<'tcx> Value<TyCtxt<'tcx>, DepKind> for ty::Binder<'_, ty::FnSig<'_>> { fn from_cycle_error(tcx: TyCtxt<'tcx>, stack: &[QueryInfo<DepKind>]) -> Self { - let err = tcx.ty_error(); + let err = tcx.ty_error_misc(); let arity = if let Some(frame) = stack.get(0) && frame.query.dep_kind == DepKind::fn_sig @@ -199,7 +199,8 @@ fn find_item_ty_spans( ) { match ty.kind { hir::TyKind::Path(hir::QPath::Resolved(_, path)) => { - if let Some(def_id) = path.res.opt_def_id() { + if let Res::Def(kind, def_id) = path.res + && kind != DefKind::TyAlias { let check_params = def_id.as_local().map_or(true, |def_id| { if def_id == needle { spans.push(ty.span); diff --git a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl b/compiler/rustc_mir_build/locales/en-US.ftl index f9bda721df3..f9bda721df3 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_build.ftl +++ b/compiler/rustc_mir_build/locales/en-US.ftl diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index 1d96893c7a3..2f63333d46b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -132,14 +132,14 @@ pub(crate) fn lit_to_mir_constant<'tcx>( (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let s = s.as_str(); let allocation = Allocation::from_bytes_byte_aligned_immutable(s.as_bytes()); - let allocation = tcx.intern_const_alloc(allocation); + let allocation = tcx.mk_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: s.len() } } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => { let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]); - let allocation = tcx.intern_const_alloc(allocation); + let allocation = tcx.mk_const_alloc(allocation); ConstValue::Slice { data: allocation, start: 0, end: data.len() } } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_array() => { diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index c621efb3b3a..ff3198847df 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -170,7 +170,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Return the operand *tmp0 to be used as the call argument let place = Place { local: operand, - projection: tcx.intern_place_elems(&[PlaceElem::Deref]), + projection: tcx.mk_place_elems(&[PlaceElem::Deref]), }; return block.and(Operand::Move(place)); diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index e22fa6365dc..eb20b2308c0 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -263,7 +263,7 @@ impl<'tcx> PlaceBuilder<'tcx> { let resolved = self.resolve_upvar(cx); let builder = resolved.as_ref().unwrap_or(self); let PlaceBase::Local(local) = builder.base else { return None }; - let projection = cx.tcx.intern_place_elems(&builder.projection); + let projection = cx.tcx.mk_place_elems(&builder.projection); Some(Place { local, projection }) } @@ -692,7 +692,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty); let fake_borrow_temp = self.local_decls.push(LocalDecl::new(fake_borrow_ty, expr_span)); - let projection = tcx.intern_place_elems(&base_place.projection[..idx]); + let projection = tcx.mk_place_elems(&base_place.projection[..idx]); self.cfg.push_assign( block, source_info, diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index fb0e9181b52..a4e48c1545d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -520,7 +520,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let source_info = self.source_info(span); let bool_ty = self.tcx.types.bool; if self.check_overflow && op.is_checkable() && ty.is_integral() { - let result_tup = self.tcx.intern_tup(&[ty, bool_ty]); + let result_tup = self.tcx.mk_tup(&[ty, bool_ty]); let result_value = self.temp(result_tup, span); self.cfg.push_assign( diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 6b960ebdb16..de2851a1af9 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -1206,7 +1206,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fake_borrows.insert(Place { local: source.local, - projection: self.tcx.intern_place_elems(proj_base), + projection: self.tcx.mk_place_elems(proj_base), }); } } @@ -1743,7 +1743,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .map(|matched_place_ref| { let matched_place = Place { local: matched_place_ref.local, - projection: tcx.intern_place_elems(matched_place_ref.projection), + projection: tcx.mk_place_elems(matched_place_ref.projection), }; let fake_borrow_deref_ty = matched_place.ty(&self.local_decls, tcx).ty; let fake_borrow_ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, fake_borrow_deref_ty); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 8859f5002e4..2de89f67dfd 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -832,7 +832,7 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + substs: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> ConstantKind<'tcx> { // The unhygienic comparison here is acceptable because this is only // used on known traits. diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index fbe08a7bd24..c34105174ef 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -5,7 +5,7 @@ use crate::build::Builder; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use smallvec::SmallVec; impl<'a, 'tcx> Builder<'a, 'tcx> { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 933b1158fa6..a6de8684c0f 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -20,7 +20,7 @@ use rustc_middle::mir::*; use rustc_middle::thir::{ self, BindingMode, Expr, ExprId, LintLevel, LocalVarId, Param, ParamId, PatKind, Thir, }; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable, TypeckResults}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypeckResults}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::Symbol; @@ -639,7 +639,7 @@ fn construct_error( let hir_id = tcx.hir().local_def_id_to_hir_id(def); let generator_kind = tcx.generator_kind(def); - let ty = tcx.ty_error(); + let ty = tcx.ty_error(err); let num_params = match body_owner_kind { hir::BodyOwnerKind::Fn => tcx.fn_sig(def).skip_binder().inputs().skip_binder().len(), hir::BodyOwnerKind::Closure => { @@ -859,7 +859,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let use_place = Place { local: ty::CAPTURE_STRUCT_LOCAL, - projection: tcx.intern_place_elems(&projs), + projection: tcx.mk_place_elems(&projs), }; self.var_debug_info.push(VarDebugInfo { name: *sym, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index ced251267d3..c1f6b8b59ce 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -1,9 +1,10 @@ -use crate::thir::pattern::deconstruct_pat::DeconstructedPat; -use crate::thir::pattern::MatchCheckCtxt; -use rustc_errors::Handler; +use crate::{ + fluent_generated as fluent, + thir::pattern::{deconstruct_pat::DeconstructedPat, MatchCheckCtxt}, +}; use rustc_errors::{ error_code, AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, - IntoDiagnostic, MultiSpan, SubdiagnosticMessage, + Handler, IntoDiagnostic, MultiSpan, SubdiagnosticMessage, }; use rustc_hir::def::Res; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; @@ -358,7 +359,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::mir_build_non_exhaustive_patterns_type_not_empty, + fluent::mir_build_non_exhaustive_patterns_type_not_empty, error_code!(E0004), ); @@ -380,7 +381,7 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { let mut span: MultiSpan = def_span.into(); span.push_span_label(def_span, ""); - diag.span_note(span, rustc_errors::fluent::def_note); + diag.span_note(span, fluent::mir_build_def_note); } let is_variant_list_non_exhaustive = match self.ty.kind() { @@ -391,14 +392,14 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { }; if is_variant_list_non_exhaustive { - diag.note(rustc_errors::fluent::non_exhaustive_type_note); + diag.note(fluent::mir_build_non_exhaustive_type_note); } else { - diag.note(rustc_errors::fluent::type_note); + diag.note(fluent::mir_build_type_note); } if let ty::Ref(_, sub_ty, _) = self.ty.kind() { if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.param_env) { - diag.note(rustc_errors::fluent::reference_note); + diag.note(fluent::mir_build_reference_note); } } @@ -424,12 +425,12 @@ impl<'a> IntoDiagnostic<'a> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { if let Some((span, sugg)) = suggestion { diag.span_suggestion_verbose( span, - rustc_errors::fluent::suggestion, + fluent::mir_build_suggestion, sugg, Applicability::HasPlaceholders, ); } else { - diag.help(rustc_errors::fluent::help); + diag.help(fluent::mir_build_help); } diag @@ -469,7 +470,7 @@ pub struct NonConstPath { pub struct UnreachablePattern { #[label] pub span: Option<Span>, - #[label(catchall_label)] + #[label(mir_build_catchall_label)] pub catchall: Option<Span>, } @@ -493,7 +494,7 @@ pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { #[primary_span] #[label] pub span: Span, - #[note(teach_note)] + #[note(mir_build_teach_note)] pub teach: Option<()>, } @@ -585,9 +586,9 @@ pub struct BorrowOfMovedValue<'tcx> { #[primary_span] pub span: Span, #[label] - #[label(occurs_because_label)] + #[label(mir_build_occurs_because_label)] pub binding_span: Span, - #[label(value_borrowed_label)] + #[label(mir_build_value_borrowed_label)] pub conflicts_ref: Vec<Span>, pub name: Ident, pub ty: Ty<'tcx>, @@ -708,7 +709,7 @@ pub struct NontrivialStructuralMatch<'tcx> { #[diag(mir_build_overlapping_range_endpoints)] #[note] pub struct OverlappingRangeEndpoints<'tcx> { - #[label(range)] + #[label(mir_build_range)] pub range: Span, #[subdiagnostic] pub overlap: Vec<Overlap<'tcx>>, @@ -788,7 +789,7 @@ pub(crate) struct PatternNotCovered<'s, 'tcx> { pub interpreted_as_const: Option<InterpretedAsConst>, #[subdiagnostic] pub adt_defined_here: Option<AdtDefinedHere<'tcx>>, - #[note(pattern_ty)] + #[note(mir_build_pattern_ty)] pub _p: (), pub pattern_ty: Ty<'tcx>, #[subdiagnostic] @@ -823,10 +824,10 @@ impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> { let mut spans = MultiSpan::from(self.adt_def_span); for Variant { span } in self.variants { - spans.push_span_label(span, rustc_errors::fluent::mir_build_variant_defined_here); + spans.push_span_label(span, fluent::mir_build_variant_defined_here); } - diag.span_note(spans, rustc_errors::fluent::mir_build_adt_defined_here); + diag.span_note(spans, fluent::mir_build_adt_defined_here); } } diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 94dae36154c..fbc130501f9 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -25,6 +25,11 @@ pub mod thir; use rustc_middle::ty::query::Providers; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + +fluent_messages! { "../locales/en-US.ftl" } + pub fn provide(providers: &mut Providers) { providers.check_match = thir::pattern::check_match; providers.lit_to_const = thir::constant::lit_to_const; diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 261b95ba95b..ae203233bd5 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -307,7 +307,7 @@ impl<'tcx> Cx<'tcx> { let arg_tys = args.iter().map(|e| self.typeck_results().expr_ty_adjusted(e)); let tupled_args = Expr { - ty: tcx.mk_tup(arg_tys), + ty: tcx.mk_tup_from_iter(arg_tys), temp_lifetime, span: expr.span, kind: ExprKind::Tuple { fields: self.mirror_exprs(args) }, @@ -758,7 +758,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Tup(ref fields) => ExprKind::Tuple { fields: self.mirror_exprs(fields) }, hir::ExprKind::Yield(ref v, _) => ExprKind::Yield { value: self.mirror_expr(v) }, - hir::ExprKind::Err => unreachable!(), + hir::ExprKind::Err(_) => unreachable!(), }; Expr { temp_lifetime, ty: expr_ty, span: expr.span, kind } diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index 74c35ef0fc2..20af60a511e 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -133,9 +133,8 @@ impl<'tcx> Cx<'tcx> { bug!("closure expr does not have closure type: {:?}", closure_ty); }; - let bound_vars = self - .tcx - .intern_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]); + let bound_vars = + self.tcx.mk_bound_variable_kinds(&[ty::BoundVariableKind::Region(ty::BrEnv)]); let br = ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind: ty::BrEnv, diff --git a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl b/compiler/rustc_mir_dataflow/locales/en-US.ftl index 98854152508..98854152508 100644 --- a/compiler/rustc_error_messages/locales/en-US/mir_dataflow.ftl +++ b/compiler/rustc_mir_dataflow/locales/en-US.ftl diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs index 077a21fc8af..2ae3ae02fcc 100644 --- a/compiler/rustc_mir_dataflow/src/framework/direction.rs +++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs @@ -1,4 +1,3 @@ -use rustc_index::bit_set::BitSet; use rustc_middle::mir::{self, BasicBlock, Location, SwitchTargets}; use rustc_middle::ty::TyCtxt; use std::ops::RangeInclusive; @@ -54,7 +53,6 @@ pub trait Direction { analysis: &A, tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, - dead_unwinds: Option<&BitSet<BasicBlock>>, exit_state: &mut A::Domain, block: (BasicBlock, &'_ mir::BasicBlockData<'tcx>), propagate: impl FnMut(BasicBlock, &A::Domain), @@ -221,7 +219,6 @@ impl Direction for Backward { analysis: &A, _tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>, - dead_unwinds: Option<&BitSet<BasicBlock>>, exit_state: &mut A::Domain, (bb, _bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>), mut propagate: impl FnMut(BasicBlock, &A::Domain), @@ -278,20 +275,6 @@ impl Direction for Backward { } } - // Ignore dead unwinds. - mir::TerminatorKind::Call { cleanup: Some(unwind), .. } - | mir::TerminatorKind::Assert { cleanup: Some(unwind), .. } - | mir::TerminatorKind::Drop { unwind: Some(unwind), .. } - | mir::TerminatorKind::DropAndReplace { unwind: Some(unwind), .. } - | mir::TerminatorKind::FalseUnwind { unwind: Some(unwind), .. } - | mir::TerminatorKind::InlineAsm { cleanup: Some(unwind), .. } - if unwind == bb => - { - if dead_unwinds.map_or(true, |dead| !dead.contains(pred)) { - propagate(pred, exit_state); - } - } - _ => propagate(pred, exit_state), } } @@ -304,7 +287,6 @@ struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> { exit_state: &'a mut D, bb: BasicBlock, propagate: &'a mut F, - effects_applied: bool, } @@ -484,7 +466,6 @@ impl Direction for Forward { analysis: &A, _tcx: TyCtxt<'tcx>, _body: &mir::Body<'tcx>, - dead_unwinds: Option<&BitSet<BasicBlock>>, exit_state: &mut A::Domain, (bb, bb_data): (BasicBlock, &'_ mir::BasicBlockData<'tcx>), mut propagate: impl FnMut(BasicBlock, &A::Domain), @@ -502,9 +483,7 @@ impl Direction for Forward { | DropAndReplace { target, unwind, value: _, place: _ } | FalseUnwind { real_target: target, unwind } => { if let Some(unwind) = unwind { - if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { - propagate(unwind, exit_state); - } + propagate(unwind, exit_state); } propagate(target, exit_state); @@ -534,9 +513,7 @@ impl Direction for Forward { fn_span: _, } => { if let Some(unwind) = cleanup { - if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { - propagate(unwind, exit_state); - } + propagate(unwind, exit_state); } if let Some(target) = target { @@ -560,9 +537,7 @@ impl Direction for Forward { cleanup, } => { if let Some(unwind) = cleanup { - if dead_unwinds.map_or(true, |dead| !dead.contains(bb)) { - propagate(unwind, exit_state); - } + propagate(unwind, exit_state); } if let Some(target) = destination { diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs index 6ddbe69e17e..91c3bf0ad21 100644 --- a/compiler/rustc_mir_dataflow/src/framework/engine.rs +++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs @@ -12,7 +12,6 @@ use rustc_ast as ast; use rustc_data_structures::work_queue::WorkQueue; use rustc_graphviz as dot; use rustc_hir::def_id::DefId; -use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::{self, traversal, BasicBlock}; use rustc_middle::mir::{create_dump_file, dump_enabled}; @@ -78,7 +77,6 @@ where { tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, - dead_unwinds: Option<&'a BitSet<BasicBlock>>, entry_sets: IndexVec<BasicBlock, A::Domain>, pass_name: Option<&'static str>, analysis: A, @@ -154,25 +152,7 @@ where bug!("`initialize_start_block` is not yet supported for backward dataflow analyses"); } - Engine { - analysis, - tcx, - body, - dead_unwinds: None, - pass_name: None, - entry_sets, - apply_trans_for_block, - } - } - - /// Signals that we do not want dataflow state to propagate across unwind edges for these - /// `BasicBlock`s. - /// - /// You must take care that `dead_unwinds` does not contain a `BasicBlock` that *can* actually - /// unwind during execution. Otherwise, your dataflow results will not be correct. - pub fn dead_unwinds(mut self, dead_unwinds: &'a BitSet<BasicBlock>) -> Self { - self.dead_unwinds = Some(dead_unwinds); - self + Engine { analysis, tcx, body, pass_name: None, entry_sets, apply_trans_for_block } } /// Adds an identifier to the graphviz output for this particular run of a dataflow analysis. @@ -190,14 +170,7 @@ where A::Domain: DebugWithContext<A>, { let Engine { - analysis, - body, - dead_unwinds, - mut entry_sets, - tcx, - apply_trans_for_block, - pass_name, - .. + analysis, body, mut entry_sets, tcx, apply_trans_for_block, pass_name, .. } = self; let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len()); @@ -236,7 +209,6 @@ where &analysis, tcx, body, - dead_unwinds, &mut state, (bb, bb_data), |target: BasicBlock, state: &A::Domain| { diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 3e382f500af..b1e03faff05 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -16,7 +16,9 @@ extern crate tracing; extern crate rustc_middle; use rustc_ast::MetaItem; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir::def_id::DefId; +use rustc_macros::fluent_messages; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; @@ -44,6 +46,8 @@ pub mod storage; pub mod un_derefer; pub mod value_analysis; +fluent_messages! { "../locales/en-US.ftl" } + pub(crate) mod indexes { pub(crate) use super::move_paths::MovePathIndex; } diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index 6d30276aeab..4a163028fcf 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -126,7 +126,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { BorrowedContent { target_place: Place { local: place.local, - projection: tcx.intern_place_elems(proj), + projection: tcx.mk_place_elems(proj), }, }, )); @@ -165,7 +165,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { if union_path.is_none() { base = self.add_move_path(base, elem, |tcx| Place { local: place.local, - projection: tcx.intern_place_elems(&place.projection[..i + 1]), + projection: tcx.mk_place_elems(&place.projection[..i + 1]), }); } } @@ -476,7 +476,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // `ConstIndex` patterns. This is done to ensure that all move paths // are disjoint, which is expected by drop elaboration. let base_place = - Place { local: place.local, projection: self.builder.tcx.intern_place_elems(base) }; + Place { local: place.local, projection: self.builder.tcx.mk_place_elems(base) }; let base_path = match self.move_path_for(base_place) { Ok(path) => path, Err(MoveError::UnionMove { path }) => { diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 33ee90ffc11..6b2eefce24d 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -13,14 +13,10 @@ use rustc_index::vec::IndexVec; use rustc_middle::mir::visit::{ MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor, }; -use rustc_middle::mir::{ - BasicBlock, BinOp, Body, Constant, ConstantKind, Local, LocalDecl, LocalKind, Location, - Operand, Place, Rvalue, SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, - RETURN_PLACE, -}; +use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::InternalSubsts; -use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, ConstKind, Instance, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::{def_id::DefId, Span}; use rustc_target::abi::{self, Align, HasDataLayout, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi as CallAbi; @@ -456,27 +452,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { }; } - fn use_ecx<F, T>(&mut self, f: F) -> Option<T> - where - F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, - { - match f(self) { - Ok(val) => Some(val), - Err(error) => { - trace!("InterpCx operation failed: {:?}", error); - // Some errors shouldn't come up because creating them causes - // an allocation, which we should avoid. When that happens, - // dedicated error variants should be introduced instead. - assert!( - !error.kind().formatted_string(), - "const-prop encountered formatting error: {}", - error - ); - None - } - } - } - /// Returns the value, if any, of evaluating `c`. fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<OpTy<'tcx>> { // FIXME we need to revisit this for #67176 @@ -491,7 +466,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { /// Returns the value, if any, of evaluating `place`. fn eval_place(&mut self, place: Place<'tcx>) -> Option<OpTy<'tcx>> { trace!("eval_place(place={:?})", place); - self.use_ecx(|this| this.ecx.eval_place_to_op(place, None)) + self.ecx.eval_place_to_op(place, None).ok() } /// Returns the value, if any, of evaluating `op`. Calls upon `eval_constant` @@ -595,35 +570,37 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { rvalue: &Rvalue<'tcx>, place: Place<'tcx>, ) -> Option<()> { - self.use_ecx(|this| match rvalue { + match rvalue { Rvalue::BinaryOp(op, box (left, right)) | Rvalue::CheckedBinaryOp(op, box (left, right)) => { - let l = this.ecx.eval_operand(left, None).and_then(|x| this.ecx.read_immediate(&x)); + let l = self.ecx.eval_operand(left, None).and_then(|x| self.ecx.read_immediate(&x)); let r = - this.ecx.eval_operand(right, None).and_then(|x| this.ecx.read_immediate(&x)); + self.ecx.eval_operand(right, None).and_then(|x| self.ecx.read_immediate(&x)); let const_arg = match (l, r) { (Ok(x), Err(_)) | (Err(_), Ok(x)) => x, // exactly one side is known - (Err(e), Err(_)) => return Err(e), // neither side is known - (Ok(_), Ok(_)) => return this.ecx.eval_rvalue_into_place(rvalue, place), // both sides are known + (Err(_), Err(_)) => return None, // neither side is known + (Ok(_), Ok(_)) => return self.ecx.eval_rvalue_into_place(rvalue, place).ok(), // both sides are known }; if !matches!(const_arg.layout.abi, abi::Abi::Scalar(..)) { // We cannot handle Scalar Pair stuff. // No point in calling `eval_rvalue_into_place`, since only one side is known - throw_machine_stop_str!("cannot optimize this") + return None; } - let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size)?; - let dest = this.ecx.eval_place(place)?; + let arg_value = const_arg.to_scalar().to_bits(const_arg.layout.size).ok()?; + let dest = self.ecx.eval_place(place).ok()?; match op { - BinOp::BitAnd if arg_value == 0 => this.ecx.write_immediate(*const_arg, &dest), + BinOp::BitAnd if arg_value == 0 => { + self.ecx.write_immediate(*const_arg, &dest).ok() + } BinOp::BitOr if arg_value == const_arg.layout.size.truncate(u128::MAX) || (const_arg.layout.ty.is_bool() && arg_value == 1) => { - this.ecx.write_immediate(*const_arg, &dest) + self.ecx.write_immediate(*const_arg, &dest).ok() } BinOp::Mul if const_arg.layout.ty.is_integral() && arg_value == 0 => { if let Rvalue::CheckedBinaryOp(_, _) = rvalue { @@ -631,16 +608,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { const_arg.to_scalar(), Scalar::from_bool(false), ); - this.ecx.write_immediate(val, &dest) + self.ecx.write_immediate(val, &dest).ok() } else { - this.ecx.write_immediate(*const_arg, &dest) + self.ecx.write_immediate(*const_arg, &dest).ok() } } - _ => throw_machine_stop_str!("cannot optimize this"), + _ => None, } } - _ => this.ecx.eval_rvalue_into_place(rvalue, place), - }) + _ => self.ecx.eval_rvalue_into_place(rvalue, place).ok(), + } } /// Creates a new `Operand::Constant` from a `Scalar` value @@ -682,7 +659,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } // FIXME> figure out what to do when read_immediate_raw fails - let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value)); + let imm = self.ecx.read_immediate_raw(value).ok(); if let Some(Right(imm)) = imm { match *imm { @@ -702,25 +679,23 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { if let ty::Tuple(types) = ty.kind() { // Only do it if tuple is also a pair with two scalars if let [ty1, ty2] = types[..] { - let alloc = self.use_ecx(|this| { - let ty_is_scalar = |ty| { - this.ecx.layout_of(ty).ok().map(|layout| layout.abi.is_scalar()) - == Some(true) - }; - if ty_is_scalar(ty1) && ty_is_scalar(ty2) { - let alloc = this - .ecx - .intern_with_temp_alloc(value.layout, |ecx, dest| { - ecx.write_immediate(*imm, dest) - }) - .unwrap(); - Ok(Some(alloc)) - } else { - Ok(None) - } - }); - - if let Some(Some(alloc)) = alloc { + let ty_is_scalar = |ty| { + self.ecx.layout_of(ty).ok().map(|layout| layout.abi.is_scalar()) + == Some(true) + }; + let alloc = if ty_is_scalar(ty1) && ty_is_scalar(ty2) { + let alloc = self + .ecx + .intern_with_temp_alloc(value.layout, |ecx, dest| { + ecx.write_immediate(*imm, dest) + }) + .unwrap(); + Some(alloc) + } else { + None + }; + + if let Some(alloc) = alloc { // Assign entire constant in a single statement. // We can't use aggregates, as we run after the aggregate-lowering `MirPhase`. let const_val = ConstValue::ByRef { alloc, offset: Size::ZERO }; @@ -921,84 +896,80 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { trace!("visit_statement: {:?}", statement); let source_info = statement.source_info; self.source_info = Some(source_info); - if let StatementKind::Assign(box (place, ref mut rval)) = statement.kind { - let can_const_prop = self.ecx.machine.can_const_prop[place.local]; - if let Some(()) = self.const_prop(rval, place) { - // This will return None if the above `const_prop` invocation only "wrote" a - // type whose creation requires no write. E.g. a generator whose initial state - // consists solely of uninitialized memory (so it doesn't capture any locals). - if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) { - trace!("replacing {:?} with {:?}", rval, value); - self.replace_with_const(rval, value, source_info); - if can_const_prop == ConstPropMode::FullConstProp - || can_const_prop == ConstPropMode::OnlyInsideOwnBlock - { - trace!("propagated into {:?}", place); + match statement.kind { + StatementKind::Assign(box (place, ref mut rval)) => { + let can_const_prop = self.ecx.machine.can_const_prop[place.local]; + if let Some(()) = self.const_prop(rval, place) { + // This will return None if the above `const_prop` invocation only "wrote" a + // type whose creation requires no write. E.g. a generator whose initial state + // consists solely of uninitialized memory (so it doesn't capture any locals). + if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) { + trace!("replacing {:?} with {:?}", rval, value); + self.replace_with_const(rval, value, source_info); + if can_const_prop == ConstPropMode::FullConstProp + || can_const_prop == ConstPropMode::OnlyInsideOwnBlock + { + trace!("propagated into {:?}", place); + } } - } - match can_const_prop { - ConstPropMode::OnlyInsideOwnBlock => { - trace!( - "found local restricted to its block. \ + match can_const_prop { + ConstPropMode::OnlyInsideOwnBlock => { + trace!( + "found local restricted to its block. \ Will remove it from const-prop after block is finished. Local: {:?}", - place.local - ); - } - ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { - trace!("can't propagate into {:?}", place); - if place.local != RETURN_PLACE { - Self::remove_const(&mut self.ecx, place.local); + place.local + ); } - } - ConstPropMode::FullConstProp => {} - } - } else { - // Const prop failed, so erase the destination, ensuring that whatever happens - // from here on, does not know about the previous value. - // This is important in case we have - // ```rust - // let mut x = 42; - // x = SOME_MUTABLE_STATIC; - // // x must now be uninit - // ``` - // FIXME: we overzealously erase the entire local, because that's easier to - // implement. - trace!( - "propagation into {:?} failed. - Nuking the entire site from orbit, it's the only way to be sure", - place, - ); - Self::remove_const(&mut self.ecx, place.local); - } - } else { - match statement.kind { - StatementKind::SetDiscriminant { ref place, .. } => { - match self.ecx.machine.can_const_prop[place.local] { - ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => { - if self.use_ecx(|this| this.ecx.statement(statement)).is_some() { - trace!("propped discriminant into {:?}", place); - } else { + ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { + trace!("can't propagate into {:?}", place); + if place.local != RETURN_PLACE { Self::remove_const(&mut self.ecx, place.local); } } - ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { - Self::remove_const(&mut self.ecx, place.local); - } + ConstPropMode::FullConstProp => {} } + } else { + // Const prop failed, so erase the destination, ensuring that whatever happens + // from here on, does not know about the previous value. + // This is important in case we have + // ```rust + // let mut x = 42; + // x = SOME_MUTABLE_STATIC; + // // x must now be uninit + // ``` + // FIXME: we overzealously erase the entire local, because that's easier to + // implement. + trace!( + "propagation into {:?} failed. + Nuking the entire site from orbit, it's the only way to be sure", + place, + ); + Self::remove_const(&mut self.ecx, place.local); } - StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { - let frame = self.ecx.frame_mut(); - frame.locals[local].value = - if let StatementKind::StorageLive(_) = statement.kind { - LocalValue::Live(interpret::Operand::Immediate( - interpret::Immediate::Uninit, - )) + } + StatementKind::SetDiscriminant { ref place, .. } => { + match self.ecx.machine.can_const_prop[place.local] { + ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => { + if self.ecx.statement(statement).is_ok() { + trace!("propped discriminant into {:?}", place); } else { - LocalValue::Dead - }; + Self::remove_const(&mut self.ecx, place.local); + } + } + ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { + Self::remove_const(&mut self.ecx, place.local); + } } - _ => {} } + StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { + let frame = self.ecx.frame_mut(); + frame.locals[local].value = if let StatementKind::StorageLive(_) = statement.kind { + LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit)) + } else { + LocalValue::Dead + }; + } + _ => {} } self.super_statement(statement, location); @@ -1008,12 +979,10 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { let source_info = terminator.source_info; self.source_info = Some(source_info); self.super_terminator(terminator, location); - // Do NOT early return in this function, it does some crucial fixup of the state at the end! + match &mut terminator.kind { TerminatorKind::Assert { expected, ref mut cond, .. } => { if let Some(ref value) = self.eval_operand(&cond) - // FIXME should be used use_ecx rather than a local match... but we have - // quite a few of these read_scalar/read_immediate that need fixing. && let Ok(value_const) = self.ecx.read_scalar(&value) && self.should_const_prop(value) { @@ -1050,6 +1019,10 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> { // gated on `mir_opt_level=3`. TerminatorKind::Call { .. } => {} } + } + + fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { + self.super_basic_block_data(block, data); // We remove all Locals which are restricted in propagation to their containing blocks and // which were modified in the current block. diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index be41d611fe4..6c1980ff3ad 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -21,7 +21,9 @@ use rustc_middle::mir::{ }; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; use rustc_middle::ty::InternalSubsts; -use rustc_middle::ty::{self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{ + self, ConstInt, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, +}; use rustc_session::lint; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index c57ec137d4b..f27beb64a14 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -124,7 +124,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { fn visit_place(&mut self, place: &mut Place<'tcx>, ctxt: PlaceContext, loc: Location) { if let Some(new_projection) = self.process_projection(&place.projection, loc) { - place.projection = self.tcx().intern_place_elems(&new_projection); + place.projection = self.tcx().mk_place_elems(&new_projection); } let observes_address = match ctxt { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 19019e3ef74..49ded10ba1f 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -122,7 +122,10 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { ) { match rvalue { Rvalue::Aggregate(kind, operands) => { - state.flood_with(target.as_ref(), self.map(), FlatSet::Bottom); + // If we assign `target = Enum::Variant#0(operand)`, + // we must make sure that all `target as Variant#i` are `Top`. + state.flood(target.as_ref(), self.map()); + if let Some(target_idx) = self.map().find(target.as_ref()) { let (variant_target, variant_index) = match **kind { AggregateKind::Tuple | AggregateKind::Closure(..) => { @@ -131,18 +134,21 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { AggregateKind::Adt(def_id, variant_index, ..) => { match self.tcx.def_kind(def_id) { DefKind::Struct => (Some(target_idx), None), - DefKind::Enum => (Some(target_idx), Some(variant_index)), + DefKind::Enum => ( + self.map.apply(target_idx, TrackElem::Variant(variant_index)), + Some(variant_index), + ), _ => (None, None), } } _ => (None, None), }; - if let Some(target) = variant_target { + if let Some(variant_target_idx) = variant_target { for (field_index, operand) in operands.iter().enumerate() { - if let Some(field) = self - .map() - .apply(target, TrackElem::Field(Field::from_usize(field_index))) - { + if let Some(field) = self.map().apply( + variant_target_idx, + TrackElem::Field(Field::from_usize(field_index)), + ) { let result = self.handle_operand(operand, state); state.insert_idx(field, result, self.map()); } @@ -151,6 +157,11 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { if let Some(variant_index) = variant_index && let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant) { + // We are assigning the discriminant as part of an aggregate. + // This discriminant can only alias a variant field's value if the operand + // had an invalid value for that type. + // Using invalid values is UB, so we are allowed to perform the assignment + // without extra flooding. let enum_ty = target.ty(self.local_decls, self.tcx).ty; if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) { state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map); diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index dc583471c89..954bb5aff8d 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -17,7 +17,7 @@ pub fn build_ptr_tys<'tcx>( unique_did: DefId, nonnull_did: DefId, ) -> (Ty<'tcx>, Ty<'tcx>, Ty<'tcx>) { - let substs = tcx.intern_substs(&[pointee.into()]); + let substs = tcx.mk_substs(&[pointee.into()]); let unique_ty = tcx.type_of(unique_did).subst(tcx, substs); let nonnull_ty = tcx.type_of(nonnull_did).subst(tcx, substs); let ptr_ty = tcx.mk_imm_ptr(pointee); @@ -138,7 +138,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { if let Some(mut new_projections) = new_projections { new_projections.extend_from_slice(&place.projection[last_deref..]); - place.projection = tcx.intern_place_elems(&new_projections); + place.projection = tcx.mk_place_elems(&new_projections); } } } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index c2ff8645635..bdfd8dc6e99 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -67,13 +67,11 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { }; let un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: side_table }; let elaborate_patch = { - let body = &*body; let env = MoveDataParamEnv { move_data, param_env }; - let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer); + remove_dead_unwinds(tcx, body, &env, &un_derefer); let inits = MaybeInitializedPlaces::new(tcx, body, &env) .into_engine(tcx, body) - .dead_unwinds(&dead_unwinds) .pass_name("elaborate_drops") .iterate_to_fixpoint() .into_results_cursor(body); @@ -81,11 +79,12 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { let uninits = MaybeUninitializedPlaces::new(tcx, body, &env) .mark_inactive_variants_as_uninit() .into_engine(tcx, body) - .dead_unwinds(&dead_unwinds) .pass_name("elaborate_drops") .iterate_to_fixpoint() .into_results_cursor(body); + let reachable = traversal::reachable_as_bitset(body); + ElaborateDropsCtxt { tcx, body, @@ -94,6 +93,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { drop_flags: Default::default(), patch: MirPatch::new(body), un_derefer: un_derefer, + reachable, } .elaborate() }; @@ -102,22 +102,21 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { } } -/// Returns the set of basic blocks whose unwind edges are known -/// to not be reachable, because they are `drop` terminators +/// Removes unwind edges which are known to be unreachable, because they are in `drop` terminators /// that can't drop anything. -fn find_dead_unwinds<'tcx>( +fn remove_dead_unwinds<'tcx>( tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, + body: &mut Body<'tcx>, env: &MoveDataParamEnv<'tcx>, und: &UnDerefer<'tcx>, -) -> BitSet<BasicBlock> { - debug!("find_dead_unwinds({:?})", body.span); +) { + debug!("remove_dead_unwinds({:?})", body.span); // We only need to do this pass once, because unwind edges can only // reach cleanup blocks, which can't have unwind edges themselves. - let mut dead_unwinds = BitSet::new_empty(body.basic_blocks.len()); + let mut dead_unwinds = Vec::new(); let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &env) .into_engine(tcx, body) - .pass_name("find_dead_unwinds") + .pass_name("remove_dead_unwinds") .iterate_to_fixpoint() .into_results_cursor(body); for (bb, bb_data) in body.basic_blocks.iter_enumerated() { @@ -129,16 +128,16 @@ fn find_dead_unwinds<'tcx>( _ => continue, }; - debug!("find_dead_unwinds @ {:?}: {:?}", bb, bb_data); + debug!("remove_dead_unwinds @ {:?}: {:?}", bb, bb_data); let LookupResult::Exact(path) = env.move_data.rev_lookup.find(place.as_ref()) else { - debug!("find_dead_unwinds: has parent; skipping"); + debug!("remove_dead_unwinds: has parent; skipping"); continue; }; flow_inits.seek_before_primary_effect(body.terminator_loc(bb)); debug!( - "find_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}", + "remove_dead_unwinds @ {:?}: path({:?})={:?}; init_data={:?}", bb, place, path, @@ -150,13 +149,22 @@ fn find_dead_unwinds<'tcx>( maybe_live |= flow_inits.contains(child); }); - debug!("find_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live); + debug!("remove_dead_unwinds @ {:?}: maybe_live={}", bb, maybe_live); if !maybe_live { - dead_unwinds.insert(bb); + dead_unwinds.push(bb); } } - dead_unwinds + if dead_unwinds.is_empty() { + return; + } + + let basic_blocks = body.basic_blocks.as_mut(); + for &bb in dead_unwinds.iter() { + if let Some(unwind) = basic_blocks[bb].terminator_mut().unwind_mut() { + *unwind = None; + } + } } struct InitializationData<'mir, 'tcx> { @@ -290,6 +298,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> { drop_flags: FxHashMap<MovePathIndex, Local>, patch: MirPatch<'tcx>, un_derefer: UnDerefer<'tcx>, + reachable: BitSet<BasicBlock>, } impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { @@ -329,6 +338,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn collect_drop_flags(&mut self) { for (bb, data) in self.body.basic_blocks.iter_enumerated() { + if !self.reachable.contains(bb) { + continue; + } let terminator = data.terminator(); let place = match terminator.kind { TerminatorKind::Drop { ref place, .. } @@ -384,6 +396,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn elaborate_drops(&mut self) { for (bb, data) in self.body.basic_blocks.iter_enumerated() { + if !self.reachable.contains(bb) { + continue; + } let loc = Location { block: bb, statement_index: data.statements.len() }; let terminator = data.terminator(); @@ -541,6 +556,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { fn drop_flags_for_fn_rets(&mut self) { for (bb, data) in self.body.basic_blocks.iter_enumerated() { + if !self.reachable.contains(bb) { + continue; + } if let TerminatorKind::Call { destination, target: Some(tgt), cleanup: Some(_), .. } = data.terminator().kind @@ -576,6 +594,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { // clobbered before they are read. for (bb, data) in self.body.basic_blocks.iter_enumerated() { + if !self.reachable.contains(bb) { + continue; + } debug!("drop_flags_for_locs({:?})", data); for i in 0..(data.statements.len() + 1) { debug!("drop_flag_for_locs: stmt {}", i); diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index dc5f88f24f8..2e97312ee50 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -126,7 +126,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> { place, Place { local: SELF_ARG, - projection: self.tcx().intern_place_elems(&[ProjectionElem::Deref]), + projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]), }, self.tcx, ); @@ -162,10 +162,9 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { place, Place { local: SELF_ARG, - projection: self.tcx().intern_place_elems(&[ProjectionElem::Field( - Field::new(0), - self.ref_gen_ty, - )]), + projection: self + .tcx() + .mk_place_elems(&[ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]), }, self.tcx, ); @@ -187,7 +186,7 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx let mut new_projection = new_base.projection.to_vec(); new_projection.append(&mut place.projection.to_vec()); - place.projection = tcx.intern_place_elems(&new_projection); + place.projection = tcx.mk_place_elems(&new_projection); } const SELF_ARG: Local = Local::from_u32(1); @@ -300,7 +299,7 @@ impl<'tcx> TransformVisitor<'tcx> { let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); - Place { local: base.local, projection: self.tcx.intern_place_elems(&projection) } + Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) } } // Create a statement which changes the discriminant @@ -427,7 +426,7 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span)); let pin_adt_ref = tcx.adt_def(pin_did); - let substs = tcx.intern_substs(&[ref_gen_ty.into()]); + let substs = tcx.mk_substs(&[ref_gen_ty.into()]); let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs); // Replace the by ref generator argument @@ -1450,13 +1449,13 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // Compute Poll<return_ty> let poll_did = tcx.require_lang_item(LangItem::Poll, None); let poll_adt_ref = tcx.adt_def(poll_did); - let poll_substs = tcx.intern_substs(&[body.return_ty().into()]); + let poll_substs = tcx.mk_substs(&[body.return_ty().into()]); (poll_adt_ref, poll_substs) } else { // Compute GeneratorState<yield_ty, return_ty> let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[yield_ty.into(), body.return_ty().into()]); + let state_substs = tcx.mk_substs(&[yield_ty.into(), body.return_ty().into()]); (state_adt_ref, state_substs) }; let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 8c6b0463a73..6e6d6566f4b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -888,7 +888,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { location: Location, ) { if let ProjectionElem::Field(f, ty) = elem { - let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; + let parent = Place { local, projection: self.tcx.mk_place_elems(proj_base) }; let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx); let check_equal = |this: &mut Self, f_ty| { if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) { diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index b027f94925d..792457c80b0 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -2,7 +2,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::mir::TerminatorKind; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, subst::SubstsRef, InstanceDef, TyCtxt}; use rustc_session::Limit; diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 0534e688703..14e644bc344 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -30,6 +30,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine { ctx.combine_bool_cmp(&statement.source_info, rvalue); ctx.combine_ref_deref(&statement.source_info, rvalue); ctx.combine_len(&statement.source_info, rvalue); + ctx.combine_cast(&statement.source_info, rvalue); } _ => {} } @@ -120,7 +121,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { *rvalue = Rvalue::Use(Operand::Copy(Place { local: base.local, - projection: self.tcx.intern_place_elems(base.projection), + projection: self.tcx.mk_place_elems(base.projection), })); } } @@ -142,6 +143,14 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } } + fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { + if let Rvalue::Cast(_kind, operand, ty) = rvalue { + if operand.ty(self.local_decls, self.tcx) == *ty { + *rvalue = Rvalue::Use(operand.clone()); + } + } + } + fn combine_primitive_clone( &self, terminator: &mut Terminator<'tcx>, diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs index 2ca33a624e2..89e0a007dac 100644 --- a/compiler/rustc_mir_transform/src/large_enums.rs +++ b/compiler/rustc_mir_transform/src/large_enums.rs @@ -114,7 +114,7 @@ impl EnumSizeOpt { tcx.data_layout.ptr_sized_integer().align(&tcx.data_layout).abi, Mutability::Not, ); - let alloc = tcx.create_memory_alloc(tcx.intern_const_alloc(alloc)); + let alloc = tcx.create_memory_alloc(tcx.mk_const_alloc(alloc)); Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc))) } fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { @@ -197,9 +197,8 @@ impl EnumSizeOpt { size_place, Rvalue::Use(Operand::Copy(Place { local: size_array_local, - projection: tcx.intern_place_elems(&[PlaceElem::Index( - discr_cast_place.local, - )]), + projection: tcx + .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]), })), )), }; diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 45cd4024c9f..4193eb7d6e8 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -35,7 +35,7 @@ use rustc_middle::mir::{ TerminatorKind, }; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; use rustc_span::sym; #[macro_use] @@ -192,7 +192,7 @@ fn remap_mir_for_const_eval_select<'tcx>( let arguments = (0..num_args).map(|x| { let mut place_elems = place_elems.to_vec(); place_elems.push(ProjectionElem::Field(x.into(), fields[x])); - let projection = tcx.intern_place_elems(&place_elems); + let projection = tcx.mk_place_elems(&place_elems); let place = Place { local: place.local, projection, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 682ad081f5c..ebe63d6cb7e 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -147,7 +147,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) assert!(!matches!(ty, Some(ty) if ty.is_generator())); let substs = if let Some(ty) = ty { - tcx.intern_substs(&[ty.into()]) + tcx.mk_substs(&[ty.into()]) } else { InternalSubsts::identity_for_item(tcx, def_id) }; @@ -597,7 +597,7 @@ fn build_call_shim<'tcx>( let untuple_args = sig.inputs(); // Create substitutions for the `Self` and `Args` generic parameters of the shim body. - let arg_tup = tcx.intern_tup(untuple_args); + let arg_tup = tcx.mk_tup(untuple_args); (Some([ty.into(), arg_tup.into()]), Some(untuple_args)) } else { @@ -632,7 +632,7 @@ fn build_call_shim<'tcx>( Adjustment::Deref => tcx.mk_imm_ptr(fnty), Adjustment::RefMut => tcx.mk_mut_ptr(fnty), }; - sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } // FIXME(eddyb) avoid having this snippet both here and in @@ -643,7 +643,7 @@ fn build_call_shim<'tcx>( let self_arg = &mut inputs_and_output[0]; debug_assert!(tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param); *self_arg = tcx.mk_mut_ptr(*self_arg); - sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); } let span = tcx.def_span(def_id); diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index 8a37423b2a0..13168e9a268 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -122,7 +122,7 @@ impl<'tcx> ReplacementMap<'tcx> { let &[PlaceElem::Field(f, _), ref rest @ ..] = place.projection else { return None; }; let fields = self.fragments[place.local].as_ref()?; let (_, new_local) = fields[f]?; - Some(Place { local: new_local, projection: tcx.intern_place_elems(&rest) }) + Some(Place { local: new_local, projection: tcx.mk_place_elems(&rest) }) } fn place_fragments( diff --git a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl b/compiler/rustc_monomorphize/locales/en-US.ftl index 6cea6a603f3..6cea6a603f3 100644 --- a/compiler/rustc_error_messages/locales/en-US/monomorphize.ftl +++ b/compiler/rustc_monomorphize/locales/en-US.ftl diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 55a9f912e08..45e659eab6c 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -189,7 +189,9 @@ use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; -use rustc_middle::ty::{self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, VtblEntry}; +use rustc_middle::ty::{ + self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry, +}; use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; @@ -658,7 +660,7 @@ struct MirNeighborCollector<'a, 'tcx> { impl<'a, 'tcx> MirNeighborCollector<'a, 'tcx> { pub fn monomorphize<T>(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!("monomorphize: self.instance={:?}", self.instance); self.instance.subst_mir_and_normalize_erasing_regions( @@ -1296,7 +1298,7 @@ impl<'v> RootCollector<'_, 'v> { self.tcx, ty::ParamEnv::reveal_all(), start_def_id, - self.tcx.intern_substs(&[main_ret_ty.into()]), + self.tcx.mk_substs(&[main_ret_ty.into()]), ) .unwrap() .unwrap(); diff --git a/compiler/rustc_monomorphize/src/errors.rs b/compiler/rustc_monomorphize/src/errors.rs index a53bd7e1fef..495a73490a2 100644 --- a/compiler/rustc_monomorphize/src/errors.rs +++ b/compiler/rustc_monomorphize/src/errors.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +use crate::fluent_generated as fluent; use rustc_errors::ErrorGuaranteed; use rustc_errors::IntoDiagnostic; use rustc_macros::{Diagnostic, LintDiagnostic}; @@ -44,7 +45,7 @@ impl IntoDiagnostic<'_> for UnusedGenericParamsHint { self, handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(rustc_errors::fluent::monomorphize_unused_generic_params); + let mut diag = handler.struct_err(fluent::monomorphize_unused_generic_params); diag.set_span(self.span); for (span, name) in self.param_spans.into_iter().zip(self.param_names) { // FIXME: I can figure out how to do a label with a fluent string with a fixed message, diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index f88155e4fc7..f6b791f29c1 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -9,7 +9,9 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir::lang_items::LangItem; +use rustc_macros::fluent_messages; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; use rustc_middle::ty::query::{Providers, TyCtxtAt}; @@ -21,6 +23,8 @@ mod partitioning; mod polymorphize; mod util; +fluent_messages! { "../locales/en-US.ftl" } + fn custom_coerce_unsize_info<'tcx>( tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 62bafb981e7..2c56edd89bc 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -9,7 +9,7 @@ use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder, Linkage, Visibility}; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; use rustc_middle::ty::print::characteristic_def_id_of_type; -use rustc_middle::ty::{self, visit::TypeVisitable, DefIdTree, InstanceDef, TyCtxt}; +use rustc_middle::ty::{self, visit::TypeVisitableExt, DefIdTree, InstanceDef, TyCtxt}; use rustc_span::symbol::Symbol; use super::PartitioningCx; diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs index 207ad332c22..b7c3dbcc091 100644 --- a/compiler/rustc_monomorphize/src/polymorphize.rs +++ b/compiler/rustc_monomorphize/src/polymorphize.rs @@ -15,7 +15,7 @@ use rustc_middle::ty::{ self, query::Providers, subst::SubstsRef, - visit::{ir::TypeVisitor, TypeSuperVisitable, TypeVisitable}, + visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}, Const, Ty, TyCtxt, UnusedGenericParams, }; use rustc_span::symbol::sym; diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index dbcfb390333..3eb158c817c 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -16,7 +16,7 @@ rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.8" +thin-vec = "0.2.12" tracing = "0.1" unicode-normalization = "0.1.11" unicode-width = "0.1.4" diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_parse/locales/en-US.ftl index c9cf7b62071..a31b1f6ac1a 100644 --- a/compiler/rustc_error_messages/locales/en-US/parse.ftl +++ b/compiler/rustc_parse/locales/en-US.ftl @@ -93,6 +93,26 @@ parse_do_catch_syntax_removed = found removed `do catch` syntax parse_float_literal_requires_integer_part = float literals must have an integer part .suggestion = must have an integer part +parse_invalid_int_literal_width = invalid width `{$width}` for integer literal + .help = valid widths are 8, 16, 32, 64 and 128 + +parse_invalid_num_literal_base_prefix = invalid base prefix for number literal + .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + .suggestion = try making the prefix lowercase + +parse_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal + .label = invalid suffix `{$suffix}` + .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +parse_invalid_float_literal_width = invalid width `{$width}` for float literal + .help = valid widths are 32 and 64 + +parse_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal + .label = invalid suffix `{$suffix}` + .help = valid suffixes are `f32` and `f64` + +parse_int_literal_too_large = integer literal is too large + parse_missing_semicolon_before_array = expected `;`, found `[` .suggestion = consider adding `;` here @@ -219,6 +239,14 @@ parse_struct_literal_not_allowed_here = struct literals are not allowed here parse_invalid_interpolated_expression = invalid interpolated expression +parse_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported +parse_octal_float_literal_not_supported = octal float literal is not supported +parse_binary_float_literal_not_supported = binary float literal is not supported +parse_not_supported = not supported + +parse_invalid_literal_suffix = suffixes on {$kind} literals are invalid + .label = invalid suffix `{$suffix}` + parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid .label = invalid suffix `{$suffix}` .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 63bf864f2a8..c746a870964 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2,13 +2,14 @@ use std::borrow::Cow; use rustc_ast::token::Token; use rustc_ast::{Path, Visibility}; -use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic}; +use rustc_errors::{AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::edition::{Edition, LATEST_STABLE_EDITION}; use rustc_span::symbol::Ident; use rustc_span::{Span, Symbol}; +use crate::fluent_generated as fluent; use crate::parser::TokenDescription; #[derive(Diagnostic)] @@ -78,7 +79,7 @@ pub(crate) struct IncorrectSemicolon<'a> { #[diag(parse_incorrect_use_of_await)] pub(crate) struct IncorrectUseOfAwait { #[primary_span] - #[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")] + #[suggestion(parse_parentheses_suggestion, code = "", applicability = "machine-applicable")] pub span: Span, } @@ -87,7 +88,7 @@ pub(crate) struct IncorrectUseOfAwait { pub(crate) struct IncorrectAwait { #[primary_span] pub span: Span, - #[suggestion(postfix_suggestion, code = "{expr}.await{question_mark}")] + #[suggestion(parse_postfix_suggestion, code = "{expr}.await{question_mark}")] pub sugg_span: (Span, Applicability), pub expr: String, pub question_mark: &'static str, @@ -140,7 +141,7 @@ pub(crate) struct InvalidComparisonOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidComparisonOperatorSub { #[suggestion( - use_instead, + parse_use_instead, style = "short", applicability = "machine-applicable", code = "{correct}" @@ -151,7 +152,7 @@ pub(crate) enum InvalidComparisonOperatorSub { invalid: String, correct: String, }, - #[label(spaceship_operator_invalid)] + #[label(parse_spaceship_operator_invalid)] Spaceship(#[primary_span] Span), } @@ -169,14 +170,14 @@ pub(crate) struct InvalidLogicalOperator { #[derive(Subdiagnostic)] pub(crate) enum InvalidLogicalOperatorSub { #[suggestion( - use_amp_amp_for_conjunction, + parse_use_amp_amp_for_conjunction, style = "short", applicability = "machine-applicable", code = "&&" )] Conjunction(#[primary_span] Span), #[suggestion( - use_pipe_pipe_for_disjunction, + parse_use_pipe_pipe_for_disjunction, style = "short", applicability = "machine-applicable", code = "||" @@ -262,14 +263,14 @@ pub(crate) struct UnexpectedTokenAfterLabel { #[primary_span] #[label(parse_unexpected_token_after_label)] pub span: Span, - #[suggestion(suggestion_remove_label, style = "verbose", code = "")] + #[suggestion(parse_suggestion_remove_label, style = "verbose", code = "")] pub remove_label: Option<Span>, #[subdiagnostic] pub enclose_in_block: Option<UnexpectedTokenAfterLabelSugg>, } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion_enclose_in_block, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion_enclose_in_block, applicability = "machine-applicable")] pub(crate) struct UnexpectedTokenAfterLabelSugg { #[suggestion_part(code = "{{ ")] pub left: Span, @@ -347,9 +348,9 @@ pub(crate) struct IfExpressionMissingThenBlock { #[derive(Subdiagnostic)] pub(crate) enum IfExpressionMissingThenBlockSub { - #[help(condition_possibly_unfinished)] + #[help(parse_condition_possibly_unfinished)] UnfinishedCondition(#[primary_span] Span), - #[help(add_then_block)] + #[help(parse_add_then_block)] AddThenBlock(#[primary_span] Span), } @@ -364,9 +365,9 @@ pub(crate) struct IfExpressionLetSomeSub { #[diag(parse_if_expression_missing_condition)] pub(crate) struct IfExpressionMissingCondition { #[primary_span] - #[label(condition_label)] + #[label(parse_condition_label)] pub if_span: Span, - #[label(block_label)] + #[label(parse_block_label)] pub block_span: Span, } @@ -404,10 +405,10 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse { #[primary_span] pub last: Span, - #[label(branch_label)] + #[label(parse_branch_label)] pub branch_span: Span, - #[label(ctx_label)] + #[label(parse_ctx_label)] pub ctx_span: Span, pub ctx: String, @@ -427,9 +428,14 @@ pub(crate) struct MissingInInForLoop { #[derive(Subdiagnostic)] pub(crate) enum MissingInInForLoopSub { // Has been misleading, at least in the past (closed Issue #48492), thus maybe-incorrect - #[suggestion(use_in_not_of, style = "short", applicability = "maybe-incorrect", code = "in")] + #[suggestion( + parse_use_in_not_of, + style = "short", + applicability = "maybe-incorrect", + code = "in" + )] InNotOf(#[primary_span] Span), - #[suggestion(add_in, style = "short", applicability = "maybe-incorrect", code = " in ")] + #[suggestion(parse_add_in, style = "short", applicability = "maybe-incorrect", code = " in ")] AddIn(#[primary_span] Span), } @@ -484,8 +490,8 @@ pub(crate) struct EqFieldInit { #[diag(parse_dotdotdot)] pub(crate) struct DotDotDot { #[primary_span] - #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")] - #[suggestion(suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")] + #[suggestion(parse_suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")] + #[suggestion(parse_suggest_inclusive_range, applicability = "maybe-incorrect", code = "..=")] pub span: Span, } @@ -525,10 +531,10 @@ pub(crate) struct UseEmptyBlockNotSemi { #[diag(parse_comparison_interpreted_as_generic)] pub(crate) struct ComparisonInterpretedAsGeneric { #[primary_span] - #[label(label_comparison)] + #[label(parse_label_comparison)] pub comparison: Span, pub r#type: Path, - #[label(label_args)] + #[label(parse_label_args)] pub args: Span, #[subdiagnostic] pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, @@ -538,17 +544,17 @@ pub(crate) struct ComparisonInterpretedAsGeneric { #[diag(parse_shift_interpreted_as_generic)] pub(crate) struct ShiftInterpretedAsGeneric { #[primary_span] - #[label(label_comparison)] + #[label(parse_label_comparison)] pub shift: Span, pub r#type: Path, - #[label(label_args)] + #[label(parse_label_args)] pub args: Span, #[subdiagnostic] pub suggestion: ComparisonOrShiftInterpretedAsGenericSugg, } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg { #[suggestion_part(code = "(")] pub left: Span, @@ -574,7 +580,7 @@ pub(crate) struct LeadingPlusNotSupported { #[label] pub span: Span, #[suggestion( - suggestion_remove_plus, + parse_suggestion_remove_plus, style = "verbose", code = "", applicability = "machine-applicable" @@ -597,7 +603,7 @@ pub(crate) struct ParenthesesWithStructFields { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion_braces_for_struct, applicability = "maybe-incorrect")] +#[multipart_suggestion(parse_suggestion_braces_for_struct, applicability = "maybe-incorrect")] pub(crate) struct BracesForStructLiteral { #[suggestion_part(code = " {{ ")] pub first: Span, @@ -606,7 +612,7 @@ pub(crate) struct BracesForStructLiteral { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion_no_fields_for_fn, applicability = "maybe-incorrect")] +#[multipart_suggestion(parse_suggestion_no_fields_for_fn, applicability = "maybe-incorrect")] pub(crate) struct NoFieldsForFnCall { #[suggestion_part(code = "")] pub fields: Vec<Span>, @@ -643,7 +649,7 @@ pub(crate) struct ArrayBracketsInsteadOfSpaces { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] pub(crate) struct ArrayBracketsInsteadOfSpacesSugg { #[suggestion_part(code = "[")] pub left: Span, @@ -655,9 +661,9 @@ pub(crate) struct ArrayBracketsInsteadOfSpacesSugg { #[diag(parse_match_arm_body_without_braces)] pub(crate) struct MatchArmBodyWithoutBraces { #[primary_span] - #[label(label_statements)] + #[label(parse_label_statements)] pub statements: Span, - #[label(label_arrow)] + #[label(parse_label_arrow)] pub arrow: Span, pub num_statements: usize, #[subdiagnostic] @@ -670,7 +676,7 @@ pub(crate) struct MatchArmBodyWithoutBraces { pub(crate) struct InclusiveRangeExtraEquals { #[primary_span] #[suggestion( - suggestion_remove_eq, + parse_suggestion_remove_eq, style = "short", code = "..=", applicability = "maybe-incorrect" @@ -695,7 +701,7 @@ pub(crate) struct InclusiveRangeMatchArrow { pub(crate) struct InclusiveRangeNoEnd { #[primary_span] #[suggestion( - suggestion_open_range, + parse_suggestion_open_range, code = "..", applicability = "machine-applicable", style = "short" @@ -705,7 +711,7 @@ pub(crate) struct InclusiveRangeNoEnd { #[derive(Subdiagnostic)] pub(crate) enum MatchArmBodyWithoutBracesSugg { - #[multipart_suggestion(suggestion_add_braces, applicability = "machine-applicable")] + #[multipart_suggestion(parse_suggestion_add_braces, applicability = "machine-applicable")] AddBraces { #[suggestion_part(code = "{{ ")] left: Span, @@ -713,7 +719,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg { right: Span, }, #[suggestion( - suggestion_use_comma_not_semicolon, + parse_suggestion_use_comma_not_semicolon, code = ",", applicability = "machine-applicable" )] @@ -733,7 +739,7 @@ pub(crate) struct StructLiteralNotAllowedHere { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct StructLiteralNotAllowedHereSugg { #[suggestion_part(code = "(")] pub left: Span, @@ -755,9 +761,9 @@ pub(crate) struct InvalidLiteralSuffixOnTupleIndex { #[label] pub span: Span, pub suffix: Symbol, - #[help(tuple_exception_line_1)] - #[help(tuple_exception_line_2)] - #[help(tuple_exception_line_3)] + #[help(parse_tuple_exception_line_1)] + #[help(parse_tuple_exception_line_2)] + #[help(parse_tuple_exception_line_3)] pub exception: Option<()>, } @@ -775,11 +781,11 @@ pub(crate) struct MismatchedClosingDelimiter { #[primary_span] pub spans: Vec<Span>, pub delimiter: String, - #[label(label_unmatched)] + #[label(parse_label_unmatched)] pub unmatched: Span, - #[label(label_opening_candidate)] + #[label(parse_label_opening_candidate)] pub opening_candidate: Option<Span>, - #[label(label_unclosed)] + #[label(parse_label_unclosed)] pub unclosed: Option<Span>, } @@ -930,7 +936,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { self, handler: &'a rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'a, G> { - let token_descr = super::parser::TokenDescription::from_token(&self.token); + let token_descr = TokenDescription::from_token(&self.token); let mut diag = handler.struct_diagnostic(match token_descr { Some(TokenDescription::ReservedIdentifier) => { @@ -976,7 +982,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { self, handler: &'a rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'a, G> { - let token_descr = super::parser::TokenDescription::from_token(&self.token); + let token_descr = TokenDescription::from_token(&self.token); let mut diag = handler.struct_diagnostic(match token_descr { Some(TokenDescription::ReservedIdentifier) => { @@ -1025,7 +1031,7 @@ pub(crate) struct StructLiteralBodyWithoutPath { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "has-placeholders")] +#[multipart_suggestion(parse_suggestion, applicability = "has-placeholders")] pub(crate) struct StructLiteralBodyWithoutPathSugg { #[suggestion_part(code = "{{ SomeStruct ")] pub before: Span, @@ -1043,7 +1049,7 @@ pub(crate) struct StructLiteralNeedingParens { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct StructLiteralNeedingParensSugg { #[suggestion_part(code = "(")] pub before: Span, @@ -1070,7 +1076,7 @@ pub(crate) struct GenericParamsWithoutAngleBrackets { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct GenericParamsWithoutAngleBracketsSugg { #[suggestion_part(code = "<")] pub left: Span, @@ -1091,7 +1097,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained { )] pub suggest_turbofish: Option<Span>, #[help(parse_sugg_turbofish_syntax)] - #[help(sugg_parentheses_for_function_args)] + #[help(parse_sugg_parentheses_for_function_args)] pub help_turbofish: Option<()>, #[subdiagnostic] pub chaining_sugg: Option<ComparisonOperatorsCannotBeChainedSugg>, @@ -1100,7 +1106,7 @@ pub(crate) struct ComparisonOperatorsCannotBeChained { #[derive(Subdiagnostic)] pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { #[suggestion( - sugg_split_comparison, + parse_sugg_split_comparison, style = "verbose", code = " && {middle_term}", applicability = "maybe-incorrect" @@ -1110,7 +1116,7 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { span: Span, middle_term: String, }, - #[multipart_suggestion(sugg_parenthesize, applicability = "maybe-incorrect")] + #[multipart_suggestion(parse_sugg_parenthesize, applicability = "maybe-incorrect")] Parenthesize { #[suggestion_part(code = "(")] left: Span, @@ -1130,7 +1136,7 @@ pub(crate) struct QuestionMarkInType { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct QuestionMarkInTypeSugg { #[suggestion_part(code = "Option<")] pub left: Span, @@ -1148,7 +1154,7 @@ pub(crate) struct ParenthesesInForHead { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct ParenthesesInForHeadSugg { #[suggestion_part(code = "{left_snippet}")] pub left: Span, @@ -1208,7 +1214,7 @@ pub(crate) struct ConstGenericWithoutBraces { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct ConstGenericWithoutBracesSugg { #[suggestion_part(code = "{{ ")] pub left: Span, @@ -1228,7 +1234,7 @@ pub(crate) struct UnexpectedConstParamDeclaration { #[derive(Subdiagnostic)] pub(crate) enum UnexpectedConstParamDeclarationSugg { - #[multipart_suggestion(suggestion, applicability = "machine-applicable")] + #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] AddParam { #[suggestion_part(code = "<{snippet}>")] impl_generics: Span, @@ -1237,7 +1243,7 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg { snippet: String, ident: String, }, - #[multipart_suggestion(suggestion, applicability = "machine-applicable")] + #[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] AppendParam { #[suggestion_part(code = ", {snippet}")] impl_generics_end: Span, @@ -1284,7 +1290,7 @@ pub(crate) struct FnPtrWithGenerics { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "maybe-incorrect")] +#[multipart_suggestion(parse_suggestion, applicability = "maybe-incorrect")] pub(crate) struct FnPtrWithGenericsSugg { #[suggestion_part(code = "{snippet}")] pub left: Span, @@ -1325,16 +1331,16 @@ pub(crate) struct WhereClauseBeforeTupleStructBody { #[primary_span] #[label] pub span: Span, - #[label(name_label)] + #[label(parse_name_label)] pub name: Span, - #[label(body_label)] + #[label(parse_body_label)] pub body: Span, #[subdiagnostic] pub sugg: Option<WhereClauseBeforeTupleStructBodySugg>, } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct WhereClauseBeforeTupleStructBodySugg { #[suggestion_part(code = "{snippet}")] pub left: Span, @@ -1429,13 +1435,13 @@ pub(crate) enum MissingKeywordForItemDefinition { #[derive(Subdiagnostic)] pub(crate) enum AmbiguousMissingKwForItemSub { - #[suggestion(suggestion, applicability = "maybe-incorrect", code = "{snippet}!")] + #[suggestion(parse_suggestion, applicability = "maybe-incorrect", code = "{snippet}!")] SuggestMacro { #[primary_span] span: Span, snippet: String, }, - #[help(help)] + #[help(parse_help)] HelpMacro, } @@ -1443,9 +1449,9 @@ pub(crate) enum AmbiguousMissingKwForItemSub { #[diag(parse_missing_trait_in_trait_impl)] pub(crate) struct MissingTraitInTraitImpl { #[primary_span] - #[suggestion(suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")] + #[suggestion(parse_suggestion_add_trait, code = " Trait ", applicability = "has-placeholders")] pub span: Span, - #[suggestion(suggestion_remove_for, code = "", applicability = "maybe-incorrect")] + #[suggestion(parse_suggestion_remove_for, code = "", applicability = "maybe-incorrect")] pub for_span: Span, } @@ -1505,7 +1511,7 @@ pub(crate) struct ExternCrateNameWithDashes { } #[derive(Subdiagnostic)] -#[multipart_suggestion(suggestion, applicability = "machine-applicable")] +#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")] pub(crate) struct ExternCrateNameWithDashesSugg { #[suggestion_part(code = "_")] pub dashes: Vec<Span>, @@ -1726,10 +1732,15 @@ pub struct UnknownPrefix<'a> { #[derive(Subdiagnostic)] pub enum UnknownPrefixSugg { - #[suggestion(suggestion_br, code = "br", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + parse_suggestion_br, + code = "br", + applicability = "maybe-incorrect", + style = "verbose" + )] UseBr(#[primary_span] Span), #[suggestion( - suggestion_whitespace, + parse_suggestion_whitespace, code = " ", applicability = "maybe-incorrect", style = "verbose" @@ -1761,7 +1772,7 @@ pub struct UnknownTokenStart { #[derive(Subdiagnostic)] pub enum TokenSubstitution { - #[suggestion(sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion(parse_sugg_quotes, code = "{suggestion}", applicability = "maybe-incorrect")] DirectedQuotes { #[primary_span] span: Span, @@ -1769,7 +1780,7 @@ pub enum TokenSubstitution { ascii_str: &'static str, ascii_name: &'static str, }, - #[suggestion(sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion(parse_sugg_other, code = "{suggestion}", applicability = "maybe-incorrect")] Other { #[primary_span] span: Span, @@ -1782,13 +1793,13 @@ pub enum TokenSubstitution { } #[derive(Subdiagnostic)] -#[note(note_repeats)] +#[note(parse_note_repeats)] pub struct UnknownTokenRepeat { pub repeats: usize, } #[derive(Subdiagnostic)] -#[help(help_null)] +#[help(parse_help_null)] pub struct UnknownTokenNull; #[derive(Diagnostic)] @@ -1805,7 +1816,7 @@ pub enum UnescapeError { EscapeOnlyChar { #[primary_span] span: Span, - #[suggestion(escape, applicability = "machine-applicable", code = "{escaped_sugg}")] + #[suggestion(parse_escape, applicability = "machine-applicable", code = "{escaped_sugg}")] char_span: Span, escaped_sugg: String, escaped_msg: String, @@ -1814,7 +1825,7 @@ pub enum UnescapeError { #[diag(parse_bare_cr)] BareCr { #[primary_span] - #[suggestion(escape, applicability = "machine-applicable", code = "\\r")] + #[suggestion(parse_escape, applicability = "machine-applicable", code = "\\r")] span: Span, double_quotes: bool, }, @@ -1854,7 +1865,12 @@ pub enum UnescapeError { #[primary_span] #[label] Span, - #[suggestion(terminate, code = "}}", applicability = "maybe-incorrect", style = "verbose")] + #[suggestion( + parse_terminate, + code = "}}", + applicability = "maybe-incorrect", + style = "verbose" + )] Span, ), #[diag(parse_no_brace_unicode_escape)] @@ -1918,20 +1934,24 @@ pub enum UnescapeError { #[derive(Subdiagnostic)] pub enum MoreThanOneCharSugg { - #[suggestion(consider_normalized, code = "{normalized}", applicability = "machine-applicable")] + #[suggestion( + parse_consider_normalized, + code = "{normalized}", + applicability = "machine-applicable" + )] NormalizedForm { #[primary_span] span: Span, ch: String, normalized: String, }, - #[suggestion(remove_non, code = "{ch}", applicability = "maybe-incorrect")] + #[suggestion(parse_remove_non, code = "{ch}", applicability = "maybe-incorrect")] RemoveNonPrinting { #[primary_span] span: Span, ch: String, }, - #[suggestion(use_double_quotes, code = "{sugg}", applicability = "machine-applicable")] + #[suggestion(parse_use_double_quotes, code = "{sugg}", applicability = "machine-applicable")] Quotes { #[primary_span] span: Span, @@ -1942,7 +1962,7 @@ pub enum MoreThanOneCharSugg { #[derive(Subdiagnostic)] pub enum MoreThanOneCharNote { - #[note(followed_by)] + #[note(parse_followed_by)] AllCombining { #[primary_span] span: Span, @@ -1950,7 +1970,7 @@ pub enum MoreThanOneCharNote { len: usize, escaped_marks: String, }, - #[note(non_printing)] + #[note(parse_non_printing)] NonPrinting { #[primary_span] span: Span, @@ -1960,13 +1980,13 @@ pub enum MoreThanOneCharNote { #[derive(Subdiagnostic)] pub enum NoBraceUnicodeSub { - #[suggestion(use_braces, code = "{suggestion}", applicability = "maybe-incorrect")] + #[suggestion(parse_use_braces, code = "{suggestion}", applicability = "maybe-incorrect")] Suggestion { #[primary_span] span: Span, suggestion: String, }, - #[help(format_of_unicode)] + #[help(parse_format_of_unicode)] Help, } @@ -2042,9 +2062,9 @@ pub(crate) struct PatternOnWrongSideOfAt { #[suggestion(code = "{whole_pat}", applicability = "machine-applicable")] pub whole_span: Span, pub whole_pat: String, - #[label(label_pattern)] + #[label(parse_label_pattern)] pub pattern: Span, - #[label(label_binding)] + #[label(parse_label_binding)] pub binding: Span, } @@ -2054,9 +2074,9 @@ pub(crate) struct PatternOnWrongSideOfAt { pub(crate) struct ExpectedBindingLeftOfAt { #[primary_span] pub whole_span: Span, - #[label(label_lhs)] + #[label(parse_label_lhs)] pub lhs: Span, - #[label(label_rhs)] + #[label(parse_label_rhs)] pub rhs: Span, } @@ -2236,7 +2256,7 @@ pub(crate) struct NegativeBoundsNotSupported { #[derive(Subdiagnostic)] #[suggestion( - suggestion, + parse_suggestion, style = "tool-only", code = "{fixed}", applicability = "machine-applicable" diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index b49a01d75ed..6f37e9758fc 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -19,6 +19,8 @@ use rustc_ast::{AttrItem, Attribute, MetaItem}; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult}; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_session::parse::ParseSess; use rustc_span::{FileName, SourceFile, Span}; @@ -34,6 +36,8 @@ pub mod validate_attr; mod errors; +fluent_messages! { "../locales/en-US.ftl" } + // A bunch of utility functions of the form `parse_<thing>_from_<source>` // where <thing> includes crate, expr, item, stmt, tts, and one that // uses a HOF to parse anything, and <source> includes file and diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 686454a8f18..e3e7c63e344 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -1,11 +1,15 @@ use crate::errors::{InvalidMetaItem, SuffixedLiteralInAttribute}; +use crate::fluent_generated as fluent; use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle}; use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::token::{self, Delimiter, Nonterminal}; -use rustc_errors::{error_code, fluent, Diagnostic, IntoDiagnostic, PResult}; +use rustc_errors::{error_code, Diagnostic, IntoDiagnostic, PResult}; use rustc_span::{sym, BytePos, Span}; +use std::convert::TryInto; +use thin_vec::ThinVec; +use tracing::debug; // Public for rustfmt usage #[derive(Debug)] @@ -65,10 +69,10 @@ impl<'a> Parser<'a> { token::CommentKind::Block => OuterAttributeType::DocBlockComment, }, ) { - err.note(fluent::note); + err.note(fluent::parse_note); err.span_suggestion_verbose( replacement_span, - fluent::suggestion, + fluent::parse_suggestion, "", rustc_errors::Applicability::MachineApplicable, ); @@ -172,10 +176,10 @@ impl<'a> Parser<'a> { Ok(Some(item)) => { // FIXME(#100717) err.set_arg("item", item.kind.descr()); - err.span_label(item.span, fluent::label_does_not_annotate_this); + err.span_label(item.span, fluent::parse_label_does_not_annotate_this); err.span_suggestion_verbose( replacement_span, - fluent::sugg_change_inner_to_outer, + fluent::parse_sugg_change_inner_to_outer, match attr_type { OuterAttributeType::Attribute => "", OuterAttributeType::DocBlockComment => "*", @@ -201,8 +205,8 @@ impl<'a> Parser<'a> { attr_sp, fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, ); - diag.span_label(attr_sp, fluent::label_attr) - .span_label(prev_doc_comment_span, fluent::label_prev_doc_comment); + diag.span_label(attr_sp, fluent::parse_label_attr) + .span_label(prev_doc_comment_span, fluent::parse_label_prev_doc_comment); diag } Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => { @@ -210,8 +214,8 @@ impl<'a> Parser<'a> { attr_sp, fluent::parse_inner_attr_not_permitted_after_outer_attr, ); - diag.span_label(attr_sp, fluent::label_attr) - .span_label(prev_outer_attr_sp, fluent::label_prev_attr); + diag.span_label(attr_sp, fluent::parse_label_attr) + .span_label(prev_outer_attr_sp, fluent::parse_label_prev_attr); diag } Some(InnerAttrForbiddenReason::InCodeBlock) | None => { @@ -346,9 +350,9 @@ impl<'a> Parser<'a> { } /// Matches `COMMASEP(meta_item_inner)`. - pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> { + pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::NestedMetaItem>> { // Presumably, the majority of the time there will only be one attr. - let mut nmis = Vec::with_capacity(1); + let mut nmis = ThinVec::with_capacity(1); while self.token.kind != token::Eof { nmis.push(self.parse_meta_item_inner()?); if !self.eat(&token::Comma) { diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 49eff41329c..b4948dddcc9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -18,6 +18,7 @@ use crate::errors::{ UseEqInstead, }; +use crate::fluent_generated as fluent; use crate::lexer::UnmatchedBrace; use crate::parser; use rustc_ast as ast; @@ -32,10 +33,9 @@ use rustc_ast::{ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{ - fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, FatalError, Handler, MultiSpan, - PResult, + pluralize, Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, + FatalError, Handler, IntoDiagnostic, MultiSpan, PResult, }; -use rustc_errors::{pluralize, Diagnostic, ErrorGuaranteed, IntoDiagnostic}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident}; @@ -693,7 +693,7 @@ impl<'a> Parser<'a> { span: self.prev_token.span.shrink_to_lo(), tokens: None, }; - let struct_expr = snapshot.parse_struct_expr(None, path, false); + let struct_expr = snapshot.parse_expr_struct(None, path, false); let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No); return Some(match (struct_expr, block_tail) { (Ok(expr), Err(mut err)) => { @@ -708,7 +708,7 @@ impl<'a> Parser<'a> { err.delay_as_bug(); self.restore_snapshot(snapshot); let mut tail = self.mk_block( - vec![self.mk_stmt_err(expr.span)], + thin_vec![self.mk_stmt_err(expr.span)], s, lo.to(self.prev_token.span), ); @@ -1624,7 +1624,7 @@ impl<'a> Parser<'a> { // Handle `await { <expr> }`. // This needs to be handled separately from the next arm to avoid // interpreting `await { <expr> }?` as `<expr>?.await`. - self.parse_block_expr(None, self.token.span, BlockCheckMode::Default) + self.parse_expr_block(None, self.token.span, BlockCheckMode::Default) } else { self.parse_expr() } @@ -2175,7 +2175,7 @@ impl<'a> Parser<'a> { /// the parameters are *names* (so we don't emit errors about not being able to find `b` in /// the local scope), but if we find the same name multiple times, like in `fn foo(i8, i8)`, /// we deduplicate them to not complain about duplicated parameter names. - pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut Vec<Param>) { + pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut ThinVec<Param>) { let mut seen_inputs = FxHashSet::default(); for input in fn_inputs.iter_mut() { let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) = @@ -2199,7 +2199,7 @@ impl<'a> Parser<'a> { /// like the user has forgotten them. pub fn handle_ambiguous_unbraced_const_arg( &mut self, - args: &mut Vec<AngleBracketedArg>, + args: &mut ThinVec<AngleBracketedArg>, ) -> PResult<'a, bool> { // If we haven't encountered a closing `>`, then the argument is malformed. // It's likely that the user has written a const expression without enclosing it diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 2fc8ce98af0..33254d034c9 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -31,6 +31,7 @@ use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::source_map::{self, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; +use thin_vec::{thin_vec, ThinVec}; /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of @@ -102,7 +103,7 @@ impl<'a> Parser<'a> { self.collect_tokens_no_attrs(|this| this.parse_expr()) } - pub fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> { + pub fn parse_expr_anon_const(&mut self) -> PResult<'a, AnonConst> { self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value }) } @@ -124,7 +125,7 @@ impl<'a> Parser<'a> { } /// Parses a sequence of expressions delimited by parentheses. - fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> { + fn parse_expr_paren_seq(&mut self) -> PResult<'a, ThinVec<P<Expr>>> { self.parse_paren_comma_seq(|p| p.parse_expr_catch_underscore()).map(|(r, _)| r) } @@ -135,7 +136,7 @@ impl<'a> Parser<'a> { r: Restrictions, already_parsed_attrs: Option<AttrWrapper>, ) -> PResult<'a, P<Expr>> { - self.with_res(r, |this| this.parse_assoc_expr(already_parsed_attrs)) + self.with_res(r, |this| this.parse_expr_assoc(already_parsed_attrs)) } /// Parses an associative expression. @@ -143,15 +144,15 @@ impl<'a> Parser<'a> { /// This parses an expression accounting for associativity and precedence of the operators in /// the expression. #[inline] - fn parse_assoc_expr( + fn parse_expr_assoc( &mut self, already_parsed_attrs: Option<AttrWrapper>, ) -> PResult<'a, P<Expr>> { - self.parse_assoc_expr_with(0, already_parsed_attrs.into()) + self.parse_expr_assoc_with(0, already_parsed_attrs.into()) } /// Parses an associative expression with operators of at least `min_prec` precedence. - pub(super) fn parse_assoc_expr_with( + pub(super) fn parse_expr_assoc_with( &mut self, min_prec: usize, lhs: LhsExpr, @@ -166,9 +167,9 @@ impl<'a> Parser<'a> { _ => None, }; if self.token.is_range_separator() { - return self.parse_prefix_range_expr(attrs); + return self.parse_expr_prefix_range(attrs); } else { - self.parse_prefix_expr(attrs)? + self.parse_expr_prefix(attrs)? } }; let last_type_ascription_set = self.last_type_ascription.is_some(); @@ -292,7 +293,7 @@ impl<'a> Parser<'a> { } else if op == AssocOp::DotDot || op == AssocOp::DotDotEq { // If we didn't have to handle `x..`/`x..=`, it would be pretty easy to // generalise it to the Fixity::None code. - lhs = self.parse_range_expr(prec, lhs, op, cur_op_span)?; + lhs = self.parse_expr_range(prec, lhs, op, cur_op_span)?; break; } @@ -305,7 +306,7 @@ impl<'a> Parser<'a> { Fixity::None => 1, }; let rhs = self.with_res(restrictions - Restrictions::STMT_EXPR, |this| { - this.parse_assoc_expr_with(prec + prec_adjustment, LhsExpr::NotYetParsed) + this.parse_expr_assoc_with(prec + prec_adjustment, LhsExpr::NotYetParsed) })?; let span = self.mk_expr_sp(&lhs, lhs_span, rhs.span); @@ -457,7 +458,7 @@ impl<'a> Parser<'a> { /// Parses `x..y`, `x..=y`, and `x..`/`x..=`. /// The other two variants are handled in `parse_prefix_range_expr` below. - fn parse_range_expr( + fn parse_expr_range( &mut self, prec: usize, lhs: P<Expr>, @@ -465,7 +466,7 @@ impl<'a> Parser<'a> { cur_op_span: Span, ) -> PResult<'a, P<Expr>> { let rhs = if self.is_at_start_of_range_notation_rhs() { - Some(self.parse_assoc_expr_with(prec + 1, LhsExpr::NotYetParsed)?) + Some(self.parse_expr_assoc_with(prec + 1, LhsExpr::NotYetParsed)?) } else { None }; @@ -490,7 +491,7 @@ impl<'a> Parser<'a> { } /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`. - fn parse_prefix_range_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { + fn parse_expr_prefix_range(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { // Check for deprecated `...` syntax. if self.token == token::DotDotDot { self.err_dotdotdot_syntax(self.token.span); @@ -517,7 +518,7 @@ impl<'a> Parser<'a> { this.bump(); let (span, opt_end) = if this.is_at_start_of_range_notation_rhs() { // RHS must be parsed with more associativity than the dots. - this.parse_assoc_expr_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed) + this.parse_expr_assoc_with(op.unwrap().precedence() + 1, LhsExpr::NotYetParsed) .map(|x| (lo.to(x.span), Some(x)))? } else { (lo, None) @@ -528,7 +529,7 @@ impl<'a> Parser<'a> { } /// Parses a prefix-unary-operator expr. - fn parse_prefix_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { + fn parse_expr_prefix(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { let attrs = self.parse_or_use_outer_attributes(attrs)?; let lo = self.token.span; @@ -546,20 +547,20 @@ impl<'a> Parser<'a> { // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr() match this.token.uninterpolate().kind { // `!expr` - token::Not => make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Not)), + token::Not => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)), // `~expr` token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)), // `-expr` token::BinOp(token::Minus) => { - make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Neg)) + make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Neg)) } // `*expr` token::BinOp(token::Star) => { - make_it!(this, attrs, |this, _| this.parse_unary_expr(lo, UnOp::Deref)) + make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Deref)) } // `&expr` and `&&expr` token::BinOp(token::And) | token::AndAnd => { - make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo)) + make_it!(this, attrs, |this, _| this.parse_expr_borrow(lo)) } // `+lit` token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => { @@ -578,7 +579,7 @@ impl<'a> Parser<'a> { this.sess.emit_err(err); this.bump(); - this.parse_prefix_expr(None) + this.parse_expr_prefix(None) } // Recover from `++x`: token::BinOp(token::Plus) @@ -591,28 +592,28 @@ impl<'a> Parser<'a> { this.bump(); this.bump(); - let operand_expr = this.parse_dot_or_call_expr(Default::default())?; + let operand_expr = this.parse_expr_dot_or_call(Default::default())?; this.recover_from_prefix_increment(operand_expr, pre_span, starts_stmt) } token::Ident(..) if this.token.is_keyword(kw::Box) => { - make_it!(this, attrs, |this, _| this.parse_box_expr(lo)) + make_it!(this, attrs, |this, _| this.parse_expr_box(lo)) } token::Ident(..) if this.may_recover() && this.is_mistaken_not_ident_negation() => { make_it!(this, attrs, |this, _| this.recover_not_expr(lo)) } - _ => return this.parse_dot_or_call_expr(Some(attrs)), + _ => return this.parse_expr_dot_or_call(Some(attrs)), } } - fn parse_prefix_expr_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> { + fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> { self.bump(); - let expr = self.parse_prefix_expr(None); + let expr = self.parse_expr_prefix(None); let (span, expr) = self.interpolated_or_expr_span(expr)?; Ok((lo.to(span), expr)) } - fn parse_unary_expr(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> { - let (span, expr) = self.parse_prefix_expr_common(lo)?; + fn parse_expr_unary(&mut self, lo: Span, op: UnOp) -> PResult<'a, (Span, ExprKind)> { + let (span, expr) = self.parse_expr_prefix_common(lo)?; Ok((span, self.mk_unary(op, expr))) } @@ -620,12 +621,12 @@ impl<'a> Parser<'a> { fn recover_tilde_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { self.sess.emit_err(errors::TildeAsUnaryOperator(lo)); - self.parse_unary_expr(lo, UnOp::Not) + self.parse_expr_unary(lo, UnOp::Not) } /// Parse `box expr`. - fn parse_box_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { - let (span, expr) = self.parse_prefix_expr_common(lo)?; + fn parse_expr_box(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { + let (span, expr) = self.parse_expr_prefix_common(lo)?; self.sess.gated_spans.gate(sym::box_syntax, span); Ok((span, ExprKind::Box(expr))) } @@ -663,7 +664,7 @@ impl<'a> Parser<'a> { ), }); - self.parse_unary_expr(lo, UnOp::Not) + self.parse_expr_unary(lo, UnOp::Not) } /// Returns the span of expr, if it was not interpolated or the span of the interpolated token. @@ -721,7 +722,7 @@ impl<'a> Parser<'a> { segments[0].ident.span, ), }; - match self.parse_labeled_expr(label, false) { + match self.parse_expr_labeled(label, false) { Ok(expr) => { type_err.cancel(); self.sess.emit_err(errors::MalformedLoopLabel { @@ -815,7 +816,7 @@ impl<'a> Parser<'a> { ("cast", None) }; - let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?; + let with_postfix = self.parse_expr_dot_or_call_with_(cast_expr, span)?; // Check if an illegal postfix operator has been added after the cast. // If the resulting expression is not a cast, it is an illegal postfix operator. @@ -886,15 +887,15 @@ impl<'a> Parser<'a> { } /// Parse `& mut? <expr>` or `& raw [ const | mut ] <expr>`. - fn parse_borrow_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { + fn parse_expr_borrow(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { self.expect_and()?; let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon); let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below. let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo); let expr = if self.token.is_range_separator() { - self.parse_prefix_range_expr(None) + self.parse_expr_prefix_range(None) } else { - self.parse_prefix_expr(None) + self.parse_expr_prefix(None) }; let (hi, expr) = self.interpolated_or_expr_span(expr)?; let span = lo.to(hi); @@ -924,16 +925,16 @@ impl<'a> Parser<'a> { } /// Parses `a.b` or `a(13)` or `a[4]` or just `a`. - fn parse_dot_or_call_expr(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { + fn parse_expr_dot_or_call(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { let attrs = self.parse_or_use_outer_attributes(attrs)?; self.collect_tokens_for_expr(attrs, |this, attrs| { - let base = this.parse_bottom_expr(); + let base = this.parse_expr_bottom(); let (span, base) = this.interpolated_or_expr_span(base)?; - this.parse_dot_or_call_expr_with(base, span, attrs) + this.parse_expr_dot_or_call_with(base, span, attrs) }) } - pub(super) fn parse_dot_or_call_expr_with( + pub(super) fn parse_expr_dot_or_call_with( &mut self, e0: P<Expr>, lo: Span, @@ -942,7 +943,7 @@ impl<'a> Parser<'a> { // Stitch the list of outer attributes onto the return value. // A little bit ugly, but the best way given the current code // structure - let res = self.parse_dot_or_call_expr_with_(e0, lo); + let res = self.parse_expr_dot_or_call_with_(e0, lo); if attrs.is_empty() { res } else { @@ -956,7 +957,7 @@ impl<'a> Parser<'a> { } } - fn parse_dot_or_call_expr_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> { + fn parse_expr_dot_or_call_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<'a, P<Expr>> { loop { let has_question = if self.prev_token.kind == TokenKind::Ident(kw::Return, false) { // we are using noexpect here because we don't expect a `?` directly after a `return` @@ -979,15 +980,15 @@ impl<'a> Parser<'a> { }; if has_dot { // expr.f - e = self.parse_dot_suffix_expr(lo, e)?; + e = self.parse_expr_dot_suffix(lo, e)?; continue; } if self.expr_is_complete(&e) { return Ok(e); } e = match self.token.kind { - token::OpenDelim(Delimiter::Parenthesis) => self.parse_fn_call_expr(lo, e), - token::OpenDelim(Delimiter::Bracket) => self.parse_index_expr(lo, e)?, + token::OpenDelim(Delimiter::Parenthesis) => self.parse_expr_fn_call(lo, e), + token::OpenDelim(Delimiter::Bracket) => self.parse_expr_index(lo, e)?, _ => return Ok(e), } } @@ -999,14 +1000,14 @@ impl<'a> Parser<'a> { && self.look_ahead(3, |t| t.can_begin_expr()) } - fn parse_dot_suffix_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { + fn parse_expr_dot_suffix(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { match self.token.uninterpolate().kind { token::Ident(..) => self.parse_dot_suffix(base, lo), token::Literal(token::Lit { kind: token::Integer, symbol, suffix }) => { - Ok(self.parse_tuple_field_access_expr(lo, base, symbol, suffix, None)) + Ok(self.parse_expr_tuple_field_access(lo, base, symbol, suffix, None)) } token::Literal(token::Lit { kind: token::Float, symbol, suffix }) => { - Ok(self.parse_tuple_field_access_expr_float(lo, base, symbol, suffix)) + Ok(self.parse_expr_tuple_field_access_float(lo, base, symbol, suffix)) } _ => { self.error_unexpected_after_dot(); @@ -1028,7 +1029,7 @@ impl<'a> Parser<'a> { // support pushing "future tokens" (would be also helpful to `break_and_eat`), or // we should break everything including floats into more basic proc-macro style // tokens in the lexer (probably preferable). - fn parse_tuple_field_access_expr_float( + fn parse_expr_tuple_field_access_float( &mut self, lo: Span, base: P<Expr>, @@ -1071,7 +1072,7 @@ impl<'a> Parser<'a> { match &*components { // 1e2 [IdentLike(i)] => { - self.parse_tuple_field_access_expr(lo, base, Symbol::intern(&i), suffix, None) + self.parse_expr_tuple_field_access(lo, base, Symbol::intern(&i), suffix, None) } // 1. [IdentLike(i), Punct('.')] => { @@ -1087,7 +1088,7 @@ impl<'a> Parser<'a> { let symbol = Symbol::intern(&i); self.token = Token::new(token::Ident(symbol, false), ident_span); let next_token = (Token::new(token::Dot, dot_span), self.token_spacing); - self.parse_tuple_field_access_expr(lo, base, symbol, None, Some(next_token)) + self.parse_expr_tuple_field_access(lo, base, symbol, None, Some(next_token)) } // 1.2 | 1.2e3 [IdentLike(i1), Punct('.'), IdentLike(i2)] => { @@ -1108,11 +1109,11 @@ impl<'a> Parser<'a> { // See issue #76399 and PR #76285 for more details let next_token1 = (Token::new(token::Dot, dot_span), Spacing::Alone); let base1 = - self.parse_tuple_field_access_expr(lo, base, symbol1, None, Some(next_token1)); + self.parse_expr_tuple_field_access(lo, base, symbol1, None, Some(next_token1)); let symbol2 = Symbol::intern(&i2); let next_token2 = Token::new(token::Ident(symbol2, false), ident2_span); self.bump_with((next_token2, self.token_spacing)); // `.` - self.parse_tuple_field_access_expr(lo, base1, symbol2, suffix, None) + self.parse_expr_tuple_field_access(lo, base1, symbol2, suffix, None) } // 1e+ | 1e- (recovered) [IdentLike(_), Punct('+' | '-')] | @@ -1130,7 +1131,7 @@ impl<'a> Parser<'a> { } } - fn parse_tuple_field_access_expr( + fn parse_expr_tuple_field_access( &mut self, lo: Span, base: P<Expr>, @@ -1151,7 +1152,7 @@ impl<'a> Parser<'a> { } /// Parse a function call expression, `expr(...)`. - fn parse_fn_call_expr(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> { + fn parse_expr_fn_call(&mut self, lo: Span, fun: P<Expr>) -> P<Expr> { let snapshot = if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) && self.look_ahead_type_ascription_as_field() { @@ -1162,7 +1163,7 @@ impl<'a> Parser<'a> { let open_paren = self.token.span; let mut seq = self - .parse_paren_expr_seq() + .parse_expr_paren_seq() .map(|args| self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args))); if let Some(expr) = self.maybe_recover_struct_lit_bad_delims(lo, open_paren, &mut seq, snapshot) @@ -1235,7 +1236,7 @@ impl<'a> Parser<'a> { } /// Parse an indexing expression `expr[...]`. - fn parse_index_expr(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { + fn parse_expr_index(&mut self, lo: Span, base: P<Expr>) -> PResult<'a, P<Expr>> { let prev_span = self.prev_token.span; let open_delim_span = self.token.span; self.bump(); // `[` @@ -1258,7 +1259,7 @@ impl<'a> Parser<'a> { if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Method call `expr.f()` - let args = self.parse_paren_expr_seq()?; + let args = self.parse_expr_paren_seq()?; let fn_span = fn_span_lo.to(self.prev_token.span); let span = lo.to(self.prev_token.span); Ok(self.mk_expr( @@ -1286,7 +1287,7 @@ impl<'a> Parser<'a> { /// /// N.B., this does not parse outer attributes, and is private because it only works /// correctly if called from `parse_dot_or_call_expr()`. - fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_bottom(&mut self) -> PResult<'a, P<Expr>> { maybe_recover_from_interpolated_ty_qpath!(self, true); maybe_whole_expr!(self); @@ -1299,13 +1300,13 @@ impl<'a> Parser<'a> { // This match arm is a special-case of the `_` match arm below and // could be removed without changing functionality, but it's faster // to have it here, especially for programs with large constants. - self.parse_lit_expr() + self.parse_expr_lit() } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { - self.parse_tuple_parens_expr() + self.parse_expr_tuple_parens() } else if self.check(&token::OpenDelim(Delimiter::Brace)) { - self.parse_block_expr(None, lo, BlockCheckMode::Default) + self.parse_expr_block(None, lo, BlockCheckMode::Default) } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) { - self.parse_closure_expr().map_err(|mut err| { + self.parse_expr_closure().map_err(|mut err| { // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }` // then suggest parens around the lhs. if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) { @@ -1314,42 +1315,42 @@ impl<'a> Parser<'a> { err }) } else if self.check(&token::OpenDelim(Delimiter::Bracket)) { - self.parse_array_or_repeat_expr(Delimiter::Bracket) + self.parse_expr_array_or_repeat(Delimiter::Bracket) } else if self.check_path() { - self.parse_path_start_expr() + self.parse_expr_path_start() } else if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) || self.check_const_closure() { - self.parse_closure_expr() + self.parse_expr_closure() } else if self.eat_keyword(kw::If) { - self.parse_if_expr() + self.parse_expr_if() } else if self.check_keyword(kw::For) { if self.choose_generics_over_qpath(1) { - self.parse_closure_expr() + self.parse_expr_closure() } else { assert!(self.eat_keyword(kw::For)); - self.parse_for_expr(None, self.prev_token.span) + self.parse_expr_for(None, self.prev_token.span) } } else if self.eat_keyword(kw::While) { - self.parse_while_expr(None, self.prev_token.span) + self.parse_expr_while(None, self.prev_token.span) } else if let Some(label) = self.eat_label() { - self.parse_labeled_expr(label, true) + self.parse_expr_labeled(label, true) } else if self.eat_keyword(kw::Loop) { let sp = self.prev_token.span; - self.parse_loop_expr(None, self.prev_token.span).map_err(|mut err| { + self.parse_expr_loop(None, self.prev_token.span).map_err(|mut err| { err.span_label(sp, "while parsing this `loop` expression"); err }) } else if self.eat_keyword(kw::Match) { let match_sp = self.prev_token.span; - self.parse_match_expr().map_err(|mut err| { + self.parse_expr_match().map_err(|mut err| { err.span_label(match_sp, "while parsing this `match` expression"); err }) } else if self.eat_keyword(kw::Unsafe) { let sp = self.prev_token.span; - self.parse_block_expr(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err( + self.parse_expr_block(None, lo, BlockCheckMode::Unsafe(ast::UserProvided)).map_err( |mut err| { err.span_label(sp, "while parsing this `unsafe` expression"); err @@ -1363,17 +1364,17 @@ impl<'a> Parser<'a> { self.expect_keyword(kw::Try)?; self.parse_try_block(lo) } else if self.eat_keyword(kw::Return) { - self.parse_return_expr() + self.parse_expr_return() } else if self.eat_keyword(kw::Continue) { - self.parse_continue_expr(lo) + self.parse_expr_continue(lo) } else if self.eat_keyword(kw::Break) { - self.parse_break_expr() + self.parse_expr_break() } else if self.eat_keyword(kw::Yield) { - self.parse_yield_expr() + self.parse_expr_yield() } else if self.is_do_yeet() { - self.parse_yeet_expr() + self.parse_expr_yeet() } else if self.check_keyword(kw::Let) { - self.parse_let_expr() + self.parse_expr_let() } else if self.eat_keyword(kw::Underscore) { Ok(self.mk_expr(self.prev_token.span, ExprKind::Underscore)) } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) { @@ -1396,19 +1397,19 @@ impl<'a> Parser<'a> { // Check for `async {` and `async move {`. self.parse_async_block() } else { - self.parse_closure_expr() + self.parse_expr_closure() } } else if self.eat_keyword(kw::Await) { self.recover_incorrect_await_syntax(lo, self.prev_token.span) } else { - self.parse_lit_expr() + self.parse_expr_lit() } } else { - self.parse_lit_expr() + self.parse_expr_lit() } } - fn parse_lit_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_lit(&mut self) -> PResult<'a, P<Expr>> { let lo = self.token.span; match self.parse_opt_token_lit() { Some((token_lit, _)) => { @@ -1419,7 +1420,7 @@ impl<'a> Parser<'a> { } } - fn parse_tuple_parens_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_tuple_parens(&mut self) -> PResult<'a, P<Expr>> { let lo = self.token.span; self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; let (es, trailing_comma) = match self.parse_seq_to_end( @@ -1443,20 +1444,20 @@ impl<'a> Parser<'a> { self.maybe_recover_from_bad_qpath(expr) } - fn parse_array_or_repeat_expr(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> { + fn parse_expr_array_or_repeat(&mut self, close_delim: Delimiter) -> PResult<'a, P<Expr>> { let lo = self.token.span; self.bump(); // `[` or other open delim let close = &token::CloseDelim(close_delim); let kind = if self.eat(close) { // Empty vector - ExprKind::Array(Vec::new()) + ExprKind::Array(ThinVec::new()) } else { // Non-empty vector let first_expr = self.parse_expr()?; if self.eat(&token::Semi) { // Repeating array syntax: `[ 0; 512 ]` - let count = self.parse_anon_const_expr()?; + let count = self.parse_expr_anon_const()?; self.expect(close)?; ExprKind::Repeat(first_expr, count) } else if self.eat(&token::Comma) { @@ -1468,14 +1469,14 @@ impl<'a> Parser<'a> { } else { // Vector with one element self.expect(close)?; - ExprKind::Array(vec![first_expr]) + ExprKind::Array(thin_vec![first_expr]) } }; let expr = self.mk_expr(lo.to(self.prev_token.span), kind); self.maybe_recover_from_bad_qpath(expr) } - fn parse_path_start_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_path_start(&mut self) -> PResult<'a, P<Expr>> { let (qself, path) = if self.eat_lt() { let (qself, path) = self.parse_qpath(PathStyle::Expr)?; (Some(qself), path) @@ -1512,7 +1513,7 @@ impl<'a> Parser<'a> { } /// Parse `'label: $expr`. The label is already parsed. - fn parse_labeled_expr( + fn parse_expr_labeled( &mut self, label_: Label, mut consume_colon: bool, @@ -1521,15 +1522,15 @@ impl<'a> Parser<'a> { let label = Some(label_); let ate_colon = self.eat(&token::Colon); let expr = if self.eat_keyword(kw::While) { - self.parse_while_expr(label, lo) + self.parse_expr_while(label, lo) } else if self.eat_keyword(kw::For) { - self.parse_for_expr(label, lo) + self.parse_expr_for(label, lo) } else if self.eat_keyword(kw::Loop) { - self.parse_loop_expr(label, lo) + self.parse_expr_loop(label, lo) } else if self.check_noexpect(&token::OpenDelim(Delimiter::Brace)) || self.token.is_whole_block() { - self.parse_block_expr(label, lo, BlockCheckMode::Default) + self.parse_expr_block(label, lo, BlockCheckMode::Default) } else if !ate_colon && self.may_recover() && (matches!(self.token.kind, token::CloseDelim(_) | token::Comma) @@ -1600,7 +1601,7 @@ impl<'a> Parser<'a> { // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to suppress future errors about `break 'label`. let stmt = self.mk_stmt(span, StmtKind::Expr(expr)); - let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span); + let blk = self.mk_block(thin_vec![stmt], BlockCheckMode::Default, span); self.mk_expr(span, ExprKind::Block(blk, label)) }); @@ -1669,7 +1670,7 @@ impl<'a> Parser<'a> { } /// Parse `"return" expr?`. - fn parse_return_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_return(&mut self) -> PResult<'a, P<Expr>> { let lo = self.prev_token.span; let kind = ExprKind::Ret(self.parse_expr_opt()?); let expr = self.mk_expr(lo.to(self.prev_token.span), kind); @@ -1677,7 +1678,7 @@ impl<'a> Parser<'a> { } /// Parse `"do" "yeet" expr?`. - fn parse_yeet_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_yeet(&mut self) -> PResult<'a, P<Expr>> { let lo = self.token.span; self.bump(); // `do` @@ -1699,13 +1700,13 @@ impl<'a> Parser<'a> { /// `break 'lbl: loop {}`); a labeled break with an unlabeled loop as its value /// expression only gets a warning for compatibility reasons; and a labeled break /// with a labeled loop does not even get a warning because there is no ambiguity. - fn parse_break_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_break(&mut self) -> PResult<'a, P<Expr>> { let lo = self.prev_token.span; let mut label = self.eat_label(); let kind = if self.token == token::Colon && let Some(label) = label.take() { // The value expression can be a labeled loop, see issue #86948, e.g.: // `loop { break 'label: loop { break 'label 42; }; }` - let lexpr = self.parse_labeled_expr(label, true)?; + let lexpr = self.parse_expr_labeled(label, true)?; self.sess.emit_err(errors::LabeledLoopInBreak { span: lexpr.span, sub: errors::WrapExpressionInParentheses { @@ -1758,7 +1759,7 @@ impl<'a> Parser<'a> { } /// Parse `"continue" label?`. - fn parse_continue_expr(&mut self, lo: Span) -> PResult<'a, P<Expr>> { + fn parse_expr_continue(&mut self, lo: Span) -> PResult<'a, P<Expr>> { let mut label = self.eat_label(); // Recover `continue label` -> `continue 'label` @@ -1775,7 +1776,7 @@ impl<'a> Parser<'a> { } /// Parse `"yield" expr?`. - fn parse_yield_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_yield(&mut self) -> PResult<'a, P<Expr>> { let lo = self.prev_token.span; let kind = ExprKind::Yield(self.parse_expr_opt()?); let span = lo.to(self.prev_token.span); @@ -1992,7 +1993,7 @@ impl<'a> Parser<'a> { /// expression. fn maybe_suggest_brackets_instead_of_braces(&mut self, lo: Span) -> Option<P<Expr>> { let mut snapshot = self.create_snapshot_for_diagnostic(); - match snapshot.parse_array_or_repeat_expr(Delimiter::Brace) { + match snapshot.parse_expr_array_or_repeat(Delimiter::Brace) { Ok(arr) => { self.sess.emit_err(errors::ArrayBracketsInsteadOfSpaces { span: arr.span, @@ -2055,7 +2056,7 @@ impl<'a> Parser<'a> { } /// Parses a block or unsafe block. - pub(super) fn parse_block_expr( + pub(super) fn parse_expr_block( &mut self, opt_label: Option<Label>, lo: Span, @@ -2085,7 +2086,7 @@ impl<'a> Parser<'a> { } /// Parses a closure expression (e.g., `move |args| expr`). - fn parse_closure_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_closure(&mut self) -> PResult<'a, P<Expr>> { let lo = self.token.span; let binder = if self.check_keyword(kw::For) { @@ -2095,7 +2096,7 @@ impl<'a> Parser<'a> { self.sess.gated_spans.gate(sym::closure_lifetime_binder, span); - ClosureBinder::For { span, generic_params: P::from_vec(lifetime_defs) } + ClosureBinder::For { span, generic_params: lifetime_defs } } else { ClosureBinder::NotPresent }; @@ -2122,7 +2123,7 @@ impl<'a> Parser<'a> { _ => { // If an explicit return type is given, require a block to appear (RFC 968). let body_lo = self.token.span; - self.parse_block_expr(None, body_lo, BlockCheckMode::Default)? + self.parse_expr_block(None, body_lo, BlockCheckMode::Default)? } }; @@ -2187,7 +2188,7 @@ impl<'a> Parser<'a> { let arg_start = self.token.span.lo(); let inputs = if self.eat(&token::OrOr) { - Vec::new() + ThinVec::new() } else { self.expect(&token::BinOp(token::Or))?; let args = self @@ -2235,9 +2236,9 @@ impl<'a> Parser<'a> { } /// Parses an `if` expression (`if` token already eaten). - fn parse_if_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_if(&mut self) -> PResult<'a, P<Expr>> { let lo = self.prev_token.span; - let cond = self.parse_cond_expr()?; + let cond = self.parse_expr_cond()?; self.parse_if_after_cond(lo, cond) } @@ -2315,12 +2316,12 @@ impl<'a> Parser<'a> { self.error_on_if_block_attrs(lo, false, block.span, attrs); block }; - let els = if self.eat_keyword(kw::Else) { Some(self.parse_else_expr()?) } else { None }; + let els = if self.eat_keyword(kw::Else) { Some(self.parse_expr_else()?) } else { None }; Ok(self.mk_expr(lo.to(self.prev_token.span), ExprKind::If(cond, thn, els))) } /// Parses the condition of a `if` or `while` expression. - fn parse_cond_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_cond(&mut self) -> PResult<'a, P<Expr>> { let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL | Restrictions::ALLOW_LET, None)?; @@ -2333,7 +2334,7 @@ impl<'a> Parser<'a> { } /// Parses a `let $pat = $expr` pseudo-expression. - fn parse_let_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_let(&mut self) -> PResult<'a, P<Expr>> { // This is a *approximate* heuristic that detects if `let` chains are // being parsed in the right position. It's approximate because it // doesn't deny all invalid `let` expressions, just completely wrong usages. @@ -2363,7 +2364,7 @@ impl<'a> Parser<'a> { self.expect(&token::Eq)?; } let expr = self.with_res(self.restrictions | Restrictions::NO_STRUCT_LITERAL, |this| { - this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) + this.parse_expr_assoc_with(1 + prec_let_scrutinee_needs_par(), None.into()) })?; let span = lo.to(expr.span); self.sess.gated_spans.gate(sym::let_chains, span); @@ -2371,11 +2372,11 @@ impl<'a> Parser<'a> { } /// Parses an `else { ... }` expression (`else` token already eaten). - fn parse_else_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_else(&mut self) -> PResult<'a, P<Expr>> { let else_span = self.prev_token.span; // `else` let attrs = self.parse_outer_attributes()?; // For recovery. let expr = if self.eat_keyword(kw::If) { - self.parse_if_expr()? + self.parse_expr_if()? } else if self.check(&TokenKind::OpenDelim(Delimiter::Brace)) { self.parse_simple_block()? } else { @@ -2449,7 +2450,7 @@ impl<'a> Parser<'a> { } /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten). - fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { + fn parse_expr_for(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { // Record whether we are about to parse `for (`. // This is used below for recovery in case of `for ( $stuff ) $block` // in which case we will suggest `for $stuff $block`. @@ -2480,7 +2481,7 @@ impl<'a> Parser<'a> { self.sess .emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() }); let err_expr = self.mk_expr(expr.span, ExprKind::Err); - let block = self.mk_block(vec![], BlockCheckMode::Default, self.prev_token.span); + let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span); return Ok(self.mk_expr( lo.to(self.prev_token.span), ExprKind::ForLoop(pat, err_expr, block, opt_label), @@ -2507,8 +2508,8 @@ impl<'a> Parser<'a> { } /// Parses a `while` or `while let` expression (`while` token already eaten). - fn parse_while_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { - let cond = self.parse_cond_expr().map_err(|mut err| { + fn parse_expr_while(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { + let cond = self.parse_expr_cond().map_err(|mut err| { err.span_label(lo, "while parsing the condition of this `while` expression"); err })?; @@ -2525,7 +2526,7 @@ impl<'a> Parser<'a> { } /// Parses `loop { ... }` (`loop` token already eaten). - fn parse_loop_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { + fn parse_expr_loop(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { let loop_span = self.prev_token.span; let (attrs, body) = self.parse_inner_attrs_and_block()?; Ok(self.mk_expr_with_attrs( @@ -2543,7 +2544,7 @@ impl<'a> Parser<'a> { } /// Parses a `match ... { ... }` expression (`match` token already eaten). - fn parse_match_expr(&mut self) -> PResult<'a, P<Expr>> { + fn parse_expr_match(&mut self) -> PResult<'a, P<Expr>> { let match_span = self.prev_token.span; let lo = self.prev_token.span; let scrutinee = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; @@ -2565,7 +2566,7 @@ impl<'a> Parser<'a> { } let attrs = self.parse_inner_attributes()?; - let mut arms: Vec<Arm> = Vec::new(); + let mut arms = ThinVec::new(); while self.token != token::CloseDelim(Delimiter::Brace) { match self.parse_arm() { Ok(arm) => arms.push(arm), @@ -2913,7 +2914,7 @@ impl<'a> Parser<'a> { if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) { return Some(Err(err)); } - let expr = self.parse_struct_expr(qself.clone(), path.clone(), true); + let expr = self.parse_expr_struct(qself.clone(), path.clone(), true); if let (Ok(expr), false) = (&expr, struct_allowed) { // This is a struct literal, but we don't can't accept them here. self.sess.emit_err(errors::StructLiteralNotAllowedHere { @@ -2934,8 +2935,8 @@ impl<'a> Parser<'a> { pth: ast::Path, recover: bool, close_delim: Delimiter, - ) -> PResult<'a, (Vec<ExprField>, ast::StructRest, bool)> { - let mut fields = Vec::new(); + ) -> PResult<'a, (ThinVec<ExprField>, ast::StructRest, bool)> { + let mut fields = ThinVec::new(); let mut base = ast::StructRest::None; let mut recover_async = false; @@ -3042,7 +3043,7 @@ impl<'a> Parser<'a> { } /// Precondition: already parsed the '{'. - pub(super) fn parse_struct_expr( + pub(super) fn parse_expr_struct( &mut self, qself: Option<P<ast::QSelf>>, pth: ast::Path, @@ -3211,7 +3212,7 @@ impl<'a> Parser<'a> { ExprKind::Index(expr, idx) } - fn mk_call(&self, f: P<Expr>, args: Vec<P<Expr>>) -> ExprKind { + fn mk_call(&self, f: P<Expr>, args: ThinVec<P<Expr>>) -> ExprKind { ExprKind::Call(f, args) } diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 23f49ec55a1..8d0f168e09d 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -14,10 +14,11 @@ use rustc_ast::{ use rustc_errors::{Applicability, PResult}; use rustc_span::symbol::{kw, Ident}; use rustc_span::Span; +use thin_vec::ThinVec; enum PredicateOrStructBody { Predicate(ast::WherePredicate), - StructBody(Vec<ast::FieldDef>), + StructBody(ThinVec<ast::FieldDef>), } impl<'a> Parser<'a> { @@ -121,8 +122,8 @@ impl<'a> Parser<'a> { /// Parses a (possibly empty) list of lifetime and type parameters, possibly including /// a trailing comma and erroneous trailing attributes. - pub(super) fn parse_generic_params(&mut self) -> PResult<'a, Vec<ast::GenericParam>> { - let mut params = Vec::new(); + pub(super) fn parse_generic_params(&mut self) -> PResult<'a, ThinVec<ast::GenericParam>> { + let mut params = ThinVec::new(); let mut done = false; while !done { let attrs = self.parse_outer_attributes()?; @@ -251,13 +252,13 @@ impl<'a> Parser<'a> { self.expect_gt()?; (params, span_lo.to(self.prev_token.span)) } else { - (vec![], self.prev_token.span.shrink_to_hi()) + (ThinVec::new(), self.prev_token.span.shrink_to_hi()) }; Ok(ast::Generics { params, where_clause: WhereClause { has_where_token: false, - predicates: Vec::new(), + predicates: ThinVec::new(), span: self.prev_token.span.shrink_to_hi(), }, span, @@ -277,17 +278,17 @@ impl<'a> Parser<'a> { &mut self, struct_name: Ident, body_insertion_point: Span, - ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> { + ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> { self.parse_where_clause_common(Some((struct_name, body_insertion_point))) } fn parse_where_clause_common( &mut self, struct_: Option<(Ident, Span)>, - ) -> PResult<'a, (WhereClause, Option<Vec<ast::FieldDef>>)> { + ) -> PResult<'a, (WhereClause, Option<ThinVec<ast::FieldDef>>)> { let mut where_clause = WhereClause { has_where_token: false, - predicates: Vec::new(), + predicates: ThinVec::new(), span: self.prev_token.span.shrink_to_hi(), }; let mut tuple_struct_body = None; diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index f164bb330f3..9d9ae154ad4 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -26,7 +26,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; use std::fmt::Write; use std::mem; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. @@ -56,12 +56,12 @@ impl<'a> Parser<'a> { pub fn parse_mod( &mut self, term: &TokenKind, - ) -> PResult<'a, (AttrVec, Vec<P<Item>>, ModSpans)> { + ) -> PResult<'a, (AttrVec, ThinVec<P<Item>>, ModSpans)> { let lo = self.token.span; let attrs = self.parse_inner_attributes()?; let post_attr_lo = self.token.span; - let mut items = vec![]; + let mut items = ThinVec::new(); while let Some(item) = self.parse_item(ForceCollect::No)? { items.push(item); self.maybe_consume_incorrect_semicolon(&items); @@ -646,20 +646,20 @@ impl<'a> Parser<'a> { &mut self, attrs: &mut AttrVec, mut parse_item: impl FnMut(&mut Parser<'a>) -> PResult<'a, Option<Option<T>>>, - ) -> PResult<'a, Vec<T>> { + ) -> PResult<'a, ThinVec<T>> { let open_brace_span = self.token.span; // Recover `impl Ty;` instead of `impl Ty {}` if self.token == TokenKind::Semi { self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span }); self.bump(); - return Ok(vec![]); + return Ok(ThinVec::new()); } self.expect(&token::OpenDelim(Delimiter::Brace))?; attrs.extend(self.parse_inner_attributes()?); - let mut items = Vec::new(); + let mut items = ThinVec::new(); while !self.eat(&token::CloseDelim(Delimiter::Brace)) { if self.recover_doc_comment_before_brace() { continue; @@ -997,7 +997,7 @@ impl<'a> Parser<'a> { /// ```text /// USE_TREE_LIST = Ø | (USE_TREE `,`)* USE_TREE [`,`] /// ``` - fn parse_use_tree_list(&mut self) -> PResult<'a, Vec<(UseTree, ast::NodeId)>> { + fn parse_use_tree_list(&mut self) -> PResult<'a, ThinVec<(UseTree, ast::NodeId)>> { self.parse_delim_comma_seq(Delimiter::Brace, |p| { p.recover_diff_marker(); Ok((p.parse_use_tree()?, DUMMY_NODE_ID)) @@ -1288,7 +1288,7 @@ impl<'a> Parser<'a> { let (variants, _) = if self.token == TokenKind::Semi { self.sess.emit_err(errors::UseEmptyBlockNotSemi { span: self.token.span }); self.bump(); - (vec![], false) + (thin_vec![], false) } else { self.parse_delim_comma_seq(Delimiter::Brace, |p| p.parse_enum_variant()).map_err( |mut e| { @@ -1331,7 +1331,7 @@ impl<'a> Parser<'a> { }; let disr_expr = - if this.eat(&token::Eq) { Some(this.parse_anon_const_expr()?) } else { None }; + if this.eat(&token::Eq) { Some(this.parse_expr_anon_const()?) } else { None }; let vr = ast::Variant { ident, @@ -1457,8 +1457,8 @@ impl<'a> Parser<'a> { adt_ty: &str, ident_span: Span, parsed_where: bool, - ) -> PResult<'a, (Vec<FieldDef>, /* recovered */ bool)> { - let mut fields = Vec::new(); + ) -> PResult<'a, (ThinVec<FieldDef>, /* recovered */ bool)> { + let mut fields = ThinVec::new(); let mut recovered = false; if self.eat(&token::OpenDelim(Delimiter::Brace)) { while self.token != token::CloseDelim(Delimiter::Brace) { @@ -1498,7 +1498,7 @@ impl<'a> Parser<'a> { Ok((fields, recovered)) } - pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, Vec<FieldDef>> { + pub(super) fn parse_tuple_struct_body(&mut self) -> PResult<'a, ThinVec<FieldDef>> { // This is the case where we find `struct Foo<T>(T) where T: Copy;` // Unit like structs are handled in parse_item_struct function self.parse_paren_comma_seq(|p| { @@ -1722,7 +1722,7 @@ impl<'a> Parser<'a> { } if self.token.kind == token::Eq { self.bump(); - let const_expr = self.parse_anon_const_expr()?; + let const_expr = self.parse_expr_anon_const()?; let sp = ty.span.shrink_to_hi().to(const_expr.value.span); self.struct_span_err(sp, "default values on `struct` fields aren't supported") .span_suggestion( @@ -2374,7 +2374,7 @@ impl<'a> Parser<'a> { } /// Parses the parameter list of a function, including the `(` and `)` delimiters. - pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, Vec<Param>> { + pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec<Param>> { let mut first_param = true; // Parse the arguments, starting out with `self` being allowed... let (mut params, _) = self.parse_paren_comma_seq(|p| { diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index a74f408d774..fda9151478f 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -36,9 +36,10 @@ use rustc_errors::{ use rustc_session::parse::ParseSess; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; - use std::ops::Range; use std::{cmp, mem, slice}; +use thin_vec::ThinVec; +use tracing::debug; use crate::errors::{ DocCommentDoesNotDocumentAnything, IncorrectVisibilityRestriction, MismatchedClosingDelimiter, @@ -853,11 +854,11 @@ impl<'a> Parser<'a> { sep: SeqSep, expect: TokenExpectType, mut f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool /* trailing */, bool /* recovered */)> { + ) -> PResult<'a, (ThinVec<T>, bool /* trailing */, bool /* recovered */)> { let mut first = true; let mut recovered = false; let mut trailing = false; - let mut v = vec![]; + let mut v = ThinVec::new(); let unclosed_delims = !self.unclosed_delims.is_empty(); while !self.expect_any_with_type(kets, expect) { @@ -981,7 +982,11 @@ impl<'a> Parser<'a> { let initial_semicolon = self.token.span; while self.eat(&TokenKind::Semi) { - let _ = self.parse_stmt(ForceCollect::Yes)?; + let _ = + self.parse_stmt_without_recovery(false, ForceCollect::Yes).unwrap_or_else(|e| { + e.cancel(); + None + }); } expect_err.set_primary_message( @@ -1037,7 +1042,7 @@ impl<'a> Parser<'a> { ket: &TokenKind, sep: SeqSep, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool, bool)> { + ) -> PResult<'a, (ThinVec<T>, bool, bool)> { self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f) } @@ -1049,7 +1054,7 @@ impl<'a> Parser<'a> { ket: &TokenKind, sep: SeqSep, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool /* trailing */)> { + ) -> PResult<'a, (ThinVec<T>, bool /* trailing */)> { let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?; if !recovered { self.eat(ket); @@ -1066,7 +1071,7 @@ impl<'a> Parser<'a> { ket: &TokenKind, sep: SeqSep, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool)> { + ) -> PResult<'a, (ThinVec<T>, bool)> { self.expect(bra)?; self.parse_seq_to_end(ket, sep, f) } @@ -1075,7 +1080,7 @@ impl<'a> Parser<'a> { &mut self, delim: Delimiter, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool)> { + ) -> PResult<'a, (ThinVec<T>, bool)> { self.parse_unspanned_seq( &token::OpenDelim(delim), &token::CloseDelim(delim), @@ -1087,7 +1092,7 @@ impl<'a> Parser<'a> { fn parse_paren_comma_seq<T>( &mut self, f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>, - ) -> PResult<'a, (Vec<T>, bool)> { + ) -> PResult<'a, (ThinVec<T>, bool)> { self.parse_delim_comma_seq(Delimiter::Parenthesis, f) } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index b054dc59a0c..8e920f1c421 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -8,6 +8,7 @@ use crate::errors::{ TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, }; +use crate::fluent_generated as fluent; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; use rustc_ast::mut_visit::{noop_visit_pat, MutVisitor}; use rustc_ast::ptr::P; @@ -17,12 +18,11 @@ use rustc_ast::{ PatField, PatKind, Path, QSelf, RangeEnd, RangeSyntax, }; use rustc_ast_pretty::pprust; -use rustc_errors::{ - fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult, -}; +use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, IntoDiagnostic, PResult}; use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::{respan, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident}; +use thin_vec::{thin_vec, ThinVec}; #[derive(PartialEq, Copy, Clone)] pub enum Expected { @@ -155,7 +155,7 @@ impl<'a> Parser<'a> { // If there was a leading vert, treat this as an or-pattern. This improves // diagnostics. let span = leading_vert_span.to(self.prev_token.span); - return Ok((self.mk_pat(span, PatKind::Or(vec![first_pat])), trailing_vert)); + return Ok((self.mk_pat(span, PatKind::Or(thin_vec![first_pat])), trailing_vert)); } return Ok((first_pat, trailing_vert)); @@ -163,7 +163,7 @@ impl<'a> Parser<'a> { // Parse the patterns `p_1 | ... | p_n` where `n > 0`. let lo = leading_vert_span.unwrap_or(first_pat.span); - let mut pats = vec![first_pat]; + let mut pats = thin_vec![first_pat]; loop { match self.eat_or_separator(Some(lo)) { EatOrResult::AteOr => {} @@ -853,7 +853,7 @@ impl<'a> Parser<'a> { e.span_label(path.span, "while parsing the fields for this pattern"); e.emit(); self.recover_stmt(); - (vec![], true) + (ThinVec::new(), true) }); self.bump(); Ok(PatKind::Struct(qself, path, fields, etc)) @@ -932,8 +932,8 @@ impl<'a> Parser<'a> { } /// Parses the fields of a struct-like pattern. - fn parse_pat_fields(&mut self) -> PResult<'a, (Vec<PatField>, bool)> { - let mut fields = Vec::new(); + fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, bool)> { + let mut fields = ThinVec::new(); let mut etc = false; let mut ate_comma = true; let mut delayed_err: Option<DiagnosticBuilder<'a, ErrorGuaranteed>> = None; diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 49959a8981c..b50d2984a4e 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -332,7 +332,7 @@ impl<'a> Parser<'a> { style: PathStyle, lo: Span, ty_generics: Option<&Generics>, - ) -> PResult<'a, Vec<AngleBracketedArg>> { + ) -> PResult<'a, ThinVec<AngleBracketedArg>> { // We need to detect whether there are extra leading left angle brackets and produce an // appropriate error and suggestion. This cannot be implemented by looking ahead at // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens @@ -472,8 +472,8 @@ impl<'a> Parser<'a> { pub(super) fn parse_angle_args( &mut self, ty_generics: Option<&Generics>, - ) -> PResult<'a, Vec<AngleBracketedArg>> { - let mut args = Vec::new(); + ) -> PResult<'a, ThinVec<AngleBracketedArg>> { + let mut args = ThinVec::new(); while let Some(arg) = self.parse_angle_arg(ty_generics)? { args.push(arg); if !self.eat(&token::Comma) { @@ -653,7 +653,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_const_arg(&mut self) -> PResult<'a, AnonConst> { // Parse const argument. let value = if let token::OpenDelim(Delimiter::Brace) = self.token.kind { - self.parse_block_expr(None, self.token.span, BlockCheckMode::Default)? + self.parse_expr_block(None, self.token.span, BlockCheckMode::Default)? } else { self.handle_unambiguous_unbraced_const_arg()? }; diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 3afda5f69f0..92a22ffc2b0 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -20,8 +20,8 @@ use rustc_ast::{StmtKind, DUMMY_NODE_ID}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym}; - use std::mem; +use thin_vec::{thin_vec, ThinVec}; impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. @@ -146,14 +146,14 @@ impl<'a> Parser<'a> { } let expr = if this.eat(&token::OpenDelim(Delimiter::Brace)) { - this.parse_struct_expr(None, path, true)? + this.parse_expr_struct(None, path, true)? } else { let hi = this.prev_token.span; this.mk_expr(lo.to(hi), ExprKind::Path(None, path)) }; let expr = this.with_res(Restrictions::STMT_EXPR, |this| { - this.parse_dot_or_call_expr_with(expr, lo, attrs) + this.parse_expr_dot_or_call_with(expr, lo, attrs) })?; // `DUMMY_SP` will get overwritten later in this function Ok((this.mk_stmt(rustc_span::DUMMY_SP, StmtKind::Expr(expr)), TrailingToken::None)) @@ -163,7 +163,7 @@ impl<'a> Parser<'a> { // Perform this outside of the `collect_tokens_trailing_token` closure, // since our outer attributes do not apply to this part of the expression let expr = self.with_res(Restrictions::STMT_EXPR, |this| { - this.parse_assoc_expr_with( + this.parse_expr_assoc_with( 0, LhsExpr::AlreadyParsed { expr, starts_statement: true }, ) @@ -199,8 +199,8 @@ impl<'a> Parser<'a> { // Since none of the above applied, this is an expression statement macro. let e = self.mk_expr(lo.to(hi), ExprKind::MacCall(mac)); let e = self.maybe_recover_from_bad_qpath(e)?; - let e = self.parse_dot_or_call_expr_with(e, lo, attrs)?; - let e = self.parse_assoc_expr_with( + let e = self.parse_expr_dot_or_call_with(e, lo, attrs)?; + let e = self.parse_expr_assoc_with( 0, LhsExpr::AlreadyParsed { expr: e, starts_statement: false }, )?; @@ -544,7 +544,7 @@ impl<'a> Parser<'a> { s: BlockCheckMode, recover: AttemptLocalParseRecovery, ) -> PResult<'a, P<Block>> { - let mut stmts = vec![]; + let mut stmts = ThinVec::new(); let mut snapshot = None; while !self.eat(&token::CloseDelim(Delimiter::Brace)) { if self.token == token::Eof { @@ -662,7 +662,12 @@ impl<'a> Parser<'a> { Ok(Some(stmt)) } - pub(super) fn mk_block(&self, stmts: Vec<Stmt>, rules: BlockCheckMode, span: Span) -> P<Block> { + pub(super) fn mk_block( + &self, + stmts: ThinVec<Stmt>, + rules: BlockCheckMode, + span: Span, + ) -> P<Block> { P(Block { stmts, id: DUMMY_NODE_ID, @@ -682,6 +687,6 @@ impl<'a> Parser<'a> { } pub(super) fn mk_block_err(&self, span: Span) -> P<Block> { - self.mk_block(vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span) + self.mk_block(thin_vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span) } } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 4f4252b532e..6fe4da71f6b 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -21,7 +21,7 @@ use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; /// Any `?` or `~const` modifiers that appear at the start of a bound. struct BoundModifiers { @@ -273,7 +273,7 @@ impl<'a> Parser<'a> { TyKind::Infer } else if self.check_fn_front_matter(false, Case::Sensitive) { // Function pointer type - self.parse_ty_bare_fn(lo, Vec::new(), None, recover_return_sign)? + self.parse_ty_bare_fn(lo, ThinVec::new(), None, recover_return_sign)? } else if self.check_keyword(kw::For) { // Function pointer type or bound list (trait object type) starting with a poly-trait. // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T` @@ -352,7 +352,7 @@ impl<'a> Parser<'a> { match ty.kind { // `(TY_BOUND_NOPAREN) + BOUND + ...`. TyKind::Path(None, path) if maybe_bounds => { - self.parse_remaining_bounds_path(Vec::new(), path, lo, true) + self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true) } TyKind::TraitObject(bounds, TraitObjectSyntax::None) if maybe_bounds && bounds.len() == 1 && !trailing_plus => @@ -378,7 +378,7 @@ impl<'a> Parser<'a> { fn parse_remaining_bounds_path( &mut self, - generic_params: Vec<GenericParam>, + generic_params: ThinVec<GenericParam>, path: ast::Path, lo: Span, parse_plus: bool, @@ -433,7 +433,7 @@ impl<'a> Parser<'a> { }; let ty = if self.eat(&token::Semi) { - let mut length = self.parse_anon_const_expr()?; + let mut length = self.parse_expr_anon_const()?; if let Err(e) = self.expect(&token::CloseDelim(Delimiter::Bracket)) { // Try to recover from `X<Y, ...>` when `X::<Y, ...>` works self.check_mistyped_turbofish_with_multiple_type_params(e, &mut length.value)?; @@ -494,7 +494,7 @@ impl<'a> Parser<'a> { // To avoid ambiguity, the type is surrounded by parentheses. fn parse_typeof_ty(&mut self) -> PResult<'a, TyKind> { self.expect(&token::OpenDelim(Delimiter::Parenthesis))?; - let expr = self.parse_anon_const_expr()?; + let expr = self.parse_expr_anon_const()?; self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; Ok(TyKind::Typeof(expr)) } @@ -511,7 +511,7 @@ impl<'a> Parser<'a> { fn parse_ty_bare_fn( &mut self, lo: Span, - mut params: Vec<GenericParam>, + mut params: ThinVec<GenericParam>, param_insertion_point: Option<Span>, recover_return_sign: RecoverReturnSign, ) -> PResult<'a, TyKind> { @@ -545,13 +545,13 @@ impl<'a> Parser<'a> { fn recover_fn_ptr_with_generics( &mut self, lo: Span, - params: &mut Vec<GenericParam>, + params: &mut ThinVec<GenericParam>, param_insertion_point: Option<Span>, ) -> PResult<'a, ()> { let generics = self.parse_generics()?; let arity = generics.params.len(); - let mut lifetimes: Vec<_> = generics + let mut lifetimes: ThinVec<_> = generics .params .into_iter() .filter(|param| matches!(param.kind, ast::GenericParamKind::Lifetime)) @@ -662,7 +662,7 @@ impl<'a> Parser<'a> { }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { // `Trait1 + Trait2 + 'a` - self.parse_remaining_bounds_path(Vec::new(), path, lo, true) + self.parse_remaining_bounds_path(ThinVec::new(), path, lo, true) } else { // Just a type path. Ok(TyKind::Path(None, path)) @@ -993,7 +993,7 @@ impl<'a> Parser<'a> { } /// Optionally parses `for<$generic_params>`. - pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, Vec<GenericParam>> { + pub(super) fn parse_late_bound_lifetime_defs(&mut self) -> PResult<'a, ThinVec<GenericParam>> { if self.eat_keyword(kw::For) { self.expect_lt()?; let params = self.parse_generic_params()?; @@ -1002,7 +1002,7 @@ impl<'a> Parser<'a> { // parameters, and the lifetime parameters must not have bounds. Ok(params) } else { - Ok(Vec::new()) + Ok(ThinVec::new()) } } @@ -1012,7 +1012,7 @@ impl<'a> Parser<'a> { fn recover_fn_trait_with_lifetime_params( &mut self, fn_path: &mut ast::Path, - lifetime_defs: &mut Vec<GenericParam>, + lifetime_defs: &mut ThinVec<GenericParam>, ) -> PResult<'a, ()> { let fn_path_segment = fn_path.segments.last_mut().unwrap(); let generic_args = if let Some(p_args) = &fn_path_segment.args { @@ -1046,7 +1046,7 @@ impl<'a> Parser<'a> { // Parse `(T, U) -> R`. let inputs_lo = self.token.span; - let inputs: Vec<_> = + let inputs: ThinVec<_> = self.parse_fn_params(|_| false)?.into_iter().map(|input| input.ty).collect(); let inputs_span = inputs_lo.to(self.prev_token.span); let output = self.parse_ret_ty(AllowPlus::No, RecoverQPath::No, RecoverReturnSign::No)?; @@ -1072,7 +1072,7 @@ impl<'a> Parser<'a> { kind: ast::GenericParamKind::Lifetime, colon_span: None, }) - .collect::<Vec<GenericParam>>(); + .collect::<ThinVec<GenericParam>>(); lifetime_defs.append(&mut generic_params); let generic_args_span = generic_args.span(); diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_passes/locales/en-US.ftl index 0c7e02912d4..0ed29ce0d47 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_passes/locales/en-US.ftl @@ -407,10 +407,10 @@ passes_duplicate_diagnostic_item = passes_duplicate_diagnostic_item_in_crate = duplicate diagnostic item in crate `{$crate_name}`: `{$name}`. + .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. passes_diagnostic_item_first_defined = the diagnostic item is first defined here - .note = the diagnostic item is first defined in crate `{$orig_crate_name}`. passes_abi = abi: {$abi} @@ -745,3 +745,7 @@ passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}" passes_proc_macro_unsafe = proc macro functions may not be `unsafe` passes_skipping_const_checks = skipping const checks + +passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument + +passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8ad4a5ef958..5ef3e13eff8 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -4,10 +4,10 @@ //! conflicts between multiple such attributes attached to the same //! item. -use crate::errors; +use crate::{errors, fluent_generated as fluent}; use rustc_ast::{ast, AttrStyle, Attribute, LitKind, MetaItemKind, MetaItemLit, NestedMetaItem}; use rustc_data_structures::fx::FxHashMap; -use rustc_errors::{fluent, Applicability, IntoDiagnosticArg, MultiSpan}; +use rustc_errors::{Applicability, IntoDiagnosticArg, MultiSpan}; use rustc_expand::base::resolve_path; use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_hir as hir; @@ -23,7 +23,8 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_session::lint::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, + UNUSED_ATTRIBUTES, }; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol}; @@ -935,15 +936,15 @@ impl CheckAttrVisitor<'_> { src.insert(1, '!'); err.span_suggestion_verbose( attr.span, - fluent::suggestion, + fluent::passes_suggestion, src, Applicability::MaybeIncorrect, ); } else { - err.span_help(attr.span, fluent::help); + err.span_help(attr.span, fluent::passes_help); } } - err.note(fluent::note); + err.note(fluent::passes_note); err }, ); @@ -2102,7 +2103,33 @@ impl CheckAttrVisitor<'_> { fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) { if target != Target::MacroDef { - self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport); + self.tcx.emit_spanned_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::MacroExport::Normal, + ); + } else if let Some(meta_item_list) = attr.meta_item_list() && + !meta_item_list.is_empty() { + if meta_item_list.len() > 1 { + self.tcx.emit_spanned_lint( + INVALID_MACRO_EXPORT_ARGUMENTS, + hir_id, + attr.span, + errors::MacroExport::TooManyItems, + ); + } else { + if meta_item_list[0].name_or_empty() != sym::local_inner_macros { + self.tcx.emit_spanned_lint( + INVALID_MACRO_EXPORT_ARGUMENTS, + hir_id, + meta_item_list[0].span(), + errors::MacroExport::UnknownItem { + name: meta_item_list[0].name_or_empty(), + }, + ); + } + } } } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 668c159f3cc..e2f858a34b6 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -395,6 +395,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { self.mark_as_used_if_union(*adt, fields); } } + hir::ExprKind::Closure(cls) => { + self.insert_def_id(cls.def_id.to_def_id()); + } _ => (), } @@ -691,7 +694,7 @@ impl<'tcx> DeadVisitor<'tcx> { }) .collect(); - let descr = tcx.def_kind(first_id).descr(first_id.to_def_id()); + let descr = tcx.def_descr(first_id.to_def_id()); let num = dead_codes.len(); let multiple = num > 6; let name_list = names.into(); @@ -703,7 +706,7 @@ impl<'tcx> DeadVisitor<'tcx> { }; let parent_info = if let Some(parent_item) = parent_item { - let parent_descr = tcx.def_kind(parent_item).descr(parent_item.to_def_id()); + let parent_descr = tcx.def_descr(parent_item.to_def_id()); Some(ParentInfo { num, descr, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 68b098e3457..2c0d21b4798 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -3,6 +3,7 @@ use std::{ path::{Path, PathBuf}, }; +use crate::fluent_generated as fluent; use rustc_ast::Label; use rustc_errors::{ error_code, Applicability, DiagnosticSymbolList, ErrorGuaranteed, IntoDiagnostic, MultiSpan, @@ -261,7 +262,7 @@ pub struct DocKeywordConflict { pub struct DocInlineOnlyUse { #[label] pub attr_span: Span, - #[label(not_a_use_item_label)] + #[label(passes_not_a_use_item_label)] pub item_span: Option<Span>, } @@ -300,7 +301,7 @@ pub struct DocTestUnknownAny { #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_spotlight)] #[note] -#[note(no_op_note)] +#[note(passes_no_op_note)] pub struct DocTestUnknownSpotlight { pub path: String, #[suggestion(style = "short", applicability = "machine-applicable", code = "notable_trait")] @@ -573,9 +574,9 @@ pub struct DebugVisualizerPlacement { #[derive(Diagnostic)] #[diag(passes_debug_visualizer_invalid)] -#[note(note_1)] -#[note(note_2)] -#[note(note_3)] +#[note(passes_note_1)] +#[note(passes_note_2)] +#[note(passes_note_3)] pub struct DebugVisualizerInvalid { #[primary_span] pub span: Span, @@ -640,8 +641,16 @@ pub struct MacroUse { } #[derive(LintDiagnostic)] -#[diag(passes_macro_export)] -pub struct MacroExport; +pub enum MacroExport { + #[diag(passes_macro_export)] + Normal, + + #[diag(passes_invalid_macro_export_arguments)] + UnknownItem { name: Symbol }, + + #[diag(passes_invalid_macro_export_arguments_too_many_items)] + TooManyItems, +} #[derive(LintDiagnostic)] #[diag(passes_plugin_registrar)] @@ -782,7 +791,7 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { self, handler: &'_ rustc_errors::Handler, ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { - let mut diag = handler.struct_err(rustc_errors::fluent::passes_invalid_attr_at_crate_level); + let mut diag = handler.struct_err(fluent::passes_invalid_attr_at_crate_level); diag.set_span(self.span); diag.set_arg("name", self.name); // Only emit an error with a suggestion if we can create a string out @@ -791,7 +800,7 @@ impl IntoDiagnostic<'_> for InvalidAttrAtCrateLevel { let replacement = src.replace("#!", "#"); diag.span_suggestion_verbose( self.span, - rustc_errors::fluent::suggestion, + fluent::passes_suggestion, replacement, rustc_errors::Applicability::MachineApplicable, ); @@ -917,17 +926,17 @@ impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> { ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::passes_break_non_loop, + fluent::passes_break_non_loop, error_code!(E0571), ); diag.set_arg("kind", self.kind); - diag.span_label(self.span, rustc_errors::fluent::label); + diag.span_label(self.span, fluent::passes_label); if let Some(head) = self.head { - diag.span_label(head, rustc_errors::fluent::label2); + diag.span_label(head, fluent::passes_label2); } diag.span_suggestion( self.span, - rustc_errors::fluent::suggestion, + fluent::passes_suggestion, self.suggestion, Applicability::MaybeIncorrect, ); @@ -945,7 +954,7 @@ impl<'a> IntoDiagnostic<'_> for BreakNonLoop<'a> { _ => { diag.span_suggestion( self.break_expr_span, - rustc_errors::fluent::break_expr_suggestion, + fluent::passes_break_expr_suggestion, label.ident, Applicability::MaybeIncorrect, ); @@ -962,7 +971,7 @@ pub struct ContinueLabeledBlock { #[primary_span] #[label] pub span: Span, - #[label(block_label)] + #[label(passes_block_label)] pub block_span: Span, } @@ -972,7 +981,7 @@ pub struct BreakInsideClosure<'a> { #[primary_span] #[label] pub span: Span, - #[label(closure_label)] + #[label(passes_closure_label)] pub closure_span: Span, pub name: &'a str, } @@ -983,7 +992,7 @@ pub struct BreakInsideAsyncBlock<'a> { #[primary_span] #[label] pub span: Span, - #[label(async_block_label)] + #[label(passes_async_block_label)] pub closure_span: Span, pub name: &'a str, } @@ -1056,14 +1065,14 @@ impl IntoDiagnostic<'_> for NakedFunctionsAsmBlock { ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( self.span, - rustc_errors::fluent::passes_naked_functions_asm_block, + fluent::passes_naked_functions_asm_block, error_code!(E0787), ); for span in self.multiple_asms.iter() { - diag.span_label(*span, rustc_errors::fluent::label_multiple_asm); + diag.span_label(*span, fluent::passes_label_multiple_asm); } for span in self.non_asms.iter() { - diag.span_label(*span, rustc_errors::fluent::label_non_asm); + diag.span_label(*span, fluent::passes_label_non_asm); } diag } @@ -1122,9 +1131,9 @@ pub struct AttrOnlyInFunctions { pub struct MultipleRustcMain { #[primary_span] pub span: Span, - #[label(first)] + #[label(passes_first)] pub first: Span, - #[label(additional)] + #[label(passes_additional)] pub additional: Span, } @@ -1135,7 +1144,7 @@ pub struct MultipleStartFunctions { pub span: Span, #[label] pub labeled: Span, - #[label(previous)] + #[label(passes_previous)] pub previous: Span, } @@ -1180,7 +1189,7 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr { ) -> rustc_errors::DiagnosticBuilder<'a, ErrorGuaranteed> { let mut diag = handler.struct_span_err_with_code( DUMMY_SP, - rustc_errors::fluent::passes_no_main_function, + fluent::passes_no_main_function, error_code!(E0601), ); diag.set_arg("crate_name", self.crate_name); @@ -1188,16 +1197,16 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr { diag.set_arg("has_filename", self.has_filename); let note = if !self.non_main_fns.is_empty() { for &span in &self.non_main_fns { - diag.span_note(span, rustc_errors::fluent::here_is_main); + diag.span_note(span, fluent::passes_here_is_main); } - diag.note(rustc_errors::fluent::one_or_more_possible_main); - diag.help(rustc_errors::fluent::consider_moving_main); + diag.note(fluent::passes_one_or_more_possible_main); + diag.help(fluent::passes_consider_moving_main); // There were some functions named `main` though. Try to give the user a hint. - rustc_errors::fluent::main_must_be_defined_at_crate + fluent::passes_main_must_be_defined_at_crate } else if self.has_filename { - rustc_errors::fluent::consider_adding_main_to_file + fluent::passes_consider_adding_main_to_file } else { - rustc_errors::fluent::consider_adding_main_at_crate + fluent::passes_consider_adding_main_at_crate }; if self.file_empty { diag.note(note); @@ -1208,11 +1217,11 @@ impl<'a> IntoDiagnostic<'a> for NoMainErr { if let Some(main_def) = self.main_def_opt && main_def.opt_fn_def_id().is_none(){ // There is something at `crate::main`, but it is not a function definition. - diag.span_label(main_def.span, rustc_errors::fluent::non_function_main); + diag.span_label(main_def.span, fluent::passes_non_function_main); } if self.add_teach_note { - diag.note(rustc_errors::fluent::teach_note); + diag.note(fluent::passes_teach_note); } diag } @@ -1241,12 +1250,9 @@ impl IntoDiagnostic<'_> for DuplicateLangItem { ) -> rustc_errors::DiagnosticBuilder<'_, ErrorGuaranteed> { let mut diag = handler.struct_err_with_code( match self.duplicate { - Duplicate::Plain => rustc_errors::fluent::passes_duplicate_lang_item, - - Duplicate::Crate => rustc_errors::fluent::passes_duplicate_lang_item_crate, - Duplicate::CrateDepends => { - rustc_errors::fluent::passes_duplicate_lang_item_crate_depends - } + Duplicate::Plain => fluent::passes_duplicate_lang_item, + Duplicate::Crate => fluent::passes_duplicate_lang_item_crate, + Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends, }, error_code!(E0152), ); @@ -1261,24 +1267,24 @@ impl IntoDiagnostic<'_> for DuplicateLangItem { diag.set_span(span); } if let Some(span) = self.first_defined_span { - diag.span_note(span, rustc_errors::fluent::first_defined_span); + diag.span_note(span, fluent::passes_first_defined_span); } else { if self.orig_dependency_of.is_empty() { - diag.note(rustc_errors::fluent::first_defined_crate); + diag.note(fluent::passes_first_defined_crate); } else { - diag.note(rustc_errors::fluent::first_defined_crate_depends); + diag.note(fluent::passes_first_defined_crate_depends); } if self.orig_is_local { - diag.note(rustc_errors::fluent::first_definition_local); + diag.note(fluent::passes_first_definition_local); } else { - diag.note(rustc_errors::fluent::first_definition_path); + diag.note(fluent::passes_first_definition_path); } if self.is_local { - diag.note(rustc_errors::fluent::second_definition_local); + diag.note(fluent::passes_second_definition_local); } else { - diag.note(rustc_errors::fluent::second_definition_path); + diag.note(fluent::passes_second_definition_path); } } diag @@ -1389,7 +1395,7 @@ pub struct UselessStability { #[primary_span] #[label] pub span: Span, - #[label(item)] + #[label(passes_item)] pub item_sp: Span, } @@ -1399,7 +1405,7 @@ pub struct InvalidStability { #[primary_span] #[label] pub span: Span, - #[label(item)] + #[label(passes_item)] pub item_sp: Span, } @@ -1409,7 +1415,7 @@ pub struct CannotStabilizeDeprecated { #[primary_span] #[label] pub span: Span, - #[label(item)] + #[label(passes_item)] pub item_sp: Span, } @@ -1419,7 +1425,7 @@ pub struct InvalidDeprecationVersion { #[primary_span] #[label] pub span: Span, - #[label(item)] + #[label(passes_item)] pub item_sp: Span, } diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index 6e621b7eb5e..0cb8424082c 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -18,6 +18,8 @@ extern crate rustc_middle; #[macro_use] extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_middle::ty::query::Providers; mod check_attr; @@ -40,6 +42,8 @@ pub mod stability; mod upvars; mod weak_lang_items; +fluent_messages! { "../locales/en-US.ftl" } + pub fn provide(providers: &mut Providers) { check_attr::provide(providers); check_const::provide(providers); diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 678f1815d01..df5c8f53ec1 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -475,7 +475,7 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { | hir::ExprKind::InlineAsm(..) | hir::ExprKind::Box(..) | hir::ExprKind::Type(..) - | hir::ExprKind::Err + | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) | hir::ExprKind::Path(hir::QPath::LangItem(..)) => { intravisit::walk_expr(self, expr); @@ -1129,7 +1129,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprKind::Lit(..) | hir::ExprKind::ConstBlock(..) - | hir::ExprKind::Err + | hir::ExprKind::Err(_) | hir::ExprKind::Path(hir::QPath::TypeRelative(..)) | hir::ExprKind::Path(hir::QPath::LangItem(..)) => succ, @@ -1427,7 +1427,7 @@ fn check_expr<'tcx>(this: &mut Liveness<'_, 'tcx>, expr: &'tcx Expr<'tcx>) { | hir::ExprKind::Yield(..) | hir::ExprKind::Box(..) | hir::ExprKind::Type(..) - | hir::ExprKind::Err => {} + | hir::ExprKind::Err(_) => {} } } diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index acc54e7e110..c5b5cf7f5a9 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -219,7 +219,7 @@ impl<'tcx> CheckInlineAssembly<'tcx> { hir::intravisit::walk_expr(self, expr); } - ExprKind::Err => { + ExprKind::Err(_) => { self.items.push((ItemKind::Err, span)); } } diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 2e736039fb5..16194a6f196 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -523,7 +523,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { && stab.is_none() && self.effective_visibilities.is_reachable(def_id) { - let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); + let descr = self.tcx.def_descr(def_id.to_def_id()); self.tcx.sess.emit_err(errors::MissingStabilityAttr { span, descr }); } } @@ -551,7 +551,7 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> { let is_reachable = self.effective_visibilities.is_reachable(def_id); if is_const && is_stable && missing_const_stability_attribute && is_reachable { - let descr = self.tcx.def_kind(def_id).descr(def_id.to_def_id()); + let descr = self.tcx.def_descr(def_id.to_def_id()); self.tcx.sess.emit_err(errors::MissingConstStabAttr { span, descr }); } } @@ -748,7 +748,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true }; c.visit_ty(self_ty); c.visit_trait_ref(t); - if c.fully_stable { + + // do not lint when the trait isn't resolved, since resolution error should + // be fixed first + if t.path.res != Res::Err && c.fully_stable { self.tcx.struct_span_lint_hir( INEFFECTIVE_UNSTABLE_TRAIT_IMPL, item.hir_id(), diff --git a/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl b/compiler/rustc_plugin_impl/locales/en-US.ftl index 8db32a42c1d..8db32a42c1d 100644 --- a/compiler/rustc_error_messages/locales/en-US/plugin_impl.ftl +++ b/compiler/rustc_plugin_impl/locales/en-US.ftl diff --git a/compiler/rustc_plugin_impl/src/lib.rs b/compiler/rustc_plugin_impl/src/lib.rs index 9ac27c65da8..3f03eef9ee3 100644 --- a/compiler/rustc_plugin_impl/src/lib.rs +++ b/compiler/rustc_plugin_impl/src/lib.rs @@ -11,11 +11,15 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_lint::LintStore; +use rustc_macros::fluent_messages; mod errors; pub mod load; +fluent_messages! { "../locales/en-US.ftl" } + /// Structure used to register plugins. /// /// A plugin registrar function takes an `&mut Registry` and should call diff --git a/compiler/rustc_error_messages/locales/en-US/privacy.ftl b/compiler/rustc_privacy/locales/en-US.ftl index a26d1b2b381..a26d1b2b381 100644 --- a/compiler/rustc_error_messages/locales/en-US/privacy.ftl +++ b/compiler/rustc_privacy/locales/en-US.ftl diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index a6c95f1a815..72b53eefa08 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -57,7 +57,7 @@ pub struct InPublicInterfaceTraits<'a> { pub vis_descr: &'static str, pub kind: &'a str, pub descr: DiagnosticArgFromDisplay<'a>, - #[label(visibility_label)] + #[label(privacy_visibility_label)] pub vis_span: Span, } @@ -71,7 +71,7 @@ pub struct InPublicInterface<'a> { pub vis_descr: &'static str, pub kind: &'a str, pub descr: DiagnosticArgFromDisplay<'a>, - #[label(visibility_label)] + #[label(privacy_visibility_label)] pub vis_span: Span, } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 58dfca75c65..50176c80232 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -16,11 +16,13 @@ use rustc_ast::MacroDef; use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind}; +use rustc_macros::fluent_messages; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, Level}; @@ -28,7 +30,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind}; -use rustc_middle::ty::{ir::TypeVisitor, TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_session::lint; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, sym, Ident}; @@ -44,6 +46,8 @@ use errors::{ UnnamedItemIsPrivate, }; +fluent_messages! { "../locales/en-US.ftl" } + //////////////////////////////////////////////////////////////////////////////// /// Generic infrastructure used to implement specific visitors below. //////////////////////////////////////////////////////////////////////////////// @@ -81,7 +85,10 @@ trait DefIdVisitor<'tcx> { dummy: Default::default(), } } - fn visit(&mut self, ty_fragment: impl TypeVisitable<'tcx>) -> ControlFlow<Self::BreakTy> { + fn visit( + &mut self, + ty_fragment: impl TypeVisitable<TyCtxt<'tcx>>, + ) -> ControlFlow<Self::BreakTy> { ty_fragment.visit_with(&mut self.skeleton()) } fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> { @@ -1329,7 +1336,7 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { hir::QPath::Resolved(_, path) => Some(self.tcx.def_path_str(path.res.def_id())), hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()), }; - let kind = kind.descr(def_id); + let kind = self.tcx.def_descr(def_id); let sess = self.tcx.sess; let _ = match name { Some(name) => { diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 21732d26035..3e8a88c7e81 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -20,7 +20,7 @@ rustc-rayon-core = { version = "0.4.0", optional = true } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" [features] diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index e2884f2026e..a8592bd7086 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -124,9 +124,7 @@ impl QueryContext for QueryCtxt<'_> { }; // Use the `ImplicitCtxt` while we execute the query. - tls::enter_context(&new_icx, || { - rustc_data_structures::stack::ensure_sufficient_stack(compute) - }) + tls::enter_context(&new_icx, compute) }) } diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 028756b5a0a..7d8f75e2566 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -22,7 +22,7 @@ rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } rustc_type_ir = { path = "../rustc_type_ir" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" tracing = "0.1" [features] diff --git a/compiler/rustc_error_messages/locales/en-US/query_system.ftl b/compiler/rustc_query_system/locales/en-US.ftl index 870e824039c..870e824039c 100644 --- a/compiler/rustc_error_messages/locales/en-US/query_system.ftl +++ b/compiler/rustc_query_system/locales/en-US.ftl diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 9443ded704d..59e0c359745 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -6,6 +6,7 @@ use rustc_data_structures::sharded::{self, Sharded}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::steal::Steal; use rustc_data_structures::sync::{AtomicU32, AtomicU64, Lock, Lrc, Ordering}; +use rustc_data_structures::OnDrop; use rustc_index::vec::IndexVec; use rustc_serialize::opaque::{FileEncodeResult, FileEncoder}; use smallvec::{smallvec, SmallVec}; @@ -278,6 +279,7 @@ impl<K: DepKind> DepGraph<K> { /// `arg` parameter. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/incremental-compilation.html + #[inline(always)] pub fn with_task<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>( &self, key: DepNode<K>, @@ -297,6 +299,7 @@ impl<K: DepKind> DepGraph<K> { } } + #[inline(always)] fn with_task_impl<Ctxt: HasDepContext<DepKind = K>, A: Debug, R>( &self, key: DepNode<K>, @@ -597,6 +600,7 @@ impl<K: DepKind> DepGraph<K> { self.data.is_some() && self.dep_node_index_of_opt(dep_node).is_some() } + #[inline] pub fn prev_fingerprint_of(&self, dep_node: &DepNode<K>) -> Option<Fingerprint> { self.data.as_ref().unwrap().previous.fingerprint_of(dep_node) } @@ -671,17 +675,24 @@ impl<K: DepKind> DepGraph<K> { let prev_index = data.previous.node_to_index_opt(dep_node)?; match data.colors.get(prev_index) { - Some(DepNodeColor::Green(dep_node_index)) => Some((prev_index, dep_node_index)), - Some(DepNodeColor::Red) => None, - None => { - // This DepNode and the corresponding query invocation existed - // in the previous compilation session too, so we can try to - // mark it as green by recursively marking all of its - // dependencies green. - self.try_mark_previous_green(qcx, data, prev_index, &dep_node) - .map(|dep_node_index| (prev_index, dep_node_index)) - } + Some(DepNodeColor::Green(dep_node_index)) => return Some((prev_index, dep_node_index)), + Some(DepNodeColor::Red) => return None, + None => {} } + + let backtrace = backtrace_printer(qcx.dep_context().sess(), data, prev_index); + + // This DepNode and the corresponding query invocation existed + // in the previous compilation session too, so we can try to + // mark it as green by recursively marking all of its + // dependencies green. + let ret = self + .try_mark_previous_green(qcx, data, prev_index, &dep_node) + .map(|dep_node_index| (prev_index, dep_node_index)); + + // We succeeded, no backtrace. + backtrace.disable(); + return ret; } #[instrument(skip(self, qcx, data, parent_dep_node_index), level = "debug")] @@ -794,7 +805,10 @@ impl<K: DepKind> DepGraph<K> { let prev_deps = data.previous.edge_targets_from(prev_dep_node_index); for &dep_dep_node_index in prev_deps { - self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node)? + let backtrace = backtrace_printer(qcx.dep_context().sess(), data, dep_dep_node_index); + let success = self.try_mark_parent_green(qcx, data, dep_dep_node_index, dep_node); + backtrace.disable(); + success?; } // If we got here without hitting a `return` that means that all @@ -1116,6 +1130,7 @@ impl<K: DepKind> CurrentDepGraph<K> { /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it. /// Assumes that this is a node that has no equivalent in the previous dep-graph. + #[inline(always)] fn intern_new_node( &self, profiler: &SelfProfilerRef, @@ -1354,6 +1369,7 @@ impl DepNodeColorMap { } } + #[inline] fn insert(&self, index: SerializedDepNodeIndex, color: DepNodeColor) { self.values[index].store( match color { @@ -1364,3 +1380,26 @@ impl DepNodeColorMap { ) } } + +fn backtrace_printer<'a, K: DepKind>( + sess: &'a rustc_session::Session, + graph: &'a DepGraphData<K>, + node: SerializedDepNodeIndex, +) -> OnDrop<impl Fn() + 'a> { + OnDrop( + #[inline(never)] + #[cold] + move || { + let node = graph.previous.index_to_node(node); + // Do not try to rely on DepNode's Debug implementation, since it may panic. + let diag = rustc_errors::Diagnostic::new( + rustc_errors::Level::FailureNote, + &format!( + "encountered while trying to mark dependency green: {:?}({})", + node.kind, node.hash + ), + ); + sess.diagnostic().force_print_diagnostic(diag); + }, + ) +} diff --git a/compiler/rustc_query_system/src/ich/hcx.rs b/compiler/rustc_query_system/src/ich/hcx.rs index 8db8ee9428b..5593a15412f 100644 --- a/compiler/rustc_query_system/src/ich/hcx.rs +++ b/compiler/rustc_query_system/src/ich/hcx.rs @@ -146,7 +146,7 @@ impl<'a> rustc_span::HashStableContext for StableHashingContext<'a> { #[inline] fn def_span(&self, def_id: LocalDefId) -> Span { - *self.untracked.source_span.read().get(def_id).unwrap_or(&DUMMY_SP) + self.untracked.source_span.get(def_id).unwrap_or(DUMMY_SP) } #[inline] diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs index 623be668464..6cc4c9a7e1e 100644 --- a/compiler/rustc_query_system/src/lib.rs +++ b/compiler/rustc_query_system/src/lib.rs @@ -15,6 +15,9 @@ extern crate rustc_data_structures; #[macro_use] extern crate rustc_macros; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + pub mod cache; pub mod dep_graph; mod error; @@ -26,3 +29,5 @@ pub use error::HandleCycleError; pub use error::LayoutOfDepth; pub use error::QueryOverflow; pub use values::Value; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index e840108bdd8..4b3cd16c29f 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -21,7 +21,7 @@ pub trait QueryStorage { } pub trait QueryCache: QueryStorage + Sized { - type Key: Hash + Eq + Clone + Debug; + type Key: Hash + Eq + Copy + Debug; /// Checks if the query is already computed and in the cache. /// It returns the shard index and a lock guard to the shard, @@ -61,7 +61,7 @@ impl<K: Eq + Hash, V: Copy + Debug> QueryStorage for DefaultCache<K, V> { impl<K, V> QueryCache for DefaultCache<K, V> where - K: Eq + Hash + Clone + Debug, + K: Eq + Hash + Copy + Debug, V: Copy + Debug, { type Key = K; @@ -179,7 +179,7 @@ impl<K: Eq + Idx, V: Copy + Debug> QueryStorage for VecCache<K, V> { impl<K, V> QueryCache for VecCache<K, V> where - K: Eq + Idx + Clone + Debug, + K: Eq + Idx + Copy + Debug, V: Copy + Debug, { type Key = K; diff --git a/compiler/rustc_query_system/src/query/config.rs b/compiler/rustc_query_system/src/query/config.rs index 56247e827a2..d5637387346 100644 --- a/compiler/rustc_query_system/src/query/config.rs +++ b/compiler/rustc_query_system/src/query/config.rs @@ -19,7 +19,9 @@ pub type TryLoadFromDisk<Qcx, Q> = pub trait QueryConfig<Qcx: QueryContext> { const NAME: &'static str; - type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Clone + Debug; + // `Key` and `Value` are `Copy` instead of `Clone` to ensure copying them stays cheap, + // but it isn't necessary. + type Key: DepNodeParams<Qcx::DepContext> + Eq + Hash + Copy + Debug; type Value: Debug + Copy; type Cache: QueryCache<Key = Self::Key, Value = Self::Value>; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 21a0c73d720..586bd38fbb8 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -15,6 +15,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::profiling::TimingGuard; #[cfg(parallel_compiler)] use rustc_data_structures::sharded::Sharded; +use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::Lock; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError}; use rustc_session::Session; @@ -48,7 +49,7 @@ enum QueryResult<D: DepKind> { impl<K, D> QueryState<K, D> where - K: Eq + Hash + Clone + Debug, + K: Eq + Hash + Copy + Debug, D: DepKind, { pub fn all_inactive(&self) -> bool { @@ -77,7 +78,7 @@ where for shard in shards.iter() { for (k, v) in shard.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(qcx, k.clone()); + let query = make_query(qcx, *k); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -91,7 +92,7 @@ where // really hurt much.) for (k, v) in self.active.try_lock()?.iter() { if let QueryResult::Started(ref job) = *v { - let query = make_query(qcx, k.clone()); + let query = make_query(qcx, *k); jobs.insert(job.id, QueryJobInfo { query, job: job.clone() }); } } @@ -111,7 +112,7 @@ impl<K, D: DepKind> Default for QueryState<K, D> { /// This will poison the relevant query if dropped. struct JobOwner<'tcx, K, D: DepKind> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, { state: &'tcx QueryState<K, D>, key: K, @@ -163,7 +164,7 @@ where impl<'tcx, K, D: DepKind> JobOwner<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, { /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or returns with the result of the query. @@ -188,14 +189,14 @@ where #[cfg(not(parallel_compiler))] let mut state_lock = state.active.lock(); let lock = &mut *state_lock; + let current_job_id = qcx.current_query_job(); match lock.entry(key) { Entry::Vacant(entry) => { let id = qcx.next_job_id(); - let job = qcx.current_query_job(); - let job = QueryJob::new(id, span, job); + let job = QueryJob::new(id, span, current_job_id); - let key = entry.key().clone(); + let key = *entry.key(); entry.insert(QueryResult::Started(job)); let owner = JobOwner { state, id, key }; @@ -212,7 +213,7 @@ where // so we just return the error. return TryGetJob::Cycle(id.find_cycle_in_stack( qcx.try_collect_active_jobs().unwrap(), - &qcx.current_query_job(), + ¤t_job_id, span, )); } @@ -230,7 +231,7 @@ where // With parallel queries we might just have to wait on some other // thread. - let result = latch.wait_on(qcx.current_query_job(), span); + let result = latch.wait_on(current_job_id, span); match result { Ok(()) => TryGetJob::JobCompleted(query_blocked_prof_timer), @@ -274,7 +275,7 @@ where impl<'tcx, K, D> Drop for JobOwner<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, D: DepKind, { #[inline(never)] @@ -291,7 +292,7 @@ where QueryResult::Started(job) => job, QueryResult::Poisoned => panic!(), }; - shard.insert(self.key.clone(), QueryResult::Poisoned); + shard.insert(self.key, QueryResult::Poisoned); job }; // Also signal the completion of the job, so waiters @@ -310,7 +311,7 @@ pub(crate) struct CycleError<D: DepKind> { /// The result of `try_start`. enum TryGetJob<'tcx, K, D> where - K: Eq + Hash + Clone, + K: Eq + Hash + Copy, D: DepKind, { /// The query is not yet started. Contains a guard to the cache eventually used to start it. @@ -346,10 +347,9 @@ where } } +#[inline(never)] fn try_execute_query<Q, Qcx>( qcx: Qcx, - state: &QueryState<Q::Key, Qcx::DepKind>, - cache: &Q::Cache, span: Span, key: Q::Key, dep_node: Option<DepNode<Qcx::DepKind>>, @@ -358,10 +358,11 @@ where Q: QueryConfig<Qcx>, Qcx: QueryContext, { - match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key.clone()) { + let state = Q::query_state(qcx); + match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, span, key) { TryGetJob::NotYetStarted(job) => { - let (result, dep_node_index) = - execute_job::<Q, Qcx>(qcx, key.clone(), dep_node, job.id); + let (result, dep_node_index) = execute_job::<Q, Qcx>(qcx, key, dep_node, job.id); + let cache = Q::query_cache(qcx); if Q::FEEDABLE { // We should not compute queries that also got a value via feeding. // This can't happen, as query feeding adds the very dependencies to the fed query @@ -382,7 +383,7 @@ where } #[cfg(parallel_compiler)] TryGetJob::JobCompleted(query_blocked_prof_timer) => { - let Some((v, index)) = cache.lookup(&key) else { + let Some((v, index)) = Q::query_cache(qcx).lookup(&key) else { panic!("value must be in cache after waiting") }; @@ -394,6 +395,7 @@ where } } +#[inline(always)] fn execute_job<Q, Qcx>( qcx: Qcx, key: Q::Key, @@ -479,6 +481,7 @@ where (result, dep_node_index) } +#[inline(always)] fn try_load_from_disk_and_cache_in_memory<Q, Qcx>( qcx: Qcx, key: &Q::Key, @@ -551,7 +554,7 @@ where let prof_timer = qcx.dep_context().profiler().query_provider(); // The dep-graph for this computation is already in-place. - let result = dep_graph.with_ignore(|| Q::compute(qcx, key.clone())); + let result = dep_graph.with_ignore(|| Q::compute(qcx, *key)); prof_timer.finish_with_query_invocation_id(dep_node_index.into()); @@ -569,6 +572,7 @@ where Some((result, dep_node_index)) } +#[inline] #[instrument(skip(tcx, result, hash_result), level = "debug")] pub(crate) fn incremental_verify_ich<Tcx, V: Debug>( tcx: Tcx, @@ -723,6 +727,7 @@ pub enum QueryMode { Ensure, } +#[inline(always)] pub fn get_query<Q, Qcx, D>(qcx: Qcx, span: Span, key: Q::Key, mode: QueryMode) -> Option<Q::Value> where D: DepKind, @@ -740,14 +745,8 @@ where None }; - let (result, dep_node_index) = try_execute_query::<Q, Qcx>( - qcx, - Q::query_state(qcx), - Q::query_cache(qcx), - span, - key, - dep_node, - ); + let (result, dep_node_index) = + ensure_sufficient_stack(|| try_execute_query::<Q, Qcx>(qcx, span, key, dep_node)); if let Some(dep_node_index) = dep_node_index { qcx.dep_context().dep_graph().read_index(dep_node_index) } @@ -763,14 +762,12 @@ where { // We may be concurrently trying both execute and force a query. // Ensure that only one of them runs the query. - let cache = Q::query_cache(qcx); - if let Some((_, index)) = cache.lookup(&key) { + if let Some((_, index)) = Q::query_cache(qcx).lookup(&key) { qcx.dep_context().profiler().query_cache_hit(index.into()); return; } - let state = Q::query_state(qcx); debug_assert!(!Q::ANON); - try_execute_query::<Q, _>(qcx, state, cache, DUMMY_SP, key, Some(dep_node)); + ensure_sufficient_stack(|| try_execute_query::<Q, _>(qcx, DUMMY_SP, key, Some(dep_node))); } diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index d4935b52b10..5c4ec44d2b8 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -25,5 +25,5 @@ rustc_query_system = { path = "../rustc_query_system" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.8" +thin-vec = "0.2.12" tracing = "0.1" diff --git a/compiler/rustc_error_messages/locales/en-US/resolve.ftl b/compiler/rustc_resolve/locales/en-US.ftl index 817bb83ed78..817bb83ed78 100644 --- a/compiler/rustc_error_messages/locales/en-US/resolve.ftl +++ b/compiler/rustc_resolve/locales/en-US.ftl diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 9aec25fff0b..ee2d2301399 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -12,11 +12,10 @@ use rustc_errors::{struct_span_err, SuggestionStyle}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; -use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; +use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; -use rustc_index::vec::IndexVec; use rustc_middle::bug; -use rustc_middle::ty::DefIdTree; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_session::lint::builtin::ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE; use rustc_session::lint::builtin::MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS; use rustc_session::lint::BuiltinLintDiagnostics; @@ -30,7 +29,7 @@ use rustc_span::{BytePos, Span, SyntaxContext}; use thin_vec::ThinVec; use crate::errors as errs; -use crate::imports::{Import, ImportKind, ImportResolver}; +use crate::imports::{Import, ImportKind}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, BindingError, Finalize}; @@ -154,8 +153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if !candidates.is_empty() { show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, &mut err, span, &candidates, @@ -191,7 +189,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } let container = match parent.kind { - ModuleKind::Def(kind, _, _) => kind.descr(parent.def_id()), + ModuleKind::Def(kind, _, _) => self.tcx.def_kind_descr(kind, parent.def_id()), ModuleKind::Block => "block", }; @@ -687,8 +685,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { err.span_help(span, &help_msg); } show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, &mut err, Some(span), &import_suggestions, @@ -1352,8 +1349,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let import_suggestions = self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected); show_candidates( - &self.tcx.sess, - &self.tcx.untracked().source_span.read(), + self.tcx, err, None, &import_suggestions, @@ -1808,7 +1804,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { found("module") } else { match binding.res() { - Res::Def(kind, id) => found(kind.descr(id)), + Res::Def(kind, id) => found(self.tcx.def_kind_descr(kind, id)), _ => found(ns_to_try.descr()), } } @@ -1892,15 +1888,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { (format!("use of undeclared crate or module `{}`", ident), suggestion) } } -} -impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Adds suggestions for a path that cannot be resolved. pub(crate) fn make_path_suggestion( &mut self, span: Span, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { debug!("make_path_suggestion: span={:?} path={:?}", span, path); @@ -1935,11 +1929,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_self_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `self` and check if that is valid. path[0].ident.name = kw::SelfLower; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, None)) } else { None } } @@ -1954,11 +1948,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_crate_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Crate; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some(( @@ -1985,11 +1979,11 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_missing_super_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { // Replace first ident with `crate` and check if that is valid. path[0].ident.name = kw::Super; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { Some((path, None)) } else { None } } @@ -2007,7 +2001,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn make_external_crate_suggestion( &mut self, mut path: Vec<Segment>, - parent_scope: &ParentScope<'b>, + parent_scope: &ParentScope<'a>, ) -> Option<(Vec<Segment>, Option<String>)> { if path[1].ident.span.is_rust_2015() { return None; @@ -2017,13 +2011,13 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 1) some consistent ordering for emitted diagnostics, and // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = - self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>(); + self.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>(); extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap()); for name in extern_crate_names.into_iter() { // Replace first ident with a crate name and check if that is valid. path[0].ident.name = name; - let result = self.r.maybe_resolve_path(&path, None, parent_scope); + let result = self.maybe_resolve_path(&path, None, parent_scope); debug!( "make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result @@ -2050,8 +2044,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// ``` pub(crate) fn check_for_module_export_macro( &mut self, - import: &'b Import<'b>, - module: ModuleOrUniformRoot<'b>, + import: &'a Import<'a>, + module: ModuleOrUniformRoot<'a>, ident: Ident, ) -> Option<(Option<Suggestion>, Option<String>)> { let ModuleOrUniformRoot::Module(mut crate_module) = module else { @@ -2068,8 +2062,8 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { return None; } - let resolutions = self.r.resolutions(crate_module).borrow(); - let resolution = resolutions.get(&self.r.new_key(ident, MacroNS))?; + let resolutions = self.resolutions(crate_module).borrow(); + let resolution = resolutions.get(&self.new_key(ident, MacroNS))?; let binding = resolution.borrow().binding()?; if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() { let module_name = crate_module.kind.name().unwrap(); @@ -2090,7 +2084,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // ie. `use a::b::{c, d, e};` // ^^^ let (found_closing_brace, binding_span) = find_span_of_binding_until_next_binding( - self.r.tcx.sess, + self.tcx.sess, import.span, import.use_span, ); @@ -2109,7 +2103,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // ie. `use a::b::{c, d};` // ^^^ if let Some(previous_span) = - extend_span_to_previous_binding(self.r.tcx.sess, binding_span) + extend_span_to_previous_binding(self.tcx.sess, binding_span) { debug!("check_for_module_export_macro: previous_span={:?}", previous_span); removal_span = removal_span.with_lo(previous_span.lo()); @@ -2127,7 +2121,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // or `use a::{b, c, d}};` // ^^^^^^^^^^^ let (has_nested, after_crate_name) = find_span_immediately_after_crate_name( - self.r.tcx.sess, + self.tcx.sess, module_name, import.use_span, ); @@ -2136,7 +2130,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { has_nested, after_crate_name ); - let source_map = self.r.tcx.sess.source_map(); + let source_map = self.tcx.sess.source_map(); // Make sure this is actually crate-relative. let is_definitely_crate = import @@ -2358,8 +2352,7 @@ pub(crate) enum DiagnosticMode { } pub(crate) fn import_candidates( - session: &Session, - source_span: &IndexVec<LocalDefId, Span>, + tcx: TyCtxt<'_>, err: &mut Diagnostic, // This is `None` if all placement locations are inside expansions use_placement_span: Option<Span>, @@ -2368,8 +2361,7 @@ pub(crate) fn import_candidates( append: &str, ) { show_candidates( - session, - source_span, + tcx, err, use_placement_span, candidates, @@ -2385,8 +2377,7 @@ pub(crate) fn import_candidates( /// entities with that name in all crates. This method allows outputting the /// results of this search in a programmer-friendly way fn show_candidates( - session: &Session, - source_span: &IndexVec<LocalDefId, Span>, + tcx: TyCtxt<'_>, err: &mut Diagnostic, // This is `None` if all placement locations are inside expansions use_placement_span: Option<Span>, @@ -2511,8 +2502,8 @@ fn show_candidates( ); if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = source_span[local_def_id]; - let span = session.source_map().guess_head_span(span); + let span = tcx.source_span(local_def_id); + let span = tcx.sess.source_map().guess_head_span(span); let mut multi_span = MultiSpan::from_span(span); multi_span.push_span_label(span, "not accessible"); err.span_note(multi_span, &msg); @@ -2542,8 +2533,8 @@ fn show_candidates( let mut spans = Vec::new(); for (name, _, def_id, _) in &inaccessible_path_strings { if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) { - let span = source_span[local_def_id]; - let span = session.source_map().guess_head_span(span); + let span = tcx.source_span(local_def_id); + let span = tcx.sess.source_map().guess_head_span(span); spans.push((name, span)); } else { if !has_colon { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs index 2c442774667..867363f4246 100644 --- a/compiler/rustc_resolve/src/errors.rs +++ b/compiler/rustc_resolve/src/errors.rs @@ -38,7 +38,7 @@ pub(crate) struct NameAlreadyUsedInParameterList { #[primary_span] #[label] pub(crate) span: Span, - #[label(first_use_of_name)] + #[label(resolve_first_use_of_name)] pub(crate) first_use_span: Span, pub(crate) name: Symbol, } @@ -121,7 +121,7 @@ pub(crate) struct VariableBoundWithDifferentMode { #[primary_span] #[label] pub(crate) span: Span, - #[label(first_binding_span)] + #[label(resolve_first_binding_span)] pub(crate) first_binding_span: Span, pub(crate) variable_name: Symbol, } @@ -293,7 +293,7 @@ pub(crate) struct BindingShadowsSomethingUnacceptable<'a> { pub(crate) article: &'a str, #[subdiagnostic] pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>, - #[label(label_shadowed_binding)] + #[label(resolve_label_shadowed_binding)] pub(crate) shadowed_binding_span: Span, pub(crate) participle: &'a str, pub(crate) name: Symbol, @@ -369,7 +369,7 @@ pub(crate) struct UnreachableLabel { #[label] pub(crate) span: Span, pub(crate) name: Symbol, - #[label(label_definition_span)] + #[label(resolve_label_definition_span)] pub(crate) definition_span: Span, #[subdiagnostic] pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>, @@ -413,7 +413,7 @@ pub(crate) struct TraitImplMismatch { pub(crate) span: Span, pub(crate) name: Symbol, pub(crate) kind: String, - #[label(label_trait_item)] + #[label(resolve_label_trait_item)] pub(crate) trait_item_span: Span, pub(crate) trait_path: String, pub(crate) code: String, @@ -434,9 +434,9 @@ pub(crate) struct TraitImplDuplicate { #[primary_span] #[label] pub(crate) span: Span, - #[label(old_span_label)] + #[label(resolve_old_span_label)] pub(crate) old_span: Span, - #[label(trait_item_span)] + #[label(resolve_trait_item_span)] pub(crate) trait_item_span: Span, pub(crate) name: Symbol, } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 449d8094bd6..4dab0836d28 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -210,6 +210,17 @@ impl<'a> NameResolution<'a> { } } +/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved +/// import errors within the same use tree into a single diagnostic. +#[derive(Debug, Clone)] +struct UnresolvedImportError { + span: Span, + label: Option<String>, + note: Option<String>, + suggestion: Option<Suggestion>, + candidates: Option<Vec<ImportSuggestion>>, +} + // Reexports of the form `pub use foo as bar;` where `foo` is `extern crate foo;` // are permitted for backward-compatibility under a deprecation lint. fn pub_use_of_private_extern_crate_hack(import: &Import<'_>, binding: &NameBinding<'_>) -> bool { @@ -392,24 +403,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } -} - -/// An error that may be transformed into a diagnostic later. Used to combine multiple unresolved -/// import errors within the same use tree into a single diagnostic. -#[derive(Debug, Clone)] -struct UnresolvedImportError { - span: Span, - label: Option<String>, - note: Option<String>, - suggestion: Option<Suggestion>, - candidates: Option<Vec<ImportSuggestion>>, -} - -pub(crate) struct ImportResolver<'a, 'b, 'tcx> { - pub r: &'a mut Resolver<'b, 'tcx>, -} -impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Import resolution // // This is a fixed-point algorithm. We resolve imports until our efforts @@ -421,28 +415,28 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Resolves all imports for the crate. This method performs the fixed- /// point iteration. pub(crate) fn resolve_imports(&mut self) { - let mut prev_num_indeterminates = self.r.indeterminate_imports.len() + 1; - while self.r.indeterminate_imports.len() < prev_num_indeterminates { - prev_num_indeterminates = self.r.indeterminate_imports.len(); - for import in mem::take(&mut self.r.indeterminate_imports) { + let mut prev_num_indeterminates = self.indeterminate_imports.len() + 1; + while self.indeterminate_imports.len() < prev_num_indeterminates { + prev_num_indeterminates = self.indeterminate_imports.len(); + for import in mem::take(&mut self.indeterminate_imports) { match self.resolve_import(&import) { - true => self.r.determined_imports.push(import), - false => self.r.indeterminate_imports.push(import), + true => self.determined_imports.push(import), + false => self.indeterminate_imports.push(import), } } } } pub(crate) fn finalize_imports(&mut self) { - for module in self.r.arenas.local_modules().iter() { + for module in self.arenas.local_modules().iter() { self.finalize_resolutions_in(module); } let mut seen_spans = FxHashSet::default(); let mut errors = vec![]; let mut prev_root_id: NodeId = NodeId::from_u32(0); - let determined_imports = mem::take(&mut self.r.determined_imports); - let indeterminate_imports = mem::take(&mut self.r.indeterminate_imports); + let determined_imports = mem::take(&mut self.determined_imports); + let indeterminate_imports = mem::take(&mut self.indeterminate_imports); for (is_indeterminate, import) in determined_imports .into_iter() @@ -453,7 +447,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // If this import is unresolved then create a dummy import // resolution for it so that later resolve stages won't complain. - self.r.import_dummy_binding(import); + self.import_dummy_binding(import); if let Some(err) = unresolved_import_error { if let ImportKind::Single { source, ref source_bindings, .. } = import.kind { @@ -526,7 +520,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { .collect::<Vec<_>>(); let msg = format!("unresolved import{} {}", pluralize!(paths.len()), paths.join(", "),); - let mut diag = struct_span_err!(self.r.tcx.sess, span, E0432, "{}", &msg); + let mut diag = struct_span_err!(self.tcx.sess, span, E0432, "{}", &msg); if let Some((_, UnresolvedImportError { note: Some(note), .. })) = errors.iter().last() { diag.note(note); @@ -548,8 +542,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if let Some(candidates) = &err.candidates { match &import.kind { ImportKind::Single { nested: false, source, target, .. } => import_candidates( - self.r.tcx.sess, - &self.r.tcx.untracked().source_span.read(), + self.tcx, &mut diag, Some(err.span), &candidates, @@ -561,8 +554,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { ), ImportKind::Single { nested: true, source, target, .. } => { import_candidates( - self.r.tcx.sess, - &self.r.tcx.untracked().source_span.read(), + self.tcx, &mut diag, None, &candidates, @@ -583,7 +575,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. - fn resolve_import(&mut self, import: &'b Import<'b>) -> bool { + fn resolve_import(&mut self, import: &'a Import<'a>) -> bool { debug!( "(resolving import for module) resolving import `{}::...` in `{}`", Segment::names_to_string(&import.module_path), @@ -596,8 +588,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // For better failure detection, pretend that the import will // not define any names while resolving its module path. let orig_vis = import.vis.take(); - let path_res = - self.r.maybe_resolve_path(&import.module_path, None, &import.parent_scope); + let path_res = self.maybe_resolve_path(&import.module_path, None, &import.parent_scope); import.vis.set(orig_vis); match path_res { @@ -625,7 +616,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let mut indeterminate = false; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { if let Err(Undetermined) = source_bindings[ns].get() { // For better failure detection, pretend that the import will @@ -678,15 +669,15 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { /// /// Optionally returns an unresolved import error. This error is buffered and used to /// consolidate multiple unresolved import errors into a single diagnostic. - fn finalize_import(&mut self, import: &'b Import<'b>) -> Option<UnresolvedImportError> { + fn finalize_import(&mut self, import: &'a Import<'a>) -> Option<UnresolvedImportError> { let orig_vis = import.vis.take(); let ignore_binding = match &import.kind { ImportKind::Single { target_bindings, .. } => target_bindings[TypeNS].get(), _ => None, }; - let prev_ambiguity_errors_len = self.r.ambiguity_errors.len(); + let prev_ambiguity_errors_len = self.ambiguity_errors.len(); let finalize = Finalize::with_root_span(import.root_id, import.span, import.root_span); - let path_res = self.r.resolve_path( + let path_res = self.resolve_path( &import.module_path, None, &import.parent_scope, @@ -694,7 +685,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { ignore_binding, ); - let no_ambiguity = self.r.ambiguity_errors.len() == prev_ambiguity_errors_len; + let no_ambiguity = self.ambiguity_errors.len() == prev_ambiguity_errors_len; import.vis.set(orig_vis); let module = match path_res { PathResult::Module(module) => { @@ -703,10 +694,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if !ModuleOrUniformRoot::same_def(module, initial_module) && no_ambiguity { span_bug!(import.span, "inconsistent resolution for an import"); } - } else if self.r.privacy_errors.is_empty() { + } else if self.privacy_errors.is_empty() { let msg = "cannot determine resolution for the import"; let msg_note = "import resolution is stuck, try simplifying other imports"; - self.r.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); + self.tcx.sess.struct_span_err(import.span, msg).note(msg_note).emit(); } module @@ -714,8 +705,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { PathResult::Failed { is_error_from_last_segment: false, span, label, suggestion } => { if no_ambiguity { assert!(import.imported_module.get().is_none()); - self.r - .report_error(span, ResolutionError::FailedToResolve { label, suggestion }); + self.report_error(span, ResolutionError::FailedToResolve { label, suggestion }); } return None; } @@ -777,7 +767,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(Ident::empty())); - self.r.lint_if_path_starts_with_module(Some(finalize), &full_path, None); + self.lint_if_path_starts_with_module(Some(finalize), &full_path, None); } if let ModuleOrUniformRoot::Module(module) = module { @@ -796,10 +786,10 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { } if !is_prelude && let Some(max_vis) = max_vis.get() - && !max_vis.is_at_least(import.expect_vis(), &*self.r) + && !max_vis.is_at_least(import.expect_vis(), &*self) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; - self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); + self.lint_buffer.buffer_lint(UNUSED_IMPORTS, id, import.span, msg); } return None; } @@ -807,7 +797,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let mut all_ns_err = true; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let orig_vis = import.vis.take(); let binding = this.resolve_ident_in_module( @@ -876,7 +866,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if all_ns_err { let mut all_ns_failed = true; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if !type_ns_only || ns == TypeNS { let binding = this.resolve_ident_in_module( module, @@ -894,9 +884,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { return if all_ns_failed { let resolutions = match module { - ModuleOrUniformRoot::Module(module) => { - Some(self.r.resolutions(module).borrow()) - } + ModuleOrUniformRoot::Module(module) => Some(self.resolutions(module).borrow()), _ => None, }; let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter()); @@ -965,7 +953,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { }; let parent_suggestion = - self.r.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true); + self.lookup_import_candidates(ident, TypeNS, &import.parent_scope, |_| true); Some(UnresolvedImportError { span: import.span, @@ -987,7 +975,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut reexport_error = None; let mut any_successful_reexport = false; let mut crate_private_reexport = false; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { if !binding.vis.is_at_least(import.expect_vis(), &*this) { reexport_error = Some((ns, binding)); @@ -1012,7 +1000,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { `pub`", ident ); - self.r.lint_buffer.buffer_lint( + self.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, import_id, import.span, @@ -1035,17 +1023,17 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { format!("re-export of private `{}`", ident) }; - struct_span_err!(self.r.tcx.sess, import.span, E0365, "{}", error_msg) + struct_span_err!(self.tcx.sess, import.span, E0365, "{}", error_msg) .span_label(import.span, label_msg) .note(&format!("consider declaring type or module `{}` with `pub`", ident)) .emit(); } else { let mut err = - struct_span_err!(self.r.tcx.sess, import.span, E0364, "{error_msg}"); + struct_span_err!(self.tcx.sess, import.span, E0364, "{error_msg}"); match binding.kind { NameBindingKind::Res(Res::Def(DefKind::Macro(_), def_id)) // exclude decl_macro - if self.r.get_macro_by_def_id(def_id).macro_rules => + if self.get_macro_by_def_id(def_id).macro_rules => { err.span_help( binding.span, @@ -1071,7 +1059,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = import.module_path.clone(); full_path.push(Segment::from_ident(ident)); - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.lint_if_path_starts_with_module(Some(finalize), &full_path, Some(binding)); } @@ -1081,7 +1069,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Record what this import resolves to for later uses in documentation, // this may resolve to either a value or a type, but for documentation // purposes it's good enough to just favor one over the other. - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { this.import_res_map.entry(import_id).or_default()[ns] = Some(binding.res()); } @@ -1096,9 +1084,9 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { fn check_for_redundant_imports( &mut self, ident: Ident, - import: &'b Import<'b>, - source_bindings: &PerNS<Cell<Result<&'b NameBinding<'b>, Determinacy>>>, - target_bindings: &PerNS<Cell<Option<&'b NameBinding<'b>>>>, + import: &'a Import<'a>, + source_bindings: &PerNS<Cell<Result<&'a NameBinding<'a>, Determinacy>>>, + target_bindings: &PerNS<Cell<Option<&'a NameBinding<'a>>>>, target: Ident, ) { // This function is only called for single imports. @@ -1119,7 +1107,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut redundant_span = PerNS { value_ns: None, type_ns: None, macro_ns: None }; - self.r.per_ns(|this, ns| { + self.per_ns(|this, ns| { if let Ok(binding) = source_bindings[ns].get() { if binding.res() == Res::Err { return; @@ -1149,7 +1137,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { let mut redundant_spans: Vec<_> = redundant_span.present_items().collect(); redundant_spans.sort(); redundant_spans.dedup(); - self.r.lint_buffer.buffer_lint_with_diagnostic( + self.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, id, import.span, @@ -1159,22 +1147,22 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { } } - fn resolve_glob_import(&mut self, import: &'b Import<'b>) { + fn resolve_glob_import(&mut self, import: &'a Import<'a>) { // This function is only called for glob imports. let ImportKind::Glob { id, is_prelude, .. } = import.kind else { unreachable!() }; let ModuleOrUniformRoot::Module(module) = import.imported_module.get().unwrap() else { - self.r.tcx.sess.span_err(import.span, "cannot glob-import all possible crates"); + self.tcx.sess.span_err(import.span, "cannot glob-import all possible crates"); return; }; if module.is_trait() { - self.r.tcx.sess.span_err(import.span, "items in traits are not importable"); + self.tcx.sess.span_err(import.span, "items in traits are not importable"); return; } else if ptr::eq(module, import.parent_scope.module) { return; } else if is_prelude { - self.r.prelude = Some(module); + self.prelude = Some(module); return; } @@ -1184,7 +1172,6 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { // Ensure that `resolutions` isn't borrowed during `try_define`, // since it might get updated via a glob cycle. let bindings = self - .r .resolutions(module) .borrow() .iter() @@ -1194,30 +1181,30 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { .collect::<Vec<_>>(); for (mut key, binding) in bindings { let scope = match key.ident.span.reverse_glob_adjust(module.expansion, import.span) { - Some(Some(def)) => self.r.expn_def_scope(def), + Some(Some(def)) => self.expn_def_scope(def), Some(None) => import.parent_scope.module, None => continue, }; - if self.r.is_accessible_from(binding.vis, scope) { - let imported_binding = self.r.import(binding, import); - let _ = self.r.try_define(import.parent_scope.module, key, imported_binding); + if self.is_accessible_from(binding.vis, scope) { + let imported_binding = self.import(binding, import); + let _ = self.try_define(import.parent_scope.module, key, imported_binding); } } // Record the destination of this import - self.r.record_partial_res(id, PartialRes::new(module.res().unwrap())); + self.record_partial_res(id, PartialRes::new(module.res().unwrap())); } // Miscellaneous post-processing, including recording re-exports, // reporting conflicts, and reporting unresolved imports. - fn finalize_resolutions_in(&mut self, module: Module<'b>) { + fn finalize_resolutions_in(&mut self, module: Module<'a>) { // Since import resolution is finished, globs will not define any more names. *module.globs.borrow_mut() = Vec::new(); if let Some(def_id) = module.opt_def_id() { let mut reexports = Vec::new(); - module.for_each_child(self.r, |this, ident, _, binding| { + module.for_each_child(self, |this, ident, _, binding| { if let Some(res) = this.is_reexport(binding) { reexports.push(ModChild { ident, @@ -1232,7 +1219,7 @@ impl<'a, 'b, 'tcx> ImportResolver<'a, 'b, 'tcx> { if !reexports.is_empty() { // Call to `expect_local` should be fine because current // code is only called for local modules. - self.r.reexport_map.insert(def_id.expect_local(), reexports); + self.reexport_map.insert(def_id.expect_local(), reexports); } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 66034baaa0b..7a1f14f71f2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -28,7 +28,9 @@ use rustc_ast::{AngleBracketedArg, Crate, Expr, ExprKind, GenericArg, GenericArg use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::{Lrc, MappedReadGuard}; -use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{ + Applicability, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, SubdiagnosticMessage, +}; use rustc_expand::base::{DeriveResolutions, SyntaxExtension, SyntaxExtensionKind}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS}; @@ -37,6 +39,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::DefPathData; use rustc_hir::TraitCandidate; use rustc_index::vec::IndexVec; +use rustc_macros::fluent_messages; use rustc_metadata::creader::{CStore, CrateLoader}; use rustc_middle::metadata::ModChild; use rustc_middle::middle::privacy::EffectiveVisibilities; @@ -57,7 +60,7 @@ use std::collections::BTreeSet; use std::{fmt, ptr}; use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion}; -use imports::{Import, ImportKind, ImportResolver, NameResolution}; +use imports::{Import, ImportKind, NameResolution}; use late::{HasGenericParams, PathSource, PatternSource}; use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; @@ -77,6 +80,8 @@ mod late; mod macros; pub mod rustdoc; +fluent_messages! { "../locales/en-US.ftl" } + enum Weak { Yes, No, @@ -1156,7 +1161,7 @@ impl<'tcx> Resolver<'_, 'tcx> { // A relative span's parent must be an absolute span. debug_assert_eq!(span.data_untracked().parent, None); - let _id = self.tcx.untracked().source_span.write().push(span); + let _id = self.tcx.untracked().source_span.push(span); debug_assert_eq!(_id, def_id); // Some things for which we allocate `LocalDefId`s don't correspond to @@ -1486,9 +1491,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { self.tcx.sess.time("resolve_crate", || { - self.tcx - .sess - .time("finalize_imports", || ImportResolver { r: self }.finalize_imports()); + self.tcx.sess.time("finalize_imports", || self.finalize_imports()); self.tcx.sess.time("compute_effective_visibilities", || { EffectiveVisibilitiesVisitor::compute_effective_visibilities(self, krate) }); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 341db774b4d..b38c11e8bb8 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -1,7 +1,6 @@ //! A bunch of methods and structures more or less related to resolving macros and //! interface provided by `Resolver` to macro expander. -use crate::imports::ImportResolver; use crate::Namespace::*; use crate::{BuiltinMacroState, Determinacy}; use crate::{DeriveData, Finalize, ParentScope, ResolutionError, Resolver, ScopeSet}; @@ -233,7 +232,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { } fn resolve_imports(&mut self) { - ImportResolver { r: self }.resolve_imports() + self.resolve_imports() } fn resolve_macro_invocation( diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index db0ef73544f..c0446571905 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] indexmap = "1.9.1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -thin-vec = "0.2.9" +thin-vec = "0.2.12" [dev-dependencies] rustc_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_session/locales/en-US.ftl index fe553edab42..fe553edab42 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_session/locales/en-US.ftl diff --git a/compiler/rustc_session/src/cstore.rs b/compiler/rustc_session/src/cstore.rs index 97aa930b5ec..868ffdf0f1d 100644 --- a/compiler/rustc_session/src/cstore.rs +++ b/compiler/rustc_session/src/cstore.rs @@ -6,10 +6,9 @@ use crate::search_paths::PathKind; use crate::utils::NativeLibKind; use crate::Session; use rustc_ast as ast; -use rustc_data_structures::sync::{self, MetadataRef, RwLock}; +use rustc_data_structures::sync::{self, AppendOnlyVec, MetadataRef, RwLock}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, StableCrateId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash, Definitions}; -use rustc_index::vec::IndexVec; use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -252,10 +251,9 @@ pub trait CrateStore: std::fmt::Debug { pub type CrateStoreDyn = dyn CrateStore + sync::Sync + sync::Send; -#[derive(Debug)] pub struct Untracked { pub cstore: RwLock<Box<CrateStoreDyn>>, /// Reference span for definitions. - pub source_span: RwLock<IndexVec<LocalDefId, Span>>, + pub source_span: AppendOnlyVec<LocalDefId, Span>, pub definitions: RwLock<Definitions>, } diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 39e871f532c..e1f1a5f6d2e 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -18,6 +18,9 @@ pub mod errors; #[macro_use] extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + pub mod cgu_reuse_tracker; pub mod utils; pub use lint::{declare_lint, declare_lint_pass, declare_tool_lint, impl_lint_pass}; @@ -39,6 +42,8 @@ pub mod output; pub use getopts; +fluent_messages! { "../locales/en-US.ftl" } + /// Requirements for a `StableHashingContext` to be used in this crate. /// This is a hack to allow using the `HashStable_Generic` derive macro /// instead of implementing everything in `rustc_middle`. diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 0d5818bd39c..4beac931632 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1489,6 +1489,8 @@ options! { "keep hygiene data after analysis (default: no)"), layout_seed: Option<u64> = (None, parse_opt_number, [TRACKED], "seed layout randomization"), + link_directives: bool = (true, parse_bool, [TRACKED], + "honor #[link] directives in the compiled crate (default: yes)"), link_native_libraries: bool = (true, parse_bool, [UNTRACKED], "link native libraries in the linker invocation (default: yes)"), link_only: bool = (false, parse_bool, [TRACKED], @@ -1567,8 +1569,6 @@ options! { "parse only; do not compile, assemble, or link (default: no)"), perf_stats: bool = (false, parse_bool, [UNTRACKED], "print some performance-related statistics (default: no)"), - pick_stable_methods_before_any_unstable: bool = (true, parse_bool, [TRACKED], - "try to pick stable methods first before picking any unstable methods (default: yes)"), plt: Option<bool> = (None, parse_opt_bool, [TRACKED], "whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index cbdcc5581e5..4e8c3f73e29 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -226,8 +226,8 @@ pub struct ParseSess { impl ParseSess { /// Used for testing. - pub fn new(file_path_mapping: FilePathMapping) -> Self { - let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + pub fn new(locale_resources: Vec<&'static str>, file_path_mapping: FilePathMapping) -> Self { + let fallback_bundle = fallback_fluent_bundle(locale_resources, false); let sm = Lrc::new(SourceMap::new(file_path_mapping)); let handler = Handler::with_tty_emitter( ColorConfig::Auto, @@ -265,7 +265,7 @@ impl ParseSess { } pub fn with_silent_emitter(fatal_note: Option<String>) -> Self { - let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = fallback_fluent_bundle(Vec::new(), false); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); let fatal_handler = Handler::with_tty_emitter(ColorConfig::Auto, false, None, None, None, fallback_bundle); diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 3dc09854b3c..446ba63ed1c 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1341,6 +1341,7 @@ pub fn build_session( io: CompilerIO, bundle: Option<Lrc<rustc_errors::FluentBundle>>, registry: rustc_errors::registry::Registry, + fluent_resources: Vec<&'static str>, driver_lint_caps: FxHashMap<lint::LintId, lint::Level>, file_loader: Option<Box<dyn FileLoader + Send + Sync + 'static>>, target_override: Option<Target>, @@ -1385,7 +1386,7 @@ pub fn build_session( )); let fallback_bundle = fallback_fluent_bundle( - rustc_errors::DEFAULT_LOCALE_RESOURCES, + fluent_resources, sopts.unstable_opts.translate_directionality_markers, ); let emitter = default_emitter(&sopts, registry, source_map.clone(), bundle, fallback_bundle); @@ -1630,7 +1631,10 @@ pub enum IncrCompSession { } fn early_error_handler(output: config::ErrorOutputType) -> rustc_errors::Handler { - let fallback_bundle = fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + // FIXME(#100717): early errors aren't translated at the moment, so this is fine, but it will + // need to reference every crate that might emit an early error for translation to work. + let fallback_bundle = + fallback_fluent_bundle(vec![rustc_errors::DEFAULT_LOCALE_RESOURCE], false); let emitter: Box<dyn Emitter + sync::Send> = match output { config::ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index e112100aa5f..873cd33f6a4 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -2149,3 +2149,17 @@ where Hash::hash(&len, hasher); } } + +/// Useful type to use with `Result<>` indicate that an error has already +/// been reported to the user, so no need to continue checking. +#[derive(Clone, Copy, Debug, Encodable, Decodable, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(HashStable_Generic)] +pub struct ErrorGuaranteed(()); + +impl ErrorGuaranteed { + /// To be used only if you really know what you are doing... ideally, we would find a way to + /// eliminate all calls to this method. + pub fn unchecked_claim_error_was_emitted() -> Self { + ErrorGuaranteed(()) + } +} diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 37d2aea42ad..fb579e4ff77 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -740,6 +740,7 @@ symbols! { frem_fast, from, from_desugaring, + from_fn, from_iter, from_method, from_output, diff --git a/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl b/compiler/rustc_symbol_mangling/locales/en-US.ftl index b7d48280f46..b7d48280f46 100644 --- a/compiler/rustc_error_messages/locales/en-US/symbol_mangling.ftl +++ b/compiler/rustc_symbol_mangling/locales/en-US.ftl diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 744e8a4320e..2368468c891 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -3,7 +3,7 @@ use rustc_hir::def_id::CrateNum; use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::ty::print::{PrettyPrinter, Print, Printer}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::util::common::record_time; use std::fmt::{self, Write}; diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index d81722e59a6..d9ce7373483 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -100,8 +100,10 @@ extern crate rustc_middle; #[macro_use] extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; use rustc_hir::def::DefKind; use rustc_hir::def_id::{CrateNum, LOCAL_CRATE}; +use rustc_macros::fluent_messages; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::mir::mono::{InstantiationMode, MonoItem}; @@ -117,6 +119,8 @@ pub mod errors; pub mod test; pub mod typeid; +fluent_messages! { "../locales/en-US.ftl" } + /// This function computes the symbol name for the given `instance` and the /// given instantiating crate. That is, if you know that instance X is /// instantiated in crate Y, this is the symbol name this instance would have. diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 59a2227cd36..1a679f32ca5 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -396,6 +396,7 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String { hir::definitions::DefPathData::CrateRoot | hir::definitions::DefPathData::Use | hir::definitions::DefPathData::GlobalAsm + | hir::definitions::DefPathData::ImplTraitAssocTy | hir::definitions::DefPathData::MacroNs(..) | hir::definitions::DefPathData::LifetimeNs(..) => { bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data); @@ -674,7 +675,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio _ if ty.is_unit() => {} ty::Tuple(tys) => { - ty = tcx.mk_tup(tys.iter().map(|ty| transform_ty(tcx, ty, options))); + ty = tcx.mk_tup_from_iter(tys.iter().map(|ty| transform_ty(tcx, ty, options))); } ty::Array(ty0, len) => { @@ -824,7 +825,7 @@ fn transform_substs<'tcx>( subst } }); - tcx.mk_substs(substs) + tcx.mk_substs_from_iter(substs) } /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index c58b6a24ab5..2f20d42139c 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -8,7 +8,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::print::{Print, Printer}; use rustc_middle::ty::{ - self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, UintTy, + self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt, + UintTy, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::kw; @@ -204,7 +205,7 @@ impl<'tcx> SymbolMangler<'tcx> { print_value: impl FnOnce(&'a mut Self, &T) -> Result<&'a mut Self, !>, ) -> Result<&'a mut Self, !> where - T: TypeVisitable<'tcx>, + T: TypeVisitable<TyCtxt<'tcx>>, { // FIXME(non-lifetime-binders): What to do here? let regions = if value.has_late_bound_regions() { @@ -791,6 +792,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { | DefPathData::Use | DefPathData::GlobalAsm | DefPathData::Impl + | DefPathData::ImplTraitAssocTy | DefPathData::MacroNs(_) | DefPathData::LifetimeNs(_) => { bug!("symbol_names: unexpected DefPathData: {:?}", disambiguated_data.data) diff --git a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl b/compiler/rustc_trait_selection/locales/en-US.ftl index 14eb4a5502d..14eb4a5502d 100644 --- a/compiler/rustc_error_messages/locales/en-US/trait_selection.ftl +++ b/compiler/rustc_trait_selection/locales/en-US.ftl diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs index 4405537c645..df7c4df1868 100644 --- a/compiler/rustc_trait_selection/src/errors.rs +++ b/compiler/rustc_trait_selection/src/errors.rs @@ -1,4 +1,5 @@ -use rustc_errors::{fluent, ErrorGuaranteed, Handler, IntoDiagnostic}; +use crate::fluent_generated as fluent; +use rustc_errors::{ErrorGuaranteed, Handler, IntoDiagnostic}; use rustc_macros::Diagnostic; use rustc_middle::ty::{self, PolyTraitRef, Ty}; use rustc_span::{Span, Symbol}; @@ -69,19 +70,19 @@ impl IntoDiagnostic<'_> for NegativePositiveConflict<'_> { diag.code(rustc_errors::error_code!(E0751)); match self.negative_impl_span { Ok(span) => { - diag.span_label(span, fluent::negative_implementation_here); + diag.span_label(span, fluent::trait_selection_negative_implementation_here); } Err(cname) => { - diag.note(fluent::negative_implementation_in_crate); + diag.note(fluent::trait_selection_negative_implementation_in_crate); diag.set_arg("negative_impl_cname", cname.to_string()); } } match self.positive_impl_span { Ok(span) => { - diag.span_label(span, fluent::positive_implementation_here); + diag.span_label(span, fluent::trait_selection_positive_implementation_here); } Err(cname) => { - diag.note(fluent::positive_implementation_in_crate); + diag.note(fluent::trait_selection_positive_implementation_in_crate); diag.set_arg("positive_impl_cname", cname.to_string()); } } diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index c0bfe152a1e..9b47c7299bb 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -6,7 +6,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalQueryResponse, QueryResponse}; use rustc_middle::traits::query::Fallible; -use rustc_middle::ty::{self, Ty, TypeFoldable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, ToPredicate}; use rustc_span::{Span, DUMMY_SP}; @@ -42,7 +42,7 @@ pub trait InferCtxtExt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult; } @@ -82,7 +82,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params); @@ -104,8 +104,8 @@ pub trait InferCtxtBuilderExt<'tcx> { operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>, ) -> Fallible<CanonicalQueryResponse<'tcx, R>> where - K: TypeFoldable<'tcx>, - R: Debug + TypeFoldable<'tcx>, + K: TypeFoldable<TyCtxt<'tcx>>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>; } @@ -125,15 +125,15 @@ impl<'tcx> InferCtxtBuilderExt<'tcx> for InferCtxtBuilder<'tcx> { /// In part because we would need a `for<'tcx>` sort of /// bound for the closure and in part because it is convenient to /// have `'tcx` be free on this function so that we can talk about - /// `K: TypeFoldable<'tcx>`.) + /// `K: TypeFoldable<TyCtxt<'tcx>>`.) fn enter_canonical_trait_query<K, R>( &mut self, canonical_key: &Canonical<'tcx, K>, operation: impl FnOnce(&ObligationCtxt<'_, 'tcx>, K) -> Fallible<R>, ) -> Fallible<CanonicalQueryResponse<'tcx, R>> where - K: TypeFoldable<'tcx>, - R: Debug + TypeFoldable<'tcx>, + K: TypeFoldable<TyCtxt<'tcx>>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>, { let (infcx, key, canonical_inference_vars) = diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 6fa09410363..548b42cef43 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -36,7 +36,12 @@ extern crate rustc_middle; #[macro_use] extern crate smallvec; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; + pub mod errors; pub mod infer; pub mod solve; pub mod traits; + +fluent_messages! { "../locales/en-US.ftl" } diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 841169ac78d..dec9f8016b0 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -1,6 +1,5 @@ //! Code shared by trait and projection goals for candidate assembly. -use super::infcx_ext::InferCtxtExt; #[cfg(doc)] use super::trait_goals::structural_traits::*; use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult}; @@ -83,7 +82,7 @@ pub(super) enum CandidateSource { } /// Methods used to assemble candidates for either trait or projection goals. -pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq { +pub(super) trait GoalKind<'tcx>: TypeFoldable<TyCtxt<'tcx>> + Copy + Eq { fn self_ty(self) -> Ty<'tcx>; fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self; @@ -100,6 +99,15 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq { requirements: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>, ) -> QueryResult<'tcx>; + // Consider a clause specifically for a `dyn Trait` self type. This requires + // additionally checking all of the supertraits and object bounds to hold, + // since they're not implied by the well-formedness of the object type. + fn consider_object_bound_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + assumption: ty::Predicate<'tcx>, + ) -> QueryResult<'tcx>; + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, @@ -206,7 +214,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { &mut self, goal: Goal<'tcx, G>, ) -> Vec<Candidate<'tcx>> { - debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal)); + debug_assert_eq!(goal, self.resolve_vars_if_possible(goal)); // HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule, // object bound, alias bound, etc. We are unable to determine this until we can at @@ -250,8 +258,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let &ty::Alias(ty::Projection, projection_ty) = goal.predicate.self_ty().kind() else { return }; - self.infcx.probe(|_| { - let normalized_ty = self.infcx.next_ty_infer(); + self.probe(|this| { + let normalized_ty = this.next_ty_infer(); let normalizes_to_goal = goal.with( tcx, ty::Binder::dummy(ty::ProjectionPredicate { @@ -259,16 +267,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { term: normalized_ty.into(), }), ); - let normalization_certainty = match self.evaluate_goal(normalizes_to_goal) { + let normalization_certainty = match this.evaluate_goal(normalizes_to_goal) { Ok((_, certainty)) => certainty, Err(NoSolution) => return, }; - let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty); + let normalized_ty = this.resolve_vars_if_possible(normalized_ty); // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate. // This doesn't work as long as we use `CandidateSource` in winnowing. let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); - let normalized_candidates = self.assemble_and_evaluate_candidates(goal); + let normalized_candidates = this.assemble_and_evaluate_candidates(goal); for mut normalized_candidate in normalized_candidates { normalized_candidate.result = normalized_candidate.result.unchecked_map(|mut response| { @@ -456,7 +464,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty))) { - match G::consider_implied_clause(self, goal, assumption.predicate, []) { + match G::consider_object_bound_candidate(self, goal, assumption.predicate) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }) } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs new file mode 100644 index 00000000000..c8097e81953 --- /dev/null +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -0,0 +1,175 @@ +use rustc_hir::def_id::DefId; +use rustc_infer::infer::at::ToTrace; +use rustc_infer::infer::canonical::CanonicalVarValues; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; +use rustc_infer::traits::query::NoSolution; +use rustc_infer::traits::ObligationCause; +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, + TypeVisitor, +}; +use rustc_span::DUMMY_SP; +use std::ops::ControlFlow; + +use super::search_graph::SearchGraph; +use super::Goal; + +pub struct EvalCtxt<'a, 'tcx> { + // FIXME: should be private. + pub(super) infcx: &'a InferCtxt<'tcx>, + + pub(super) var_values: CanonicalVarValues<'tcx>, + + pub(super) search_graph: &'a mut SearchGraph<'tcx>, + + /// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`], + /// see the comment in that method for more details. + pub in_projection_eq_hack: bool, +} + +impl<'tcx> EvalCtxt<'_, 'tcx> { + pub(super) fn probe<T>(&mut self, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> T) -> T { + self.infcx.probe(|_| f(self)) + } + + pub(super) fn tcx(&self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + pub(super) fn next_ty_infer(&self) -> Ty<'tcx> { + self.infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span: DUMMY_SP, + }) + } + + pub(super) fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { + self.infcx.next_const_var( + ty, + ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP }, + ) + } + + /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`. + /// + /// This is the case if the `term` is an inference variable in the innermost universe + /// and does not occur in any other part of the predicate. + pub(super) fn term_is_fully_unconstrained( + &self, + goal: Goal<'tcx, ty::ProjectionPredicate<'tcx>>, + ) -> bool { + let term_is_infer = match goal.predicate.term.unpack() { + ty::TermKind::Ty(ty) => { + if let &ty::Infer(ty::TyVar(vid)) = ty.kind() { + match self.infcx.probe_ty_var(vid) { + Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), + Err(universe) => universe == self.universe(), + } + } else { + false + } + } + ty::TermKind::Const(ct) => { + if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { + match self.infcx.probe_const_var(vid) { + Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), + Err(universe) => universe == self.universe(), + } + } else { + false + } + } + }; + + // Guard against `<T as Trait<?0>>::Assoc = ?0>`. + struct ContainsTerm<'tcx> { + term: ty::Term<'tcx>, + } + impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> { + type BreakTy = (); + fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { + if t.needs_infer() { + if ty::Term::from(t) == self.term { + ControlFlow::Break(()) + } else { + t.super_visit_with(self) + } + } else { + ControlFlow::Continue(()) + } + } + + fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { + if c.needs_infer() { + if ty::Term::from(c) == self.term { + ControlFlow::Break(()) + } else { + c.super_visit_with(self) + } + } else { + ControlFlow::Continue(()) + } + } + } + + let mut visitor = ContainsTerm { term: goal.predicate.term }; + + term_is_infer + && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue() + && goal.param_env.visit_with(&mut visitor).is_continue() + } + + #[instrument(level = "debug", skip(self, param_env), ret)] + pub(super) fn eq<T: ToTrace<'tcx>>( + &self, + param_env: ty::ParamEnv<'tcx>, + lhs: T, + rhs: T, + ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> { + self.infcx + .at(&ObligationCause::dummy(), param_env) + .eq(lhs, rhs) + .map(|InferOk { value: (), obligations }| { + obligations.into_iter().map(|o| o.into()).collect() + }) + .map_err(|e| { + debug!(?e, "failed to equate"); + NoSolution + }) + } + + pub(super) fn instantiate_binder_with_infer<T: TypeFoldable<TyCtxt<'tcx>> + Copy>( + &self, + value: ty::Binder<'tcx, T>, + ) -> T { + self.infcx.instantiate_binder_with_fresh_vars( + DUMMY_SP, + LateBoundRegionConversionTime::HigherRankedType, + value, + ) + } + + pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<TyCtxt<'tcx>> + Copy>( + &self, + value: ty::Binder<'tcx, T>, + ) -> T { + self.infcx.instantiate_binder_with_placeholders(value) + } + + pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T + where + T: TypeFoldable<TyCtxt<'tcx>>, + { + self.infcx.resolve_vars_if_possible(value) + } + + pub(super) fn fresh_substs_for_item(&self, def_id: DefId) -> ty::SubstsRef<'tcx> { + self.infcx.fresh_substs_for_item(DUMMY_SP, def_id) + } + + pub(super) fn universe(&self) -> ty::UniverseIndex { + self.infcx.universe() + } +} diff --git a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs b/compiler/rustc_trait_selection/src/solve/infcx_ext.rs deleted file mode 100644 index 36f987c9f9c..00000000000 --- a/compiler/rustc_trait_selection/src/solve/infcx_ext.rs +++ /dev/null @@ -1,78 +0,0 @@ -use rustc_infer::infer::at::ToTrace; -use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; -use rustc_infer::traits::query::NoSolution; -use rustc_infer::traits::ObligationCause; -use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::ty::{self, Ty, TypeFoldable}; -use rustc_span::DUMMY_SP; - -use super::Goal; - -/// Methods used inside of the canonical queries of the solver. -/// -/// Most notably these do not care about diagnostics information. -/// If you find this while looking for methods to use outside of the -/// solver, you may look at the implementation of these method for -/// help. -pub(super) trait InferCtxtExt<'tcx> { - fn next_ty_infer(&self) -> Ty<'tcx>; - fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx>; - - fn eq<T: ToTrace<'tcx>>( - &self, - param_env: ty::ParamEnv<'tcx>, - lhs: T, - rhs: T, - ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution>; - - fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>( - &self, - value: ty::Binder<'tcx, T>, - ) -> T; -} - -impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { - fn next_ty_infer(&self) -> Ty<'tcx> { - self.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::MiscVariable, - span: DUMMY_SP, - }) - } - fn next_const_infer(&self, ty: Ty<'tcx>) -> ty::Const<'tcx> { - self.next_const_var( - ty, - ConstVariableOrigin { kind: ConstVariableOriginKind::MiscVariable, span: DUMMY_SP }, - ) - } - - #[instrument(level = "debug", skip(self, param_env), ret)] - fn eq<T: ToTrace<'tcx>>( - &self, - param_env: ty::ParamEnv<'tcx>, - lhs: T, - rhs: T, - ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> { - self.at(&ObligationCause::dummy(), param_env) - .define_opaque_types(false) - .eq(lhs, rhs) - .map(|InferOk { value: (), obligations }| { - obligations.into_iter().map(|o| o.into()).collect() - }) - .map_err(|e| { - debug!(?e, "failed to equate"); - NoSolution - }) - } - - fn instantiate_binder_with_infer<T: TypeFoldable<'tcx> + Copy>( - &self, - value: ty::Binder<'tcx, T>, - ) -> T { - self.instantiate_binder_with_fresh_vars( - DUMMY_SP, - LateBoundRegionConversionTime::HigherRankedType, - value, - ) - } -} diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 6890811fd04..71f536dd3cb 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -35,16 +35,15 @@ use crate::solve::search_graph::OverflowHandler; use crate::traits::ObligationCause; mod assembly; +mod eval_ctxt; mod fulfill; -mod infcx_ext; mod project_goals; mod search_graph; mod trait_goals; +pub use eval_ctxt::EvalCtxt; pub use fulfill::FulfillmentCtxt; -use self::infcx_ext::InferCtxtExt; - /// A goal is a statement, i.e. `predicate`, we want to prove /// given some assumptions, i.e. `param_env`. /// @@ -180,22 +179,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> { } } -struct EvalCtxt<'a, 'tcx> { - infcx: &'a InferCtxt<'tcx>, - var_values: CanonicalVarValues<'tcx>, - - search_graph: &'a mut search_graph::SearchGraph<'tcx>, - - /// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`], - /// see the comment in that method for more details. - in_projection_eq_hack: bool, -} - impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - /// The entry point of the solver. /// /// This function deals with (coinductive) cycles, overflow, and caching @@ -427,7 +411,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { let evaluate_normalizes_to = |ecx: &mut EvalCtxt<'_, 'tcx>, alias, other| { debug!("evaluate_normalizes_to(alias={:?}, other={:?})", alias, other); - let r = ecx.infcx.probe(|_| { + let r = ecx.probe(|ecx| { let (_, certainty) = ecx.evaluate_goal(goal.with( tcx, ty::Binder::dummy(ty::ProjectionPredicate { @@ -462,10 +446,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { // Evaluate all 3 potential candidates for the alias' being equal candidates.push(evaluate_normalizes_to(self, alias_lhs, goal.predicate.1)); candidates.push(evaluate_normalizes_to(self, alias_rhs, goal.predicate.0)); - candidates.push(self.infcx.probe(|_| { + candidates.push(self.probe(|this| { debug!("compute_alias_eq_goal: alias defids are equal, equating substs"); - let nested_goals = self.infcx.eq(goal.param_env, alias_lhs, alias_rhs)?; - self.evaluate_all_and_make_canonical_response(nested_goals) + let nested_goals = this.eq(goal.param_env, alias_lhs, alias_rhs)?; + this.evaluate_all_and_make_canonical_response(nested_goals) })); debug!(?candidates); @@ -481,7 +465,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, (ty::Const<'tcx>, Ty<'tcx>)>, ) -> QueryResult<'tcx> { let (ct, ty) = goal.predicate; - let nested_goals = self.infcx.eq(goal.param_env, ct.ty(), ty)?; + let nested_goals = self.eq(goal.param_env, ct.ty(), ty)?; self.evaluate_all_and_make_canonical_response(nested_goals) } } @@ -583,7 +567,7 @@ fn compute_external_query_constraints<'tcx>( ) -> Result<ExternalConstraints<'tcx>, NoSolution> { let region_obligations = infcx.take_registered_region_obligations(); let opaque_types = infcx.take_opaque_types_for_query_response(); - Ok(infcx.tcx.intern_external_constraints(ExternalConstraintsData { + Ok(infcx.tcx.mk_external_constraints(ExternalConstraintsData { // FIXME: Now that's definitely wrong :) // // Should also do the leak check here I think @@ -632,8 +616,7 @@ pub(super) fn response_no_constraints<'tcx>( var_values: CanonicalVarValues::make_identity(tcx, goal.variables), // FIXME: maybe we should store the "no response" version in tcx, like // we do for tcx.types and stuff. - external_constraints: tcx - .intern_external_constraints(ExternalConstraintsData::default()), + external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()), certainty, }, }) diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 48153b465b7..88fd8bb8bd0 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -1,7 +1,6 @@ use crate::traits::{specialization_graph, translate_substs}; use super::assembly; -use super::infcx_ext::InferCtxtExt; use super::trait_goals::structural_traits; use super::{Certainty, EvalCtxt, Goal, QueryResult}; use rustc_errors::ErrorGuaranteed; @@ -13,12 +12,11 @@ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::specialization_graph::LeafDef; use rustc_infer::traits::Reveal; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; +use rustc_middle::ty::ProjectionPredicate; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_middle::ty::{ir::TypeVisitor, ProjectionPredicate, TypeSuperVisitable}; -use rustc_middle::ty::{ToPredicate, TypeVisitable}; +use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; use rustc_span::{sym, DUMMY_SP}; use std::iter; -use std::ops::ControlFlow; impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn compute_projection_goal( @@ -38,8 +36,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { } else { let predicate = goal.predicate; let unconstrained_rhs = match predicate.term.unpack() { - ty::TermKind::Ty(_) => self.infcx.next_ty_infer().into(), - ty::TermKind::Const(ct) => self.infcx.next_const_infer(ct.ty()).into(), + ty::TermKind::Ty(_) => self.next_ty_infer().into(), + ty::TermKind::Const(ct) => self.next_const_infer(ct.ty()).into(), }; let unconstrained_predicate = ty::Clause::Projection(ProjectionPredicate { projection_ty: goal.predicate.projection_ty, @@ -49,8 +47,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { this.evaluate_goal(goal.with(this.tcx(), unconstrained_predicate)) })?; - let nested_eq_goals = - self.infcx.eq(goal.param_env, unconstrained_rhs, predicate.term)?; + let nested_eq_goals = self.eq(goal.param_env, unconstrained_rhs, predicate.term)?; let eval_certainty = self.evaluate_all(nested_eq_goals)?; self.make_canonical_response(normalize_certainty.unify_and(eval_certainty)) } @@ -65,73 +62,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { result } - /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`. - /// - /// This is the case if the `term` is an inference variable in the innermost universe - /// and does not occur in any other part of the predicate. - fn term_is_fully_unconstrained(&self, goal: Goal<'tcx, ProjectionPredicate<'tcx>>) -> bool { - let infcx = self.infcx; - let term_is_infer = match goal.predicate.term.unpack() { - ty::TermKind::Ty(ty) => { - if let &ty::Infer(ty::TyVar(vid)) = ty.kind() { - match infcx.probe_ty_var(vid) { - Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == infcx.universe(), - } - } else { - false - } - } - ty::TermKind::Const(ct) => { - if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { - match self.infcx.probe_const_var(vid) { - Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == infcx.universe(), - } - } else { - false - } - } - }; - - // Guard against `<T as Trait<?0>>::Assoc = ?0>`. - struct ContainsTerm<'tcx> { - term: ty::Term<'tcx>, - } - impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> { - type BreakTy = (); - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - if t.needs_infer() { - if ty::Term::from(t) == self.term { - ControlFlow::Break(()) - } else { - t.super_visit_with(self) - } - } else { - ControlFlow::Continue(()) - } - } - - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - if c.needs_infer() { - if ty::Term::from(c) == self.term { - ControlFlow::Break(()) - } else { - c.super_visit_with(self) - } - } else { - ControlFlow::Continue(()) - } - } - } - - let mut visitor = ContainsTerm { term: goal.predicate.term }; - - term_is_infer - && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue() - && goal.param_env.visit_with(&mut visitor).is_continue() - } - /// After normalizing the projection to `normalized_alias` with the given /// `normalization_certainty`, constrain the inference variable `term` to it /// and return a query response. @@ -145,7 +75,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // // It can however be ambiguous when the `normalized_alias` contains a projection. let nested_goals = self - .infcx .eq(goal.param_env, goal.predicate.term, normalized_alias.into()) .expect("failed to unify with unconstrained term"); let rhs_certainty = @@ -177,10 +106,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() && poly_projection_pred.projection_def_id() == goal.predicate.def_id() { - ecx.infcx.probe(|_| { + ecx.probe(|ecx| { let assumption_projection_pred = - ecx.infcx.instantiate_binder_with_infer(poly_projection_pred); - let mut nested_goals = ecx.infcx.eq( + ecx.instantiate_binder_with_infer(poly_projection_pred); + let mut nested_goals = ecx.eq( goal.param_env, goal.predicate.projection_ty, assumption_projection_pred.projection_ty, @@ -199,6 +128,51 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { } } + fn consider_object_bound_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + assumption: ty::Predicate<'tcx>, + ) -> QueryResult<'tcx> { + if let Some(poly_projection_pred) = assumption.to_opt_poly_projection_pred() + && poly_projection_pred.projection_def_id() == goal.predicate.def_id() + { + ecx.probe(|ecx| { + let assumption_projection_pred = + ecx.instantiate_binder_with_infer(poly_projection_pred); + let mut nested_goals = ecx.eq( + goal.param_env, + goal.predicate.projection_ty, + assumption_projection_pred.projection_ty, + )?; + + let tcx = ecx.tcx(); + let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { + bug!("expected object type in `consider_object_bound_candidate`"); + }; + nested_goals.extend( + structural_traits::predicates_for_object_candidate( + ecx, + goal.param_env, + goal.predicate.projection_ty.trait_ref(tcx), + bounds, + ) + .into_iter() + .map(|pred| goal.with(tcx, pred)), + ); + + let subst_certainty = ecx.evaluate_all(nested_goals)?; + + ecx.eq_term_and_make_canonical_response( + goal, + subst_certainty, + assumption_projection_pred.term, + ) + }) + } else { + Err(NoSolution) + } + } + fn consider_impl_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, ProjectionPredicate<'tcx>>, @@ -215,11 +189,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { return Err(NoSolution); } - ecx.infcx.probe(|_| { - let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + ecx.probe(|ecx| { + let impl_substs = ecx.fresh_substs_for_item(impl_def_id); let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs); - let mut nested_goals = ecx.infcx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; + let mut nested_goals = ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?; let where_clause_bounds = tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_substs) @@ -367,7 +341,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { let tcx = ecx.tcx(); - ecx.infcx.probe(|_| { + ecx.probe(|ecx| { let metadata_ty = match goal.predicate.self_ty().kind() { ty::Bool | ty::Char @@ -387,7 +361,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { | ty::Never | ty::Foreign(..) => tcx.types.unit, - ty::Error(e) => tcx.ty_error_with_guaranteed(*e), + ty::Error(e) => tcx.ty_error(*e), ty::Str | ty::Slice(_) => tcx.types.usize, @@ -546,8 +520,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { let discriminant = goal.predicate.self_ty().discriminant_ty(ecx.tcx()); - ecx.infcx - .probe(|_| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant)) + ecx.probe(|ecx| ecx.eq_term_and_make_canonical_response(goal, Certainty::Yes, discriminant)) } } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index f2f25ef850a..5c499c36e9b 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -3,16 +3,14 @@ use std::iter; use super::assembly; -use super::infcx_ext::InferCtxtExt; use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult}; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::util::supertraits; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; -use rustc_middle::ty::{TraitPredicate, TypeVisitable}; +use rustc_middle::ty::{TraitPredicate, TypeVisitableExt}; use rustc_span::DUMMY_SP; pub mod structural_traits; @@ -45,12 +43,12 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { return Err(NoSolution); } - ecx.infcx.probe(|_| { - let impl_substs = ecx.infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); + ecx.probe(|ecx| { + let impl_substs = ecx.fresh_substs_for_item(impl_def_id); let impl_trait_ref = impl_trait_ref.subst(tcx, impl_substs); let mut nested_goals = - ecx.infcx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; + ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?; let where_clause_bounds = tcx .predicates_of(impl_def_id) .instantiate(tcx, impl_substs) @@ -72,10 +70,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { && poly_trait_pred.def_id() == goal.predicate.def_id() { // FIXME: Constness and polarity - ecx.infcx.probe(|_| { + ecx.probe(|ecx| { let assumption_trait_pred = - ecx.infcx.instantiate_binder_with_infer(poly_trait_pred); - let mut nested_goals = ecx.infcx.eq( + ecx.instantiate_binder_with_infer(poly_trait_pred); + let mut nested_goals = ecx.eq( goal.param_env, goal.predicate.trait_ref, assumption_trait_pred.trait_ref, @@ -88,6 +86,46 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } } + fn consider_object_bound_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + assumption: ty::Predicate<'tcx>, + ) -> QueryResult<'tcx> { + if let Some(poly_trait_pred) = assumption.to_opt_poly_trait_pred() + && poly_trait_pred.def_id() == goal.predicate.def_id() + { + // FIXME: Constness and polarity + ecx.probe(|ecx| { + let assumption_trait_pred = + ecx.instantiate_binder_with_infer(poly_trait_pred); + let mut nested_goals = ecx.eq( + goal.param_env, + goal.predicate.trait_ref, + assumption_trait_pred.trait_ref, + )?; + + let tcx = ecx.tcx(); + let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else { + bug!("expected object type in `consider_object_bound_candidate`"); + }; + nested_goals.extend( + structural_traits::predicates_for_object_candidate( + ecx, + goal.param_env, + goal.predicate.trait_ref, + bounds, + ) + .into_iter() + .map(|pred| goal.with(tcx, pred)), + ); + + ecx.evaluate_all_and_make_canonical_response(nested_goals) + }) + } else { + Err(NoSolution) + } + } + fn consider_auto_trait_candidate( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, @@ -118,7 +156,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { ) -> QueryResult<'tcx> { let tcx = ecx.tcx(); - ecx.infcx.probe(|_| { + ecx.probe(|ecx| { let nested_obligations = tcx .predicates_of(goal.predicate.def_id()) .instantiate(tcx, goal.predicate.trait_ref.substs); @@ -275,7 +313,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { if b_ty.is_ty_var() { return ecx.make_canonical_response(Certainty::AMBIGUOUS); } - ecx.infcx.probe(|_| { + ecx.probe(|ecx| { match (a_ty.kind(), b_ty.kind()) { // Trait upcasting, or `dyn Trait + Auto + 'a` -> `dyn Trait + 'b` (&ty::Dynamic(_, _, ty::Dyn), &ty::Dynamic(_, _, ty::Dyn)) => { @@ -318,7 +356,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `[T; n]` -> `[T]` unsizing (&ty::Array(a_elem_ty, ..), &ty::Slice(b_elem_ty)) => { // We just require that the element type stays the same - let nested_goals = ecx.infcx.eq(goal.param_env, a_elem_ty, b_elem_ty)?; + let nested_goals = ecx.eq(goal.param_env, a_elem_ty, b_elem_ty)?; ecx.evaluate_all_and_make_canonical_response(nested_goals) } // Struct unsizing `Struct<T>` -> `Struct<U>` where `T: Unsize<U>` @@ -345,14 +383,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // Substitute just the unsizing params from B into A. The type after // this substitution must be equal to B. This is so we don't unsize // unrelated type parameters. - let new_a_substs = tcx.mk_substs(a_substs.iter().enumerate().map(|(i, a)| { - if unsizing_params.contains(i as u32) { b_substs[i] } else { a } - })); + let new_a_substs = + tcx.mk_substs_from_iter(a_substs.iter().enumerate().map(|(i, a)| { + if unsizing_params.contains(i as u32) { b_substs[i] } else { a } + })); let unsized_a_ty = tcx.mk_adt(a_def, new_a_substs); // Finally, we require that `TailA: Unsize<TailB>` for the tail field // types. - let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?; + let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?; nested_goals.push(goal.with( tcx, ty::Binder::dummy( @@ -370,8 +409,9 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let b_last_ty = b_tys.last().unwrap(); // Substitute just the tail field of B., and require that they're equal. - let unsized_a_ty = tcx.mk_tup(a_rest_tys.iter().chain([b_last_ty]).copied()); - let mut nested_goals = ecx.infcx.eq(goal.param_env, unsized_a_ty, b_ty)?; + let unsized_a_ty = + tcx.mk_tup_from_iter(a_rest_tys.iter().chain([b_last_ty]).copied()); + let mut nested_goals = ecx.eq(goal.param_env, unsized_a_ty, b_ty)?; // Similar to ADTs, require that the rest of the fields are equal. nested_goals.push(goal.with( @@ -411,7 +451,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } let mut unsize_dyn_to_principal = |principal: Option<ty::PolyExistentialTraitRef<'tcx>>| { - ecx.infcx.probe(|_| -> Result<_, NoSolution> { + ecx.probe(|ecx| -> Result<_, NoSolution> { // Require that all of the trait predicates from A match B, except for // the auto traits. We do this by constructing a new A type with B's // auto traits, and equating these types. @@ -427,11 +467,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { .map(ty::ExistentialPredicate::AutoTrait) .map(ty::Binder::dummy), ); - let new_a_data = tcx.mk_poly_existential_predicates(new_a_data); + let new_a_data = tcx.mk_poly_existential_predicates_from_iter(new_a_data); let new_a_ty = tcx.mk_dynamic(new_a_data, b_region, ty::Dyn); // We also require that A's lifetime outlives B's lifetime. - let mut nested_obligations = ecx.infcx.eq(goal.param_env, new_a_ty, b_ty)?; + let mut nested_obligations = ecx.eq(goal.param_env, new_a_ty, b_ty)?; nested_obligations.push( goal.with(tcx, ty::Binder::dummy(ty::OutlivesPredicate(a_region, b_region))), ); @@ -482,16 +522,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { fn probe_and_evaluate_goal_for_constituent_tys( &mut self, goal: Goal<'tcx, TraitPredicate<'tcx>>, - constituent_tys: impl Fn(&InferCtxt<'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>, + constituent_tys: impl Fn(&EvalCtxt<'_, 'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>, ) -> QueryResult<'tcx> { - self.infcx.probe(|_| { - self.evaluate_all_and_make_canonical_response( - constituent_tys(self.infcx, goal.predicate.self_ty())? + self.probe(|this| { + this.evaluate_all_and_make_canonical_response( + constituent_tys(this, goal.predicate.self_ty())? .into_iter() .map(|ty| { goal.with( - self.tcx(), - ty::Binder::dummy(goal.predicate.with_self_ty(self.tcx(), ty)), + this.tcx(), + ty::Binder::dummy(goal.predicate.with_self_ty(this.tcx(), ty)), ) }) .collect(), diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 3662463178f..d7d93377cf1 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -1,16 +1,19 @@ -use rustc_hir::{Movability, Mutability}; -use rustc_infer::{infer::InferCtxt, traits::query::NoSolution}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::{def_id::DefId, Movability, Mutability}; +use rustc_infer::traits::query::NoSolution; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; + +use crate::solve::EvalCtxt; // Calculates the constituent types of a type for `auto trait` purposes. // // For types with an "existential" binder, i.e. generator witnesses, we also // instantiate the binder with placeholders eagerly. pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( - infcx: &InferCtxt<'tcx>, + ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, ) -> Result<Vec<Ty<'tcx>>, NoSolution> { - let tcx = infcx.tcx; + let tcx = ecx.tcx(); match *ty.kind() { ty::Uint(_) | ty::Int(_) @@ -18,12 +21,14 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never | ty::Char => Ok(vec![]), + // Treat this like `struct str([u8]);` + ty::Str => Ok(vec![tcx.mk_slice(tcx.types.u8)]), + ty::Dynamic(..) | ty::Param(..) | ty::Foreign(..) @@ -53,9 +58,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( Ok(vec![generator_substs.tupled_upvars_ty(), generator_substs.witness()]) } - ty::GeneratorWitness(types) => { - Ok(infcx.instantiate_binder_with_placeholders(types).to_vec()) - } + ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), ty::GeneratorWitnessMIR(..) => todo!(), @@ -74,7 +77,7 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>( - infcx: &InferCtxt<'tcx>, + ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, ) -> Result<Vec<Ty<'tcx>>, NoSolution> { match *ty.kind() { @@ -113,18 +116,18 @@ pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ty::Tuple(tys) => Ok(tys.to_vec()), ty::Adt(def, substs) => { - let sized_crit = def.sized_constraint(infcx.tcx); + let sized_crit = def.sized_constraint(ecx.tcx()); Ok(sized_crit .0 .iter() - .map(|ty| sized_crit.rebind(*ty).subst(infcx.tcx, substs)) + .map(|ty| sized_crit.rebind(*ty).subst(ecx.tcx(), substs)) .collect()) } } } pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( - infcx: &InferCtxt<'tcx>, + ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, ) -> Result<Vec<Ty<'tcx>>, NoSolution> { match *ty.kind() { @@ -165,7 +168,7 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ty::Closure(_, substs) => Ok(vec![substs.as_closure().tupled_upvars_ty()]), ty::Generator(_, substs, Movability::Movable) => { - if infcx.tcx.features().generator_clone { + if ecx.tcx().features().generator_clone { let generator = substs.as_generator(); Ok(vec![generator.tupled_upvars_ty(), generator.witness()]) } else { @@ -173,9 +176,7 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( } } - ty::GeneratorWitness(types) => { - Ok(infcx.instantiate_binder_with_placeholders(types).to_vec()) - } + ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), ty::GeneratorWitnessMIR(..) => todo!(), } @@ -191,11 +192,9 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( ty::FnDef(def_id, substs) => Ok(Some( tcx.fn_sig(def_id) .subst(tcx, substs) - .map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())), + .map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())), )), - ty::FnPtr(sig) => { - Ok(Some(sig.map_bound(|sig| (tcx.intern_tup(sig.inputs()), sig.output())))) - } + ty::FnPtr(sig) => Ok(Some(sig.map_bound(|sig| (tcx.mk_tup(sig.inputs()), sig.output())))), ty::Closure(_, substs) => { let closure_substs = substs.as_closure(); match closure_substs.kind_ty().to_opt_closure_kind() { @@ -235,3 +234,112 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( } } } + +/// Assemble a list of predicates that would be present on a theoretical +/// user impl for an object type. These predicates must be checked any time +/// we assemble a built-in object candidate for an object type, since they +/// are not implied by the well-formedness of the type. +/// +/// For example, given the following traits: +/// +/// ```rust,ignore (theoretical code) +/// trait Foo: Baz { +/// type Bar: Copy; +/// } +/// +/// trait Baz {} +/// ``` +/// +/// For the dyn type `dyn Foo<Item = Ty>`, we can imagine there being a +/// pair of theoretical impls: +/// +/// ```rust,ignore (theoretical code) +/// impl Foo for dyn Foo<Item = Ty> +/// where +/// Self: Baz, +/// <Self as Foo>::Bar: Copy, +/// { +/// type Bar = Ty; +/// } +/// +/// impl Baz for dyn Foo<Item = Ty> {} +/// ``` +/// +/// However, in order to make such impls well-formed, we need to do an +/// additional step of eagerly folding the associated types in the where +/// clauses of the impl. In this example, that means replacing +/// `<Self as Foo>::Bar` with `Ty` in the first impl. +pub(crate) fn predicates_for_object_candidate<'tcx>( + ecx: &EvalCtxt<'_, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + trait_ref: ty::TraitRef<'tcx>, + object_bound: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, +) -> Vec<ty::Predicate<'tcx>> { + let tcx = ecx.tcx(); + let mut requirements = vec![]; + requirements.extend( + tcx.super_predicates_of(trait_ref.def_id).instantiate(tcx, trait_ref.substs).predicates, + ); + for item in tcx.associated_items(trait_ref.def_id).in_definition_order() { + // FIXME(associated_const_equality): Also add associated consts to + // the requirements here. + if item.kind == ty::AssocKind::Type { + requirements.extend(tcx.item_bounds(item.def_id).subst(tcx, trait_ref.substs)); + } + } + + let mut replace_projection_with = FxHashMap::default(); + for bound in object_bound { + if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() { + let proj = proj.with_self_ty(tcx, trait_ref.self_ty()); + let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj)); + assert_eq!( + old_ty, + None, + "{} has two substitutions: {} and {}", + proj.projection_ty, + proj.term, + old_ty.unwrap() + ); + } + } + + requirements.fold_with(&mut ReplaceProjectionWith { + ecx, + param_env, + mapping: replace_projection_with, + }) +} + +struct ReplaceProjectionWith<'a, 'tcx> { + ecx: &'a EvalCtxt<'a, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + mapping: FxHashMap<DefId, ty::PolyProjectionPredicate<'tcx>>, +} + +impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReplaceProjectionWith<'_, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { + self.ecx.tcx() + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Alias(ty::Projection, alias_ty) = *ty.kind() + && let Some(replacement) = self.mapping.get(&alias_ty.def_id) + { + // We may have a case where our object type's projection bound is higher-ranked, + // but the where clauses we instantiated are not. We can solve this by instantiating + // the binder at the usage site. + let proj = self.ecx.instantiate_binder_with_infer(*replacement); + // FIXME: Technically this folder could be fallible? + let nested = self + .ecx + .eq(self.param_env, alias_ty, proj.projection_ty) + .expect("expected to be able to unify goal projection with dyn's projection"); + // FIXME: Technically we could register these too.. + assert!(nested.is_empty(), "did not expect unification to have any nested goals"); + proj.term.ty().unwrap() + } else { + ty.super_fold_with(self) + } + } +} diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 9776cc57af8..1fb8659bb27 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -8,9 +8,8 @@ use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::InferCtxt; use crate::traits::project::ProjectAndUnifyResult; use rustc_middle::mir::interpret::ErrorHandled; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; -#[cfg(not(bootstrap))] -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::{ImplPolarity, Region, RegionVid}; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet}; @@ -351,14 +350,14 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) .map(|o| o.predicate); new_env = ty::ParamEnv::new( - tcx.mk_predicates(normalized_preds), + tcx.mk_predicates_from_iter(normalized_preds), param_env.reveal(), param_env.constness(), ); } let final_user_env = ty::ParamEnv::new( - tcx.mk_predicates(user_computed_preds.into_iter()), + tcx.mk_predicates_from_iter(user_computed_preds.into_iter()), user_env.reveal(), user_env.constness(), ); diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs index e26bef0b8b7..b42a49eb47b 100644 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs @@ -8,7 +8,7 @@ use crate::traits::{ SelectionError, TraitEngine, }; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; pub struct FulfillmentContext<'tcx> { obligations: FxIndexSet<PredicateObligation<'tcx>>, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 599238e405d..6b688c322c7 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -21,8 +21,8 @@ use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; -use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ir::TypeVisitor, ImplSubject, Ty, TyCtxt}; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; @@ -217,6 +217,7 @@ fn equate_impl_headers<'cx, 'tcx>( selcx .infcx .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .define_opaque_types(true) .eq_impl_headers(impl1_header, impl2_header) .map(|infer_ok| infer_ok.obligations) .ok() diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index dd9b5b534d7..345e84990ed 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -14,7 +14,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::abstract_const::NotConstEvaluatable; -use rustc_middle::ty::{self, ir::TypeVisitor, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitable, TypeVisitableExt, TypeVisitor}; use rustc_span::Span; use std::ops::ControlFlow; diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index a2ddd91546c..b20636174ee 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -104,7 +104,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { }); } - pub fn normalize<T: TypeFoldable<'tcx>>( + pub fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>( &self, cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -128,6 +128,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { { self.infcx .at(cause, param_env) + .define_opaque_types(true) .eq_exp(a_is_expected, a, b) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -141,6 +142,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { ) -> Result<(), TypeError<'tcx>> { self.infcx .at(cause, param_env) + .define_opaque_types(true) .eq(expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -155,6 +157,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { ) -> Result<(), TypeError<'tcx>> { self.infcx .at(cause, param_env) + .define_opaque_types(true) .sup(expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -169,6 +172,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { ) -> Result<(), TypeError<'tcx>> { self.infcx .at(cause, param_env) + .define_opaque_types(true) .sup(expected, actual) .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } @@ -216,7 +220,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { answer: T, ) -> Fallible<CanonicalQueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { self.infcx.make_canonicalized_query_response( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs index 9474c70cb53..1174efdbfa8 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/method_chain.rs @@ -98,7 +98,7 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for CollectAllMismatches<'_, 'tcx> { fn register_predicates( &mut self, - _obligations: impl IntoIterator<Item = impl ty::ToPredicate<'tcx>>, + _obligations: impl IntoIterator<Item: ty::ToPredicate<'tcx>>, ) { // FIXME(deferred_projection_equality) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index a32ab16263a..a844a1494e2 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -34,10 +34,11 @@ use rustc_infer::infer::{InferOk, TypeTrace}; use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::print::{with_forced_trimmed_paths, FmtPrinter, Print}; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, + TypeVisitable, TypeVisitableExt, }; use rustc_session::config::TraitSolver; use rustc_session::Limit; @@ -108,7 +109,7 @@ pub trait TypeErrCtxtExt<'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug; @@ -121,7 +122,7 @@ pub trait TypeErrCtxtExt<'tcx> { ) -> ! where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug; @@ -491,7 +492,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> ! where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug, { @@ -511,7 +512,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> where T: fmt::Display - + TypeFoldable<'tcx> + + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug, { @@ -2970,7 +2971,7 @@ impl ArgKind { struct HasNumericInferVisitor; -impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor { +impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for HasNumericInferVisitor { type BreakTy = (); fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 91b463800a8..66d74fd05a6 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -30,10 +30,10 @@ use rustc_middle::hir::map; use rustc_middle::ty::error::TypeError::{self, Sorts}; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{ - self, ir::TypeFolder, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, - DefIdTree, GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts, - IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeSuperFoldable, - TypeckResults, + self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, DefIdTree, + GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts, + IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, + TypeSuperFoldable, TypeVisitableExt, TypeckResults, }; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -927,7 +927,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { DefKind::Ctor(CtorOf::Variant, _) => { "use parentheses to construct this tuple variant".to_string() } - kind => format!("use parentheses to call this {}", kind.descr(def_id)), + kind => format!( + "use parentheses to call this {}", + self.tcx.def_kind_descr(kind, def_id) + ), }, DefIdOrName::Name(name) => format!("use parentheses to call this {name}"), }; @@ -2139,7 +2142,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { err.note(&format!( "{}s cannot be accessed directly on a `trait`, they can only be \ accessed through a specific `impl`", - assoc_item.kind.as_def_kind().descr(item_def_id) + self.tcx.def_kind_descr(assoc_item.kind.as_def_kind(), item_def_id) )); err.span_suggestion( span, @@ -2784,7 +2787,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { _ => true, }; if ident.span.is_visible(sm) && !ident.span.overlaps(span) && !same_line { - multispan.push_span_label(ident.span, "required by a bound in this"); + multispan.push_span_label( + ident.span, + format!( + "required by a bound in this {}", + tcx.def_kind(item_def_id).descr(item_def_id) + ), + ); } } let descr = format!("required by a bound in `{item_name}`"); @@ -3098,6 +3107,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.def_span(def_id), "required because it's used within this closure", ), + ty::Str => err.note("`str` is considered to contain a `[u8]` slice for auto trait purposes"), _ => err.note(&msg), }; } @@ -3525,7 +3535,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { { if let hir::Expr { kind: hir::ExprKind::Block(..), .. } = expr { let expr = expr.peel_blocks(); - let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()); + let ty = typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()); let span = expr.span; if Some(span) != err.span.primary_span() { err.span_label( @@ -3628,7 +3638,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let mut assocs = vec![]; let mut expr = expr; let mut prev_ty = self.resolve_vars_if_possible( - typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()), + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()), ); while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, span) = expr.kind { // Point at every method call in the chain with the resulting type. @@ -3639,7 +3649,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.probe_assoc_types_at_expr(&type_diffs, span, prev_ty, expr.hir_id, param_env); assocs.push(assocs_in_this_method); prev_ty = self.resolve_vars_if_possible( - typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error()), + typeck_results.expr_ty_adjusted_opt(expr).unwrap_or(tcx.ty_error_misc()), ); if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind @@ -3657,7 +3667,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let hir::Node::Param(param) = parent { // ...and it is a an fn argument. let prev_ty = self.resolve_vars_if_possible( - typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error()), + typeck_results.node_type_opt(param.hir_id).unwrap_or(tcx.ty_error_misc()), ); let assocs_in_this_method = self.probe_assoc_types_at_expr(&type_diffs, param.ty_span, prev_ty, param.hir_id, param_env); if assocs_in_this_method.iter().any(|a| a.is_some()) { diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index deeed930e50..da2416b9646 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -8,7 +8,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, Binder, Const, TypeVisitable}; +use rustc_middle::ty::{self, Binder, Const, TypeVisitableExt}; use std::marker::PhantomData; use super::const_evaluatable; diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index de730773794..b94346b0956 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -8,7 +8,7 @@ use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt}; use rustc_infer::traits::query::NoSolution; use rustc_infer::{infer::outlives::env::OutlivesEnvironment, traits::FulfillmentError}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::DUMMY_SP; use super::outlives_bounds::InferCtxtExt; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 2d299486ee6..b2317f55d25 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -27,7 +27,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeSuperVisitable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_span::def_id::{DefId, CRATE_DEF_ID}; @@ -141,7 +141,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( fn pred_known_to_hold_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - pred: impl ToPredicate<'tcx> + TypeVisitable<'tcx>, + pred: impl ToPredicate<'tcx> + TypeVisitable<TyCtxt<'tcx>>, span: Span, ) -> bool { let has_non_region_infer = pred.has_non_region_infer(); @@ -281,7 +281,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); let elaborated_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), + tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), ); @@ -333,10 +333,9 @@ pub fn normalize_param_env_or_error<'tcx>( // Not sure whether it is better to include the unnormalized TypeOutlives predicates // here. I believe they should not matter, because we are ignoring TypeOutlives param-env // predicates here anyway. Keeping them here anyway because it seems safer. - let outlives_env: Vec<_> = - non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect(); + let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned(); let outlives_env = ty::ParamEnv::new( - tcx.intern_predicates(&outlives_env), + tcx.mk_predicates_from_iter(outlives_env), unnormalized_env.reveal(), unnormalized_env.constness(), ); @@ -356,7 +355,7 @@ pub fn normalize_param_env_or_error<'tcx>( predicates.extend(outlives_predicates); debug!("normalize_param_env_or_error: final predicates={:?}", predicates); ty::ParamEnv::new( - tcx.intern_predicates(&predicates), + tcx.mk_predicates(&predicates), unnormalized_env.reveal(), unnormalized_env.constness(), ) @@ -371,7 +370,7 @@ pub fn fully_normalize<'tcx, T>( value: T, ) -> Result<T, Vec<FulfillmentError<'tcx>>> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let ocx = ObligationCtxt::new(infcx); debug!(?value); @@ -481,7 +480,7 @@ fn is_impossible_method(tcx: TyCtxt<'_>, (impl_def_id, trait_item_def_id): (DefI generics: &'tcx ty::Generics, trait_item_def_id: DefId, } - impl<'tcx> ty::ir::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> { + impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for ReferencesOnlyParentGenerics<'tcx> { type BreakTy = (); fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { // If this is a parameter from the trait item's own generics, then bail diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index df1aeed941d..4eacb5211f7 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -18,10 +18,10 @@ use rustc_errors::{DelayDm, FatalError, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; +use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{ - self, ir::TypeVisitor, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + self, EarlyBinder, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; -use rustc_middle::ty::{Predicate, ToPredicate}; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -666,8 +666,9 @@ fn object_ty_for_trait<'tcx>( elaborated_predicates.sort_by(|a, b| a.skip_binder().stable_cmp(tcx, &b.skip_binder())); elaborated_predicates.dedup(); - let existential_predicates = tcx - .mk_poly_existential_predicates(iter::once(trait_predicate).chain(elaborated_predicates)); + let existential_predicates = tcx.mk_poly_existential_predicates_from_iter( + iter::once(trait_predicate).chain(elaborated_predicates), + ); debug!(?existential_predicates); tcx.mk_dynamic(existential_predicates, lifetime, ty::Dyn) @@ -766,11 +767,11 @@ fn receiver_is_dispatchable<'tcx>( ty::Binder::dummy(tcx.mk_trait_ref(trait_def_id, substs)).to_predicate(tcx) }; - let caller_bounds: Vec<Predicate<'tcx>> = - param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]).collect(); + let caller_bounds = + param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]); ty::ParamEnv::new( - tcx.intern_predicates(&caller_bounds), + tcx.mk_predicates_from_iter(caller_bounds), param_env.reveal(), param_env.constness(), ) @@ -790,7 +791,7 @@ fn receiver_is_dispatchable<'tcx>( infcx.predicate_must_hold_modulo_regions(&obligation) } -fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( +fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, value: T, diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 1c66fb257eb..e5b0f9d3300 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -30,8 +30,8 @@ use rustc_infer::infer::at::At; use rustc_infer::infer::resolve::OpportunisticRegionResolver; use rustc_infer::traits::ImplSourceBuiltinData; use rustc_middle::traits::select::OverflowError; -use rustc_middle::ty::fold::{ir::TypeFolder, TypeFoldable, TypeSuperFoldable}; -use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable}; +use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; use rustc_middle::ty::DefIdTree; use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt}; use rustc_span::symbol::sym; @@ -53,11 +53,11 @@ pub trait NormalizeExt<'tcx> { /// /// This normalization should be used when the type contains inference variables or the /// projection may be fallible. - fn normalize<T: TypeFoldable<'tcx>>(&self, t: T) -> InferOk<'tcx, T>; + fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> InferOk<'tcx, T>; } impl<'tcx> NormalizeExt<'tcx> for At<'_, 'tcx> { - fn normalize<T: TypeFoldable<'tcx>>(&self, value: T) -> InferOk<'tcx, T> { + fn normalize<T: TypeFoldable<TyCtxt<'tcx>>>(&self, value: T) -> InferOk<'tcx, T> { let mut selcx = SelectionContext::new(self.infcx); let Normalized { value, obligations } = normalize_with_depth(&mut selcx, self.param_env, self.cause.clone(), 0, value); @@ -286,7 +286,12 @@ fn project_and_unify_type<'cx, 'tcx>( ); obligations.extend(new); - match infcx.at(&obligation.cause, obligation.param_env).eq(normalized, actual) { + match infcx + .at(&obligation.cause, obligation.param_env) + // This is needed to support nested opaque types like `impl Fn() -> impl Trait` + .define_opaque_types(true) + .eq(normalized, actual) + { Ok(InferOk { obligations: inferred_obligations, value: () }) => { obligations.extend(inferred_obligations); ProjectAndUnifyResult::Holds(obligations) @@ -307,7 +312,7 @@ pub(crate) fn normalize_with_depth<'a, 'b, 'tcx, T>( value: T, ) -> Normalized<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { let mut obligations = Vec::new(); let value = normalize_with_depth_to(selcx, param_env, cause, depth, value, &mut obligations); @@ -324,7 +329,7 @@ pub(crate) fn normalize_with_depth_to<'a, 'b, 'tcx, T>( obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new(selcx, param_env, cause, depth, obligations); @@ -344,7 +349,7 @@ pub(crate) fn try_normalize_with_depth_to<'a, 'b, 'tcx, T>( obligations: &mut Vec<PredicateObligation<'tcx>>, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!(obligations.len = obligations.len()); let mut normalizer = AssocTypeNormalizer::new_without_eager_inference_replacement( @@ -360,7 +365,10 @@ where result } -pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<'tcx>>(value: &T, reveal: Reveal) -> bool { +pub(crate) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>( + value: &T, + reveal: Reveal, +) -> bool { match reveal { Reveal::UserFacing => value .has_type_flags(ty::TypeFlags::HAS_TY_PROJECTION | ty::TypeFlags::HAS_CT_PROJECTION), @@ -422,7 +430,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { } } - fn fold<T: TypeFoldable<'tcx>>(&mut self, value: T) -> T { + fn fold<T: TypeFoldable<TyCtxt<'tcx>>>(&mut self, value: T) -> T { let value = self.selcx.infcx.resolve_vars_if_possible(value); debug!(?value); @@ -445,7 +453,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx self.selcx.tcx() } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -664,7 +672,12 @@ pub struct BoundVarReplacer<'me, 'tcx> { /// /// FIXME(@lcnr): We may even consider experimenting with eagerly replacing bound vars during /// normalization as well, at which point this function will be unnecessary and can be removed. -pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: TypeFoldable<'tcx>>( +pub fn with_replaced_escaping_bound_vars< + 'a, + 'tcx, + T: TypeFoldable<TyCtxt<'tcx>>, + R: TypeFoldable<TyCtxt<'tcx>>, +>( infcx: &'a InferCtxt<'tcx>, universe_indices: &'a mut Vec<Option<ty::UniverseIndex>>, value: T, @@ -690,7 +703,7 @@ pub fn with_replaced_escaping_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>, R: Typ impl<'me, 'tcx> BoundVarReplacer<'me, 'tcx> { /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that /// use a binding level above `universe_indices.len()`, we fail. - pub fn replace_bound_vars<T: TypeFoldable<'tcx>>( + pub fn replace_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>( infcx: &'me InferCtxt<'tcx>, universe_indices: &'me mut Vec<Option<ty::UniverseIndex>>, value: T, @@ -737,7 +750,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for BoundVarReplacer<'_, 'tcx> { self.infcx.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -818,7 +831,7 @@ pub struct PlaceholderReplacer<'me, 'tcx> { } impl<'me, 'tcx> PlaceholderReplacer<'me, 'tcx> { - pub fn replace_placeholders<T: TypeFoldable<'tcx>>( + pub fn replace_placeholders<T: TypeFoldable<TyCtxt<'tcx>>>( infcx: &'me InferCtxt<'tcx>, mapped_regions: BTreeMap<ty::PlaceholderRegion, ty::BoundRegion>, mapped_types: BTreeMap<ty::PlaceholderType, ty::BoundTy>, @@ -843,7 +856,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> { self.infcx.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -1200,8 +1213,8 @@ struct Progress<'tcx> { } impl<'tcx> Progress<'tcx> { - fn error(tcx: TyCtxt<'tcx>) -> Self { - Progress { term: tcx.ty_error().into(), obligations: vec![] } + fn error(tcx: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self { + Progress { term: tcx.ty_error(guar).into(), obligations: vec![] } } fn with_addl_obligations(mut self, mut obligations: Vec<PredicateObligation<'tcx>>) -> Self { @@ -1227,8 +1240,8 @@ fn project<'cx, 'tcx>( ))); } - if obligation.predicate.references_error() { - return Ok(Projected::Progress(Progress::error(selcx.tcx()))); + if let Err(guar) = obligation.predicate.error_reported() { + return Ok(Projected::Progress(Progress::error(selcx.tcx(), guar))); } let mut candidates = ProjectionCandidateSet::None; @@ -1893,7 +1906,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>( ) -> Progress<'tcx> { let tcx = selcx.tcx(); let self_ty = obligation.predicate.self_ty(); - let substs = tcx.intern_substs(&[self_ty.into()]); + let substs = tcx.mk_substs(&[self_ty.into()]); let lang_items = tcx.lang_items(); let item_def_id = obligation.predicate.def_id; let trait_def_id = tcx.trait_of_item(item_def_id).unwrap(); @@ -2084,8 +2097,9 @@ fn confirm_impl_candidate<'cx, 'tcx>( let trait_def_id = tcx.trait_id_of_impl(impl_def_id).unwrap(); let param_env = obligation.param_env; - let Ok(assoc_ty) = specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) else { - return Progress { term: tcx.ty_error().into(), obligations: nested }; + let assoc_ty = match specialization_graph::assoc_def(tcx, impl_def_id, assoc_item_id) { + Ok(assoc_ty) => assoc_ty, + Err(guar) => return Progress::error(tcx, guar), }; if !assoc_ty.item.defaultness(tcx).has_value() { @@ -2097,7 +2111,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( "confirm_impl_candidate: no associated type {:?} for {:?}", assoc_ty.item.name, obligation.predicate ); - return Progress { term: tcx.ty_error().into(), obligations: nested }; + return Progress { term: tcx.ty_error_misc().into(), obligations: nested }; } // If we're trying to normalize `<Vec<u32> as X>::A<S>` using //`impl<T> X for Vec<T> { type A<Y> = Box<Y>; }`, then: @@ -2181,11 +2195,12 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( let mut obligations = data.nested; let trait_fn_def_id = tcx.impl_trait_in_trait_parent(obligation.predicate.def_id); - let Ok(leaf_def) = specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) else { - return Progress { term: tcx.ty_error().into(), obligations }; + let leaf_def = match specialization_graph::assoc_def(tcx, data.impl_def_id, trait_fn_def_id) { + Ok(assoc_ty) => assoc_ty, + Err(guar) => return Progress::error(tcx, guar), }; if !leaf_def.item.defaultness(tcx).has_value() { - return Progress { term: tcx.ty_error().into(), obligations }; + return Progress { term: tcx.ty_error_misc().into(), obligations }; } // Use the default `impl Trait` for the trait, e.g., for a default trait body @@ -2256,7 +2271,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( obligation.recursion_depth + 1, tcx.bound_return_position_impl_trait_in_trait_tys(impl_fn_def_id) .map_bound(|tys| { - tys.map_or_else(|_| tcx.ty_error(), |tys| tys[&obligation.predicate.def_id]) + tys.map_or_else(|guar| tcx.ty_error(guar), |tys| tys[&obligation.predicate.def_id]) }) .subst(tcx, impl_fn_substs), &mut obligations, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a266013b8fd..b0cec3ce7a3 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -11,9 +11,9 @@ use crate::traits::{ObligationCause, PredicateObligation, Reveal}; use rustc_data_structures::sso::SsoHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_infer::traits::Normalized; -use rustc_middle::ty::fold::{ir::FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; -use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable}; -use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt}; +use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; +use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; use rustc_span::DUMMY_SP; use std::ops::ControlFlow; @@ -32,7 +32,7 @@ pub trait QueryNormalizeExt<'tcx> { /// use [`TyCtxt::normalize_erasing_regions`], which wraps this procedure. fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution> where - T: TypeFoldable<'tcx>; + T: TypeFoldable<TyCtxt<'tcx>>; } impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> { @@ -51,7 +51,7 @@ impl<'cx, 'tcx> QueryNormalizeExt<'tcx> for At<'cx, 'tcx> { /// and other details are still "under development". fn query_normalize<T>(&self, value: T) -> Result<Normalized<'tcx, T>, NoSolution> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { debug!( "normalize::<{}>(value={:?}, param_env={:?}, cause={:?})", @@ -116,7 +116,7 @@ struct MaxEscapingBoundVarVisitor { } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for MaxEscapingBoundVarVisitor { - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &ty::Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -177,7 +177,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'cx, 'tcx> self.infcx.tcx } - fn try_fold_binder<T: TypeFoldable<'tcx>>( + fn try_fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> Result<ty::Binder<'tcx, T>, Self::Error> { diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index 97002b461aa..9e8bc8bce9a 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -54,8 +54,8 @@ pub struct TypeOpOutput<'tcx, Op: TypeOp<'tcx>> { /// which produces the resulting query region constraints. /// /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html -pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<'tcx> + 'tcx { - type QueryResponse: TypeFoldable<'tcx>; +pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable<TyCtxt<'tcx>> + 'tcx { + type QueryResponse: TypeFoldable<TyCtxt<'tcx>>; /// Give query the option for a simple fast path that never /// actually hits the tcx cache lookup etc. Return `Some(r)` with diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs index 8f0b4de31e6..5b216c07692 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs @@ -1,7 +1,7 @@ use crate::infer::canonical::{Canonical, CanonicalQueryResponse}; use crate::traits::query::Fallible; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt}; +use rustc_middle::ty::{self, Lift, ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt}; use std::fmt; pub use rustc_middle::traits::query::type_op::Normalize; @@ -24,7 +24,7 @@ where } } -pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx> + Copy { +pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy { fn type_op_method( tcx: TyCtxt<'tcx>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index dae602908a3..4ad13dcb645 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -9,7 +9,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::spec::abi::Abi; use crate::traits; diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index e4a832e4728..21c158fd0fd 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -12,7 +12,7 @@ use rustc_infer::infer::InferOk; use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType; use rustc_middle::ty::{ self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, - TraitRef, Ty, TyCtxt, TypeVisitable, + TraitRef, Ty, TyCtxt, TypeVisitableExt, }; use rustc_session::config::TraitSolver; use rustc_span::def_id::DefId; @@ -564,8 +564,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .into() } }); - let bound_vars = tcx.intern_bound_variable_kinds(&bound_vars); - let assoc_ty_substs = tcx.intern_substs(&substs); + let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); + let assoc_ty_substs = tcx.mk_substs(&substs); let bound = bound.map_bound(|b| b.kind().skip_binder()).subst(tcx, assoc_ty_substs); tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars)) @@ -821,6 +821,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.infcx .at(&obligation.cause, obligation.param_env) + // needed for tests/ui/type-alias-impl-trait/assoc-projection-ice.rs + .define_opaque_types(true) .sup(obligation_trait_ref, expected_trait_ref) .map(|InferOk { mut obligations, .. }| { obligations.extend(nested); @@ -878,7 +880,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map(ty::ExistentialPredicate::AutoTrait) .map(ty::Binder::dummy), ); - let existential_predicates = tcx.mk_poly_existential_predicates(iter); + let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter); let source_trait = tcx.mk_dynamic(existential_predicates, r_b, repr_a); // Require that the traits involved in this upcast are **equal**; @@ -977,7 +979,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map(ty::ExistentialPredicate::AutoTrait) .map(ty::Binder::dummy), ); - let existential_predicates = tcx.mk_poly_existential_predicates(iter); + let existential_predicates = tcx.mk_poly_existential_predicates_from_iter(iter); let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a); // Require that the traits involved in this upcast are **equal**; @@ -1097,7 +1099,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check that the source struct with the target's // unsizing parameters is equal to the target. - let substs = tcx.mk_substs(substs_a.iter().enumerate().map(|(i, k)| { + let substs = tcx.mk_substs_from_iter(substs_a.iter().enumerate().map(|(i, k)| { if unsizing_params.contains(i as u32) { substs_b[i] } else { k } })); let new_struct = tcx.mk_adt(def, substs); @@ -1129,7 +1131,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Check that the source tuple with the target's // last element is equal to the target. - let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last))); + let new_tuple = + tcx.mk_tup_from_iter(a_mid.iter().copied().chain(iter::once(b_last))); let InferOk { obligations, .. } = self .infcx .at(&obligation.cause, obligation.param_env) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 4b15dd408b3..01c1ad3a4ce 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -49,7 +49,7 @@ use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::SubstsRef; use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; -use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{Ty, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_session::config::TraitSolver; use rustc_span::symbol::sym; @@ -1406,7 +1406,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// The weird return type of this function allows it to be used with the `try` (`?`) /// operator within certain functions. #[inline(always)] - fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>( + fn check_recursion_limit<T: Display + TypeFoldable<TyCtxt<'tcx>>, V>( &self, obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, @@ -1752,7 +1752,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { }); self.infcx .at(&obligation.cause, obligation.param_env) - .define_opaque_types(false) .sup(ty::Binder::dummy(placeholder_trait_ref), trait_bound) .map(|InferOk { obligations: _, value: () }| { // This method is called within a probe, so we can't have @@ -1815,7 +1814,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let is_match = self .infcx .at(&obligation.cause, obligation.param_env) - .define_opaque_types(false) .sup(obligation.predicate, infer_projection) .map_or(false, |InferOk { obligations, value: () }| { self.evaluate_predicates_recursively( @@ -2232,7 +2230,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } // (*) binder moved here - let all_vars = self.tcx().mk_bound_variable_kinds( + let all_vars = self.tcx().mk_bound_variable_kinds_from_iter( obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()), ); Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars)) @@ -2302,12 +2300,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never | ty::Char => ty::Binder::dummy(Vec::new()), + // Treat this like `struct str([u8]);` + ty::Str => ty::Binder::dummy(vec![self.tcx().mk_slice(self.tcx().types.u8)]), + ty::Placeholder(..) | ty::Dynamic(..) | ty::Param(..) @@ -2445,7 +2445,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the placeholder trait ref may fail due the Generalizer relation // raising a CyclicalTy error due to a sub_root_var relation // for a variable being generalized... - self.infcx.tcx.sess.delay_span_bug( + let guar = self.infcx.tcx.sess.delay_span_bug( obligation.cause.span, &format!( "Impl {:?} was matchable against {:?} but now is not", @@ -2453,7 +2453,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ), ); let value = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id); - let err = self.tcx().ty_error(); + let err = self.tcx().ty_error(guar); let value = value.fold_with(&mut BottomUpFolder { tcx: self.tcx(), ty_op: |_| err, @@ -2507,7 +2507,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let InferOk { obligations, .. } = self .infcx .at(&cause, obligation.param_env) - .define_opaque_types(false) .eq(placeholder_obligation_trait_ref, impl_trait_ref) .map_err(|e| { debug!("match_impl: failed eq_trait_refs due to `{}`", e.to_string(self.tcx())) @@ -2558,11 +2557,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Result<Vec<PredicateObligation<'tcx>>, ()> { self.infcx .at(&obligation.cause, obligation.param_env) - // We don't want predicates for opaque types to just match all other types, - // if there is an obligation on the opaque type, then that obligation must be met - // opaquely. Otherwise we'd match any obligation to the opaque type and then error - // out later. - .define_opaque_types(false) .sup(obligation.predicate.to_poly_trait_ref(), poly_trait_ref) .map(|InferOk { obligations, .. }| obligations) .map_err(|_| ()) @@ -3042,7 +3036,7 @@ fn bind_generator_hidden_types_above<'tcx>( if considering_regions { debug_assert!(!hidden_types.has_erased_regions()); } - let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.iter().chain( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain( (num_bound_variables..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))), )); ty::Binder::bind_with_vars(hidden_types, bound_vars) diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 2e4a5cfe4bc..61ed9ef2ec1 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -4,7 +4,7 @@ use crate::traits; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::DefId; use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams}; -use rustc_middle::ty::{self, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt}; pub use rustc_middle::traits::specialization_graph::*; diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 32dd8f25b44..e38ae9381c1 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -1,8 +1,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; -#[cfg(not(bootstrap))] -use rustc_middle::ty::TypeVisitable; -use rustc_middle::ty::{self, ir::TypeVisitor, Ty, TyCtxt, TypeSuperVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::Span; use std::ops::ControlFlow; diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index b5df583e3f4..bcf63d5a6f6 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -4,7 +4,7 @@ use smallvec::SmallVec; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{GenericArg, SubstsRef}; use super::NormalizeExt; @@ -239,7 +239,7 @@ pub fn predicate_for_trait_def<'tcx>( cause: ObligationCause<'tcx>, trait_def_id: DefId, recursion_depth: usize, - params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + params: impl IntoIterator<Item: Into<GenericArg<'tcx>>>, ) -> PredicateObligation<'tcx> { let trait_ref = tcx.mk_trait_ref(trait_def_id, params); predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) @@ -292,7 +292,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( assert!(!self_ty.has_escaping_bound_vars()); let arguments_tuple = match tuple_arguments { TupleArgumentsFlag::No => sig.skip_binder().inputs()[0], - TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), + TupleArgumentsFlag::Yes => tcx.mk_tup(sig.skip_binder().inputs()), }; let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]); sig.map_bound(|sig| (trait_ref, sig.output())) diff --git a/compiler/rustc_trait_selection/src/traits/vtable.rs b/compiler/rustc_trait_selection/src/traits/vtable.rs index 9f5c5bbeac8..a4e9928f8b2 100644 --- a/compiler/rustc_trait_selection/src/traits/vtable.rs +++ b/compiler/rustc_trait_selection/src/traits/vtable.rs @@ -4,7 +4,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_infer::traits::util::PredicateSet; use rustc_infer::traits::ImplSource; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::TypeVisitableExt; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, GenericParamDefKind, ToPredicate, Ty, TyCtxt, VtblEntry}; use rustc_span::{sym, Span}; diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 6a881c233db..d498af359c5 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -3,7 +3,7 @@ use crate::traits; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_span::{Span, DUMMY_SP}; diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index e2b5d17e073..f8c8f744e6d 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -769,12 +769,12 @@ struct ReplaceOpaqueTyFolder<'tcx> { binder_index: ty::DebruijnIndex, } -impl<'tcx> ty::ir::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> { +impl<'tcx> ty::TypeFolder<TyCtxt<'tcx>> for ReplaceOpaqueTyFolder<'tcx> { fn interner(&self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 7635f4bfec3..60e22d1001c 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -35,9 +35,8 @@ use rustc_ast::ast; use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - self, - ir::{TypeFolder, TypeVisitor}, - Binder, Region, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, + self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, + TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_span::def_id::DefId; @@ -63,7 +62,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution<RustInterner<'tcx>>> for Subst impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution<RustInterner<'tcx>> { fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> { - interner.tcx.mk_substs(self.iter(interner).map(|subst| subst.lower_into(interner))) + interner + .tcx + .mk_substs_from_iter(self.iter(interner).map(|subst| subst.lower_into(interner))) } } @@ -456,7 +457,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)), ), TyKind::Foreign(def_id) => ty::Foreign(def_id.0), - TyKind::Error => return interner.tcx.ty_error(), + TyKind::Error => return interner.tcx.ty_error_misc(), TyKind::Alias(alias_ty) => match alias_ty { chalk_ir::AliasTy::Projection(projection) => ty::Alias( ty::Projection, @@ -488,7 +489,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty<RustInterner<'tcx>> { TyKind::InferenceVar(_, _) => unimplemented!(), TyKind::Dyn(_) => unimplemented!(), }; - interner.tcx.mk_ty(kind) + interner.tcx.mk_ty_from_kind(kind) } } @@ -880,7 +881,7 @@ impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound<RustInterner<'tcx> /// It's important to note that because of prior substitution, we may have /// late-bound regions, even outside of fn contexts, since this is the best way /// to prep types for chalk lowering. -pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<'tcx>>( +pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( interner: RustInterner<'tcx>, tcx: TyCtxt<'tcx>, ty: Binder<'tcx, T>, @@ -931,7 +932,7 @@ impl<'tcx> BoundVarsCollector<'tcx> { } impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for BoundVarsCollector<'tcx> { - fn visit_binder<T: TypeVisitable<'tcx>>( + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>( &mut self, t: &Binder<'tcx, T>, ) -> ControlFlow<Self::BreakTy> { @@ -1016,7 +1017,10 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for NamedBoundVarSubstitutor<'a, 'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); @@ -1072,7 +1076,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ParamsSubstitutor<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>(&mut self, t: Binder<'tcx, T>) -> Binder<'tcx, T> { + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( + &mut self, + t: Binder<'tcx, T>, + ) -> Binder<'tcx, T> { self.binder_index.shift_in(1); let result = t.super_fold_with(self); self.binder_index.shift_out(1); diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index f33f9edd627..a5ebc26a8bc 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -9,7 +9,7 @@ pub(crate) mod lowering; use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; use rustc_middle::traits::ChalkRustInterner; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_infer::infer::canonical::{ Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, @@ -96,37 +96,34 @@ pub(crate) fn evaluate_goal<'tcx>( use rustc_middle::infer::canonical::CanonicalVarInfo; let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params); - let var_values = tcx.mk_substs( + let var_values = tcx.mk_substs_from_iter( subst .as_slice(interner) .iter() .map(|p| p.lower_into(interner).fold_with(&mut reverse_param_substitutor)), ); - let variables: Vec<_> = binders - .iter(interner) - .map(|var| { - let kind = match var.kind { - chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind { - chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General( - ty::UniverseIndex::from_usize(var.skip_kind().counter), - ), - chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int, - chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float, - }), - chalk_ir::VariableKind::Lifetime => CanonicalVarKind::Region( + let variables = binders.iter(interner).map(|var| { + let kind = match var.kind { + chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind { + chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General( ty::UniverseIndex::from_usize(var.skip_kind().counter), ), - // FIXME(compiler-errors): We don't currently have a way of turning - // a Chalk ty back into a rustc ty, right? - chalk_ir::VariableKind::Const(_) => todo!(), - }; - CanonicalVarInfo { kind } - }) - .collect(); + chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int, + chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float, + }), + chalk_ir::VariableKind::Lifetime => { + CanonicalVarKind::Region(ty::UniverseIndex::from_usize(var.skip_kind().counter)) + } + // FIXME(compiler-errors): We don't currently have a way of turning + // a Chalk ty back into a rustc ty, right? + chalk_ir::VariableKind::Const(_) => todo!(), + }; + CanonicalVarInfo { kind } + }); let max_universe = binders.iter(interner).map(|v| v.skip_kind().counter).max().unwrap_or(0); let sol = Canonical { max_universe: ty::UniverseIndex::from_usize(max_universe), - variables: tcx.intern_canonical_var_infos(&variables), + variables: tcx.mk_canonical_var_infos_from_iter(variables), value: QueryResponse { var_values: CanonicalVarValues { var_values }, region_constraints: QueryRegionConstraints::default(), diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index abf0c1c5f3e..ddd4ca1436c 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -7,7 +7,7 @@ use rustc_infer::infer::outlives::components::{push_outlives_components, Compone use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::query::OutlivesBound; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::source_map::DUMMY_SP; use rustc_trait_selection::infer::InferCtxtBuilderExt; diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 2c18a034050..f0597f19225 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -1,7 +1,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, ParamEnvAnd, TyCtxt, TypeFoldable, TypeVisitableExt}; use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; use rustc_trait_selection::traits::{Normalized, ObligationCause}; use std::sync::atomic::Ordering; @@ -22,7 +22,7 @@ pub(crate) fn provide(p: &mut Providers) { }; } -fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + Copy>( +fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<TyCtxt<'tcx>> + PartialEq + Copy>( tcx: TyCtxt<'tcx>, goal: ParamEnvAnd<'tcx, T>, ) -> Result<T, NoSolution> { diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index d34fce64dd7..e0fd487b3d3 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -161,7 +161,7 @@ fn type_op_normalize<'tcx, T>( key: ParamEnvAnd<'tcx, Normalize<T>>, ) -> Fallible<T> where - T: fmt::Debug + TypeFoldable<'tcx> + Lift<'tcx>, + T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>, { let (param_env, Normalize { value }) = key.into_parts(); let Normalized { value, obligations } = diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index b3b9a67b26e..4b4a8ebd079 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -117,7 +117,7 @@ mod rustc { c: Const<'tcx>, ) -> Option<Self> { use rustc_middle::ty::ScalarInt; - use rustc_middle::ty::TypeVisitable; + use rustc_middle::ty::TypeVisitableExt; use rustc_span::symbol::sym; let c = c.eval(tcx, param_env); diff --git a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl b/compiler/rustc_ty_utils/locales/en-US.ftl index abe65a0e3fe..abe65a0e3fe 100644 --- a/compiler/rustc_error_messages/locales/en-US/ty_utils.ftl +++ b/compiler/rustc_ty_utils/locales/en-US.ftl diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index 41924dc2a6d..35c9f95eb03 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -54,7 +54,7 @@ fn fn_sig_for_fn_abi<'tcx>( sig = sig.map_bound(|mut sig| { let mut inputs_and_output = sig.inputs_and_output.to_vec(); inputs_and_output[0] = tcx.mk_mut_ptr(inputs_and_output[0]); - sig.inputs_and_output = tcx.intern_type_list(&inputs_and_output); + sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output); sig }); } @@ -63,7 +63,7 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Closure(def_id, substs) => { let sig = substs.as_closure().sig(); - let bound_vars = tcx.mk_bound_variable_kinds( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), ); let br = ty::BoundRegion { @@ -88,7 +88,7 @@ fn fn_sig_for_fn_abi<'tcx>( ty::Generator(did, substs, _) => { let sig = substs.as_generator().poly_sig(); - let bound_vars = tcx.mk_bound_variable_kinds( + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( sig.bound_vars().iter().chain(iter::once(ty::BoundVariableKind::Region(ty::BrEnv))), ); let br = ty::BoundRegion { @@ -99,7 +99,7 @@ fn fn_sig_for_fn_abi<'tcx>( let pin_did = tcx.require_lang_item(LangItem::Pin, None); let pin_adt_ref = tcx.adt_def(pin_did); - let pin_substs = tcx.intern_substs(&[env_ty.into()]); + let pin_substs = tcx.mk_substs(&[env_ty.into()]); let env_ty = tcx.mk_adt(pin_adt_ref, pin_substs); let sig = sig.skip_binder(); @@ -111,7 +111,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Future::poll(_, &mut Context<'_>) -> Poll<Output>` let poll_did = tcx.require_lang_item(LangItem::Poll, None); let poll_adt_ref = tcx.adt_def(poll_did); - let poll_substs = tcx.intern_substs(&[sig.return_ty.into()]); + let poll_substs = tcx.mk_substs(&[sig.return_ty.into()]); let ret_ty = tcx.mk_adt(poll_adt_ref, poll_substs); // We have to replace the `ResumeTy` that is used for type and borrow checking @@ -133,7 +133,7 @@ fn fn_sig_for_fn_abi<'tcx>( // The signature should be `Generator::resume(_, Resume) -> GeneratorState<Yield, Return>` let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); let state_adt_ref = tcx.adt_def(state_did); - let state_substs = tcx.intern_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); + let state_substs = tcx.mk_substs(&[sig.yield_ty.into(), sig.return_ty.into()]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); (sig.resume_ty, ret_ty) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 164cac6a010..d4866b5dbdd 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,13 +1,18 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; -use rustc_hir::def_id::DefId; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_hir::def::DefKind; +use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::definitions::DefPathData; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_middle::ty::{self, DefIdTree, TyCtxt}; pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { associated_item, associated_item_def_ids, associated_items, + associated_items_for_impl_trait_in_trait, + associated_item_for_impl_trait_in_trait, impl_item_implementor_ids, ..*providers }; @@ -112,3 +117,97 @@ fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::A fn_has_self_parameter: has_self, } } + +/// Given an `fn_def_id` of a trait or of an impl that implements a given trait: +/// if `fn_def_id` is the def id of a function defined inside a trait, then it creates and returns +/// the associated items that correspond to each impl trait in return position for that trait. +/// if `fn_def_id` is the def id of a function defined inside an impl that implements a trait, then it +/// creates and returns the associated items that correspond to each impl trait in return position +/// of the implemented trait. +fn associated_items_for_impl_trait_in_trait(tcx: TyCtxt<'_>, fn_def_id: DefId) -> &'_ [DefId] { + let parent_def_id = tcx.parent(fn_def_id); + + match tcx.def_kind(parent_def_id) { + DefKind::Trait => { + struct RPITVisitor { + rpits: Vec<LocalDefId>, + } + + impl<'v> Visitor<'v> for RPITVisitor { + fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { + if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind { + self.rpits.push(item_id.owner_id.def_id) + } + intravisit::walk_ty(self, ty) + } + } + + let mut visitor = RPITVisitor { rpits: Vec::new() }; + + if let Some(output) = tcx.hir().get_fn_output(fn_def_id.expect_local()) { + visitor.visit_fn_ret_ty(output); + + tcx.arena.alloc_from_iter(visitor.rpits.iter().map(|opaque_ty_def_id| { + tcx.associated_item_for_impl_trait_in_trait(opaque_ty_def_id).to_def_id() + })) + } else { + &[] + } + } + + DefKind::Impl { .. } => { + let Some(trait_fn_def_id) = tcx.associated_item(fn_def_id).trait_item_def_id else { return &[] }; + + tcx.arena.alloc_from_iter( + tcx.associated_items_for_impl_trait_in_trait(trait_fn_def_id).iter().map( + move |trait_assoc_def_id| { + impl_associated_item_for_impl_trait_in_trait( + tcx, + trait_assoc_def_id.expect_local(), + fn_def_id.expect_local(), + ) + .to_def_id() + }, + ), + ) + } + + def_kind => bug!( + "associated_items_for_impl_trait_in_trait: {:?} should be Trait or Impl but is {:?}", + parent_def_id, + def_kind + ), + } +} + +/// Given an `opaque_ty_def_id` corresponding to an impl trait in trait, create and return the +/// corresponding associated item. +fn associated_item_for_impl_trait_in_trait( + tcx: TyCtxt<'_>, + opaque_ty_def_id: LocalDefId, +) -> LocalDefId { + let fn_def_id = tcx.impl_trait_in_trait_parent(opaque_ty_def_id.to_def_id()); + let trait_def_id = tcx.parent(fn_def_id); + assert_eq!(tcx.def_kind(trait_def_id), DefKind::Trait); + + let span = tcx.def_span(opaque_ty_def_id); + let trait_assoc_ty = + tcx.at(span).create_def(trait_def_id.expect_local(), DefPathData::ImplTraitAssocTy); + trait_assoc_ty.def_id() +} + +/// Given an `trait_assoc_def_id` that corresponds to a previously synthethized impl trait in trait +/// into an associated type and an `impl_def_id` corresponding to an impl block, create and return +/// the corresponding associated item inside the impl block. +fn impl_associated_item_for_impl_trait_in_trait( + tcx: TyCtxt<'_>, + trait_assoc_def_id: LocalDefId, + impl_fn_def_id: LocalDefId, +) -> LocalDefId { + let impl_def_id = tcx.local_parent(impl_fn_def_id); + + let span = tcx.def_span(trait_assoc_def_id); + let impl_assoc_ty = tcx.at(span).create_def(impl_def_id, DefPathData::ImplTraitAssocTy); + + impl_assoc_ty.def_id() +} diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 852156c24f4..f2635271609 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; use rustc_middle::thir::visit; use rustc_middle::thir::visit::Visitor; use rustc_middle::ty::abstract_const::CastKind; -use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitableExt}; use rustc_middle::{mir, thir}; use rustc_span::Span; use rustc_target::abi::VariantIdx; @@ -144,7 +144,7 @@ fn recurse_build<'tcx>( for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - let new_args = tcx.intern_const_list(&new_args); + let new_args = tcx.mk_const_list(&new_args); tcx.mk_const(Expr::FunctionCall(fun, new_args), node.ty) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs index c05eeb353a8..ab3e62f0484 100644 --- a/compiler/rustc_ty_utils/src/errors.rs +++ b/compiler/rustc_ty_utils/src/errors.rs @@ -16,7 +16,7 @@ pub struct NeedsDropOverflow<'tcx> { pub struct GenericConstantTooComplex { #[primary_span] pub span: Span, - #[note(maybe_supported)] + #[note(ty_utils_maybe_supported)] pub maybe_supported: Option<()>, #[subdiagnostic] pub sub: GenericConstantTooComplexSub, diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index eb307e66e34..7fecee2a38b 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -19,16 +19,16 @@ fn assumed_wf_types(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Ty<'_>> { let mut assumed_wf_types: Vec<_> = tcx.assumed_wf_types(tcx.parent(def_id)).as_slice().into(); assumed_wf_types.extend(liberated_sig.inputs_and_output); - tcx.intern_type_list(&assumed_wf_types) + tcx.mk_type_list(&assumed_wf_types) } DefKind::Impl { .. } => { match tcx.impl_trait_ref(def_id) { Some(trait_ref) => { let types: Vec<_> = trait_ref.skip_binder().substs.types().collect(); - tcx.intern_type_list(&types) + tcx.mk_type_list(&types) } // Only the impl self type - None => tcx.intern_type_list(&[tcx.type_of(def_id).subst_identity()]), + None => tcx.mk_type_list(&[tcx.type_of(def_id).subst_identity()]), } } DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.parent(def_id)), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index de7230b0cfa..2eaeca73da7 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -3,7 +3,7 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::traits::CodegenObligationError; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Instance, TyCtxt, TypeVisitableExt}; use rustc_span::sym; use rustc_trait_selection::traits; use traits::{translate_substs, Reveal}; diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1a62794b0b4..e3132fcc4c4 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; use rustc_middle::ty::{ - self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitable, + self, subst::SubstsRef, AdtDef, EarlyBinder, ReprOptions, Ty, TyCtxt, TypeVisitableExt, }; use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo}; use rustc_span::symbol::Symbol; @@ -104,23 +104,23 @@ fn layout_of_uncached<'tcx>( assert!(size.bits() <= 128); Scalar::Initialized { value, valid_range: WrappingRange::full(size) } }; - let scalar = |value: Primitive| tcx.intern_layout(LayoutS::scalar(cx, scalar_unit(value))); + let scalar = |value: Primitive| tcx.mk_layout(LayoutS::scalar(cx, scalar_unit(value))); let univariant = |fields: &[Layout<'_>], repr: &ReprOptions, kind| { - Ok(tcx.intern_layout(univariant_uninterned(cx, ty, fields, repr, kind)?)) + Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?)) }; debug_assert!(!ty.has_non_region_infer()); Ok(match *ty.kind() { // Basic scalars. - ty::Bool => tcx.intern_layout(LayoutS::scalar( + ty::Bool => tcx.mk_layout(LayoutS::scalar( cx, Scalar::Initialized { value: Int(I8, false), valid_range: WrappingRange { start: 0, end: 1 }, }, )), - ty::Char => tcx.intern_layout(LayoutS::scalar( + ty::Char => tcx.mk_layout(LayoutS::scalar( cx, Scalar::Initialized { value: Int(I32, false), @@ -136,11 +136,11 @@ fn layout_of_uncached<'tcx>( ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer(dl.instruction_address_space)); ptr.valid_range_mut().start = 1; - tcx.intern_layout(LayoutS::scalar(cx, ptr)) + tcx.mk_layout(LayoutS::scalar(cx, ptr)) } // The never type. - ty::Never => tcx.intern_layout(cx.layout_of_never_type()), + ty::Never => tcx.mk_layout(cx.layout_of_never_type()), // Potentially-wide pointers. ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => { @@ -151,7 +151,7 @@ fn layout_of_uncached<'tcx>( let pointee = tcx.normalize_erasing_regions(param_env, pointee); if pointee.is_sized(tcx, param_env) { - return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); } let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env); @@ -164,7 +164,7 @@ fn layout_of_uncached<'tcx>( let metadata_layout = cx.layout_of(metadata_ty)?; // If the metadata is a 1-zst, then the pointer is thin. if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 { - return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); } let Abi::Scalar(metadata) = metadata_layout.abi else { @@ -174,7 +174,7 @@ fn layout_of_uncached<'tcx>( } else { match unsized_part.kind() { ty::Foreign(..) => { - return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); } ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), ty::Dynamic(..) => { @@ -189,7 +189,7 @@ fn layout_of_uncached<'tcx>( }; // Effectively a (ptr, meta) tuple. - tcx.intern_layout(cx.scalar_pair(data_ptr, metadata)) + tcx.mk_layout(cx.scalar_pair(data_ptr, metadata)) } ty::Dynamic(_, _, ty::DynStar) => { @@ -197,7 +197,7 @@ fn layout_of_uncached<'tcx>( data.valid_range_mut().start = 0; let mut vtable = scalar_unit(Pointer(AddressSpace::DATA)); vtable.valid_range_mut().start = 1; - tcx.intern_layout(cx.scalar_pair(data, vtable)) + tcx.mk_layout(cx.scalar_pair(data, vtable)) } // Arrays and slices. @@ -222,7 +222,7 @@ fn layout_of_uncached<'tcx>( let largest_niche = if count != 0 { element.largest_niche } else { None }; - tcx.intern_layout(LayoutS { + tcx.mk_layout(LayoutS { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Array { stride: element.size, count }, abi, @@ -233,7 +233,7 @@ fn layout_of_uncached<'tcx>( } ty::Slice(element) => { let element = cx.layout_of(element)?; - tcx.intern_layout(LayoutS { + tcx.mk_layout(LayoutS { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Array { stride: element.size, count: 0 }, abi: Abi::Aggregate { sized: false }, @@ -242,7 +242,7 @@ fn layout_of_uncached<'tcx>( size: Size::ZERO, }) } - ty::Str => tcx.intern_layout(LayoutS { + ty::Str => tcx.mk_layout(LayoutS { variants: Variants::Single { index: VariantIdx::new(0) }, fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, abi: Abi::Aggregate { sized: false }, @@ -265,7 +265,7 @@ fn layout_of_uncached<'tcx>( Abi::Aggregate { ref mut sized } => *sized = false, _ => bug!(), } - tcx.intern_layout(unit) + tcx.mk_layout(unit) } ty::Generator(def_id, substs, _) => generator_layout(cx, ty, def_id, substs)?, @@ -394,7 +394,7 @@ fn layout_of_uncached<'tcx>( FieldsShape::Array { stride: e_ly.size, count: e_len } }; - tcx.intern_layout(LayoutS { + tcx.mk_layout(LayoutS { variants: Variants::Single { index: VariantIdx::new(0) }, fields, abi: Abi::Vector { element: e_abi, count: e_len }, @@ -427,12 +427,12 @@ fn layout_of_uncached<'tcx>( return Err(LayoutError::Unknown(ty)); } - return Ok(tcx.intern_layout( + return Ok(tcx.mk_layout( cx.layout_of_union(&def.repr(), &variants).ok_or(LayoutError::Unknown(ty))?, )); } - tcx.intern_layout( + tcx.mk_layout( cx.layout_of_struct_or_enum( &def.repr(), &variants, @@ -636,7 +636,7 @@ fn generator_layout<'tcx>( value: Primitive::Int(discr_int, false), valid_range: WrappingRange { start: 0, end: max_discr }, }; - let tag_layout = cx.tcx.intern_layout(LayoutS::scalar(cx, tag)); + let tag_layout = cx.tcx.mk_layout(LayoutS::scalar(cx, tag)); let promoted_layouts = ineligible_locals .iter() @@ -784,7 +784,7 @@ fn generator_layout<'tcx>( Abi::Aggregate { sized: true } }; - let layout = tcx.intern_layout(LayoutS { + let layout = tcx.mk_layout(LayoutS { variants: Variants::Multiple { tag, tag_encoding: TagEncoding::Direct, diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 0853de601b0..35f468aa952 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -15,6 +15,8 @@ extern crate rustc_middle; #[macro_use] extern crate tracing; +use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::fluent_messages; use rustc_middle::ty::query::Providers; mod abi; @@ -31,6 +33,8 @@ pub mod representability; mod structural_match; mod ty; +fluent_messages! { "../locales/en-US.ftl" } + pub fn provide(providers: &mut Providers) { abi::provide(providers); assoc::provide(providers); diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs index c177d60bb59..de7fd003176 100644 --- a/compiler/rustc_ty_utils/src/needs_drop.rs +++ b/compiler/rustc_ty_utils/src/needs_drop.rs @@ -303,7 +303,7 @@ fn adt_drop_tys<'tcx>( false, ) .collect::<Result<Vec<_>, _>>() - .map(|components| tcx.intern_type_list(&components)) + .map(|components| tcx.mk_type_list(&components)) } // If `def_id` refers to a generic ADT, the queries above and below act as if they had been handed // a `tcx.make_ty(def, identity_substs)` and as such it is legal to substitute the generic parameters @@ -320,7 +320,7 @@ fn adt_significant_drop_tys( true, ) .collect::<Result<Vec<_>, _>>() - .map(|components| tcx.intern_type_list(&components)) + .map(|components| tcx.mk_type_list(&components)) } pub(crate) fn provide(providers: &mut ty::query::Providers) { diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index f1af0073e4d..18159778a8e 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -2,11 +2,9 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; -#[cfg(not(bootstrap))] -use rustc_middle::ty::ir::TypeVisitable; use rustc_middle::ty::{ - self, ir::TypeVisitor, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, - TypeSuperVisitable, + self, Binder, EarlyBinder, Predicate, PredicateKind, ToPredicate, Ty, TyCtxt, + TypeSuperVisitable, TypeVisitable, TypeVisitor, }; use rustc_session::config::TraitSolver; use rustc_span::def_id::{DefId, CRATE_DEF_ID}; @@ -100,12 +98,12 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness { fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { if let Some(def_id) = def_id.as_local() { if matches!(tcx.representability(def_id), ty::Representability::Infinite) { - return tcx.intern_type_list(&[tcx.ty_error()]); + return tcx.mk_type_list(&[tcx.ty_error_misc()]); } } let def = tcx.adt_def(def_id); - let result = tcx.mk_type_list( + let result = tcx.mk_type_list_from_iter( def.variants() .iter() .flat_map(|v| v.fields.last()) @@ -228,11 +226,8 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { None => hir::Constness::NotConst, }; - let unnormalized_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - traits::Reveal::UserFacing, - constness, - ); + let unnormalized_env = + ty::ParamEnv::new(tcx.mk_predicates(&predicates), traits::Reveal::UserFacing, constness); let body_id = local_did.unwrap_or(CRATE_DEF_ID); let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); @@ -388,7 +383,7 @@ fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List<Predica } }); - tcx.mk_predicates(clauses.chain(input_clauses)) + tcx.mk_predicates_from_iter(clauses.chain(input_clauses)) } fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { diff --git a/config.toml.example b/config.toml.example index df4478bb0cb..69eb228a2d5 100644 --- a/config.toml.example +++ b/config.toml.example @@ -666,6 +666,9 @@ changelog-seen = 2 # LTO entirely. #lto = "thin-local" +# Build compiler with the optimization enabled and -Zvalidate-mir, currently only for `std` +#validate-mir-opts = 3 + # ============================================================================= # Options for specific targets # diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 1573b3d77dc..d4a12509b1c 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -944,65 +944,72 @@ impl<T, A: Allocator> VecDeque<T, A> { return; } - if target_cap < self.capacity() { - // There are three cases of interest: - // All elements are out of desired bounds - // Elements are contiguous, and head is out of desired bounds - // Elements are discontiguous, and tail is out of desired bounds + // There are three cases of interest: + // All elements are out of desired bounds + // Elements are contiguous, and tail is out of desired bounds + // Elements are discontiguous + // + // At all other times, element positions are unaffected. + + // `head` and `len` are at most `isize::MAX` and `target_cap < self.capacity()`, so nothing can + // overflow. + let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); + + if self.len == 0 { + self.head = 0; + } else if self.head >= target_cap && tail_outside { + // Head and tail are both out of bounds, so copy all of them to the front. // - // At all other times, element positions are unaffected. + // H := head + // L := last element + // H L + // [. . . . . . . . o o o o o o o . ] + // H L + // [o o o o o o o . ] + unsafe { + // nonoverlapping because `self.head >= target_cap >= self.len`. + self.copy_nonoverlapping(self.head, 0, self.len); + } + self.head = 0; + } else if self.head < target_cap && tail_outside { + // Head is in bounds, tail is out of bounds. + // Copy the overflowing part to the beginning of the + // buffer. This won't overlap because `target_cap >= self.len`. // - // Indicates that elements at the head should be moved. - - let tail_outside = (target_cap + 1..=self.capacity()).contains(&(self.head + self.len)); - // Move elements from out of desired bounds (positions after target_cap) - if self.len == 0 { - self.head = 0; - } else if self.head >= target_cap && tail_outside { - // H := head - // L := last element - // H L - // [. . . . . . . . o o o o o o o . ] - // H L - // [o o o o o o o . ] - unsafe { - // nonoverlapping because self.head >= target_cap >= self.len - self.copy_nonoverlapping(self.head, 0, self.len); - } - self.head = 0; - } else if self.head < target_cap && tail_outside { - // H := head - // L := last element - // H L - // [. . . o o o o o o o . . . . . . ] - // L H - // [o o . o o o o o ] - let len = self.head + self.len - target_cap; - unsafe { - self.copy_nonoverlapping(target_cap, 0, len); - } - } else if self.head >= target_cap { - // H := head - // L := last element - // L H - // [o o o o o . . . . . . . . . o o ] - // L H - // [o o o o o . o o ] - let len = self.capacity() - self.head; - let new_head = target_cap - len; - unsafe { - // can't use copy_nonoverlapping here for the same reason - // as in `handle_capacity_increase()` - self.copy(self.head, new_head, len); - } - self.head = new_head; + // H := head + // L := last element + // H L + // [. . . o o o o o o o . . . . . . ] + // L H + // [o o . o o o o o ] + let len = self.head + self.len - target_cap; + unsafe { + self.copy_nonoverlapping(target_cap, 0, len); } - - self.buf.shrink_to_fit(target_cap); - - debug_assert!(self.head < self.capacity() || self.capacity() == 0); - debug_assert!(self.len <= self.capacity()); + } else if !self.is_contiguous() { + // The head slice is at least partially out of bounds, tail is in bounds. + // Copy the head backwards so it lines up with the target capacity. + // This won't overlap because `target_cap >= self.len`. + // + // H := head + // L := last element + // L H + // [o o o o o . . . . . . . . . o o ] + // L H + // [o o o o o . o o ] + let head_len = self.capacity() - self.head; + let new_head = target_cap - head_len; + unsafe { + // can't use `copy_nonoverlapping()` here because the new and old + // regions for the head might overlap. + self.copy(self.head, new_head, head_len); + } + self.head = new_head; } + self.buf.shrink_to_fit(target_cap); + + debug_assert!(self.head < self.capacity() || self.capacity() == 0); + debug_assert!(self.len <= self.capacity()); } /// Shortens the deque, keeping the first `len` elements and dropping diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs index 220ad71beab..205a8ff3c19 100644 --- a/library/alloc/src/collections/vec_deque/tests.rs +++ b/library/alloc/src/collections/vec_deque/tests.rs @@ -749,6 +749,48 @@ fn test_drain() { } #[test] +fn issue_108453() { + let mut deque = VecDeque::with_capacity(10); + + deque.push_back(1u8); + deque.push_back(2); + deque.push_back(3); + + deque.push_front(10); + deque.push_front(9); + + deque.shrink_to(9); + + assert_eq!(deque.into_iter().collect::<Vec<_>>(), vec![9, 10, 1, 2, 3]); +} + +#[test] +fn test_shrink_to() { + // test deques with capacity 16 with all possible head positions, lengths and target capacities. + let cap = 16; + + for len in 0..cap { + for head in 0..cap { + let expected = (1..=len).collect::<VecDeque<_>>(); + + for target_cap in len..cap { + let mut deque = VecDeque::with_capacity(cap); + // currently, `with_capacity` always allocates the exact capacity if it's greater than 8. + assert_eq!(deque.capacity(), cap); + + // we can let the head point anywhere in the buffer since the deque is empty. + deque.head = head; + deque.extend(1..=len); + + deque.shrink_to(target_cap); + + assert_eq!(deque, expected); + } + } + } +} + +#[test] fn test_shrink_to_fit() { // This test checks that every single combination of head and tail position, // is tested. Capacity 15 should be large enough to cover every case. diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index a07f3da78d3..b279f21b524 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -378,8 +378,8 @@ mod spec_extend; /// Currently, `Vec` does not guarantee the order in which elements are dropped. /// The order has changed in the past and may change again. /// -/// [`get`]: ../../std/vec/struct.Vec.html#method.get -/// [`get_mut`]: ../../std/vec/struct.Vec.html#method.get_mut +/// [`get`]: slice::get +/// [`get_mut`]: slice::get_mut /// [`String`]: crate::string::String /// [`&str`]: type@str /// [`shrink_to_fit`]: Vec::shrink_to_fit diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index f95b880df34..805354be089 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -542,7 +542,7 @@ pub trait Into<T>: Sized { #[const_trait] pub trait From<T>: Sized { /// Converts to this type from the input type. - #[lang = "from"] + #[rustc_diagnostic_item = "from_fn"] #[must_use] #[stable(feature = "rust1", since = "1.0.0")] fn from(value: T) -> Self; diff --git a/library/core/src/iter/mod.rs b/library/core/src/iter/mod.rs index 156b925de77..ae00232c12c 100644 --- a/library/core/src/iter/mod.rs +++ b/library/core/src/iter/mod.rs @@ -278,6 +278,7 @@ //! //! ``` //! # #![allow(unused_must_use)] +//! # #![cfg_attr(not(bootstrap), allow(map_unit_fn))] //! let v = vec![1, 2, 3, 4, 5]; //! v.iter().map(|x| println!("{x}")); //! ``` diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 9e3e13e7004..b8e7d0a68da 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -69,6 +69,7 @@ fn _assert_is_object_safe(_: &dyn Iterator<Item = ()>) {} #[doc(notable_trait)] #[rustc_diagnostic_item = "Iterator"] #[must_use = "iterators are lazy and do nothing unless consumed"] +#[cfg_attr(not(bootstrap), const_trait)] pub trait Iterator { /// The type of the elements being iterated over. #[rustc_diagnostic_item = "IteratorItem"] @@ -141,6 +142,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_next_chunk", reason = "recently added", issue = "98326")] + #[rustc_do_not_const_check] fn next_chunk<const N: usize>( &mut self, ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> @@ -218,6 +220,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn size_hint(&self) -> (usize, Option<usize>) { (0, None) } @@ -255,6 +258,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn count(self) -> usize where Self: Sized, @@ -285,6 +289,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn last(self) -> Option<Self::Item> where Self: Sized, @@ -331,6 +336,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] + #[rustc_do_not_const_check] fn advance_by(&mut self, n: usize) -> Result<(), usize> { for i in 0..n { self.next().ok_or(i)?; @@ -379,6 +385,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn nth(&mut self, n: usize) -> Option<Self::Item> { self.advance_by(n).ok()?; self.next() @@ -431,6 +438,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_step_by", since = "1.28.0")] + #[rustc_do_not_const_check] fn step_by(self, step: usize) -> StepBy<Self> where Self: Sized, @@ -502,6 +510,7 @@ pub trait Iterator { /// [`OsStr`]: ../../std/ffi/struct.OsStr.html #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where Self: Sized, @@ -620,6 +629,7 @@ pub trait Iterator { /// [`zip`]: crate::iter::zip #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter> where Self: Sized, @@ -662,6 +672,7 @@ pub trait Iterator { /// [`intersperse_with`]: Iterator::intersperse_with #[inline] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[rustc_do_not_const_check] fn intersperse(self, separator: Self::Item) -> Intersperse<Self> where Self: Sized, @@ -720,6 +731,7 @@ pub trait Iterator { /// [`intersperse`]: Iterator::intersperse #[inline] #[unstable(feature = "iter_intersperse", reason = "recently added", issue = "79524")] + #[rustc_do_not_const_check] fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G> where Self: Sized, @@ -777,8 +789,10 @@ pub trait Iterator { /// println!("{x}"); /// } /// ``` + #[rustc_diagnostic_item = "IteratorMap"] #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn map<B, F>(self, f: F) -> Map<Self, F> where Self: Sized, @@ -824,6 +838,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_for_each", since = "1.21.0")] + #[rustc_do_not_const_check] fn for_each<F>(self, f: F) where Self: Sized, @@ -899,6 +914,7 @@ pub trait Iterator { /// Note that `iter.filter(f).next()` is equivalent to `iter.find(f)`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn filter<P>(self, predicate: P) -> Filter<Self, P> where Self: Sized, @@ -944,6 +960,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where Self: Sized, @@ -990,6 +1007,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn enumerate(self) -> Enumerate<Self> where Self: Sized, @@ -1061,6 +1079,7 @@ pub trait Iterator { /// [`next`]: Iterator::next #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn peekable(self) -> Peekable<Self> where Self: Sized, @@ -1126,6 +1145,7 @@ pub trait Iterator { #[inline] #[doc(alias = "drop_while")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where Self: Sized, @@ -1207,6 +1227,7 @@ pub trait Iterator { /// the iteration should stop, but wasn't placed back into the iterator. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where Self: Sized, @@ -1295,6 +1316,7 @@ pub trait Iterator { /// [`fuse`]: Iterator::fuse #[inline] #[stable(feature = "iter_map_while", since = "1.57.0")] + #[rustc_do_not_const_check] fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P> where Self: Sized, @@ -1326,6 +1348,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn skip(self, n: usize) -> Skip<Self> where Self: Sized, @@ -1379,6 +1402,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn take(self, n: usize) -> Take<Self> where Self: Sized, @@ -1428,6 +1452,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F> where Self: Sized, @@ -1468,6 +1493,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F> where Self: Sized, @@ -1552,6 +1578,7 @@ pub trait Iterator { /// [`flat_map()`]: Iterator::flat_map #[inline] #[stable(feature = "iterator_flatten", since = "1.29.0")] + #[rustc_do_not_const_check] fn flatten(self) -> Flatten<Self> where Self: Sized, @@ -1620,6 +1647,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn fuse(self) -> Fuse<Self> where Self: Sized, @@ -1704,6 +1732,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn inspect<F>(self, f: F) -> Inspect<Self, F> where Self: Sized, @@ -1734,6 +1763,7 @@ pub trait Iterator { /// assert_eq!(of_rust, vec!["of", "Rust"]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn by_ref(&mut self) -> &mut Self where Self: Sized, @@ -1853,6 +1883,7 @@ pub trait Iterator { #[stable(feature = "rust1", since = "1.0.0")] #[must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead"] #[cfg_attr(not(test), rustc_diagnostic_item = "iterator_collect_fn")] + #[rustc_do_not_const_check] fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized, @@ -1931,6 +1962,7 @@ pub trait Iterator { /// [`collect`]: Iterator::collect #[inline] #[unstable(feature = "iterator_try_collect", issue = "94047")] + #[rustc_do_not_const_check] fn try_collect<B>(&mut self) -> ChangeOutputType<Self::Item, B> where Self: Sized, @@ -2004,6 +2036,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iter_collect_into", reason = "new API", issue = "94780")] + #[rustc_do_not_const_check] fn collect_into<E: Extend<Self::Item>>(self, collection: &mut E) -> &mut E where Self: Sized, @@ -2038,6 +2071,7 @@ pub trait Iterator { /// assert_eq!(odd, vec![1, 3]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn partition<B, F>(self, f: F) -> (B, B) where Self: Sized, @@ -2100,6 +2134,7 @@ pub trait Iterator { /// assert!(a[i..].iter().all(|&n| n % 2 == 1)); // odds /// ``` #[unstable(feature = "iter_partition_in_place", reason = "new API", issue = "62543")] + #[rustc_do_not_const_check] fn partition_in_place<'a, T: 'a, P>(mut self, ref mut predicate: P) -> usize where Self: Sized + DoubleEndedIterator<Item = &'a mut T>, @@ -2157,6 +2192,7 @@ pub trait Iterator { /// assert!(!"IntoIterator".chars().is_partitioned(char::is_uppercase)); /// ``` #[unstable(feature = "iter_is_partitioned", reason = "new API", issue = "62544")] + #[rustc_do_not_const_check] fn is_partitioned<P>(mut self, mut predicate: P) -> bool where Self: Sized, @@ -2251,6 +2287,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_try_fold", since = "1.27.0")] + #[rustc_do_not_const_check] fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where Self: Sized, @@ -2309,6 +2346,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_try_fold", since = "1.27.0")] + #[rustc_do_not_const_check] fn try_for_each<F, R>(&mut self, f: F) -> R where Self: Sized, @@ -2428,6 +2466,7 @@ pub trait Iterator { #[doc(alias = "inject", alias = "foldl")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn fold<B, F>(mut self, init: B, mut f: F) -> B where Self: Sized, @@ -2465,6 +2504,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_fold_self", since = "1.51.0")] + #[rustc_do_not_const_check] fn reduce<F>(mut self, f: F) -> Option<Self::Item> where Self: Sized, @@ -2536,6 +2576,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "iterator_try_reduce", reason = "new API", issue = "87053")] + #[rustc_do_not_const_check] fn try_reduce<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<R::Output>> where Self: Sized, @@ -2593,6 +2634,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn all<F>(&mut self, f: F) -> bool where Self: Sized, @@ -2646,6 +2688,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn any<F>(&mut self, f: F) -> bool where Self: Sized, @@ -2709,6 +2752,7 @@ pub trait Iterator { /// Note that `iter.find(f)` is equivalent to `iter.filter(f).next()`. #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn find<P>(&mut self, predicate: P) -> Option<Self::Item> where Self: Sized, @@ -2740,6 +2784,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iterator_find_map", since = "1.30.0")] + #[rustc_do_not_const_check] fn find_map<B, F>(&mut self, f: F) -> Option<B> where Self: Sized, @@ -2796,6 +2841,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "try_find", reason = "new API", issue = "63178")] + #[rustc_do_not_const_check] fn try_find<F, R>(&mut self, f: F) -> ChangeOutputType<R, Option<Self::Item>> where Self: Sized, @@ -2878,6 +2924,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn position<P>(&mut self, predicate: P) -> Option<usize> where Self: Sized, @@ -2935,6 +2982,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn rposition<P>(&mut self, predicate: P) -> Option<usize> where P: FnMut(Self::Item) -> bool, @@ -2986,6 +3034,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn max(self) -> Option<Self::Item> where Self: Sized, @@ -3024,6 +3073,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn min(self) -> Option<Self::Item> where Self: Sized, @@ -3046,6 +3096,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + #[rustc_do_not_const_check] fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> where Self: Sized, @@ -3079,6 +3130,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_max_by", since = "1.15.0")] + #[rustc_do_not_const_check] fn max_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, @@ -3106,6 +3158,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + #[rustc_do_not_const_check] fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item> where Self: Sized, @@ -3139,6 +3192,7 @@ pub trait Iterator { /// ``` #[inline] #[stable(feature = "iter_min_by", since = "1.15.0")] + #[rustc_do_not_const_check] fn min_by<F>(self, compare: F) -> Option<Self::Item> where Self: Sized, @@ -3176,6 +3230,7 @@ pub trait Iterator { #[inline] #[doc(alias = "reverse")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn rev(self) -> Rev<Self> where Self: Sized + DoubleEndedIterator, @@ -3214,6 +3269,7 @@ pub trait Iterator { /// assert_eq!(z, [3, 6]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where FromA: Default + Extend<A>, @@ -3246,6 +3302,7 @@ pub trait Iterator { /// assert_eq!(v_map, vec![1, 2, 3]); /// ``` #[stable(feature = "iter_copied", since = "1.36.0")] + #[rustc_do_not_const_check] fn copied<'a, T: 'a>(self) -> Copied<Self> where Self: Sized + Iterator<Item = &'a T>, @@ -3293,6 +3350,7 @@ pub trait Iterator { /// assert_eq!(&[vec![23]], &faster[..]); /// ``` #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_do_not_const_check] fn cloned<'a, T: 'a>(self) -> Cloned<Self> where Self: Sized + Iterator<Item = &'a T>, @@ -3327,6 +3385,7 @@ pub trait Iterator { /// ``` #[stable(feature = "rust1", since = "1.0.0")] #[inline] + #[rustc_do_not_const_check] fn cycle(self) -> Cycle<Self> where Self: Sized + Clone, @@ -3370,6 +3429,7 @@ pub trait Iterator { /// ``` #[track_caller] #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] + #[rustc_do_not_const_check] fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N> where Self: Sized, @@ -3400,6 +3460,7 @@ pub trait Iterator { /// assert_eq!(sum, 6); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] + #[rustc_do_not_const_check] fn sum<S>(self) -> S where Self: Sized, @@ -3429,6 +3490,7 @@ pub trait Iterator { /// assert_eq!(factorial(5), 120); /// ``` #[stable(feature = "iter_arith", since = "1.11.0")] + #[rustc_do_not_const_check] fn product<P>(self) -> P where Self: Sized, @@ -3450,6 +3512,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().cmp([1].iter()), Ordering::Greater); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn cmp<I>(self, other: I) -> Ordering where I: IntoIterator<Item = Self::Item>, @@ -3479,6 +3542,7 @@ pub trait Iterator { /// assert_eq!(xs.iter().cmp_by(&ys, |&x, &y| (2 * x).cmp(&y)), Ordering::Greater); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering where Self: Sized, @@ -3535,6 +3599,7 @@ pub trait Iterator { /// ``` /// #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn partial_cmp<I>(self, other: I) -> Option<Ordering> where I: IntoIterator, @@ -3573,6 +3638,7 @@ pub trait Iterator { /// ); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering> where Self: Sized, @@ -3606,6 +3672,7 @@ pub trait Iterator { /// assert_eq!([1].iter().eq([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn eq<I>(self, other: I) -> bool where I: IntoIterator, @@ -3631,6 +3698,7 @@ pub trait Iterator { /// assert!(xs.iter().eq_by(&ys, |&x, &y| x * x == y)); /// ``` #[unstable(feature = "iter_order_by", issue = "64295")] + #[rustc_do_not_const_check] fn eq_by<I, F>(self, other: I, eq: F) -> bool where Self: Sized, @@ -3663,6 +3731,7 @@ pub trait Iterator { /// assert_eq!([1].iter().ne([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn ne<I>(self, other: I) -> bool where I: IntoIterator, @@ -3684,6 +3753,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().lt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn lt<I>(self, other: I) -> bool where I: IntoIterator, @@ -3705,6 +3775,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().le([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn le<I>(self, other: I) -> bool where I: IntoIterator, @@ -3726,6 +3797,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().gt([1, 2].iter()), false); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn gt<I>(self, other: I) -> bool where I: IntoIterator, @@ -3747,6 +3819,7 @@ pub trait Iterator { /// assert_eq!([1, 2].iter().ge([1, 2].iter()), true); /// ``` #[stable(feature = "iter_order", since = "1.5.0")] + #[rustc_do_not_const_check] fn ge<I>(self, other: I) -> bool where I: IntoIterator, @@ -3778,6 +3851,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted(self) -> bool where Self: Sized, @@ -3806,6 +3880,7 @@ pub trait Iterator { /// /// [`is_sorted`]: Iterator::is_sorted #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted_by<F>(mut self, compare: F) -> bool where Self: Sized, @@ -3852,6 +3927,7 @@ pub trait Iterator { /// ``` #[inline] #[unstable(feature = "is_sorted", reason = "new API", issue = "53485")] + #[rustc_do_not_const_check] fn is_sorted_by_key<F, K>(self, f: F) -> bool where Self: Sized, @@ -3867,6 +3943,7 @@ pub trait Iterator { #[inline] #[doc(hidden)] #[unstable(feature = "trusted_random_access", issue = "none")] + #[rustc_do_not_const_check] unsafe fn __iterator_get_unchecked(&mut self, _idx: usize) -> Self::Item where Self: TrustedRandomAccessNoCoerce, diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index dc0702c467a..d3727a824b5 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -194,6 +194,7 @@ #![feature(cfg_target_has_atomic_equal_alignment)] #![feature(const_closures)] #![feature(const_fn_floating_point_arithmetic)] +#![feature(const_for)] #![feature(const_mut_refs)] #![feature(const_precise_live_drops)] #![feature(const_refs_to_cell)] diff --git a/library/core/src/slice/sort.rs b/library/core/src/slice/sort.rs index 4ca4eb86bde..7b8062c431e 100644 --- a/library/core/src/slice/sort.rs +++ b/library/core/src/slice/sort.rs @@ -673,19 +673,23 @@ where fn break_patterns<T>(v: &mut [T]) { let len = v.len(); if len >= 8 { - // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia. - let mut random = len as u32; - let mut gen_u32 = || { - random ^= random << 13; - random ^= random >> 17; - random ^= random << 5; - random - }; + let mut seed = len; let mut gen_usize = || { + // Pseudorandom number generator from the "Xorshift RNGs" paper by George Marsaglia. if usize::BITS <= 32 { - gen_u32() as usize + let mut r = seed as u32; + r ^= r << 13; + r ^= r >> 17; + r ^= r << 5; + seed = r as usize; + seed } else { - (((gen_u32() as u64) << 32) | (gen_u32() as u64)) as usize + let mut r = seed as u64; + r ^= r << 13; + r ^= r >> 7; + r ^= r << 17; + seed = r as usize; + seed } }; diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 1d14efc7523..00bcaf3e18c 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -922,13 +922,13 @@ impl AtomicBool { /// /// let mut atomic = AtomicBool::new(true); /// unsafe { - /// my_atomic_op(atomic.as_mut_ptr()); + /// my_atomic_op(atomic.as_ptr()); /// } /// # } /// ``` #[inline] #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")] - pub const fn as_mut_ptr(&self) -> *mut bool { + pub const fn as_ptr(&self) -> *mut bool { self.v.get().cast() } @@ -1814,12 +1814,12 @@ impl<T> AtomicPtr<T> { /// /// // SAFETY: Safe as long as `my_atomic_op` is atomic. /// unsafe { - /// my_atomic_op(atomic.as_mut_ptr()); + /// my_atomic_op(atomic.as_ptr()); /// } /// ``` #[inline] #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")] - pub const fn as_mut_ptr(&self) -> *mut *mut T { + pub const fn as_ptr(&self) -> *mut *mut T { self.p.get() } } @@ -2719,7 +2719,7 @@ macro_rules! atomic_int { /// /// // SAFETY: Safe as long as `my_atomic_op` is atomic. /// unsafe { - /// my_atomic_op(atomic.as_mut_ptr()); + /// my_atomic_op(atomic.as_ptr()); /// } /// # } /// ``` @@ -2727,7 +2727,7 @@ macro_rules! atomic_int { #[unstable(feature = "atomic_mut_ptr", reason = "recently added", issue = "66893")] - pub const fn as_mut_ptr(&self) -> *mut $int_type { + pub const fn as_ptr(&self) -> *mut $int_type { self.v.get() } } diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 349cd91c89e..311b2e21c17 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -43,7 +43,7 @@ dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] } fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] } [target.'cfg(target_os = "hermit")'.dependencies] -hermit-abi = { version = "0.2.6", features = ['rustc-dep-of-std'] } +hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] } [target.wasm32-wasi.dependencies] wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false } diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 839fdc96632..909d9bf4093 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1595,3 +1595,19 @@ fn test_read_dir_infinite_loop() { // Check for duplicate errors assert!(dir.filter(|e| e.is_err()).take(2).count() < 2); } + +#[test] +fn rename_directory() { + let tmpdir = tmpdir(); + let old_path = tmpdir.join("foo/bar/baz"); + fs::create_dir_all(&old_path).unwrap(); + let test_file = &old_path.join("temp.txt"); + + File::create(test_file).unwrap(); + + let new_path = tmpdir.join("quux/blat"); + fs::create_dir_all(&new_path).unwrap(); + fs::rename(&old_path, &new_path.join("newdir")).unwrap(); + assert!(new_path.join("newdir").is_dir()); + assert!(new_path.join("newdir/temp.txt").exists()); +} diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index e35145c4ade..203c490fa29 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -1568,7 +1568,7 @@ mod static_keyword {} /// /// # Style conventions /// -/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a +/// Structs are always written in UpperCamelCase, with few exceptions. While the trailing comma on a /// struct's list of fields can be omitted, it's usually kept for convenience in adding and /// removing fields down the line. /// diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 439b8d52a2d..258919d53a4 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -9,7 +9,7 @@ use crate::fs; use crate::io; use crate::marker::PhantomData; use crate::mem::forget; -#[cfg(not(any(target_arch = "wasm32", target_env = "sgx")))] +#[cfg(not(any(target_arch = "wasm32", target_env = "sgx", target_os = "hermit")))] use crate::sys::cvt; use crate::sys_common::{AsInner, FromInner, IntoInner}; @@ -89,7 +89,7 @@ impl OwnedFd { impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(not(any(target_arch = "wasm32", target_os = "hermit")))] #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> { // We want to atomically duplicate this file descriptor and set the @@ -112,7 +112,7 @@ impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. - #[cfg(target_arch = "wasm32")] + #[cfg(any(target_arch = "wasm32", target_os = "hermit"))] #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> crate::io::Result<OwnedFd> { Err(crate::io::const_io_error!( @@ -174,7 +174,10 @@ impl Drop for OwnedFd { // the file descriptor was closed or not, and if we retried (for // something like EINTR), we might close another valid file descriptor // opened after we closed ours. + #[cfg(not(target_os = "hermit"))] let _ = libc::close(self.fd); + #[cfg(target_os = "hermit")] + let _ = hermit_abi::close(self.fd); } } } diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index c138162f1ab..0a4cefd2095 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -4,6 +4,9 @@ use crate::fs; use crate::io; +#[cfg(target_os = "hermit")] +use crate::os::hermit::io::OwnedFd; +#[cfg(not(target_os = "hermit"))] use crate::os::raw; #[cfg(all(doc, not(target_arch = "wasm32")))] use crate::os::unix::io::AsFd; @@ -12,11 +15,18 @@ use crate::os::unix::io::OwnedFd; #[cfg(target_os = "wasi")] use crate::os::wasi::io::OwnedFd; use crate::sys_common::{AsInner, IntoInner}; +#[cfg(target_os = "hermit")] +use hermit_abi as libc; /// Raw file descriptors. #[rustc_allowed_through_unstable_modules] #[stable(feature = "rust1", since = "1.0.0")] +#[cfg(not(target_os = "hermit"))] pub type RawFd = raw::c_int; +#[rustc_allowed_through_unstable_modules] +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg(target_os = "hermit")] +pub type RawFd = i32; /// A trait to extract the raw file descriptor from an underlying object. /// diff --git a/library/std/src/os/hermit/io/mod.rs b/library/std/src/os/hermit/io/mod.rs new file mode 100644 index 00000000000..524dfae0d63 --- /dev/null +++ b/library/std/src/os/hermit/io/mod.rs @@ -0,0 +1,13 @@ +#![stable(feature = "os_fd", since = "1.66.0")] + +mod net; +#[path = "../../fd/owned.rs"] +mod owned; +#[path = "../../fd/raw.rs"] +mod raw; + +// Export the types and traits for the public API. +#[stable(feature = "os_fd", since = "1.66.0")] +pub use owned::*; +#[stable(feature = "os_fd", since = "1.66.0")] +pub use raw::*; diff --git a/library/std/src/os/hermit/io/net.rs b/library/std/src/os/hermit/io/net.rs new file mode 100644 index 00000000000..8f3802d7873 --- /dev/null +++ b/library/std/src/os/hermit/io/net.rs @@ -0,0 +1,46 @@ +use crate::os::hermit::io::OwnedFd; +use crate::os::hermit::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; +use crate::sys_common::{self, AsInner, FromInner, IntoInner}; +use crate::{net, sys}; + +macro_rules! impl_as_raw_fd { + ($($t:ident)*) => {$( + #[stable(feature = "rust1", since = "1.0.0")] + impl AsRawFd for net::$t { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.as_inner().socket().as_raw_fd() + } + } + )*}; +} +impl_as_raw_fd! { TcpStream TcpListener UdpSocket } + +macro_rules! impl_from_raw_fd { + ($($t:ident)*) => {$( + #[stable(feature = "from_raw_os", since = "1.1.0")] + impl FromRawFd for net::$t { + #[inline] + unsafe fn from_raw_fd(fd: RawFd) -> net::$t { + unsafe { + let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))); + net::$t::from_inner(sys_common::net::$t::from_inner(socket)) + } + } + } + )*}; +} +impl_from_raw_fd! { TcpStream TcpListener UdpSocket } + +macro_rules! impl_into_raw_fd { + ($($t:ident)*) => {$( + #[stable(feature = "into_raw_os", since = "1.4.0")] + impl IntoRawFd for net::$t { + #[inline] + fn into_raw_fd(self) -> RawFd { + self.into_inner().into_socket().into_inner().into_inner().into_raw_fd() + } + } + )*}; +} +impl_into_raw_fd! { TcpStream TcpListener UdpSocket } diff --git a/library/std/src/os/hermit/mod.rs b/library/std/src/os/hermit/mod.rs index 4657b545a1b..89b1b831912 100644 --- a/library/std/src/os/hermit/mod.rs +++ b/library/std/src/os/hermit/mod.rs @@ -1,6 +1,11 @@ #![stable(feature = "rust1", since = "1.0.0")] +#[allow(unused_extern_crates)] +#[stable(feature = "rust1", since = "1.0.0")] +pub extern crate hermit_abi as abi; + pub mod ffi; +pub mod io; /// A prelude for conveniently writing platform-specific code. /// diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 42773805cdb..af137c9bd85 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -60,16 +60,6 @@ pub mod windows {} all(target_vendor = "fortanix", target_env = "sgx") ) )))] -#[cfg(target_os = "hermit")] -#[path = "hermit/mod.rs"] -pub mod unix; -#[cfg(not(all( - doc, - any( - all(target_arch = "wasm32", not(target_os = "wasi")), - all(target_vendor = "fortanix", target_env = "sgx") - ) -)))] #[cfg(all(not(target_os = "hermit"), any(unix, doc)))] pub mod unix; @@ -123,6 +113,8 @@ pub mod freebsd; pub mod fuchsia; #[cfg(target_os = "haiku")] pub mod haiku; +#[cfg(target_os = "hermit")] +pub mod hermit; #[cfg(target_os = "horizon")] pub mod horizon; #[cfg(target_os = "illumos")] diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index b0db3112e22..e59f32af77d 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -95,13 +95,16 @@ impl Default for Hook { static HOOK: RwLock<Hook> = RwLock::new(Hook::Default); -/// Registers a custom panic hook, replacing any that was previously registered. +/// Registers a custom panic hook, replacing the previously registered hook. /// /// The panic hook is invoked when a thread panics, but before the panic runtime /// is invoked. As such, the hook will run with both the aborting and unwinding -/// runtimes. The default hook prints a message to standard error and generates -/// a backtrace if requested, but this behavior can be customized with the -/// `set_hook` and [`take_hook`] functions. +/// runtimes. +/// +/// The default hook, which is registered at startup, prints a message to standard error and +/// generates a backtrace if requested. This behavior can be customized using the `set_hook` function. +/// The current hook can be retrieved while reinstating the default hook with the [`take_hook`] +/// function. /// /// [`take_hook`]: ./fn.take_hook.html /// @@ -143,13 +146,14 @@ pub fn set_hook(hook: Box<dyn Fn(&PanicInfo<'_>) + 'static + Sync + Send>) { drop(old); } -/// Unregisters the current panic hook, returning it. +/// Unregisters the current panic hook and returns it, registering the default hook +/// in its place. /// /// *See also the function [`set_hook`].* /// /// [`set_hook`]: ./fn.set_hook.html /// -/// If no custom hook is registered, the default hook will be returned. +/// If the default hook is registered it will be returned, but remain registered. /// /// # Panics /// diff --git a/library/std/src/sys/hermit/args.rs b/library/std/src/sys/hermit/args.rs index afcae6c90ee..220a76e4b12 100644 --- a/library/std/src/sys/hermit/args.rs +++ b/library/std/src/sys/hermit/args.rs @@ -1,6 +1,6 @@ use crate::ffi::{c_char, CStr, OsString}; use crate::fmt; -use crate::os::unix::ffi::OsStringExt; +use crate::os::hermit::ffi::OsStringExt; use crate::ptr; use crate::sync::atomic::{ AtomicIsize, AtomicPtr, diff --git a/library/std/src/sys/hermit/fd.rs b/library/std/src/sys/hermit/fd.rs index c400f5f2c2e..3a2cdd301ea 100644 --- a/library/std/src/sys/hermit/fd.rs +++ b/library/std/src/sys/hermit/fd.rs @@ -1,36 +1,23 @@ #![unstable(reason = "not public", issue = "none", feature = "fd")] use crate::io::{self, Read}; -use crate::mem; +use crate::os::hermit::io::{FromRawFd, OwnedFd, RawFd}; use crate::sys::cvt; use crate::sys::hermit::abi; use crate::sys::unsupported; -use crate::sys_common::AsInner; +use crate::sys_common::{AsInner, FromInner, IntoInner}; + +use crate::os::hermit::io::*; #[derive(Debug)] pub struct FileDesc { - fd: i32, + fd: OwnedFd, } impl FileDesc { - pub fn new(fd: i32) -> FileDesc { - FileDesc { fd } - } - - pub fn raw(&self) -> i32 { - self.fd - } - - /// Extracts the actual file descriptor without closing it. - pub fn into_raw(self) -> i32 { - let fd = self.fd; - mem::forget(self); - fd - } - pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { - let result = unsafe { abi::read(self.fd, buf.as_mut_ptr(), buf.len()) }; - cvt(result as i32) + let result = cvt(unsafe { abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?; + Ok(result as usize) } pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> { @@ -39,8 +26,8 @@ impl FileDesc { } pub fn write(&self, buf: &[u8]) -> io::Result<usize> { - let result = unsafe { abi::write(self.fd, buf.as_ptr(), buf.len()) }; - cvt(result as i32) + let result = cvt(unsafe { abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?; + Ok(result as usize) } pub fn duplicate(&self) -> io::Result<FileDesc> { @@ -69,19 +56,45 @@ impl<'a> Read for &'a FileDesc { } } -impl AsInner<i32> for FileDesc { - fn as_inner(&self) -> &i32 { +impl IntoInner<OwnedFd> for FileDesc { + fn into_inner(self) -> OwnedFd { + self.fd + } +} + +impl FromInner<OwnedFd> for FileDesc { + fn from_inner(owned_fd: OwnedFd) -> Self { + Self { fd: owned_fd } + } +} + +impl FromRawFd for FileDesc { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self { fd: FromRawFd::from_raw_fd(raw_fd) } + } +} + +impl AsInner<OwnedFd> for FileDesc { + fn as_inner(&self) -> &OwnedFd { &self.fd } } -impl Drop for FileDesc { - fn drop(&mut self) { - // Note that errors are ignored when closing a file descriptor. The - // reason for this is that if an error occurs we don't actually know if - // the file descriptor was closed or not, and if we retried (for - // something like EINTR), we might close another valid file descriptor - // (opened after we closed ours. - let _ = unsafe { abi::close(self.fd) }; +impl AsFd for FileDesc { + fn as_fd(&self) -> BorrowedFd<'_> { + self.fd.as_fd() + } +} + +impl AsRawFd for FileDesc { + #[inline] + fn as_raw_fd(&self) -> RawFd { + self.fd.as_raw_fd() + } +} + +impl IntoRawFd for FileDesc { + fn into_raw_fd(self) -> RawFd { + self.fd.into_raw_fd() } } diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index 6fb92c037ee..c966f217757 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -3,14 +3,17 @@ use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::io::{self, Error, ErrorKind}; use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; +use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; use crate::path::{Path, PathBuf}; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::{O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY}; +use crate::sys::hermit::abi::{ + self, O_APPEND, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_TRUNC, O_WRONLY, +}; use crate::sys::hermit::fd::FileDesc; use crate::sys::time::SystemTime; use crate::sys::unsupported; +use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; pub use crate::sys_common::fs::{copy, try_exists}; //pub use crate::sys_common::fs::remove_dir_all; @@ -283,7 +286,7 @@ impl File { } let fd = unsafe { cvt(abi::open(path.as_ptr(), flags, mode))? }; - Ok(File(FileDesc::new(fd as i32))) + Ok(File(unsafe { FileDesc::from_raw_fd(fd as i32) })) } pub fn file_attr(&self) -> io::Result<FileAttr> { @@ -363,6 +366,54 @@ impl DirBuilder { } } +impl AsInner<FileDesc> for File { + fn as_inner(&self) -> &FileDesc { + &self.0 + } +} + +impl AsInnerMut<FileDesc> for File { + fn as_inner_mut(&mut self) -> &mut FileDesc { + &mut self.0 + } +} + +impl IntoInner<FileDesc> for File { + fn into_inner(self) -> FileDesc { + self.0 + } +} + +impl FromInner<FileDesc> for File { + fn from_inner(file_desc: FileDesc) -> Self { + Self(file_desc) + } +} + +impl AsFd for File { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() + } +} + +impl AsRawFd for File { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() + } +} + +impl IntoRawFd for File { + fn into_raw_fd(self) -> RawFd { + self.0.into_raw_fd() + } +} + +impl FromRawFd for File { + unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + Self(FromRawFd::from_raw_fd(raw_fd)) + } +} + pub fn readdir(_p: &Path) -> io::Result<ReadDir> { unsupported() } diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index 20fd3dd8f09..d34a4cfedea 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -13,7 +13,7 @@ //! compiling for wasm. That way it's a compile time error for something that's //! guaranteed to be a runtime error! -#![allow(unsafe_op_in_unsafe_fn)] +#![allow(missing_docs, nonstandard_style, unsafe_op_in_unsafe_fn)] use crate::intrinsics; use crate::os::raw::c_char; @@ -57,9 +57,7 @@ pub mod locks { } use crate::io::ErrorKind; - -#[allow(unused_extern_crates)] -pub extern crate hermit_abi as abi; +use crate::os::hermit::abi; pub fn unsupported<T>() -> crate::io::Result<T> { Err(unsupported_err()) @@ -126,25 +124,72 @@ pub unsafe extern "C" fn runtime_entry( pub fn decode_error_kind(errno: i32) -> ErrorKind { match errno { - x if x == 13 as i32 => ErrorKind::PermissionDenied, - x if x == 98 as i32 => ErrorKind::AddrInUse, - x if x == 99 as i32 => ErrorKind::AddrNotAvailable, - x if x == 11 as i32 => ErrorKind::WouldBlock, - x if x == 103 as i32 => ErrorKind::ConnectionAborted, - x if x == 111 as i32 => ErrorKind::ConnectionRefused, - x if x == 104 as i32 => ErrorKind::ConnectionReset, - x if x == 17 as i32 => ErrorKind::AlreadyExists, - x if x == 4 as i32 => ErrorKind::Interrupted, - x if x == 22 as i32 => ErrorKind::InvalidInput, - x if x == 2 as i32 => ErrorKind::NotFound, - x if x == 107 as i32 => ErrorKind::NotConnected, - x if x == 1 as i32 => ErrorKind::PermissionDenied, - x if x == 32 as i32 => ErrorKind::BrokenPipe, - x if x == 110 as i32 => ErrorKind::TimedOut, + abi::errno::EACCES => ErrorKind::PermissionDenied, + abi::errno::EADDRINUSE => ErrorKind::AddrInUse, + abi::errno::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, + abi::errno::EAGAIN => ErrorKind::WouldBlock, + abi::errno::ECONNABORTED => ErrorKind::ConnectionAborted, + abi::errno::ECONNREFUSED => ErrorKind::ConnectionRefused, + abi::errno::ECONNRESET => ErrorKind::ConnectionReset, + abi::errno::EEXIST => ErrorKind::AlreadyExists, + abi::errno::EINTR => ErrorKind::Interrupted, + abi::errno::EINVAL => ErrorKind::InvalidInput, + abi::errno::ENOENT => ErrorKind::NotFound, + abi::errno::ENOTCONN => ErrorKind::NotConnected, + abi::errno::EPERM => ErrorKind::PermissionDenied, + abi::errno::EPIPE => ErrorKind::BrokenPipe, + abi::errno::ETIMEDOUT => ErrorKind::TimedOut, _ => ErrorKind::Uncategorized, } } -pub fn cvt(result: i32) -> crate::io::Result<usize> { - if result < 0 { Err(crate::io::Error::from_raw_os_error(-result)) } else { Ok(result as usize) } +#[doc(hidden)] +pub trait IsNegative { + fn is_negative(&self) -> bool; + fn negate(&self) -> i32; +} + +macro_rules! impl_is_negative { + ($($t:ident)*) => ($(impl IsNegative for $t { + fn is_negative(&self) -> bool { + *self < 0 + } + + fn negate(&self) -> i32 { + i32::try_from(-(*self)).unwrap() + } + })*) +} + +impl IsNegative for i32 { + fn is_negative(&self) -> bool { + *self < 0 + } + + fn negate(&self) -> i32 { + -(*self) + } +} +impl_is_negative! { i8 i16 i64 isize } + +pub fn cvt<T: IsNegative>(t: T) -> crate::io::Result<T> { + if t.is_negative() { + let e = decode_error_kind(t.negate()); + Err(crate::io::Error::from(e)) + } else { + Ok(t) + } +} + +pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T> +where + T: IsNegative, + F: FnMut() -> T, +{ + loop { + match cvt(f()) { + Err(ref e) if e.kind() == ErrorKind::Interrupted => {} + other => return other, + } + } } diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs index 8a13879d8cc..5fb6281aa1e 100644 --- a/library/std/src/sys/hermit/net.rs +++ b/library/std/src/sys/hermit/net.rs @@ -1,490 +1,353 @@ -use crate::fmt; -use crate::io::{self, ErrorKind, IoSlice, IoSliceMut}; -use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr}; -use crate::str; -use crate::sync::Arc; -use crate::sys::hermit::abi; -use crate::sys::hermit::abi::IpAddress::{Ipv4, Ipv6}; -use crate::sys::unsupported; -use crate::sys_common::AsInner; +#![allow(dead_code)] + +use crate::cmp; +use crate::io::{self, IoSlice, IoSliceMut}; +use crate::mem; +use crate::net::{Shutdown, SocketAddr}; +use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; +use crate::sys::hermit::fd::FileDesc; +use crate::sys::time::Instant; +use crate::sys_common::net::{getsockopt, setsockopt, sockaddr_to_addr}; +use crate::sys_common::{AsInner, FromInner, IntoInner}; use crate::time::Duration; -/// Checks whether the HermitCore's socket interface has been started already, and -/// if not, starts it. -pub fn init() -> io::Result<()> { - if abi::network_init() < 0 { - return Err(io::const_io_error!( - ErrorKind::Uncategorized, - "Unable to initialize network interface", - )); - } - - Ok(()) -} - -#[derive(Debug, Clone)] -pub struct Socket(abi::Handle); - -impl AsInner<abi::Handle> for Socket { - fn as_inner(&self) -> &abi::Handle { - &self.0 - } -} +use core::ffi::c_int; -impl Drop for Socket { - fn drop(&mut self) { - let _ = abi::tcpstream::close(self.0); - } -} +#[allow(unused_extern_crates)] +pub extern crate hermit_abi as netc; -// Arc is used to count the number of used sockets. -// Only if all sockets are released, the drop -// method will close the socket. -#[derive(Clone)] -pub struct TcpStream(Arc<Socket>); - -impl TcpStream { - pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> { - let addr = addr?; - - match abi::tcpstream::connect(addr.ip().to_string().as_bytes(), addr.port(), None) { - Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))), - _ => Err(io::const_io_error!( - ErrorKind::Uncategorized, - "Unable to initiate a connection on a socket", - )), - } - } +pub use crate::sys::{cvt, cvt_r}; - pub fn connect_timeout(saddr: &SocketAddr, duration: Duration) -> io::Result<TcpStream> { - match abi::tcpstream::connect( - saddr.ip().to_string().as_bytes(), - saddr.port(), - Some(duration.as_millis() as u64), - ) { - Ok(handle) => Ok(TcpStream(Arc::new(Socket(handle)))), - _ => Err(io::const_io_error!( - ErrorKind::Uncategorized, - "Unable to initiate a connection on a socket", - )), - } - } +pub type wrlen_t = usize; - pub fn set_read_timeout(&self, duration: Option<Duration>) -> io::Result<()> { - abi::tcpstream::set_read_timeout(*self.0.as_inner(), duration.map(|d| d.as_millis() as u64)) - .map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value") - }) +pub fn cvt_gai(err: i32) -> io::Result<()> { + if err == 0 { + return Ok(()); } - pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> { - abi::tcpstream::set_write_timeout( - *self.0.as_inner(), - duration.map(|d| d.as_millis() as u64), - ) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "Unable to set timeout value")) - } + let detail = ""; - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - let duration = abi::tcpstream::get_read_timeout(*self.0.as_inner()).map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value") - })?; + Err(io::Error::new( + io::ErrorKind::Uncategorized, + &format!("failed to lookup address information: {detail}")[..], + )) +} - Ok(duration.map(|d| Duration::from_millis(d))) +/// Checks whether the HermitCore's socket interface has been started already, and +/// if not, starts it. +pub fn init() { + if unsafe { netc::network_init() } < 0 { + panic!("Unable to initialize network interface"); } +} - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - let duration = abi::tcpstream::get_write_timeout(*self.0.as_inner()).map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "Unable to determine timeout value") - })?; +#[derive(Debug)] +pub struct Socket(FileDesc); - Ok(duration.map(|d| Duration::from_millis(d))) +impl Socket { + pub fn new(addr: &SocketAddr, ty: i32) -> io::Result<Socket> { + let fam = match *addr { + SocketAddr::V4(..) => netc::AF_INET, + SocketAddr::V6(..) => netc::AF_INET6, + }; + Socket::new_raw(fam, ty) } - pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { - abi::tcpstream::peek(*self.0.as_inner(), buf) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peek failed")) + pub fn new_raw(fam: i32, ty: i32) -> io::Result<Socket> { + let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?; + Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } - pub fn read(&self, buffer: &mut [u8]) -> io::Result<usize> { - self.read_vectored(&mut [IoSliceMut::new(buffer)]) + pub fn new_pair(_fam: i32, _ty: i32) -> io::Result<(Socket, Socket)> { + unimplemented!() } - pub fn read_vectored(&self, ioslice: &mut [IoSliceMut<'_>]) -> io::Result<usize> { - let mut size: usize = 0; - - for i in ioslice.iter_mut() { - let ret = abi::tcpstream::read(*self.0.as_inner(), &mut i[0..]).map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "Unable to read on socket") - })?; + pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { + self.set_nonblocking(true)?; + let r = unsafe { + let (addr, len) = addr.into_inner(); + cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len)) + }; + self.set_nonblocking(false)?; - if ret != 0 { - size += ret; - } + match r { + Ok(_) => return Ok(()), + // there's no ErrorKind for EINPROGRESS :( + Err(ref e) if e.raw_os_error() == Some(netc::errno::EINPROGRESS) => {} + Err(e) => return Err(e), } - Ok(size) - } - - #[inline] - pub fn is_read_vectored(&self) -> bool { - true - } - - pub fn write(&self, buffer: &[u8]) -> io::Result<usize> { - self.write_vectored(&[IoSlice::new(buffer)]) - } + let mut pollfd = netc::pollfd { fd: self.as_raw_fd(), events: netc::POLLOUT, revents: 0 }; - pub fn write_vectored(&self, ioslice: &[IoSlice<'_>]) -> io::Result<usize> { - let mut size: usize = 0; - - for i in ioslice.iter() { - size += abi::tcpstream::write(*self.0.as_inner(), i).map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "Unable to write on socket") - })?; + if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 { + return Err(io::const_io_error!( + io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout", + )); } - Ok(size) - } - - #[inline] - pub fn is_write_vectored(&self) -> bool { - true - } - - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - let (ipaddr, port) = abi::tcpstream::peer_addr(*self.0.as_inner()) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed"))?; + let start = Instant::now(); - let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), - Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), - _ => { - return Err(io::const_io_error!(ErrorKind::Uncategorized, "peer_addr failed")); + loop { + let elapsed = start.elapsed(); + if elapsed >= timeout { + return Err(io::const_io_error!(io::ErrorKind::TimedOut, "connection timed out")); } - }; - - Ok(saddr) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } - - pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { - abi::tcpstream::shutdown(*self.0.as_inner(), how as i32) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to shutdown socket")) - } - - pub fn duplicate(&self) -> io::Result<TcpStream> { - Ok(self.clone()) - } - - pub fn set_linger(&self, _linger: Option<Duration>) -> io::Result<()> { - unsupported() - } - - pub fn linger(&self) -> io::Result<Option<Duration>> { - unsupported() - } - - pub fn set_nodelay(&self, mode: bool) -> io::Result<()> { - abi::tcpstream::set_nodelay(*self.0.as_inner(), mode) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "set_nodelay failed")) - } - - pub fn nodelay(&self) -> io::Result<bool> { - abi::tcpstream::nodelay(*self.0.as_inner()) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "nodelay failed")) - } - - pub fn set_ttl(&self, tll: u32) -> io::Result<()> { - abi::tcpstream::set_tll(*self.0.as_inner(), tll) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to set TTL")) - } - - pub fn ttl(&self) -> io::Result<u32> { - abi::tcpstream::get_tll(*self.0.as_inner()) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "unable to get TTL")) - } - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() - } - - pub fn set_nonblocking(&self, mode: bool) -> io::Result<()> { - abi::tcpstream::set_nonblocking(*self.0.as_inner(), mode).map_err(|_| { - io::const_io_error!(ErrorKind::Uncategorized, "unable to set blocking mode") - }) - } -} - -impl fmt::Debug for TcpStream { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) - } -} - -#[derive(Clone)] -pub struct TcpListener(SocketAddr); - -impl TcpListener { - pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> { - let addr = addr?; - - Ok(TcpListener(*addr)) - } - - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - Ok(self.0) - } - - pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { - let (handle, ipaddr, port) = abi::tcplistener::accept(self.0.port()) - .map_err(|_| io::const_io_error!(ErrorKind::Uncategorized, "accept failed"))?; - let saddr = match ipaddr { - Ipv4(ref addr) => SocketAddr::new(IpAddr::V4(Ipv4Addr::from(addr.0)), port), - Ipv6(ref addr) => SocketAddr::new(IpAddr::V6(Ipv6Addr::from(addr.0)), port), - _ => { - return Err(io::const_io_error!(ErrorKind::Uncategorized, "accept failed")); + let timeout = timeout - elapsed; + let mut timeout = timeout + .as_secs() + .saturating_mul(1_000) + .saturating_add(timeout.subsec_nanos() as u64 / 1_000_000); + if timeout == 0 { + timeout = 1; } - }; - - Ok((TcpStream(Arc::new(Socket(handle))), saddr)) - } - pub fn duplicate(&self) -> io::Result<TcpListener> { - Ok(self.clone()) - } - - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unsupported() - } - - pub fn ttl(&self) -> io::Result<u32> { - unsupported() - } - - pub fn set_only_v6(&self, _: bool) -> io::Result<()> { - unsupported() + let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; + + match unsafe { netc::poll(&mut pollfd, 1, timeout) } { + -1 => { + let err = io::Error::last_os_error(); + if err.kind() != io::ErrorKind::Interrupted { + return Err(err); + } + } + 0 => {} + _ => { + // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look + // for POLLHUP rather than read readiness + if pollfd.revents & netc::POLLHUP != 0 { + let e = self.take_error()?.unwrap_or_else(|| { + io::const_io_error!( + io::ErrorKind::Uncategorized, + "no error set after POLLHUP", + ) + }); + return Err(e); + } + + return Ok(()); + } + } + } } - pub fn only_v6(&self) -> io::Result<bool> { - unsupported() + pub fn accept( + &self, + storage: *mut netc::sockaddr, + len: *mut netc::socklen_t, + ) -> io::Result<Socket> { + let fd = cvt(unsafe { netc::accept(self.0.as_raw_fd(), storage, len) })?; + Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } - pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() + pub fn duplicate(&self) -> io::Result<Socket> { + let fd = cvt(unsafe { netc::dup(self.0.as_raw_fd()) })?; + Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unsupported() + fn recv_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<usize> { + let ret = + cvt(unsafe { netc::recv(self.0.as_raw_fd(), buf.as_mut_ptr(), buf.len(), flags) })?; + Ok(ret as usize) } -} -impl fmt::Debug for TcpListener { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) + pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> { + self.recv_with_flags(buf, 0) } -} - -pub struct UdpSocket(abi::Handle); -impl UdpSocket { - pub fn bind(_: io::Result<&SocketAddr>) -> io::Result<UdpSocket> { - unsupported() + pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { + self.recv_with_flags(buf, netc::MSG_PEEK) } - pub fn peer_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } + pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { + let mut size: isize = 0; - pub fn socket_addr(&self) -> io::Result<SocketAddr> { - unsupported() - } + for i in bufs.iter_mut() { + let ret: isize = + cvt(unsafe { netc::read(self.0.as_raw_fd(), i.as_mut_ptr(), i.len()) })?; - pub fn recv_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unsupported() - } + if ret != 0 { + size += ret; + } + } - pub fn peek_from(&self, _: &mut [u8]) -> io::Result<(usize, SocketAddr)> { - unsupported() + Ok(size.try_into().unwrap()) } - pub fn send_to(&self, _: &[u8], _: &SocketAddr) -> io::Result<usize> { - unsupported() + #[inline] + pub fn is_read_vectored(&self) -> bool { + true } - pub fn duplicate(&self) -> io::Result<UdpSocket> { - unsupported() - } + fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> { + let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; + let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t; - pub fn set_read_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() + let n = cvt(unsafe { + netc::recvfrom( + self.as_raw_fd(), + buf.as_mut_ptr(), + buf.len(), + flags, + &mut storage as *mut _ as *mut _, + &mut addrlen, + ) + })?; + Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?)) } - pub fn set_write_timeout(&self, _: Option<Duration>) -> io::Result<()> { - unsupported() + pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.recv_from_with_flags(buf, 0) } - pub fn read_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() + pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + self.recv_from_with_flags(buf, netc::MSG_PEEK) } - pub fn write_timeout(&self) -> io::Result<Option<Duration>> { - unsupported() + pub fn write(&self, buf: &[u8]) -> io::Result<usize> { + let sz = cvt(unsafe { netc::write(self.0.as_raw_fd(), buf.as_ptr(), buf.len()) })?; + Ok(sz.try_into().unwrap()) } - pub fn set_broadcast(&self, _: bool) -> io::Result<()> { - unsupported() - } + pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { + let mut size: isize = 0; - pub fn broadcast(&self) -> io::Result<bool> { - unsupported() - } + for i in bufs.iter() { + size += cvt(unsafe { netc::write(self.0.as_raw_fd(), i.as_ptr(), i.len()) })?; + } - pub fn set_multicast_loop_v4(&self, _: bool) -> io::Result<()> { - unsupported() + Ok(size.try_into().unwrap()) } - pub fn multicast_loop_v4(&self) -> io::Result<bool> { - unsupported() + pub fn is_write_vectored(&self) -> bool { + true } - pub fn set_multicast_ttl_v4(&self, _: u32) -> io::Result<()> { - unsupported() - } + pub fn set_timeout(&self, dur: Option<Duration>, kind: i32) -> io::Result<()> { + let timeout = match dur { + Some(dur) => { + if dur.as_secs() == 0 && dur.subsec_nanos() == 0 { + return Err(io::const_io_error!( + io::ErrorKind::InvalidInput, + "cannot set a 0 duration timeout", + )); + } + + let secs = if dur.as_secs() > netc::time_t::MAX as u64 { + netc::time_t::MAX + } else { + dur.as_secs() as netc::time_t + }; + let mut timeout = netc::timeval { + tv_sec: secs, + tv_usec: dur.subsec_micros() as netc::suseconds_t, + }; + if timeout.tv_sec == 0 && timeout.tv_usec == 0 { + timeout.tv_usec = 1; + } + timeout + } + None => netc::timeval { tv_sec: 0, tv_usec: 0 }, + }; - pub fn multicast_ttl_v4(&self) -> io::Result<u32> { - unsupported() + setsockopt(self, netc::SOL_SOCKET, kind, timeout) } - pub fn set_multicast_loop_v6(&self, _: bool) -> io::Result<()> { - unsupported() + pub fn timeout(&self, kind: i32) -> io::Result<Option<Duration>> { + let raw: netc::timeval = getsockopt(self, netc::SOL_SOCKET, kind)?; + if raw.tv_sec == 0 && raw.tv_usec == 0 { + Ok(None) + } else { + let sec = raw.tv_sec as u64; + let nsec = (raw.tv_usec as u32) * 1000; + Ok(Some(Duration::new(sec, nsec))) + } } - pub fn multicast_loop_v6(&self) -> io::Result<bool> { - unsupported() + pub fn shutdown(&self, how: Shutdown) -> io::Result<()> { + let how = match how { + Shutdown::Write => netc::SHUT_WR, + Shutdown::Read => netc::SHUT_RD, + Shutdown::Both => netc::SHUT_RDWR, + }; + cvt(unsafe { netc::shutdown_socket(self.as_raw_fd(), how) })?; + Ok(()) } - pub fn join_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unsupported() - } + pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> { + let linger = netc::linger { + l_onoff: linger.is_some() as i32, + l_linger: linger.unwrap_or_default().as_secs() as libc::c_int, + }; - pub fn join_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unsupported() + setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) } - pub fn leave_multicast_v4(&self, _: &Ipv4Addr, _: &Ipv4Addr) -> io::Result<()> { - unsupported() - } + pub fn linger(&self) -> io::Result<Option<Duration>> { + let val: netc::linger = getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)?; - pub fn leave_multicast_v6(&self, _: &Ipv6Addr, _: u32) -> io::Result<()> { - unsupported() + Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) } - pub fn set_ttl(&self, _: u32) -> io::Result<()> { - unsupported() + pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + let value: i32 = if nodelay { 1 } else { 0 }; + setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value) } - pub fn ttl(&self) -> io::Result<u32> { - unsupported() + pub fn nodelay(&self) -> io::Result<bool> { + let raw: i32 = getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)?; + Ok(raw != 0) + } + + pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + let mut nonblocking: i32 = if nonblocking { 1 } else { 0 }; + cvt(unsafe { + netc::ioctl( + self.as_raw_fd(), + netc::FIONBIO, + &mut nonblocking as *mut _ as *mut core::ffi::c_void, + ) + }) + .map(drop) } pub fn take_error(&self) -> io::Result<Option<io::Error>> { - unsupported() - } - - pub fn set_nonblocking(&self, _: bool) -> io::Result<()> { - unsupported() - } - - pub fn recv(&self, _: &mut [u8]) -> io::Result<usize> { - unsupported() - } - - pub fn peek(&self, _: &mut [u8]) -> io::Result<usize> { - unsupported() + unimplemented!() } - pub fn send(&self, _: &[u8]) -> io::Result<usize> { - unsupported() - } - - pub fn connect(&self, _: io::Result<&SocketAddr>) -> io::Result<()> { - unsupported() + // This is used by sys_common code to abstract over Windows and Unix. + pub fn as_raw(&self) -> RawFd { + self.0.as_raw_fd() } } -impl fmt::Debug for UdpSocket { - fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { - Ok(()) +impl AsInner<FileDesc> for Socket { + fn as_inner(&self) -> &FileDesc { + &self.0 } } -pub struct LookupHost(!); - -impl LookupHost { - pub fn port(&self) -> u16 { +impl IntoInner<FileDesc> for Socket { + fn into_inner(self) -> FileDesc { self.0 } } -impl Iterator for LookupHost { - type Item = SocketAddr; - fn next(&mut self) -> Option<SocketAddr> { - self.0 +impl FromInner<FileDesc> for Socket { + fn from_inner(file_desc: FileDesc) -> Self { + Self(file_desc) } } -impl TryFrom<&str> for LookupHost { - type Error = io::Error; - - fn try_from(_v: &str) -> io::Result<LookupHost> { - unsupported() +impl AsFd for Socket { + fn as_fd(&self) -> BorrowedFd<'_> { + self.0.as_fd() } } -impl<'a> TryFrom<(&'a str, u16)> for LookupHost { - type Error = io::Error; - - fn try_from(_v: (&'a str, u16)) -> io::Result<LookupHost> { - unsupported() +impl AsRawFd for Socket { + fn as_raw_fd(&self) -> RawFd { + self.0.as_raw_fd() } } - -#[allow(nonstandard_style)] -pub mod netc { - pub const AF_INET: u8 = 0; - pub const AF_INET6: u8 = 1; - pub type sa_family_t = u8; - - #[derive(Copy, Clone)] - pub struct in_addr { - pub s_addr: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in { - pub sin_family: sa_family_t, - pub sin_port: u16, - pub sin_addr: in_addr, - } - - #[derive(Copy, Clone)] - pub struct in6_addr { - pub s6_addr: [u8; 16], - } - - #[derive(Copy, Clone)] - pub struct sockaddr_in6 { - pub sin6_family: sa_family_t, - pub sin6_port: u16, - pub sin6_addr: in6_addr, - pub sin6_flowinfo: u32, - pub sin6_scope_id: u32, - } - - #[derive(Copy, Clone)] - pub struct sockaddr {} -} diff --git a/library/std/src/sys/hermit/os.rs b/library/std/src/sys/hermit/os.rs index 8f927df85be..e53dbae6119 100644 --- a/library/std/src/sys/hermit/os.rs +++ b/library/std/src/sys/hermit/os.rs @@ -4,7 +4,7 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::fmt; use crate::io; use crate::marker::PhantomData; -use crate::os::unix::ffi::OsStringExt; +use crate::os::hermit::ffi::OsStringExt; use crate::path::{self, PathBuf}; use crate::str; use crate::sync::Mutex; diff --git a/library/std/src/sys/hermit/time.rs b/library/std/src/sys/hermit/time.rs index c17e6c8af62..32ddc4346ee 100644 --- a/library/std/src/sys/hermit/time.rs +++ b/library/std/src/sys/hermit/time.rs @@ -1,6 +1,7 @@ #![allow(dead_code)] use crate::cmp::Ordering; +use crate::ops::{Add, AddAssign, Sub, SubAssign}; use crate::sys::hermit::abi; use crate::sys::hermit::abi::timespec; use crate::sys::hermit::abi::{CLOCK_MONOTONIC, CLOCK_REALTIME, NSEC_PER_SEC}; @@ -102,55 +103,122 @@ impl Hash for Timespec { } #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Instant { - t: Timespec, -} +pub struct Instant(Timespec); impl Instant { pub fn now() -> Instant { let mut time: Timespec = Timespec::zero(); let _ = unsafe { abi::clock_gettime(CLOCK_MONOTONIC, &mut time.t as *mut timespec) }; - Instant { t: time } + Instant(time) + } + + #[stable(feature = "time2", since = "1.8.0")] + pub fn elapsed(&self) -> Duration { + Instant::now() - *self + } + + pub fn duration_since(&self, earlier: Instant) -> Duration { + self.checked_duration_since(earlier).unwrap_or_default() + } + + pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> { + self.checked_sub_instant(&earlier) } pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> { - self.t.sub_timespec(&other.t).ok() + self.0.sub_timespec(&other.0).ok() } pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> { - Some(Instant { t: self.t.checked_add_duration(other)? }) + Some(Instant(self.0.checked_add_duration(other)?)) } pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> { - Some(Instant { t: self.t.checked_sub_duration(other)? }) + Some(Instant(self.0.checked_sub_duration(other)?)) + } + + pub fn checked_add(&self, duration: Duration) -> Option<Instant> { + self.0.checked_add_duration(&duration).map(Instant) + } + + pub fn checked_sub(&self, duration: Duration) -> Option<Instant> { + self.0.checked_sub_duration(&duration).map(Instant) } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -pub struct SystemTime { - t: Timespec, +impl Add<Duration> for Instant { + type Output = Instant; + + /// # Panics + /// + /// This function may panic if the resulting point in time cannot be represented by the + /// underlying data structure. See [`Instant::checked_add`] for a version without panic. + fn add(self, other: Duration) -> Instant { + self.checked_add(other).expect("overflow when adding duration to instant") + } } -pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; +impl AddAssign<Duration> for Instant { + fn add_assign(&mut self, other: Duration) { + *self = *self + other; + } +} + +impl Sub<Duration> for Instant { + type Output = Instant; + + fn sub(self, other: Duration) -> Instant { + self.checked_sub(other).expect("overflow when subtracting duration from instant") + } +} + +impl SubAssign<Duration> for Instant { + fn sub_assign(&mut self, other: Duration) { + *self = *self - other; + } +} + +impl Sub<Instant> for Instant { + type Output = Duration; + + /// Returns the amount of time elapsed from another instant to this one, + /// or zero duration if that instant is later than this one. + /// + /// # Panics + /// + /// Previous rust versions panicked when `other` was later than `self`. Currently this + /// method saturates. Future versions may reintroduce the panic in some circumstances. + /// See [Monotonicity]. + /// + /// [Monotonicity]: Instant#monotonicity + fn sub(self, other: Instant) -> Duration { + self.duration_since(other) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct SystemTime(Timespec); + +pub const UNIX_EPOCH: SystemTime = SystemTime(Timespec::zero()); impl SystemTime { pub fn now() -> SystemTime { let mut time: Timespec = Timespec::zero(); let _ = unsafe { abi::clock_gettime(CLOCK_REALTIME, &mut time.t as *mut timespec) }; - SystemTime { t: time } + SystemTime(time) } pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> { - self.t.sub_timespec(&other.t) + self.0.sub_timespec(&other.0) } pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime { t: self.t.checked_add_duration(other)? }) + Some(SystemTime(self.0.checked_add_duration(other)?)) } pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> { - Some(SystemTime { t: self.t.checked_sub_duration(other)? }) + Some(SystemTime(self.0.checked_sub_duration(other)?)) } } diff --git a/library/std/src/sys/unix/fd.rs b/library/std/src/sys/unix/fd.rs index ab57fba6c9f..66c33d58d6c 100644 --- a/library/std/src/sys/unix/fd.rs +++ b/library/std/src/sys/unix/fd.rs @@ -197,11 +197,6 @@ impl FileDesc { } } - #[cfg(target_os = "linux")] - pub fn get_cloexec(&self) -> io::Result<bool> { - unsafe { Ok((cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))? & libc::FD_CLOEXEC) != 0) } - } - #[cfg(not(any( target_env = "newlib", target_os = "solaris", diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs index 6741ae46d32..30356fa8519 100644 --- a/library/std/src/sys/windows/args.rs +++ b/library/std/src/sys/windows/args.rs @@ -270,7 +270,7 @@ pub(crate) fn make_bat_command_line( // It is necessary to surround the command in an extra pair of quotes, // hence the trailing quote here. It will be closed after all arguments // have been added. - let mut cmd: Vec<u16> = "cmd.exe /c \"".encode_utf16().collect(); + let mut cmd: Vec<u16> = "cmd.exe /d /c \"".encode_utf16().collect(); // Push the script name surrounded by its quote pair. cmd.push(b'"' as u16); @@ -290,6 +290,15 @@ pub(crate) fn make_bat_command_line( // reconstructed by the batch script by default. for arg in args { cmd.push(' ' as u16); + // Make sure to always quote special command prompt characters, including: + // * Characters `cmd /?` says require quotes. + // * `%` for environment variables, as in `%TMP%`. + // * `|<>` pipe/redirect characters. + const SPECIAL: &[u8] = b"\t &()[]{}^=;!'+,`~%|<>"; + let force_quotes = match arg { + Arg::Regular(arg) if !force_quotes => arg.bytes().iter().any(|c| SPECIAL.contains(c)), + _ => force_quotes, + }; append_arg(&mut cmd, arg, force_quotes)?; } diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index f58dcf1287b..1d0ab772739 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -539,14 +539,6 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER { pub PathBuffer: WCHAR, } -/// NB: Use carefully! In general using this as a reference is likely to get the -/// provenance wrong for the `PathBuffer` field! -#[repr(C)] -pub struct FILE_NAME_INFO { - pub FileNameLength: DWORD, - pub FileName: [WCHAR; 1], -} - #[repr(C)] pub struct MOUNT_POINT_REPARSE_BUFFER { pub SubstituteNameOffset: c_ushort, diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs index 2cc34c986b9..7fdd1f702e2 100644 --- a/library/std/src/sys/windows/io.rs +++ b/library/std/src/sys/windows/io.rs @@ -2,8 +2,7 @@ use crate::marker::PhantomData; use crate::mem::size_of; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle}; use crate::slice; -use crate::sys::{c, Align8}; -use core; +use crate::sys::c; use libc; #[derive(Copy, Clone)] @@ -125,22 +124,33 @@ unsafe fn msys_tty_on(handle: c::HANDLE) -> bool { return false; } - const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>(); - let mut name_info_bytes = Align8([0u8; SIZE]); + /// Mirrors [`FILE_NAME_INFO`], giving it a fixed length that we can stack + /// allocate + /// + /// [`FILE_NAME_INFO`]: https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_name_info + #[repr(C)] + #[allow(non_snake_case)] + struct FILE_NAME_INFO { + FileNameLength: u32, + FileName: [u16; c::MAX_PATH as usize], + } + let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] }; + // Safety: buffer length is fixed. let res = c::GetFileInformationByHandleEx( handle, c::FileNameInfo, - name_info_bytes.0.as_mut_ptr() as *mut libc::c_void, - SIZE as u32, + &mut name_info as *mut _ as *mut libc::c_void, + size_of::<FILE_NAME_INFO>() as u32, ); if res == 0 { return false; } - let name_info: &c::FILE_NAME_INFO = &*(name_info_bytes.0.as_ptr() as *const c::FILE_NAME_INFO); - let name_len = name_info.FileNameLength as usize / 2; - // Offset to get the `FileName` field. - let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>(); - let s = core::slice::from_raw_parts(name_ptr, name_len); + + // Use `get` because `FileNameLength` can be out of range. + let s = match name_info.FileName.get(..name_info.FileNameLength as usize / 2) { + None => return false, + Some(s) => s, + }; let name = String::from_utf16_lossy(s); // Get the file name only. let name = name.rsplit('\\').next().unwrap_or(&name); diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs index 6b24b0e9aa8..e9c727cbbd1 100644 --- a/library/std/src/sys_common/mod.rs +++ b/library/std/src/sys_common/mod.rs @@ -44,7 +44,6 @@ cfg_if::cfg_if! { cfg_if::cfg_if! { if #[cfg(any(target_os = "l4re", - target_os = "hermit", feature = "restricted-std", all(target_family = "wasm", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx")))] { diff --git a/library/std/src/sys_common/thread_parking/id.rs b/library/std/src/sys_common/thread_parking/id.rs index e98169597c3..575988ec760 100644 --- a/library/std/src/sys_common/thread_parking/id.rs +++ b/library/std/src/sys_common/thread_parking/id.rs @@ -60,7 +60,7 @@ impl Parker { if state == PARKED { // Loop to guard against spurious wakeups. while state == PARKED { - park(self.state.as_mut_ptr().addr()); + park(self.state.as_ptr().addr()); state = self.state.load(Acquire); } @@ -76,7 +76,7 @@ impl Parker { let state = self.state.fetch_sub(1, Acquire).wrapping_sub(1); if state == PARKED { - park_timeout(dur, self.state.as_mut_ptr().addr()); + park_timeout(dur, self.state.as_ptr().addr()); // Swap to ensure that we observe all state changes with acquire // ordering, even if the state has been changed after the timeout // occured. @@ -99,7 +99,7 @@ impl Parker { // and terminated before this call is made. This call then returns an // error or wakes up an unrelated thread. The platform API and // environment does allow this, however. - unpark(tid, self.state.as_mut_ptr().addr()); + unpark(tid, self.state.as_ptr().addr()); } } } diff --git a/library/std/src/time.rs b/library/std/src/time.rs index acf9c29083f..5c2e9da70fb 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -352,7 +352,7 @@ impl Instant { self.checked_duration_since(earlier).unwrap_or_default() } - /// Returns the amount of time elapsed since this instant was created. + /// Returns the amount of time elapsed since this instant. /// /// # Panics /// @@ -525,8 +525,8 @@ impl SystemTime { self.0.sub_time(&earlier.0).map_err(SystemTimeError) } - /// Returns the difference between the clock time when this - /// system time was created, and the current clock time. + /// Returns the difference from this system time to the + /// current clock time. /// /// This function may fail as the underlying system clock is susceptible to /// drift and updates (e.g., the system clock could go backwards), so this diff --git a/library/std/tests/common/mod.rs b/library/std/tests/common/mod.rs new file mode 100644 index 00000000000..fce220223a0 --- /dev/null +++ b/library/std/tests/common/mod.rs @@ -0,0 +1,58 @@ +#![allow(unused)] + +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; +use std::thread; +use rand::RngCore; + +/// Copied from `std::test_helpers::test_rng`, since these tests rely on the +/// seed not being the same for every RNG invocation too. +#[track_caller] +pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use core::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); + core::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) +} + +// Copied from std::sys_common::io +pub struct TempDir(PathBuf); + +impl TempDir { + pub fn join(&self, path: &str) -> PathBuf { + let TempDir(ref p) = *self; + p.join(path) + } + + pub fn path(&self) -> &Path { + let TempDir(ref p) = *self; + p + } +} + +impl Drop for TempDir { + fn drop(&mut self) { + // Gee, seeing how we're testing the fs module I sure hope that we + // at least implement this correctly! + let TempDir(ref p) = *self; + let result = fs::remove_dir_all(p); + // Avoid panicking while panicking as this causes the process to + // immediately abort, without displaying test results. + if !thread::panicking() { + result.unwrap(); + } + } +} + +#[track_caller] // for `test_rng` +pub fn tmpdir() -> TempDir { + let p = env::temp_dir(); + let mut r = test_rng(); + let ret = p.join(&format!("rust-{}", r.next_u32())); + fs::create_dir(&ret).unwrap(); + TempDir(ret) +} diff --git a/library/std/tests/create_dir_all_bare.rs b/library/std/tests/create_dir_all_bare.rs new file mode 100644 index 00000000000..fe789323f97 --- /dev/null +++ b/library/std/tests/create_dir_all_bare.rs @@ -0,0 +1,39 @@ +#![cfg(all(test, not(any(target_os = "emscripten", target_env = "sgx"))))] + +//! Note that this test changes the current directory so +//! should not be in the same process as other tests. +use std::env; +use std::fs; +use std::path::{Path, PathBuf}; + +mod common; + +// On some platforms, setting the current directory will prevent deleting it. +// So this helper ensures the current directory is reset. +struct CurrentDir(PathBuf); +impl CurrentDir { + fn new() -> Self { + Self(env::current_dir().unwrap()) + } + fn set(&self, path: &Path) { + env::set_current_dir(path).unwrap(); + } + fn with(path: &Path, f: impl FnOnce()) { + let current_dir = Self::new(); + current_dir.set(path); + f(); + } +} +impl Drop for CurrentDir { + fn drop(&mut self) { + env::set_current_dir(&self.0).unwrap(); + } +} + +#[test] +fn create_dir_all_bare() { + let tmpdir = common::tmpdir(); + CurrentDir::with(tmpdir.path(), || { + fs::create_dir_all("create-dir-all-bare").unwrap(); + }); +} diff --git a/library/std/tests/env.rs b/library/std/tests/env.rs index aae2c49d898..96b4f372b8b 100644 --- a/library/std/tests/env.rs +++ b/library/std/tests/env.rs @@ -3,18 +3,8 @@ use std::ffi::{OsStr, OsString}; use rand::distributions::{Alphanumeric, DistString}; -/// Copied from `std::test_helpers::test_rng`, since these tests rely on the -/// seed not being the same for every RNG invocation too. -#[track_caller] -pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use core::hash::{BuildHasher, Hash, Hasher}; - let mut hasher = std::collections::hash_map::RandomState::new().build_hasher(); - core::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<Vec<u8>>(); - let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); - rand::SeedableRng::from_seed(seed) -} +mod common; +use common::test_rng; #[track_caller] fn make_rand_name() -> OsString { diff --git a/library/test/Cargo.toml b/library/test/Cargo.toml index 61b6f33bce0..18cb023d274 100644 --- a/library/test/Cargo.toml +++ b/library/test/Cargo.toml @@ -7,11 +7,9 @@ edition = "2021" crate-type = ["dylib", "rlib"] [dependencies] -cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } std = { path = "../std" } core = { path = "../core" } -libc = { version = "0.2", default-features = false } panic_unwind = { path = "../panic_unwind" } panic_abort = { path = "../panic_abort" } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 952c70cec1c..b33fc02f49c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -792,7 +792,7 @@ impl<'a> Builder<'a> { run::CollectLicenseMetadata, run::GenerateCopyright, ), - Kind::Setup => describe!(setup::Profile), + Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode), Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), // special-cased in Build::build() Kind::Format => vec![], @@ -1915,6 +1915,13 @@ impl<'a> Builder<'a> { } } + if matches!(mode, Mode::Std) { + if let Some(mir_opt_level) = self.config.rust_validate_mir_opts { + rustflags.arg("-Zvalidate-mir"); + rustflags.arg(&format!("-Zmir-opt-level={}", mir_opt_level)); + } + } + Cargo { command: cargo, rustflags, rustdocflags, allow_features } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index f0fcdf0d5a0..348d22a9ce6 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -459,72 +459,6 @@ impl Step for StdLink { let libdir = builder.sysroot_libdir(target_compiler, target); let hostdir = builder.sysroot_libdir(target_compiler, compiler.host); add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); - - if compiler.stage == 0 { - // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0` - // work for stage0-sysroot - let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot"); - - let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib"); - let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap()); - let host_codegen_backends = - host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends"); - let sysroot_bin_dir = sysroot.join("bin"); - let sysroot_lib_dir = sysroot.join("lib"); - let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler); - - // Create the `bin` directory in stage0-sysroot - t!(fs::create_dir_all(&sysroot_bin_dir)); - - // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin` - if let Ok(files) = fs::read_dir(&host_bin_dir) { - for file in files { - let file = t!(file); - if file.file_name() == "rustfmt" { - // This is when `rustc` and `cargo` are set in `config.toml` - if !file.path().starts_with(&builder.out) { - builder.copy( - &file.path().into_boxed_path(), - &sysroot_bin_dir.join(file.file_name()), - ); - } else { - builder.copy( - &builder - .out - .join(&compiler.host.triple) - .join("rustfmt/bin/rustfmt"), - &sysroot_bin_dir.join(file.file_name()), - ); - } - } else { - builder.copy( - &file.path().into_boxed_path(), - &sysroot_bin_dir.join(file.file_name()), - ); - } - } - } - - // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib` - if let Ok(files) = fs::read_dir(&host_lib_dir) { - for file in files { - let file = t!(file); - let path = file.path(); - if path.is_file() - && is_dylib(&file.file_name().into_string().unwrap()) - && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path()) - { - builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap())); - } - } - } - - t!(fs::create_dir_all(&sysroot_codegen_backends)); - // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists. - if host_codegen_backends.exists() { - builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends); - } - } } } diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 56f96734bbb..4a563bc396d 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -173,6 +173,7 @@ pub struct Config { pub rust_profile_use: Option<String>, pub rust_profile_generate: Option<String>, pub rust_lto: RustcLto, + pub rust_validate_mir_opts: Option<u32>, pub llvm_profile_use: Option<String>, pub llvm_profile_generate: bool, pub llvm_libunwind_default: Option<LlvmLibunwind>, @@ -770,6 +771,7 @@ define_config! { // ignored; this is set from an env var set by bootstrap.py download_rustc: Option<StringOrBool> = "download-rustc", lto: Option<String> = "lto", + validate_mir_opts: Option<u32> = "validate-mir-opts", } } @@ -1149,6 +1151,7 @@ impl Config { .as_deref() .map(|value| RustcLto::from_str(value).unwrap()) .unwrap_or_default(); + config.rust_validate_mir_opts = rust.validate_mir_opts; } else { config.rust_profile_use = flags.rust_profile_use; config.rust_profile_generate = flags.rust_profile_generate; diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d6592d2d771..d1e2149d3f9 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -2,7 +2,7 @@ use std::{ env, ffi::{OsStr, OsString}, fs::{self, File}, - io::{self, BufRead, BufReader, ErrorKind}, + io::{BufRead, BufReader, ErrorKind}, path::{Path, PathBuf}, process::{Command, Stdio}, }; @@ -26,14 +26,6 @@ impl Config { self.verbose > 0 } - pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> { - #[cfg(unix)] - use std::os::unix::fs::symlink as symlink_file; - #[cfg(windows)] - use std::os::windows::fs::symlink_file; - if !self.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } - } - pub(crate) fn create(&self, path: &Path, s: &str) { if self.dry_run() { return; @@ -338,15 +330,6 @@ impl Config { let bin_root = self.out.join(host.triple).join("rustfmt"); let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host)); let rustfmt_stamp = bin_root.join(".rustfmt-stamp"); - - #[cfg(not(windows))] - { - let legacy_rustfmt = self.initial_rustc.with_file_name(exe("rustfmt", host)); - if !legacy_rustfmt.exists() { - t!(self.symlink_file(&rustfmt_path, &legacy_rustfmt)); - } - } - if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) { return Some(rustfmt_path); } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index f07e710a9e6..9d1504c34e8 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -554,7 +554,8 @@ Arguments: Kind::Setup => { subcommand_help.push_str(&format!( "\n -x.py setup creates a `config.toml` which changes the defaults for x.py itself. +x.py setup creates a `config.toml` which changes the defaults for x.py itself, +as well as setting up a git pre-push hook, VS code config and toolchain link. Arguments: This subcommand accepts a 'profile' to use for builds. For example: @@ -564,7 +565,13 @@ Arguments: The profile is optional and you will be prompted interactively if it is not given. The following profiles are available: -{}", +{} + + To only set up the git hook, VS code or toolchain link, you may use + ./x.py setup hook + ./x.py setup vscode + ./x.py setup link +", Profile::all_for_help(" ").trim_end() )); } @@ -638,7 +645,7 @@ Arguments: } Kind::Setup => { let profile = if paths.len() > 1 { - eprintln!("\nerror: At most one profile can be passed to setup\n"); + eprintln!("\nerror: At most one option can be passed to setup\n"); usage(1, &opts, verbose, &subcommand_help) } else if let Some(path) = paths.pop() { let profile_string = t!(path.into_os_string().into_string().map_err( diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 615794958d0..ae72a42973c 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -218,7 +218,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { WalkBuilder::new(first) } } else { - WalkBuilder::new(first) + WalkBuilder::new(src.join(first)) }; for path in &paths[1..] { @@ -229,7 +229,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { walker.add(path); } } else { - walker.add(path); + walker.add(src.join(path)); } } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f753720b353..f4abdf1cc57 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -20,6 +20,7 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; use std::fs::{self, File}; +use std::io; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; @@ -1406,7 +1407,7 @@ impl Build { src = t!(fs::canonicalize(src)); } else { let link = t!(fs::read_link(src)); - t!(self.config.symlink_file(link, dst)); + t!(self.symlink_file(link, dst)); return; } } @@ -1524,6 +1525,14 @@ impl Build { iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter() } + fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> { + #[cfg(unix)] + use std::os::unix::fs::symlink as symlink_file; + #[cfg(windows)] + use std::os::windows::fs::symlink_file; + if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) } + } + /// Returns if config.ninja is enabled, and checks for ninja existence, /// exiting with a nicer error message if not. fn ninja(&self) -> bool { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d6e63fb937e..21157b02a78 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -516,7 +516,7 @@ impl Step for Llvm { let lib_llvm = out_dir.join("build").join("lib").join(lib_name); if !lib_llvm.exists() { - t!(builder.build.config.symlink_file("libLLVM.dylib", &lib_llvm)); + t!(builder.symlink_file("libLLVM.dylib", &lib_llvm)); } } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index a027139df23..4480bce99d7 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -21,6 +21,7 @@ pub enum Profile { Library, Tools, User, + None, } /// A list of historical hashes of `src/etc/vscode_settings.json`. @@ -41,7 +42,7 @@ impl Profile { pub fn all() -> impl Iterator<Item = Self> { use Profile::*; // N.B. these are ordered by how they are displayed, not alphabetically - [Library, Compiler, Codegen, Tools, User].iter().copied() + [Library, Compiler, Codegen, Tools, User, None].iter().copied() } pub fn purpose(&self) -> String { @@ -52,6 +53,7 @@ impl Profile { Codegen => "Contribute to the compiler, and also modify LLVM or codegen", Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)", User => "Install Rust from source", + None => "Do not modify `config.toml`" } .to_string() } @@ -71,6 +73,7 @@ impl Profile { Profile::Library => "library", Profile::Tools => "tools", Profile::User => "user", + Profile::None => "none", } } } @@ -87,6 +90,7 @@ impl FromStr for Profile { "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => { Ok(Profile::Tools) } + "none" => Ok(Profile::None), _ => Err(format!("unknown profile: '{}'", s)), } } @@ -144,17 +148,8 @@ impl Step for Profile { } pub fn setup(config: &Config, profile: Profile) { - let stage_path = - ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); - - if !rustup_installed() && profile != Profile::User { - eprintln!("`rustup` is not installed; cannot link `stage1` toolchain"); - } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() { - attempt_toolchain_link(&stage_path[..]); - } - - let suggestions = match profile { - Profile::Codegen | Profile::Compiler => &["check", "build", "test"][..], + let suggestions: &[&str] = match profile { + Profile::Codegen | Profile::Compiler | Profile::None => &["check", "build", "test"], Profile::Tools => &[ "check", "build", @@ -167,11 +162,6 @@ pub fn setup(config: &Config, profile: Profile) { Profile::User => &["dist", "build"], }; - if !config.dry_run() { - t!(install_git_hook_maybe(&config)); - t!(create_vscode_settings_maybe(&config)); - } - println!(); println!("To get started, try one of the following commands:"); @@ -190,6 +180,9 @@ pub fn setup(config: &Config, profile: Profile) { } fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { + if profile == Profile::None { + return; + } if path.exists() { eprintln!(); eprintln!( @@ -217,6 +210,41 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { println!("`x.py` will now use the configuration at {}", include_path.display()); } +/// Creates a toolchain link for stage1 using `rustup` +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Link; +impl Step for Link { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("link") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "link" { + run.builder.ensure(Link); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + let stage_path = + ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); + + if !rustup_installed() { + eprintln!("`rustup` is not installed; cannot link `stage1` toolchain"); + } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() { + attempt_toolchain_link(&stage_path[..]); + } + } +} + fn rustup_installed() -> bool { Command::new("rustup") .arg("--version") @@ -394,6 +422,35 @@ fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> { } } +/// Installs `src/etc/pre-push.sh` as a Git hook +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Hook; + +impl Step for Hook { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("hook") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "hook" { + run.builder.ensure(Hook); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + t!(install_git_hook_maybe(&config)); + } +} + // install a git hook to automatically run tidy, if they want fn install_git_hook_maybe(config: &Config) -> io::Result<()> { let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| { @@ -432,6 +489,35 @@ undesirable, simply delete the `pre-push` file from .git/hooks." Ok(()) } +/// Sets up or displays `src/etc/vscode_settings.json` +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] +pub struct Vscode; + +impl Step for Vscode { + type Output = (); + const DEFAULT: bool = true; + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("vscode") + } + fn make_run(run: RunConfig<'_>) { + if run.builder.config.dry_run() { + return; + } + if let [cmd] = &run.paths[..] { + if cmd.assert_single_path().path.as_path().as_os_str() == "vscode" { + run.builder.ensure(Vscode); + } + } + } + fn run(self, builder: &Builder<'_>) -> Self::Output { + let config = &builder.config; + if config.dry_run() { + return; + } + t!(create_vscode_settings_maybe(&config)); + } +} + /// Create a `.vscode/settings.json` file for rustc development, or just print it fn create_vscode_settings_maybe(config: &Config) -> io::Result<()> { let (current_hash, historical_hashes) = SETTINGS_HASHES.split_last().unwrap(); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d30532ef3c6..3c9a154da9a 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -595,7 +595,7 @@ impl Step for Rustdoc { features.push("jemalloc".to_string()); } - let cargo = prepare_tool_cargo( + let mut cargo = prepare_tool_cargo( builder, build_compiler, Mode::ToolRustc, @@ -606,6 +606,10 @@ impl Step for Rustdoc { features.as_slice(), ); + if builder.config.rustc_parallel { + cargo.rustflag("--cfg=parallel_compiler"); + } + let msg = tooling_output( Mode::ToolRustc, "rustdoc", diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index 4cc5d9f8a0d..98bd90210d6 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -23,6 +23,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ RUN curl -sL https://nodejs.org/dist/v16.9.0/node-v16.9.0-linux-x64.tar.xz | tar -xJ ENV PATH="/node-v16.9.0-linux-x64/bin:${PATH}" +ENV RUST_CONFIGURE_ARGS="--set rust.validate-mir-opts=3" + # Install es-check # Pin its version to prevent unrelated CI failures due to future es-check versions. RUN npm install es-check@6.1.1 eslint@8.6.0 -g @@ -38,7 +40,7 @@ COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/ ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ - python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu --all-targets && \ + python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \ python3 ../x.py build --stage 0 src/tools/build-manifest && \ python3 ../x.py test --stage 0 src/tools/compiletest && \ python3 ../x.py test --stage 0 core alloc std test proc_macro && \ diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 94ec2401292..9c550b2d728 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.14.3 \ No newline at end of file +0.14.4 \ No newline at end of file diff --git a/src/ci/docker/scripts/fuchsia-test-runner.py b/src/ci/docker/scripts/fuchsia-test-runner.py index a6d84a3c18a..c3d532c4b27 100755 --- a/src/ci/docker/scripts/fuchsia-test-runner.py +++ b/src/ci/docker/scripts/fuchsia-test-runner.py @@ -507,9 +507,8 @@ class TestEnvironment: bin/{exe_name}={bin_path} lib/{libstd_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libstd_name} lib/{libtest_name}={rust_dir}/lib/rustlib/{rustlib_dir}/lib/{libtest_name} - lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/lib/libc.so - lib/libzircon.so={sdk_dir}/arch/{target_arch}/sysroot/lib/libzircon.so - lib/libfdio.so={sdk_dir}/arch/{target_arch}/lib/libfdio.so + lib/ld.so.1={sdk_dir}/arch/{target_arch}/sysroot/dist/lib/ld.so.1 + lib/libfdio.so={sdk_dir}/arch/{target_arch}/dist/libfdio.so """ TEST_ENV_VARS: ClassVar[List[str]] = [ @@ -844,23 +843,34 @@ class TestEnvironment: "--", "--build-id-dir", os.path.join(self.sdk_dir, ".build-id"), - "--build-id-dir", - os.path.join(self.libs_dir(), ".build-id"), ] - # Add rust source if it's available - if args.rust_src is not None: + libs_build_id_path = os.path.join(self.libs_dir(), ".build-id") + if os.path.exists(libs_build_id_path): + # Add .build-id symbols if installed libs have been stripped into a + # .build-id directory command += [ - "--build-dir", - args.rust_src, + "--build-id-dir", + libs_build_id_path, + ] + else: + # If no .build-id directory is detected, then assume that the shared + # libs contain their debug symbols + command += [ + f"--symbol-path={self.rust_dir}/lib/rustlib/{self.target}/lib", ] + # Add rust source if it's available + rust_src_map = None + if args.rust_src is not None: + # This matches the remapped prefix used by compiletest. There's no + # clear way that we can determine this, so it's hard coded. + rust_src_map = f"/rustc/FAKE_PREFIX={args.rust_src}" + # Add fuchsia source if it's available + fuchsia_src_map = None if args.fuchsia_src is not None: - command += [ - "--build-dir", - os.path.join(args.fuchsia_src, "out", "default"), - ] + fuchsia_src_map = f"./../..={args.fuchsia_src}" # Load debug symbols for the test binary and automatically attach if args.test is not None: @@ -883,7 +893,28 @@ class TestEnvironment: test_name, ) + # The fake-test-src-base directory maps to the suite directory + # e.g. tests/ui/foo.rs has a path of rust/fake-test-src-base/foo.rs + fake_test_src_base = os.path.join( + args.rust_src, + "fake-test-src-base", + ) + real_test_src_base = os.path.join( + args.rust_src, + "tests", + args.test.split(os.path.sep)[0], + ) + test_src_map = f"{fake_test_src_base}={real_test_src_base}" + with open(self.zxdb_script_path(), mode="w", encoding="utf-8") as f: + print(f"set source-map += {test_src_map}", file=f) + + if rust_src_map is not None: + print(f"set source-map += {rust_src_map}", file=f) + + if fuchsia_src_map is not None: + print(f"set source-map += {fuchsia_src_map}", file=f) + print(f"attach {test_name[:31]}", file=f) command += [ @@ -900,6 +931,20 @@ class TestEnvironment: # Connect to the running emulator with zxdb subprocess.run(command, env=self.ffx_cmd_env(), check=False) + def syslog(self, args): + subprocess.run( + [ + self.tool_path("ffx"), + "--config", + self.ffx_user_config_path(), + "log", + "--since", + "now", + ], + env=self.ffx_cmd_env(), + check=False, + ) + def start(args): test_env = TestEnvironment.from_args(args) @@ -933,6 +978,12 @@ def debug(args): return 0 +def syslog(args): + test_env = TestEnvironment.read_from_file() + test_env.syslog(args) + return 0 + + def main(): parser = argparse.ArgumentParser() @@ -1028,6 +1079,11 @@ def main(): ) debug_parser.set_defaults(func=debug) + syslog_parser = subparsers.add_parser( + "syslog", help="prints the device syslog" + ) + syslog_parser.set_defaults(func=syslog) + args = parser.parse_args() return args.func(args) diff --git a/src/doc/index.md b/src/doc/index.md index bf08960f338..7c97c16c20b 100644 --- a/src/doc/index.md +++ b/src/doc/index.md @@ -4,6 +4,20 @@ nav { display: none; } +body { + font-family: serif; +} +h1, h2, h3, h4, h5, h6 { + font-family: sans-serif; +} +h3 { + font-size: 1.35rem; +} +h4 { + font-size: 1.1rem; +} + +/* Formatting for docs search bar */ #search-input { width: calc(100% - 58px); } @@ -21,53 +35,74 @@ nav { #search-but:hover, #search-input:focus { border-color: #55a9ff; } -h2 { - font-size: 18px; + +/* Formatting for external link icon */ +svg.external-link { + display: inline-block; + position: relative; + vertical-align: super; + width: 0.7rem; + height: 0.7rem; + padding-left: 2px; + top: 3px; } </style> -Welcome to an overview of the documentation provided by the [Rust project]. -All of these projects are managed by the Docs Team; there are other -unofficial documentation resources as well! +Welcome to an overview of the documentation provided by the [Rust +project]. This page contains links to various helpful references, +most of which are available offline (if opened with `rustup doc`). Many of these +resources take the form of "books"; we collectively call these "The Rust +Bookshelf." Some are large, some are small. -Many of these resources take the form of "books"; we collectively call these -"The Rust Bookshelf." Some are large, some are small. +All of these books are managed by the Rust Organization, but other unofficial +documentation resources are included here as well! -# Learn Rust +If you're just looking for the standard library reference, here it is: +[Rust API documentation](std/index.html) -If you'd like to learn Rust, this is the spot for you! All of these resources + +## Learning Rust + +If you'd like to learn Rust, this is the section for you! All of these resources assume that you have programmed before, but not in any specific language: -## The Rust Programming Language +### The Rust Programming Language -Affectionately nicknamed "the book," [The Rust Programming -Language](book/index.html) will give you an overview of the language from -first principles. You'll build a few projects along the way, and by the end, -you'll have a solid grasp of the language. +Affectionately nicknamed "the book," [The Rust Programming Language](book/index.html) +will give you an overview of the language from first principles. You'll build a +few projects along the way, and by the end, you'll have a solid grasp of how to +use the language. -## Rust By Example +### Rust By Example If reading multiple hundreds of pages about a language isn't your style, then -[Rust By Example](rust-by-example/index.html) has you covered. While the book talks about code with -a lot of words, RBE shows off a bunch of code, and keeps the talking to a -minimum. It also includes exercises! +[Rust By Example](rust-by-example/index.html) has you covered. RBE shows off a +bunch of code without using a lot of words. It also includes exercises! + +### Rustlings + +[Rustlings](https://github.com/rust-lang/rustlings) guides you +through downloading and setting up the Rust toolchain, then provides an +interactive tool that teaches you how to solve coding challenges in Rust. + +### Rust Playground -## Rustlings +The [Rust Playground](https://play.rust-lang.org) is a great place +to try out and share small bits of code, or experiment with some of the most +popular crates. -[Rustlings](https://github.com/rust-lang/rustlings) guides you through downloading and setting up the Rust toolchain, -and teaches you the basics of reading and writing Rust syntax. It's an -alternative to Rust by Example that works with your own environment. -# Use Rust +## Using Rust -Once you've gotten familiar with the language, these resources can help you -when you're actually using it day-to-day. +Once you've gotten familiar with the language, these resources can help you put +it to work. -## The Standard Library +### The Standard Library -Rust's standard library has [extensive API documentation](std/index.html), -with explanations of how to use various things, as well as example code for -accomplishing various tasks. +Rust's standard library has [extensive API documentation](std/index.html), with +explanations of how to use various things, as well as example code for +accomplishing various tasks. Code examples have a "Run" button on hover that +opens the sample in the playground. <div> <form action="std/index.html" method="get"> @@ -77,76 +112,143 @@ accomplishing various tasks. </form> </div> -## The Edition Guide +### Your Personal Documentation -[The Edition Guide](edition-guide/index.html) describes the Rust editions. +Whenever you are working in a crate, `cargo doc --open` will generate +documentation for your project _and_ all its dependencies in their correct +version, and open it in your browser. Add the flag `--document-private-items` to +also show items not marked `pub`. -## The Rustc Book +### The Edition Guide -[The Rustc Book](rustc/index.html) describes the Rust compiler, `rustc`. +[The Edition Guide](edition-guide/index.html) describes the Rust editions and +their differences. -## The Cargo Book +### The `rustc` Book -[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and dependency manager. +[The `rustc` Book](rustc/index.html) describes the Rust compiler, `rustc`. -## The Rustdoc Book +### The Cargo Book + +[The Cargo Book](cargo/index.html) is a guide to Cargo, Rust's build tool and +dependency manager. + +### The Rustdoc Book [The Rustdoc Book](rustdoc/index.html) describes our documentation tool, `rustdoc`. -## The Clippy Book +### The Clippy Book [The Clippy Book](clippy/index.html) describes our static analyzer, Clippy. -## Extended Error Listing +### Extended Error Listing Many of Rust's errors come with error codes, and you can request extended -diagnostics from the compiler on those errors. You can also [read them -here](error_codes/index.html), if you prefer to read them that way. +diagnostics from the compiler on those errors (with `rustc --explain`). You can +also read them here if you prefer: [rustc error codes](error_codes/index.html) + -# Master Rust +## Mastering Rust Once you're quite familiar with the language, you may find these advanced resources useful. -## The Reference +### The Reference -[The Reference](reference/index.html) is not a formal spec, but is more detailed and -comprehensive than the book. +[The Reference](reference/index.html) is not a formal spec, but is more detailed +and comprehensive than the book. -## The Style Guide +### The Style Guide -[The Rust Style Guide](style-guide/index.html) describes the standard formatting of Rust -code. Most developers use rustfmt to format their code, and rustfmt's default -formatting matches this style guide. +[The Rust Style Guide](style-guide/index.html) describes the standard formatting +of Rust code. Most developers use `cargo fmt` to invoke `rustfmt` and format the +code automatically (the result matches this style guide). -## The Rustonomicon +### The Rustonomicon -[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of unsafe -Rust. It's also sometimes called "the 'nomicon." +[The Rustonomicon](nomicon/index.html) is your guidebook to the dark arts of +unsafe Rust. It's also sometimes called "the 'nomicon." -## The Unstable Book +### The Unstable Book -[The Unstable Book](unstable-book/index.html) has documentation for unstable features. +[The Unstable Book](unstable-book/index.html) has documentation for unstable +features. -## The `rustc` Contribution Guide +### The `rustc` Contribution Guide -[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) documents how -the compiler works and how to contribute to it. This is useful if you want to build -or modify the Rust compiler from source (e.g. to target something non-standard). +[The `rustc` Guide](https://rustc-dev-guide.rust-lang.org/) +documents how the compiler works and how to contribute to it. This is useful if +you want to build or modify the Rust compiler from source (e.g. to target +something non-standard). -# Specialize Rust -When using Rust in specific domain areas, consider using the following resources tailored to each domain. +## Specialized Rust -## Embedded Systems +When using Rust in specific domains, consider using the following resources +tailored to each area. -When developing for Bare Metal or Embedded Linux systems, you may find these resources maintained by the [Embedded Working Group] useful. +### Embedded Systems + +When developing for Bare Metal or Embedded Linux systems, you may find these +resources maintained by the [Embedded Working Group] useful. [Embedded Working Group]: https://github.com/rust-embedded -### The Embedded Rust Book +#### The Embedded Rust Book -[The Embedded Rust Book] is targeted at developers familiar with embedded development and familiar with Rust, but have not used Rust for embedded development. +[The Embedded Rust Book] is targeted at developers familiar with embedded +development and familiar with Rust, but have not used Rust for embedded +development. [The Embedded Rust Book]: embedded-book/index.html [Rust project]: https://www.rust-lang.org + +<script> +// check if a given link is external +function isExternalLink(url) { + const tmp = document.createElement('a'); + tmp.href = url; + return tmp.host !== window.location.host; +} + +// Add the `external` class to all <a> tags with external links and append the external link SVG +function updateExternalAnchors() { + /* + External link SVG from Font-Awesome + CC BY-SA 3.0 https://creativecommons.org/licenses/by-sa/3.0 + via Wikimedia Commons + */ + const svgText = `<svg + class='external-link' + xmlns='http://www.w3.org/2000/svg' + viewBox='0 -256 1850 1850' + width='100%' + height='100%'> + <g transform='matrix(1,0,0,-1,30,1427)'> + <path d='M 1408,608 V 288 Q 1408,169 1323.5,84.5 1239,0 1120, + 0 H 288 Q 169,0 84.5,84.5 0,169 0,288 v 832 Q 0,1239 84.5,1323.5 169, + 1408 288,1408 h 704 q 14,0 23,-9 9,-9 9,-23 v -64 q 0,-14 -9,-23 -9, + -9 -23,-9 H 288 q -66,0 -113,-47 -47,-47 -47,-113 V 288 q 0,-66 47, + -113 47,-47 113,-47 h 832 q 66,0 113,47 47,47 47,113 v 320 q 0,14 9, + 23 9,9 23,9 h 64 q 14,0 23,-9 9,-9 9,-23 z m 384,864 V 960 q 0, + -26 -19,-45 -19,-19 -45,-19 -26,0 -45,19 L 1507,1091 855,439 q -10, + -10 -23,-10 -13,0 -23,10 L 695,553 q -10,10 -10,23 0,13 10,23 l 652, + 652 -176,176 q -19,19 -19,45 0,26 19,45 19,19 45,19 h 512 q 26,0 45, + -19 19,-19 19,-45 z' style='fill:currentColor' /> + </g> + </svg>`; + let allAnchors = document.getElementsByTagName("a"); + + for (var i = 0; i < allAnchors.length; ++i) { + let anchor = allAnchors[i]; + if (isExternalLink(anchor.href)) { + anchor.classList.add("external"); + anchor.innerHTML += svgText; + } + } +} + +// on page load, update external anchors +document.addEventListener("DOMContentLoaded", updateExternalAnchors); + +</script> diff --git a/src/doc/rustc/src/platform-support/fuchsia.md b/src/doc/rustc/src/platform-support/fuchsia.md index 0f165b268ba..63dde2aaedd 100644 --- a/src/doc/rustc/src/platform-support/fuchsia.md +++ b/src/doc/rustc/src/platform-support/fuchsia.md @@ -687,7 +687,9 @@ Rust compiler locally. See "[Targeting Fuchsia with a compiler built from source for the steps to build locally. You'll also need to download a copy of the Fuchsia SDK. The current minimum -supported SDK version is [9.20220726.1.1](https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:9.20220726.1.1). +supported SDK version is [10.20221207.2.89][minimum_supported_sdk_version]. + +[minimum_supported_sdk_version]: https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core/linux-amd64/+/version:10.20221207.2.89 Fuchsia's test runner interacts with the Fuchsia emulator and is located at `src/ci/docker/scripts/fuchsia-test-runner.py`. We can use it to start our @@ -697,7 +699,7 @@ test environment with: src/ci/docker/scripts/fuchsia-test-runner.py start --rust ${RUST_SRC_PATH}/install --sdk ${SDK_PATH} - --target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} + --target {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia} ``` Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and @@ -717,17 +719,11 @@ run the full `tests/ui` test suite: --target x86_64-unknown-fuchsia \ --run=always --jobs 1 \ --test-args --target-rustcflags \ - --test-args -L \ - --test-args --target-rustcflags \ - --test-args ${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ - --test-args --target-rustcflags \ - --test-args -L \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ --test-args --target-rustcflags \ - --test-args ${SDK_PATH}/arch/{x64|arm64}/lib \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \ --test-args --target-rustcflags \ - --test-args -Cpanic=abort \ - --test-args --target-rustcflags \ - --test-args -Zpanic_abort_tests \ + --test-args -Clink-arg=--undefined-version \ --test-args --remote-test-client \ --test-args src/ci/docker/scripts/fuchsia-test-runner.py \ ) @@ -736,7 +732,18 @@ run the full `tests/ui` test suite: *Note: The test suite cannot be run in parallel at the moment, so `x.py` must be run with `--jobs 1` to ensure only one test runs at a time.* -When finished, the test runner can be used to stop the test environment: +By default, `x.py` compiles test binaries with `panic=unwind`. If you built your +Rust toolchain with `-Cpanic=abort`, you need to tell `x.py` to compile test +binaries with `panic=abort` as well: + +```sh + --test-args --target-rustcflags \ + --test-args -Cpanic=abort \ + --test-args --target-rustcflags \ + --test-args -Zpanic_abort_tests \ +``` + +When finished testing, the test runner can be used to stop the test environment: ```sh src/ci/docker/scripts/fuchsia-test-runner.py stop @@ -764,8 +771,9 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ * `--symbol-path` gets required symbol paths, which are necessary for stepping through your program. -The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" section describes how you can -display Rust and/or Fuchsia source code in your debugging session. +The "[displaying source code in `zxdb`](#displaying-source-code-in-zxdb)" +section describes how you can display Rust and/or Fuchsia source code in your +debugging session. ### Using `zxdb` @@ -866,6 +874,64 @@ ${SDK_PATH}/tools/${ARCH}/ffx debug connect -- \ Linking to a Fuchsia checkout can help with debugging Fuchsia libraries, such as [fdio]. +### Debugging the compiler test suite + +Debugging the compiler test suite requires some special configuration: + +First, we have to properly configure zxdb so it will be able to find debug +symbols and source information for our test. The test runner can do this for us +with: + +```sh +src/ci/docker/scripts/fuchsia-test-runner.py debug \ + --rust-src ${RUST_SRC_PATH} \ + --fuchsia-src ${FUCHSIA_SRC_PATH} \ + --test ${TEST} +``` + +where `${TEST}` is relative to Rust's `tests` directory (e.g. `ui/abi/...`). + +This will start a zxdb session that is properly configured for the specific test +being run. All three arguments are optional, so you can omit `--fuchsia-src` if +you don't have it downloaded. Now is a good time to set any desired breakpoints, +like `b main`. + +Next, we have to tell `x.py` not to optimize or strip debug symbols from our +test suite binaries. We can do this by passing some new arguments to `rustc` +through our `x.py` invocation. The full invocation is: + +```sh +( \ + source config-env.sh && \ + ./x.py \ + --config config.toml \ + --stage=2 \ + test tests/${TEST} \ + --target x86_64-unknown-fuchsia \ + --run=always --jobs 1 \ + --test-args --target-rustcflags \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/sysroot/lib \ + --test-args --target-rustcflags \ + --test-args -Lnative=${SDK_PATH}/arch/{x64|arm64}/lib \ + --test-args --target-rustcflags \ + --test-args -Clink-arg=--undefined-version \ + --test-args --target-rustcflags \ + --test-args -Cdebuginfo=2 \ + --test-args --target-rustcflags \ + --test-args -Copt-level=0 \ + --test-args --target-rustcflags \ + --test-args -Cstrip=none \ + --test-args --remote-test-client \ + --test-args src/ci/docker/scripts/fuchsia-test-runner.py \ +) +``` + +*If you built your Rust toolchain with `panic=abort`, make sure to include the +previous flags so your test binaries are also compiled with `panic=abort`.* + +Upon running this command, the test suite binary will be run and zxdb will +attach and load any relevant debug symbols. + [Fuchsia team]: https://team-api.infra.rust-lang.org/v1/teams/fuchsia.json [Fuchsia]: https://fuchsia.dev/ [source tree]: https://fuchsia.dev/fuchsia-src/get-started/learn/build diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 5e592227d49..c48f7998c5a 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -18,7 +18,6 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } smallvec = "1.8.1" tempfile = "3" -thin-vec = "0.2.9" tracing = "0.1" tracing-tree = "0.2.0" diff --git a/src/librustdoc/clean/cfg/tests.rs b/src/librustdoc/clean/cfg/tests.rs index 81f67672436..bb62660e194 100644 --- a/src/librustdoc/clean/cfg/tests.rs +++ b/src/librustdoc/clean/cfg/tests.rs @@ -4,6 +4,7 @@ use rustc_ast::{LitKind, MetaItemLit, Path, StrStyle}; use rustc_span::create_default_session_globals_then; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::DUMMY_SP; +use thin_vec::thin_vec; fn word_cfg(s: &str) -> Cfg { Cfg::Cfg(Symbol::intern(s), None) @@ -34,7 +35,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:ident),* $(,)?]) => { MetaItem { path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(vec![ + kind: MetaItemKind::List(thin_vec![ $( NestedMetaItem::MetaItem( dummy_meta_item_word(stringify!($list)), @@ -48,7 +49,7 @@ macro_rules! dummy_meta_item_list { ($name:ident, [$($list:expr),* $(,)?]) => { MetaItem { path: Path::from_ident(Ident::from_str(stringify!($name))), - kind: MetaItemKind::List(vec![ + kind: MetaItemKind::List(thin_vec![ $( NestedMetaItem::MetaItem($list), )* diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0c70d31ed60..0e8f0cfc518 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -22,9 +22,9 @@ use rustc_hir::PredicateOrigin; use rustc_hir_analysis::hir_ty_to_ty; use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::middle::resolve_bound_vars as rbv; -use rustc_middle::ty::fold::ir::TypeFolder; +use rustc_middle::ty::fold::TypeFolder; use rustc_middle::ty::InternalSubsts; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, AdtKind, DefIdTree, EarlyBinder, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::hygiene::{AstPass, MacroKind}; @@ -77,7 +77,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< // This covers the case where somebody does an import which should pull in an item, // but there's already an item with the same namespace and same name. Rust gives // priority to the not-imported one, so we should, too. - items.extend(doc.items.iter().flat_map(|(item, renamed, import_id)| { + items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| { // First, lower everything other than imports. if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) { return Vec::new(); @@ -90,7 +90,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext< } v })); - items.extend(doc.items.iter().flat_map(|(item, renamed, _)| { + items.extend(doc.items.values().flat_map(|(item, renamed, _)| { // Now we actually lower the imports, skipping everything else. if let hir::ItemKind::Use(path, hir::UseKind::Glob) = item.kind { let name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id())); @@ -1661,7 +1661,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::BareFn(barefn) => BareFunction(Box::new(clean_bare_fn_ty(barefn, cx))), // Rustdoc handles `TyKind::Err`s by turning them into `Type::Infer`s. - TyKind::Infer | TyKind::Err | TyKind::Typeof(..) => Infer, + TyKind::Infer | TyKind::Err(_) | TyKind::Typeof(..) => Infer, } } @@ -2114,17 +2114,29 @@ fn get_all_import_attributes<'hir>( attributes: &mut Vec<ast::Attribute>, is_inline: bool, ) { + let mut first = true; let hir_map = tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visited = FxHashSet::default(); + // If the item is an import and has at least a path with two parts, we go into it. while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) { - // We add the attributes from this import into the list. - add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + if first { + // This is the "original" reexport so we get all its attributes without filtering them. + attributes.extend_from_slice(hir_map.attrs(item.hir_id())); + first = false; + } else { + add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + } - let def_id = if path.segments.len() > 1 { - match path.segments[path.segments.len() - 2].res { + let def_id = if let [.., parent_segment, _] = &path.segments { + match parent_segment.res { hir::def::Res::Def(_, def_id) => def_id, + _ if parent_segment.ident.name == kw::Crate => { + // In case the "parent" is the crate, it'll give `Res::Err` so we need to + // circumvent it this way. + tcx.parent(item.owner_id.def_id.to_def_id()) + } _ => break, } } else { @@ -2341,9 +2353,7 @@ fn clean_maybe_renamed_item<'tcx>( if let Some(import_id) = import_id && let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id) { - // First, we add the attributes from the current import. - extra_attrs.extend_from_slice(inline::load_attrs(cx, import_id.to_def_id())); - let is_inline = extra_attrs.lists(sym::doc).get_word_attr(sym::inline).is_some(); + let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some(); // Then we get all the various imports' attributes. get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut extra_attrs, is_inline); add_without_unwanted_attributes(&mut extra_attrs, inline::load_attrs(cx, def_id), is_inline); diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index ed7683e36fd..ef38ca3c16c 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -63,7 +63,8 @@ fn snippet_equal_to_token(tcx: TyCtxt<'_>, matcher: &TokenTree) -> Option<String let snippet = source_map.span_to_snippet(span).ok()?; // Create a Parser. - let sess = ParseSess::new(FilePathMapping::empty()); + let sess = + ParseSess::new(rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), FilePathMapping::empty()); let file_name = source_map.span_to_filename(span); let mut parser = match rustc_parse::maybe_new_parser_from_source_str(&sess, file_name, snippet.clone()) { diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 5a564c2ac1c..c9c1c2c458a 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -470,6 +470,12 @@ pub(crate) fn get_auto_trait_and_blanket_impls( cx: &mut DocContext<'_>, item_def_id: DefId, ) -> impl Iterator<Item = Item> { + // FIXME: To be removed once `parallel_compiler` bugs are fixed! + // More information in <https://github.com/rust-lang/rust/pull/106930>. + if cfg!(parallel_compiler) { + return vec![].into_iter().chain(vec![].into_iter()); + } + let auto_impls = cx .sess() .prof diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5ab7056be44..fbfc58a436b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -115,8 +115,10 @@ pub(crate) fn new_handler( diagnostic_width: Option<usize>, unstable_opts: &UnstableOptions, ) -> rustc_errors::Handler { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter: Box<dyn Emitter + sync::Send> = match error_format { ErrorOutputType::HumanReadable(kind) => { let (short, color_config) = kind.unzip(); @@ -254,6 +256,7 @@ pub(crate) fn create_config( output_file: None, output_dir: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, register_lints: Some(Box::new(crate::lint::register_lints)), diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 0eba81c7c1e..8a73d25d3f0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -96,6 +96,7 @@ pub(crate) fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { output_file: None, output_dir: None, file_loader: None, + locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES, lint_caps, parse_sess_created: None, register_lints: Some(Box::new(crate::lint::register_lints)), @@ -545,8 +546,10 @@ pub(crate) fn make_test( // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); supports_color = EmitterWriter::stderr( ColorConfig::Auto, None, @@ -741,8 +744,10 @@ fn check_if_attr_is_complete(source: &str, edition: Edition) -> bool { // Any errors in parsing should also appear when the doctest is compiled for real, so just // send all the errors that librustc_ast emits directly into a `Sink` instead of stderr. let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = EmitterWriter::new( Box::new(io::sink()), diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index aa406f30cbe..6bdd9db9bfa 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -775,7 +775,7 @@ pub(crate) fn link_tooltip(did: DefId, fragment: &Option<UrlFragment>, cx: &Cont let fqp = fqp.iter().map(|sym| sym.as_str()).join("::"); if let &Some(UrlFragment::Item(id)) = fragment { let name = cx.tcx().item_name(id); - let descr = cx.tcx().def_kind(id).descr(id); + let descr = cx.tcx().def_descr(id); format!("{descr} {fqp}::{name}") } else { format!("{shortty} {fqp}") diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 9ef0b501c08..89f1ad71134 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -552,10 +552,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> SummaryLine<'a, I> { } fn check_if_allowed_tag(t: &Tag<'_>) -> bool { - matches!( - t, - Tag::Paragraph | Tag::Item | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote - ) + matches!(t, Tag::Paragraph | Tag::Emphasis | Tag::Strong | Tag::Link(..) | Tag::BlockQuote) } fn is_forbidden_tag(t: &Tag<'_>) -> bool { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 910a7190b58..4fcf0873600 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -20,6 +20,7 @@ #![allow(clippy::collapsible_if, clippy::collapsible_else_if)] #![allow(rustc::potential_query_instability)] +extern crate thin_vec; #[macro_use] extern crate tracing; diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs index 03be5e79971..26fbb03a43e 100644 --- a/src/librustdoc/passes/lint/check_code_block_syntax.rs +++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs @@ -33,8 +33,10 @@ fn check_rust_syntax( code_block: RustCodeBlock, ) { let buffer = Lrc::new(Lock::new(Buffer::default())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); let emitter = BufferEmitter { buffer: Lrc::clone(&buffer), fallback_bundle }; let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 9c1e5f4a3cd..277201e4de9 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -1,7 +1,7 @@ //! The Rust AST Visitor. Extracts useful information and massages it into a form //! usable for `clean`. -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LocalDefIdSet}; @@ -26,8 +26,12 @@ pub(crate) struct Module<'hir> { pub(crate) where_inner: Span, pub(crate) mods: Vec<Module<'hir>>, pub(crate) def_id: LocalDefId, - // (item, renamed, import_id) - pub(crate) items: Vec<(&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>)>, + /// The key is the item `ItemId` and the value is: (item, renamed, import_id). + /// We use `FxIndexMap` to keep the insert order. + pub(crate) items: FxIndexMap< + (LocalDefId, Option<Symbol>), + (&'hir hir::Item<'hir>, Option<Symbol>, Option<LocalDefId>), + >, pub(crate) foreigns: Vec<(&'hir hir::ForeignItem<'hir>, Option<Symbol>)>, } @@ -38,7 +42,7 @@ impl Module<'_> { def_id, where_inner, mods: Vec::new(), - items: Vec::new(), + items: FxIndexMap::default(), foreigns: Vec::new(), } } @@ -136,7 +140,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { inserted.insert(def_id) { let item = self.cx.tcx.hir().expect_item(local_def_id); - top_level_module.items.push((item, None, None)); + top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None)); } } @@ -294,7 +298,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { renamed: Option<Symbol>, parent_id: Option<LocalDefId>, ) { - self.modules.last_mut().unwrap().items.push((item, renamed, parent_id)) + self.modules + .last_mut() + .unwrap() + .items + .insert((item.owner_id.def_id, renamed), (item, renamed, parent_id)); } fn visit_item_inner( diff --git a/src/tools/cargo b/src/tools/cargo -Subproject 17b3d0de0897e1c6b8ca347bd39f850bb0a5b9f +Subproject 9d5b32f503fc099c4064298465add14d4bce11e diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index b4543aa2544..644604a2e3f 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -27,7 +27,7 @@ use rustc_middle::mir::{Rvalue, StatementKind}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::{ self, Binder, BoundVariableKind, Clause, EarlyBinder, FnSig, GenericArgKind, List, ParamTy, PredicateKind, - ProjectionPredicate, Ty, TyCtxt, TypeVisitable, TypeckResults, + ProjectionPredicate, Ty, TyCtxt, TypeVisitableExt, TypeckResults, }; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{symbol::sym, Span, Symbol}; @@ -1022,7 +1022,7 @@ fn binding_ty_auto_deref_stability<'tcx>( )) .is_sized(cx.tcx, cx.param_env.without_caller_bounds()), ), - TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err => { + TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(..) | TyKind::TraitObject(..) | TyKind::Err(_) => { Position::ReborrowStable(precedence) }, }; @@ -1038,7 +1038,7 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool { if self.0 || matches!( ty.kind, - TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err + TyKind::OpaqueDef(..) | TyKind::Infer | TyKind::Typeof(_) | TyKind::Err(_) ) { self.0 = true; diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index 1cdcccd5f14..b8428d66a5d 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -514,7 +514,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) -> } ParamEnv::new( - tcx.mk_predicates(ty_predicates.iter().map(|&(p, _)| p).chain( + tcx.mk_predicates_from_iter(ty_predicates.iter().map(|&(p, _)| p).chain( params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| { tcx.mk_predicate(Binder::dummy(PredicateKind::Clause(Clause::Trait(TraitPredicate { trait_ref: tcx.mk_trait_ref(eq_trait_id, [tcx.mk_param_from_def(param)]), diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs index 0b31e20fc87..6fdb7de25cc 100644 --- a/src/tools/clippy/clippy_lints/src/doc.rs +++ b/src/tools/clippy/clippy_lints/src/doc.rs @@ -704,8 +704,10 @@ fn check_code(cx: &LateContext<'_>, text: &str, edition: Edition, span: Span) { let filename = FileName::anon_source_code(&code); let sm = Lrc::new(SourceMap::new(FilePathMapping::empty())); - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = EmitterWriter::new( Box::new(io::sink()), None, diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index ddade65c515..b2071f4dcb1 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::binding::BindingMode; -use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitable}; +use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index 565c5b7af00..9011f0896a0 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -42,6 +42,7 @@ extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; extern crate rustc_trait_selection; +extern crate thin_vec; #[macro_use] extern crate clippy_utils; diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs index 14f161f5102..d7e00047312 100644 --- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs @@ -224,7 +224,7 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H | ExprKind::Path(_) | ExprKind::ConstBlock(_) | ExprKind::Lit(_) - | ExprKind::Err => NeverLoopResult::Otherwise, + | ExprKind::Err(_) => NeverLoopResult::Otherwise, } } diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index f587c69f730..b33a2478172 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -341,7 +341,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { ExprKind::ConstBlock(_) | ExprKind::Continue(_) | ExprKind::DropTemps(_) | - ExprKind::Err | + ExprKind::Err(_) | ExprKind::InlineAsm(_) | ExprKind::Let(_) | ExprKind::Lit(_) | diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 8ddbacc3d7a..0b0c6adc504 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -173,7 +173,7 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) - && let substs = cx.tcx.intern_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) + && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 4e5af1c7c71..df26b36b7b3 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -414,7 +414,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< } }); - let new_subst = cx.tcx.mk_substs( + let new_subst = cx.tcx.mk_substs_from_iter( call_substs.iter() .enumerate() .map(|(i, t)| diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 3cc765108d7..5a533261cad 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -3,7 +3,7 @@ use clippy_utils::{def_path_def_ids, trait_ref_of_method}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 996ea6ed723..da3b6fa9899 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -18,7 +18,7 @@ use rustc_hir_typeck::expr_use_visitor as euv; use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; -use rustc_middle::ty::{self, TypeVisitable}; +use rustc_middle::ty::{self, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; diff --git a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs index 24aeb82a37f..d3de9699fe9 100644 --- a/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs +++ b/src/tools/clippy/clippy_lints/src/operators/cmp_owned.rs @@ -49,10 +49,10 @@ fn check_op(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) (arg, arg.span) }, ExprKind::Call(path, [arg]) - if path_def_id(cx, path).map_or(false, |id| { - if match_def_path(cx, id, &paths::FROM_STR_METHOD) { + if path_def_id(cx, path).map_or(false, |did| { + if match_def_path(cx, did, &paths::FROM_STR_METHOD) { true - } else if cx.tcx.lang_items().from_fn() == Some(id) { + } else if cx.tcx.is_diagnostic_item(sym::from_fn, did) { !is_copy(cx, typeck.expr_ty(expr)) } else { false diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index 398329e455b..2fdd775ad48 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -134,7 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - cx.tcx.mk_projection(target_id, cx.tcx.intern_substs(&[GenericArg::from(indexed_ty)])), + cx.tcx.mk_projection(target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs index 54ac04df1c1..6bdb9aa5a26 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs @@ -6,7 +6,7 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::{self as hir, Expr, GenericArg, Mutability, Path, TyKind}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; /// Checks for `transmute_ptr_to_ref` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs index 871c3fadbba..56207fe767c 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs @@ -4,7 +4,7 @@ use clippy_utils::sugg; use rustc_errors::Applicability; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty::{self, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitableExt}; /// Checks for `useless_transmute` lint. /// Returns `true` if it's triggered, otherwise returns `false`. diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs index f9b9a66b5fa..f7adc9d3555 100644 --- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs +++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs @@ -5,7 +5,7 @@ use rustc_errors::Applicability; use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_span::symbol::sym; use super::{utils, REDUNDANT_ALLOCATION}; diff --git a/src/tools/clippy/clippy_lints/src/types/vec_box.rs b/src/tools/clippy/clippy_lints/src/types/vec_box.rs index 7a3c7cd8a99..d3062f3d2e3 100644 --- a/src/tools/clippy/clippy_lints/src/types/vec_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/vec_box.rs @@ -7,7 +7,7 @@ use rustc_hir::{self as hir, def_id::DefId, GenericArg, QPath, TyKind}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::LateContext; use rustc_middle::ty::layout::LayoutOf; -use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::TypeVisitableExt; use rustc_span::symbol::sym; use super::VEC_BOX; diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs index 9f207d32fcf..6e802794f5a 100644 --- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs +++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs @@ -7,6 +7,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; declare_clippy_lint! { /// ### What it does @@ -54,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings { ); } else { if_chain! { - if Some(fun_def_id) == cx.tcx.lang_items().from_fn(); + if cx.tcx.is_diagnostic_item(sym::from_fn, fun_def_id); if let [.., last_arg] = args; if let ExprKind::Lit(spanned) = &last_arg.kind; if let LitKind::Str(symbol, _) = spanned.node; diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs index 7355260ae4a..06d248204c1 100644 --- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs +++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs @@ -12,9 +12,9 @@ use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::DUMMY_SP; - use std::cell::Cell; use std::mem; +use thin_vec::{thin_vec, ThinVec}; declare_clippy_lint! { /// ### What it does @@ -214,7 +214,7 @@ macro_rules! always_pat { /// Focus on `focus_idx` in `alternatives`, /// attempting to extend it with elements of the same constructor `C` /// in `alternatives[focus_idx + 1..]`. -fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize) -> bool { +fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool { // Extract the kind; we'll need to make some changes in it. let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, PatKind::Wild); // We'll focus on `alternatives[focus_idx]`, @@ -296,7 +296,7 @@ fn extend_with_struct_pat( fps1: &mut [ast::PatField], rest1: bool, start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, ) -> bool { (0..fps1.len()).any(|idx| { let pos_in_2 = Cell::new(None); // The element `k`. @@ -336,9 +336,9 @@ fn extend_with_struct_pat( fn extend_with_matching_product( targets: &mut [P<Pat>], start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind, &[P<Pat>], usize) -> bool, - extract: impl Fn(PatKind) -> Vec<P<Pat>>, + extract: impl Fn(PatKind) -> ThinVec<P<Pat>>, ) -> bool { (0..targets.len()).any(|idx| { let tail_or = drain_matching( @@ -365,14 +365,14 @@ fn take_pat(from: &mut Pat) -> Pat { /// Extend `target` as an or-pattern with the alternatives /// in `tail_or` if there are any and return if there were. -fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool { - fn extend(target: &mut Pat, mut tail_or: Vec<P<Pat>>) { +fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<P<Pat>>) -> bool { + fn extend(target: &mut Pat, mut tail_or: ThinVec<P<Pat>>) { match target { // On an existing or-pattern in the target, append to it. Pat { kind: Or(ps), .. } => ps.append(&mut tail_or), // Otherwise convert the target to an or-pattern. target => { - let mut init_or = vec![P(take_pat(target))]; + let mut init_or = thin_vec![P(take_pat(target))]; init_or.append(&mut tail_or); target.kind = Or(init_or); }, @@ -391,26 +391,42 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: Vec<P<Pat>>) -> bool { // Only elements beginning with `start` are considered for extraction. fn drain_matching( start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind) -> bool, extract: impl Fn(PatKind) -> P<Pat>, -) -> Vec<P<Pat>> { - let mut tail_or = vec![]; +) -> ThinVec<P<Pat>> { + let mut tail_or = ThinVec::new(); let mut idx = 0; - for pat in alternatives.drain_filter(|p| { - // Check if we should extract, but only if `idx >= start`. + + // If `ThinVec` had the `drain_filter` method, this loop could be rewritten + // like so: + // + // for pat in alternatives.drain_filter(|p| { + // // Check if we should extract, but only if `idx >= start`. + // idx += 1; + // idx > start && predicate(&p.kind) + // }) { + // tail_or.push(extract(pat.into_inner().kind)); + // } + let mut i = 0; + while i < alternatives.len() { idx += 1; - idx > start && predicate(&p.kind) - }) { - tail_or.push(extract(pat.into_inner().kind)); + // Check if we should extract, but only if `idx >= start`. + if idx > start && predicate(&alternatives[i].kind) { + let pat = alternatives.remove(i); + tail_or.push(extract(pat.into_inner().kind)); + } else { + i += 1; + } } + tail_or } fn extend_with_matching( target: &mut Pat, start: usize, - alternatives: &mut Vec<P<Pat>>, + alternatives: &mut ThinVec<P<Pat>>, predicate: impl Fn(&PatKind) -> bool, extract: impl Fn(PatKind) -> P<Pat>, ) -> bool { diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index a95e7b61374..fede625f72a 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { } if_chain! { - if Some(def_id) == cx.tcx.lang_items().from_fn(); + if cx.tcx.is_diagnostic_item(sym::from_fn, def_id); if same_type_and_consts(a, b); then { diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index bd7daf0773c..c37e5bb6716 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -588,7 +588,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, } }, - ExprKind::Err => kind!("Err"), + ExprKind::Err(_) => kind!("Err"), ExprKind::DropTemps(expr) => { bind!(self, expr); kind!("DropTemps({expr})"); diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 6cf2a955fd5..93e4b023c5c 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -5,7 +5,7 @@ use rustc_hir::{self as hir, HirId, ItemKind, Node}; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::layout::LayoutOf as _; -use rustc_middle::ty::{Adt, Ty, TypeVisitable}; +use rustc_middle::ty::{Adt, Ty, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs index 9d0263e93be..d82098523e3 100644 --- a/src/tools/clippy/clippy_utils/src/ast_utils.rs +++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs @@ -144,7 +144,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (_, Paren(r)) => eq_expr(l, r), (Err, Err) => true, (Box(l), Box(r)) | (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r), - (Array(l), Array(r)) | (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), + (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), + (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), (Call(lc, la), Call(rc, ra)) => eq_expr(lc, rc) && over(la, ra, |l, r| eq_expr(l, r)), ( diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index 8b00ce2cc25..bb8890dcaf9 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -237,7 +237,7 @@ pub fn constant<'tcx>( typeck_results, param_env: lcx.param_env, needed_resolution: false, - substs: lcx.tcx.intern_substs(&[]), + substs: ty::List::empty(), }; cx.expr(e).map(|cst| (cst, cx.needed_resolution)) } @@ -306,7 +306,7 @@ pub fn constant_context<'a, 'tcx>( typeck_results, param_env: lcx.param_env, needed_resolution: false, - substs: lcx.tcx.intern_substs(&[]), + substs: ty::List::empty(), } } diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 6ff7728374f..ee2f816f181 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -193,7 +193,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS | ExprKind::Ret(_) | ExprKind::InlineAsm(_) | ExprKind::Yield(..) - | ExprKind::Err => { + | ExprKind::Err(_) => { self.eagerness = ForceNoChange; return; }, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 2bbe1a19b62..0603755f8a9 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -714,7 +714,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } self.hash_pat(pat); }, - ExprKind::Err => {}, + ExprKind::Err(_) => {}, ExprKind::Lit(ref l) => { l.node.hash(&mut self.s); }, @@ -986,7 +986,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { TyKind::Typeof(anon_const) => { self.hash_body(anon_const.body); }, - TyKind::Err | TyKind::Infer | TyKind::Never => {}, + TyKind::Err(_) | TyKind::Infer | TyKind::Never => {}, } } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index b2edd1bbfef..f02f8ecb43d 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -104,7 +104,7 @@ use rustc_middle::ty::fast_reject::SimplifiedType::{ PtrSimplifiedType, SliceSimplifiedType, StrSimplifiedType, UintSimplifiedType, }; use rustc_middle::ty::{ - layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitable, UpvarCapture, + layout::IntegerExt, BorrowKind, ClosureKind, DefIdTree, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UpvarCapture, }; use rustc_middle::ty::{FloatTy, IntTy, UintTy}; use rustc_span::hygiene::{ExpnKind, MacroKind}; diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs index e9dc7351b58..920ce8e655b 100644 --- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs +++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::{BitSet, HybridBitSet}; use rustc_lint::LateContext; use rustc_middle::mir::{self, visit::Visitor as _, Mutability}; -use rustc_middle::ty::{self, visit::ir::TypeVisitor, TyCtxt}; +use rustc_middle::ty::{self, visit::TypeVisitor, TyCtxt}; use rustc_mir_dataflow::{impls::MaybeStorageLive, Analysis, ResultsCursor}; use std::borrow::Cow; use std::ops::ControlFlow; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 78fb2e0eb7e..11ca81cfe6c 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -157,7 +157,7 @@ impl<'a> Sugg<'a> { | hir::ExprKind::Ret(..) | hir::ExprKind::Struct(..) | hir::ExprKind::Tup(..) - | hir::ExprKind::Err => Sugg::NonParen(get_snippet(expr.span)), + | hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)), hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet), hir::ExprKind::Assign(lhs, rhs, _) => { Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span)) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index 2ed301fcc22..f8ec4bb5493 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -17,8 +17,8 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, DefIdTree, FnSig, IntTy, List, ParamEnv, Predicate, - PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, ir::TypeVisitor, UintTy, - VariantDef, VariantDiscr, + PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, UintTy, + VariantDef, VariantDiscr, TypeVisitableExt, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; @@ -237,7 +237,7 @@ pub fn implements_trait_with_env<'tcx>( kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }; - let ty_params = tcx.mk_substs( + let ty_params = tcx.mk_substs_from_iter( ty_params .into_iter() .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())), @@ -847,7 +847,7 @@ pub fn for_each_top_level_late_bound_region<B>( ControlFlow::Continue(()) } } - fn visit_binder<T: TypeVisitable<'tcx>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> { + fn visit_binder<T: TypeVisitable<TyCtxt<'tcx>>>(&mut self, t: &Binder<'tcx, T>) -> ControlFlow<Self::BreakTy> { self.index += 1; let res = t.super_visit_with(self); self.index -= 1; @@ -1065,7 +1065,7 @@ pub fn make_projection<'tcx>( tcx, container_id, assoc_ty, - tcx.mk_substs(substs.into_iter().map(Into::into)), + tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)), ) } diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index 00073bcd82a..d27a20bd4df 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -665,7 +665,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Path(_) | ExprKind::Continue(_) | ExprKind::InlineAsm(_) - | ExprKind::Err => (), + | ExprKind::Err(_) => (), } ControlFlow::Continue(()) } diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index e45835efe74..9ac849aecf1 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -209,7 +209,10 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { // Separate the output with an empty line eprintln!(); - let fallback_bundle = rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false + ); let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr( rustc_errors::ColorConfig::Auto, None, diff --git a/src/tools/clippy/tests/ui/missing_doc_impl.stderr b/src/tools/clippy/tests/ui/missing_doc_impl.stderr index f22fa19dbca..b410f56e167 100644 --- a/src/tools/clippy/tests/ui/missing_doc_impl.stderr +++ b/src/tools/clippy/tests/ui/missing_doc_impl.stderr @@ -51,13 +51,13 @@ LL | | fn foo_with_impl(&self) {} LL | | } | |_^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:44:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/missing_doc_impl.rs:45:5 | LL | fn foo_with_impl(&self) {} diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml index deed6fbd439..0db043a4fca 100644 --- a/src/tools/compiletest/Cargo.toml +++ b/src/tools/compiletest/Cargo.toml @@ -16,7 +16,7 @@ regex = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" rustfix = "0.6.0" -lazy_static = "1.0" +once_cell = "1.16.0" walkdir = "2" glob = "0.3.0" lazycell = "1.3.0" @@ -25,5 +25,5 @@ lazycell = "1.3.0" libc = "0.2" [target.'cfg(windows)'.dependencies] -miow = "0.3" +miow = "0.5" winapi = { version = "0.3", features = ["winerror"] } diff --git a/src/tools/compiletest/src/errors.rs b/src/tools/compiletest/src/errors.rs index 054235ec16d..c33e66e02ac 100644 --- a/src/tools/compiletest/src/errors.rs +++ b/src/tools/compiletest/src/errors.rs @@ -7,7 +7,7 @@ use std::io::BufReader; use std::path::Path; use std::str::FromStr; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use regex::Regex; use tracing::*; @@ -117,10 +117,8 @@ fn parse_expected( // //~^^^^^ // //[cfg1]~ // //[cfg1,cfg2]~^^ - lazy_static! { - static ref RE: Regex = - Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap(); - } + static RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)").unwrap()); let captures = RE.captures(line)?; diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index c648b2f12f1..1760c29ec66 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -588,7 +588,8 @@ fn modified_tests(config: &Config, dir: &Path) -> Result<Vec<PathBuf>, String> { let full_paths = { let mut full_paths: Vec<PathBuf> = all_paths .into_iter() - .map(|f| fs::canonicalize(&f).unwrap().with_extension("").with_extension("rs")) + .map(|f| PathBuf::from(f).with_extension("").with_extension("rs")) + .filter_map(|f| if Path::new(&f).exists() { f.canonicalize().ok() } else { None }) .collect(); full_paths.dedup(); full_paths.sort_unstable(); diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 51c9a27c83d..7824ef81d7a 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -32,7 +32,7 @@ use std::process::{Child, Command, ExitStatus, Output, Stdio}; use std::str; use glob::glob; -use lazy_static::lazy_static; +use once_cell::sync::Lazy; use tracing::*; use crate::extract_gdb_version; @@ -52,9 +52,8 @@ fn disable_error_reporting<F: FnOnce() -> R, R>(f: F) -> R { use winapi::um::errhandlingapi::SetErrorMode; use winapi::um::winbase::SEM_NOGPFAULTERRORBOX; - lazy_static! { - static ref LOCK: Mutex<()> = Mutex::new(()); - } + static LOCK: Mutex<()> = Mutex::new(()); + // Error mode is a global variable, so lock it so only one thread will change it let _lock = LOCK.lock().unwrap(); @@ -2848,11 +2847,10 @@ impl<'test> TestCx<'test> { // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>, // remove all crate-disambiguators. fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String { - lazy_static! { - static ref RE: Regex = - Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?") - .unwrap(); - } + static RE: Lazy<Regex> = Lazy::new(|| { + Regex::new(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?") + .unwrap() + }); let captures = RE.captures(cgu).unwrap_or_else(|| panic!("invalid cgu name encountered: {}", cgu)); @@ -3170,12 +3168,12 @@ impl<'test> TestCx<'test> { // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"' // is printed to stdout by the client and then captured in the ProcRes, // so it needs to be removed when comparing the run-pass test execution output - lazy_static! { - static ref REMOTE_TEST_RE: Regex = Regex::new( + static REMOTE_TEST_RE: Lazy<Regex> = Lazy::new(|| { + Regex::new( "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-.]+)+\", waiting for result\n" ) - .unwrap(); - } + .unwrap() + }); REMOTE_TEST_RE .replace( &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout), @@ -3620,10 +3618,8 @@ impl<'test> TestCx<'test> { // with placeholders as we do not want tests needing updated when compiler source code // changes. // eg. $SRC_DIR/libcore/mem.rs:323:14 becomes $SRC_DIR/libcore/mem.rs:LL:COL - lazy_static! { - static ref SRC_DIR_RE: Regex = - Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap(); - } + static SRC_DIR_RE: Lazy<Regex> = + Lazy::new(|| Regex::new("SRC_DIR(.+):\\d+:\\d+(: \\d+:\\d+)?").unwrap()); normalized = SRC_DIR_RE.replace_all(&normalized, "SRC_DIR$1:LL:COL").into_owned(); @@ -3634,19 +3630,17 @@ impl<'test> TestCx<'test> { // since they duplicate actual errors and make the output hard to read. // This mirrors the regex in src/tools/tidy/src/style.rs, please update // both if either are changed. - lazy_static! { - static ref ANNOTATION_RE: Regex = Regex::new("\\s*//(\\[.*\\])?~.*").unwrap(); - } + static ANNOTATION_RE: Lazy<Regex> = + Lazy::new(|| Regex::new("\\s*//(\\[.*\\])?~.*").unwrap()); normalized = ANNOTATION_RE.replace_all(&normalized, "").into_owned(); // This code normalizes various hashes in v0 symbol mangling that is // emitted in the ui and mir-opt tests. - lazy_static! { - static ref V0_CRATE_HASH_PREFIX_RE: Regex = - Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap(); - static ref V0_CRATE_HASH_RE: Regex = Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap(); - } + static V0_CRATE_HASH_PREFIX_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"_R.*?Cs[0-9a-zA-Z]+_").unwrap()); + static V0_CRATE_HASH_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"Cs[0-9a-zA-Z]+_").unwrap()); const V0_CRATE_HASH_PLACEHOLDER: &str = r"CsCRATE_HASH_"; if V0_CRATE_HASH_PREFIX_RE.is_match(&normalized) { @@ -3655,10 +3649,9 @@ impl<'test> TestCx<'test> { V0_CRATE_HASH_RE.replace_all(&normalized, V0_CRATE_HASH_PLACEHOLDER).into_owned(); } - lazy_static! { - static ref V0_BACK_REF_PREFIX_RE: Regex = Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap(); - static ref V0_BACK_REF_RE: Regex = Regex::new(r"B[0-9a-zA-Z]_").unwrap(); - } + static V0_BACK_REF_PREFIX_RE: Lazy<Regex> = + Lazy::new(|| Regex::new(r"\(_R.*?B[0-9a-zA-Z]_").unwrap()); + static V0_BACK_REF_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"B[0-9a-zA-Z]_").unwrap()); const V0_BACK_REF_PLACEHOLDER: &str = r"B<REF>_"; if V0_BACK_REF_PREFIX_RE.is_match(&normalized) { @@ -3681,21 +3674,23 @@ impl<'test> TestCx<'test> { /// Replaces backslashes in paths with forward slashes, and replaces CRLF line endings /// with LF. fn normalize_platform_differences(output: &str) -> String { - lazy_static! { - /// Used to find Windows paths. - /// - /// It's not possible to detect paths in the error messages generally, but this is a - /// decent enough heuristic. - static ref PATH_BACKSLASH_RE: Regex = Regex::new(r#"(?x) + /// Used to find Windows paths. + /// + /// It's not possible to detect paths in the error messages generally, but this is a + /// decent enough heuristic. + static PATH_BACKSLASH_RE: Lazy<Regex> = Lazy::new(|| { + Regex::new( + r#"(?x) (?: # Match paths that don't include spaces. (?:\\[\pL\pN\.\-_']+)+\.\pL+ | # If the path starts with a well-known root, then allow spaces. \$(?:DIR|SRC_DIR|TEST_BUILD_DIR|BUILD_DIR|LIB_DIR)(?:\\[\pL\pN\.\-_' ]+)+ - )"# - ).unwrap(); - } + )"#, + ) + .unwrap() + }); let output = output.replace(r"\\", r"\"); diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index f4dac6e947e..76c2e330b21 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] mdbook = { version = "0.4", default-features = false, features = ["search"] } +rustc_error_codes = { version = "0.0.0", path = "../../../compiler/rustc_error_codes" } [[bin]] name = "error_index_generator" diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index 98eda97e236..f984275b164 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -2,9 +2,6 @@ extern crate rustc_driver; -// We use the function we generate from `register_diagnostics!`. -use crate::error_codes::error_codes; - use std::env; use std::error::Error; use std::fs::{self, File}; @@ -17,22 +14,6 @@ use std::str::FromStr; use mdbook::book::{parse_summary, BookItem, Chapter}; use mdbook::{Config, MDBook}; -macro_rules! register_diagnostics { - ($($error_code:ident: $message:expr,)+ ; $($undocumented:ident,)* ) => { - pub fn error_codes() -> Vec<(&'static str, Option<&'static str>)> { - let mut errors: Vec<(&str, Option<&str>)> = vec![ - $((stringify!($error_code), Some($message)),)+ - $((stringify!($undocumented), None),)+ - ]; - errors.sort(); - errors - } - } -} - -#[path = "../../../compiler/rustc_error_codes/src/error_codes.rs"] -mod error_codes; - enum OutputFormat { HTML, Markdown, @@ -55,11 +36,8 @@ fn render_markdown(output_path: &Path) -> Result<(), Box<dyn Error>> { write!(output_file, "# Rust Compiler Error Index\n")?; - for (err_code, description) in error_codes().iter() { - match description { - Some(ref desc) => write!(output_file, "## {}\n{}\n", err_code, desc)?, - None => {} - } + for (err_code, description) in rustc_error_codes::DIAGNOSTICS.iter() { + write!(output_file, "## {}\n{}\n", err_code, description)? } Ok(()) @@ -105,27 +83,23 @@ This page lists all the error codes emitted by the Rust compiler. " ); - let err_codes = error_codes(); + let err_codes = rustc_error_codes::DIAGNOSTICS; let mut chapters = Vec::with_capacity(err_codes.len()); for (err_code, explanation) in err_codes.iter() { - if let Some(explanation) = explanation { - introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); - - let content = add_rust_attribute_on_codeblock(explanation); - chapters.push(BookItem::Chapter(Chapter { - name: err_code.to_string(), - content: format!("# Error code {}\n\n{}\n", err_code, content), - number: None, - sub_items: Vec::new(), - // We generate it into the `error_codes` folder. - path: Some(PathBuf::from(&format!("{}.html", err_code))), - source_path: None, - parent_names: Vec::new(), - })); - } else { - introduction.push_str(&format!(" * {}\n", err_code)); - } + introduction.push_str(&format!(" * [{0}](./{0}.html)\n", err_code)); + + let content = add_rust_attribute_on_codeblock(explanation); + chapters.push(BookItem::Chapter(Chapter { + name: err_code.to_string(), + content: format!("# Error code {}\n\n{}\n", err_code, content), + number: None, + sub_items: Vec::new(), + // We generate it into the `error_codes` folder. + path: Some(PathBuf::from(&format!("{}.html", err_code))), + source_path: None, + parent_names: Vec::new(), + })); } let mut config = Config::from_str(include_str!("book_config.toml"))?; diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index c6f55410e44..a1f675a3b40 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -71,6 +71,19 @@ impl<'a> Validator<'a> { } } + fn check_items(&mut self, id: &Id, items: &[Id]) { + let mut visited_ids = HashSet::with_capacity(items.len()); + + for item in items { + if !visited_ids.insert(item) { + self.fail( + id, + ErrorKind::Custom(format!("Duplicated entry in `items` field: `{item:?}`")), + ); + } + } + } + fn check_item(&mut self, id: &'a Id) { if let Some(item) = &self.krate.index.get(id) { item.links.values().for_each(|id| self.add_any_id(id)); @@ -83,9 +96,9 @@ impl<'a> Validator<'a> { ItemEnum::Enum(x) => self.check_enum(x), ItemEnum::Variant(x) => self.check_variant(x, id), ItemEnum::Function(x) => self.check_function(x), - ItemEnum::Trait(x) => self.check_trait(x), + ItemEnum::Trait(x) => self.check_trait(x, id), ItemEnum::TraitAlias(x) => self.check_trait_alias(x), - ItemEnum::Impl(x) => self.check_impl(x), + ItemEnum::Impl(x) => self.check_impl(x, id), ItemEnum::Typedef(x) => self.check_typedef(x), ItemEnum::OpaqueTy(x) => self.check_opaque_ty(x), ItemEnum::Constant(x) => self.check_constant(x), @@ -94,7 +107,7 @@ impl<'a> Validator<'a> { ItemEnum::Macro(x) => self.check_macro(x), ItemEnum::ProcMacro(x) => self.check_proc_macro(x), ItemEnum::Primitive(x) => self.check_primitive_type(x), - ItemEnum::Module(x) => self.check_module(x), + ItemEnum::Module(x) => self.check_module(x, id), // FIXME: Why don't these have their own structs? ItemEnum::ExternCrate { .. } => {} ItemEnum::AssocConst { type_, default: _ } => self.check_type(type_), @@ -112,7 +125,8 @@ impl<'a> Validator<'a> { } // Core checkers - fn check_module(&mut self, module: &'a Module) { + fn check_module(&mut self, module: &'a Module, id: &Id) { + self.check_items(id, &module.items); module.items.iter().for_each(|i| self.add_mod_item_id(i)); } @@ -181,7 +195,8 @@ impl<'a> Validator<'a> { self.check_fn_decl(&x.decl); } - fn check_trait(&mut self, x: &'a Trait) { + fn check_trait(&mut self, x: &'a Trait, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); x.items.iter().for_each(|i| self.add_trait_item_id(i)); x.bounds.iter().for_each(|i| self.check_generic_bound(i)); @@ -193,7 +208,8 @@ impl<'a> Validator<'a> { x.params.iter().for_each(|i| self.check_generic_bound(i)); } - fn check_impl(&mut self, x: &'a Impl) { + fn check_impl(&mut self, x: &'a Impl, id: &Id) { + self.check_items(id, &x.items); self.check_generics(&x.generics); if let Some(path) = &x.trait_ { self.check_path(path, PathKind::Trait); diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 461add9f508..53ec1ba0821 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -f715e430aac0de131e2ad21804013ea405722a66 +c4e0cd966062ca67daed20775f4e8a60c28e57df diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index ebb71b57ae3..8443e907938 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -363,7 +363,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx, ty::ParamEnv::reveal_all(), start_id, - tcx.intern_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), + tcx.mk_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap(); diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index c82c274524a..f21b4f84c4c 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -173,7 +173,7 @@ pub fn layout_of_ty(db: &dyn HirDatabase, ty: &Ty, krate: CrateId) -> Result<Lay // let pointee = tcx.normalize_erasing_regions(param_env, pointee); // if pointee.is_sized(tcx.at(DUMMY_SP), param_env) { - // return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); + // return Ok(tcx.mk_layout(LayoutS::scalar(cx, data_ptr))); // } let unsized_part = struct_tail_erasing_lifetimes(db, pointee.clone()); diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs index 39b8d687809..cbe523c6c3c 100644 --- a/src/tools/rustfmt/src/chains.rs +++ b/src/tools/rustfmt/src/chains.rs @@ -74,6 +74,8 @@ use crate::utils::{ rewrite_ident, trimmed_last_line_width, wrap_str, }; +use thin_vec::ThinVec; + /// Provides the original input contents from the span /// of a chain element with trailing spaces trimmed. fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option<String> { @@ -168,7 +170,7 @@ enum ChainItemKind { MethodCall( ast::PathSegment, Vec<ast::GenericArg>, - Vec<ptr::P<ast::Expr>>, + ThinVec<ptr::P<ast::Expr>>, ), StructField(symbol::Ident), TupleField(symbol::Ident, bool), diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs index 8fd0fcf8f5c..340113866c4 100644 --- a/src/tools/rustfmt/src/closures.rs +++ b/src/tools/rustfmt/src/closures.rs @@ -1,5 +1,6 @@ use rustc_ast::{ast, ptr}; use rustc_span::Span; +use thin_vec::thin_vec; use crate::attr::get_attrs_from_stmt; use crate::config::lists::*; @@ -150,7 +151,7 @@ fn rewrite_closure_with_block( } let block = ast::Block { - stmts: vec![ast::Stmt { + stmts: thin_vec![ast::Stmt { id: ast::NodeId::root(), kind: ast::StmtKind::Expr(ptr::P(body.clone())), span: body.span, diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs index 0c27bcacfb8..b27405efdb7 100644 --- a/src/tools/rustfmt/src/lib.rs +++ b/src/tools/rustfmt/src/lib.rs @@ -23,6 +23,7 @@ extern crate rustc_expand; extern crate rustc_parse; extern crate rustc_session; extern crate rustc_span; +extern crate thin_vec; // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta // files. diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs index 7a0d1736c59..af9a154a6ae 100644 --- a/src/tools/rustfmt/src/modules.rs +++ b/src/tools/rustfmt/src/modules.rs @@ -6,6 +6,7 @@ use rustc_ast::ast; use rustc_ast::visit::Visitor; use rustc_span::symbol::{self, sym, Symbol}; use rustc_span::Span; +use thin_vec::ThinVec; use thiserror::Error; use crate::attr::MetaVisitor; @@ -25,7 +26,7 @@ type FileModMap<'ast> = BTreeMap<FileName, Module<'ast>>; #[derive(Debug, Clone)] pub(crate) struct Module<'a> { ast_mod_kind: Option<Cow<'a, ast::ModKind>>, - pub(crate) items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, + pub(crate) items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>, inner_attr: ast::AttrVec, pub(crate) span: Span, } @@ -34,7 +35,7 @@ impl<'a> Module<'a> { pub(crate) fn new( mod_span: Span, ast_mod_kind: Option<Cow<'a, ast::ModKind>>, - mod_items: Cow<'a, Vec<rustc_ast::ptr::P<ast::Item>>>, + mod_items: Cow<'a, ThinVec<rustc_ast::ptr::P<ast::Item>>>, mod_attrs: Cow<'a, ast::AttrVec>, ) -> Self { let inner_attr = mod_attrs @@ -157,7 +158,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( module_item.item.span, Some(Cow::Owned(sub_mod_kind.clone())), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Owned(ast::AttrVec::new()), ), )?; @@ -169,7 +170,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { /// Visit modules defined inside macro calls. fn visit_mod_outside_ast( &mut self, - items: Vec<rustc_ast::ptr::P<ast::Item>>, + items: ThinVec<rustc_ast::ptr::P<ast::Item>>, ) -> Result<(), ModuleResolutionError> { for item in items { if is_cfg_if(&item) { @@ -184,7 +185,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( span, Some(Cow::Owned(sub_mod_kind.clone())), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Owned(ast::AttrVec::new()), ), )?; @@ -210,7 +211,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> { Module::new( span, Some(Cow::Borrowed(sub_mod_kind)), - Cow::Owned(vec![]), + Cow::Owned(ThinVec::new()), Cow::Borrowed(&item.attrs), ), )?; diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs index e0bd065518b..7ab042506bd 100644 --- a/src/tools/rustfmt/src/parse/parser.rs +++ b/src/tools/rustfmt/src/parse/parser.rs @@ -6,6 +6,7 @@ use rustc_ast::{ast, ptr}; use rustc_errors::Diagnostic; use rustc_parse::{new_parser_from_file, parser::Parser as RawParser}; use rustc_span::{sym, Span}; +use thin_vec::ThinVec; use crate::attr::first_attr_value_str_by_name; use crate::parse::session::ParseSess; @@ -109,7 +110,7 @@ impl<'a> Parser<'a> { sess: &'a ParseSess, path: &Path, span: Span, - ) -> Result<(ast::AttrVec, Vec<ptr::P<ast::Item>>, Span), ParserError> { + ) -> Result<(ast::AttrVec, ThinVec<ptr::P<ast::Item>>, Span), ParserError> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = new_parser_from_file(sess.inner(), path, Some(span)); match parser.parse_mod(&TokenKind::Eof) { diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs index 9014026b0aa..a64963db6a7 100644 --- a/src/tools/rustfmt/src/parse/session.rs +++ b/src/tools/rustfmt/src/parse/session.rs @@ -123,8 +123,10 @@ fn default_handler( let emitter = if hide_parse_errors { silent_emitter() } else { - let fallback_bundle = - rustc_errors::fallback_fluent_bundle(rustc_errors::DEFAULT_LOCALE_RESOURCES, false); + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); Box::new(EmitterWriter::stderr( color_cfg, Some(source_map.clone()), diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index 4c93f8a16b6..bddfdcfaf19 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -120,6 +120,7 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "dissimilar", "dlmalloc", "either", + "elsa", "ena", "expect-test", "fallible-iterator", // dependency of `thorin` diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index dd2fd1911f2..c60caa0d49c 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -31,7 +31,7 @@ const IGNORE_DOCTEST_CHECK: &[&str] = &["E0464", "E0570", "E0601", "E0602", "E06 // Error codes that don't yet have a UI test. This list will eventually be removed. const IGNORE_UI_TEST_CHECK: &[&str] = - &["E0461", "E0465", "E0476", "E0514", "E0554", "E0640", "E0717", "E0729"]; + &["E0461", "E0465", "E0514", "E0554", "E0640", "E0717", "E0729"]; macro_rules! verbose_print { ($verbose:expr, $($fmt:tt)*) => { @@ -45,7 +45,7 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut let mut errors = Vec::new(); // Stage 1: create list - let error_codes = extract_error_codes(root_path, &mut errors, verbose); + let error_codes = extract_error_codes(root_path, &mut errors); println!("Found {} error codes", error_codes.len()); println!("Highest error code: `{}`", error_codes.iter().max().unwrap()); @@ -65,18 +65,17 @@ pub fn check(root_path: &Path, search_paths: &[&Path], verbose: bool, bad: &mut } /// Stage 1: Parses a list of error codes from `error_codes.rs`. -fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool) -> Vec<String> { +fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>) -> Vec<String> { let path = root_path.join(Path::new(ERROR_CODES_PATH)); let file = fs::read_to_string(&path).unwrap_or_else(|e| panic!("failed to read `{path:?}`: {e}")); let mut error_codes = Vec::new(); - let mut reached_undocumented_codes = false; for line in file.lines() { let line = line.trim(); - if !reached_undocumented_codes && line.starts_with('E') { + if line.starts_with('E') { let split_line = line.split_once(':'); // Extract the error code from the line, emitting a fatal error if it is not in a correct format. @@ -111,23 +110,6 @@ fn extract_error_codes(root_path: &Path, errors: &mut Vec<String>, verbose: bool } error_codes.push(err_code); - } else if reached_undocumented_codes && line.starts_with('E') { - let err_code = match line.split_once(',') { - None => line, - Some((err_code, _)) => err_code, - } - .to_string(); - - verbose_print!(verbose, "warning: Error code `{}` is undocumented.", err_code); - - if error_codes.contains(&err_code) { - errors.push(format!("Found duplicate error code: `{}`", err_code)); - } - - error_codes.push(err_code); - } else if line == ";" { - // Once we reach the undocumented error codes, adapt to different syntax. - reached_undocumented_codes = true; } } diff --git a/tests/mir-opt/casts.redundant.InstCombine.diff b/tests/mir-opt/casts.redundant.InstCombine.diff new file mode 100644 index 00000000000..528a8e5a90f --- /dev/null +++ b/tests/mir-opt/casts.redundant.InstCombine.diff @@ -0,0 +1,25 @@ +- // MIR for `redundant` before InstCombine ++ // MIR for `redundant` after InstCombine + + fn redundant(_1: *const &u8) -> *const &u8 { + debug x => _1; // in scope 0 at $DIR/casts.rs:+0:30: +0:31 + let mut _0: *const &u8; // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64 + let mut _2: *const &u8; // in scope 0 at $DIR/casts.rs:+1:5: +1:55 + let mut _3: *const &u8; // in scope 0 at $DIR/casts.rs:+1:36: +1:37 + scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38 + debug x => _3; // in scope 1 at $DIR/casts.rs:10:23: 10:24 + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/casts.rs:+1:5: +1:55 + StorageLive(_3); // scope 0 at $DIR/casts.rs:+1:36: +1:37 + _3 = _1; // scope 0 at $DIR/casts.rs:+1:36: +1:37 +- _2 = _3 as *const &u8 (PtrToPtr); // scope 1 at $DIR/casts.rs:11:5: 11:18 ++ _2 = _3; // scope 1 at $DIR/casts.rs:11:5: 11:18 + StorageDead(_3); // scope 0 at $DIR/casts.rs:+1:37: +1:38 + _0 = _2; // scope 0 at $DIR/casts.rs:+1:5: +1:55 + StorageDead(_2); // scope 0 at $DIR/casts.rs:+2:1: +2:2 + return; // scope 0 at $DIR/casts.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/casts.redundant.PreCodegen.after.mir b/tests/mir-opt/casts.redundant.PreCodegen.after.mir new file mode 100644 index 00000000000..21a470ea300 --- /dev/null +++ b/tests/mir-opt/casts.redundant.PreCodegen.after.mir @@ -0,0 +1,14 @@ +// MIR for `redundant` after PreCodegen + +fn redundant(_1: *const &u8) -> *const &u8 { + debug x => _1; // in scope 0 at $DIR/casts.rs:+0:30: +0:31 + let mut _0: *const &u8; // return place in scope 0 at $DIR/casts.rs:+0:51: +0:64 + scope 1 (inlined generic_cast::<&u8, &u8>) { // at $DIR/casts.rs:6:5: 6:38 + debug x => _1; // in scope 1 at $DIR/casts.rs:10:23: 10:24 + } + + bb0: { + _0 = _1; // scope 0 at $DIR/casts.rs:+1:5: +1:55 + return; // scope 0 at $DIR/casts.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir new file mode 100644 index 00000000000..0c793984ceb --- /dev/null +++ b/tests/mir-opt/casts.roundtrip.PreCodegen.after.mir @@ -0,0 +1,15 @@ +// MIR for `roundtrip` after PreCodegen + +fn roundtrip(_1: *const u8) -> *const u8 { + debug x => _1; // in scope 0 at $DIR/casts.rs:+0:18: +0:19 + let mut _0: *const u8; // return place in scope 0 at $DIR/casts.rs:+0:35: +0:44 + let mut _2: *mut u8; // in scope 0 at $DIR/casts.rs:+1:5: +1:17 + + bb0: { + StorageLive(_2); // scope 0 at $DIR/casts.rs:+1:5: +1:17 + _2 = _1 as *mut u8 (PtrToPtr); // scope 0 at $DIR/casts.rs:+1:5: +1:17 + _0 = move _2 as *const u8 (Pointer(MutToConstPointer)); // scope 0 at $DIR/casts.rs:+1:5: +1:17 + StorageDead(_2); // scope 0 at $DIR/casts.rs:+1:16: +1:17 + return; // scope 0 at $DIR/casts.rs:+2:2: +2:2 + } +} diff --git a/tests/mir-opt/casts.rs b/tests/mir-opt/casts.rs new file mode 100644 index 00000000000..259c462da3d --- /dev/null +++ b/tests/mir-opt/casts.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] + +// EMIT_MIR casts.redundant.InstCombine.diff +// EMIT_MIR casts.redundant.PreCodegen.after.mir +pub fn redundant<'a, 'b: 'a>(x: *const &'a u8) -> *const &'a u8 { + generic_cast::<&'a u8, &'b u8>(x) as *const &'a u8 +} + +#[inline] +fn generic_cast<T, U>(x: *const T) -> *const U { + x as *const U +} + +// EMIT_MIR casts.roundtrip.PreCodegen.after.mir +pub fn roundtrip(x: *const u8) -> *const u8 { + x as *mut u8 as *const u8 +} diff --git a/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff new file mode 100644 index 00000000000..c4002d65e5d --- /dev/null +++ b/tests/mir-opt/dataflow-const-prop/enum.multiple.DataflowConstProp.diff @@ -0,0 +1,82 @@ +- // MIR for `multiple` before DataflowConstProp ++ // MIR for `multiple` after DataflowConstProp + + fn multiple(_1: bool, _2: u8) -> () { + debug x => _1; // in scope 0 at $DIR/enum.rs:+0:13: +0:14 + debug i => _2; // in scope 0 at $DIR/enum.rs:+0:22: +0:23 + let mut _0: (); // return place in scope 0 at $DIR/enum.rs:+0:29: +0:29 + let _3: std::option::Option<u8>; // in scope 0 at $DIR/enum.rs:+1:9: +1:10 + let mut _4: bool; // in scope 0 at $DIR/enum.rs:+1:16: +1:17 + let mut _5: u8; // in scope 0 at $DIR/enum.rs:+2:14: +2:15 + let mut _7: isize; // in scope 0 at $DIR/enum.rs:+9:23: +9:30 + scope 1 { + debug e => _3; // in scope 1 at $DIR/enum.rs:+1:9: +1:10 + let _6: u8; // in scope 1 at $DIR/enum.rs:+9:9: +9:10 + let _8: u8; // in scope 1 at $DIR/enum.rs:+9:28: +9:29 + scope 2 { + debug x => _6; // in scope 2 at $DIR/enum.rs:+9:9: +9:10 + let _9: u8; // in scope 2 at $DIR/enum.rs:+11:9: +11:10 + scope 4 { + debug y => _9; // in scope 4 at $DIR/enum.rs:+11:9: +11:10 + } + } + scope 3 { + debug i => _8; // in scope 3 at $DIR/enum.rs:+9:28: +9:29 + } + } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/enum.rs:+1:9: +1:10 + StorageLive(_4); // scope 0 at $DIR/enum.rs:+1:16: +1:17 + _4 = _1; // scope 0 at $DIR/enum.rs:+1:16: +1:17 + switchInt(move _4) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/enum.rs:+1:16: +1:17 + } + + bb1: { + StorageLive(_5); // scope 0 at $DIR/enum.rs:+2:14: +2:15 + _5 = _2; // scope 0 at $DIR/enum.rs:+2:14: +2:15 + _3 = Option::<u8>::Some(move _5); // scope 0 at $DIR/enum.rs:+2:9: +2:16 + StorageDead(_5); // scope 0 at $DIR/enum.rs:+2:15: +2:16 + goto -> bb3; // scope 0 at $DIR/enum.rs:+1:13: +5:6 + } + + bb2: { + _3 = Option::<u8>::None; // scope 0 at $DIR/enum.rs:+4:9: +4:13 + goto -> bb3; // scope 0 at $DIR/enum.rs:+1:13: +5:6 + } + + bb3: { + StorageDead(_4); // scope 0 at $DIR/enum.rs:+5:5: +5:6 + StorageLive(_6); // scope 1 at $DIR/enum.rs:+9:9: +9:10 + _7 = discriminant(_3); // scope 1 at $DIR/enum.rs:+9:19: +9:20 + switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb5]; // scope 1 at $DIR/enum.rs:+9:13: +9:20 + } + + bb4: { + _6 = const 0_u8; // scope 1 at $DIR/enum.rs:+9:45: +9:46 + goto -> bb7; // scope 1 at $DIR/enum.rs:+9:45: +9:46 + } + + bb5: { + unreachable; // scope 1 at $DIR/enum.rs:+9:19: +9:20 + } + + bb6: { + StorageLive(_8); // scope 1 at $DIR/enum.rs:+9:28: +9:29 + _8 = ((_3 as Some).0: u8); // scope 1 at $DIR/enum.rs:+9:28: +9:29 + _6 = _8; // scope 3 at $DIR/enum.rs:+9:34: +9:35 + StorageDead(_8); // scope 1 at $DIR/enum.rs:+9:34: +9:35 + goto -> bb7; // scope 1 at $DIR/enum.rs:+9:34: +9:35 + } + + bb7: { + StorageLive(_9); // scope 2 at $DIR/enum.rs:+11:9: +11:10 + _9 = _6; // scope 2 at $DIR/enum.rs:+11:13: +11:14 + _0 = const (); // scope 0 at $DIR/enum.rs:+0:29: +12:2 + StorageDead(_9); // scope 2 at $DIR/enum.rs:+12:1: +12:2 + StorageDead(_6); // scope 1 at $DIR/enum.rs:+12:1: +12:2 + StorageDead(_3); // scope 0 at $DIR/enum.rs:+12:1: +12:2 + return; // scope 0 at $DIR/enum.rs:+12:2: +12:2 + } + } + diff --git a/tests/mir-opt/dataflow-const-prop/enum.rs b/tests/mir-opt/dataflow-const-prop/enum.rs index 7ea405bd9c4..79a20d7ef45 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.rs +++ b/tests/mir-opt/dataflow-const-prop/enum.rs @@ -46,7 +46,23 @@ fn mutate_discriminant() -> u8 { ) } +// EMIT_MIR enum.multiple.DataflowConstProp.diff +fn multiple(x: bool, i: u8) { + let e = if x { + Some(i) + } else { + None + }; + // The dataflow state must have: + // discriminant(e) => Top + // (e as Some).0 => Top + let x = match e { Some(i) => i, None => 0 }; + // Therefore, `x` should be `Top` here, and no replacement shall happen. + let y = x; +} + fn main() { simple(); mutate_discriminant(); + multiple(false, 5); } diff --git a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff index 1fb65e65845..22bdc35d694 100644 --- a/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff +++ b/tests/mir-opt/dataflow-const-prop/enum.simple.DataflowConstProp.diff @@ -45,8 +45,10 @@ bb3: { StorageLive(_4); // scope 1 at $DIR/enum.rs:+2:29: +2:30 - _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30 - _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36 +- _4 = ((_1 as V1).0: i32); // scope 1 at $DIR/enum.rs:+2:29: +2:30 +- _2 = _4; // scope 3 at $DIR/enum.rs:+2:35: +2:36 ++ _4 = const 0_i32; // scope 1 at $DIR/enum.rs:+2:29: +2:30 ++ _2 = const 0_i32; // scope 3 at $DIR/enum.rs:+2:35: +2:36 StorageDead(_4); // scope 1 at $DIR/enum.rs:+2:35: +2:36 goto -> bb4; // scope 1 at $DIR/enum.rs:+2:35: +2:36 } diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir deleted file mode 100644 index c2ea3ac502f..00000000000 --- a/tests/mir-opt/issue_41110.main.ElaborateDrops.after.mir +++ /dev/null @@ -1,70 +0,0 @@ -// MIR for `main` after ElaborateDrops - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11 - let _1: (); // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - let mut _2: S; // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - let mut _3: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 - let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 - let mut _5: bool; // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - scope 1 { - debug x => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 - } - - bb0: { - _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - StorageLive(_2); // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - _5 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - _2 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - StorageLive(_3); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 - StorageLive(_4); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 - _4 = S; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 - _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 - // mir::Constant - // + span: $DIR/issue_41110.rs:8:23: 8:25 - // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) } - } - - bb1: { - StorageDead(_4); // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 - _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 - _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 - // mir::Constant - // + span: $DIR/issue_41110.rs:8:15: 8:20 - // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) } - } - - bb2: { - StorageDead(_3); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - StorageDead(_2); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2 - StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2 - return; // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2 - } - - bb3 (cleanup): { - goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - } - - bb4 (cleanup): { - goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 - } - - bb5 (cleanup): { - goto -> bb8; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - } - - bb6 (cleanup): { - resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2 - } - - bb7 (cleanup): { - drop(_2) -> bb6; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - } - - bb8 (cleanup): { - switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 - } -} diff --git a/tests/mir-opt/issue_41110.main.ElaborateDrops.diff b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff new file mode 100644 index 00000000000..7ac75b51a37 --- /dev/null +++ b/tests/mir-opt/issue_41110.main.ElaborateDrops.diff @@ -0,0 +1,75 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:11: +0:11 + let _1: (); // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + let mut _3: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 ++ let mut _5: bool; // in scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + scope 1 { + debug x => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 + } + + bb0: { ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_2); // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 ++ _5 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _2 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_3); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + StorageLive(_4); // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _4 = S; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:22 + _3 = S::id(move _4) -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/issue_41110.rs:+1:21: +1:27 + // mir::Constant + // + span: $DIR/issue_41110.rs:8:23: 8:25 + // + literal: Const { ty: fn(S) -> S {S::id}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 + _1 = S::other(move _2, move _3) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:28 + // mir::Constant + // + span: $DIR/issue_41110.rs:8:15: 8:20 + // + literal: Const { ty: fn(S, S) {S::other}, val: Value(<ZST>) } + } + + bb2: { + StorageDead(_3); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ _5 = const false; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + StorageDead(_2); // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:11: +2:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+2:1: +2:2 + return; // scope 0 at $DIR/issue_41110.rs:+2:2: +2:2 + } + + bb3 (cleanup): { +- drop(_3) -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + + bb4 (cleanup): { +- drop(_4) -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 ++ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+1:26: +1:27 + } + + bb5 (cleanup): { +- drop(_2) -> bb6; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ goto -> bb8; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +2:2 ++ } ++ ++ bb7 (cleanup): { ++ drop(_2) -> bb6; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 ++ } ++ ++ bb8 (cleanup): { ++ switchInt(_5) -> [0: bb6, otherwise: bb7]; // scope 0 at $DIR/issue_41110.rs:+1:27: +1:28 + } + } + diff --git a/tests/mir-opt/issue_41110.rs b/tests/mir-opt/issue_41110.rs index 638dc601ec8..e1067ce53e4 100644 --- a/tests/mir-opt/issue_41110.rs +++ b/tests/mir-opt/issue_41110.rs @@ -3,14 +3,14 @@ // check that we don't emit multiple drop flags when they are not needed. -// EMIT_MIR issue_41110.main.ElaborateDrops.after.mir +// EMIT_MIR issue_41110.main.ElaborateDrops.diff fn main() { let x = S.other(S.id()); } // no_mangle to make sure this gets instantiated even in an executable. #[no_mangle] -// EMIT_MIR issue_41110.test.ElaborateDrops.after.mir +// EMIT_MIR issue_41110.test.ElaborateDrops.diff pub fn test() { let u = S; let mut v = S; diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir b/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir deleted file mode 100644 index 82989c3f071..00000000000 --- a/tests/mir-opt/issue_41110.test.ElaborateDrops.after.mir +++ /dev/null @@ -1,101 +0,0 @@ -// MIR for `test` after ElaborateDrops - -fn test() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15 - let _1: S; // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - let _3: (); // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12 - let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11 - let mut _5: S; // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10 - let mut _6: bool; // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - scope 1 { - debug u => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 - let mut _2: S; // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 - scope 2 { - debug v => _2; // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14 - } - } - - bb0: { - _6 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 - _6 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - _1 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 - StorageLive(_2); // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 - _2 = S; // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18 - StorageLive(_3); // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 - StorageLive(_4); // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 - _4 = move _2; // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 - _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 - // mir::Constant - // + span: $DIR/issue_41110.rs:17:5: 17:9 - // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) } - } - - bb1: { - StorageDead(_4); // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 - StorageDead(_3); // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13 - StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - goto -> bb12; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 - } - - bb2: { - goto -> bb3; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - } - - bb3: { - StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 - drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 - } - - bb4: { - StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 - goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - } - - bb5: { - _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2 - } - - bb6 (cleanup): { - goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - } - - bb7 (cleanup): { - goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 - } - - bb8 (cleanup): { - goto -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 - } - - bb9 (cleanup): { - goto -> bb14; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - } - - bb10 (cleanup): { - resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2 - } - - bb11 (cleanup): { - _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 - goto -> bb6; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 - } - - bb12: { - _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 - goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 - } - - bb13 (cleanup): { - drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - } - - bb14 (cleanup): { - switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 - } -} diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff new file mode 100644 index 00000000000..79e3d073be5 --- /dev/null +++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff @@ -0,0 +1,109 @@ +- // MIR for `test` before ElaborateDrops ++ // MIR for `test` after ElaborateDrops + + fn test() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41110.rs:+0:15: +0:15 + let _1: S; // in scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + let _3: (); // in scope 0 at $DIR/issue_41110.rs:+3:5: +3:12 + let mut _4: S; // in scope 0 at $DIR/issue_41110.rs:+3:10: +3:11 + let mut _5: S; // in scope 0 at $DIR/issue_41110.rs:+4:9: +4:10 ++ let mut _6: bool; // in scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + scope 1 { + debug u => _1; // in scope 1 at $DIR/issue_41110.rs:+1:9: +1:10 + let mut _2: S; // in scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 + scope 2 { + debug v => _2; // in scope 2 at $DIR/issue_41110.rs:+2:9: +2:14 + } + } + + bb0: { ++ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41110.rs:+1:9: +1:10 ++ _6 = const true; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + _1 = S; // scope 0 at $DIR/issue_41110.rs:+1:13: +1:14 + StorageLive(_2); // scope 1 at $DIR/issue_41110.rs:+2:9: +2:14 + _2 = S; // scope 1 at $DIR/issue_41110.rs:+2:17: +2:18 + StorageLive(_3); // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 + StorageLive(_4); // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _4 = move _2; // scope 2 at $DIR/issue_41110.rs:+3:10: +3:11 + _3 = std::mem::drop::<S>(move _4) -> [return: bb1, unwind: bb7]; // scope 2 at $DIR/issue_41110.rs:+3:5: +3:12 + // mir::Constant + // + span: $DIR/issue_41110.rs:17:5: 17:9 + // + literal: Const { ty: fn(S) {std::mem::drop::<S>}, val: Value(<ZST>) } + } + + bb1: { + StorageDead(_4); // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + StorageDead(_3); // scope 2 at $DIR/issue_41110.rs:+3:12: +3:13 + StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 ++ _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 +- replace(_2 <- move _5) -> [return: bb2, unwind: bb6]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ goto -> bb12; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + } + + bb2: { +- drop(_5) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 ++ goto -> bb3; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + } + + bb3: { + StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 + drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb4: { + StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 +- drop(_1) -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb5: { ++ _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2 + } + + bb6 (cleanup): { + drop(_5) -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + } + + bb7 (cleanup): { +- drop(_4) -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 ++ goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + } + + bb8 (cleanup): { +- drop(_2) -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb9; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb9 (cleanup): { +- drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb14; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb10 (cleanup): { + resume; // scope 0 at $DIR/issue_41110.rs:+0:1: +5:2 ++ } ++ ++ bb11 (cleanup): { ++ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ goto -> bb10; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ } ++ ++ bb12: { ++ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ } ++ ++ bb13 (cleanup): { ++ drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ } ++ ++ bb14 (cleanup): { ++ switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + } + diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir b/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir deleted file mode 100644 index 00504273245..00000000000 --- a/tests/mir-opt/issue_41888.main.ElaborateDrops.after.mir +++ /dev/null @@ -1,152 +0,0 @@ -// MIR for `main` after ElaborateDrops - -fn main() -> () { - let mut _0: (); // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11 - let _1: E; // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 - let mut _2: bool; // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14 - let mut _3: E; // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20 - let mut _4: K; // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19 - let mut _5: isize; // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24 - let mut _7: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - let mut _8: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - let mut _9: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - let mut _10: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - let mut _11: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - scope 1 { - debug e => _1; // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10 - scope 2 { - debug _k => _6; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 - let _6: K; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 - } - } - - bb0: { - _9 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 - _7 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 - _8 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 - StorageLive(_1); // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 - StorageLive(_2); // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 - _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 - // mir::Constant - // + span: $DIR/issue_41888.rs:8:8: 8:12 - // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) } - } - - bb1: { - switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 - } - - bb2: { - StorageLive(_3); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 - StorageLive(_4); // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 - _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 - _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 - StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - goto -> bb14; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - } - - bb3: { - goto -> bb4; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - } - - bb4: { - StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 - switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 - } - - bb5: { - StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 - _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 - _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 - _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10 - StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 - } - - bb6: { - _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 - } - - bb7: { - _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 - } - - bb8: { - StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 - goto -> bb20; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb9: { - _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - StorageDead(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2 - } - - bb10 (cleanup): { - goto -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - } - - bb11 (cleanup): { - goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb12 (cleanup): { - resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 - } - - bb13 (cleanup): { - _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - goto -> bb10; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - } - - bb14: { - _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 - } - - bb15: { - _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - goto -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb16 (cleanup): { - goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb17: { - drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb18 (cleanup): { - drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb19: { - _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb20: { - switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb21 (cleanup): { - _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } - - bb22 (cleanup): { - switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 - } -} diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff new file mode 100644 index 00000000000..257f0b1e6e8 --- /dev/null +++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff @@ -0,0 +1,158 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/issue_41888.rs:+0:11: +0:11 + let _1: E; // in scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + let mut _2: bool; // in scope 0 at $DIR/issue_41888.rs:+2:8: +2:14 + let mut _3: E; // in scope 0 at $DIR/issue_41888.rs:+3:13: +3:20 + let mut _4: K; // in scope 0 at $DIR/issue_41888.rs:+3:18: +3:19 + let mut _5: isize; // in scope 0 at $DIR/issue_41888.rs:+4:16: +4:24 ++ let mut _7: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _8: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _9: bool; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _10: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ let mut _11: isize; // in scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + scope 1 { + debug e => _1; // in scope 1 at $DIR/issue_41888.rs:+1:9: +1:10 + scope 2 { + debug _k => _6; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + let _6: K; // in scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + } + } + + bb0: { ++ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 ++ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_1); // scope 0 at $DIR/issue_41888.rs:+1:9: +1:10 + StorageLive(_2); // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + _2 = cond() -> [return: bb1, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + // mir::Constant + // + span: $DIR/issue_41888.rs:8:8: 8:12 + // + literal: Const { ty: fn() -> bool {cond}, val: Value(<ZST>) } + } + + bb1: { + switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + } + + bb2: { + StorageLive(_3); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageLive(_4); // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 + _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 + StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 +- replace(_1 <- move _3) -> [return: bb3, unwind: bb10]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ goto -> bb14; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + } + + bb3: { +- drop(_3) -> [return: bb4, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 ++ goto -> bb4; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + } + + bb4: { + StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + } + + bb5: { + StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 ++ _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10 + StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 + } + + bb7: { + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 + goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 + } + + bb8: { + StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 +- drop(_1) -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb20; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb9: { ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + StorageDead(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2 + } + + bb10 (cleanup): { + drop(_3) -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + } + + bb11 (cleanup): { +- drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb12 (cleanup): { + resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 ++ } ++ ++ bb13 (cleanup): { ++ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ goto -> bb12; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ } ++ ++ bb14: { ++ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ } ++ ++ bb15: { ++ _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb16 (cleanup): { ++ goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb17: { ++ drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb18 (cleanup): { ++ drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb19: { ++ _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb20: { ++ switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb21 (cleanup): { ++ _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ } ++ ++ bb22 (cleanup): { ++ switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + } + diff --git a/tests/mir-opt/issue_41888.rs b/tests/mir-opt/issue_41888.rs index c1046c14dbf..0f10c0a1d09 100644 --- a/tests/mir-opt/issue_41888.rs +++ b/tests/mir-opt/issue_41888.rs @@ -2,7 +2,7 @@ // check that we clear the "ADT master drop flag" even when there are // no fields to be dropped. -// EMIT_MIR issue_41888.main.ElaborateDrops.after.mir +// EMIT_MIR issue_41888.main.ElaborateDrops.diff fn main() { let e; if cond() { diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs index 3aa57d58908..8dac53c2a62 100644 --- a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs @@ -27,6 +27,8 @@ use std::any::Any; struct TheBackend; impl CodegenBackend for TheBackend { + fn locale_resource(&self) -> &'static str { "" } + fn codegen_crate<'a, 'tcx>( &self, tcx: TyCtxt<'tcx>, diff --git a/tests/run-make-fulldeps/issue-19371/foo.rs b/tests/run-make-fulldeps/issue-19371/foo.rs index 5bb38fc02af..53ec79e477b 100644 --- a/tests/run-make-fulldeps/issue-19371/foo.rs +++ b/tests/run-make-fulldeps/issue-19371/foo.rs @@ -53,6 +53,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { output_file: Some(output), output_dir: None, file_loader: None, + locale_resources: &[], lint_caps: Default::default(), parse_sess_created: None, register_lints: None, diff --git a/tests/run-make/translation/Makefile b/tests/run-make/translation/Makefile index 20e86c7f9a0..5b0b331ca46 100644 --- a/tests/run-make/translation/Makefile +++ b/tests/run-make/translation/Makefile @@ -6,8 +6,10 @@ include ../../run-make-fulldeps/tools.mk SYSROOT:=$(shell $(RUSTC) --print sysroot) FAKEROOT=$(TMPDIR)/fakeroot +RUSTC_LOG:=rustc_error_messages +export RUSTC_TRANSLATION_NO_DEBUG_ASSERT:=1 -all: normal custom sysroot +all: normal custom missing broken sysroot sysroot-invalid sysroot-missing # Check that the test works normally, using the built-in fallback bundle. normal: test.rs @@ -32,6 +34,7 @@ broken: test.rs broken.ftl # identifier by making a local copy of the sysroot and adding the custom locale # to it. sysroot: test.rs working.ftl + rm -rf $(FAKEROOT) mkdir $(FAKEROOT) ln -s $(SYSROOT)/* $(FAKEROOT) rm -f $(FAKEROOT)/lib @@ -51,12 +54,12 @@ sysroot: test.rs working.ftl # found. This test might start failing if there actually exists a Klingon # translation of rustc's error messages. sysroot-missing: - $(RUSTC) $< -Ztranslate-lang=tlh 2>&1 || grep "missing locale directory" + $(RUSTC) $< -Ztranslate-lang=tlh 2>&1 | grep "missing locale directory" -# Check that the compiler errors out when the sysroot requested cannot be -# found. This test might start failing if there actually exists a Klingon -# translation of rustc's error messages. +# Check that the compiler errors out when the directory for the locale in the +# sysroot is actually a file. sysroot-invalid: test.rs working.ftl + rm -rf $(FAKEROOT) mkdir $(FAKEROOT) ln -s $(SYSROOT)/* $(FAKEROOT) rm -f $(FAKEROOT)/lib @@ -68,5 +71,6 @@ sysroot-invalid: test.rs working.ftl rm -f $(FAKEROOT)/lib/rustlib/src mkdir $(FAKEROOT)/lib/rustlib/src ln -s $(SYSROOT)/lib/rustlib/src/* $(FAKEROOT)/lib/rustlib/src - touch $(FAKEROOT)/share/locale/zh-CN/ - $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 || grep "`\$sysroot/share/locales/\$locale` is not a directory" + mkdir -p $(FAKEROOT)/share/locale + touch $(FAKEROOT)/share/locale/zh-CN + $(RUSTC) $< --sysroot $(FAKEROOT) -Ztranslate-lang=zh-CN 2>&1 | grep "`\$sysroot/share/locales/\$locale` is not a directory" diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml index 5f4c1ba2f85..6e2321a6963 100644 --- a/tests/rustdoc-gui/help-page.goml +++ b/tests/rustdoc-gui/help-page.goml @@ -68,5 +68,4 @@ size: (1000, 1000) // Popover only appears when the screen width is >700px. assert-false: "#help" click: "#help-button > a" click: ".popover a[href='https://doc.rust-lang.org/rustdoc/']" -wait-for: 2000 -assert-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"} +wait-for-document-property: {"URL": "https://doc.rust-lang.org/rustdoc/"} diff --git a/tests/rustdoc-ui/auxiliary/panic-handler.rs b/tests/rustdoc-ui/auxiliary/panic-handler.rs new file mode 100644 index 00000000000..0aaaeee1051 --- /dev/null +++ b/tests/rustdoc-ui/auxiliary/panic-handler.rs @@ -0,0 +1,9 @@ +// compile-flags: -C panic=abort + +#![no_std] +#![no_main] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/rustdoc-ui/issue-107918.rs b/tests/rustdoc-ui/issue-107918.rs new file mode 100644 index 00000000000..13788df0fc9 --- /dev/null +++ b/tests/rustdoc-ui/issue-107918.rs @@ -0,0 +1,12 @@ +// aux-build:panic-handler.rs +// compile-flags: --document-private-items +// build-pass +// ignore-windows + +#![no_std] +#![no_main] + +#[panic_handler] +fn panic(_: &core::panic::PanicInfo) -> ! { + loop {} +} diff --git a/tests/rustdoc-ui/proc_macro_bug.rs b/tests/rustdoc-ui/proc_macro_bug.rs new file mode 100644 index 00000000000..e384e4863ad --- /dev/null +++ b/tests/rustdoc-ui/proc_macro_bug.rs @@ -0,0 +1,12 @@ +// regression test for failing to pass `--crate-type proc-macro` to rustdoc +// when documenting a proc macro crate https://github.com/rust-lang/rust/pull/107291 + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(DeriveA)] +//~^ ERROR the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type +pub fn a_derive(input: TokenStream) -> TokenStream { + input +} diff --git a/tests/rustdoc-ui/proc_macro_bug.stderr b/tests/rustdoc-ui/proc_macro_bug.stderr new file mode 100644 index 00000000000..5b048097c49 --- /dev/null +++ b/tests/rustdoc-ui/proc_macro_bug.stderr @@ -0,0 +1,8 @@ +error: the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type + --> $DIR/proc_macro_bug.rs:8:1 + | +LL | #[proc_macro_derive(DeriveA)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr index a16b5b6eb2f..72f35cb9224 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.stderr +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/unable-fulfill-trait.rs:4:17 | LL | field1: dyn Bar<'a, 'b,>, diff --git a/tests/rustdoc-ui/z-help.stdout b/tests/rustdoc-ui/z-help.stdout index 8d0155151b8..6aa9785f44e 100644 --- a/tests/rustdoc-ui/z-help.stdout +++ b/tests/rustdoc-ui/z-help.stdout @@ -1,76 +1,76 @@ - -Z allow-features=val -- only allow the listed language features to be enabled in code (comma separated) - -Z always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no) - -Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no) - -Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`. - -Z assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no) - -Z binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no) - -Z box-noalias=val -- emit noalias metadata for box (default: yes) - -Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64 - -Z cf-protection=val -- instrument control-flow architecture protection - -Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use - -Z codegen-backend=val -- the backend to use - -Z combine-cgu=val -- combine CGUs into a single one - -Z crate-attr=val -- inject the given attribute in the crate - -Z debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO - -Z debug-macros=val -- emit line numbers debug info inside macros (default: no) - -Z deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes) - -Z dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no) - -Z dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no) - -Z diagnostic-width=val -- set the current output width for diagnostic truncation - -Z dlltool=val -- import library generation tool (windows-gnu only) - -Z dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no) - -Z drop-tracking=val -- enables drop tracking in generators (default: no) - -Z drop-tracking-mir=val -- enables drop tracking on MIR in generators (default: no) - -Z dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no) - -Z dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no) - -Z dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no) - -Z dump-mir=val -- dump MIR state to file. + -Z allow-features=val -- only allow the listed language features to be enabled in code (comma separated) + -Z always-encode-mir=val -- encode MIR of all functions into the crate metadata (default: no) + -Z asm-comments=val -- generate comments into the assembly (may change behavior) (default: no) + -Z assert-incr-state=val -- assert that the incremental cache is in given state: either `loaded` or `not-loaded`. + -Z assume-incomplete-release=val -- make cfg(version) treat the current version as incomplete (default: no) + -Z binary-dep-depinfo=val -- include artifacts (sysroot, crate dependencies) used during compilation in dep-info (default: no) + -Z box-noalias=val -- emit noalias metadata for box (default: yes) + -Z branch-protection=val -- set options for branch target identification and pointer authentication on AArch64 + -Z cf-protection=val -- instrument control-flow architecture protection + -Z cgu-partitioning-strategy=val -- the codegen unit partitioning strategy to use + -Z codegen-backend=val -- the backend to use + -Z combine-cgu=val -- combine CGUs into a single one + -Z crate-attr=val -- inject the given attribute in the crate + -Z debug-info-for-profiling=val -- emit discriminators and other data necessary for AutoFDO + -Z debug-macros=val -- emit line numbers debug info inside macros (default: no) + -Z deduplicate-diagnostics=val -- deduplicate identical diagnostics (default: yes) + -Z dep-info-omit-d-target=val -- in dep-info output, omit targets for tracking dependencies of the dep-info files themselves (default: no) + -Z dep-tasks=val -- print tasks that execute and the color their dep node gets (requires debug build) (default: no) + -Z diagnostic-width=val -- set the current output width for diagnostic truncation + -Z dlltool=val -- import library generation tool (windows-gnu only) + -Z dont-buffer-diagnostics=val -- emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) (default: no) + -Z drop-tracking=val -- enables drop tracking in generators (default: no) + -Z drop-tracking-mir=val -- enables drop tracking on MIR in generators (default: no) + -Z dual-proc-macros=val -- load proc macros for both target and host, but only link to the target (default: no) + -Z dump-dep-graph=val -- dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) (default: no) + -Z dump-drop-tracking-cfg=val -- dump drop-tracking control-flow graph as a `.dot` file (default: no) + -Z dump-mir=val -- dump MIR state to file. `val` is used to select which passes and functions to dump. For example: `all` matches all passes and functions, `foo` matches all passes for functions whose name contains 'foo', `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo', `foo | bar` all passes for function names containing 'foo' or 'bar'. - -Z dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no) - -Z dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`) - -Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no) - -Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no) - -Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans. - -Z dump-mono-stats=val -- output statistics about monomorphization collection - -Z dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`) - -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) - -Z dylib-lto=val -- enables LTO for dylib crate type - -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) - -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) - -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries - -Z extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no) - -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) - -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) - -Z fuel=val -- set the optimization fuel quota for a crate - -Z function-sections=val -- whether each function should go in its own section - -Z future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no) - -Z gcc-ld=val -- implementation of ld used by cc - -Z graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no) - -Z graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`) - -Z hir-stats=val -- print some statistics about AST and HIR (default: no) - -Z human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no) - -Z identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no) - -Z incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no) - -Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no) - -Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no) - -Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no) - -Z inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs - -Z inline-llvm=val -- enable LLVM inlining (default: yes) - -Z inline-mir=val -- enable MIR inlining (default: no) - -Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100) - -Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50) - -Z input-stats=val -- gather statistics about the input (default: no) - -Z instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: + -Z dump-mir-dataflow=val -- in addition to `.mir` files, create graphviz `.dot` files with dataflow results (default: no) + -Z dump-mir-dir=val -- the directory the MIR is dumped into (default: `mir_dump`) + -Z dump-mir-exclude-pass-number=val -- exclude the pass number when dumping MIR (used in tests) (default: no) + -Z dump-mir-graphviz=val -- in addition to `.mir` files, create graphviz `.dot` files (and with `-Z instrument-coverage`, also create a `.dot` file for the MIR-derived coverage graph) (default: no) + -Z dump-mir-spanview=val -- in addition to `.mir` files, create `.html` files to view spans for all `statement`s (including terminators), only `terminator` spans, or computed `block` spans (one span encompassing a block's terminator and all statements). If `-Z instrument-coverage` is also enabled, create an additional `.html` file showing the computed coverage spans. + -Z dump-mono-stats=val -- output statistics about monomorphization collection + -Z dump-mono-stats-format=val -- the format to use for -Z dump-mono-stats (`markdown` (default) or `json`) + -Z dwarf-version=val -- version of DWARF debug information to emit (default: 2 or 4, depending on platform) + -Z dylib-lto=val -- enables LTO for dylib crate type + -Z emit-stack-sizes=val -- emit a section containing stack size metadata (default: no) + -Z emit-thin-lto=val -- emit the bc module with thin LTO info (default: yes) + -Z export-executable-symbols=val -- export symbols from executables, as if they were dynamic libraries + -Z extra-const-ub-checks=val -- turns on more checks to detect const UB, which can be slow (default: no) + -Z fewer-names=val -- reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) (default: no) + -Z force-unstable-if-unmarked=val -- force all crates to be `rustc_private` unstable (default: no) + -Z fuel=val -- set the optimization fuel quota for a crate + -Z function-sections=val -- whether each function should go in its own section + -Z future-incompat-test=val -- forces all lints to be future incompatible, used for internal testing (default: no) + -Z gcc-ld=val -- implementation of ld used by cc + -Z graphviz-dark-mode=val -- use dark-themed colors in graphviz output (default: no) + -Z graphviz-font=val -- use the given `fontname` in graphviz output; can be overridden by setting environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`) + -Z hir-stats=val -- print some statistics about AST and HIR (default: no) + -Z human-readable-cgu-names=val -- generate human-readable, predictable names for codegen units (default: no) + -Z identify-regions=val -- display unnamed regions as `'<id>`, using a non-ident unique id (default: no) + -Z incremental-ignore-spans=val -- ignore spans during ICH computation -- used for testing (default: no) + -Z incremental-info=val -- print high-level information about incremental reuse (or the lack thereof) (default: no) + -Z incremental-relative-spans=val -- hash spans relative to their parent item for incr. comp. (default: no) + -Z incremental-verify-ich=val -- verify incr. comp. hashes of green query instances (default: no) + -Z inline-in-all-cgus=val -- control whether `#[inline]` functions are in all CGUs + -Z inline-llvm=val -- enable LLVM inlining (default: yes) + -Z inline-mir=val -- enable MIR inlining (default: no) + -Z inline-mir-hint-threshold=val -- inlining threshold for functions with inline hint (default: 100) + -Z inline-mir-threshold=val -- a default MIR inlining threshold (default: 50) + -Z input-stats=val -- gather statistics about the input (default: no) + -Z instrument-coverage=val -- instrument the generated code to support LLVM source-based code coverage reports (note, the compiler build config must include `profiler = true`); implies `-C symbol-mangling-version=v0`. Optional values are: `=all` (implicit value) `=except-unused-generics` `=except-unused-functions` `=off` (default) - -Z instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no) - -Z instrument-xray=val -- insert function instrument code for XRay-based tracing (default: no) + -Z instrument-mcount=val -- insert function instrument code for mcount-based tracing (default: no) + -Z instrument-xray=val -- insert function instrument code for XRay-based tracing (default: no) Optional extra settings: `=always` `=never` @@ -79,125 +79,125 @@ `=skip-entry` `=skip-exit` Multiple options can be combined with commas. - -Z keep-hygiene-data=val -- keep hygiene data after analysis (default: no) - -Z layout-seed=val -- seed layout randomization - -Z link-native-libraries=val -- link native libraries in the linker invocation (default: yes) - -Z link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no) - -Z llvm-plugins=val -- a list LLVM plugins to enable (space separated) - -Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no) - -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) - -Z ls=val -- list the symbols defined by a library crate (default: no) - -Z macro-backtrace=val -- show macro backtraces (default: no) - -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) - -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name - -Z meta-stats=val -- gather metadata statistics (default: no) - -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) - -Z mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual. - -Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds) - -Z mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing - -Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted - -Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes) - -Z nll-facts=val -- dump facts from NLL analysis into side files (default: no) - -Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`) - -Z no-analysis=val -- parse and expand the source, but run no analysis - -Z no-codegen=val -- run all passes except codegen; no output - -Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups - -Z no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering - -Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests - -Z no-link=val -- compile without linking - -Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO) - -Z no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate - -Z no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used - -Z normalize-docs=val -- normalize associated items in rustdoc when generating documentation - -Z oom=val -- panic strategy for out-of-memory handling - -Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no) - -Z packed-bundled-libs=val -- change rlib format to store native libraries as archives - -Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no) - -Z panic-in-drop=val -- panic strategy for panics in drops - -Z parse-only=val -- parse only; do not compile, assemble, or link (default: no) - -Z perf-stats=val -- print some performance-related statistics (default: no) - -Z pick-stable-methods-before-any-unstable=val -- try to pick stable methods first before picking any unstable methods (default: yes) - -Z plt=val -- whether to use the PLT when calling into shared libraries; + -Z keep-hygiene-data=val -- keep hygiene data after analysis (default: no) + -Z layout-seed=val -- seed layout randomization + -Z link-directives=val -- honor #[link] directives in the compiled crate (default: yes) + -Z link-native-libraries=val -- link native libraries in the linker invocation (default: yes) + -Z link-only=val -- link the `.rlink` file generated by `-Z no-link` (default: no) + -Z llvm-plugins=val -- a list LLVM plugins to enable (space separated) + -Z llvm-time-trace=val -- generate JSON tracing data file from LLVM data (default: no) + -Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`) + -Z ls=val -- list the symbols defined by a library crate (default: no) + -Z macro-backtrace=val -- show macro backtraces (default: no) + -Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no) + -Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name + -Z meta-stats=val -- gather metadata statistics (default: no) + -Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no) + -Z mir-enable-passes=val -- use like `-Zmir-enable-passes=+DestProp,-InstCombine`. Forces the specified passes to be enabled, overriding all other checks. Passes that are not specified are enabled or disabled by other flags as usual. + -Z mir-opt-level=val -- MIR optimization level (0-4; default: 1 in non optimized builds and 2 in optimized builds) + -Z mir-pretty-relative-line-numbers=val -- use line numbers relative to the function in mir pretty printing + -Z move-size-limit=val -- the size at which the `large_assignments` lint starts to be emitted + -Z mutable-noalias=val -- emit noalias metadata for mutable references (default: yes) + -Z nll-facts=val -- dump facts from NLL analysis into side files (default: no) + -Z nll-facts-dir=val -- the directory the NLL facts are dumped into (default: `nll-facts`) + -Z no-analysis=val -- parse and expand the source, but run no analysis + -Z no-codegen=val -- run all passes except codegen; no output + -Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups + -Z no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering + -Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests + -Z no-link=val -- compile without linking + -Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO) + -Z no-profiler-runtime=val -- prevent automatic injection of the profiler_builtins crate + -Z no-unique-section-names=val -- do not use unique names for text and data sections when -Z function-sections is used + -Z normalize-docs=val -- normalize associated items in rustdoc when generating documentation + -Z oom=val -- panic strategy for out-of-memory handling + -Z osx-rpath-install-name=val -- pass `-install_name @rpath/...` to the macOS linker (default: no) + -Z packed-bundled-libs=val -- change rlib format to store native libraries as archives + -Z panic-abort-tests=val -- support compiling tests with panic=abort (default: no) + -Z panic-in-drop=val -- panic strategy for panics in drops + -Z parse-only=val -- parse only; do not compile, assemble, or link (default: no) + -Z perf-stats=val -- print some performance-related statistics (default: no) + -Z plt=val -- whether to use the PLT when calling into shared libraries; only has effect for PIC code on systems with ELF binaries (default: PLT is disabled if full relro is enabled) - -Z polonius=val -- enable polonius-based borrow-checker (default: no) - -Z polymorphize=val -- perform polymorphization analysis - -Z pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times) - -Z pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated) - -Z precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551. - -Z print-fuel=val -- make rustc print the total optimization fuel used by a crate - -Z print-llvm-passes=val -- print the LLVM optimization passes being run (default: no) - -Z print-mono-items=val -- print the result of the monomorphization collection pass - -Z print-type-sizes=val -- print layout information for each type encountered (default: no) - -Z proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no) - -Z proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread) - -Z profile=val -- insert profiling code (default: no) - -Z profile-closures=val -- profile size of closures - -Z profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path) - -Z profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO) - -Z profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`) - -Z query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no) - -Z randomize-layout=val -- randomize the layout of types (default: no) - -Z relax-elf-relocations=val -- whether ELF relocations can be relaxed - -Z relro-level=val -- choose which RELRO level to use - -Z remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix - -Z report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no) - -Z sanitizer=val -- use a sanitizer - -Z sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer - -Z sanitizer-recover=val -- enable recovery for selected sanitizers - -Z saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes) - -Z self-profile=val -- run the self profiler and output the raw event data - -Z self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of: + -Z polonius=val -- enable polonius-based borrow-checker (default: no) + -Z polymorphize=val -- perform polymorphization analysis + -Z pre-link-arg=val -- a single extra argument to prepend the linker invocation (can be used several times) + -Z pre-link-args=val -- extra arguments to prepend to the linker invocation (space separated) + -Z precise-enum-drop-elaboration=val -- use a more precise version of drop elaboration for matches on enums (default: yes). This results in better codegen, but has caused miscompilations on some tier 2 platforms. See #77382 and #74551. + -Z print-fuel=val -- make rustc print the total optimization fuel used by a crate + -Z print-llvm-passes=val -- print the LLVM optimization passes being run (default: no) + -Z print-mono-items=val -- print the result of the monomorphization collection pass + -Z print-type-sizes=val -- print layout information for each type encountered (default: no) + -Z proc-macro-backtrace=val -- show backtraces for panics during proc-macro execution (default: no) + -Z proc-macro-execution-strategy=val -- how to run proc-macro code (default: same-thread) + -Z profile=val -- insert profiling code (default: no) + -Z profile-closures=val -- profile size of closures + -Z profile-emit=val -- file path to emit profiling data at runtime when using 'profile' (default based on relative source path) + -Z profile-sample-use=val -- use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO) + -Z profiler-runtime=val -- name of the profiler runtime crate to automatically inject (default: `profiler_builtins`) + -Z query-dep-graph=val -- enable queries of the dependency graph for regression testing (default: no) + -Z randomize-layout=val -- randomize the layout of types (default: no) + -Z relax-elf-relocations=val -- whether ELF relocations can be relaxed + -Z relro-level=val -- choose which RELRO level to use + -Z remap-cwd-prefix=val -- remap paths under the current working directory to this path prefix + -Z report-delayed-bugs=val -- immediately print bugs registered with `delay_span_bug` (default: no) + -Z sanitizer=val -- use a sanitizer + -Z sanitizer-memory-track-origins=val -- enable origins tracking in MemorySanitizer + -Z sanitizer-recover=val -- enable recovery for selected sanitizers + -Z saturating-float-casts=val -- make float->int casts UB-free: numbers outside the integer type's range are clipped to the max/min integer respectively, and NaN is mapped to 0 (default: yes) + -Z self-profile=val -- run the self profiler and output the raw event data + -Z self-profile-counter=val -- counter used by the self profiler (default: `wall-time`), one of: `wall-time` (monotonic clock, i.e. `std::time::Instant`) `instructions:u` (retired instructions, userspace-only) `instructions-minus-irqs:u` (subtracting hardware interrupt counts for extra accuracy) - -Z self-profile-events=val -- specify the events recorded by the self profiler; + -Z self-profile-events=val -- specify the events recorded by the self profiler; for example: `-Z self-profile-events=default,query-keys` all options: none, all, default, generic-activity, query-provider, query-cache-hit query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes - -Z share-generics=val -- make the current crate share its generic instantiations - -Z show-span=val -- show spans for compiler debugging (expr|pat|ty) - -Z simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes - -Z span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span` - -Z span-free-formats=val -- exclude spans when debug-printing compiler state (default: no) - -Z split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF - -Z split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) + -Z share-generics=val -- make the current crate share its generic instantiations + -Z show-span=val -- show spans for compiler debugging (expr|pat|ty) + -Z simulate-remapped-rust-src-base=val -- simulate the effect of remap-debuginfo = true at bootstrapping by remapping path to rust's source base directory. only meant for testing purposes + -Z span-debug=val -- forward proc_macro::Span's `Debug` impl to `Span` + -Z span-free-formats=val -- exclude spans when debug-printing compiler state (default: no) + -Z split-dwarf-inlining=val -- provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF + -Z split-dwarf-kind=val -- split dwarf variant (only if -Csplit-debuginfo is enabled and on relevant platform) (default: `split`) `split`: sections which do not require relocation are written into a DWARF object (`.dwo`) file which is ignored by the linker `single`: sections which do not require relocation are written into object file but ignored by the linker - -Z src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`) - -Z stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details) - -Z strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB - -Z strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) - -Z symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') - -Z teach=val -- show extended diagnostic help (default: no) - -Z temps-dir=val -- the directory the intermediate files are written to - -Z terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output - -Z thinlto=val -- enable ThinLTO when possible - -Z thir-unsafeck=val -- use the THIR unsafety checker (default: no) - -Z threads=val -- use a thread pool with N threads - -Z time-llvm-passes=val -- measure time of each LLVM pass (default: no) - -Z time-passes=val -- measure time of each rustc pass (default: no) - -Z tiny-const-eval-limit=val -- sets a tiny, non-configurable limit for const eval; useful for compiler tests - -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) - -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) - -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted - -Z trait-solver=val -- specify the trait solver mode used by rustc (default: classic) - -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) - -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics - -Z translate-lang=val -- language identifier for diagnostic output - -Z translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes) - -Z trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes) - -Z treat-err-as-bug=val -- treat error number `val` that occurs as bug - -Z trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items - -Z tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details) - -Z ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no) - -Z uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16) - -Z unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no) - -Z unpretty=val -- present the input source, unstable (and less-pretty) variants; + -Z src-hash-algorithm=val -- hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`) + -Z stack-protector=val -- control stack smash protection strategy (`rustc --print stack-protector-strategies` for details) + -Z strict-init-checks=val -- control if mem::uninitialized and mem::zeroed panic on more UB + -Z strip=val -- tell the linker which information to strip (`none` (default), `debuginfo` or `symbols`) + -Z symbol-mangling-version=val -- which mangling version to use for symbol names ('legacy' (default) or 'v0') + -Z teach=val -- show extended diagnostic help (default: no) + -Z temps-dir=val -- the directory the intermediate files are written to + -Z terminal-urls=val -- use the OSC 8 hyperlink terminal specification to print hyperlinks in the compiler output + -Z thinlto=val -- enable ThinLTO when possible + -Z thir-unsafeck=val -- use the THIR unsafety checker (default: no) + -Z threads=val -- use a thread pool with N threads + -Z time-llvm-passes=val -- measure time of each LLVM pass (default: no) + -Z time-passes=val -- measure time of each rustc pass (default: no) + -Z tiny-const-eval-limit=val -- sets a tiny, non-configurable limit for const eval; useful for compiler tests + -Z tls-model=val -- choose the TLS model to use (`rustc --print tls-models` for details) + -Z trace-macros=val -- for every macro invocation, print its name and arguments (default: no) + -Z track-diagnostics=val -- tracks where in rustc a diagnostic was emitted + -Z trait-solver=val -- specify the trait solver mode used by rustc (default: classic) + -Z translate-additional-ftl=val -- additional fluent translation to preferentially use (for testing translation) + -Z translate-directionality-markers=val -- emit directionality isolation markers in translated diagnostics + -Z translate-lang=val -- language identifier for diagnostic output + -Z translate-remapped-path-to-local-path=val -- translate remapped paths into local paths when possible (default: yes) + -Z trap-unreachable=val -- generate trap instructions for unreachable intrinsics (default: use target setting, usually yes) + -Z treat-err-as-bug=val -- treat error number `val` that occurs as bug + -Z trim-diagnostic-paths=val -- in diagnostics, use heuristics to shorten paths referring to items + -Z tune-cpu=val -- select processor to schedule for (`rustc --print target-cpus` for details) + -Z ui-testing=val -- emit compiler diagnostics in a form suitable for UI testing (default: no) + -Z uninit-const-chunk-threshold=val -- allow generating const initializers with mixed init/uninit chunks, and set the maximum number of chunks for which this is allowed (default: 16) + -Z unleash-the-miri-inside-of-you=val -- take the brakes off const evaluation. NOTE: this is unsound (default: no) + -Z unpretty=val -- present the input source, unstable (and less-pretty) variants; `normal`, `identified`, `expanded`, `expanded,identified`, `expanded,hygiene` (with internal representations), @@ -207,11 +207,11 @@ `hir,typed` (HIR with types for each node), `hir-tree` (dump the raw HIR), `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR) - -Z unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no) - -Z unstable-options=val -- adds unstable command line options to rustc interface (default: no) - -Z use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array - -Z validate-mir=val -- validate MIR after each transformation - -Z verbose=val -- in general, enable more debug printouts (default: no) - -Z verify-llvm-ir=val -- verify LLVM IR (default: no) - -Z virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]` - -Z wasi-exec-model=val -- whether to build a wasi command or reactor + -Z unsound-mir-opts=val -- enable unsound and buggy MIR optimizations (default: no) + -Z unstable-options=val -- adds unstable command line options to rustc interface (default: no) + -Z use-ctors-section=val -- use legacy .ctors section for initializers rather than .init_array + -Z validate-mir=val -- validate MIR after each transformation + -Z verbose=val -- in general, enable more debug printouts (default: no) + -Z verify-llvm-ir=val -- verify LLVM IR (default: no) + -Z virtual-function-elimination=val -- enables dead virtual function elimination optimization. Requires `-Clto[=[fat,yes]]` + -Z wasi-exec-model=val -- whether to build a wasi command or reactor diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc/intra-doc/basic.rs index e2d3ef425cb..96e21137b2d 100644 --- a/tests/rustdoc/intra-doc/basic.rs +++ b/tests/rustdoc/intra-doc/basic.rs @@ -2,7 +2,9 @@ // @has - '//a/@href' 'struct.ThisType.html' // @has - '//a/@title' 'struct basic::ThisType' // @has - '//a/@href' 'struct.ThisType.html#method.this_method' -// @has - '//a/@title' 'associated function basic::ThisType::this_method' +// @has - '//a/@title' 'method basic::ThisType::this_method' +// @has - '//a/@href' 'struct.ThisType.html#method.this_assoc_fn' +// @has - '//a/@title' 'associated function basic::ThisType::this_assoc_fn' // @has - '//a/@href' 'enum.ThisEnum.html' // @has - '//a/@title' 'enum basic::ThisEnum' // @has - '//a/@href' 'enum.ThisEnum.html#variant.ThisVariant' @@ -10,7 +12,9 @@ // @has - '//a/@href' 'trait.ThisTrait.html' // @has - '//a/@title' 'trait basic::ThisTrait' // @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_method' -// @has - '//a/@title' 'associated function basic::ThisTrait::this_associated_method' +// @has - '//a/@title' 'method basic::ThisTrait::this_associated_method' +// @has - '//a/@href' 'trait.ThisTrait.html#tymethod.this_associated_fn' +// @has - '//a/@title' 'associated function basic::ThisTrait::this_associated_fn' // @has - '//a/@href' 'trait.ThisTrait.html#associatedtype.ThisAssociatedType' // @has - '//a/@title' 'associated type basic::ThisTrait::ThisAssociatedType' // @has - '//a/@href' 'trait.ThisTrait.html#associatedconstant.THIS_ASSOCIATED_CONST' @@ -37,11 +41,13 @@ //! //! * [`ThisType`](ThisType) //! * [`ThisType::this_method`](ThisType::this_method) +//! * [`ThisType::this_assoc_fn`](ThisType::this_assoc_fn) //! * [`ThisEnum`](ThisEnum) //! * [`ThisEnum::ThisVariant`](ThisEnum::ThisVariant) //! * [`ThisEnum::ThisVariantCtor`](ThisEnum::ThisVariantCtor) //! * [`ThisTrait`](ThisTrait) //! * [`ThisTrait::this_associated_method`](ThisTrait::this_associated_method) +//! * [`ThisTrait::this_associated_fn`](ThisTrait::this_associated_fn) //! * [`ThisTrait::ThisAssociatedType`](ThisTrait::ThisAssociatedType) //! * [`ThisTrait::THIS_ASSOCIATED_CONST`](ThisTrait::THIS_ASSOCIATED_CONST) //! * [`ThisAlias`](ThisAlias) @@ -68,13 +74,15 @@ macro_rules! this_macro { pub struct ThisType; impl ThisType { - pub fn this_method() {} + pub fn this_assoc_fn() {} + pub fn this_method(self) {} } pub enum ThisEnum { ThisVariant, ThisVariantCtor(u32), } pub trait ThisTrait { type ThisAssociatedType; const THIS_ASSOCIATED_CONST: u8; - fn this_associated_method(); + fn this_associated_fn(); + fn this_associated_method(&self); } pub type ThisAlias = Result<(), ()>; pub union ThisUnion { this_field: usize, } diff --git a/tests/rustdoc/issue-108281.rs b/tests/rustdoc/issue-108281.rs new file mode 100644 index 00000000000..8e1b6ba88a6 --- /dev/null +++ b/tests/rustdoc/issue-108281.rs @@ -0,0 +1,25 @@ +// Regression test for <https://github.com/rust-lang/rust/issues/108281>. +// It ensures that the attributes on the first reexport are not duplicated. + +#![crate_name = "foo"] + +// @has 'foo/index.html' + +#[doc(hidden)] +pub fn bar() {} +mod sub { + pub fn public() {} +} + +// @matches - '//*[@class="desc docblock-short"]' '^Displayed$' +/// Displayed +#[doc(inline)] +pub use crate::bar as Bar; +// @matches - '//*[@class="desc docblock-short"]' '^Hello\sDisplayed$' +#[doc(inline)] +/// Hello +pub use crate::Bar as Bar2; + +// @matches - '//*[@class="desc docblock-short"]' '^Public$' +/// Public +pub use crate::sub::public as Public; diff --git a/tests/rustdoc/item-desc-list-at-start.item-table.html b/tests/rustdoc/item-desc-list-at-start.item-table.html new file mode 100644 index 00000000000..72bde573cea --- /dev/null +++ b/tests/rustdoc/item-desc-list-at-start.item-table.html @@ -0,0 +1 @@ +<ul class="item-table"><li><div class="item-name"><a class="constant" href="constant.MY_CONSTANT.html" title="constant item_desc_list_at_start::MY_CONSTANT">MY_CONSTANT</a></div><div class="desc docblock-short">Groups: <code>SamplePatternSGIS</code>, <code>SamplePatternEXT</code></div></li></ul> \ No newline at end of file diff --git a/tests/rustdoc/item-desc-list-at-start.rs b/tests/rustdoc/item-desc-list-at-start.rs new file mode 100644 index 00000000000..d88c61d333e --- /dev/null +++ b/tests/rustdoc/item-desc-list-at-start.rs @@ -0,0 +1,9 @@ +// @has item_desc_list_at_start/index.html +// @count - '//ul[@class="item-table"]/li/div/li' 0 +// @count - '//ul[@class="item-table"]/li' 1 +// @snapshot item-table - '//ul[@class="item-table"]' + +// based on https://docs.rs/gl_constants/0.1.1/src/gl_constants/lib.rs.html#16 + +/// * Groups: `SamplePatternSGIS`, `SamplePatternEXT` +pub const MY_CONSTANT: usize = 0; diff --git a/tests/rustdoc/reexports-of-same-name.rs b/tests/rustdoc/reexports-of-same-name.rs new file mode 100644 index 00000000000..fe6f1b38ca6 --- /dev/null +++ b/tests/rustdoc/reexports-of-same-name.rs @@ -0,0 +1,26 @@ +// This test ensures that there are 4 imports as expected: +// * 2 for `Foo` +// * 2 for `Bar` + +#![crate_name = "foo"] + +// @has 'foo/index.html' + +pub mod nested { + /// Foo the struct + pub struct Foo {} + + #[allow(non_snake_case)] + /// Foo the function + pub fn Foo() {} +} + +// @count - '//*[@id="main-content"]//code' 'pub use nested::Foo;' 2 +// @has - '//*[@id="reexport.Foo"]//a[@href="nested/struct.Foo.html"]' 'Foo' +// @has - '//*[@id="reexport.Foo-1"]//a[@href="nested/fn.Foo.html"]' 'Foo' +pub use nested::Foo; + +// @count - '//*[@id="main-content"]//code' 'pub use Foo as Bar;' 2 +// @has - '//*[@id="reexport.Bar"]//a[@href="nested/struct.Foo.html"]' 'Foo' +// @has - '//*[@id="reexport.Bar-1"]//a[@href="nested/fn.Foo.html"]' 'Foo' +pub use Foo as Bar; diff --git a/tests/ui-fulldeps/create-dir-all-bare.rs b/tests/ui-fulldeps/create-dir-all-bare.rs deleted file mode 100644 index 4554680ec24..00000000000 --- a/tests/ui-fulldeps/create-dir-all-bare.rs +++ /dev/null @@ -1,11 +0,0 @@ -// run-pass - -use std::env; -use std::fs; -use std::path::PathBuf; - -fn main() { - let path = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - env::set_current_dir(&path).unwrap(); - fs::create_dir_all("create-dir-all-bare").unwrap(); -} diff --git a/tests/ui-fulldeps/fluent-messages/duplicate.ftl b/tests/ui-fulldeps/fluent-messages/duplicate.ftl new file mode 100644 index 00000000000..871550b231a --- /dev/null +++ b/tests/ui-fulldeps/fluent-messages/duplicate.ftl @@ -0,0 +1,3 @@ +no_crate_a_b_key = Value + +no_crate_a_b_key = Another Value diff --git a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl index 016cbeef662..3088b1f8dc8 100644 --- a/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl +++ b/tests/ui-fulldeps/fluent-messages/label-with-hyphens.ftl @@ -1,2 +1,2 @@ -label_with_hyphens_some_slug = hi +no_crate_some_slug = hi .label-has-hyphens = test diff --git a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl index 9bd035c1bba..0a64e3894bd 100644 --- a/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl +++ b/tests/ui-fulldeps/fluent-messages/missing-crate-name.ftl @@ -1,2 +1,2 @@ with-hyphens = 1234 -test-crate_foo = abcd +no-crate_foo = abcd diff --git a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl index 0cd8229b230..4c6514a9770 100644 --- a/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl +++ b/tests/ui-fulldeps/fluent-messages/missing-message-ref.ftl @@ -1 +1 @@ -missing_message_ref = {message} +no_crate_missing_message_ref = {message} diff --git a/tests/ui-fulldeps/fluent-messages/missing-message.ftl b/tests/ui-fulldeps/fluent-messages/missing-message.ftl index 74b2aa1d44d..61f56fd4d57 100644 --- a/tests/ui-fulldeps/fluent-messages/missing-message.ftl +++ b/tests/ui-fulldeps/fluent-messages/missing-message.ftl @@ -1 +1 @@ -missing_message = +no_crate_missing_message = diff --git a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl index 86ba9a268f3..a64c85094f1 100644 --- a/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl +++ b/tests/ui-fulldeps/fluent-messages/slug-with-hyphens.ftl @@ -1 +1 @@ -slug_with_hyphens_this-slug-has-hyphens = hi +no_crate_this-slug-has-hyphens = hi diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 74303e97dba..66575eb8e30 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -21,87 +21,74 @@ pub enum SubdiagnosticMessage { mod missing_absolute { use super::fluent_messages; - fluent_messages! { - missing_absolute => "/definitely_does_not_exist.ftl", -//~^ ERROR could not open Fluent resource - } + fluent_messages! { "/definitely_does_not_exist.ftl" } + //~^ ERROR could not open Fluent resource } mod missing_relative { use super::fluent_messages; - fluent_messages! { - missing_relative => "../definitely_does_not_exist.ftl", -//~^ ERROR could not open Fluent resource - } + fluent_messages! { "../definitely_does_not_exist.ftl" } + //~^ ERROR could not open Fluent resource } mod missing_message { use super::fluent_messages; - fluent_messages! { - missing_message => "./missing-message.ftl", -//~^ ERROR could not parse Fluent resource - } + fluent_messages! { "./missing-message.ftl" } + //~^ ERROR could not parse Fluent resource } mod duplicate { use super::fluent_messages; - fluent_messages! { -//~^ ERROR the name `a_b_key` is defined multiple times - a => "./duplicate-a.ftl", - a_b => "./duplicate-a-b.ftl", -//~^ ERROR overrides existing message: `a_b_key` - } + fluent_messages! { "./duplicate.ftl" } + //~^ ERROR overrides existing message: `no_crate_a_b_key` } mod slug_with_hyphens { use super::fluent_messages; - fluent_messages! { - slug_with_hyphens => "./slug-with-hyphens.ftl", -//~^ ERROR name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character - } + fluent_messages! { "./slug-with-hyphens.ftl" } + //~^ ERROR name `no_crate_this-slug-has-hyphens` contains a '-' character } mod label_with_hyphens { use super::fluent_messages; - fluent_messages! { - label_with_hyphens => "./label-with-hyphens.ftl", -//~^ ERROR attribute `label-has-hyphens` contains a '-' character - } + fluent_messages! { "./label-with-hyphens.ftl" } + //~^ ERROR attribute `label-has-hyphens` contains a '-' character } mod valid { use super::fluent_messages; - fluent_messages! { - valid => "./valid.ftl", - } + fluent_messages! { "./valid.ftl" } - use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, valid_key}; + mod test_generated { + use super::{fluent_generated::no_crate_key, DEFAULT_LOCALE_RESOURCE}; + } } mod missing_crate_name { use super::fluent_messages; - fluent_messages! { - test_crate => "./missing-crate-name.ftl", -//~^ ERROR name `test-crate_foo` contains a '-' character -//~| ERROR name `with-hyphens` contains a '-' character -//~| ERROR name `with-hyphens` does not start with the crate name - } + fluent_messages! { "./missing-crate-name.ftl" } + //~^ ERROR name `no-crate_foo` contains a '-' character + //~| ERROR name `with-hyphens` contains a '-' character + //~| ERROR name `with-hyphens` does not start with the crate name - use self::fluent_generated::{DEFAULT_LOCALE_RESOURCES, test_crate_foo, with_hyphens}; + mod test_generated { + use super::{ + fluent_generated::{no_crate_foo, with_hyphens}, + DEFAULT_LOCALE_RESOURCE, + }; + } } mod missing_message_ref { use super::fluent_messages; - fluent_messages! { - missing => "./missing-message-ref.ftl" -//~^ ERROR referenced message `message` does not exist - } + fluent_messages! { "./missing-message-ref.ftl" } + //~^ ERROR referenced message `message` does not exist } diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index 2631b0a6232..c7961ed22f2 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -1,106 +1,87 @@ error: could not open Fluent resource - --> $DIR/test.rs:25:29 + --> $DIR/test.rs:24:24 | -LL | missing_absolute => "/definitely_does_not_exist.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "/definitely_does_not_exist.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: os-specific message error: could not open Fluent resource - --> $DIR/test.rs:34:29 + --> $DIR/test.rs:31:24 | -LL | missing_relative => "../definitely_does_not_exist.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "../definitely_does_not_exist.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: os-specific message error: could not parse Fluent resource - --> $DIR/test.rs:43:28 + --> $DIR/test.rs:38:24 | -LL | missing_message => "./missing-message.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./missing-message.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^ | = help: see additional errors emitted -error: expected a message field for "missing_message" +error: expected a message field for "no_crate_missing_message" --> ./missing-message.ftl:1:1 | -1 | missing_message = - | ^^^^^^^^^^^^^^^^^ +1 | no_crate_missing_message = + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -error: overrides existing message: `a_b_key` - --> $DIR/test.rs:54:16 +error: overrides existing message: `no_crate_a_b_key` + --> $DIR/test.rs:45:24 | -LL | a_b => "./duplicate-a-b.ftl", - | ^^^^^^^^^^^^^^^^^^^^^ - | -help: previously defined in this resource - --> $DIR/test.rs:53:14 - | -LL | a => "./duplicate-a.ftl", - | ^^^^^^^^^^^^^^^^^^^ - -error[E0428]: the name `a_b_key` is defined multiple times - --> $DIR/test.rs:51:5 - | -LL | fluent_messages! { - | ^^^^^^^^^^^^^^^^ - | | - | `a_b_key` redefined here - | previous definition of the value `a_b_key` here - | - = note: os-specific message - = note: os-specific message +LL | fluent_messages! { "./duplicate.ftl" } + | ^^^^^^^^^^^^^^^^^ -error: name `slug_with_hyphens_this-slug-has-hyphens` contains a '-' character - --> $DIR/test.rs:63:30 +error: name `no_crate_this-slug-has-hyphens` contains a '-' character + --> $DIR/test.rs:52:24 | -LL | slug_with_hyphens => "./slug-with-hyphens.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./slug-with-hyphens.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: replace any '-'s with '_'s error: attribute `label-has-hyphens` contains a '-' character - --> $DIR/test.rs:72:31 + --> $DIR/test.rs:59:24 | -LL | label_with_hyphens => "./label-with-hyphens.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./label-with-hyphens.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: replace any '-'s with '_'s error: name `with-hyphens` contains a '-' character - --> $DIR/test.rs:91:23 + --> $DIR/test.rs:76:24 | -LL | test_crate => "./missing-crate-name.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./missing-crate-name.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: replace any '-'s with '_'s error: name `with-hyphens` does not start with the crate name - --> $DIR/test.rs:91:23 + --> $DIR/test.rs:76:24 | -LL | test_crate => "./missing-crate-name.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./missing-crate-name.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: prepend `test_crate_` to the slug name: `test_crate_with_hyphens` + = help: prepend `no_crate_` to the slug name: `no_crate_with_hyphens` -error: name `test-crate_foo` contains a '-' character - --> $DIR/test.rs:91:23 +error: name `no-crate_foo` contains a '-' character + --> $DIR/test.rs:76:24 | -LL | test_crate => "./missing-crate-name.ftl", - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./missing-crate-name.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: replace any '-'s with '_'s -error: referenced message `message` does not exist (in message `missing_message_ref`) - --> $DIR/test.rs:104:20 +error: referenced message `message` does not exist (in message `no_crate_missing_message_ref`) + --> $DIR/test.rs:92:24 | -LL | missing => "./missing-message-ref.ftl" - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fluent_messages! { "./missing-message-ref.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: you may have meant to use a variable reference (`{$message}`) -error: aborting due to 11 previous errors +error: aborting due to 10 previous errors -For more information about this error, try `rustc --explain E0428`. diff --git a/tests/ui-fulldeps/fluent-messages/valid.ftl b/tests/ui-fulldeps/fluent-messages/valid.ftl index 54927430600..598473adb68 100644 --- a/tests/ui-fulldeps/fluent-messages/valid.ftl +++ b/tests/ui-fulldeps/fluent-messages/valid.ftl @@ -1 +1 @@ -valid_key = Valid! +no_crate_key = Valid! diff --git a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl b/tests/ui-fulldeps/internal-lints/diagnostics.ftl index 55061fbce7e..cb2d476d815 100644 --- a/compiler/rustc_error_messages/locales/en-US/compiletest.ftl +++ b/tests/ui-fulldeps/internal-lints/diagnostics.ftl @@ -1,4 +1,4 @@ -compiletest_example = this is an example message used in testing +no_crate_example = this is an example message used in testing .note = with a note .help = with a help .suggestion = with a suggestion diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs index 643e81d99c6..3aa65d53d4e 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.rs +++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs @@ -13,20 +13,22 @@ extern crate rustc_span; use rustc_errors::{ AddToDiagnostic, IntoDiagnostic, Diagnostic, DiagnosticBuilder, - ErrorGuaranteed, Handler, fluent, SubdiagnosticMessage, + ErrorGuaranteed, Handler, DiagnosticMessage, SubdiagnosticMessage, }; -use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_macros::{fluent_messages, Diagnostic, Subdiagnostic}; use rustc_span::Span; +fluent_messages! { "./diagnostics.ftl" } + #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct DeriveDiagnostic { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[note(compiletest_example)] +#[note(no_crate_example)] struct Note { #[primary_span] span: Span, @@ -45,7 +47,7 @@ pub struct TranslatableInIntoDiagnostic; impl<'a> IntoDiagnostic<'a, ErrorGuaranteed> for TranslatableInIntoDiagnostic { fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGuaranteed> { - handler.struct_err(fluent::compiletest_example) + handler.struct_err(crate::fluent_generated::no_crate_example) } } @@ -68,12 +70,12 @@ impl AddToDiagnostic for TranslatableInAddToDiagnostic { where F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, { - diag.note(fluent::note); + diag.note(crate::fluent_generated::no_crate_note); } } pub fn make_diagnostics<'a>(handler: &'a Handler) { - let _diag = handler.struct_err(fluent::compiletest_example); + let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); //~^ ERROR diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls let _diag = handler.struct_err("untranslatable diagnostic"); diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr index 510d6a17108..6f797ebc2dd 100644 --- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr +++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr @@ -1,5 +1,5 @@ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:39:17 + --> $DIR/diagnostics.rs:41:17 | LL | handler.struct_err("untranslatable diagnostic") | ^^^^^^^^^^ @@ -11,15 +11,15 @@ LL | #![deny(rustc::untranslatable_diagnostic)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:59:14 + --> $DIR/diagnostics.rs:61:14 | LL | diag.note("untranslatable diagnostic"); | ^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:76:25 + --> $DIR/diagnostics.rs:78:25 | -LL | let _diag = handler.struct_err(fluent::compiletest_example); +LL | let _diag = handler.struct_err(crate::fluent_generated::no_crate_example); | ^^^^^^^^^^ | note: the lint level is defined here @@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls - --> $DIR/diagnostics.rs:79:25 + --> $DIR/diagnostics.rs:81:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ error: diagnostics should be created using translatable messages - --> $DIR/diagnostics.rs:79:25 + --> $DIR/diagnostics.rs:81:25 | LL | let _diag = handler.struct_err("untranslatable diagnostic"); | ^^^^^^^^^^ diff --git a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs index bdfd9628c48..ddc86c1dc31 100644 --- a/tests/ui-fulldeps/mod_dir_path_canonicalized.rs +++ b/tests/ui-fulldeps/mod_dir_path_canonicalized.rs @@ -31,7 +31,10 @@ pub fn main() { } fn parse() { - let parse_session = ParseSess::new(FilePathMapping::empty()); + let parse_session = ParseSess::new( + vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], + FilePathMapping::empty() + ); let path = Path::new(file!()); let path = path.canonicalize().unwrap(); diff --git a/tests/ui-fulldeps/pprust-expr-roundtrip.rs b/tests/ui-fulldeps/pprust-expr-roundtrip.rs index 7a91dcf0dad..e417a6a833b 100644 --- a/tests/ui-fulldeps/pprust-expr-roundtrip.rs +++ b/tests/ui-fulldeps/pprust-expr-roundtrip.rs @@ -41,7 +41,7 @@ use rustc_session::parse::ParseSess; use rustc_span::source_map::FilePathMapping; use rustc_span::source_map::{FileName, Spanned, DUMMY_SP}; use rustc_span::symbol::Ident; -use thin_vec::thin_vec; +use thin_vec::{thin_vec, ThinVec}; fn parse_expr(ps: &ParseSess, src: &str) -> Option<P<Expr>> { let src_as_string = src.to_string(); @@ -76,17 +76,17 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { for kind in 0..=19 { match kind { 0 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Box(e))), - 1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, vec![]))), + 1 => iter_exprs(depth - 1, &mut |e| g(ExprKind::Call(e, thin_vec![]))), 2 => { let seg = PathSegment::from_ident(Ident::from_str("x")); iter_exprs(depth - 1, &mut |e| { g(ExprKind::MethodCall(Box::new(MethodCall { - seg: seg.clone(), receiver: e, args: vec![make_x()], span: DUMMY_SP + seg: seg.clone(), receiver: e, args: thin_vec![make_x()], span: DUMMY_SP })) )}); iter_exprs(depth - 1, &mut |e| { g(ExprKind::MethodCall(Box::new(MethodCall { - seg: seg.clone(), receiver: make_x(), args: vec![e], span: DUMMY_SP + seg: seg.clone(), receiver: make_x(), args: thin_vec![e], span: DUMMY_SP })) )}); } @@ -111,7 +111,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { } 10 => { let block = P(Block { - stmts: Vec::new(), + stmts: ThinVec::new(), id: DUMMY_NODE_ID, rules: BlockCheckMode::Default, span: DUMMY_SP, @@ -121,7 +121,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { iter_exprs(depth - 1, &mut |e| g(ExprKind::If(e, block.clone(), None))); } 11 => { - let decl = P(FnDecl { inputs: vec![], output: FnRetTy::Default(DUMMY_SP) }); + let decl = P(FnDecl { inputs: thin_vec![], output: FnRetTy::Default(DUMMY_SP) }); iter_exprs(depth - 1, &mut |e| { g(ExprKind::Closure(Box::new(Closure { binder: ClosureBinder::NotPresent, @@ -165,7 +165,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) { g(ExprKind::Struct(P(StructExpr { qself: None, path, - fields: vec![], + fields: thin_vec![], rest: StructRest::Base(make_x()), }))); } @@ -220,7 +220,7 @@ fn main() { } fn run() { - let ps = ParseSess::new(FilePathMapping::empty()); + let ps = ParseSess::new(vec![rustc_parse::DEFAULT_LOCALE_RESOURCE], FilePathMapping::empty()); iter_exprs(2, &mut |mut e| { // If the pretty printer is correct, then `parse(print(e))` should be identical to `e`, diff --git a/tests/ui-fulldeps/rename-directory.rs b/tests/ui-fulldeps/rename-directory.rs deleted file mode 100644 index 8fc340cb918..00000000000 --- a/tests/ui-fulldeps/rename-directory.rs +++ /dev/null @@ -1,30 +0,0 @@ -// run-pass - -#![allow(unused_must_use)] -#![allow(unused_imports)] -// This test can't be a unit test in std, -// because it needs TempDir, which is in extra - -// ignore-cross-compile - -use std::env; -use std::ffi::CString; -use std::fs::{self, File}; -use std::path::PathBuf; - -fn rename_directory() { - let tmpdir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); - let old_path = tmpdir.join("foo/bar/baz"); - fs::create_dir_all(&old_path).unwrap(); - let test_file = &old_path.join("temp.txt"); - - File::create(test_file).unwrap(); - - let new_path = tmpdir.join("quux/blat"); - fs::create_dir_all(&new_path).unwrap(); - fs::rename(&old_path, &new_path.join("newdir")); - assert!(new_path.join("newdir").is_dir()); - assert!(new_path.join("newdir/temp.txt").exists()); -} - -pub fn main() { rename_directory() } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 07f95d13937..01e6434b075 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -17,26 +17,28 @@ use rustc_span::symbol::Ident; use rustc_span::Span; extern crate rustc_macros; -use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; +use rustc_macros::{fluent_messages, Diagnostic, LintDiagnostic, Subdiagnostic}; extern crate rustc_middle; use rustc_middle::ty::Ty; extern crate rustc_errors; -use rustc_errors::{Applicability, MultiSpan}; +use rustc_errors::{Applicability, DiagnosticMessage, MultiSpan, SubdiagnosticMessage}; extern crate rustc_session; +fluent_messages! { "./example.ftl" } + #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct Hello {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct HelloWarn {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] //~^ ERROR unsupported type attribute for diagnostic derive enum enum DiagnosticOnEnum { Foo, @@ -46,13 +48,13 @@ enum DiagnosticOnEnum { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] #[diag = "E0123"] //~^ ERROR `#[diag = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(Diagnostic)] -#[nonsense(compiletest_example, code = "E0123")] +#[nonsense(no_crate_example, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic slug not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope @@ -66,7 +68,7 @@ struct InvalidLitNestedAttr {} #[derive(Diagnostic)] #[diag(nonsense, code = "E0123")] -//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent` +//~^ ERROR cannot find value `nonsense` in module `crate::fluent_generated` struct InvalidNestedStructAttr {} #[derive(Diagnostic)] @@ -90,12 +92,12 @@ struct InvalidNestedStructAttr2 {} struct InvalidNestedStructAttr3 {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123", slug = "foo")] +#[diag(no_crate_example, code = "E0123", slug = "foo")] //~^ ERROR `#[diag(slug = ...)]` is not a valid attribute struct InvalidNestedStructAttr4 {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct WrongPlaceField { #[suggestion = "bar"] //~^ ERROR `#[suggestion = ...]` is not a valid attribute @@ -103,20 +105,20 @@ struct WrongPlaceField { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] -#[diag(compiletest_example, code = "E0456")] +#[diag(no_crate_example, code = "E0123")] +#[diag(no_crate_example, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times struct DiagSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0456", code = "E0457")] +#[diag(no_crate_example, code = "E0456", code = "E0457")] //~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(Diagnostic)] -#[diag(compiletest_example, compiletest_example, code = "E0456")] -//~^ ERROR `#[diag(compiletest_example)]` is not a valid attribute +#[diag(no_crate_example, no_crate::example, code = "E0456")] +//~^ ERROR `#[diag(no_crate::example)]` is not a valid attribute struct SlugSpecifiedTwice {} #[derive(Diagnostic)] @@ -128,11 +130,11 @@ struct KindNotProvided {} //~ ERROR diagnostic slug not specified struct SlugNotProvided {} #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct CodeNotProvided {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct MessageWrongType { #[primary_span] //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` @@ -140,7 +142,7 @@ struct MessageWrongType { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute @@ -149,34 +151,34 @@ struct InvalidPathFieldAttr { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithField { name: String, - #[label(label)] + #[label(no_crate_label)] span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithMessageAppliedToField { - #[label(label)] + #[label(no_crate_label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` name: String, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithNonexistentField { - #[suggestion(suggestion, code = "{name}")] + #[suggestion(no_crate_suggestion, code = "{name}")] //~^ ERROR `name` doesn't refer to a field on this type suggestion: (Span, Applicability), } #[derive(Diagnostic)] //~^ ERROR invalid format string: expected `'}'` -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorMissingClosingBrace { - #[suggestion(suggestion, code = "{name")] + #[suggestion(no_crate_suggestion, code = "{name")] suggestion: (Span, Applicability), name: String, val: usize, @@ -184,50 +186,50 @@ struct ErrorMissingClosingBrace { #[derive(Diagnostic)] //~^ ERROR invalid format string: unmatched `}` -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorMissingOpeningBrace { - #[suggestion(suggestion, code = "name}")] + #[suggestion(no_crate_suggestion, code = "name}")] suggestion: (Span, Applicability), name: String, val: usize, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct LabelOnSpan { - #[label(label)] + #[label(no_crate_label)] sp: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct LabelOnNonSpan { - #[label(label)] + #[label(no_crate_label)] //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` id: u32, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct Suggest { - #[suggestion(suggestion, code = "This is the suggested code")] - #[suggestion(suggestion, code = "This is the suggested code", style = "normal")] - #[suggestion(suggestion, code = "This is the suggested code", style = "short")] - #[suggestion(suggestion, code = "This is the suggested code", style = "hidden")] - #[suggestion(suggestion, code = "This is the suggested code", style = "verbose")] + #[suggestion(no_crate_suggestion, code = "This is the suggested code")] + #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "normal")] + #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "short")] + #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "hidden")] + #[suggestion(no_crate_suggestion, code = "This is the suggested code", style = "verbose")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithoutCode { - #[suggestion(suggestion)] + #[suggestion(no_crate_suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute @@ -236,7 +238,7 @@ struct SuggestWithBadKey { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute @@ -245,52 +247,52 @@ struct SuggestWithShorthandMsg { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithoutMsg { #[suggestion(code = "bar")] suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithTypesSwapped { - #[suggestion(suggestion, code = "This is suggested code")] + #[suggestion(no_crate_suggestion, code = "This is suggested code")] suggestion: (Applicability, Span), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(suggestion, code = "This is suggested code")] + #[suggestion(no_crate_suggestion, code = "This is suggested code")] //~^ ERROR wrong field type for suggestion suggestion: Applicability, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithSpanOnly { - #[suggestion(suggestion, code = "This is suggested code")] + #[suggestion(no_crate_suggestion, code = "This is suggested code")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(suggestion, code = "This is suggested code")] + #[suggestion(no_crate_suggestion, code = "This is suggested code")] suggestion: (Span, Span, Applicability), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(suggestion, code = "This is suggested code")] + #[suggestion(no_crate_suggestion, code = "This is suggested code")] suggestion: (Applicability, Applicability, Span), //~^ ERROR specified multiple times } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct WrongKindOfAnnotation { #[label = "bar"] //~^ ERROR `#[label = ...]` is not a valid attribute @@ -298,38 +300,38 @@ struct WrongKindOfAnnotation { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct OptionsInErrors { - #[label(label)] + #[label(no_crate_label)] label: Option<Span>, - #[suggestion(suggestion, code = "...")] + #[suggestion(no_crate_suggestion, code = "...")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0456")] +#[diag(no_crate_example, code = "E0456")] struct MoveOutOfBorrowError<'tcx> { name: Ident, ty: Ty<'tcx>, #[primary_span] - #[label(label)] + #[label(no_crate_label)] span: Span, - #[label(label)] + #[label(no_crate_label)] other_span: Span, - #[suggestion(suggestion, code = "{name}.clone()")] + #[suggestion(no_crate_suggestion, code = "{name}.clone()")] opt_sugg: Option<(Span, Applicability)>, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithLifetime<'a> { - #[label(label)] + #[label(no_crate_label)] span: Span, name: &'a str, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithDefaultLabelAttr<'a> { #[label] span: Span, @@ -338,7 +340,7 @@ struct ErrorWithDefaultLabelAttr<'a> { #[derive(Diagnostic)] //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, @@ -346,7 +348,7 @@ struct ArgFieldWithoutSkip { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ArgFieldWithSkip { #[primary_span] span: Span, @@ -357,132 +359,132 @@ struct ArgFieldWithSkip { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithSpannedNote { #[note] span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithSpannedNoteCustom { - #[note(note)] + #[note(no_crate_note)] span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] #[note] struct ErrorWithNote { val: String, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] -#[note(note)] +#[diag(no_crate_example, code = "E0123")] +#[note(no_crate_note)] struct ErrorWithNoteCustom { val: String, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithSpannedHelp { #[help] span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithSpannedHelpCustom { - #[help(help)] + #[help(no_crate_help)] span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] #[help] struct ErrorWithHelp { val: String, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] -#[help(help)] +#[diag(no_crate_example, code = "E0123")] +#[help(no_crate_help)] struct ErrorWithHelpCustom { val: String, } #[derive(Diagnostic)] #[help] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithHelpWrongOrder { val: String, } #[derive(Diagnostic)] -#[help(help)] -#[diag(compiletest_example, code = "E0123")] +#[help(no_crate_help)] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithHelpCustomWrongOrder { val: String, } #[derive(Diagnostic)] #[note] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithNoteWrongOrder { val: String, } #[derive(Diagnostic)] -#[note(note)] -#[diag(compiletest_example, code = "E0123")] +#[note(no_crate_note)] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithNoteCustomWrongOrder { val: String, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ApplicabilityInBoth { - #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] //~^ ERROR specified multiple times suggestion: (Span, Applicability), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct InvalidApplicability { - #[suggestion(suggestion, code = "...", applicability = "batman")] + #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] //~^ ERROR invalid applicability suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ValidApplicability { - #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")] + #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct NoApplicability { - #[suggestion(suggestion, code = "...")] + #[suggestion(no_crate_suggestion, code = "...")] suggestion: Span, } #[derive(Subdiagnostic)] -#[note(parse_add_paren)] +#[note(no_crate_example)] struct Note; #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct Subdiagnostic { #[subdiagnostic] note: Note, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct VecField { #[primary_span] #[label] @@ -490,57 +492,57 @@ struct VecField { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct UnitField { #[primary_span] spans: Span, #[help] foo: (), - #[help(help)] + #[help(no_crate_help)] bar: (), } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct OptUnitField { #[primary_span] spans: Span, #[help] foo: Option<()>, - #[help(help)] + #[help(no_crate_help)] bar: Option<()>, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct LabelWithTrailingPath { - #[label(label, foo)] + #[label(no_crate_label, foo)] //~^ ERROR `#[label(foo)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct LabelWithTrailingNameValue { - #[label(label, foo = "...")] + #[label(no_crate_label, foo = "...")] //~^ ERROR `#[label(foo = ...)]` is not a valid attribute span: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct LabelWithTrailingList { - #[label(label, foo("..."))] + #[label(no_crate_label, foo("..."))] //~^ ERROR `#[label(foo(...))]` is not a valid attribute span: Span, } #[derive(LintDiagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct LintsGood {} #[derive(LintDiagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct PrimarySpanOnLint { #[primary_span] //~^ ERROR `#[primary_span]` is not a valid attribute @@ -548,42 +550,42 @@ struct PrimarySpanOnLint { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct ErrorWithMultiSpan { #[primary_span] span: MultiSpan, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] #[warning] struct ErrorWithWarn { val: String, } #[derive(Diagnostic)] -#[error(compiletest_example, code = "E0123")] +#[error(no_crate_example, code = "E0123")] //~^ ERROR `#[error(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `error` in this scope struct ErrorAttribute {} #[derive(Diagnostic)] -#[warn_(compiletest_example, code = "E0123")] +#[warn_(no_crate_example, code = "E0123")] //~^ ERROR `#[warn_(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `warn_` in this scope struct WarnAttribute {} #[derive(Diagnostic)] -#[lint(compiletest_example, code = "E0123")] +#[lint(no_crate_example, code = "E0123")] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified //~| ERROR cannot find attribute `lint` in this scope struct LintAttributeOnSessionDiag {} #[derive(LintDiagnostic)] -#[lint(compiletest_example, code = "E0123")] +#[lint(no_crate_example, code = "E0123")] //~^ ERROR `#[lint(...)]` is not a valid attribute //~| ERROR `#[lint(...)]` is not a valid attribute //~| ERROR diagnostic slug not specified @@ -591,55 +593,55 @@ struct LintAttributeOnSessionDiag {} struct LintAttributeOnLintDiag {} #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct DuplicatedSuggestionCode { - #[suggestion(suggestion, code = "...", code = ",,,")] + #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] //~^ ERROR specified multiple times suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct InvalidTypeInSuggestionTuple { - #[suggestion(suggestion, code = "...")] + #[suggestion(no_crate_suggestion, code = "...")] suggestion: (Span, usize), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct MissingApplicabilityInSuggestionTuple { - #[suggestion(suggestion, code = "...")] + #[suggestion(no_crate_suggestion, code = "...")] suggestion: (Span,), //~^ ERROR wrong types for suggestion } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct MissingCodeInSuggestion { - #[suggestion(suggestion)] + #[suggestion(no_crate_suggestion)] //~^ ERROR suggestion without `code = "..."` suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] -#[multipart_suggestion(suggestion)] +#[diag(no_crate_example, code = "E0123")] +#[multipart_suggestion(no_crate_suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope #[multipart_suggestion()] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope struct MultipartSuggestion { - #[multipart_suggestion(suggestion)] + #[multipart_suggestion(no_crate_suggestion)] //~^ ERROR `#[multipart_suggestion(...)]` is not a valid attribute //~| ERROR cannot find attribute `multipart_suggestion` in this scope suggestion: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] -#[suggestion(suggestion, code = "...")] +#[diag(no_crate_example, code = "E0123")] +#[suggestion(no_crate_suggestion, code = "...")] //~^ ERROR `#[suggestion(...)]` is not a valid attribute struct SuggestionOnStruct { #[primary_span] @@ -647,7 +649,7 @@ struct SuggestionOnStruct { } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] #[label] //~^ ERROR `#[label]` is not a valid attribute struct LabelOnStruct { @@ -657,30 +659,30 @@ struct LabelOnStruct { #[derive(Diagnostic)] enum ExampleEnum { - #[diag(compiletest_example)] + #[diag(no_crate_example)] Foo { #[primary_span] sp: Span, #[note] note_sp: Span, }, - #[diag(compiletest_example)] + #[diag(no_crate_example)] Bar { #[primary_span] sp: Span, }, - #[diag(compiletest_example)] + #[diag(no_crate_example)] Baz, } #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct RawIdentDiagnosticArg { pub r#type: String, } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticBad { #[subdiagnostic(bad)] //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute @@ -688,7 +690,7 @@ struct SubdiagnosticBad { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticBadStr { #[subdiagnostic = "bad"] //~^ ERROR `#[subdiagnostic = ...]` is not a valid attribute @@ -696,7 +698,7 @@ struct SubdiagnosticBadStr { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticBadTwice { #[subdiagnostic(bad, bad)] //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute @@ -704,7 +706,7 @@ struct SubdiagnosticBadTwice { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticBadLitStr { #[subdiagnostic("bad")] //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute @@ -712,7 +714,7 @@ struct SubdiagnosticBadLitStr { } #[derive(LintDiagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticEagerLint { #[subdiagnostic(eager)] //~^ ERROR `#[subdiagnostic(...)]` is not a valid attribute @@ -720,7 +722,7 @@ struct SubdiagnosticEagerLint { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticEagerCorrect { #[subdiagnostic(eager)] note: Note, @@ -731,7 +733,7 @@ struct SubdiagnosticEagerCorrect { // after the `span_suggestion` call - which breaks eager translation. #[derive(Subdiagnostic)] -#[suggestion(use_instead, applicability = "machine-applicable", code = "{correct}")] +#[suggestion(no_crate_example, applicability = "machine-applicable", code = "{correct}")] pub(crate) struct SubdiagnosticWithSuggestion { #[primary_span] span: Span, @@ -740,7 +742,7 @@ pub(crate) struct SubdiagnosticWithSuggestion { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SubdiagnosticEagerSuggestion { #[subdiagnostic(eager)] sub: SubdiagnosticWithSuggestion, @@ -748,7 +750,7 @@ struct SubdiagnosticEagerSuggestion { /// with a doc comment on the type.. #[derive(Diagnostic)] -#[diag(compiletest_example, code = "E0123")] +#[diag(no_crate_example, code = "E0123")] struct WithDocComment { /// ..and the field #[primary_span] @@ -756,21 +758,21 @@ struct WithDocComment { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionsGood { #[suggestion(code("foo", "bar"))] sub: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionsSingleItem { #[suggestion(code("foo"))] sub: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionsNoItem { #[suggestion(code())] //~^ ERROR expected at least one string literal for `code(...)` @@ -778,7 +780,7 @@ struct SuggestionsNoItem { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionsInvalidItem { #[suggestion(code(foo))] //~^ ERROR `code(...)` must contain only string literals @@ -786,7 +788,7 @@ struct SuggestionsInvalidItem { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionsInvalidLiteral { #[suggestion(code = 3)] //~^ ERROR `code = "..."`/`code(...)` must contain only string literals @@ -794,16 +796,16 @@ struct SuggestionsInvalidLiteral { } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionStyleGood { #[suggestion(code = "", style = "hidden")] sub: Span, } #[derive(Diagnostic)] -#[diag(compiletest_example)] +#[diag(no_crate_example)] struct SuggestionOnVec { - #[suggestion(suggestion, code = "")] + #[suggestion(no_crate_suggestion, code = "")] //~^ ERROR `#[suggestion(...)]` is not a valid attribute sub: Vec<Span>, } diff --git a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 61806c80efc..fc0cd8419e4 100644 --- a/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,11 +1,11 @@ error: unsupported type attribute for diagnostic derive enum - --> $DIR/diagnostic-derive.rs:39:1 + --> $DIR/diagnostic-derive.rs:41:1 | -LL | #[diag(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[diag(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:42:5 + --> $DIR/diagnostic-derive.rs:44:5 | LL | Foo, | ^^^ @@ -13,7 +13,7 @@ LL | Foo, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:44:5 + --> $DIR/diagnostic-derive.rs:46:5 | LL | Bar, | ^^^ @@ -21,21 +21,21 @@ LL | Bar, = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:50:1 + --> $DIR/diagnostic-derive.rs:52:1 | LL | #[diag = "E0123"] | ^^^^^^^^^^^^^^^^^ error: `#[nonsense(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:55:1 + --> $DIR/diagnostic-derive.rs:57:1 | -LL | #[nonsense(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[nonsense(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:55:1 + --> $DIR/diagnostic-derive.rs:57:1 | -LL | / #[nonsense(compiletest_example, code = "E0123")] +LL | / #[nonsense(no_crate_example, code = "E0123")] LL | | LL | | LL | | @@ -45,7 +45,7 @@ LL | | struct InvalidStructAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag("...")]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:62:8 + --> $DIR/diagnostic-derive.rs:64:8 | LL | #[diag("E0123")] | ^^^^^^^ @@ -53,7 +53,7 @@ LL | #[diag("E0123")] = help: a diagnostic slug is required as the first argument error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:62:1 + --> $DIR/diagnostic-derive.rs:64:1 | LL | / #[diag("E0123")] LL | | @@ -64,7 +64,7 @@ LL | | struct InvalidLitNestedAttr {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag(nonsense(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:73:8 + --> $DIR/diagnostic-derive.rs:75:8 | LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^ @@ -72,7 +72,7 @@ LL | #[diag(nonsense("foo"), code = "E0123", slug = "foo")] = help: a diagnostic slug is required as the first argument error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:73:1 + --> $DIR/diagnostic-derive.rs:75:1 | LL | / #[diag(nonsense("foo"), code = "E0123", slug = "foo")] LL | | @@ -83,7 +83,7 @@ LL | | struct InvalidNestedStructAttr1 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:79:8 + --> $DIR/diagnostic-derive.rs:81:8 | LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^ @@ -91,7 +91,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] = help: only `code` is a valid nested attributes following the slug error: `#[diag(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:79:42 + --> $DIR/diagnostic-derive.rs:81:42 | LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ @@ -99,7 +99,7 @@ LL | #[diag(nonsense = "...", code = "E0123", slug = "foo")] = help: only `code` is a valid nested attributes following the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:79:1 + --> $DIR/diagnostic-derive.rs:81:1 | LL | / #[diag(nonsense = "...", code = "E0123", slug = "foo")] LL | | @@ -111,13 +111,13 @@ LL | | struct InvalidNestedStructAttr2 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:86:8 + --> $DIR/diagnostic-derive.rs:88:8 | LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ error: `#[diag(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:86:38 + --> $DIR/diagnostic-derive.rs:88:38 | LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ @@ -125,7 +125,7 @@ LL | #[diag(nonsense = 4, code = "E0123", slug = "foo")] = help: only `code` is a valid nested attributes following the slug error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:86:1 + --> $DIR/diagnostic-derive.rs:88:1 | LL | / #[diag(nonsense = 4, code = "E0123", slug = "foo")] LL | | @@ -137,65 +137,65 @@ LL | | struct InvalidNestedStructAttr3 {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[diag(slug = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:93:45 + --> $DIR/diagnostic-derive.rs:95:42 | -LL | #[diag(compiletest_example, code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^ +LL | #[diag(no_crate_example, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | = help: only `code` is a valid nested attributes following the slug error: `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:100:5 + --> $DIR/diagnostic-derive.rs:102:5 | LL | #[suggestion = "bar"] | ^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:8 + --> $DIR/diagnostic-derive.rs:109:8 | -LL | #[diag(compiletest_example, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[diag(no_crate_example, code = "E0456")] + | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:8 + --> $DIR/diagnostic-derive.rs:108:8 | -LL | #[diag(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[diag(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:107:36 + --> $DIR/diagnostic-derive.rs:109:33 | -LL | #[diag(compiletest_example, code = "E0456")] - | ^^^^^^^ +LL | #[diag(no_crate_example, code = "E0456")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:106:36 + --> $DIR/diagnostic-derive.rs:108:33 | -LL | #[diag(compiletest_example, code = "E0123")] - | ^^^^^^^ +LL | #[diag(no_crate_example, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:113:52 + --> $DIR/diagnostic-derive.rs:115:49 | -LL | #[diag(compiletest_example, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:113:36 + --> $DIR/diagnostic-derive.rs:115:33 | -LL | #[diag(compiletest_example, code = "E0456", code = "E0457")] - | ^^^^^^^ +LL | #[diag(no_crate_example, code = "E0456", code = "E0457")] + | ^^^^^^^ -error: `#[diag(compiletest_example)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:118:29 +error: `#[diag(no_crate::example)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:120:26 | -LL | #[diag(compiletest_example, compiletest_example, code = "E0456")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[diag(no_crate_example, no_crate::example, code = "E0456")] + | ^^^^^^^^^^^^^^^^^ | = help: diagnostic slug must be the first argument error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:123:1 + --> $DIR/diagnostic-derive.rs:125:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -203,7 +203,7 @@ LL | struct KindNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:126:1 + --> $DIR/diagnostic-derive.rs:128:1 | LL | / #[diag(code = "E0456")] LL | | @@ -213,31 +213,31 @@ LL | | struct SlugNotProvided {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:137:5 + --> $DIR/diagnostic-derive.rs:139:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:145:5 + --> $DIR/diagnostic-derive.rs:147:5 | LL | #[nonsense] | ^^^^^^^^^^^ error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:162:5 + --> $DIR/diagnostic-derive.rs:164:5 | -LL | #[label(label)] - | ^^^^^^^^^^^^^^^ +LL | #[label(no_crate_label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:170:37 + --> $DIR/diagnostic-derive.rs:172:46 | -LL | #[suggestion(suggestion, code = "{name}")] - | ^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "{name}")] + | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:175:10 + --> $DIR/diagnostic-derive.rs:177:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ expected `'}'` in format string @@ -246,7 +246,7 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:185:10 + --> $DIR/diagnostic-derive.rs:187:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ unmatched `}` in format string @@ -255,19 +255,19 @@ LL | #[derive(Diagnostic)] = note: this error originates in the derive macro `Diagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/diagnostic-derive.rs:205:5 + --> $DIR/diagnostic-derive.rs:207:5 | -LL | #[label(label)] - | ^^^^^^^^^^^^^^^ +LL | #[label(no_crate_label)] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:224:5 + --> $DIR/diagnostic-derive.rs:226:5 | -LL | #[suggestion(suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:232:18 + --> $DIR/diagnostic-derive.rs:234:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ @@ -275,13 +275,13 @@ LL | #[suggestion(nonsense = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:232:5 + --> $DIR/diagnostic-derive.rs:234:5 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(msg = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:241:18 + --> $DIR/diagnostic-derive.rs:243:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ @@ -289,15 +289,15 @@ LL | #[suggestion(msg = "bar")] = help: only `style`, `code` and `applicability` are valid nested attributes error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:241:5 + --> $DIR/diagnostic-derive.rs:243:5 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:264:5 + --> $DIR/diagnostic-derive.rs:266:5 | -LL | / #[suggestion(suggestion, code = "This is suggested code")] +LL | / #[suggestion(no_crate_suggestion, code = "This is suggested code")] LL | | LL | | suggestion: Applicability, | |_____________________________^ @@ -305,75 +305,75 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: specified multiple times - --> $DIR/diagnostic-derive.rs:280:24 + --> $DIR/diagnostic-derive.rs:282:24 | LL | suggestion: (Span, Span, Applicability), | ^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:280:18 + --> $DIR/diagnostic-derive.rs:282:18 | LL | suggestion: (Span, Span, Applicability), | ^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:288:33 + --> $DIR/diagnostic-derive.rs:290:33 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:288:18 + --> $DIR/diagnostic-derive.rs:290:18 | LL | suggestion: (Applicability, Applicability, Span), | ^^^^^^^^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:295:5 + --> $DIR/diagnostic-derive.rs:297:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:446:44 + --> $DIR/diagnostic-derive.rs:448:53 | -LL | #[suggestion(suggestion, code = "...", applicability = "maybe-incorrect")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "maybe-incorrect")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:448:24 + --> $DIR/diagnostic-derive.rs:450:24 | LL | suggestion: (Span, Applicability), | ^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:454:44 + --> $DIR/diagnostic-derive.rs:456:53 | -LL | #[suggestion(suggestion, code = "...", applicability = "batman")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "...", applicability = "batman")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[label(foo)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:517:20 + --> $DIR/diagnostic-derive.rs:519:29 | -LL | #[label(label, foo)] - | ^^^ +LL | #[label(no_crate_label, foo)] + | ^^^ | = help: a diagnostic slug must be the first argument to the attribute error: `#[label(foo = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:525:20 + --> $DIR/diagnostic-derive.rs:527:29 | -LL | #[label(label, foo = "...")] - | ^^^^^^^^^^^ +LL | #[label(no_crate_label, foo = "...")] + | ^^^^^^^^^^^ error: `#[label(foo(...))]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:533:20 + --> $DIR/diagnostic-derive.rs:535:29 | -LL | #[label(label, foo("..."))] - | ^^^^^^^^^^ +LL | #[label(no_crate_label, foo("..."))] + | ^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:545:5 + --> $DIR/diagnostic-derive.rs:547:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -381,15 +381,15 @@ LL | #[primary_span] = help: the `primary_span` field attribute is not valid for lint diagnostics error: `#[error(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:565:1 + --> $DIR/diagnostic-derive.rs:567:1 | -LL | #[error(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:565:1 + --> $DIR/diagnostic-derive.rs:567:1 | -LL | / #[error(compiletest_example, code = "E0123")] +LL | / #[error(no_crate_example, code = "E0123")] LL | | LL | | LL | | @@ -399,15 +399,15 @@ LL | | struct ErrorAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[warn_(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:572:1 + --> $DIR/diagnostic-derive.rs:574:1 | -LL | #[warn_(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[warn_(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:572:1 + --> $DIR/diagnostic-derive.rs:574:1 | -LL | / #[warn_(compiletest_example, code = "E0123")] +LL | / #[warn_(no_crate_example, code = "E0123")] LL | | LL | | LL | | @@ -417,15 +417,15 @@ LL | | struct WarnAttribute {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:579:1 + --> $DIR/diagnostic-derive.rs:581:1 | -LL | #[lint(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:579:1 + --> $DIR/diagnostic-derive.rs:581:1 | -LL | / #[lint(compiletest_example, code = "E0123")] +LL | / #[lint(no_crate_example, code = "E0123")] LL | | LL | | LL | | @@ -435,21 +435,21 @@ LL | | struct LintAttributeOnSessionDiag {} = help: specify the slug as the first argument to the `#[diag(...)]` attribute, such as `#[diag(hir_analysis_example_error)]` error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:588:1 | -LL | #[lint(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[lint(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:588:1 | -LL | #[lint(compiletest_example, code = "E0123")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[lint(no_crate_example, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug not specified - --> $DIR/diagnostic-derive.rs:586:1 + --> $DIR/diagnostic-derive.rs:588:1 | -LL | / #[lint(compiletest_example, code = "E0123")] +LL | / #[lint(no_crate_example, code = "E0123")] LL | | LL | | LL | | @@ -460,19 +460,19 @@ LL | | struct LintAttributeOnLintDiag {} = help: specify the slug as the first argument to the attribute, such as `#[diag(compiletest_example)]` error: specified multiple times - --> $DIR/diagnostic-derive.rs:596:44 + --> $DIR/diagnostic-derive.rs:598:53 | -LL | #[suggestion(suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:596:30 + --> $DIR/diagnostic-derive.rs:598:39 | -LL | #[suggestion(suggestion, code = "...", code = ",,,")] - | ^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "...", code = ",,,")] + | ^^^^^^^^^^^^ error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:605:24 + --> $DIR/diagnostic-derive.rs:607:24 | LL | suggestion: (Span, usize), | ^^^^^ @@ -480,7 +480,7 @@ LL | suggestion: (Span, usize), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: wrong types for suggestion - --> $DIR/diagnostic-derive.rs:613:17 + --> $DIR/diagnostic-derive.rs:615:17 | LL | suggestion: (Span,), | ^^^^^^^ @@ -488,21 +488,21 @@ LL | suggestion: (Span,), = help: `#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)` error: suggestion without `code = "..."` - --> $DIR/diagnostic-derive.rs:620:5 + --> $DIR/diagnostic-derive.rs:622:5 | -LL | #[suggestion(suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:627:1 + --> $DIR/diagnostic-derive.rs:629:1 | -LL | #[multipart_suggestion(suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(no_crate_suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:630:1 + --> $DIR/diagnostic-derive.rs:632:1 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -510,23 +510,23 @@ LL | #[multipart_suggestion()] = help: consider creating a `Subdiagnostic` instead error: `#[multipart_suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:634:5 + --> $DIR/diagnostic-derive.rs:636:5 | -LL | #[multipart_suggestion(suggestion)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[multipart_suggestion(no_crate_suggestion)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider creating a `Subdiagnostic` instead error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:642:1 + --> $DIR/diagnostic-derive.rs:644:1 | -LL | #[suggestion(suggestion, code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[label]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:651:1 + --> $DIR/diagnostic-derive.rs:653:1 | LL | #[label] | ^^^^^^^^ @@ -534,7 +534,7 @@ LL | #[label] = help: `#[label]` and `#[suggestion]` can only be applied to fields error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:685:5 + --> $DIR/diagnostic-derive.rs:687:5 | LL | #[subdiagnostic(bad)] | ^^^^^^^^^^^^^^^^^^^^^ @@ -542,13 +542,13 @@ LL | #[subdiagnostic(bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:693:5 + --> $DIR/diagnostic-derive.rs:695:5 | LL | #[subdiagnostic = "bad"] | ^^^^^^^^^^^^^^^^^^^^^^^^ error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:701:5 + --> $DIR/diagnostic-derive.rs:703:5 | LL | #[subdiagnostic(bad, bad)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -556,7 +556,7 @@ LL | #[subdiagnostic(bad, bad)] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:709:5 + --> $DIR/diagnostic-derive.rs:711:5 | LL | #[subdiagnostic("bad")] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -564,7 +564,7 @@ LL | #[subdiagnostic("bad")] = help: `eager` is the only supported nested attribute for `subdiagnostic` error: `#[subdiagnostic(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:717:5 + --> $DIR/diagnostic-derive.rs:719:5 | LL | #[subdiagnostic(eager)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -572,95 +572,95 @@ LL | #[subdiagnostic(eager)] = help: eager subdiagnostics are not supported on lints error: expected at least one string literal for `code(...)` - --> $DIR/diagnostic-derive.rs:775:18 + --> $DIR/diagnostic-derive.rs:777:18 | LL | #[suggestion(code())] | ^^^^^^ error: `code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:783:23 + --> $DIR/diagnostic-derive.rs:785:23 | LL | #[suggestion(code(foo))] | ^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/diagnostic-derive.rs:791:18 + --> $DIR/diagnostic-derive.rs:793:18 | LL | #[suggestion(code = 3)] | ^^^^^^^^ error: `#[suggestion(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:806:5 + --> $DIR/diagnostic-derive.rs:808:5 | -LL | #[suggestion(suggestion, code = "")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_suggestion, code = "")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[suggestion(...)]` applied to `Vec` field is ambiguous = help: to show a suggestion consisting of multiple parts, use a `Subdiagnostic` annotated with `#[multipart_suggestion(...)]` = help: to show a variable set of suggestions, use a `Vec` of `Subdiagnostic`s annotated with `#[suggestion(...)]` error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:55:3 + --> $DIR/diagnostic-derive.rs:57:3 | -LL | #[nonsense(compiletest_example, code = "E0123")] +LL | #[nonsense(no_crate_example, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:145:7 + --> $DIR/diagnostic-derive.rs:147:7 | LL | #[nonsense] | ^^^^^^^^ error: cannot find attribute `error` in this scope - --> $DIR/diagnostic-derive.rs:565:3 + --> $DIR/diagnostic-derive.rs:567:3 | -LL | #[error(compiletest_example, code = "E0123")] +LL | #[error(no_crate_example, code = "E0123")] | ^^^^^ error: cannot find attribute `warn_` in this scope - --> $DIR/diagnostic-derive.rs:572:3 + --> $DIR/diagnostic-derive.rs:574:3 | -LL | #[warn_(compiletest_example, code = "E0123")] +LL | #[warn_(no_crate_example, code = "E0123")] | ^^^^^ help: a built-in attribute with a similar name exists: `warn` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:579:3 + --> $DIR/diagnostic-derive.rs:581:3 | -LL | #[lint(compiletest_example, code = "E0123")] +LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `lint` in this scope - --> $DIR/diagnostic-derive.rs:586:3 + --> $DIR/diagnostic-derive.rs:588:3 | -LL | #[lint(compiletest_example, code = "E0123")] +LL | #[lint(no_crate_example, code = "E0123")] | ^^^^ help: a built-in attribute with a similar name exists: `link` error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:627:3 + --> $DIR/diagnostic-derive.rs:629:3 | -LL | #[multipart_suggestion(suggestion)] +LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:630:3 + --> $DIR/diagnostic-derive.rs:632:3 | LL | #[multipart_suggestion()] | ^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `multipart_suggestion` in this scope - --> $DIR/diagnostic-derive.rs:634:7 + --> $DIR/diagnostic-derive.rs:636:7 | -LL | #[multipart_suggestion(suggestion)] +LL | #[multipart_suggestion(no_crate_suggestion)] | ^^^^^^^^^^^^^^^^^^^^ -error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent` - --> $DIR/diagnostic-derive.rs:68:8 +error[E0425]: cannot find value `nonsense` in module `crate::fluent_generated` + --> $DIR/diagnostic-derive.rs:70:8 | LL | #[diag(nonsense, code = "E0123")] - | ^^^^^^^^ not found in `rustc_errors::fluent` + | ^^^^^^^^ not found in `crate::fluent_generated` error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:339:10 + --> $DIR/diagnostic-derive.rs:341:10 | LL | #[derive(Diagnostic)] | ^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` diff --git a/tests/ui-fulldeps/session-diagnostic/example.ftl b/tests/ui-fulldeps/session-diagnostic/example.ftl new file mode 100644 index 00000000000..cb2d476d815 --- /dev/null +++ b/tests/ui-fulldeps/session-diagnostic/example.ftl @@ -0,0 +1,5 @@ +no_crate_example = this is an example message used in testing + .note = with a note + .help = with a help + .suggestion = with a suggestion + .label = with a label diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index 09ad6964909..c882f7792d5 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -15,12 +15,14 @@ extern crate rustc_macros; extern crate rustc_session; extern crate rustc_span; -use rustc_errors::Applicability; -use rustc_macros::Subdiagnostic; +use rustc_errors::{Applicability, DiagnosticMessage, SubdiagnosticMessage}; +use rustc_macros::{fluent_messages, Subdiagnostic}; use rustc_span::Span; +fluent_messages! { "./example.ftl" } + #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct A { #[primary_span] span: Span, @@ -29,13 +31,13 @@ struct A { #[derive(Subdiagnostic)] enum B { - #[label(parse_add_paren)] + #[label(no_crate_example)] A { #[primary_span] span: Span, var: String, }, - #[label(parse_add_paren)] + #[label(no_crate_example)] B { #[primary_span] span: Span, @@ -44,7 +46,7 @@ enum B { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] //~^ ERROR label without `#[primary_span]` field struct C { var: String, @@ -120,8 +122,8 @@ struct K { #[derive(Subdiagnostic)] #[label(slug)] -//~^ ERROR cannot find value `slug` in module `rustc_errors::fluent` -//~^^ NOTE not found in `rustc_errors::fluent` +//~^ ERROR cannot find value `slug` in module `crate::fluent_generated` +//~^^ NOTE not found in `crate::fluent_generated` struct L { #[primary_span] span: Span, @@ -138,7 +140,7 @@ struct M { } #[derive(Subdiagnostic)] -#[label(parse_add_paren, code = "...")] +#[label(no_crate_example, code = "...")] //~^ ERROR `#[label(code = ...)]` is not a valid attribute struct N { #[primary_span] @@ -147,7 +149,7 @@ struct N { } #[derive(Subdiagnostic)] -#[label(parse_add_paren, applicability = "machine-applicable")] +#[label(no_crate_example, applicability = "machine-applicable")] //~^ ERROR `#[label(applicability = ...)]` is not a valid attribute struct O { #[primary_span] @@ -160,7 +162,7 @@ struct O { //~^ ERROR cannot find attribute `foo` in this scope //~^^ ERROR unsupported type attribute for subdiagnostic enum enum P { - #[label(parse_add_paren)] + #[label(no_crate_example)] A { #[primary_span] span: Span, @@ -230,7 +232,7 @@ enum U { #[derive(Subdiagnostic)] enum V { - #[label(parse_add_paren)] + #[label(no_crate_example)] A { #[primary_span] span: Span, @@ -244,7 +246,7 @@ enum V { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] //~^ ERROR label without `#[primary_span]` field struct W { #[primary_span] @@ -253,7 +255,7 @@ struct W { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct X { #[primary_span] span: Span, @@ -263,7 +265,7 @@ struct X { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct Y { #[primary_span] span: Span, @@ -274,7 +276,7 @@ struct Y { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct Z { #[primary_span] span: Span, @@ -285,7 +287,7 @@ struct Z { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct AA { #[primary_span] span: Span, @@ -296,7 +298,7 @@ struct AA { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct AB { #[primary_span] span: Span, @@ -312,23 +314,23 @@ union AC { } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] -#[label(parse_add_paren)] +#[label(no_crate_example)] +#[label(no_crate_example)] struct AD { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[label(parse_add_paren, parse_add_paren)] -//~^ ERROR `#[label(parse_add_paren)]` is not a valid attribute +#[label(no_crate_example, no_crate::example)] +//~^ ERROR `#[label(no_crate::example)]` is not a valid attribute struct AE { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct AF { #[primary_span] //~^ NOTE previously specified here @@ -346,7 +348,7 @@ struct AG { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] struct AH { #[primary_span] span: Span, @@ -357,7 +359,7 @@ struct AH { #[derive(Subdiagnostic)] enum AI { - #[suggestion(parse_add_paren, code = "...")] + #[suggestion(no_crate_example, code = "...")] A { #[primary_span] span: Span, @@ -365,7 +367,7 @@ enum AI { applicability: Applicability, var: String, }, - #[suggestion(parse_add_paren, code = "...")] + #[suggestion(no_crate_example, code = "...")] B { #[primary_span] span: Span, @@ -376,7 +378,7 @@ enum AI { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...", code = "...")] +#[suggestion(no_crate_example, code = "...", code = "...")] //~^ ERROR specified multiple times //~^^ NOTE previously specified here struct AJ { @@ -387,7 +389,7 @@ struct AJ { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] struct AK { #[primary_span] span: Span, @@ -400,7 +402,7 @@ struct AK { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] struct AL { #[primary_span] span: Span, @@ -410,14 +412,14 @@ struct AL { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] struct AM { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren)] +#[suggestion(no_crate_example)] //~^ ERROR suggestion without `code = "..."` struct AN { #[primary_span] @@ -427,7 +429,7 @@ struct AN { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...", applicability = "foo")] +#[suggestion(no_crate_example, code = "...", applicability = "foo")] //~^ ERROR invalid applicability struct AO { #[primary_span] @@ -435,24 +437,24 @@ struct AO { } #[derive(Subdiagnostic)] -#[help(parse_add_paren)] +#[help(no_crate_example)] struct AP { var: String, } #[derive(Subdiagnostic)] -#[note(parse_add_paren)] +#[note(no_crate_example)] struct AQ; #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] //~^ ERROR suggestion without `#[primary_span]` field struct AR { var: String, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")] +#[suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] struct AS { #[primary_span] span: Span, @@ -462,7 +464,7 @@ struct AS { #[label] //~^ ERROR unsupported type attribute for subdiagnostic enum enum AT { - #[label(parse_add_paren)] + #[label(no_crate_example)] A { #[primary_span] span: Span, @@ -471,7 +473,7 @@ enum AT { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] +#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] struct AU { #[primary_span] span: Span, @@ -479,7 +481,7 @@ struct AU { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] +#[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] //~^ ERROR `var` doesn't refer to a field on this type struct AV { #[primary_span] @@ -488,7 +490,7 @@ struct AV { #[derive(Subdiagnostic)] enum AW { - #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] + #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] A { #[primary_span] span: Span, @@ -498,7 +500,7 @@ enum AW { #[derive(Subdiagnostic)] enum AX { - #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] + #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] //~^ ERROR `var` doesn't refer to a field on this type A { #[primary_span] @@ -507,18 +509,18 @@ enum AX { } #[derive(Subdiagnostic)] -#[warning(parse_add_paren)] +#[warning(no_crate_example)] struct AY {} #[derive(Subdiagnostic)] -#[warning(parse_add_paren)] +#[warning(no_crate_example)] struct AZ { #[primary_span] span: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "...")] +#[suggestion(no_crate_example, code = "...")] //~^ ERROR suggestion without `#[primary_span]` field struct BA { #[suggestion_part] @@ -533,7 +535,7 @@ struct BA { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] //~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields //~| ERROR `#[multipart_suggestion(code = ...)]` is not a valid attribute struct BBa { @@ -541,7 +543,7 @@ struct BBa { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BBb { #[suggestion_part] //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` @@ -549,7 +551,7 @@ struct BBb { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BBc { #[suggestion_part()] //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` @@ -557,7 +559,7 @@ struct BBc { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] //~^ ERROR multipart suggestion without any `#[suggestion_part(...)]` fields struct BC { #[primary_span] @@ -566,7 +568,7 @@ struct BC { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BD { #[suggestion_part] //~^ ERROR `#[suggestion_part(...)]` attribute without `code = "..."` @@ -586,7 +588,7 @@ struct BD { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BE { #[suggestion_part(code = "...", code = ",,,")] //~^ ERROR specified multiple times @@ -595,7 +597,7 @@ struct BE { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BF { #[suggestion_part(code = "(")] first: Span, @@ -604,7 +606,7 @@ struct BF { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BG { #[applicability] appl: Applicability, @@ -615,7 +617,7 @@ struct BG { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BH { #[applicability] //~^ ERROR `#[applicability]` has no effect @@ -627,14 +629,14 @@ struct BH { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren, applicability = "machine-applicable")] +#[multipart_suggestion(no_crate_example, applicability = "machine-applicable")] struct BI { #[suggestion_part(code = "")] spans: Vec<Span>, } #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct BJ { #[primary_span] span: Span, @@ -643,7 +645,7 @@ struct BJ { /// with a doc comment on the type.. #[derive(Subdiagnostic)] -#[label(parse_add_paren)] +#[label(no_crate_example)] struct BK { /// ..and the field #[primary_span] @@ -654,7 +656,7 @@ struct BK { #[derive(Subdiagnostic)] enum BL { /// ..and the variant.. - #[label(parse_add_paren)] + #[label(no_crate_example)] Foo { /// ..and the field #[primary_span] @@ -663,7 +665,7 @@ enum BL { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BM { #[suggestion_part(code("foo"))] //~^ ERROR expected exactly one string literal for `code = ...` @@ -672,7 +674,7 @@ struct BM { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BN { #[suggestion_part(code("foo", "bar"))] //~^ ERROR expected exactly one string literal for `code = ...` @@ -681,7 +683,7 @@ struct BN { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BO { #[suggestion_part(code(3))] //~^ ERROR expected exactly one string literal for `code = ...` @@ -690,7 +692,7 @@ struct BO { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BP { #[suggestion_part(code())] //~^ ERROR expected exactly one string literal for `code = ...` @@ -699,7 +701,7 @@ struct BP { } #[derive(Subdiagnostic)] -#[multipart_suggestion(parse_add_paren)] +#[multipart_suggestion(no_crate_example)] struct BQ { #[suggestion_part(code = 3)] //~^ ERROR `code = "..."`/`code(...)` must contain only string literals @@ -708,42 +710,42 @@ struct BQ { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "")] +#[suggestion(no_crate_example, code = "")] struct SuggestionStyleDefault { #[primary_span] sub: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "short")] +#[suggestion(no_crate_example, code = "", style = "short")] struct SuggestionStyleShort { #[primary_span] sub: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "hidden")] +#[suggestion(no_crate_example, code = "", style = "hidden")] struct SuggestionStyleHidden { #[primary_span] sub: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "verbose")] +#[suggestion(no_crate_example, code = "", style = "verbose")] struct SuggestionStyleVerbose { #[primary_span] sub: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "tool-only")] +#[suggestion(no_crate_example, code = "", style = "tool-only")] struct SuggestionStyleToolOnly { #[primary_span] sub: Span, } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")] +#[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] //~^ ERROR specified multiple times //~| NOTE previously specified here struct SuggestionStyleTwice { @@ -752,7 +754,7 @@ struct SuggestionStyleTwice { } #[derive(Subdiagnostic)] -#[suggestion_hidden(parse_add_paren, code = "")] +#[suggestion_hidden(no_crate_example, code = "")] //~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute struct SuggestionStyleOldSyntax { #[primary_span] @@ -760,7 +762,7 @@ struct SuggestionStyleOldSyntax { } #[derive(Subdiagnostic)] -#[suggestion_hidden(parse_add_paren, code = "", style = "normal")] +#[suggestion_hidden(no_crate_example, code = "", style = "normal")] //~^ ERROR #[suggestion_hidden(...)]` is not a valid attribute struct SuggestionStyleOldAndNewSyntax { #[primary_span] @@ -768,7 +770,7 @@ struct SuggestionStyleOldAndNewSyntax { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = "foo")] +#[suggestion(no_crate_example, code = "", style = "foo")] //~^ ERROR invalid suggestion style struct SuggestionStyleInvalid1 { #[primary_span] @@ -776,7 +778,7 @@ struct SuggestionStyleInvalid1 { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style = 42)] +#[suggestion(no_crate_example, code = "", style = 42)] //~^ ERROR `#[suggestion(style = ...)]` is not a valid attribute struct SuggestionStyleInvalid2 { #[primary_span] @@ -784,7 +786,7 @@ struct SuggestionStyleInvalid2 { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style)] +#[suggestion(no_crate_example, code = "", style)] //~^ ERROR `#[suggestion(style)]` is not a valid attribute struct SuggestionStyleInvalid3 { #[primary_span] @@ -792,7 +794,7 @@ struct SuggestionStyleInvalid3 { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "", style("foo"))] +#[suggestion(no_crate_example, code = "", style("foo"))] //~^ ERROR `#[suggestion(style(...))]` is not a valid attribute struct SuggestionStyleInvalid4 { #[primary_span] @@ -800,7 +802,7 @@ struct SuggestionStyleInvalid4 { } #[derive(Subdiagnostic)] -#[suggestion(parse_add_paren, code = "")] +#[suggestion(no_crate_example, code = "")] //~^ ERROR suggestion without `#[primary_span]` field struct PrimarySpanOnVec { #[primary_span] diff --git a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index f9d1a63031d..343134af6bc 100644 --- a/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/tests/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,7 +1,7 @@ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:47:1 + --> $DIR/subdiagnostic-derive.rs:49:1 | -LL | / #[label(parse_add_paren)] +LL | / #[label(no_crate_example)] LL | | LL | | struct C { LL | | var: String, @@ -9,141 +9,141 @@ LL | | } | |_^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:54:1 + --> $DIR/subdiagnostic-derive.rs:56:1 | LL | #[label] | ^^^^^^^^ error: `#[foo]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:63:1 + --> $DIR/subdiagnostic-derive.rs:65:1 | LL | #[foo] | ^^^^^^ error: `#[label = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:73:1 + --> $DIR/subdiagnostic-derive.rs:75:1 | LL | #[label = "..."] | ^^^^^^^^^^^^^^^^ error: `#[label(bug = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:82:9 + --> $DIR/subdiagnostic-derive.rs:84:9 | LL | #[label(bug = "...")] | ^^^^^^^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:82:1 + --> $DIR/subdiagnostic-derive.rs:84:1 | LL | #[label(bug = "...")] | ^^^^^^^^^^^^^^^^^^^^^ error: `#[label("...")]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:92:9 + --> $DIR/subdiagnostic-derive.rs:94:9 | LL | #[label("...")] | ^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:92:1 + --> $DIR/subdiagnostic-derive.rs:94:1 | LL | #[label("...")] | ^^^^^^^^^^^^^^^ error: `#[label(slug = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:102:9 + --> $DIR/subdiagnostic-derive.rs:104:9 | LL | #[label(slug = 4)] | ^^^^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:102:1 + --> $DIR/subdiagnostic-derive.rs:104:1 | LL | #[label(slug = 4)] | ^^^^^^^^^^^^^^^^^^ error: `#[label(slug(...))]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:112:9 + --> $DIR/subdiagnostic-derive.rs:114:9 | LL | #[label(slug("..."))] | ^^^^^^^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:112:1 + --> $DIR/subdiagnostic-derive.rs:114:1 | LL | #[label(slug("..."))] | ^^^^^^^^^^^^^^^^^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:132:1 + --> $DIR/subdiagnostic-derive.rs:134:1 | LL | #[label()] | ^^^^^^^^^^ error: `#[label(code = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:141:26 + --> $DIR/subdiagnostic-derive.rs:143:27 | -LL | #[label(parse_add_paren, code = "...")] - | ^^^^^^^^^^^^ +LL | #[label(no_crate_example, code = "...")] + | ^^^^^^^^^^^^ error: `#[label(applicability = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:150:26 + --> $DIR/subdiagnostic-derive.rs:152:27 | -LL | #[label(parse_add_paren, applicability = "machine-applicable")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(no_crate_example, applicability = "machine-applicable")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:159:1 + --> $DIR/subdiagnostic-derive.rs:161:1 | LL | #[foo] | ^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:173:5 + --> $DIR/subdiagnostic-derive.rs:175:5 | LL | #[bar] | ^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:185:5 + --> $DIR/subdiagnostic-derive.rs:187:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:197:5 + --> $DIR/subdiagnostic-derive.rs:199:5 | LL | #[bar = 4] | ^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:209:5 + --> $DIR/subdiagnostic-derive.rs:211:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ error: `#[label(code = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:221:13 + --> $DIR/subdiagnostic-derive.rs:223:13 | LL | #[label(code = "...")] | ^^^^^^^^^^^^ error: diagnostic slug must be first argument of a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:221:5 + --> $DIR/subdiagnostic-derive.rs:223:5 | LL | #[label(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:250:5 + --> $DIR/subdiagnostic-derive.rs:252:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:247:1 + --> $DIR/subdiagnostic-derive.rs:249:1 | -LL | / #[label(parse_add_paren)] +LL | / #[label(no_crate_example)] LL | | LL | | struct W { LL | | #[primary_span] @@ -153,13 +153,13 @@ LL | | } | |_^ error: `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:260:5 + --> $DIR/subdiagnostic-derive.rs:262:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:270:5 + --> $DIR/subdiagnostic-derive.rs:272:5 | LL | #[bar] | ^^^^^^ @@ -167,13 +167,13 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:281:5 + --> $DIR/subdiagnostic-derive.rs:283:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:292:5 + --> $DIR/subdiagnostic-derive.rs:294:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ @@ -181,7 +181,7 @@ LL | #[bar("...")] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive.rs:308:1 + --> $DIR/subdiagnostic-derive.rs:310:1 | LL | / union AC { LL | | @@ -190,78 +190,78 @@ LL | | b: u64, LL | | } | |_^ -error: `#[label(parse_add_paren)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:323:26 +error: `#[label(no_crate::example)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:325:27 | -LL | #[label(parse_add_paren, parse_add_paren)] - | ^^^^^^^^^^^^^^^ +LL | #[label(no_crate_example, no_crate::example)] + | ^^^^^^^^^^^^^^^^^ | = help: a diagnostic slug must be the first argument to the attribute error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:336:5 + --> $DIR/subdiagnostic-derive.rs:338:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:333:5 + --> $DIR/subdiagnostic-derive.rs:335:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:342:8 + --> $DIR/subdiagnostic-derive.rs:344:8 | LL | struct AG { | ^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:379:45 + --> $DIR/subdiagnostic-derive.rs:381:46 | -LL | #[suggestion(parse_add_paren, code = "...", code = "...")] - | ^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "...", code = "...")] + | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:379:31 + --> $DIR/subdiagnostic-derive.rs:381:32 | -LL | #[suggestion(parse_add_paren, code = "...", code = "...")] - | ^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "...", code = "...")] + | ^^^^^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:397:5 + --> $DIR/subdiagnostic-derive.rs:399:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:394:5 + --> $DIR/subdiagnostic-derive.rs:396:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:407:5 + --> $DIR/subdiagnostic-derive.rs:409:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:420:1 + --> $DIR/subdiagnostic-derive.rs:422:1 | -LL | #[suggestion(parse_add_paren)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:430:45 + --> $DIR/subdiagnostic-derive.rs:432:46 | -LL | #[suggestion(parse_add_paren, code = "...", applicability = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "...", applicability = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:448:1 + --> $DIR/subdiagnostic-derive.rs:450:1 | -LL | / #[suggestion(parse_add_paren, code = "...")] +LL | / #[suggestion(no_crate_example, code = "...")] LL | | LL | | struct AR { LL | | var: String, @@ -269,25 +269,25 @@ LL | | } | |_^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:462:1 + --> $DIR/subdiagnostic-derive.rs:464:1 | LL | #[label] | ^^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:482:38 + --> $DIR/subdiagnostic-derive.rs:484:39 | -LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:501:42 + --> $DIR/subdiagnostic-derive.rs:503:43 | -LL | #[suggestion(parse_add_paren, code = "{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(no_crate_example, code = "{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: `#[suggestion_part]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:524:5 + --> $DIR/subdiagnostic-derive.rs:526:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ @@ -295,7 +295,7 @@ LL | #[suggestion_part] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead error: `#[suggestion_part(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:527:5 + --> $DIR/subdiagnostic-derive.rs:529:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -303,9 +303,9 @@ LL | #[suggestion_part(code = "...")] = help: `#[suggestion_part(...)]` is only valid in multipart suggestions error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:521:1 + --> $DIR/subdiagnostic-derive.rs:523:1 | -LL | / #[suggestion(parse_add_paren, code = "...")] +LL | / #[suggestion(no_crate_example, code = "...")] LL | | LL | | struct BA { LL | | #[suggestion_part] @@ -315,17 +315,17 @@ LL | | } | |_^ error: `#[multipart_suggestion(code = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:536:41 + --> $DIR/subdiagnostic-derive.rs:538:42 | -LL | #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")] - | ^^^^^^^^^^^^ +LL | #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] + | ^^^^^^^^^^^^ | = help: only `style` and `applicability` are valid nested attributes error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:536:1 + --> $DIR/subdiagnostic-derive.rs:538:1 | -LL | / #[multipart_suggestion(parse_add_paren, code = "...", applicability = "machine-applicable")] +LL | / #[multipart_suggestion(no_crate_example, code = "...", applicability = "machine-applicable")] LL | | LL | | LL | | struct BBa { @@ -334,19 +334,19 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:546:5 + --> $DIR/subdiagnostic-derive.rs:548:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:554:5 + --> $DIR/subdiagnostic-derive.rs:556:5 | LL | #[suggestion_part()] | ^^^^^^^^^^^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:563:5 + --> $DIR/subdiagnostic-derive.rs:565:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -354,9 +354,9 @@ LL | #[primary_span] = help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]` error: multipart suggestion without any `#[suggestion_part(...)]` fields - --> $DIR/subdiagnostic-derive.rs:560:1 + --> $DIR/subdiagnostic-derive.rs:562:1 | -LL | / #[multipart_suggestion(parse_add_paren)] +LL | / #[multipart_suggestion(no_crate_example)] LL | | LL | | struct BC { LL | | #[primary_span] @@ -366,19 +366,19 @@ LL | | } | |_^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:571:5 + --> $DIR/subdiagnostic-derive.rs:573:5 | LL | #[suggestion_part] | ^^^^^^^^^^^^^^^^^^ error: `#[suggestion_part(...)]` attribute without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:574:5 + --> $DIR/subdiagnostic-derive.rs:576:5 | LL | #[suggestion_part()] | ^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion_part(foo = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:577:23 + --> $DIR/subdiagnostic-derive.rs:579:23 | LL | #[suggestion_part(foo = "bar")] | ^^^^^^^^^^^ @@ -386,123 +386,123 @@ LL | #[suggestion_part(foo = "bar")] = help: `code` is the only valid nested attribute error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:580:5 + --> $DIR/subdiagnostic-derive.rs:582:5 | LL | #[suggestion_part(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan` - --> $DIR/subdiagnostic-derive.rs:583:5 + --> $DIR/subdiagnostic-derive.rs:585:5 | LL | #[suggestion_part()] | ^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:591:37 + --> $DIR/subdiagnostic-derive.rs:593:37 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:591:23 + --> $DIR/subdiagnostic-derive.rs:593:23 | LL | #[suggestion_part(code = "...", code = ",,,")] | ^^^^^^^^^^^^ error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."` - --> $DIR/subdiagnostic-derive.rs:620:5 + --> $DIR/subdiagnostic-derive.rs:622:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:668:23 + --> $DIR/subdiagnostic-derive.rs:670:23 | LL | #[suggestion_part(code("foo"))] | ^^^^^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:677:23 + --> $DIR/subdiagnostic-derive.rs:679:23 | LL | #[suggestion_part(code("foo", "bar"))] | ^^^^^^^^^^^^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:686:23 + --> $DIR/subdiagnostic-derive.rs:688:23 | LL | #[suggestion_part(code(3))] | ^^^^^^^ error: expected exactly one string literal for `code = ...` - --> $DIR/subdiagnostic-derive.rs:695:23 + --> $DIR/subdiagnostic-derive.rs:697:23 | LL | #[suggestion_part(code())] | ^^^^^^ error: `code = "..."`/`code(...)` must contain only string literals - --> $DIR/subdiagnostic-derive.rs:704:23 + --> $DIR/subdiagnostic-derive.rs:706:23 | LL | #[suggestion_part(code = 3)] | ^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:746:60 + --> $DIR/subdiagnostic-derive.rs:748:61 | -LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")] - | ^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] + | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:746:42 + --> $DIR/subdiagnostic-derive.rs:748:43 | -LL | #[suggestion(parse_add_paren, code = "", style = "hidden", style = "normal")] - | ^^^^^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "", style = "hidden", style = "normal")] + | ^^^^^^^^^^^^^^^^ error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:755:1 + --> $DIR/subdiagnostic-derive.rs:757:1 | -LL | #[suggestion_hidden(parse_add_paren, code = "")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion_hidden(no_crate_example, code = "")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: Use `#[suggestion(..., style = "hidden")]` instead error: `#[suggestion_hidden(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:763:1 + --> $DIR/subdiagnostic-derive.rs:765:1 | -LL | #[suggestion_hidden(parse_add_paren, code = "", style = "normal")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion_hidden(no_crate_example, code = "", style = "normal")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: Use `#[suggestion(..., style = "hidden")]` instead error: invalid suggestion style - --> $DIR/subdiagnostic-derive.rs:771:50 + --> $DIR/subdiagnostic-derive.rs:773:51 | -LL | #[suggestion(parse_add_paren, code = "", style = "foo")] - | ^^^^^ +LL | #[suggestion(no_crate_example, code = "", style = "foo")] + | ^^^^^ | = help: valid styles are `normal`, `short`, `hidden`, `verbose` and `tool-only` error: `#[suggestion(style = ...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:779:42 + --> $DIR/subdiagnostic-derive.rs:781:43 | -LL | #[suggestion(parse_add_paren, code = "", style = 42)] - | ^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "", style = 42)] + | ^^^^^^^^^^ error: `#[suggestion(style)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:787:42 + --> $DIR/subdiagnostic-derive.rs:789:43 | -LL | #[suggestion(parse_add_paren, code = "", style)] - | ^^^^^ +LL | #[suggestion(no_crate_example, code = "", style)] + | ^^^^^ | = help: a diagnostic slug must be the first argument to the attribute error: `#[suggestion(style(...))]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:795:42 + --> $DIR/subdiagnostic-derive.rs:797:43 | -LL | #[suggestion(parse_add_paren, code = "", style("foo"))] - | ^^^^^^^^^^^^ +LL | #[suggestion(no_crate_example, code = "", style("foo"))] + | ^^^^^^^^^^^^ error: `#[primary_span]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:806:5 + --> $DIR/subdiagnostic-derive.rs:808:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ @@ -511,9 +511,9 @@ LL | #[primary_span] = help: to create a suggestion with multiple spans, use `#[multipart_suggestion]` instead error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:803:1 + --> $DIR/subdiagnostic-derive.rs:805:1 | -LL | / #[suggestion(parse_add_paren, code = "")] +LL | / #[suggestion(no_crate_example, code = "")] LL | | LL | | struct PrimarySpanOnVec { LL | | #[primary_span] @@ -523,64 +523,64 @@ LL | | } | |_^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:63:3 + --> $DIR/subdiagnostic-derive.rs:65:3 | LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:159:3 + --> $DIR/subdiagnostic-derive.rs:161:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:173:7 + --> $DIR/subdiagnostic-derive.rs:175:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:185:7 + --> $DIR/subdiagnostic-derive.rs:187:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:197:7 + --> $DIR/subdiagnostic-derive.rs:199:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:209:7 + --> $DIR/subdiagnostic-derive.rs:211:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:270:7 + --> $DIR/subdiagnostic-derive.rs:272:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:281:7 + --> $DIR/subdiagnostic-derive.rs:283:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:292:7 + --> $DIR/subdiagnostic-derive.rs:294:7 | LL | #[bar("...")] | ^^^ -error[E0425]: cannot find value `slug` in module `rustc_errors::fluent` - --> $DIR/subdiagnostic-derive.rs:122:9 +error[E0425]: cannot find value `slug` in module `crate::fluent_generated` + --> $DIR/subdiagnostic-derive.rs:124:9 | LL | #[label(slug)] - | ^^^^ not found in `rustc_errors::fluent` + | ^^^^ not found in `crate::fluent_generated` error: aborting due to 81 previous errors diff --git a/tests/ui-fulldeps/issue-15149.rs b/tests/ui-fulldeps/std/issue-15149.rs index 064472f5785..064472f5785 100644 --- a/tests/ui-fulldeps/issue-15149.rs +++ b/tests/ui-fulldeps/std/issue-15149.rs diff --git a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs index fdf1150f8d2..fdf1150f8d2 100644 --- a/tests/ui-fulldeps/issue-81357-unsound-file-methods.rs +++ b/tests/ui-fulldeps/std/issue-81357-unsound-file-methods.rs diff --git a/tests/ui-fulldeps/stdio-from.rs b/tests/ui-fulldeps/std/stdio-from.rs index fef9f27fcdf..fef9f27fcdf 100644 --- a/tests/ui-fulldeps/stdio-from.rs +++ b/tests/ui-fulldeps/std/stdio-from.rs diff --git a/tests/ui-fulldeps/switch-stdout.rs b/tests/ui-fulldeps/std/switch-stdout.rs index e9501a80930..e9501a80930 100644 --- a/tests/ui-fulldeps/switch-stdout.rs +++ b/tests/ui-fulldeps/std/switch-stdout.rs diff --git a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr index d1b9d7a40b4..eb739b149a1 100644 --- a/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr +++ b/tests/ui/alloc-error/alloc-error-handler-bad-signature-3.stderr @@ -7,10 +7,7 @@ LL | fn oom() -> ! { | _-^^^^^^^^^^^^ LL | | loop {} LL | | } - | | - - | | | - | |_unexpected argument of type `core::alloc::Layout` - | help: remove the extra argument + | |_- unexpected argument of type `core::alloc::Layout` | note: function defined here --> $DIR/alloc-error-handler-bad-signature-3.rs:10:4 diff --git a/tests/ui/argument-suggestions/extra_arguments.rs b/tests/ui/argument-suggestions/extra_arguments.rs index 3f83de95e2d..1442062326d 100644 --- a/tests/ui/argument-suggestions/extra_arguments.rs +++ b/tests/ui/argument-suggestions/extra_arguments.rs @@ -3,8 +3,15 @@ fn one_arg(_a: i32) {} fn two_arg_same(_a: i32, _b: i32) {} fn two_arg_diff(_a: i32, _b: &str) {} +macro_rules! foo { + ($x:expr) => { + empty($x, 1); //~ ERROR function takes + } +} + fn main() { empty(""); //~ ERROR function takes + empty(1, 1); //~ ERROR function takes one_arg(1, 1); //~ ERROR function takes one_arg(1, ""); //~ ERROR function takes @@ -32,4 +39,5 @@ fn main() { 1, "" ); + foo!(1); } diff --git a/tests/ui/argument-suggestions/extra_arguments.stderr b/tests/ui/argument-suggestions/extra_arguments.stderr index 0911685b428..11c71099743 100644 --- a/tests/ui/argument-suggestions/extra_arguments.stderr +++ b/tests/ui/argument-suggestions/extra_arguments.stderr @@ -1,5 +1,5 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied - --> $DIR/extra_arguments.rs:7:3 + --> $DIR/extra_arguments.rs:13:3 | LL | empty(""); | ^^^^^ -- @@ -13,8 +13,27 @@ note: function defined here LL | fn empty() {} | ^^^^^ +error[E0061]: this function takes 0 arguments but 2 arguments were supplied + --> $DIR/extra_arguments.rs:14:3 + | +LL | empty(1, 1); + | ^^^^^ - - unexpected argument of type `{integer}` + | | + | unexpected argument of type `{integer}` + | +note: function defined here + --> $DIR/extra_arguments.rs:1:4 + | +LL | fn empty() {} + | ^^^^^ +help: remove the extra arguments + | +LL - empty(1, 1); +LL + empty(); + | + error[E0061]: this function takes 1 argument but 2 arguments were supplied - --> $DIR/extra_arguments.rs:9:3 + --> $DIR/extra_arguments.rs:16:3 | LL | one_arg(1, 1); | ^^^^^^^ --- @@ -29,7 +48,7 @@ LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- error[E0061]: this function takes 1 argument but 2 arguments were supplied - --> $DIR/extra_arguments.rs:10:3 + --> $DIR/extra_arguments.rs:17:3 | LL | one_arg(1, ""); | ^^^^^^^ ---- @@ -44,7 +63,7 @@ LL | fn one_arg(_a: i32) {} | ^^^^^^^ ------- error[E0061]: this function takes 1 argument but 3 arguments were supplied - --> $DIR/extra_arguments.rs:11:3 + --> $DIR/extra_arguments.rs:18:3 | LL | one_arg(1, "", 1.0); | ^^^^^^^ -- --- unexpected argument of type `{float}` @@ -63,7 +82,7 @@ LL + one_arg(1); | error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:13:3 + --> $DIR/extra_arguments.rs:20:3 | LL | two_arg_same(1, 1, 1); | ^^^^^^^^^^^^ --- @@ -78,7 +97,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:14:3 + --> $DIR/extra_arguments.rs:21:3 | LL | two_arg_same(1, 1, 1.0); | ^^^^^^^^^^^^ ----- @@ -93,7 +112,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:16:3 + --> $DIR/extra_arguments.rs:23:3 | LL | two_arg_diff(1, 1, ""); | ^^^^^^^^^^^^ --- @@ -108,7 +127,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:17:3 + --> $DIR/extra_arguments.rs:24:3 | LL | two_arg_diff(1, "", ""); | ^^^^^^^^^^^^ ---- @@ -123,7 +142,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- error[E0061]: this function takes 2 arguments but 4 arguments were supplied - --> $DIR/extra_arguments.rs:18:3 + --> $DIR/extra_arguments.rs:25:3 | LL | two_arg_diff(1, 1, "", ""); | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` @@ -142,7 +161,7 @@ LL + two_arg_diff(1, ""); | error[E0061]: this function takes 2 arguments but 4 arguments were supplied - --> $DIR/extra_arguments.rs:19:3 + --> $DIR/extra_arguments.rs:26:3 | LL | two_arg_diff(1, "", 1, ""); | ^^^^^^^^^^^^ - -- unexpected argument of type `&'static str` @@ -161,7 +180,7 @@ LL + two_arg_diff(1, ""); | error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:22:3 + --> $DIR/extra_arguments.rs:29:3 | LL | two_arg_same(1, 1, ""); | ^^^^^^^^^^^^ -------- @@ -176,7 +195,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:23:3 + --> $DIR/extra_arguments.rs:30:3 | LL | two_arg_diff(1, 1, ""); | ^^^^^^^^^^^^ --- @@ -191,7 +210,7 @@ LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:24:3 + --> $DIR/extra_arguments.rs:31:3 | LL | two_arg_same( | ^^^^^^^^^^^^ @@ -211,7 +230,7 @@ LL | fn two_arg_same(_a: i32, _b: i32) {} | ^^^^^^^^^^^^ ------- ------- error[E0061]: this function takes 2 arguments but 3 arguments were supplied - --> $DIR/extra_arguments.rs:30:3 + --> $DIR/extra_arguments.rs:37:3 | LL | two_arg_diff( | ^^^^^^^^^^^^ @@ -229,6 +248,26 @@ note: function defined here LL | fn two_arg_diff(_a: i32, _b: &str) {} | ^^^^^^^^^^^^ ------- -------- -error: aborting due to 14 previous errors +error[E0061]: this function takes 0 arguments but 2 arguments were supplied + --> $DIR/extra_arguments.rs:8:9 + | +LL | empty($x, 1); + | ^^^^^ - unexpected argument of type `{integer}` +... +LL | foo!(1); + | ------- + | | | + | | unexpected argument of type `{integer}` + | | help: remove the extra argument + | in this macro invocation + | +note: function defined here + --> $DIR/extra_arguments.rs:1:4 + | +LL | fn empty() {} + | ^^^^^ + = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0061`. diff --git a/tests/ui/argument-suggestions/issue-100154.stderr b/tests/ui/argument-suggestions/issue-100154.stderr index 1499229c3ce..2504f616fb7 100644 --- a/tests/ui/argument-suggestions/issue-100154.stderr +++ b/tests/ui/argument-suggestions/issue-100154.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-100154.rs:4:5 | LL | foo::<()>(()); diff --git a/tests/ui/argument-suggestions/too-long.stderr b/tests/ui/argument-suggestions/too-long.stderr index 4928943294b..bb6f06a35c6 100644 --- a/tests/ui/argument-suggestions/too-long.stderr +++ b/tests/ui/argument-suggestions/too-long.stderr @@ -6,7 +6,7 @@ LL | qux.foo(a, b, c, d, e, f, g, h, i, j, k, l); | | | arguments to this method are incorrect | -note: associated function defined here +note: method defined here --> $DIR/too-long.rs:4:8 | LL | fn foo( diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr index 08570d4a5d9..bbafc55dac3 100644 --- a/tests/ui/associated-consts/issue-105330.stderr +++ b/tests/ui/associated-consts/issue-105330.stderr @@ -33,7 +33,7 @@ LL | fn main<A: TraitWAssocConst<A=32>>() { = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/issue-105330.rs:6:27 | LL | impl TraitWAssocConst for impl Demo { diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs new file mode 100644 index 00000000000..8cab1f66c27 --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.rs @@ -0,0 +1,14 @@ +#![feature(associated_type_bounds)] + +trait B { + type AssocType; +} + +fn f() +where + dyn for<'j> B<AssocType: 'j>:, + //~^ ERROR associated type bounds are only allowed in where clauses and function signatures +{ +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr new file mode 100644 index 00000000000..6fa266d23d4 --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-dyn-in-where-clause.stderr @@ -0,0 +1,8 @@ +error: associated type bounds are only allowed in where clauses and function signatures, not in bounds + --> $DIR/bad-universal-in-dyn-in-where-clause.rs:9:19 + | +LL | dyn for<'j> B<AssocType: 'j>:, + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs new file mode 100644 index 00000000000..1d5d181efcc --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.rs @@ -0,0 +1,13 @@ +#![feature(associated_type_bounds)] + +trait Trait { + type Item; +} + +trait Trait2 {} + +// It's not possible to insert a universal `impl Trait` here! +impl dyn Trait<Item: Trait2> {} +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures + +fn main() {} diff --git a/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr new file mode 100644 index 00000000000..8b66627d57f --- /dev/null +++ b/tests/ui/associated-type-bounds/bad-universal-in-impl-sig.stderr @@ -0,0 +1,8 @@ +error: associated type bounds are only allowed in where clauses and function signatures, not in impl headers + --> $DIR/bad-universal-in-impl-sig.rs:10:16 + | +LL | impl dyn Trait<Item: Trait2> {} + | ^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/tests/ui/associated-type-bounds/inside-adt.rs b/tests/ui/associated-type-bounds/inside-adt.rs index 8eb8c44bb42..057966941dc 100644 --- a/tests/ui/associated-type-bounds/inside-adt.rs +++ b/tests/ui/associated-type-bounds/inside-adt.rs @@ -3,28 +3,24 @@ use std::mem::ManuallyDrop; struct S1 { f: dyn Iterator<Item: Copy> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures struct S2 { f: Box<dyn Iterator<Item: Copy>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures struct S3 { f: dyn Iterator<Item: 'static> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E1 { V(dyn Iterator<Item: Copy>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E2 { V(Box<dyn Iterator<Item: Copy>>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures enum E3 { V(dyn Iterator<Item: 'static>) } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } -//~^ ERROR associated type bounds are not allowed within structs, enums, or unions -//~| ERROR the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` +//~^ ERROR associated type bounds are only allowed in where clauses and function signatures fn main() {} diff --git a/tests/ui/associated-type-bounds/inside-adt.stderr b/tests/ui/associated-type-bounds/inside-adt.stderr index 1668b613b25..f848bd798ee 100644 --- a/tests/ui/associated-type-bounds/inside-adt.stderr +++ b/tests/ui/associated-type-bounds/inside-adt.stderr @@ -1,131 +1,56 @@ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:5:29 | LL | struct S1 { f: dyn Iterator<Item: Copy> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:7:33 | LL | struct S2 { f: Box<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:9:29 | LL | struct S3 { f: dyn Iterator<Item: 'static> } | ^^^^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions +error: associated type bounds are only allowed in where clauses and function signatures, not in field types --> $DIR/inside-adt.rs:12:26 | LL | enum E1 { V(dyn Iterator<Item: Copy>) } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:15:30 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:14:30 | LL | enum E2 { V(Box<dyn Iterator<Item: Copy>>) } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:17:26 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:16:26 | LL | enum E3 { V(dyn Iterator<Item: 'static>) } | ^^^^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:21:41 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:19:41 | LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:24:45 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:21:45 | LL | union U2 { f: ManuallyDrop<Box<dyn Iterator<Item: Copy>>> } | ^^^^^^^^^^ -error: associated type bounds are not allowed within structs, enums, or unions - --> $DIR/inside-adt.rs:26:41 +error: associated type bounds are only allowed in where clauses and function signatures, not in field types + --> $DIR/inside-adt.rs:23:41 | LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } | ^^^^^^^^^^^^^ -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:12:13 - | -LL | enum E1 { V(dyn Iterator<Item: Copy>) } - | ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)` - = note: no field of an enum variant may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | enum E1 { V(&dyn Iterator<Item: Copy>) } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | enum E1 { V(Box<dyn Iterator<Item: Copy>>) } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:17:13 - | -LL | enum E3 { V(dyn Iterator<Item: 'static>) } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)` - = note: no field of an enum variant may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | enum E3 { V(&dyn Iterator<Item: 'static>) } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | enum E3 { V(Box<dyn Iterator<Item: 'static>>) } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Copy> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:21:15 - | -LL | union U1 { f: ManuallyDrop<dyn Iterator<Item: Copy>> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `ManuallyDrop<(dyn Iterator<Item = impl Copy> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Copy> + 'static)` - = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Copy>>` - = note: no field of a union may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | union U1 { f: &ManuallyDrop<dyn Iterator<Item: Copy>> } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | union U1 { f: Box<ManuallyDrop<dyn Iterator<Item: Copy>>> } - | ++++ + - -error[E0277]: the size for values of type `(dyn Iterator<Item = impl Sized + 'static> + 'static)` cannot be known at compilation time - --> $DIR/inside-adt.rs:26:15 - | -LL | union U3 { f: ManuallyDrop<dyn Iterator<Item: 'static>> } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: within `ManuallyDrop<(dyn Iterator<Item = impl Sized + 'static> + 'static)>`, the trait `Sized` is not implemented for `(dyn Iterator<Item = impl Sized + 'static> + 'static)` - = note: required because it appears within the type `ManuallyDrop<dyn Iterator<Item = impl Sized>>` - = note: no field of a union may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size - | -LL | union U3 { f: &ManuallyDrop<dyn Iterator<Item: 'static>> } - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | union U3 { f: Box<ManuallyDrop<dyn Iterator<Item: 'static>>> } - | ++++ + - -error: aborting due to 13 previous errors +error: aborting due to 9 previous errors -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr b/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr index 5fe53a27eb8..3f3bf22b0c4 100644 --- a/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr +++ b/tests/ui/associated-types/associated-type-projection-from-supertrait.stderr @@ -34,7 +34,7 @@ LL | fn f() { ModelT.chip_paint(Blue); } | | | arguments to this method are incorrect | -note: associated function defined here +note: method defined here --> $DIR/associated-type-projection-from-supertrait.rs:12:8 | LL | fn chip_paint(&self, c: Self::Color) { } @@ -48,7 +48,7 @@ LL | fn g() { ModelU.chip_paint(Black); } | | | arguments to this method are incorrect | -note: associated function defined here +note: method defined here --> $DIR/associated-type-projection-from-supertrait.rs:12:8 | LL | fn chip_paint(&self, c: Self::Color) { } diff --git a/tests/ui/associated-types/associated-types-eq-hr.stderr b/tests/ui/associated-types/associated-types-eq-hr.stderr index 99db0c1bf3b..3e1142d5d95 100644 --- a/tests/ui/associated-types/associated-types-eq-hr.stderr +++ b/tests/ui/associated-types/associated-types-eq-hr.stderr @@ -15,7 +15,7 @@ note: required by a bound in `foo` --> $DIR/associated-types-eq-hr.rs:45:36 | LL | fn foo<T>() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | T: for<'x> TheTrait<&'x isize, A = &'x isize>, | ^^^^^^^^^^^^^ required by this bound in `foo` @@ -37,7 +37,7 @@ note: required by a bound in `bar` --> $DIR/associated-types-eq-hr.rs:52:36 | LL | fn bar<T>() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | T: for<'x> TheTrait<&'x isize, A = &'x usize>, | ^^^^^^^^^^^^^ required by this bound in `bar` diff --git a/tests/ui/associated-types/defaults-suitability.stderr b/tests/ui/associated-types/defaults-suitability.stderr index eadad4cd572..2485758757b 100644 --- a/tests/ui/associated-types/defaults-suitability.stderr +++ b/tests/ui/associated-types/defaults-suitability.stderr @@ -27,7 +27,7 @@ LL | Self::Ty: Clone, | ^^^^^ required by this bound in `Tr2::Ty` LL | { LL | type Ty = NotClone; - | -- required by a bound in this + | -- required by a bound in this associated type help: consider annotating `NotClone` with `#[derive(Clone)]` | LL | #[derive(Clone)] @@ -75,7 +75,7 @@ LL | Self::Assoc: IsU8<Self::Assoc>, | ^^^^^^^^^^^^^^^^^ required by this bound in `D::Assoc` ... LL | type Assoc = NotClone; - | ----- required by a bound in this + | ----- required by a bound in this associated type error[E0277]: the trait bound `<Self as Foo2<T>>::Baz: Clone` is not satisfied --> $DIR/defaults-suitability.rs:65:23 @@ -124,7 +124,7 @@ LL | Self::Baz: Clone, | ^^^^^ required by this bound in `Foo3::Baz` ... LL | type Baz = T; - | --- required by a bound in this + | --- required by a bound in this associated type help: consider further restricting type parameter `T` | LL | Self::Baz: Clone, T: std::clone::Clone diff --git a/tests/ui/associated-types/hr-associated-type-bound-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-1.stderr index 73b5e1053fb..b380a1b6f06 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-1.stderr @@ -9,7 +9,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-1.rs:3:33 | LL | trait X<'a> - | - required by a bound in this + | - required by a bound in this trait LL | where LL | for<'b> <Self as X<'b>>::U: Clone, | ^^^^^ required by this bound in `X` diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr index 6d19186bde4..a0a6f76a583 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr @@ -8,7 +8,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-object.rs:3:33 | LL | trait X<'a> - | - required by a bound in this + | - required by a bound in this trait LL | where LL | for<'b> <Self as X<'b>>::U: Clone, | ^^^^^ required by this bound in `X` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr index af2e616896a..e249f2e0c27 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-1.stderr @@ -9,7 +9,7 @@ note: required by a bound in `Y` --> $DIR/hr-associated-type-bound-param-1.rs:4:36 | LL | trait Y<'a, T: ?Sized> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <Self as Y<'b, T>>::V: Clone, | ^^^^^ required by this bound in `Y` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr index 52294f8c94a..366670269d7 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-2.stderr @@ -9,7 +9,7 @@ note: required by a bound in `Z` --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T as Z<'b, u16>>::W: Clone, | ^^^^^ required by this bound in `Z` @@ -25,7 +25,7 @@ note: required by a bound in `Z` --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T as Z<'b, u16>>::W: Clone, | ^^^^^ required by this bound in `Z` @@ -41,7 +41,7 @@ note: required by a bound in `Z` --> $DIR/hr-associated-type-bound-param-2.rs:6:35 | LL | trait Z<'a, T: ?Sized> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T as Z<'b, u16>>::W: Clone, | ^^^^^ required by this bound in `Z` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr index 84d5e0494cb..f49439d3573 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-3.stderr @@ -9,7 +9,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-param-3.rs:4:33 | LL | trait X<'a, T> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T as X<'b, T>>::U: Clone, | ^^^^^ required by this bound in `X` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr index ee1d5d32495..f8733b423d7 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-4.stderr @@ -9,7 +9,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-param-4.rs:4:36 | LL | trait X<'a, T> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <(T,) as X<'b, T>>::U: Clone, | ^^^^^ required by this bound in `X` diff --git a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr index ece3151ba97..aae80a9b2e1 100644 --- a/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr +++ b/tests/ui/associated-types/hr-associated-type-bound-param-5.stderr @@ -9,7 +9,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-param-5.rs:17:45 | LL | trait X<'a, T: Cycle + for<'b> X<'b, T>> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone, | ^^^^^ required by this bound in `X` @@ -25,7 +25,7 @@ note: required by a bound in `X` --> $DIR/hr-associated-type-bound-param-5.rs:17:45 | LL | trait X<'a, T: Cycle + for<'b> X<'b, T>> - | - required by a bound in this + | - required by a bound in this trait ... LL | for<'b> <T::Next as X<'b, T::Next>>::U: Clone, | ^^^^^ required by this bound in `X` diff --git a/tests/ui/associated-types/hr-associated-type-projection-1.stderr b/tests/ui/associated-types/hr-associated-type-projection-1.stderr index 2281d9419b4..dd0389c34e6 100644 --- a/tests/ui/associated-types/hr-associated-type-projection-1.stderr +++ b/tests/ui/associated-types/hr-associated-type-projection-1.stderr @@ -10,7 +10,7 @@ note: required by a bound in `UnsafeCopy` --> $DIR/hr-associated-type-projection-1.rs:3:64 | LL | trait UnsafeCopy<'a, T: Copy> - | ---------- required by a bound in this + | ---------- required by a bound in this trait LL | where LL | for<'b> <Self as UnsafeCopy<'b, T>>::Item: std::ops::Deref<Target = T>, | ^^^^^^^^^^ required by this bound in `UnsafeCopy` diff --git a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr index 2e7a1dd2a31..3b4689e08cc 100644 --- a/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr +++ b/tests/ui/associated-types/point-at-type-on-obligation-failure-2.stderr @@ -23,7 +23,7 @@ LL | Self::Assoc: Bar, | ^^^ required by this bound in `Baz::Assoc` LL | { LL | type Assoc; - | ----- required by a bound in this + | ----- required by a bound in this associated type error[E0277]: the trait bound `bool: Bar` is not satisfied --> $DIR/point-at-type-on-obligation-failure-2.rs:30:18 @@ -38,7 +38,7 @@ LL | <Self as Bat>::Assoc: Bar, | ^^^ required by this bound in `Bat::Assoc` LL | { LL | type Assoc; - | ----- required by a bound in this + | ----- required by a bound in this associated type error: aborting due to 3 previous errors diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.rs b/tests/ui/async-await/in-trait/fn-not-async-err2.rs index 2c4ed553580..78017429f73 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.rs +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.rs @@ -11,7 +11,7 @@ trait MyTrait { impl MyTrait for i32 { fn foo(&self) -> impl Future<Output = i32> { - //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return [E0562] + //~^ ERROR `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types async { *self } } } diff --git a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr index f591f184772..37d9669c012 100644 --- a/tests/ui/async-await/in-trait/fn-not-async-err2.stderr +++ b/tests/ui/async-await/in-trait/fn-not-async-err2.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types --> $DIR/fn-not-async-err2.rs:13:22 | LL | fn foo(&self) -> impl Future<Output = i32> { diff --git a/tests/ui/async-await/issues/issue-62097.rs b/tests/ui/async-await/issues/issue-62097.rs index a24c84cffc7..13c72abb136 100644 --- a/tests/ui/async-await/issues/issue-62097.rs +++ b/tests/ui/async-await/issues/issue-62097.rs @@ -12,7 +12,7 @@ impl Struct { pub async fn run_dummy_fn(&self) { foo(|| self.bar()).await; //~^ ERROR closure may outlive the current function - //~| ERROR borrowed data escapes outside of associated function + //~| ERROR borrowed data escapes outside of method } pub fn bar(&self) {} diff --git a/tests/ui/async-await/issues/issue-62097.stderr b/tests/ui/async-await/issues/issue-62097.stderr index 786f6213260..21a61548d01 100644 --- a/tests/ui/async-await/issues/issue-62097.stderr +++ b/tests/ui/async-await/issues/issue-62097.stderr @@ -16,18 +16,18 @@ help: to force the closure to take ownership of `self` (and any other referenced LL | foo(move || self.bar()).await; | ++++ -error[E0521]: borrowed data escapes outside of associated function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-62097.rs:13:9 | LL | pub async fn run_dummy_fn(&self) { | ----- | | - | `self` is a reference that is only valid in the associated function body + | `self` is a reference that is only valid in the method body | let's call the lifetime of this reference `'1` LL | foo(|| self.bar()).await; | ^^^^^^^^^^^^^^^^^^ | | - | `self` escapes the associated function body here + | `self` escapes the method body here | argument requires that `'1` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/async-await/issues/issue-65159.rs b/tests/ui/async-await/issues/issue-65159.rs index df2ca025705..6e547508bd4 100644 --- a/tests/ui/async-await/issues/issue-65159.rs +++ b/tests/ui/async-await/issues/issue-65159.rs @@ -3,7 +3,7 @@ // edition:2018 async fn copy() -> Result<()> -//~^ ERROR this enum takes 2 generic arguments +//~^ ERROR enum takes 2 generic arguments { Ok(()) } diff --git a/tests/ui/async-await/issues/issue-65159.stderr b/tests/ui/async-await/issues/issue-65159.stderr index 40c0e72b203..b8741333c32 100644 --- a/tests/ui/async-await/issues/issue-65159.stderr +++ b/tests/ui/async-await/issues/issue-65159.stderr @@ -1,4 +1,4 @@ -error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied --> $DIR/issue-65159.rs:5:20 | LL | async fn copy() -> Result<()> diff --git a/tests/ui/async-await/issues/issue-72312.stderr b/tests/ui/async-await/issues/issue-72312.stderr index aa947b69003..679272858bd 100644 --- a/tests/ui/async-await/issues/issue-72312.stderr +++ b/tests/ui/async-await/issues/issue-72312.stderr @@ -1,10 +1,10 @@ -error[E0521]: borrowed data escapes outside of associated function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-72312.rs:12:9 | LL | pub async fn start(&self) { | ----- | | - | `self` is a reference that is only valid in the associated function body + | `self` is a reference that is only valid in the method body | let's call the lifetime of this reference `'1` ... LL | / require_static(async move { @@ -15,7 +15,7 @@ LL | | &self; LL | | }); | | ^ | | | - | |__________`self` escapes the associated function body here + | |__________`self` escapes the method body here | argument requires that `'1` must outlive `'static` error: aborting due to previous error diff --git a/tests/ui/attributes/invalid_macro_export_argument.rs b/tests/ui/attributes/invalid_macro_export_argument.rs new file mode 100644 index 00000000000..85d009f11a6 --- /dev/null +++ b/tests/ui/attributes/invalid_macro_export_argument.rs @@ -0,0 +1,26 @@ +// check-pass +#[macro_export(hello, world)] //~ WARN `#[macro_export]` can only take 1 or 0 arguments +macro_rules! a { + () => () +} + +#[macro_export(not_local_inner_macros)] //~ WARN `not_local_inner_macros` isn't a valid `#[macro_export]` argument +macro_rules! b { + () => () +} + +#[macro_export] +macro_rules! c { + () => () +} +#[macro_export(local_inner_macros)] +macro_rules! d { + () => () +} + +#[macro_export()] +macro_rules! e { + () => () +} + +fn main() {} diff --git a/tests/ui/attributes/invalid_macro_export_argument.stderr b/tests/ui/attributes/invalid_macro_export_argument.stderr new file mode 100644 index 00000000000..a4e17642c2a --- /dev/null +++ b/tests/ui/attributes/invalid_macro_export_argument.stderr @@ -0,0 +1,16 @@ +warning: `#[macro_export]` can only take 1 or 0 arguments + --> $DIR/invalid_macro_export_argument.rs:2:1 + | +LL | #[macro_export(hello, world)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(invalid_macro_export_arguments)]` on by default + +warning: `not_local_inner_macros` isn't a valid `#[macro_export]` argument + --> $DIR/invalid_macro_export_argument.rs:7:16 + | +LL | #[macro_export(not_local_inner_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +warning: 2 warnings emitted + diff --git a/tests/ui/auto-traits/auto-trait-validation.stderr b/tests/ui/auto-traits/auto-trait-validation.stderr index 2c380e5b09a..89b63d23d4c 100644 --- a/tests/ui/auto-traits/auto-trait-validation.stderr +++ b/tests/ui/auto-traits/auto-trait-validation.stderr @@ -12,7 +12,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Bound : Copy {} | -----^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error[E0568]: auto traits cannot have super traits or lifetime bounds --> $DIR/auto-trait-validation.rs:9:25 @@ -20,7 +20,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait LifetimeBound : 'static {} | -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error[E0380]: auto traits cannot have associated items --> $DIR/auto-trait-validation.rs:11:25 @@ -29,7 +29,7 @@ LL | auto trait MyTrait { fn foo() {} } | ------- ---^^^----- | | | | | help: remove these associated items - | auto trait cannot have associated items + | auto traits cannot have associated items error: aborting due to 4 previous errors diff --git a/tests/ui/auto-traits/issue-23080-2.stderr b/tests/ui/auto-traits/issue-23080-2.stderr index 267a712f62f..fed485612da 100644 --- a/tests/ui/auto-traits/issue-23080-2.stderr +++ b/tests/ui/auto-traits/issue-23080-2.stderr @@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items --> $DIR/issue-23080-2.rs:5:10 | LL | unsafe auto trait Trait { - | ----- auto trait cannot have associated items + | ----- auto traits cannot have associated items LL | type Output; | -----^^^^^^- help: remove these associated items diff --git a/tests/ui/auto-traits/issue-23080.stderr b/tests/ui/auto-traits/issue-23080.stderr index c1b16b2f403..f5d607298b7 100644 --- a/tests/ui/auto-traits/issue-23080.stderr +++ b/tests/ui/auto-traits/issue-23080.stderr @@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items --> $DIR/issue-23080.rs:5:8 | LL | unsafe auto trait Trait { - | ----- auto trait cannot have associated items + | ----- auto traits cannot have associated items LL | fn method(&self) { | _____- ^^^^^^ LL | | println!("Hello"); diff --git a/tests/ui/auto-traits/issue-84075.stderr b/tests/ui/auto-traits/issue-84075.stderr index 02dca598ec2..6fbdc669b6f 100644 --- a/tests/ui/auto-traits/issue-84075.stderr +++ b/tests/ui/auto-traits/issue-84075.stderr @@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Magic where Self: Copy {} | ----- ^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error: aborting due to previous error diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.rs b/tests/ui/auto-traits/str-contains-slice-conceptually.rs new file mode 100644 index 00000000000..6a16fdcf284 --- /dev/null +++ b/tests/ui/auto-traits/str-contains-slice-conceptually.rs @@ -0,0 +1,13 @@ +#![feature(negative_impls)] +#![feature(auto_traits)] + +auto trait AutoTrait {} + +impl<T> !AutoTrait for [T] {} + +fn needs_auto_trait<T: AutoTrait + ?Sized>() {} + +fn main() { + needs_auto_trait::<str>(); + //~^ ERROR the trait bound `[u8]: AutoTrait` is not satisfied in `str` +} diff --git a/tests/ui/auto-traits/str-contains-slice-conceptually.stderr b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr new file mode 100644 index 00000000000..1cf16cebddd --- /dev/null +++ b/tests/ui/auto-traits/str-contains-slice-conceptually.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `[u8]: AutoTrait` is not satisfied in `str` + --> $DIR/str-contains-slice-conceptually.rs:11:22 + | +LL | needs_auto_trait::<str>(); + | ^^^ within `str`, the trait `AutoTrait` is not implemented for `[u8]` + | + = note: `str` is considered to contain a `[u8]` slice for auto trait purposes +note: required by a bound in `needs_auto_trait` + --> $DIR/str-contains-slice-conceptually.rs:8:24 + | +LL | fn needs_auto_trait<T: AutoTrait + ?Sized>() {} + | ^^^^^^^^^ required by this bound in `needs_auto_trait` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr index 4827916fa5c..547b4bb5448 100644 --- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr +++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr @@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Magic : Sized where Option<Self> : Magic {} | -----^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error[E0568]: auto traits cannot have super traits or lifetime bounds --> $DIR/typeck-auto-trait-no-supertraits-2.rs:4:26 @@ -12,7 +12,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Magic : Sized where Option<Self> : Magic {} | ----- ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error: aborting due to 2 previous errors diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr index d7716f4b61f..80f07410381 100644 --- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr +++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits.stderr @@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Magic: Copy {} | -----^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error: aborting due to previous error diff --git a/tests/ui/borrowck/issue-103624.rs b/tests/ui/borrowck/issue-103624.rs index f1fa95f9246..d95a40bd4a0 100644 --- a/tests/ui/borrowck/issue-103624.rs +++ b/tests/ui/borrowck/issue-103624.rs @@ -12,7 +12,7 @@ impl StructA { async fn foo(&self) { let bar = self.b.bar().await; spawn_blocking(move || { - //~^ ERROR borrowed data escapes outside of associated function + //~^ ERROR borrowed data escapes outside of method self.b; //~^ ERROR cannot move out of `self.b`, as `self` is a captured variable in an `Fn` closure }) diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr index e6a35dd8801..7a281e8aa30 100644 --- a/tests/ui/borrowck/issue-103624.stderr +++ b/tests/ui/borrowck/issue-103624.stderr @@ -10,13 +10,13 @@ LL | LL | self.b; | ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait -error[E0521]: borrowed data escapes outside of associated function +error[E0521]: borrowed data escapes outside of method --> $DIR/issue-103624.rs:14:9 | LL | async fn foo(&self) { | ----- | | - | `self` is a reference that is only valid in the associated function body + | `self` is a reference that is only valid in the method body | let's call the lifetime of this reference `'1` LL | let bar = self.b.bar().await; LL | / spawn_blocking(move || { @@ -26,7 +26,7 @@ LL | | LL | | }) | | ^ | | | - | |__________`self` escapes the associated function body here + | |__________`self` escapes the method body here | argument requires that `'1` must outlive `'static` error: aborting due to 2 previous errors diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs index dd0320bc53b..d067ff44704 100644 --- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs +++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.rs @@ -14,8 +14,8 @@ impl MarketMultiplier { } async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> { - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied - //~^^ ERROR this struct takes 1 generic argument but 0 generic arguments were supplied + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied + //~^^ ERROR struct takes 1 generic argument but 0 generic arguments were supplied LockedMarket(generator.lock().unwrap().buy()) } diff --git a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr index d2b927fb664..73e0aaf1e45 100644 --- a/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr +++ b/tests/ui/borrowck/issue-82126-mismatched-subst-and-hir.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59 | LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> { @@ -12,7 +12,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct LockedMarket<T>(T); | ^^^^^^^^^^^^ -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/issue-82126-mismatched-subst-and-hir.rs:16:59 | LL | async fn buy_lock(generator: &Mutex<MarketMultiplier>) -> LockedMarket<'_> { diff --git a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr index 8dccf929b2b..c5089295063 100644 --- a/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr +++ b/tests/ui/closure-expected-type/expect-infer-var-appearing-twice.stderr @@ -12,7 +12,7 @@ note: required by a bound in `with_closure` --> $DIR/expect-infer-var-appearing-twice.rs:2:14 | LL | fn with_closure<F, A>(_: F) - | ------------ required by a bound in this + | ------------ required by a bound in this function LL | where F: FnOnce(A, A) | ^^^^^^^^^^^^ required by this bound in `with_closure` diff --git a/tests/ui/const-generics/defaults/wfness.stderr b/tests/ui/const-generics/defaults/wfness.stderr index 25038f830be..bd9bfcd7dad 100644 --- a/tests/ui/const-generics/defaults/wfness.stderr +++ b/tests/ui/const-generics/defaults/wfness.stderr @@ -23,7 +23,7 @@ note: required by a bound in `WhereClause` --> $DIR/wfness.rs:8:9 | LL | struct WhereClause<const N: u8 = 2> - | ----------- required by a bound in this + | ----------- required by a bound in this struct LL | where LL | (): Trait<N>; | ^^^^^^^^ required by this bound in `WhereClause` diff --git a/tests/ui/const-generics/ensure_is_evaluatable.stderr b/tests/ui/const-generics/ensure_is_evaluatable.stderr index bf6c35ad8fd..ab2871ff281 100644 --- a/tests/ui/const-generics/ensure_is_evaluatable.stderr +++ b/tests/ui/const-generics/ensure_is_evaluatable.stderr @@ -9,7 +9,7 @@ note: required by a bound in `bar` --> $DIR/ensure_is_evaluatable.rs:15:10 | LL | fn bar<const N: usize>() -> [(); N] - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | [(); N + 1]:, | ^^^^^ required by this bound in `bar` diff --git a/tests/ui/const-generics/fn_with_two_const_inputs.stderr b/tests/ui/const-generics/fn_with_two_const_inputs.stderr index 614e7e0d2fc..c124010aab0 100644 --- a/tests/ui/const-generics/fn_with_two_const_inputs.stderr +++ b/tests/ui/const-generics/fn_with_two_const_inputs.stderr @@ -9,7 +9,7 @@ note: required by a bound in `bar` --> $DIR/fn_with_two_const_inputs.rs:18:10 | LL | fn bar<const N: usize>() -> [(); N] - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | [(); N + 1]:, | ^^^^^ required by this bound in `bar` diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs index 7aea0d30d1a..18a9b53cf76 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.rs @@ -7,8 +7,8 @@ trait X { const _: () = { fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} - //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR this associated type takes 0 generic arguments but 1 generic argument + //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments + //~| ERROR associated type takes 0 generic arguments but 1 generic argument }; fn main() {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr index 8278edabe3a..175d54e4184 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-102768.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/issue-102768.rs:9:30 | LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} @@ -14,7 +14,7 @@ help: add missing lifetime argument LL | fn f2<'a>(arg: Box<dyn X<Y<'_, 1> = &'a ()>>) {} | +++ -error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-102768.rs:9:30 | LL | fn f2<'a>(arg: Box<dyn X<Y<1> = &'a ()>>) {} diff --git a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr index 0be4c43daac..827dd59d9ad 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-105608.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-105608.rs:13:22 | LL | Combination::<0>.and::<_>().and::<_>(); - | ^^^ cannot infer type of the type parameter `M` declared on the associated function `and` + | ^^^ cannot infer type of the type parameter `M` declared on the method `and` | help: consider specifying the generic argument | diff --git a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr index f2fddfbfbb5..996b75493e6 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-72819-generic-in-const-eval.full.stderr @@ -10,7 +10,7 @@ note: required by a bound in `Arr` --> $DIR/issue-72819-generic-in-const-eval.rs:8:39 | LL | struct Arr<const N: usize> - | --- required by a bound in this + | --- required by a bound in this struct LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` @@ -26,7 +26,7 @@ note: required by a bound in `Arr` --> $DIR/issue-72819-generic-in-const-eval.rs:8:39 | LL | struct Arr<const N: usize> - | --- required by a bound in this + | --- required by a bound in this struct LL | where Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` diff --git a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr index c587a7e153f..302da59651c 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-76595.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied --> $DIR/issue-76595.rs:15:5 | LL | test::<2>(); diff --git a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr index a253ec676f7..63e6fcc8e11 100644 --- a/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr +++ b/tests/ui/const-generics/generic_const_exprs/obligation-cause.stderr @@ -10,7 +10,7 @@ note: required by a bound in `g` --> $DIR/obligation-cause.rs:13:44 | LL | fn g<T>() - | - required by a bound in this + | - required by a bound in this function ... LL | Is<{ std::mem::size_of::<T>() == 0 }>: True, | ^^^^ required by this bound in `g` diff --git a/tests/ui/const-generics/incorrect-number-of-const-args.stderr b/tests/ui/const-generics/incorrect-number-of-const-args.stderr index a845454f762..01ac4e69a05 100644 --- a/tests/ui/const-generics/incorrect-number-of-const-args.stderr +++ b/tests/ui/const-generics/incorrect-number-of-const-args.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied --> $DIR/incorrect-number-of-const-args.rs:6:5 | LL | foo::<0>(); @@ -16,7 +16,7 @@ help: add missing generic argument LL | foo::<0, Y>(); | +++ -error[E0107]: this function takes 2 generic arguments but 3 generic arguments were supplied +error[E0107]: function takes 2 generic arguments but 3 generic arguments were supplied --> $DIR/incorrect-number-of-const-args.rs:9:5 | LL | foo::<0, 0, 0>(); diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index ff6da535bd2..f527ee6e4f5 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/method-chain.rs:15:33 | LL | Foo.bar().bar().bar().bar().baz(); - | ^^^ cannot infer the value of the const parameter `N` declared on the associated function `baz` + | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | help: consider specifying the generic argument | diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index 3980ecea863..20daf45706b 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/uninferred-consts.rs:9:9 | LL | Foo.foo(); - | ^^^ cannot infer the value of the const parameter `A` declared on the associated function `foo` + | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | help: consider specifying the generic arguments | diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs index 7d4dc98f396..bf10f471dc5 100644 --- a/tests/ui/const-generics/invalid-const-arg-for-type-param.rs +++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.rs @@ -4,11 +4,11 @@ struct S; fn main() { let _: u32 = 5i32.try_into::<32>().unwrap(); - //~^ ERROR this associated function takes + //~^ ERROR method takes S.f::<0>(); //~^ ERROR no method named `f` S::<0>; - //~^ ERROR this struct takes 0 + //~^ ERROR struct takes 0 } diff --git a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr index 8c76ca69029..4a649d8a7e8 100644 --- a/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr +++ b/tests/ui/const-generics/invalid-const-arg-for-type-param.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/invalid-const-arg-for-type-param.rs:6:23 | LL | let _: u32 = 5i32.try_into::<32>().unwrap(); @@ -23,7 +23,7 @@ LL | struct S; LL | S.f::<0>(); | ^ method not found in `S` -error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/invalid-const-arg-for-type-param.rs:12:5 | LL | S::<0>; diff --git a/tests/ui/const-generics/invalid-constant-in-args.rs b/tests/ui/const-generics/invalid-constant-in-args.rs index 7419d4a25ce..fd259197d29 100644 --- a/tests/ui/const-generics/invalid-constant-in-args.rs +++ b/tests/ui/const-generics/invalid-constant-in-args.rs @@ -2,5 +2,5 @@ use std::cell::Cell; fn main() { let _: Cell<&str, "a"> = Cell::new(""); - //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied + //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied } diff --git a/tests/ui/const-generics/invalid-constant-in-args.stderr b/tests/ui/const-generics/invalid-constant-in-args.stderr index 993b63518e4..2545cc6f396 100644 --- a/tests/ui/const-generics/invalid-constant-in-args.stderr +++ b/tests/ui/const-generics/invalid-constant-in-args.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied --> $DIR/invalid-constant-in-args.rs:4:12 | LL | let _: Cell<&str, "a"> = Cell::new(""); diff --git a/tests/ui/const-generics/issues/issue-67185-2.stderr b/tests/ui/const-generics/issues/issue-67185-2.stderr index c7be8e14a10..032b0c41047 100644 --- a/tests/ui/const-generics/issues/issue-67185-2.stderr +++ b/tests/ui/const-generics/issues/issue-67185-2.stderr @@ -35,7 +35,7 @@ note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:15:25 | LL | trait Foo - | --- required by a bound in this + | --- required by a bound in this trait ... LL | <u8 as Baz>::Quaks: Bar, | ^^^ required by this bound in `Foo` @@ -53,7 +53,7 @@ note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:14:30 | LL | trait Foo - | --- required by a bound in this + | --- required by a bound in this trait LL | where LL | [<u8 as Baz>::Quaks; 2]: Bar, | ^^^ required by this bound in `Foo` @@ -71,7 +71,7 @@ note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:14:30 | LL | trait Foo - | --- required by a bound in this + | --- required by a bound in this trait LL | where LL | [<u8 as Baz>::Quaks; 2]: Bar, | ^^^ required by this bound in `Foo` @@ -89,7 +89,7 @@ note: required by a bound in `Foo` --> $DIR/issue-67185-2.rs:15:25 | LL | trait Foo - | --- required by a bound in this + | --- required by a bound in this trait ... LL | <u8 as Baz>::Quaks: Bar, | ^^^ required by this bound in `Foo` diff --git a/tests/ui/const-generics/issues/issue-73260.stderr b/tests/ui/const-generics/issues/issue-73260.stderr index f9ff0f28d51..c56b45cc8fa 100644 --- a/tests/ui/const-generics/issues/issue-73260.stderr +++ b/tests/ui/const-generics/issues/issue-73260.stderr @@ -10,7 +10,7 @@ note: required by a bound in `Arr` --> $DIR/issue-73260.rs:5:37 | LL | struct Arr<const N: usize> - | --- required by a bound in this + | --- required by a bound in this struct LL | where LL | Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` @@ -27,7 +27,7 @@ note: required by a bound in `Arr` --> $DIR/issue-73260.rs:5:37 | LL | struct Arr<const N: usize> - | --- required by a bound in this + | --- required by a bound in this struct LL | where LL | Assert::<{N < usize::MAX / 2}>: IsTrue, | ^^^^^^ required by this bound in `Arr` diff --git a/tests/ui/const-generics/issues/issue-79674.stderr b/tests/ui/const-generics/issues/issue-79674.stderr index 02b48b55f8b..ba7fd2ca3cc 100644 --- a/tests/ui/const-generics/issues/issue-79674.stderr +++ b/tests/ui/const-generics/issues/issue-79674.stderr @@ -10,7 +10,7 @@ note: required by a bound in `requires_distinct` --> $DIR/issue-79674.rs:23:37 | LL | fn requires_distinct<A, B>(_a: A, _b: B) where - | ----------------- required by a bound in this + | ----------------- required by a bound in this function LL | A: MiniTypeId, B: MiniTypeId, LL | Lift<{is_same_type::<A, B>()}>: IsFalse {} | ^^^^^^^ required by this bound in `requires_distinct` diff --git a/tests/ui/const-generics/issues/issue-86530.stderr b/tests/ui/const-generics/issues/issue-86530.stderr index c63857b2314..620ed4f0fb2 100644 --- a/tests/ui/const-generics/issues/issue-86530.stderr +++ b/tests/ui/const-generics/issues/issue-86530.stderr @@ -10,7 +10,7 @@ note: required by a bound in `z` --> $DIR/issue-86530.rs:10:8 | LL | fn z<T>(t: T) - | - required by a bound in this + | - required by a bound in this function LL | where LL | T: X, | ^ required by this bound in `z` diff --git a/tests/ui/const-generics/issues/issue-87493.rs b/tests/ui/const-generics/issues/issue-87493.rs index d8599ab22a3..80472e6bd9c 100644 --- a/tests/ui/const-generics/issues/issue-87493.rs +++ b/tests/ui/const-generics/issues/issue-87493.rs @@ -7,7 +7,7 @@ where S: MyTrait, T: MyTrait<Assoc == S::Assoc>, //~^ ERROR: expected one of `,` or `>`, found `==` - //~| ERROR: this trait takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR: trait takes 0 generic arguments but 1 generic argument was supplied { } diff --git a/tests/ui/const-generics/issues/issue-87493.stderr b/tests/ui/const-generics/issues/issue-87493.stderr index 653afae2191..73bd6ed73e6 100644 --- a/tests/ui/const-generics/issues/issue-87493.stderr +++ b/tests/ui/const-generics/issues/issue-87493.stderr @@ -9,7 +9,7 @@ help: if you meant to use an associated type binding, replace `==` with `=` LL | T: MyTrait<Assoc = S::Assoc>, | ~ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-87493.rs:8:8 | LL | T: MyTrait<Assoc == S::Assoc>, diff --git a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr index a3c011d927b..51ef354e3ed 100644 --- a/tests/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/tests/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -9,7 +9,7 @@ note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | LL | struct A<const N: usize> - | - required by a bound in this + | - required by a bound in this unit struct LL | where LL | A<N>: Bar<N>; | ^^^^^^ required by this bound in `A` diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs index b126b24853f..79743abe409 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.rs @@ -7,7 +7,7 @@ struct Bar; const T: usize = 42; impl Foo<N = 3> for Bar { -//~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied +//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied //~| ERROR associated type bindings are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr index acfdde8e1a0..4f4e1aa3a04 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013-no-kw.stderr @@ -7,7 +7,7 @@ LL | impl Foo<N = 3> for Bar { = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/issue-89013-no-kw.rs:9:6 | LL | impl Foo<N = 3> for Bar { diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs index 9431779faf8..335d0d94e83 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.rs +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.rs @@ -8,7 +8,7 @@ const T: usize = 42; impl Foo<N = const 3> for Bar { //~^ ERROR expected lifetime, type, or constant, found keyword `const` -//~| ERROR this trait takes 1 generic +//~| ERROR trait takes 1 generic //~| ERROR associated type bindings are not allowed here //~| ERROR associated const equality is incomplete fn do_x(&self) -> [u8; 3] { diff --git a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr index 583749a8573..3d2b98feb39 100644 --- a/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr +++ b/tests/ui/const-generics/parser-error-recovery/issue-89013.stderr @@ -19,7 +19,7 @@ LL | impl Foo<N = const 3> for Bar { = note: see issue #92827 <https://github.com/rust-lang/rust/issues/92827> for more information = help: add `#![feature(associated_const_equality)]` to the crate attributes to enable -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/issue-89013.rs:9:6 | LL | impl Foo<N = const 3> for Bar { diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index 8bab0dff7f2..d4d78b59627 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -8,7 +8,7 @@ note: required by a bound in `bar` --> $DIR/unify_with_nested_expr.rs:14:10 | LL | fn bar<const N: usize>() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | [(); N + 1]:, | ^^^^^ required by this bound in `bar` diff --git a/tests/ui/constructor-lifetime-args.rs b/tests/ui/constructor-lifetime-args.rs index a824a44c9c2..f5802e7d8b1 100644 --- a/tests/ui/constructor-lifetime-args.rs +++ b/tests/ui/constructor-lifetime-args.rs @@ -15,12 +15,12 @@ enum E<'a, 'b> { fn main() { S(&0, &0); // OK S::<'static>(&0, &0); - //~^ ERROR this struct takes 2 lifetime arguments + //~^ ERROR struct takes 2 lifetime arguments S::<'static, 'static, 'static>(&0, &0); - //~^ ERROR this struct takes 2 lifetime arguments + //~^ ERROR struct takes 2 lifetime arguments E::V(&0); // OK E::V::<'static>(&0); - //~^ ERROR this enum takes 2 lifetime arguments + //~^ ERROR enum takes 2 lifetime arguments E::V::<'static, 'static, 'static>(&0); - //~^ ERROR this enum takes 2 lifetime arguments + //~^ ERROR enum takes 2 lifetime arguments } diff --git a/tests/ui/constructor-lifetime-args.stderr b/tests/ui/constructor-lifetime-args.stderr index bc1141b16c5..a18123fe19c 100644 --- a/tests/ui/constructor-lifetime-args.stderr +++ b/tests/ui/constructor-lifetime-args.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/constructor-lifetime-args.rs:17:5 | LL | S::<'static>(&0, &0); @@ -16,7 +16,7 @@ help: add missing lifetime argument LL | S::<'static, 'static>(&0, &0); | +++++++++ -error[E0107]: this struct takes 2 lifetime arguments but 3 lifetime arguments were supplied +error[E0107]: struct takes 2 lifetime arguments but 3 lifetime arguments were supplied --> $DIR/constructor-lifetime-args.rs:19:5 | LL | S::<'static, 'static, 'static>(&0, &0); @@ -30,7 +30,7 @@ note: struct defined here, with 2 lifetime parameters: `'a`, `'b` LL | struct S<'a, 'b>(&'a u8, &'b u8); | ^ -- -- -error[E0107]: this enum takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: enum takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/constructor-lifetime-args.rs:22:8 | LL | E::V::<'static>(&0); @@ -48,7 +48,7 @@ help: add missing lifetime argument LL | E::V::<'static, 'static>(&0); | +++++++++ -error[E0107]: this enum takes 2 lifetime arguments but 3 lifetime arguments were supplied +error[E0107]: enum takes 2 lifetime arguments but 3 lifetime arguments were supplied --> $DIR/constructor-lifetime-args.rs:24:8 | LL | E::V::<'static, 'static, 'static>(&0); diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr index 9710bf476ec..69fb1a59d4f 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:4:14 | LL | unsafe { std::mem::transmute(()) } - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: the `!` type has no valid value = note: `#[warn(invalid_value)]` on by default @@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:21:42 | LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: in this struct field --> $DIR/validate_uninhabited_zsts.rs:16:22 diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index 9710bf476ec..69fb1a59d4f 100644 --- a/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr +++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -2,10 +2,7 @@ warning: the type `!` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:4:14 | LL | unsafe { std::mem::transmute(()) } - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: the `!` type has no valid value = note: `#[warn(invalid_value)]` on by default @@ -40,10 +37,7 @@ warning: the type `empty::Empty` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:21:42 | LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: in this struct field --> $DIR/validate_uninhabited_zsts.rs:16:22 diff --git a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr index 43fba2573ff..fa20077da7e 100644 --- a/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr +++ b/tests/ui/consts/ct-var-in-collect_all_mismatches.stderr @@ -8,7 +8,7 @@ note: required by a bound in `Foo::<T, N>::unsatisfied` --> $DIR/ct-var-in-collect_all_mismatches.rs:15:12 | LL | fn unsatisfied(self) - | ----------- required by a bound in this + | ----------- required by a bound in this associated function LL | where LL | T: Bar<N>, | ^^^^^^ required by this bound in `Foo::<T, N>::unsatisfied` diff --git a/tests/ui/consts/gate-do-not-const-check.rs b/tests/ui/consts/gate-do-not-const-check.rs new file mode 100644 index 00000000000..be7e70dfabb --- /dev/null +++ b/tests/ui/consts/gate-do-not-const-check.rs @@ -0,0 +1,5 @@ +#[rustc_do_not_const_check] +//~^ ERROR this is an internal attribute that will never be stable +const fn foo() {} + +fn main() {} diff --git a/tests/ui/consts/gate-do-not-const-check.stderr b/tests/ui/consts/gate-do-not-const-check.stderr new file mode 100644 index 00000000000..3bb1360166a --- /dev/null +++ b/tests/ui/consts/gate-do-not-const-check.stderr @@ -0,0 +1,11 @@ +error[E0658]: this is an internal attribute that will never be stable + --> $DIR/gate-do-not-const-check.rs:1:1 + | +LL | #[rustc_do_not_const_check] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/deprecation/deprecation-lint.rs b/tests/ui/deprecation/deprecation-lint.rs index 0417e952eb7..83056feaf27 100644 --- a/tests/ui/deprecation/deprecation-lint.rs +++ b/tests/ui/deprecation/deprecation-lint.rs @@ -14,22 +14,22 @@ mod cross_crate { let foo = MethodTester; deprecated(); //~ ERROR use of deprecated function `deprecation_lint::deprecated` - foo.method_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` - Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated` - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` deprecated_text(); //~ ERROR use of deprecated function `deprecation_lint::deprecated_text`: text - foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text let _ = DeprecatedStruct { //~ ERROR use of deprecated struct `deprecation_lint::DeprecatedStruct`: text i: 0 //~ ERROR use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text @@ -61,19 +61,19 @@ mod cross_crate { } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text } struct S; @@ -243,22 +243,22 @@ mod this_crate { let foo = MethodTester; deprecated(); //~ ERROR use of deprecated function `this_crate::deprecated` - foo.method_deprecated(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` - Foo::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` - <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated` - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.method_deprecated(); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` deprecated_text(); //~ ERROR use of deprecated function `this_crate::deprecated_text`: text - foo.method_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.method_deprecated_text(); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text // Future deprecations are only permitted with `#![feature(staged_api)]` deprecated_future(); //~ ERROR use of deprecated function @@ -289,19 +289,19 @@ mod this_crate { } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text } fn test_method_object(foo: &Trait) { - foo.trait_deprecated(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ ERROR use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ ERROR use of deprecated method `this_crate::Trait::trait_deprecated_text`: text } #[deprecated(since = "1.0.0", note = "text")] diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 3842f849295..2098073409d 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -10,13 +10,13 @@ note: the lint level is defined here LL | #![deny(deprecated)] | ^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:21:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:23:25 | LL | <Foo as Trait>::trait_deprecated(&foo); @@ -28,13 +28,13 @@ error: use of deprecated function `deprecation_lint::deprecated_text`: text LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:30:16 | -LL | ... Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:32:25 | LL | ... <Foo as Trait>::trait_deprecated_text(&foo); @@ -100,25 +100,25 @@ error: use of deprecated function `deprecation_lint::deprecated_text`: text LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:65:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:67:25 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:69:16 | -LL | ... Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:71:25 | LL | ... <Foo as Trait>::trait_deprecated_text(&foo); @@ -184,13 +184,13 @@ error: use of deprecated function `this_crate::deprecated`: text LL | deprecated(); | ^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:250:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:252:25 | LL | <Foo as Trait>::trait_deprecated(&foo); @@ -202,17 +202,17 @@ error: use of deprecated function `this_crate::deprecated_text`: text LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:259:16 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:261:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::deprecated_future`: text --> $DIR/deprecation-lint.rs:264:9 @@ -274,29 +274,29 @@ error: use of deprecated tuple struct `this_crate::nested::DeprecatedTupleStruct LL | ... let _ = nested::DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:293:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:295:25 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:297:16 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:299:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated function `this_crate::test_fn_closure_body::{closure#0}::bar` --> $DIR/deprecation-lint.rs:317:13 @@ -352,65 +352,65 @@ error: use of deprecated tuple struct `this_crate2::Deprecated2`: text LL | let Deprecated2 | ^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:17:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:18:14 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:19:16 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:20:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:22:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:26:13 | -LL | ... foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:27:14 | -LL | ... Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::MethodTester::method_deprecated_text`: text +error: use of deprecated method `deprecation_lint::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:28:16 | LL | ... <Foo>::method_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:29:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:31:16 | -LL | ... <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ error: use of deprecated field `deprecation_lint::DeprecatedStruct::i`: text --> $DIR/deprecation-lint.rs:35:13 @@ -424,37 +424,37 @@ error: use of deprecated field `deprecation_lint::nested::DeprecatedStruct::i`: LL | i: 0 | ^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:64:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:66:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:68:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:70:16 | -LL | ... <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:75:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `deprecation_lint::Trait::trait_deprecated_text`: text +error: use of deprecated method `deprecation_lint::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:76:13 | LL | foo.trait_deprecated_text(); @@ -544,61 +544,61 @@ error: use of deprecated field `deprecation_lint::Deprecated2::2`: text LL | _) | ^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:246:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:247:14 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/deprecation-lint.rs:248:16 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:249:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:251:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:255:13 | -LL | ... foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:256:14 | -LL | ... Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +error: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/deprecation-lint.rs:257:16 | -LL | ... <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:258:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:260:16 | LL | <Foo>::trait_deprecated_text(&foo); @@ -616,37 +616,37 @@ error: use of deprecated field `this_crate::nested::DeprecatedStruct::i`: text LL | i: 0 | ^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:292:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:294:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:296:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:298:16 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/deprecation-lint.rs:303:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -error: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +error: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/deprecation-lint.rs:304:13 | LL | foo.trait_deprecated_text(); diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed index 99a2b09614f..85e88287094 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed @@ -3,7 +3,7 @@ #![deny(deprecated)] fn main() { - let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] + let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] - let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] + let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs index 62bf84aa3ea..246de2f5e4b 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs @@ -3,7 +3,7 @@ #![deny(deprecated)] fn main() { - let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] + let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] - let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] + let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` [deprecated] } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr index 8d4529526e3..3b518d1802b 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr @@ -1,4 +1,4 @@ -error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` +error: use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` --> $DIR/issue-84637-deprecated-associated-function.rs:6:21 | LL | let _foo = str::trim_left(" aoeu"); @@ -9,18 +9,18 @@ note: the lint level is defined here | LL | #![deny(deprecated)] | ^^^^^^^^^^ -help: replace the use of the deprecated associated function +help: replace the use of the deprecated method | LL | let _foo = str::trim_start(" aoeu"); | ~~~~~~~~~~ -error: use of deprecated associated function `core::str::<impl str>::trim_left`: superseded by `trim_start` +error: use of deprecated method `core::str::<impl str>::trim_left`: superseded by `trim_start` --> $DIR/issue-84637-deprecated-associated-function.rs:8:26 | LL | let _bar = " aoeu".trim_left(); | ^^^^^^^^^ | -help: replace the use of the deprecated associated function +help: replace the use of the deprecated method | LL | let _bar = " aoeu".trim_start(); | ~~~~~~~~~~ diff --git a/tests/ui/deprecation/suggestion.stderr b/tests/ui/deprecation/suggestion.stderr index c5f2fc09125..5584b6d2f8f 100644 --- a/tests/ui/deprecation/suggestion.stderr +++ b/tests/ui/deprecation/suggestion.stderr @@ -14,13 +14,13 @@ help: replace the use of the deprecated function LL | bar::replacement(); | ~~~~~~~~~~~ -error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement` +error: use of deprecated method `Foo::deprecated`: replaced by `replacement` --> $DIR/suggestion.rs:40:9 | LL | foo.deprecated(); | ^^^^^^^^^^ | -help: replace the use of the deprecated associated function +help: replace the use of the deprecated method | LL | foo.replacement(); | ~~~~~~~~~~~ diff --git a/tests/ui/error-codes/E0107.rs b/tests/ui/error-codes/E0107.rs index d369fc2a565..fd23e7c00f2 100644 --- a/tests/ui/error-codes/E0107.rs +++ b/tests/ui/error-codes/E0107.rs @@ -11,39 +11,39 @@ enum Bar { struct Baz<'a, 'b, 'c> { buzz: Buzz<'a>, - //~^ ERROR this struct takes 2 lifetime arguments + //~^ ERROR struct takes 2 lifetime arguments //~| HELP add missing lifetime argument bar: Bar<'a>, - //~^ ERROR this enum takes 0 lifetime arguments + //~^ ERROR enum takes 0 lifetime arguments //~| HELP remove these generics foo2: Foo<'a, 'b, 'c>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove these lifetime arguments qux1: Qux<'a, 'b, i32>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove this lifetime argument qux2: Qux<'a, i32, 'b>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove this lifetime argument qux3: Qux<'a, 'b, 'c, i32>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove these lifetime arguments qux4: Qux<'a, i32, 'b, 'c>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove these lifetime arguments qux5: Qux<'a, 'b, i32, 'c>, - //~^ ERROR this struct takes 1 lifetime argument + //~^ ERROR struct takes 1 lifetime argument //~| HELP remove this lifetime argument quux: Quux<'a, i32, 'b>, - //~^ ERROR this struct takes 0 lifetime arguments + //~^ ERROR struct takes 0 lifetime arguments //~| HELP remove this lifetime argument } @@ -53,7 +53,7 @@ pub trait T { } fn trait_bound_generic<I: T<u8, u16>>(_i: I) { - //~^ ERROR this trait takes 0 generic arguments + //~^ ERROR trait takes 0 generic arguments //~| HELP replace the generic bounds with the associated types } diff --git a/tests/ui/error-codes/E0107.stderr b/tests/ui/error-codes/E0107.stderr index 03430f8fa3a..3f540eb08bc 100644 --- a/tests/ui/error-codes/E0107.stderr +++ b/tests/ui/error-codes/E0107.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/E0107.rs:13:11 | LL | buzz: Buzz<'a>, @@ -16,7 +16,7 @@ help: add missing lifetime argument LL | buzz: Buzz<'a, 'a>, | ++++ -error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/E0107.rs:17:10 | LL | bar: Bar<'a>, @@ -30,7 +30,7 @@ note: enum defined here, with 0 lifetime parameters LL | enum Bar { | ^^^ -error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied --> $DIR/E0107.rs:21:11 | LL | foo2: Foo<'a, 'b, 'c>, @@ -44,7 +44,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Foo<'a>(&'a str); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/E0107.rs:25:11 | LL | qux1: Qux<'a, 'b, i32>, @@ -58,7 +58,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Qux<'a, T>(&'a T); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/E0107.rs:29:11 | LL | qux2: Qux<'a, i32, 'b>, @@ -72,7 +72,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Qux<'a, T>(&'a T); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied --> $DIR/E0107.rs:33:11 | LL | qux3: Qux<'a, 'b, 'c, i32>, @@ -86,7 +86,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Qux<'a, T>(&'a T); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied --> $DIR/E0107.rs:37:11 | LL | qux4: Qux<'a, i32, 'b, 'c>, @@ -100,7 +100,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Qux<'a, T>(&'a T); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 3 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 3 lifetime arguments were supplied --> $DIR/E0107.rs:41:11 | LL | qux5: Qux<'a, 'b, i32, 'c>, @@ -114,7 +114,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Qux<'a, T>(&'a T); | ^^^ -- -error[E0107]: this struct takes 0 lifetime arguments but 2 lifetime arguments were supplied +error[E0107]: struct takes 0 lifetime arguments but 2 lifetime arguments were supplied --> $DIR/E0107.rs:45:11 | LL | quux: Quux<'a, i32, 'b>, @@ -128,7 +128,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct Quux<T>(T); | ^^^^ -error[E0107]: this trait takes 0 generic arguments but 2 generic arguments were supplied +error[E0107]: trait takes 0 generic arguments but 2 generic arguments were supplied --> $DIR/E0107.rs:55:27 | LL | fn trait_bound_generic<I: T<u8, u16>>(_i: I) { diff --git a/tests/ui/error-codes/E0476.rs b/tests/ui/error-codes/E0476.rs new file mode 100644 index 00000000000..d5e4b8d2372 --- /dev/null +++ b/tests/ui/error-codes/E0476.rs @@ -0,0 +1,13 @@ +#![feature(coerce_unsized)] +#![feature(unsize)] + +use std::marker::Unsize; +use std::ops::CoerceUnsized; + +struct Wrapper<T>(T); + +impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {} +//~^ ERROR lifetime of the source pointer does not outlive lifetime bound of the object type [E0476] +//~^^ ERROR E0119 + +fn main() {} diff --git a/tests/ui/error-codes/E0476.stderr b/tests/ui/error-codes/E0476.stderr new file mode 100644 index 00000000000..a4bb26532a2 --- /dev/null +++ b/tests/ui/error-codes/E0476.stderr @@ -0,0 +1,31 @@ +error[E0119]: conflicting implementations of trait `CoerceUnsized<&Wrapper<_>>` for type `&Wrapper<_>` + --> $DIR/E0476.rs:9:1 + | +LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: conflicting implementation in crate `core`: + - impl<'a, 'b, T, U> CoerceUnsized<&'a U> for &'b T + where 'b: 'a, T: Unsize<U>, T: ?Sized, U: ?Sized; + +error[E0476]: lifetime of the source pointer does not outlive lifetime bound of the object type + --> $DIR/E0476.rs:9:1 + | +LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: object type is valid for the lifetime `'a` as defined here + --> $DIR/E0476.rs:9:6 + | +LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {} + | ^^ +note: source pointer is only valid for the lifetime `'b` as defined here + --> $DIR/E0476.rs:9:10 + | +LL | impl<'a, 'b, T, S> CoerceUnsized<&'a Wrapper<T>> for &'b Wrapper<S> where S: Unsize<T> {} + | ^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0476. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/error-codes/E0624.rs b/tests/ui/error-codes/E0624.rs index 4c68b70fb16..45f72a565ca 100644 --- a/tests/ui/error-codes/E0624.rs +++ b/tests/ui/error-codes/E0624.rs @@ -8,5 +8,5 @@ mod inner { fn main() { let foo = inner::Foo; - foo.method(); //~ ERROR associated function `method` is private [E0624] + foo.method(); //~ ERROR method `method` is private [E0624] } diff --git a/tests/ui/error-codes/E0624.stderr b/tests/ui/error-codes/E0624.stderr index e59b8a8ae35..23a8ea8a8c9 100644 --- a/tests/ui/error-codes/E0624.stderr +++ b/tests/ui/error-codes/E0624.stderr @@ -1,11 +1,11 @@ -error[E0624]: associated function `method` is private +error[E0624]: method `method` is private --> $DIR/E0624.rs:11:9 | LL | fn method(&self) {} - | ---------------- private associated function defined here + | ---------------- private method defined here ... LL | foo.method(); - | ^^^^^^ private associated function + | ^^^^^^ private method error: aborting due to previous error diff --git a/tests/ui/explore-issue-38412.stderr b/tests/ui/explore-issue-38412.stderr index 08dadb4db85..d8b485c9dc3 100644 --- a/tests/ui/explore-issue-38412.stderr +++ b/tests/ui/explore-issue-38412.stderr @@ -79,38 +79,38 @@ LL | r.unstable_undeclared(); = note: see issue #38412 <https://github.com/rust-lang/rust/issues/38412> for more information = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable -error[E0624]: associated function `pub_crate` is private +error[E0624]: method `pub_crate` is private --> $DIR/explore-issue-38412.rs:48:7 | LL | r.pub_crate(); - | ^^^^^^^^^ private associated function + | ^^^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:114:9 | LL | pub(crate) fn pub_crate(&self) -> i32 { self.d_priv } - | ------------------------------------- private associated function defined here + | ------------------------------------- private method defined here -error[E0624]: associated function `pub_mod` is private +error[E0624]: method `pub_mod` is private --> $DIR/explore-issue-38412.rs:49:7 | LL | r.pub_mod(); - | ^^^^^^^ private associated function + | ^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:116:9 | LL | pub(in m) fn pub_mod(&self) -> i32 { self.d_priv } - | ---------------------------------- private associated function defined here + | ---------------------------------- private method defined here -error[E0624]: associated function `private` is private +error[E0624]: method `private` is private --> $DIR/explore-issue-38412.rs:50:7 | LL | r.private(); - | ^^^^^^^ private associated function + | ^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:118:9 | LL | fn private(&self) -> i32 { self.d_priv } - | ------------------------ private associated function defined here + | ------------------------ private method defined here error[E0658]: use of unstable library feature 'unstable_undeclared' --> $DIR/explore-issue-38412.rs:55:7 @@ -130,38 +130,38 @@ LL | t.unstable_undeclared(); = note: see issue #38412 <https://github.com/rust-lang/rust/issues/38412> for more information = help: add `#![feature(unstable_undeclared)]` to the crate attributes to enable -error[E0624]: associated function `pub_crate` is private +error[E0624]: method `pub_crate` is private --> $DIR/explore-issue-38412.rs:61:7 | LL | t.pub_crate(); - | ^^^^^^^^^ private associated function + | ^^^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:129:9 | LL | pub(crate) fn pub_crate(&self) -> i32 { self.0 } - | ------------------------------------- private associated function defined here + | ------------------------------------- private method defined here -error[E0624]: associated function `pub_mod` is private +error[E0624]: method `pub_mod` is private --> $DIR/explore-issue-38412.rs:62:7 | LL | t.pub_mod(); - | ^^^^^^^ private associated function + | ^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:130:9 | LL | pub(in m) fn pub_mod(&self) -> i32 { self.0 } - | ---------------------------------- private associated function defined here + | ---------------------------------- private method defined here -error[E0624]: associated function `private` is private +error[E0624]: method `private` is private --> $DIR/explore-issue-38412.rs:63:7 | LL | t.private(); - | ^^^^^^^ private associated function + | ^^^^^^^ private method | ::: $DIR/auxiliary/pub-and-stability.rs:131:9 | LL | fn private(&self) -> i32 { self.0 } - | ------------------------ private associated function defined here + | ------------------------ private method defined here error: aborting due to 19 previous errors diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed index c50b9a12b6d..a7a9db7d977 100644 --- a/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed +++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.fixed @@ -4,16 +4,23 @@ // If this recovery happens, then plenty of errors are emitted. Here, we expect // only one error. // -// This is part of issue #88065: +// This is part of the following issues: // https://github.com/rust-lang/rust/issues/88065 +// https://github.com/rust-lang/rust/issues/107959 // run-rustfix fn main() { + // Closure with multiple expressions delimited by semicolon. let num = 5; (1..num).reduce(|a, b| { //~^ ERROR: closure bodies that contain statements must be surrounded by braces println!("{}", a); a * b }).unwrap(); + + // Closure with a single expression ended by a semicolon. + let mut v = vec![1, 2, 3]; + v.iter_mut().for_each(|x| {*x = *x+1;}); + //~^ ERROR: closure bodies that contain statements must be surrounded by braces } diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs index 58c81f3a6e2..b5690b2eca7 100644 --- a/tests/ui/expr/malformed_closure/missing_braces_around_block.rs +++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.rs @@ -4,16 +4,23 @@ // If this recovery happens, then plenty of errors are emitted. Here, we expect // only one error. // -// This is part of issue #88065: +// This is part of the following issues: // https://github.com/rust-lang/rust/issues/88065 +// https://github.com/rust-lang/rust/issues/107959 // run-rustfix fn main() { + // Closure with multiple expressions delimited by semicolon. let num = 5; (1..num).reduce(|a, b| //~^ ERROR: closure bodies that contain statements must be surrounded by braces println!("{}", a); a * b ).unwrap(); + + // Closure with a single expression ended by a semicolon. + let mut v = vec![1, 2, 3]; + v.iter_mut().for_each(|x|*x = *x+1;); + //~^ ERROR: closure bodies that contain statements must be surrounded by braces } diff --git a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr index dac9a8cfc69..039eef909fc 100644 --- a/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr +++ b/tests/ui/expr/malformed_closure/missing_braces_around_block.stderr @@ -1,5 +1,5 @@ error: closure bodies that contain statements must be surrounded by braces - --> $DIR/missing_braces_around_block.rs:14:26 + --> $DIR/missing_braces_around_block.rs:16:26 | LL | (1..num).reduce(|a, b| | ^ @@ -8,14 +8,14 @@ LL | ).unwrap(); | ^ | note: statement found outside of a block - --> $DIR/missing_braces_around_block.rs:16:26 + --> $DIR/missing_braces_around_block.rs:18:26 | LL | println!("{}", a); | -----------------^ this `;` turns the preceding closure into a statement | | | this expression is a statement because of the trailing semicolon note: the closure body may be incorrectly delimited - --> $DIR/missing_braces_around_block.rs:14:21 + --> $DIR/missing_braces_around_block.rs:16:21 | LL | (1..num).reduce(|a, b| | _____________________^ @@ -34,5 +34,30 @@ LL | a * b LL ~ }).unwrap(); | -error: aborting due to previous error +error: closure bodies that contain statements must be surrounded by braces + --> $DIR/missing_braces_around_block.rs:24:29 + | +LL | v.iter_mut().for_each(|x|*x = *x+1;); + | ^ ^ + | +note: statement found outside of a block + --> $DIR/missing_braces_around_block.rs:24:39 + | +LL | v.iter_mut().for_each(|x|*x = *x+1;); + | ---------^ this `;` turns the preceding closure into a statement + | | + | this expression is a statement because of the trailing semicolon +note: the closure body may be incorrectly delimited + --> $DIR/missing_braces_around_block.rs:24:27 + | +LL | v.iter_mut().for_each(|x|*x = *x+1;); + | ^^^^^^^^^^^^ - ...but likely you meant the closure to end here + | | + | this is the parsed closure... +help: try adding braces + | +LL | v.iter_mut().for_each(|x| {*x = *x+1;}); + | + + + +error: aborting due to 2 previous errors diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr index edbbf7db565..4233a8af9b6 100644 --- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -115,19 +115,19 @@ LL | let _: impl Tr1<As1: Copy> = S1; = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:55:14 | LL | const _cdef: impl Tr1<As1: Copy> = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/feature-gate-associated_type_bounds.rs:61:15 | LL | static _sdef: impl Tr1<As1: Copy> = S1; | ^^^^^^^^^^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/feature-gate-associated_type_bounds.rs:68:12 | LL | let _: impl Tr1<As1: Copy> = S1; diff --git a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr index 760dcb615c8..c8c3e13d7fc 100644 --- a/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr +++ b/tests/ui/feature-gates/feature-gate-impl_trait_in_fn_trait_return.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:1:24 | LL | fn f() -> impl Fn() -> impl Sized { || () } @@ -7,7 +7,7 @@ LL | fn f() -> impl Fn() -> impl Sized { || () } = note: see issue #99697 <https://github.com/rust-lang/rust/issues/99697> for more information = help: add `#![feature(impl_trait_in_fn_trait_return)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/feature-gate-impl_trait_in_fn_trait_return.rs:3:32 | LL | fn g() -> &'static dyn Fn() -> impl Sized { &|| () } diff --git a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr index aeabed4a6ab..0082b6fafee 100644 --- a/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr +++ b/tests/ui/feature-gates/feature-gate-return_position_impl_trait_in_trait.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:8:17 | LL | fn bar() -> impl Sized; @@ -7,7 +7,7 @@ LL | fn bar() -> impl Sized; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:9:21 | LL | fn baz() -> Box<impl std::fmt::Display>; @@ -16,7 +16,7 @@ LL | fn baz() -> Box<impl std::fmt::Display>; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/feature-gate-return_position_impl_trait_in_trait.rs:15:23 | LL | async fn bar() -> impl Sized; diff --git a/tests/ui/fn/issue-3044.stderr b/tests/ui/fn/issue-3044.stderr index 2690ad71176..219029e2afd 100644 --- a/tests/ui/fn/issue-3044.stderr +++ b/tests/ui/fn/issue-3044.stderr @@ -7,7 +7,7 @@ LL | | LL | | }); | |______- an argument is missing | -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL help: provide the argument | diff --git a/tests/ui/generator/generator-yielding-or-returning-itself.stderr b/tests/ui/generator/generator-yielding-or-returning-itself.stderr index 8f5d2429a28..a26dbf3f27c 100644 --- a/tests/ui/generator/generator-yielding-or-returning-itself.stderr +++ b/tests/ui/generator/generator-yielding-or-returning-itself.stderr @@ -19,7 +19,7 @@ note: required by a bound in `want_cyclic_generator_return` --> $DIR/generator-yielding-or-returning-itself.rs:10:36 | LL | pub fn want_cyclic_generator_return<T>(_: T) - | ---------------------------- required by a bound in this + | ---------------------------- required by a bound in this function LL | where T: Generator<Yield = (), Return = T> | ^^^^^^^^^^ required by this bound in `want_cyclic_generator_return` @@ -44,7 +44,7 @@ note: required by a bound in `want_cyclic_generator_yield` --> $DIR/generator-yielding-or-returning-itself.rs:23:24 | LL | pub fn want_cyclic_generator_yield<T>(_: T) - | --------------------------- required by a bound in this + | --------------------------- required by a bound in this function LL | where T: Generator<Yield = T, Return = ()> | ^^^^^^^^^ required by this bound in `want_cyclic_generator_yield` diff --git a/tests/ui/generator/issue-102645.stderr b/tests/ui/generator/issue-102645.stderr index f6d2440295e..3f9a4c2f3c5 100644 --- a/tests/ui/generator/issue-102645.stderr +++ b/tests/ui/generator/issue-102645.stderr @@ -4,7 +4,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied LL | Pin::new(&mut b).resume(); | ^^^^^^-- an argument of type `()` is missing | -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/ops/generator.rs:LL:COL help: provide the argument | diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr index 6612c4b4944..a2047f103d4 100644 --- a/tests/ui/generic-associated-types/bugs/issue-88460.stderr +++ b/tests/ui/generic-associated-types/bugs/issue-88460.stderr @@ -11,7 +11,7 @@ note: required by a bound in `test` --> $DIR/issue-88460.rs:15:27 | LL | fn test<T>(value: T) - | ---- required by a bound in this + | ---- required by a bound in this function ... LL | for<'a> T::Assoc<'a>: Marker, | ^^^^^^ required by this bound in `test` diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs index 9eb069637c6..5738dfa83ee 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.rs @@ -5,12 +5,12 @@ trait X { fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} //~^ ERROR: lifetime in trait object type must be followed by `+` //~| ERROR: parenthesized generic arguments cannot be used - //~| ERROR this associated type takes 0 generic arguments but 1 generic argument - //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments + //~| ERROR associated type takes 0 generic arguments but 1 generic argument + //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} //~^ ERROR: parenthesized generic arguments cannot be used - //~| ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments + //~| ERROR associated type takes 1 lifetime argument but 0 lifetime arguments fn main() {} diff --git a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr index 165779796e0..461853379b5 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-parenthesised-args.stderr @@ -23,7 +23,7 @@ LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} | | | help: remove these parentheses -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 | LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} @@ -39,7 +39,7 @@ help: add missing lifetime argument LL | fn foo<'a>(arg: Box<dyn X<Y('_, 'a) = &'a ()>>) {} | +++ -error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied --> $DIR/gat-trait-path-parenthesised-args.rs:5:27 | LL | fn foo<'a>(arg: Box<dyn X<Y('a) = &'a ()>>) {} @@ -53,7 +53,7 @@ note: associated type defined here, with 0 generic parameters LL | type Y<'a>; | ^ -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/gat-trait-path-parenthesised-args.rs:12:27 | LL | fn bar<'a>(arg: Box<dyn X<Y() = ()>>) {} diff --git a/tests/ui/generic-associated-types/issue-101020.stderr b/tests/ui/generic-associated-types/issue-101020.stderr index 1f9273a8c4a..5c8db617c17 100644 --- a/tests/ui/generic-associated-types/issue-101020.stderr +++ b/tests/ui/generic-associated-types/issue-101020.stderr @@ -13,7 +13,7 @@ note: required by a bound in `LendingIterator::consume` --> $DIR/issue-101020.rs:9:33 | LL | fn consume<F>(self, _f: F) - | ------- required by a bound in this + | ------- required by a bound in this associated function ... LL | for<'a> Self::Item<'a>: FuncInput<'a, Self::Item<'a>>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `LendingIterator::consume` diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs index 83655341d6a..83655341d6a 100644 --- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.rs +++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs diff --git a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr index baef38f6b80..4246f8c069d 100644 --- a/tests/ui/generic-associated-types/method-unsatified-assoc-type-predicate.stderr +++ b/tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr @@ -1,5 +1,5 @@ error[E0599]: the method `f` exists for struct `S`, but its trait bounds were not satisfied - --> $DIR/method-unsatified-assoc-type-predicate.rs:28:7 + --> $DIR/method-unsatisfied-assoc-type-predicate.rs:28:7 | LL | struct S; | -------- @@ -12,7 +12,7 @@ LL | a.f(); | ^ method cannot be called on `S` due to unsatisfied trait bounds | note: trait bound `<S as X>::Y<i32> = i32` was not satisfied - --> $DIR/method-unsatified-assoc-type-predicate.rs:12:11 + --> $DIR/method-unsatisfied-assoc-type-predicate.rs:12:11 | LL | impl<T: X<Y<i32> = i32>> M for T {} | ^^^^^^^^^^^^ - - diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.rs b/tests/ui/generic-associated-types/missing_lifetime_args.rs index 78def80925a..331511ba61a 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.rs +++ b/tests/ui/generic-associated-types/missing_lifetime_args.rs @@ -12,9 +12,9 @@ fn foo<'c, 'd>(_arg: Box<dyn X<Y = (&'c u32, &'d u32)>>) {} //~^ ERROR missing generics for associated type fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} -//~^ ERROR this struct takes 3 lifetime arguments but 2 lifetime +//~^ ERROR struct takes 3 lifetime arguments but 2 lifetime fn f<'a>(_arg: Foo<'a>) {} -//~^ ERROR this struct takes 3 lifetime arguments but 1 lifetime +//~^ ERROR struct takes 3 lifetime arguments but 1 lifetime fn main() {} diff --git a/tests/ui/generic-associated-types/missing_lifetime_args.stderr b/tests/ui/generic-associated-types/missing_lifetime_args.stderr index 8f74b12c008..1a7a2e787a1 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_args.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_args.stderr @@ -14,7 +14,7 @@ help: add missing lifetime arguments LL | fn foo<'c, 'd>(_arg: Box<dyn X<Y<'_, '_> = (&'c u32, &'d u32)>>) {} | ++++++++ -error[E0107]: this struct takes 3 lifetime arguments but 2 lifetime arguments were supplied +error[E0107]: struct takes 3 lifetime arguments but 2 lifetime arguments were supplied --> $DIR/missing_lifetime_args.rs:14:26 | LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b>) {} @@ -32,7 +32,7 @@ help: add missing lifetime argument LL | fn bar<'a, 'b, 'c>(_arg: Foo<'a, 'b, 'a>) {} | ++++ -error[E0107]: this struct takes 3 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 3 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing_lifetime_args.rs:17:16 | LL | fn f<'a>(_arg: Foo<'a>) {} diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.rs b/tests/ui/generic-associated-types/missing_lifetime_const.rs index 8b174b9e971..6e395dfdec1 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_const.rs +++ b/tests/ui/generic-associated-types/missing_lifetime_const.rs @@ -4,7 +4,7 @@ trait Foo { fn foo<T: Foo>() { let _: <T as Foo>::Assoc<3>; - //~^ ERROR this associated type + //~^ ERROR associated type } fn main() {} diff --git a/tests/ui/generic-associated-types/missing_lifetime_const.stderr b/tests/ui/generic-associated-types/missing_lifetime_const.stderr index 62d2e9f49dd..41945aabfb5 100644 --- a/tests/ui/generic-associated-types/missing_lifetime_const.stderr +++ b/tests/ui/generic-associated-types/missing_lifetime_const.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/missing_lifetime_const.rs:6:24 | LL | let _: <T as Foo>::Assoc<3>; diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.rs b/tests/ui/generic-associated-types/parameter_number_and_kind.rs index 8428e7763fb..ae2f7c00ea4 100644 --- a/tests/ui/generic-associated-types/parameter_number_and_kind.rs +++ b/tests/ui/generic-associated-types/parameter_number_and_kind.rs @@ -9,10 +9,10 @@ trait Foo { // Test parameters in default values type FOk<T> = Self::E<'static, T>; type FErr1 = Self::E<'static, 'static>; - //~^ ERROR this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied - //~| ERROR this associated type takes 1 + //~^ ERROR associated type takes 1 lifetime argument but 2 lifetime arguments were supplied + //~| ERROR associated type takes 1 type FErr2<T> = Self::E<'static, T, u32>; - //~^ ERROR this associated type takes 1 + //~^ ERROR associated type takes 1 } fn main() {} diff --git a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr index c20b9669e81..4523044b588 100644 --- a/tests/ui/generic-associated-types/parameter_number_and_kind.stderr +++ b/tests/ui/generic-associated-types/parameter_number_and_kind.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated type takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/parameter_number_and_kind.rs:11:24 | LL | type FErr1 = Self::E<'static, 'static>; @@ -12,7 +12,7 @@ note: associated type defined here, with 1 lifetime parameter: `'a` LL | type E<'a, T>; | ^ -- -error[E0107]: this associated type takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: associated type takes 1 generic argument but 0 generic arguments were supplied --> $DIR/parameter_number_and_kind.rs:11:24 | LL | type FErr1 = Self::E<'static, 'static>; @@ -28,7 +28,7 @@ help: add missing generic argument LL | type FErr1 = Self::E<'static, 'static, T>; | +++ -error[E0107]: this associated type takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: associated type takes 1 generic argument but 2 generic arguments were supplied --> $DIR/parameter_number_and_kind.rs:14:27 | LL | type FErr2<T> = Self::E<'static, T, u32>; diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs index 1622b92aa0c..c58f9cf1dfc 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.rs @@ -4,8 +4,8 @@ trait X { const _: () = { fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} - //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments - //~| ERROR this associated type takes 0 generic arguments but 1 generic argument + //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments + //~| ERROR associated type takes 0 generic arguments but 1 generic argument }; fn main() {} diff --git a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr index 0a09ec5dc49..fab5b474d92 100644 --- a/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr +++ b/tests/ui/generic-associated-types/parse/trait-path-type-error-once-implemented.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/trait-path-type-error-once-implemented.rs:6:29 | LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} @@ -14,7 +14,7 @@ help: add missing lifetime argument LL | fn f2<'a>(arg : Box<dyn X<Y<'_, 1> = &'a ()>>) {} | +++ -error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied --> $DIR/trait-path-type-error-once-implemented.rs:6:29 | LL | fn f2<'a>(arg : Box<dyn X<Y<1> = &'a ()>>) {} diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs index 1cc09aa6dd4..060ee8821d8 100644 --- a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.rs +++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.rs @@ -1,3 +1,5 @@ +#![warn(unused_lifetimes)] + pub trait X { type Y<'a: 'static>; //~^ WARNING unnecessary lifetime parameter diff --git a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr index fbd79879d0f..a69cd0028c1 100644 --- a/tests/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr +++ b/tests/ui/generic-associated-types/unsatisfied-item-lifetime-bound.stderr @@ -1,45 +1,50 @@ warning: unnecessary lifetime parameter `'a` - --> $DIR/unsatified-item-lifetime-bound.rs:2:12 + --> $DIR/unsatisfied-item-lifetime-bound.rs:4:12 | LL | type Y<'a: 'static>; | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` +note: the lint level is defined here + --> $DIR/unsatisfied-item-lifetime-bound.rs:1:9 + | +LL | #![warn(unused_lifetimes)] + | ^^^^^^^^^^^^^^^^ error[E0478]: lifetime bound not satisfied - --> $DIR/unsatified-item-lifetime-bound.rs:11:8 + --> $DIR/unsatisfied-item-lifetime-bound.rs:13:8 | LL | f: <T as X>::Y<'a>, | ^^^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/unsatified-item-lifetime-bound.rs:10:10 + --> $DIR/unsatisfied-item-lifetime-bound.rs:12:10 | LL | struct B<'a, T: for<'r> X<Y<'r> = &'r ()>> { | ^^ = note: but lifetime parameter must outlive the static lifetime error[E0478]: lifetime bound not satisfied - --> $DIR/unsatified-item-lifetime-bound.rs:16:8 + --> $DIR/unsatisfied-item-lifetime-bound.rs:18:8 | LL | f: <T as X>::Y<'a>, | ^^^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/unsatified-item-lifetime-bound.rs:15:10 + --> $DIR/unsatisfied-item-lifetime-bound.rs:17:10 | LL | struct C<'a, T: X> { | ^^ = note: but lifetime parameter must outlive the static lifetime error[E0478]: lifetime bound not satisfied - --> $DIR/unsatified-item-lifetime-bound.rs:21:8 + --> $DIR/unsatisfied-item-lifetime-bound.rs:23:8 | LL | f: <() as X>::Y<'a>, | ^^^^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/unsatified-item-lifetime-bound.rs:20:10 + --> $DIR/unsatisfied-item-lifetime-bound.rs:22:10 | LL | struct D<'a> { | ^^ diff --git a/tests/ui/generics/bad-mid-path-type-params.rs b/tests/ui/generics/bad-mid-path-type-params.rs index 23a5d1525d9..37d484cba0b 100644 --- a/tests/ui/generics/bad-mid-path-type-params.rs +++ b/tests/ui/generics/bad-mid-path-type-params.rs @@ -28,17 +28,17 @@ impl Trait<isize> for S2 { fn foo<'a>() { let _ = S::new::<isize,f64>(1, 1.0); - //~^ ERROR this associated function takes 1 + //~^ ERROR associated function takes 1 let _ = S::<'a,isize>::new::<f64>(1, 1.0); - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied let _: S2 = Trait::new::<isize,f64>(1, 1.0); - //~^ ERROR this associated function takes 1 + //~^ ERROR associated function takes 1 let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0); - //~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this associated function takes 1 + //~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR associated function takes 1 } fn main() {} diff --git a/tests/ui/generics/bad-mid-path-type-params.stderr b/tests/ui/generics/bad-mid-path-type-params.stderr index aee2b60159f..71e15dd4c92 100644 --- a/tests/ui/generics/bad-mid-path-type-params.stderr +++ b/tests/ui/generics/bad-mid-path-type-params.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied --> $DIR/bad-mid-path-type-params.rs:30:16 | LL | let _ = S::new::<isize,f64>(1, 1.0); @@ -12,7 +12,7 @@ note: associated function defined here, with 1 generic parameter: `U` LL | fn new<U>(x: T, _: U) -> S<T> { | ^^^ - -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/bad-mid-path-type-params.rs:33:13 | LL | let _ = S::<'a,isize>::new::<f64>(1, 1.0); @@ -26,7 +26,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct S<T> { | ^ -error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied --> $DIR/bad-mid-path-type-params.rs:36:24 | LL | let _: S2 = Trait::new::<isize,f64>(1, 1.0); @@ -40,7 +40,7 @@ note: associated function defined here, with 1 generic parameter: `U` LL | fn new<U>(x: T, y: U) -> Self; | ^^^ - -error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/bad-mid-path-type-params.rs:39:17 | LL | let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0); @@ -54,7 +54,7 @@ note: trait defined here, with 0 lifetime parameters LL | trait Trait<T> { | ^^^^^ -error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: associated function takes 1 generic argument but 2 generic arguments were supplied --> $DIR/bad-mid-path-type-params.rs:39:36 | LL | let _: S2 = Trait::<'a,isize>::new::<f64,f64>(1, 1.0); diff --git a/tests/ui/generics/generic-arg-mismatch-recover.rs b/tests/ui/generics/generic-arg-mismatch-recover.rs index 2cf7f1d657b..947f33414db 100644 --- a/tests/ui/generics/generic-arg-mismatch-recover.rs +++ b/tests/ui/generics/generic-arg-mismatch-recover.rs @@ -4,9 +4,9 @@ struct Bar<'a>(&'a ()); fn main() { Foo::<'static, 'static, ()>(&0); - //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied Bar::<'static, 'static, ()>(&()); - //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied - //~| ERROR this struct takes 0 + //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied + //~| ERROR struct takes 0 } diff --git a/tests/ui/generics/generic-arg-mismatch-recover.stderr b/tests/ui/generics/generic-arg-mismatch-recover.stderr index 45fea925f27..f549a7180fc 100644 --- a/tests/ui/generics/generic-arg-mismatch-recover.stderr +++ b/tests/ui/generics/generic-arg-mismatch-recover.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/generic-arg-mismatch-recover.rs:6:5 | LL | Foo::<'static, 'static, ()>(&0); @@ -12,7 +12,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Foo<'a, T: 'a>(&'a T); | ^^^ -- -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/generic-arg-mismatch-recover.rs:9:5 | LL | Bar::<'static, 'static, ()>(&()); @@ -26,7 +26,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Bar<'a>(&'a ()); | ^^^ -- -error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/generic-arg-mismatch-recover.rs:9:5 | LL | Bar::<'static, 'static, ()>(&()); diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.rs b/tests/ui/generics/generic-impl-less-params-with-defaults.rs index 66afbb58ad4..6c00411561e 100644 --- a/tests/ui/generics/generic-impl-less-params-with-defaults.rs +++ b/tests/ui/generics/generic-impl-less-params-with-defaults.rs @@ -9,5 +9,5 @@ impl<A, B, C> Foo<A, B, C> { fn main() { Foo::<isize>::new(); - //~^ ERROR this struct takes at least 2 generic arguments but 1 generic argument + //~^ ERROR struct takes at least 2 generic arguments but 1 generic argument } diff --git a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr index cdbb57902e4..262561fa81e 100644 --- a/tests/ui/generics/generic-impl-less-params-with-defaults.stderr +++ b/tests/ui/generics/generic-impl-less-params-with-defaults.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied --> $DIR/generic-impl-less-params-with-defaults.rs:11:5 | LL | Foo::<isize>::new(); diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.rs b/tests/ui/generics/generic-impl-more-params-with-defaults.rs index a283323742a..be633ec464f 100644 --- a/tests/ui/generics/generic-impl-more-params-with-defaults.rs +++ b/tests/ui/generics/generic-impl-more-params-with-defaults.rs @@ -11,5 +11,5 @@ impl<T, A> Vec<T, A> { fn main() { Vec::<isize, Heap, bool>::new(); - //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments were supplied + //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments were supplied } diff --git a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr index fe9b670da79..2f4682c4e5a 100644 --- a/tests/ui/generics/generic-impl-more-params-with-defaults.stderr +++ b/tests/ui/generics/generic-impl-more-params-with-defaults.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied +error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied --> $DIR/generic-impl-more-params-with-defaults.rs:13:5 | LL | Vec::<isize, Heap, bool>::new(); diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.rs b/tests/ui/generics/generic-type-more-params-with-defaults.rs index 3dab03297c9..b83fdb5c455 100644 --- a/tests/ui/generics/generic-type-more-params-with-defaults.rs +++ b/tests/ui/generics/generic-type-more-params-with-defaults.rs @@ -7,5 +7,5 @@ struct Vec<T, A = Heap>( fn main() { let _: Vec<isize, Heap, bool>; - //~^ ERROR this struct takes at most 2 generic arguments but 3 generic arguments + //~^ ERROR struct takes at most 2 generic arguments but 3 generic arguments } diff --git a/tests/ui/generics/generic-type-more-params-with-defaults.stderr b/tests/ui/generics/generic-type-more-params-with-defaults.stderr index 7f0198f0e84..4d01ba1f453 100644 --- a/tests/ui/generics/generic-type-more-params-with-defaults.stderr +++ b/tests/ui/generics/generic-type-more-params-with-defaults.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes at most 2 generic arguments but 3 generic arguments were supplied +error[E0107]: struct takes at most 2 generic arguments but 3 generic arguments were supplied --> $DIR/generic-type-more-params-with-defaults.rs:9:12 | LL | let _: Vec<isize, Heap, bool>; diff --git a/tests/ui/generics/wrong-number-of-args.rs b/tests/ui/generics/wrong-number-of-args.rs index cd2f96a1819..e4eaff21af1 100644 --- a/tests/ui/generics/wrong-number-of-args.rs +++ b/tests/ui/generics/wrong-number-of-args.rs @@ -4,18 +4,18 @@ mod no_generics { type A = Ty; type B = Ty<'static>; - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument //~| HELP remove these generics type C = Ty<'static, usize>; - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument - //~| ERROR this struct takes 0 generic arguments but 1 generic argument + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument + //~| ERROR struct takes 0 generic arguments but 1 generic argument //~| HELP remove this lifetime argument //~| HELP remove this generic argument type D = Ty<'static, usize, { 0 }>; - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument - //~| ERROR this struct takes 0 generic arguments but 2 generic arguments + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument + //~| ERROR struct takes 0 generic arguments but 2 generic arguments //~| HELP remove this lifetime argument //~| HELP remove these generic arguments } @@ -28,17 +28,17 @@ mod type_and_type { //~| HELP add missing type B = Ty<usize>; - //~^ ERROR this struct takes 2 generic arguments but 1 generic argument + //~^ ERROR struct takes 2 generic arguments but 1 generic argument //~| HELP add missing type C = Ty<usize, String>; type D = Ty<usize, String, char>; - //~^ ERROR this struct takes 2 generic arguments but 3 generic arguments + //~^ ERROR struct takes 2 generic arguments but 3 generic arguments //~| HELP remove this type E = Ty<>; - //~^ ERROR this struct takes 2 generic arguments but 0 generic arguments were supplied + //~^ ERROR struct takes 2 generic arguments but 0 generic arguments were supplied //~| HELP add missing } @@ -52,7 +52,7 @@ mod lifetime_and_type { //~| HELP consider introducing type B = Ty<'static>; - //~^ ERROR this struct takes 1 generic argument but 0 generic arguments + //~^ ERROR struct takes 1 generic argument but 0 generic arguments //~| HELP add missing type C = Ty<usize>; @@ -62,14 +62,14 @@ mod lifetime_and_type { type D = Ty<'static, usize>; type E = Ty<>; - //~^ ERROR this struct takes 1 generic argument but 0 generic arguments + //~^ ERROR struct takes 1 generic argument but 0 generic arguments //~| ERROR missing lifetime specifier //~| HELP consider introducing //~| HELP add missing type F = Ty<'static, usize, 'static, usize>; - //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments - //~| ERROR this struct takes 1 generic argument but 2 generic arguments + //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments + //~| ERROR struct takes 1 generic argument but 2 generic arguments //~| HELP remove this lifetime argument //~| HELP remove this generic argument } @@ -82,7 +82,7 @@ mod type_and_type_and_type { //~| HELP add missing type B = Ty<usize>; - //~^ ERROR this struct takes at least 2 + //~^ ERROR struct takes at least 2 //~| HELP add missing type C = Ty<usize, String>; @@ -90,11 +90,11 @@ mod type_and_type_and_type { type D = Ty<usize, String, char>; type E = Ty<usize, String, char, f64>; - //~^ ERROR this struct takes at most 3 + //~^ ERROR struct takes at most 3 //~| HELP remove type F = Ty<>; - //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments + //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments //~| HELP add missing } @@ -114,7 +114,7 @@ mod r#trait { } type A = Box<dyn NonGeneric<usize>>; - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| HELP remove type B = Box<dyn GenericLifetime>; @@ -123,7 +123,7 @@ mod r#trait { //~| HELP consider making the bound lifetime-generic type C = Box<dyn GenericLifetime<'static, 'static>>; - //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied //~| HELP remove type D = Box<dyn GenericType>; @@ -131,7 +131,7 @@ mod r#trait { //~| HELP add missing type E = Box<dyn GenericType<String, usize>>; - //~^ ERROR this trait takes 1 generic argument but 2 generic arguments + //~^ ERROR trait takes 1 generic argument but 2 generic arguments //~| HELP remove type F = Box<dyn GenericLifetime<>>; @@ -140,7 +140,7 @@ mod r#trait { //~| HELP consider making the bound lifetime-generic type G = Box<dyn GenericType<>>; - //~^ ERROR this trait takes 1 generic argument but 0 generic arguments + //~^ ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing } @@ -151,7 +151,7 @@ mod associated_item { } type A = Box<dyn NonGenericAT<usize, AssocTy=()>>; - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| HELP remove } @@ -166,14 +166,14 @@ mod associated_item { //~| HELP consider making the bound lifetime-generic type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>; - //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied //~| HELP remove type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>; //~^ ERROR missing lifetime specifier //~| HELP consider introducing //~| HELP consider making the bound lifetime-generic - //~| ERROR this trait takes 0 generic arguments but 1 generic argument + //~| ERROR trait takes 0 generic arguments but 1 generic argument //~| HELP remove } @@ -183,17 +183,17 @@ mod associated_item { } type A = Box<dyn GenericTypeAT<AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 0 generic arguments + //~^ ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 2 generic arguments + //~^ ERROR trait takes 1 generic argument but 2 generic arguments //~| HELP remove type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 0 generic arguments + //~^ ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing - //~| ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied //~| HELP remove } @@ -203,20 +203,20 @@ mod associated_item { } type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 0 generic arguments + //~^ ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing //~| ERROR missing lifetime specifier //~| HELP consider introducing //~| HELP consider making the bound lifetime-generic type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 0 generic arguments were supplied + //~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied //~| HELP add missing type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>; - //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied //~| HELP remove - //~| ERROR this trait takes 1 generic argument but 0 generic arguments + //~| ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing type D = Box<dyn GenericLifetimeTypeAT<(), AssocTy=()>>; @@ -228,21 +228,21 @@ mod associated_item { //~^ ERROR missing lifetime specifier //~| HELP consider introducing //~| HELP consider making the bound lifetime-generic - //~| ERROR this trait takes 1 generic argument but 2 generic arguments + //~| ERROR trait takes 1 generic argument but 2 generic arguments //~| HELP remove type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>; - //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied //~| HELP remove type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>; - //~^ ERROR this trait takes 1 generic argument but 2 generic arguments + //~^ ERROR trait takes 1 generic argument but 2 generic arguments //~| HELP remove type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>; - //~^ ERROR this trait takes 1 lifetime argument but 2 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 2 lifetime arguments were supplied //~| HELP remove - //~| ERROR this trait takes 1 generic argument but 2 generic arguments + //~| ERROR trait takes 1 generic argument but 2 generic arguments //~| HELP remove } @@ -252,15 +252,15 @@ mod associated_item { } type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>; - //~^ ERROR this trait takes 2 generic arguments but 0 generic arguments + //~^ ERROR trait takes 2 generic arguments but 0 generic arguments //~| HELP add missing type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>; - //~^ ERROR this trait takes 2 generic arguments but 1 generic argument + //~^ ERROR trait takes 2 generic arguments but 1 generic argument //~| HELP add missing type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>; - //~^ ERROR this trait takes 2 generic arguments but 3 generic arguments + //~^ ERROR trait takes 2 generic arguments but 3 generic arguments //~| HELP remove } @@ -275,7 +275,7 @@ mod associated_item { //~| HELP consider making the bound lifetime-generic type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>; - //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied //~| HELP add missing lifetime argument } @@ -288,17 +288,17 @@ mod associated_item { //~^ ERROR missing lifetime specifier //~| HELP consider introducing //~| HELP consider making the bound lifetime-generic - //~| ERROR this trait takes 1 generic argument but 0 generic arguments + //~| ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>; - //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied //~| HELP add missing lifetime argument - //~| ERROR this trait takes 1 generic argument but 0 generic arguments + //~| ERROR trait takes 1 generic argument but 0 generic arguments //~| HELP add missing type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>; - //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied //~| HELP add missing lifetime argument } } @@ -312,21 +312,21 @@ mod stdlib { //~| HELP add missing type B = HashMap<String>; - //~^ ERROR this struct takes at least + //~^ ERROR struct takes at least //~| HELP add missing type C = HashMap<'static>; - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument //~| HELP remove these generics - //~| ERROR this struct takes at least 2 + //~| ERROR struct takes at least 2 //~| HELP add missing type D = HashMap<usize, String, char, f64>; - //~^ ERROR this struct takes at most 3 + //~^ ERROR struct takes at most 3 //~| HELP remove this type E = HashMap<>; - //~^ ERROR this struct takes at least 2 generic arguments but 0 generic arguments + //~^ ERROR struct takes at least 2 generic arguments but 0 generic arguments //~| HELP add missing } @@ -336,21 +336,21 @@ mod stdlib { //~| HELP add missing type B = Result<String>; - //~^ ERROR this enum takes 2 generic arguments but 1 generic argument + //~^ ERROR enum takes 2 generic arguments but 1 generic argument //~| HELP add missing type C = Result<'static>; - //~^ ERROR this enum takes 0 lifetime arguments but 1 lifetime argument + //~^ ERROR enum takes 0 lifetime arguments but 1 lifetime argument //~| HELP remove these generics - //~| ERROR this enum takes 2 generic arguments but 0 generic arguments + //~| ERROR enum takes 2 generic arguments but 0 generic arguments //~| HELP add missing type D = Result<usize, String, char>; - //~^ ERROR this enum takes 2 generic arguments but 3 generic arguments + //~^ ERROR enum takes 2 generic arguments but 3 generic arguments //~| HELP remove type E = Result<>; - //~^ ERROR this enum takes 2 generic arguments but 0 generic arguments + //~^ ERROR enum takes 2 generic arguments but 0 generic arguments //~| HELP add missing } } diff --git a/tests/ui/generics/wrong-number-of-args.stderr b/tests/ui/generics/wrong-number-of-args.stderr index 75e33f680ea..9006fb10b67 100644 --- a/tests/ui/generics/wrong-number-of-args.stderr +++ b/tests/ui/generics/wrong-number-of-args.stderr @@ -167,7 +167,7 @@ help: consider introducing a named lifetime parameter LL | type A<'a> = Box<dyn GenericLifetimeLifetimeTypeAT<'a, 'a, AssocTy=()>>; | ++++ +++++++ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:6:14 | LL | type B = Ty<'static>; @@ -181,7 +181,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct Ty; | ^^ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:10:14 | LL | type C = Ty<'static, usize>; @@ -195,7 +195,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct Ty; | ^^ -error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:10:14 | LL | type C = Ty<'static, usize>; @@ -209,7 +209,7 @@ note: struct defined here, with 0 generic parameters LL | struct Ty; | ^^ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:16:14 | LL | type D = Ty<'static, usize, { 0 }>; @@ -223,7 +223,7 @@ note: struct defined here, with 0 lifetime parameters LL | struct Ty; | ^^ -error[E0107]: this struct takes 0 generic arguments but 2 generic arguments were supplied +error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:16:14 | LL | type D = Ty<'static, usize, { 0 }>; @@ -253,7 +253,7 @@ help: add missing generic arguments LL | type A = Ty<A, B>; | ++++++ -error[E0107]: this struct takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:30:14 | LL | type B = Ty<usize>; @@ -271,7 +271,7 @@ help: add missing generic argument LL | type B = Ty<usize, B>; | +++ -error[E0107]: this struct takes 2 generic arguments but 3 generic arguments were supplied +error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:36:14 | LL | type D = Ty<usize, String, char>; @@ -285,7 +285,7 @@ note: struct defined here, with 2 generic parameters: `A`, `B` LL | struct Ty<A, B>; | ^^ - - -error[E0107]: this struct takes 2 generic arguments but 0 generic arguments were supplied +error[E0107]: struct takes 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:40:14 | LL | type E = Ty<>; @@ -317,7 +317,7 @@ help: add missing generic argument LL | type A = Ty<T>; | +++ -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:54:14 | LL | type B = Ty<'static>; @@ -333,7 +333,7 @@ help: add missing generic argument LL | type B = Ty<'static, T>; | +++ -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:64:14 | LL | type E = Ty<>; @@ -349,7 +349,7 @@ help: add missing generic argument LL | type E = Ty<T>; | + -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:70:14 | LL | type F = Ty<'static, usize, 'static, usize>; @@ -363,7 +363,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct Ty<'a, T>; | ^^ -- -error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:70:14 | LL | type F = Ty<'static, usize, 'static, usize>; @@ -393,7 +393,7 @@ help: add missing generic arguments LL | type A = Ty<A, B>; | ++++++ -error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:84:14 | LL | type B = Ty<usize>; @@ -411,7 +411,7 @@ help: add missing generic argument LL | type B = Ty<usize, B>; | +++ -error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied +error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:92:14 | LL | type E = Ty<usize, String, char, f64>; @@ -425,7 +425,7 @@ note: struct defined here, with at most 3 generic parameters: `A`, `B`, `C` LL | struct Ty<A, B, C = &'static str>; | ^^ - - ---------------- -error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied +error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:96:14 | LL | type F = Ty<>; @@ -441,7 +441,7 @@ help: add missing generic arguments LL | type F = Ty<A, B>; | ++++ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:116:22 | LL | type A = Box<dyn NonGeneric<usize>>; @@ -455,7 +455,7 @@ note: trait defined here, with 0 generic parameters LL | trait NonGeneric { | ^^^^^^^^^^ -error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:125:22 | LL | type C = Box<dyn GenericLifetime<'static, 'static>>; @@ -485,7 +485,7 @@ help: add missing generic argument LL | type D = Box<dyn GenericType<A>>; | +++ -error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:133:22 | LL | type E = Box<dyn GenericType<String, usize>>; @@ -499,7 +499,7 @@ note: trait defined here, with 1 generic parameter: `A` LL | trait GenericType<A> { | ^^^^^^^^^^^ - -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:142:22 | LL | type G = Box<dyn GenericType<>>; @@ -515,7 +515,7 @@ help: add missing generic argument LL | type G = Box<dyn GenericType<A>>; | + -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:153:26 | LL | type A = Box<dyn NonGenericAT<usize, AssocTy=()>>; @@ -529,7 +529,7 @@ note: trait defined here, with 0 generic parameters LL | trait NonGenericAT { | ^^^^^^^^^^^^ -error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:168:26 | LL | type B = Box<dyn GenericLifetimeAT<'static, 'static, AssocTy=()>>; @@ -543,7 +543,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetimeAT<'a> { | ^^^^^^^^^^^^^^^^^ -- -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:172:26 | LL | type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>; @@ -557,7 +557,7 @@ note: trait defined here, with 0 generic parameters LL | trait GenericLifetimeAT<'a> { | ^^^^^^^^^^^^^^^^^ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:185:26 | LL | type A = Box<dyn GenericTypeAT<AssocTy=()>>; @@ -573,7 +573,7 @@ help: add missing generic argument LL | type A = Box<dyn GenericTypeAT<A, AssocTy=()>>; | ++ -error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:189:26 | LL | type B = Box<dyn GenericTypeAT<(), (), AssocTy=()>>; @@ -587,7 +587,7 @@ note: trait defined here, with 1 generic parameter: `A` LL | trait GenericTypeAT<A> { | ^^^^^^^^^^^^^ - -error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:193:26 | LL | type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>; @@ -601,7 +601,7 @@ note: trait defined here, with 0 lifetime parameters LL | trait GenericTypeAT<A> { | ^^^^^^^^^^^^^ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:193:26 | LL | type C = Box<dyn GenericTypeAT<'static, AssocTy=()>>; @@ -617,7 +617,7 @@ help: add missing generic argument LL | type C = Box<dyn GenericTypeAT<'static, A, AssocTy=()>>; | +++ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:205:26 | LL | type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>; @@ -633,7 +633,7 @@ help: add missing generic argument LL | type A = Box<dyn GenericLifetimeTypeAT<A, AssocTy=()>>; | ++ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:212:26 | LL | type B = Box<dyn GenericLifetimeTypeAT<'static, AssocTy=()>>; @@ -649,7 +649,7 @@ help: add missing generic argument LL | type B = Box<dyn GenericLifetimeTypeAT<'static, A, AssocTy=()>>; | +++ -error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:216:26 | LL | type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>; @@ -663,7 +663,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ -- -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:216:26 | LL | type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, AssocTy=()>>; @@ -679,7 +679,7 @@ help: add missing generic argument LL | type C = Box<dyn GenericLifetimeTypeAT<'static, 'static, A, AssocTy=()>>; | +++ -error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:227:26 | LL | type E = Box<dyn GenericLifetimeTypeAT<(), (), AssocTy=()>>; @@ -693,7 +693,7 @@ note: trait defined here, with 1 generic parameter: `A` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:234:26 | LL | type F = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), AssocTy=()>>; @@ -707,7 +707,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ -- -error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:238:26 | LL | type G = Box<dyn GenericLifetimeTypeAT<'static, (), (), AssocTy=()>>; @@ -721,7 +721,7 @@ note: trait defined here, with 1 generic parameter: `A` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/wrong-number-of-args.rs:242:26 | LL | type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>; @@ -735,7 +735,7 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ -- -error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 2 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:242:26 | LL | type H = Box<dyn GenericLifetimeTypeAT<'static, 'static, (), (), AssocTy=()>>; @@ -749,7 +749,7 @@ note: trait defined here, with 1 generic parameter: `A` LL | trait GenericLifetimeTypeAT<'a, A> { | ^^^^^^^^^^^^^^^^^^^^^ - -error[E0107]: this trait takes 2 generic arguments but 0 generic arguments were supplied +error[E0107]: trait takes 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:254:26 | LL | type A = Box<dyn GenericTypeTypeAT<AssocTy=()>>; @@ -765,7 +765,7 @@ help: add missing generic arguments LL | type A = Box<dyn GenericTypeTypeAT<A, B, AssocTy=()>>; | +++++ -error[E0107]: this trait takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:258:26 | LL | type B = Box<dyn GenericTypeTypeAT<(), AssocTy=()>>; @@ -783,7 +783,7 @@ help: add missing generic argument LL | type B = Box<dyn GenericTypeTypeAT<(), B, AssocTy=()>>; | +++ -error[E0107]: this trait takes 2 generic arguments but 3 generic arguments were supplied +error[E0107]: trait takes 2 generic arguments but 3 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:262:26 | LL | type C = Box<dyn GenericTypeTypeAT<(), (), (), AssocTy=()>>; @@ -797,7 +797,7 @@ note: trait defined here, with 2 generic parameters: `A`, `B` LL | trait GenericTypeTypeAT<A, B> { | ^^^^^^^^^^^^^^^^^ - - -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:277:26 | LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, AssocTy=()>>; @@ -815,7 +815,7 @@ help: add missing lifetime argument LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'static, AssocTy=()>>; | +++++++++ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:287:26 | LL | type A = Box<dyn GenericLifetimeLifetimeTypeAT<AssocTy=()>>; @@ -831,7 +831,7 @@ help: add missing generic argument LL | type A = Box<dyn GenericLifetimeLifetimeTypeAT<A, AssocTy=()>>; | ++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:294:26 | LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>; @@ -849,7 +849,7 @@ help: add missing lifetime argument LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, 'static, AssocTy=()>>; | +++++++++ -error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:294:26 | LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, AssocTy=()>>; @@ -865,7 +865,7 @@ help: add missing generic argument LL | type B = Box<dyn GenericLifetimeLifetimeTypeAT<'static, A, AssocTy=()>>; | +++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:300:26 | LL | type C = Box<dyn GenericLifetimeLifetimeTypeAT<'static, (), AssocTy=()>>; @@ -894,7 +894,7 @@ help: add missing generic arguments LL | type A = HashMap<K, V>; | ++++++ -error[E0107]: this struct takes at least 2 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes at least 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:314:18 | LL | type B = HashMap<String>; @@ -907,7 +907,7 @@ help: add missing generic argument LL | type B = HashMap<String, V>; | +++ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:318:18 | LL | type C = HashMap<'static>; @@ -915,7 +915,7 @@ LL | type C = HashMap<'static>; | | | expected 0 lifetime arguments -error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied +error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:318:18 | LL | type C = HashMap<'static>; @@ -926,7 +926,7 @@ help: add missing generic arguments LL | type C = HashMap<'static, K, V>; | ++++++ -error[E0107]: this struct takes at most 3 generic arguments but 4 generic arguments were supplied +error[E0107]: struct takes at most 3 generic arguments but 4 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:324:18 | LL | type D = HashMap<usize, String, char, f64>; @@ -934,7 +934,7 @@ LL | type D = HashMap<usize, String, char, f64>; | | | expected at most 3 generic arguments -error[E0107]: this struct takes at least 2 generic arguments but 0 generic arguments were supplied +error[E0107]: struct takes at least 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:328:18 | LL | type E = HashMap<>; @@ -956,7 +956,7 @@ help: add missing generic arguments LL | type A = Result<T, E>; | ++++++ -error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied --> $DIR/wrong-number-of-args.rs:338:18 | LL | type B = Result<String>; @@ -969,7 +969,7 @@ help: add missing generic argument LL | type B = Result<String, E>; | +++ -error[E0107]: this enum takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: enum takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/wrong-number-of-args.rs:342:18 | LL | type C = Result<'static>; @@ -977,7 +977,7 @@ LL | type C = Result<'static>; | | | expected 0 lifetime arguments -error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied +error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:342:18 | LL | type C = Result<'static>; @@ -988,7 +988,7 @@ help: add missing generic arguments LL | type C = Result<'static, T, E>; | ++++++ -error[E0107]: this enum takes 2 generic arguments but 3 generic arguments were supplied +error[E0107]: enum takes 2 generic arguments but 3 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:348:18 | LL | type D = Result<usize, String, char>; @@ -996,7 +996,7 @@ LL | type D = Result<usize, String, char>; | | | expected 2 generic arguments -error[E0107]: this enum takes 2 generic arguments but 0 generic arguments were supplied +error[E0107]: enum takes 2 generic arguments but 0 generic arguments were supplied --> $DIR/wrong-number-of-args.rs:352:18 | LL | type E = Result<>; diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr index 8cda76b9490..b1b8ffa8c54 100644 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr +++ b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr @@ -10,7 +10,7 @@ note: required by a bound in `want_bar_for_any_ccx` --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15 | LL | fn want_bar_for_any_ccx<B>(b: &B) - | -------------------- required by a bound in this + | -------------------- required by a bound in this function LL | where B : for<'ccx> Bar<'ccx> | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` help: consider further restricting this bound diff --git a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr index 88793a1525b..7f96909b6e7 100644 --- a/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr +++ b/tests/ui/higher-rank-trait-bounds/hrtb-higher-ranker-supertraits.stderr @@ -10,7 +10,7 @@ note: required by a bound in `want_foo_for_any_tcx` --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15 | LL | fn want_foo_for_any_tcx<F>(f: &F) - | -------------------- required by a bound in this + | -------------------- required by a bound in this function LL | where F : for<'tcx> Foo<'tcx> | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx` help: consider further restricting this bound @@ -30,7 +30,7 @@ note: required by a bound in `want_bar_for_any_ccx` --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15 | LL | fn want_bar_for_any_ccx<B>(b: &B) - | -------------------- required by a bound in this + | -------------------- required by a bound in this function LL | where B : for<'ccx> Bar<'ccx> | ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx` help: consider further restricting this bound diff --git a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr index 86198c3f7fd..4d470ae7022 100644 --- a/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr +++ b/tests/ui/higher-rank-trait-bounds/issue-62203-hrtb-ice.stderr @@ -25,7 +25,7 @@ note: required by a bound in `T1::m` --> $DIR/issue-62203-hrtb-ice.rs:27:51 | LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - | - required by a bound in this + | - required by a bound in this associated function LL | where LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>, | ^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` @@ -56,7 +56,7 @@ note: required by a bound in `T1::m` --> $DIR/issue-62203-hrtb-ice.rs:27:12 | LL | fn m<'a, B: Ty<'a>, F>(&self, f: F) -> Unit1 - | - required by a bound in this + | - required by a bound in this associated function LL | where LL | F: for<'r> T0<'r, (<Self as Ty<'r>>::V,), O = <B as Ty<'r>>::V>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `T1::m` diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr index 62d0128fd85..edef6ccd34e 100644 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr +++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-89118.stderr @@ -15,7 +15,7 @@ note: required by a bound in `StackContext` --> $DIR/issue-89118.rs:9:14 | LL | trait StackContext - | ------------ required by a bound in this + | ------------ required by a bound in this trait LL | where LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` @@ -37,7 +37,7 @@ note: required by a bound in `EthernetWorker` --> $DIR/issue-89118.rs:28:14 | LL | struct EthernetWorker<C>(C) - | -------------- required by a bound in this + | -------------- required by a bound in this struct LL | where LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `EthernetWorker` @@ -59,7 +59,7 @@ note: required by a bound in `StackContext` --> $DIR/issue-89118.rs:9:14 | LL | trait StackContext - | ------------ required by a bound in this + | ------------ required by a bound in this trait LL | where LL | Ctx<()>: for<'a> BufferUdpStateContext<&'a ()>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `StackContext` diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr index 6206b167b0b..5be33bccdc3 100644 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr +++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/issue-90950.stderr @@ -11,7 +11,7 @@ note: required by a bound in `upcast` --> $DIR/issue-90950.rs:27:42 | LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where - | ------ required by a bound in this + | ------ required by a bound in this function LL | Y: for<'a> Yokeable<'a>, LL | for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a> | ^^^^^^^^^^^^^^^ required by this bound in `upcast` diff --git a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr index 51c9646004a..73388a72574 100644 --- a/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr +++ b/tests/ui/higher-rank-trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr @@ -8,7 +8,7 @@ note: required by a bound in `weird_bound` --> $DIR/norm-before-method-resolution.rs:18:40 | LL | fn weird_bound<X>() -> X - | ----------- required by a bound in this + | ----------- required by a bound in this function ... LL | for<'a> <X as Trait<'a>>::Out: Copy | ^^^^ required by this bound in `weird_bound` diff --git a/tests/ui/impl-trait/equal-hidden-lifetimes.rs b/tests/ui/impl-trait/equal-hidden-lifetimes.rs index 79db88828b9..a6dbf3f08f2 100644 --- a/tests/ui/impl-trait/equal-hidden-lifetimes.rs +++ b/tests/ui/impl-trait/equal-hidden-lifetimes.rs @@ -5,7 +5,6 @@ // `'a == 'static` so `&'a i32` is fine as the return type fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized { - //~^ WARNING unnecessary lifetime parameter `'a` x } diff --git a/tests/ui/impl-trait/equal-hidden-lifetimes.stderr b/tests/ui/impl-trait/equal-hidden-lifetimes.stderr deleted file mode 100644 index 3e48aef553b..00000000000 --- a/tests/ui/impl-trait/equal-hidden-lifetimes.stderr +++ /dev/null @@ -1,10 +0,0 @@ -warning: unnecessary lifetime parameter `'a` - --> $DIR/equal-hidden-lifetimes.rs:7:25 - | -LL | fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized { - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - -warning: 1 warning emitted - diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr index c8b82783ea8..9c101101870 100644 --- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr +++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: function takes 1 generic argument but 2 generic arguments were supplied --> $DIR/explicit-generic-args-for-impl.rs:4:5 | LL | foo::<str, String>("".to_string()); diff --git a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr index 9d6db88d364..a26460c8ecc 100644 --- a/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr +++ b/tests/ui/impl-trait/explicit-generic-args-with-impl-trait/not-enough-args.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied --> $DIR/not-enough-args.rs:4:5 | LL | f::<[u8]>("a", b"a"); diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.rs b/tests/ui/impl-trait/in-trait/default-method-constraint.rs new file mode 100644 index 00000000000..8c50cc29586 --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.rs @@ -0,0 +1,17 @@ +// check-pass + +// This didn't work in the previous default RPITIT method hack attempt + +#![feature(return_position_impl_trait_in_trait)] +//~^ WARN the feature `return_position_impl_trait_in_trait` is incomplete + +trait Foo { + fn bar(x: bool) -> impl Sized { + if x { + let _: u32 = Self::bar(!x); + } + Default::default() + } +} + +fn main() {} diff --git a/tests/ui/impl-trait/in-trait/default-method-constraint.stderr b/tests/ui/impl-trait/in-trait/default-method-constraint.stderr new file mode 100644 index 00000000000..5e18605aa4c --- /dev/null +++ b/tests/ui/impl-trait/in-trait/default-method-constraint.stderr @@ -0,0 +1,11 @@ +warning: the feature `return_position_impl_trait_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/default-method-constraint.rs:5:12 + | +LL | #![feature(return_position_impl_trait_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/impl-trait/issues/issue-54600.stderr b/tests/ui/impl-trait/issues/issue-54600.stderr index 316566a57a8..7ef063af952 100644 --- a/tests/ui/impl-trait/issues/issue-54600.stderr +++ b/tests/ui/impl-trait/issues/issue-54600.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-54600.rs:4:19 | LL | let x: Option<impl Debug> = Some(44_u32); diff --git a/tests/ui/impl-trait/issues/issue-54840.stderr b/tests/ui/impl-trait/issues/issue-54840.stderr index 8d82133ac90..1d1316f0e11 100644 --- a/tests/ui/impl-trait/issues/issue-54840.stderr +++ b/tests/ui/impl-trait/issues/issue-54840.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-54840.rs:5:13 | LL | let j: &impl Add = &i; diff --git a/tests/ui/impl-trait/issues/issue-58504.stderr b/tests/ui/impl-trait/issues/issue-58504.stderr index 6656e9fc3fb..26ec2a4f9cf 100644 --- a/tests/ui/impl-trait/issues/issue-58504.stderr +++ b/tests/ui/impl-trait/issues/issue-58504.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-58504.rs:10:16 | LL | let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ]; diff --git a/tests/ui/impl-trait/issues/issue-58956.stderr b/tests/ui/impl-trait/issues/issue-58956.stderr index f591c07bcf5..2b4d0abdffc 100644 --- a/tests/ui/impl-trait/issues/issue-58956.stderr +++ b/tests/ui/impl-trait/issues/issue-58956.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/issue-58956.rs:7:11 | LL | const _A: impl Lam = { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-58956.rs:9:17 | LL | let x: Wrap<impl Lam> = Wrap(B); diff --git a/tests/ui/impl-trait/issues/issue-70971.stderr b/tests/ui/impl-trait/issues/issue-70971.stderr index 4dda4c22aa2..d066256bfb0 100644 --- a/tests/ui/impl-trait/issues/issue-70971.stderr +++ b/tests/ui/impl-trait/issues/issue-70971.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-70971.rs:2:14 | LL | let x : (impl Copy,) = (true,); diff --git a/tests/ui/impl-trait/issues/issue-79099.stderr b/tests/ui/impl-trait/issues/issue-79099.stderr index 362c67dafd2..580250a62fe 100644 --- a/tests/ui/impl-trait/issues/issue-79099.stderr +++ b/tests/ui/impl-trait/issues/issue-79099.stderr @@ -9,7 +9,7 @@ LL | let f: impl core::future::Future<Output = u8> = async { 1 }; = help: pass `--edition 2021` to `rustc` = note: for more on editions, read https://doc.rust-lang.org/edition-guide -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-79099.rs:3:16 | LL | let f: impl core::future::Future<Output = u8> = async { 1 }; diff --git a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr index a227f0ba7d1..656bd047061 100644 --- a/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr +++ b/tests/ui/impl-trait/issues/issue-83929-impl-trait-in-generic-default.stderr @@ -1,10 +1,10 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:1:16 | LL | struct Foo<T = impl Copy>(T); | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/issue-83929-impl-trait-in-generic-default.rs:4:20 | LL | type Result<T, E = impl std::error::Error> = std::result::Result<T, E>; diff --git a/tests/ui/impl-trait/issues/issue-84919.stderr b/tests/ui/impl-trait/issues/issue-84919.stderr index 5abe1bd8779..36010fdef36 100644 --- a/tests/ui/impl-trait/issues/issue-84919.stderr +++ b/tests/ui/impl-trait/issues/issue-84919.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-84919.rs:5:13 | LL | let _x: impl Trait = (); diff --git a/tests/ui/impl-trait/issues/issue-86642.stderr b/tests/ui/impl-trait/issues/issue-86642.stderr index a137777840b..b6f8a54f35a 100644 --- a/tests/ui/impl-trait/issues/issue-86642.stderr +++ b/tests/ui/impl-trait/issues/issue-86642.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in const types --> $DIR/issue-86642.rs:1:11 | LL | static x: impl Fn(&str) -> Result<&str, ()> = move |source| { diff --git a/tests/ui/impl-trait/issues/issue-87295.stderr b/tests/ui/impl-trait/issues/issue-87295.stderr index 0b043056b84..ec59b719c10 100644 --- a/tests/ui/impl-trait/issues/issue-87295.stderr +++ b/tests/ui/impl-trait/issues/issue-87295.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-87295.rs:16:31 | LL | let _do_not_waste: Struct<impl Trait<Output = i32>> = Struct::new(()); diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr index 9a8f5a34068..ffe84b8e86f 100644 --- a/tests/ui/impl-trait/nested_impl_trait.stderr +++ b/tests/ui/impl-trait/nested_impl_trait.stderr @@ -34,7 +34,7 @@ LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x } | | nested `impl Trait` here | outer `impl Trait` -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/nested_impl_trait.rs:10:32 | LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {} diff --git a/tests/ui/impl-trait/normalize-tait-in-const.rs b/tests/ui/impl-trait/normalize-tait-in-const.rs index 020bcbb8396..d2e34c00b64 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.rs +++ b/tests/ui/impl-trait/normalize-tait-in-const.rs @@ -2,6 +2,7 @@ // failure-status: 101 // normalize-stderr-test "note: .*\n\n" -> "" // normalize-stderr-test "thread 'rustc' panicked.*\n" -> "" +// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: " // rustc-env:RUST_BACKTRACE=0 #![feature(type_alias_impl_trait)] diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr index 99eed29207b..84b00918724 100644 --- a/tests/ui/impl-trait/normalize-tait-in-const.stderr +++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr @@ -1,4 +1,4 @@ -error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:201:90: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead +error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:LL:CC: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead query stack during panic: #0 [eval_to_allocation_raw] const-evaluating + checking `BAR` diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr index 201aba3adff..1cae3f77cc5 100644 --- a/tests/ui/impl-trait/where-allowed.stderr +++ b/tests/ui/impl-trait/where-allowed.stderr @@ -43,109 +43,109 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; = note: see issue #63063 <https://github.com/rust-lang/rust/issues/63063> for more information = help: add `#![feature(type_alias_impl_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params --> $DIR/where-allowed.rs:16:40 | LL | fn in_fn_parameter_in_parameters(_: fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:20:42 | LL | fn in_fn_return_in_parameters(_: fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer params --> $DIR/where-allowed.rs:24:38 | LL | fn in_fn_parameter_in_return() -> fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:28:40 | LL | fn in_fn_return_in_return() -> fn() -> impl Debug { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:32:49 | LL | fn in_dyn_Fn_parameter_in_parameters(_: &dyn Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:36:51 | LL | fn in_dyn_Fn_return_in_parameters(_: &dyn Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:40:55 | LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:47:51 | LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:52:53 | LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:56:57 | LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:64:38 | LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:68:40 | LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:81:32 | LL | struct InBraceStructField { x: impl Debug } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:85:41 | LL | struct InAdtInBraceStructField { x: Vec<impl Debug> } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:89:27 | LL | struct InTupleStructField(impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:94:25 | LL | InBraceVariant { x: impl Debug }, | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field type +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in field types --> $DIR/where-allowed.rs:96:20 | LL | InTupleVariant(impl Debug), | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait method return types --> $DIR/where-allowed.rs:107:23 | LL | fn in_return() -> impl Debug; @@ -154,7 +154,7 @@ LL | fn in_return() -> impl Debug; = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `impl` method return types --> $DIR/where-allowed.rs:124:34 | LL | fn in_trait_impl_return() -> impl Debug { () } @@ -163,121 +163,121 @@ LL | fn in_trait_impl_return() -> impl Debug { () } = note: see issue #91611 <https://github.com/rust-lang/rust/issues/91611> for more information = help: add `#![feature(return_position_impl_trait_in_trait)]` to the crate attributes to enable -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` params --> $DIR/where-allowed.rs:137:33 | LL | fn in_foreign_parameters(_: impl Debug); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `extern fn` return types --> $DIR/where-allowed.rs:140:31 | LL | fn in_foreign_return() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/where-allowed.rs:156:39 | LL | type InReturnInTypeAlias<R> = fn() -> impl Debug; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in trait +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in traits --> $DIR/where-allowed.rs:161:16 | LL | impl PartialEq<impl Debug> for () { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:166:24 | LL | impl PartialEq<()> for impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:171:6 | LL | impl impl Debug { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl header +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in impl headers --> $DIR/where-allowed.rs:177:24 | LL | impl InInherentImplAdt<impl Debug> { | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:183:11 | LL | where impl Debug: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:190:15 | LL | where Vec<impl Debug>: Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bound +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in bounds --> $DIR/where-allowed.rs:197:24 | LL | where T: PartialEq<impl Debug> | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait param +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait params --> $DIR/where-allowed.rs:204:17 | LL | where T: Fn(impl Debug) | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `Fn` trait return types --> $DIR/where-allowed.rs:211:22 | LL | where T: Fn() -> impl Debug | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:217:40 | LL | struct InStructGenericParamDefault<T = impl Debug>(T); | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:221:36 | LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) } | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:225:38 | LL | trait InTraitGenericParamDefault<T = impl Debug> {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:229:41 | LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T; | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:233:11 | LL | impl <T = impl Debug> T {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter default +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic parameter defaults --> $DIR/where-allowed.rs:240:40 | LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {} | ^^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/where-allowed.rs:246:29 | LL | let _in_local_variable: impl Fn() = || {}; | ^^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in closure return types --> $DIR/where-allowed.rs:248:46 | LL | let _in_return_in_local_variable = || -> impl Fn() { || {} }; diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr index 3f6af70d8ed..dba0353377f 100644 --- a/tests/ui/implied-bounds/issue-100690.stderr +++ b/tests/ui/implied-bounds/issue-100690.stderr @@ -12,7 +12,7 @@ note: required by a bound in `real_dispatch` --> $DIR/issue-100690.rs:9:8 | LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error> - | ------------- required by a bound in this + | ------------- required by a bound in this function ... LL | F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch` diff --git a/tests/ui/inference/inference_unstable.rs b/tests/ui/inference/inference_unstable.rs index daf0cf042c4..ad76499591c 100644 --- a/tests/ui/inference/inference_unstable.rs +++ b/tests/ui/inference/inference_unstable.rs @@ -14,16 +14,16 @@ use inference_unstable_itertools::IpuItertools; fn main() { assert_eq!('x'.ipu_flatten(), 1); -//~^ WARN an associated function with this name may be added to the standard library in the future +//~^ WARN a method with this name may be added to the standard library in the future //~| WARN once this associated item is added to the standard library, the ambiguity may cause an assert_eq!('x'.ipu_by_value_vs_by_ref(), 1); -//~^ WARN an associated function with this name may be added to the standard library in the future +//~^ WARN a method with this name may be added to the standard library in the future //~| WARN once this associated item is added to the standard library, the ambiguity may cause an assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1); -//~^ WARN an associated function with this name may be added to the standard library in the future +//~^ WARN a method with this name may be added to the standard library in the future //~| WARN once this associated item is added to the standard library, the ambiguity may cause an assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1); -//~^ WARN an associated function with this name may be added to the standard library in the future +//~^ WARN a method with this name may be added to the standard library in the future //~| WARN once this associated item is added to the standard library, the ambiguity may cause an assert_eq!(char::C, 1); //~^ WARN an associated constant with this name may be added to the standard library in the future diff --git a/tests/ui/inference/inference_unstable.stderr b/tests/ui/inference/inference_unstable.stderr index ecbf2641bec..c48aaf9f495 100644 --- a/tests/ui/inference/inference_unstable.stderr +++ b/tests/ui/inference/inference_unstable.stderr @@ -1,4 +1,4 @@ -warning: an associated function with this name may be added to the standard library in the future +warning: a method with this name may be added to the standard library in the future --> $DIR/inference_unstable.rs:16:20 | LL | assert_eq!('x'.ipu_flatten(), 1); @@ -10,7 +10,7 @@ LL | assert_eq!('x'.ipu_flatten(), 1); = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_flatten` = note: `#[warn(unstable_name_collisions)]` on by default -warning: an associated function with this name may be added to the standard library in the future +warning: a method with this name may be added to the standard library in the future --> $DIR/inference_unstable.rs:19:20 | LL | assert_eq!('x'.ipu_by_value_vs_by_ref(), 1); @@ -21,7 +21,7 @@ LL | assert_eq!('x'.ipu_by_value_vs_by_ref(), 1); = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_value_vs_by_ref(...)` to keep using the current method = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_value_vs_by_ref` -warning: an associated function with this name may be added to the standard library in the future +warning: a method with this name may be added to the standard library in the future --> $DIR/inference_unstable.rs:22:20 | LL | assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1); @@ -32,7 +32,7 @@ LL | assert_eq!('x'.ipu_by_ref_vs_by_ref_mut(), 1); = help: call with fully qualified syntax `inference_unstable_itertools::IpuItertools::ipu_by_ref_vs_by_ref_mut(...)` to keep using the current method = help: add `#![feature(ipu_flatten)]` to the crate attributes to enable `inference_unstable_iterator::IpuIterator::ipu_by_ref_vs_by_ref_mut` -warning: an associated function with this name may be added to the standard library in the future +warning: a method with this name may be added to the standard library in the future --> $DIR/inference_unstable.rs:25:40 | LL | assert_eq!((&mut 'x' as *mut char).ipu_by_mut_ptr_vs_by_const_ptr(), 1); diff --git a/tests/ui/inference/inference_unstable_featured.stderr b/tests/ui/inference/inference_unstable_featured.stderr index 4ddede29c85..dc43abf52c6 100644 --- a/tests/ui/inference/inference_unstable_featured.stderr +++ b/tests/ui/inference/inference_unstable_featured.stderr @@ -6,11 +6,11 @@ LL | assert_eq!('x'.ipu_flatten(), 0); | = note: candidate #1 is defined in an impl of the trait `IpuIterator` for the type `char` = note: candidate #2 is defined in an impl of the trait `IpuItertools` for the type `char` -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | assert_eq!(IpuIterator::ipu_flatten(&'x'), 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | assert_eq!(IpuItertools::ipu_flatten(&'x'), 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/inference/issue-71732.stderr b/tests/ui/inference/issue-71732.stderr index 01b37f2acaa..e89e4dca619 100644 --- a/tests/ui/inference/issue-71732.stderr +++ b/tests/ui/inference/issue-71732.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | .get(&"key".into()) | ^^^ ------------- type must be known at this point | | - | cannot infer type of the type parameter `Q` declared on the associated function `get` + | cannot infer type of the type parameter `Q` declared on the method `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow<str> for String; diff --git a/tests/ui/inference/question-mark-type-infer.stderr b/tests/ui/inference/question-mark-type-infer.stderr index a9cb7e5257c..7a1e850d157 100644 --- a/tests/ui/inference/question-mark-type-infer.stderr +++ b/tests/ui/inference/question-mark-type-infer.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/question-mark-type-infer.rs:10:21 | LL | l.iter().map(f).collect()? - | ^^^^^^^ cannot infer type of the type parameter `B` declared on the associated function `collect` + | ^^^^^^^ cannot infer type of the type parameter `B` declared on the method `collect` | help: consider specifying the generic argument | diff --git a/tests/ui/infinite/auxiliary/alias.rs b/tests/ui/infinite/auxiliary/alias.rs new file mode 100644 index 00000000000..59add7eb18b --- /dev/null +++ b/tests/ui/infinite/auxiliary/alias.rs @@ -0,0 +1,2 @@ +pub struct W<T>(T); +pub type Wrapper<T> = W<T>; diff --git a/tests/ui/infinite/infinite-alias.rs b/tests/ui/infinite/infinite-alias.rs new file mode 100644 index 00000000000..45356f359ce --- /dev/null +++ b/tests/ui/infinite/infinite-alias.rs @@ -0,0 +1,9 @@ +// aux-build: alias.rs +// regression test for 108160 + +extern crate alias; + +use alias::Wrapper; +struct Rec(Wrapper<Rec>); //~ ERROR recursive type `Rec` has infinite + +fn main() {} diff --git a/tests/ui/infinite/infinite-alias.stderr b/tests/ui/infinite/infinite-alias.stderr new file mode 100644 index 00000000000..9d9265f8c36 --- /dev/null +++ b/tests/ui/infinite/infinite-alias.stderr @@ -0,0 +1,14 @@ +error[E0072]: recursive type `Rec` has infinite size + --> $DIR/infinite-alias.rs:7:1 + | +LL | struct Rec(Wrapper<Rec>); + | ^^^^^^^^^^ ------------ recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct Rec(Box<Wrapper<Rec>>); + | ++++ + + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0072`. diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs new file mode 100644 index 00000000000..46ece725fb7 --- /dev/null +++ b/tests/ui/issues/issue-106755.rs @@ -0,0 +1,19 @@ +// compile-flags:-Ztranslate-lang=en_US + +#![feature(negative_impls)] +#![feature(marker_trait_attr)] + +#[marker] +trait MyTrait {} + +struct TestType<T>(::std::marker::PhantomData<T>); + +unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + +impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation + +unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations + +impl !Send for TestType<i32> {} + +fn main() {} diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr new file mode 100644 index 00000000000..54397034062 --- /dev/null +++ b/tests/ui/issues/issue-106755.stderr @@ -0,0 +1,22 @@ +error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`: + --> $DIR/issue-106755.rs:13:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ positive implementation here +LL | +LL | impl<T: MyTrait> !Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here + +error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` + --> $DIR/issue-106755.rs:15:1 + | +LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {} + | ------------------------------------------------------ first implementation here +... +LL | unsafe impl<T: 'static> Send for TestType<T> {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0119, E0751. +For more information about an error, try `rustc --explain E0119`. diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr index ef28c81d857..6e1fb1540bb 100644 --- a/tests/ui/issues/issue-11374.stderr +++ b/tests/ui/issues/issue-11374.stderr @@ -10,7 +10,7 @@ LL | c.read_to(v); | = note: expected mutable reference `&mut [u8]` found struct `Vec<_>` -note: associated function defined here +note: method defined here --> $DIR/issue-11374.rs:13:12 | LL | pub fn read_to(&mut self, vec: &mut [u8]) { diff --git a/tests/ui/issues/issue-17337.stderr b/tests/ui/issues/issue-17337.stderr index 34c2eb05fff..55e51e566d9 100644 --- a/tests/ui/issues/issue-17337.stderr +++ b/tests/ui/issues/issue-17337.stderr @@ -1,4 +1,4 @@ -error: use of deprecated associated function `Foo::foo`: text +error: use of deprecated method `Foo::foo`: text --> $DIR/issue-17337.rs:16:6 | LL | .foo(); diff --git a/tests/ui/issues/issue-18423.rs b/tests/ui/issues/issue-18423.rs index a81b32f050c..675fd041154 100644 --- a/tests/ui/issues/issue-18423.rs +++ b/tests/ui/issues/issue-18423.rs @@ -2,7 +2,7 @@ struct Foo<'a> { x: Box<'a, isize> - //~^ ERROR this struct takes 0 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR struct takes 0 lifetime arguments but 1 lifetime argument was supplied } fn main() { } diff --git a/tests/ui/issues/issue-18423.stderr b/tests/ui/issues/issue-18423.stderr index bbf79366244..5d154dbbbdd 100644 --- a/tests/ui/issues/issue-18423.stderr +++ b/tests/ui/issues/issue-18423.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: struct takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/issue-18423.rs:4:8 | LL | x: Box<'a, isize> diff --git a/tests/ui/issues/issue-18446.stderr b/tests/ui/issues/issue-18446.stderr index 939cf029253..602b80c6824 100644 --- a/tests/ui/issues/issue-18446.stderr +++ b/tests/ui/issues/issue-18446.stderr @@ -14,7 +14,7 @@ note: candidate #2 is defined in the trait `T` | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | T::foo(&x); | ~~~~~~~~~~ diff --git a/tests/ui/issues/issue-21202.rs b/tests/ui/issues/issue-21202.rs index f62de7ce7db..2c5f1394449 100644 --- a/tests/ui/issues/issue-21202.rs +++ b/tests/ui/issues/issue-21202.rs @@ -8,7 +8,7 @@ mod B { use crate1::A::Foo; fn bar(f: Foo) { Foo::foo(&f); - //~^ ERROR: associated function `foo` is private + //~^ ERROR: method `foo` is private } } diff --git a/tests/ui/issues/issue-21202.stderr b/tests/ui/issues/issue-21202.stderr index 1d2816feda9..e7c3f2f9a07 100644 --- a/tests/ui/issues/issue-21202.stderr +++ b/tests/ui/issues/issue-21202.stderr @@ -1,13 +1,13 @@ -error[E0624]: associated function `foo` is private +error[E0624]: method `foo` is private --> $DIR/issue-21202.rs:10:14 | LL | Foo::foo(&f); - | ^^^ private associated function + | ^^^ private method | ::: $DIR/auxiliary/issue-21202.rs:4:9 | LL | fn foo(&self) { } - | ------------- private associated function defined here + | ------------- private method defined here error: aborting due to previous error diff --git a/tests/ui/issues/issue-23041.stderr b/tests/ui/issues/issue-23041.stderr index 6592b76a39f..4271c67c3bc 100644 --- a/tests/ui/issues/issue-23041.stderr +++ b/tests/ui/issues/issue-23041.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-23041.rs:6:7 | LL | b.downcast_ref::<fn(_)->_>(); - | ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the associated function `downcast_ref` + | ^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the method `downcast_ref` | help: consider specifying the generic argument | diff --git a/tests/ui/issues/issue-26094.rs b/tests/ui/issues/issue-26094.rs index abf3543ddb9..2742529edd3 100644 --- a/tests/ui/issues/issue-26094.rs +++ b/tests/ui/issues/issue-26094.rs @@ -1,7 +1,7 @@ macro_rules! some_macro { - ($other: expr) => ({ + ($other: expr) => {{ $other(None) //~ NOTE unexpected argument of type `Option<_>` - }) + }}; } fn some_function() {} //~ NOTE defined here @@ -9,5 +9,4 @@ fn some_function() {} //~ NOTE defined here fn main() { some_macro!(some_function); //~^ ERROR function takes 0 arguments but 1 argument was supplied - //~| NOTE in this expansion of some_macro! } diff --git a/tests/ui/issues/issue-26094.stderr b/tests/ui/issues/issue-26094.stderr index 608d2c7aff9..ecdf48470f7 100644 --- a/tests/ui/issues/issue-26094.stderr +++ b/tests/ui/issues/issue-26094.stderr @@ -2,10 +2,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied --> $DIR/issue-26094.rs:10:17 | LL | $other(None) - | ---- - | | - | unexpected argument of type `Option<_>` - | help: remove the extra argument + | ---- unexpected argument of type `Option<_>` ... LL | some_macro!(some_function); | ^^^^^^^^^^^^^ diff --git a/tests/ui/issues/issue-30438-c.rs b/tests/ui/issues/issue-30438-c.rs index 4cf634245be..813c1d3e2cc 100644 --- a/tests/ui/issues/issue-30438-c.rs +++ b/tests/ui/issues/issue-30438-c.rs @@ -5,7 +5,6 @@ trait Trait { type Out; } struct Test<'a> { s: &'a str } fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static { - //~^ WARN unnecessary lifetime parameter `'z` let x = Test { s: "this cannot last" }; &x //~^ ERROR: cannot return reference to local variable `x` diff --git a/tests/ui/issues/issue-30438-c.stderr b/tests/ui/issues/issue-30438-c.stderr index a7a5c0500fd..7c001088097 100644 --- a/tests/ui/issues/issue-30438-c.stderr +++ b/tests/ui/issues/issue-30438-c.stderr @@ -1,17 +1,9 @@ -warning: unnecessary lifetime parameter `'z` - --> $DIR/issue-30438-c.rs:7:74 - | -LL | fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static { - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'z` - error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-30438-c.rs:10:5 + --> $DIR/issue-30438-c.rs:9:5 | LL | &x | ^^ returns a reference to data owned by the current function -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0515`. diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/issues/issue-3214.rs index 928a65938b7..e3c07bb3f72 100644 --- a/tests/ui/issues/issue-3214.rs +++ b/tests/ui/issues/issue-3214.rs @@ -4,7 +4,7 @@ fn foo<T>() { } impl<T> Drop for Foo<T> { - //~^ ERROR this struct takes 0 generic arguments but 1 generic argument + //~^ ERROR struct takes 0 generic arguments but 1 generic argument fn drop(&mut self) {} } } diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/issues/issue-3214.stderr index aa0b5ce64b4..7a2d772f0a1 100644 --- a/tests/ui/issues/issue-3214.stderr +++ b/tests/ui/issues/issue-3214.stderr @@ -8,7 +8,7 @@ LL | struct Foo { LL | x: T, | ^ use of generic parameter from outer function -error[E0107]: this struct takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-3214.rs:6:22 | LL | impl<T> Drop for Foo<T> { diff --git a/tests/ui/issues/issue-3702-2.stderr b/tests/ui/issues/issue-3702-2.stderr index 1fd64ca90aa..0b94c3135a1 100644 --- a/tests/ui/issues/issue-3702-2.stderr +++ b/tests/ui/issues/issue-3702-2.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Add` for the type `isize` | LL | fn to_int(&self) -> isize { *self } | ^^^^^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | ToPrimitive::to_int(&self) + other.to_int() | ~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | Add::to_int(&self) + other.to_int() | ~~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/issues/issue-3763.rs b/tests/ui/issues/issue-3763.rs index 2e72d39cb32..893009a2cd9 100644 --- a/tests/ui/issues/issue-3763.rs +++ b/tests/ui/issues/issue-3763.rs @@ -20,9 +20,9 @@ fn main() { let _woohoo = (Box::new(my_struct)).priv_field; //~^ ERROR field `priv_field` of struct `MyStruct` is private - (&my_struct).happyfun(); //~ ERROR associated function `happyfun` is private + (&my_struct).happyfun(); //~ ERROR method `happyfun` is private - (Box::new(my_struct)).happyfun(); //~ ERROR associated function `happyfun` is private + (Box::new(my_struct)).happyfun(); //~ ERROR method `happyfun` is private let nope = my_struct.priv_field; //~^ ERROR field `priv_field` of struct `MyStruct` is private } diff --git a/tests/ui/issues/issue-3763.stderr b/tests/ui/issues/issue-3763.stderr index a09c8421bb7..d101e4c33ad 100644 --- a/tests/ui/issues/issue-3763.stderr +++ b/tests/ui/issues/issue-3763.stderr @@ -10,23 +10,23 @@ error[E0616]: field `priv_field` of struct `MyStruct` is private LL | let _woohoo = (Box::new(my_struct)).priv_field; | ^^^^^^^^^^ private field -error[E0624]: associated function `happyfun` is private +error[E0624]: method `happyfun` is private --> $DIR/issue-3763.rs:23:18 | LL | fn happyfun(&self) {} - | ------------------ private associated function defined here + | ------------------ private method defined here ... LL | (&my_struct).happyfun(); - | ^^^^^^^^ private associated function + | ^^^^^^^^ private method -error[E0624]: associated function `happyfun` is private +error[E0624]: method `happyfun` is private --> $DIR/issue-3763.rs:25:27 | LL | fn happyfun(&self) {} - | ------------------ private associated function defined here + | ------------------ private method defined here ... LL | (Box::new(my_struct)).happyfun(); - | ^^^^^^^^ private associated function + | ^^^^^^^^ private method error[E0616]: field `priv_field` of struct `MyStruct` is private --> $DIR/issue-3763.rs:26:26 diff --git a/tests/ui/issues/issue-47715.stderr b/tests/ui/issues/issue-47715.stderr index 0ee9388bf2b..dadea34b688 100644 --- a/tests/ui/issues/issue-47715.stderr +++ b/tests/ui/issues/issue-47715.stderr @@ -1,22 +1,22 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:9:37 | LL | struct Container<T: Iterable<Item = impl Foo>> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:14:30 | LL | enum Enum<T: Iterable<Item = impl Foo>> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:19:32 | LL | union Union<T: Iterable<Item = impl Foo> + Copy> { | ^^^^^^^^ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generic +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in generics --> $DIR/issue-47715.rs:24:30 | LL | type Type<T: Iterable<Item = impl Foo>> = T; diff --git a/tests/ui/issues/issue-48364.stderr b/tests/ui/issues/issue-48364.stderr index a4c88fd880a..cac4af6a7f3 100644 --- a/tests/ui/issues/issue-48364.stderr +++ b/tests/ui/issues/issue-48364.stderr @@ -8,7 +8,7 @@ LL | b"".starts_with(stringify!(foo)) | = note: expected reference `&[u8]` found reference `&'static str` -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/slice/mod.rs:LL:COL = note: this error originates in the macro `stringify` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/issues/issue-53251.rs b/tests/ui/issues/issue-53251.rs index 240826a161d..da3ba63ef67 100644 --- a/tests/ui/issues/issue-53251.rs +++ b/tests/ui/issues/issue-53251.rs @@ -9,8 +9,8 @@ macro_rules! impl_add { $( fn $n() { S::f::<i64>(); - //~^ ERROR this associated function takes 0 generic - //~| ERROR this associated function takes 0 generic + //~^ ERROR associated function takes 0 generic + //~| ERROR associated function takes 0 generic } )* } diff --git a/tests/ui/issues/issue-53251.stderr b/tests/ui/issues/issue-53251.stderr index cee9a5deb05..d5f14e8deb9 100644 --- a/tests/ui/issues/issue-53251.stderr +++ b/tests/ui/issues/issue-53251.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-53251.rs:11:20 | LL | S::f::<i64>(); @@ -16,7 +16,7 @@ LL | fn f() {} | ^ = note: this error originates in the macro `impl_add` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-53251.rs:11:20 | LL | S::f::<i64>(); diff --git a/tests/ui/issues/issue-60218.stderr b/tests/ui/issues/issue-60218.stderr index dd72b6515dd..563690c9a5d 100644 --- a/tests/ui/issues/issue-60218.stderr +++ b/tests/ui/issues/issue-60218.stderr @@ -10,7 +10,7 @@ note: required by a bound in `trigger_error` --> $DIR/issue-60218.rs:13:72 | LL | pub fn trigger_error<I, F>(iterable: I, functor: F) - | ------------- required by a bound in this + | ------------- required by a bound in this function ... LL | for<'t> <Map<<&'t I as IntoIterator>::IntoIter, F> as Iterator>::Item: Foo, | ^^^ required by this bound in `trigger_error` diff --git a/tests/ui/issues/issue-60622.rs b/tests/ui/issues/issue-60622.rs index 8e230c615bc..7b9443eee50 100644 --- a/tests/ui/issues/issue-60622.rs +++ b/tests/ui/issues/issue-60622.rs @@ -9,7 +9,7 @@ impl Borked { fn run_wild<T>(b: &Borked) { b.a::<'_, T>(); //~^ ERROR cannot specify lifetime arguments explicitly if late bound lifetime parameters are present - //~| ERROR this associated function takes 0 generic arguments but 1 generic argument + //~| ERROR method takes 0 generic arguments but 1 generic argument //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! } diff --git a/tests/ui/issues/issue-60622.stderr b/tests/ui/issues/issue-60622.stderr index ecf1ae758dd..43da2773940 100644 --- a/tests/ui/issues/issue-60622.stderr +++ b/tests/ui/issues/issue-60622.stderr @@ -16,7 +16,7 @@ LL | #![deny(warnings)] | ^^^^^^^^ = note: `#[deny(late_bound_lifetime_arguments)]` implied by `#[deny(warnings)]` -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-60622.rs:10:7 | LL | b.a::<'_, T>(); @@ -24,7 +24,7 @@ LL | b.a::<'_, T>(); | | | expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/issue-60622.rs:6:8 | LL | fn a(&self) {} diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr index d0cb16995af..4af3672ef72 100644 --- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr +++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `await` for the type `r#fn | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | async::r#struct(&r#fn {}); | ~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | await::r#struct(&r#fn {}); | ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr index a75c1c41363..2b96a0fb5e5 100644 --- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr +++ b/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `r#await` for the type `r# | LL | fn r#struct(&self) { | ^^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | r#async::r#struct(&r#fn {}); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | r#await::r#struct(&r#fn {}); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/issues/issue-69455.stderr b/tests/ui/issues/issue-69455.stderr index fc343bb54aa..d3e307fba2c 100644 --- a/tests/ui/issues/issue-69455.stderr +++ b/tests/ui/issues/issue-69455.stderr @@ -2,7 +2,7 @@ error[E0284]: type annotations needed --> $DIR/issue-69455.rs:29:41 | LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | | | type must be known at this point | @@ -16,7 +16,7 @@ error[E0283]: type annotations needed --> $DIR/issue-69455.rs:29:41 | LL | println!("{}", 23u64.test(xs.iter().sum())); - | ---- ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ---- ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | | | required by a bound introduced by this call | diff --git a/tests/ui/issues/issue-69683.stderr b/tests/ui/issues/issue-69683.stderr index 193de1a35cf..c428ea9ea2c 100644 --- a/tests/ui/issues/issue-69683.stderr +++ b/tests/ui/issues/issue-69683.stderr @@ -31,7 +31,7 @@ LL | u8: Element<I>, | ^^^^^^^^^^ required by this bound in `Foo::foo` LL | { LL | fn foo(self, x: <u8 as Element<I>>::Array); - | --- required by a bound in this + | --- required by a bound in this associated function help: try using a fully qualified path to specify the expected types | LL | <u16 as Foo<I>>::foo(0u16, b); diff --git a/tests/ui/issues/issue-70093/issue-70093-link-directives.rs b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs new file mode 100644 index 00000000000..83f9b16c408 --- /dev/null +++ b/tests/ui/issues/issue-70093/issue-70093-link-directives.rs @@ -0,0 +1,10 @@ +// run-pass +// compile-flags: -Zlink-directives=no +// ignore-windows - this will probably only work on unixish systems +// ignore-fuchsia - missing __libc_start_main for some reason (#84733) +// ignore-cross-compile - default-linker-libraries=yes doesn't play well with cross compiling + +#[link(name = "some-random-non-existent-library", kind = "static")] +extern "C" {} + +fn main() {} diff --git a/tests/ui/issues/issue-70093.rs b/tests/ui/issues/issue-70093/issue-70093.rs index 86459dc904a..86459dc904a 100644 --- a/tests/ui/issues/issue-70093.rs +++ b/tests/ui/issues/issue-70093/issue-70093.rs diff --git a/tests/ui/lang-items/bad-add-impl.rs b/tests/ui/lang-items/bad-add-impl.rs new file mode 100644 index 00000000000..0c44edbe51a --- /dev/null +++ b/tests/ui/lang-items/bad-add-impl.rs @@ -0,0 +1,18 @@ +#![feature(no_core)] +#![feature(lang_items)] +#![no_core] + +#[lang = "sized"] +trait Sized {} + +#[lang = "add"] +trait Add<T> { + const add: u32 = 1u32; +} + +impl Add<u32> for u32 {} + +fn main() { + 1u32 + 1u32; + //~^ ERROR cannot add `u32` to `u32` +} diff --git a/tests/ui/lang-items/bad-add-impl.stderr b/tests/ui/lang-items/bad-add-impl.stderr new file mode 100644 index 00000000000..3143729f99b --- /dev/null +++ b/tests/ui/lang-items/bad-add-impl.stderr @@ -0,0 +1,11 @@ +error[E0369]: cannot add `u32` to `u32` + --> $DIR/bad-add-impl.rs:16:10 + | +LL | 1u32 + 1u32; + | ---- ^ ---- u32 + | | + | u32 + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr new file mode 100644 index 00000000000..ff603111e94 --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_item.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr new file mode 100644 index 00000000000..ff603111e94 --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.bad_sig.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:39:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:43:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_item.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_bad_sig.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_item.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_mut_bad_sig.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_item.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr new file mode 100644 index 00000000000..02e33c597fe --- /dev/null +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.fn_once_bad_sig.stderr @@ -0,0 +1,18 @@ +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:42:5 + | +LL | a(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: failed to find an overloaded call trait for closure call + --> $DIR/fn-fn_mut-call-ill-formed.rs:47:5 + | +LL | b(); + | ^^^ + | + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs index 52bd8136d9c..757c6538d05 100644 --- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs +++ b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.rs @@ -1,27 +1,49 @@ -// Make sure that an error is reported if the `call` function of the -// `fn`/`fn_mut` lang item is grossly ill-formed. +// revisions: fn_once_bad_item fn_once_bad_sig fn_mut_bad_item fn_mut_bad_sig fn_bad_item fn_bad_sig #![feature(lang_items)] #![feature(no_core)] #![no_core] +#[lang = "sized"] +trait Sized {} + +#[cfg(any(fn_bad_item, fn_bad_sig))] #[lang = "fn"] trait MyFn<T> { + #[cfg(fn_bad_sig)] + fn call(i: i32) -> i32 { 0 } + + #[cfg(fn_bad_item)] const call: i32 = 42; - //~^ ERROR: `call` trait item in `fn` lang item must be a function } +#[cfg(any(fn_mut_bad_item, fn_mut_bad_sig))] #[lang = "fn_mut"] trait MyFnMut<T> { - fn call(i: i32, j: i32) -> i32 { i + j } - //~^ ERROR: first argument of `call` in `fn_mut` lang item must be a reference + #[cfg(fn_mut_bad_sig)] + fn call_mut(i: i32) -> i32 { 0 } + + #[cfg(fn_mut_bad_item)] + const call_mut: i32 = 42; +} + +#[cfg(any(fn_once_bad_item, fn_once_bad_sig))] +#[lang = "fn_once"] +trait MyFnOnce<T> { + #[cfg(fn_once_bad_sig)] + fn call_once(i: i32) -> i32 { 0 } + + #[cfg(fn_once_bad_item)] + const call_once: i32 = 42; } fn main() { let a = || 42; a(); + //~^ ERROR failed to find an overloaded call trait for closure call let mut i = 0; - let mut b = || { i += 1; }; + let mut b = || { }; b(); + //~^ ERROR failed to find an overloaded call trait for closure call } diff --git a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr b/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr deleted file mode 100644 index 82bdae270c8..00000000000 --- a/tests/ui/lang-items/fn-fn_mut-call-ill-formed.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: `call` trait item in `fn` lang item must be a function - --> $DIR/fn-fn_mut-call-ill-formed.rs:10:5 - | -LL | const call: i32 = 42; - | ^^^^^^^^^^^^^^^^^^^^^ - -error: first argument of `call` in `fn_mut` lang item must be a reference - --> $DIR/fn-fn_mut-call-ill-formed.rs:16:16 - | -LL | fn call(i: i32, j: i32) -> i32 { i + j } - | ^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/lang-items/issue-86238.stderr b/tests/ui/lang-items/issue-86238.stderr index 767e6de2263..c6e811a94fe 100644 --- a/tests/ui/lang-items/issue-86238.stderr +++ b/tests/ui/lang-items/issue-86238.stderr @@ -4,7 +4,7 @@ error: failed to find an overloaded call trait for closure call LL | one() | ^^^^^ | - = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have associated `call`/`call_mut`/`call_once` functions + = help: make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods error: aborting due to previous error diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs index 0b331e2039f..792563fd82b 100644 --- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs +++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.rs @@ -7,6 +7,6 @@ trait Trait<'a> { type Alias<'a, T> = <T as Trait<'a>>::Assoc; fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} -//~^ error: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied +//~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied fn main() {} diff --git a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr index 3704d9bb957..de58a014ee8 100644 --- a/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr +++ b/tests/ui/late-bound-lifetimes/mismatched_arg_count.stderr @@ -1,4 +1,4 @@ -error[E0107]: this type alias takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/mismatched_arg_count.rs:9:29 | LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr index 4bcd7cf9578..6fd7f67d15e 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-return-type-is-anon.stderr @@ -7,7 +7,7 @@ LL | fn foo<'a>(&self, x: &'a i32) -> &i32 { | lifetime `'a` defined here LL | LL | x - | ^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | ^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` error: aborting due to previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr index 34a64f8a63e..2687266e098 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1-return-one-existing-name-self-is-anon.stderr @@ -7,7 +7,7 @@ LL | fn foo<'a>(&self, x: &'a Foo) -> &'a Foo { | lifetime `'a` defined here LL | LL | if true { x } else { self } - | ^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` + | ^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'1` error: aborting due to previous error diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr index 5601335d275..9ff5e42d732 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.stderr @@ -6,7 +6,7 @@ LL | fn foo<'a>(&self, x: &i32) -> &i32 { | | | let's call the lifetime of this reference `'2` LL | x - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr index e221902c4a9..e4c855e11fe 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.stderr @@ -6,7 +6,7 @@ LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | | | let's call the lifetime of this reference `'2` LL | if true { x } else { self } - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/lint/dead-code/in-closure.rs b/tests/ui/lint/dead-code/in-closure.rs new file mode 100644 index 00000000000..c55634405ed --- /dev/null +++ b/tests/ui/lint/dead-code/in-closure.rs @@ -0,0 +1,16 @@ +// edition: 2021 + +#![deny(dead_code)] + +pub fn foo() { + let closure = || { + fn a() {} //~ ERROR function `a` is never used + }; + closure() +} + +pub async fn async_foo() { + const A: usize = 1; //~ ERROR constant `A` is never used +} + +fn main() {} diff --git a/tests/ui/lint/dead-code/in-closure.stderr b/tests/ui/lint/dead-code/in-closure.stderr new file mode 100644 index 00000000000..deb276be702 --- /dev/null +++ b/tests/ui/lint/dead-code/in-closure.stderr @@ -0,0 +1,20 @@ +error: function `a` is never used + --> $DIR/in-closure.rs:7:12 + | +LL | fn a() {} + | ^ + | +note: the lint level is defined here + --> $DIR/in-closure.rs:3:9 + | +LL | #![deny(dead_code)] + | ^^^^^^^^^ + +error: constant `A` is never used + --> $DIR/in-closure.rs:13:11 + | +LL | const A: usize = 1; + | ^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/lint/dead-code/issue-85255.rs b/tests/ui/lint/dead-code/issue-85255.rs index 043f68137b8..1978bd4e824 100644 --- a/tests/ui/lint/dead-code/issue-85255.rs +++ b/tests/ui/lint/dead-code/issue-85255.rs @@ -11,8 +11,8 @@ struct Foo { struct Bar; impl Bar { - fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used - pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used + fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used + pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used } pub(crate) struct Foo1 { @@ -23,8 +23,8 @@ pub(crate) struct Foo1 { pub(crate) struct Bar1; impl Bar1 { - fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used - pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used + fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used + pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used } pub(crate) struct Foo2 { @@ -35,8 +35,8 @@ pub(crate) struct Foo2 { pub(crate) struct Bar2; impl Bar2 { - fn a(&self) -> i32 { 5 } //~ WARNING: associated function `a` is never used - pub fn b(&self) -> i32 { 6 } //~ WARNING: associated function `b` is never used + fn a(&self) -> i32 { 5 } //~ WARNING: method `a` is never used + pub fn b(&self) -> i32 { 6 } //~ WARNING: method `b` is never used } diff --git a/tests/ui/lint/dead-code/issue-85255.stderr b/tests/ui/lint/dead-code/issue-85255.stderr index 3497b952fdd..58a19cf3c99 100644 --- a/tests/ui/lint/dead-code/issue-85255.stderr +++ b/tests/ui/lint/dead-code/issue-85255.stderr @@ -34,37 +34,37 @@ LL | a: i32, LL | pub b: i32, | ^ -warning: associated function `a` is never used +warning: method `a` is never used --> $DIR/issue-85255.rs:14:8 | LL | fn a(&self) -> i32 { 5 } | ^ -warning: associated function `b` is never used +warning: method `b` is never used --> $DIR/issue-85255.rs:15:12 | LL | pub fn b(&self) -> i32 { 6 } | ^ -warning: associated function `a` is never used +warning: method `a` is never used --> $DIR/issue-85255.rs:26:8 | LL | fn a(&self) -> i32 { 5 } | ^ -warning: associated function `b` is never used +warning: method `b` is never used --> $DIR/issue-85255.rs:27:12 | LL | pub fn b(&self) -> i32 { 6 } | ^ -warning: associated function `a` is never used +warning: method `a` is never used --> $DIR/issue-85255.rs:38:8 | LL | fn a(&self) -> i32 { 5 } | ^ -warning: associated function `b` is never used +warning: method `b` is never used --> $DIR/issue-85255.rs:39:12 | LL | pub fn b(&self) -> i32 { 6 } diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.rs b/tests/ui/lint/dead-code/lint-dead-code-3.rs index 293fcdbc5ee..20b568054df 100644 --- a/tests/ui/lint/dead-code/lint-dead-code-3.rs +++ b/tests/ui/lint/dead-code/lint-dead-code-3.rs @@ -13,7 +13,7 @@ extern "C" { struct Foo; //~ ERROR: struct `Foo` is never constructed impl Foo { - fn foo(&self) { //~ ERROR: associated function `foo` is never used + fn foo(&self) { //~ ERROR: method `foo` is never used bar() } } diff --git a/tests/ui/lint/dead-code/lint-dead-code-3.stderr b/tests/ui/lint/dead-code/lint-dead-code-3.stderr index 26fc13bae08..797b7559c01 100644 --- a/tests/ui/lint/dead-code/lint-dead-code-3.stderr +++ b/tests/ui/lint/dead-code/lint-dead-code-3.stderr @@ -34,7 +34,7 @@ error: function `blah` is never used LL | fn blah() {} | ^^^^ -error: associated function `foo` is never used +error: method `foo` is never used --> $DIR/lint-dead-code-3.rs:16:8 | LL | fn foo(&self) { diff --git a/tests/ui/lint/invalid_value.stderr b/tests/ui/lint/invalid_value.stderr index 48fd4169da7..57531b0968f 100644 --- a/tests/ui/lint/invalid_value.stderr +++ b/tests/ui/lint/invalid_value.stderr @@ -61,10 +61,7 @@ error: the type `!` does not permit zero-initialization --> $DIR/invalid_value.rs:65:23 | LL | let _val: ! = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: the `!` type has no valid value @@ -72,10 +69,7 @@ error: the type `!` does not permit being left uninitialized --> $DIR/invalid_value.rs:66:23 | LL | let _val: ! = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: the `!` type has no valid value @@ -83,10 +77,7 @@ error: the type `(i32, !)` does not permit zero-initialization --> $DIR/invalid_value.rs:68:30 | LL | let _val: (i32, !) = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: the `!` type has no valid value @@ -94,10 +85,7 @@ error: the type `(i32, !)` does not permit being left uninitialized --> $DIR/invalid_value.rs:69:30 | LL | let _val: (i32, !) = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | = note: integers must be initialized @@ -105,10 +93,7 @@ error: the type `Void` does not permit zero-initialization --> $DIR/invalid_value.rs:71:26 | LL | let _val: Void = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/invalid_value.rs:12:1 @@ -120,10 +105,7 @@ error: the type `Void` does not permit being left uninitialized --> $DIR/invalid_value.rs:72:26 | LL | let _val: Void = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/invalid_value.rs:12:1 @@ -405,10 +387,7 @@ error: the type `TwoUninhabited` does not permit zero-initialization --> $DIR/invalid_value.rs:104:36 | LL | let _val: TwoUninhabited = mem::zeroed(); - | ^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/invalid_value.rs:42:1 @@ -420,10 +399,7 @@ error: the type `TwoUninhabited` does not permit being left uninitialized --> $DIR/invalid_value.rs:105:36 | LL | let _val: TwoUninhabited = mem::uninitialized(); - | ^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/invalid_value.rs:42:1 diff --git a/tests/ui/lint/issue-106991.rs b/tests/ui/lint/issue-106991.rs new file mode 100644 index 00000000000..e4d7f765b4a --- /dev/null +++ b/tests/ui/lint/issue-106991.rs @@ -0,0 +1,13 @@ +fn foo(items: &mut Vec<u8>) { + items.sort(); +} + +fn bar() -> impl Iterator<Item = i32> { + //~^ ERROR expected `foo` to be a fn item that returns `i32`, but it returns `()` [E0271] + let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]]; + x.iter_mut().map(foo) +} + +fn main() { + bar(); +} diff --git a/tests/ui/lint/issue-106991.stderr b/tests/ui/lint/issue-106991.stderr new file mode 100644 index 00000000000..7b43f0b2ca8 --- /dev/null +++ b/tests/ui/lint/issue-106991.stderr @@ -0,0 +1,11 @@ +error[E0271]: expected `foo` to be a fn item that returns `i32`, but it returns `()` + --> $DIR/issue-106991.rs:5:13 + | +LL | fn bar() -> impl Iterator<Item = i32> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found `i32` + | + = note: required for `Map<std::slice::IterMut<'_, Vec<u8>>, for<'a> fn(&'a mut Vec<u8>) {foo}>` to implement `Iterator` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/lint/lint-missing-doc.rs b/tests/ui/lint/lint-missing-doc.rs index 2297257919e..4a234d2651a 100644 --- a/tests/ui/lint/lint-missing-doc.rs +++ b/tests/ui/lint/lint-missing-doc.rs @@ -50,8 +50,10 @@ trait B { } pub trait C { //~ ERROR: missing documentation for a trait - fn foo(&self); //~ ERROR: missing documentation for an associated function - fn foo_with_impl(&self) {} //~ ERROR: missing documentation for an associated function + fn foo(&self); //~ ERROR: missing documentation for a method + fn foo_with_impl(&self) {} //~ ERROR: missing documentation for a method + fn foo_no_self(); //~ ERROR: missing documentation for an associated function + fn foo_no_self_with_impl() {} //~ ERROR: missing documentation for an associated function } #[allow(missing_docs)] diff --git a/tests/ui/lint/lint-missing-doc.stderr b/tests/ui/lint/lint-missing-doc.stderr index d68472d4b66..733d062a08b 100644 --- a/tests/ui/lint/lint-missing-doc.stderr +++ b/tests/ui/lint/lint-missing-doc.stderr @@ -40,101 +40,113 @@ error: missing documentation for a trait LL | pub trait C { | ^^^^^^^^^^^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/lint-missing-doc.rs:53:5 | LL | fn foo(&self); | ^^^^^^^^^^^^^^ -error: missing documentation for an associated function +error: missing documentation for a method --> $DIR/lint-missing-doc.rs:54:5 | LL | fn foo_with_impl(&self) {} | ^^^^^^^^^^^^^^^^^^^^^^^ +error: missing documentation for an associated function + --> $DIR/lint-missing-doc.rs:55:5 + | +LL | fn foo_no_self(); + | ^^^^^^^^^^^^^^^^^ + +error: missing documentation for an associated function + --> $DIR/lint-missing-doc.rs:56:5 + | +LL | fn foo_no_self_with_impl() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: missing documentation for an associated type - --> $DIR/lint-missing-doc.rs:64:5 + --> $DIR/lint-missing-doc.rs:66:5 | LL | type AssociatedType; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated type - --> $DIR/lint-missing-doc.rs:65:5 + --> $DIR/lint-missing-doc.rs:67:5 | LL | type AssociatedTypeDef = Self; | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for an associated function - --> $DIR/lint-missing-doc.rs:81:5 + --> $DIR/lint-missing-doc.rs:83:5 | LL | pub fn foo() {} | ^^^^^^^^^^^^ error: missing documentation for an enum - --> $DIR/lint-missing-doc.rs:118:1 + --> $DIR/lint-missing-doc.rs:120:1 | LL | pub enum PubBaz { | ^^^^^^^^^^^^^^^ error: missing documentation for a variant - --> $DIR/lint-missing-doc.rs:119:5 + --> $DIR/lint-missing-doc.rs:121:5 | LL | PubBazA { | ^^^^^^^ error: missing documentation for a struct field - --> $DIR/lint-missing-doc.rs:120:9 + --> $DIR/lint-missing-doc.rs:122:9 | LL | a: isize, | ^^^^^^^^ error: missing documentation for a constant - --> $DIR/lint-missing-doc.rs:151:1 + --> $DIR/lint-missing-doc.rs:153:1 | LL | pub const FOO4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/lint-missing-doc.rs:161:1 + --> $DIR/lint-missing-doc.rs:163:1 | LL | pub static BAR4: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:167:5 + --> $DIR/lint-missing-doc.rs:169:5 | LL | pub fn undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:168:5 + --> $DIR/lint-missing-doc.rs:170:5 | LL | pub fn undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:174:9 + --> $DIR/lint-missing-doc.rs:176:9 | LL | pub fn also_undocumented1() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a function - --> $DIR/lint-missing-doc.rs:189:5 + --> $DIR/lint-missing-doc.rs:191:5 | LL | pub fn extern_fn_undocumented(f: f32) -> f32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a static - --> $DIR/lint-missing-doc.rs:194:5 + --> $DIR/lint-missing-doc.rs:196:5 | LL | pub static EXTERN_STATIC_UNDOCUMENTED: u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: missing documentation for a foreign type - --> $DIR/lint-missing-doc.rs:199:5 + --> $DIR/lint-missing-doc.rs:201:5 | LL | pub type ExternTyUndocumented; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 22 previous errors +error: aborting due to 24 previous errors diff --git a/tests/ui/lint/lint-stability-deprecated.rs b/tests/ui/lint/lint-stability-deprecated.rs index 74c35083e60..a56a37228e5 100644 --- a/tests/ui/lint/lint-stability-deprecated.rs +++ b/tests/ui/lint/lint-stability-deprecated.rs @@ -22,40 +22,40 @@ mod cross_crate { let foo = MethodTester; deprecated(); //~ WARN use of deprecated function `lint_stability::deprecated` - foo.method_deprecated(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` - Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated` - foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` + foo.method_deprecated(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` deprecated_text(); //~ WARN use of deprecated function `lint_stability::deprecated_text`: text - foo.method_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text deprecated_unstable(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable` - foo.method_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` - Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` - <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable` - foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` + foo.method_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable` + Foo::method_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable` + <Foo>::method_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable` + foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` deprecated_unstable_text(); //~ WARN use of deprecated function `lint_stability::deprecated_unstable_text`: text - foo.method_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + foo.method_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text + Foo::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text + <Foo>::method_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text unstable(); foo.method_unstable(); @@ -141,22 +141,22 @@ mod cross_crate { } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text - <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + Trait::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + <Foo>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + <Foo as Trait>::trait_deprecated_unstable(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + Trait::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text + <Foo as Trait>::trait_deprecated_unstable_text(&foo); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -172,10 +172,10 @@ mod cross_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text - foo.trait_deprecated_unstable(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable` - foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text + foo.trait_deprecated(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text + foo.trait_deprecated_unstable(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable` + foo.trait_deprecated_unstable_text(); //~ WARN use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); @@ -328,22 +328,22 @@ mod this_crate { let foo = MethodTester; deprecated(); //~ WARN use of deprecated function `this_crate::deprecated` - foo.method_deprecated(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` - Foo::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` - <Foo>::method_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated` - foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` + foo.method_deprecated(); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated` + Foo::method_deprecated(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated` + <Foo>::method_deprecated(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated` + foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` deprecated_text(); //~ WARN use of deprecated function `this_crate::deprecated_text`: text - foo.method_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - Foo::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.method_deprecated_text(); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + Foo::method_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + <Foo>::method_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text + foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text unstable(); foo.method_unstable(); @@ -402,14 +402,14 @@ mod this_crate { } fn test_method_param<Foo: Trait>(foo: Foo) { - foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - Trait::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text - <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + Trait::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + <Foo as Trait>::trait_deprecated(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + Trait::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text + <Foo as Trait>::trait_deprecated_text(&foo); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); Trait::trait_unstable(&foo); <Foo>::trait_unstable(&foo); @@ -425,8 +425,8 @@ mod this_crate { } fn test_method_object(foo: &dyn Trait) { - foo.trait_deprecated(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated` - foo.trait_deprecated_text(); //~ WARN use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text + foo.trait_deprecated(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated` + foo.trait_deprecated_text(); //~ WARN use of deprecated method `this_crate::Trait::trait_deprecated_text`: text foo.trait_unstable(); foo.trait_unstable_text(); foo.trait_stable(); diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr index 9f1e7b281e9..19a4649e168 100644 --- a/tests/ui/lint/lint-stability-deprecated.stderr +++ b/tests/ui/lint/lint-stability-deprecated.stderr @@ -10,13 +10,13 @@ note: the lint level is defined here LL | #![warn(deprecated)] | ^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:29:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:31:25 | LL | <Foo as Trait>::trait_deprecated(&foo); @@ -28,17 +28,17 @@ warning: use of deprecated function `lint_stability::deprecated_text`: text LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:38:16 | -LL | ... Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:40:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `lint_stability::deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:42:9 @@ -46,13 +46,13 @@ warning: use of deprecated function `lint_stability::deprecated_unstable`: text LL | deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:47:16 | -LL | ... Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:49:25 | LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); @@ -64,13 +64,13 @@ warning: use of deprecated function `lint_stability::deprecated_unstable_text`: LL | deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:56:16 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:58:25 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); @@ -142,49 +142,49 @@ warning: use of deprecated function `lint_stability::deprecated_text`: text LL | macro_test_arg!(macro_test_arg!(deprecated_text())); | ^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:145:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:147:25 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:149:16 | -LL | ... Trait::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:151:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:153:16 | -LL | ... Trait::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Trait::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:155:25 | LL | ... <Foo as Trait>::trait_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:157:16 | LL | ... Trait::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:159:25 | LL | ... <Foo as Trait>::trait_deprecated_unstable_text(&foo); @@ -214,13 +214,13 @@ warning: use of deprecated function `this_crate::deprecated`: text LL | deprecated(); | ^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:335:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:337:25 | LL | <Foo as Trait>::trait_deprecated(&foo); @@ -232,17 +232,17 @@ warning: use of deprecated function `this_crate::deprecated_text`: text LL | deprecated_text(); | ^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:344:16 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:346:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated struct `this_crate::DeprecatedStruct`: text --> $DIR/lint-stability-deprecated.rs:384:17 @@ -268,29 +268,29 @@ warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: tex LL | let _ = DeprecatedTupleStruct (1); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:406:16 | LL | Trait::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:408:25 | LL | <Foo as Trait>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:410:16 | LL | Trait::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:412:25 | -LL | ... <Foo as Trait>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo as Trait>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text --> $DIR/lint-stability-deprecated.rs:439:9 @@ -328,121 +328,121 @@ warning: use of deprecated associated type `lint_stability::TraitWithAssociatedT LL | TypeDeprecated = u16, | ^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:25:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:26:14 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:27:16 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:28:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:30:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:34:13 | -LL | ... foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:35:14 | -LL | ... Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:36:16 | -LL | ... <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:37:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:39:16 | -LL | ... <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:43:13 | -LL | ... foo.method_deprecated_unstable(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | foo.method_deprecated_unstable(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:44:14 | -LL | ... Foo::method_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | Foo::method_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:45:16 | LL | ... <Foo>::method_deprecated_unstable(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:46:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:48:16 | -LL | ... <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:52:13 | LL | ... foo.method_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:53:14 | LL | ... Foo::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::MethodTester::method_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::MethodTester::method_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:54:16 | LL | ... <Foo>::method_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:55:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:57:16 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); @@ -460,133 +460,133 @@ warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: LL | i: 0 | ^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:144:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:146:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:148:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:150:16 | -LL | ... <Foo>::trait_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:152:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:154:16 | -LL | ... <Foo>::trait_deprecated_unstable(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::trait_deprecated_unstable(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:156:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:158:16 | LL | ... <Foo>::trait_deprecated_unstable_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:175:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:176:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text --> $DIR/lint-stability-deprecated.rs:177:13 | LL | foo.trait_deprecated_unstable(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `lint_stability::Trait::trait_deprecated_unstable_text`: text +warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text --> $DIR/lint-stability-deprecated.rs:178:13 | LL | ... foo.trait_deprecated_unstable_text(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:331:13 | LL | foo.method_deprecated(); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:332:14 | LL | Foo::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text --> $DIR/lint-stability-deprecated.rs:333:16 | LL | <Foo>::method_deprecated(&foo); | ^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:334:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:336:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:340:13 | -LL | ... foo.method_deprecated_text(); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | foo.method_deprecated_text(); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:341:14 | -LL | ... Foo::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | Foo::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::MethodTester::method_deprecated_text`: text +warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:342:16 | -LL | ... <Foo>::method_deprecated_text(&foo); - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | <Foo>::method_deprecated_text(&foo); + | ^^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:343:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:345:16 | LL | <Foo>::trait_deprecated_text(&foo); @@ -598,37 +598,37 @@ warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text LL | i: 0 | ^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:405:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:407:16 | LL | <Foo>::trait_deprecated(&foo); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:409:13 | LL | foo.trait_deprecated_text(); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:411:16 | LL | <Foo>::trait_deprecated_text(&foo); | ^^^^^^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text --> $DIR/lint-stability-deprecated.rs:428:13 | LL | foo.trait_deprecated(); | ^^^^^^^^^^^^^^^^ -warning: use of deprecated associated function `this_crate::Trait::trait_deprecated_text`: text +warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text --> $DIR/lint-stability-deprecated.rs:429:13 | LL | foo.trait_deprecated_text(); diff --git a/tests/ui/lint/lint_map_unit_fn.rs b/tests/ui/lint/lint_map_unit_fn.rs new file mode 100644 index 00000000000..dc1ecbf8424 --- /dev/null +++ b/tests/ui/lint/lint_map_unit_fn.rs @@ -0,0 +1,20 @@ +#![deny(map_unit_fn)] + +fn foo(items: &mut Vec<u8>) { + items.sort(); +} + +fn main() { + let mut x: Vec<Vec<u8>> = vec![vec![0, 2, 1], vec![5, 4, 3]]; + x.iter_mut().map(foo); + //~^ ERROR `Iterator::map` call that discard the iterator's values + x.iter_mut().map(|items| { + //~^ ERROR `Iterator::map` call that discard the iterator's values + items.sort(); + }); + let f = |items: &mut Vec<u8>| { + items.sort(); + }; + x.iter_mut().map(f); + //~^ ERROR `Iterator::map` call that discard the iterator's values +} diff --git a/tests/ui/lint/lint_map_unit_fn.stderr b/tests/ui/lint/lint_map_unit_fn.stderr new file mode 100644 index 00000000000..fbf689c5421 --- /dev/null +++ b/tests/ui/lint/lint_map_unit_fn.stderr @@ -0,0 +1,66 @@ +error: `Iterator::map` call that discard the iterator's values + --> $DIR/lint_map_unit_fn.rs:9:18 + | +LL | fn foo(items: &mut Vec<u8>) { + | --------------------------- this function returns `()`, which is likely not what you wanted +... +LL | x.iter_mut().map(foo); + | ^^^^---^ + | | | + | | called `Iterator::map` with callable that returns `()` + | after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items + | + = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated +note: the lint level is defined here + --> $DIR/lint_map_unit_fn.rs:1:9 + | +LL | #![deny(map_unit_fn)] + | ^^^^^^^^^^^ +help: you might have meant to use `Iterator::for_each` + | +LL | x.iter_mut().for_each(foo); + | ~~~~~~~~ + +error: `Iterator::map` call that discard the iterator's values + --> $DIR/lint_map_unit_fn.rs:11:18 + | +LL | x.iter_mut().map(|items| { + | ^ ------- + | | | + | ____________________|___this function returns `()`, which is likely not what you wanted + | | __________________| + | | | +LL | | | +LL | | | items.sort(); +LL | | | }); + | | | -^ after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items + | | |_____|| + | |_______| + | called `Iterator::map` with callable that returns `()` + | + = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated +help: you might have meant to use `Iterator::for_each` + | +LL | x.iter_mut().for_each(|items| { + | ~~~~~~~~ + +error: `Iterator::map` call that discard the iterator's values + --> $DIR/lint_map_unit_fn.rs:18:18 + | +LL | let f = |items: &mut Vec<u8>| { + | --------------------- this function returns `()`, which is likely not what you wanted +... +LL | x.iter_mut().map(f); + | ^^^^-^ + | | | + | | called `Iterator::map` with callable that returns `()` + | after this call to map, the resulting iterator is `impl Iterator<Item = ()>`, which means the only information carried by the iterator is the number of items + | + = note: `Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated +help: you might have meant to use `Iterator::for_each` + | +LL | x.iter_mut().for_each(f); + | ~~~~~~~~ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/match/match-ref-mut-invariance.stderr b/tests/ui/match/match-ref-mut-invariance.stderr index 3b7e53cd527..b353d3514fe 100644 --- a/tests/ui/match/match-ref-mut-invariance.stderr +++ b/tests/ui/match/match-ref-mut-invariance.stderr @@ -6,7 +6,7 @@ LL | impl<'b> S<'b> { LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here LL | match self.0 { ref mut x => x } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to `&i32` diff --git a/tests/ui/match/match-ref-mut-let-invariance.stderr b/tests/ui/match/match-ref-mut-let-invariance.stderr index f4d1cea670b..bb0fcdb9990 100644 --- a/tests/ui/match/match-ref-mut-let-invariance.stderr +++ b/tests/ui/match/match-ref-mut-let-invariance.stderr @@ -7,7 +7,7 @@ LL | fn bar<'a>(&'a mut self) -> &'a mut &'a i32 { | -- lifetime `'a` defined here LL | let ref mut x = self.0; LL | x - | ^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | ^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` = note: requirement occurs because of a mutable reference to `&i32` diff --git a/tests/ui/methods/issues/issue-105732.stderr b/tests/ui/methods/issues/issue-105732.stderr index 7696642548d..19ccd2de685 100644 --- a/tests/ui/methods/issues/issue-105732.stderr +++ b/tests/ui/methods/issues/issue-105732.stderr @@ -2,7 +2,7 @@ error[E0380]: auto traits cannot have associated items --> $DIR/issue-105732.rs:4:8 | LL | auto trait Foo { - | --- auto trait cannot have associated items + | --- auto traits cannot have associated items LL | fn g(&self); | ---^-------- help: remove these associated items diff --git a/tests/ui/methods/issues/issue-61525.stderr b/tests/ui/methods/issues/issue-61525.stderr index 32e269b7ad8..a8afdeb8401 100644 --- a/tests/ui/methods/issues/issue-61525.stderr +++ b/tests/ui/methods/issues/issue-61525.stderr @@ -27,7 +27,7 @@ LL | 1.query::<dyn ToString>("") | = note: expected trait object `dyn ToString` found reference `&'static str` -note: associated function defined here +note: method defined here --> $DIR/issue-61525.rs:2:8 | LL | fn query<Q>(self, q: Q); diff --git a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr index 4b2597eed3c..5132d92777b 100644 --- a/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr +++ b/tests/ui/methods/method-ambig-two-traits-cross-crate.stderr @@ -10,11 +10,11 @@ note: candidate #2 is defined in an impl of the trait `Me2` for the type `usize` | LL | impl Me2 for usize { fn me(&self) -> usize { *self } } | ^^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | fn main() { Me::me(&1_usize); } | ~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | fn main() { Me2::me(&1_usize); } | ~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr b/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr index 1feaa2c73e0..601e6bbb006 100644 --- a/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr +++ b/tests/ui/methods/method-ambig-two-traits-from-bounds.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B` | LL | trait B { fn foo(&self); } | ^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | A::foo(t); | ~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | B::foo(t); | ~~~~~~~~~ diff --git a/tests/ui/methods/method-ambig-two-traits-from-impls.stderr b/tests/ui/methods/method-ambig-two-traits-from-impls.stderr index f69b5689239..31359143391 100644 --- a/tests/ui/methods/method-ambig-two-traits-from-impls.stderr +++ b/tests/ui/methods/method-ambig-two-traits-from-impls.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `AB` | LL | fn foo(self) {} | ^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | A::foo(AB {}); | ~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | B::foo(AB {}); | ~~~~~~~~~~~~~ diff --git a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr index e84dff8bab7..df01966b3a2 100644 --- a/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr +++ b/tests/ui/methods/method-ambig-two-traits-with-default-method.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `Bar` for the type `usize` | LL | trait Bar { fn method(&self) {} } | ^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | Foo::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | Bar::method(&1_usize); | ~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr index 0f37e8f09a9..c340c2d32b3 100644 --- a/tests/ui/methods/method-call-err-msg.stderr +++ b/tests/ui/methods/method-call-err-msg.stderr @@ -7,7 +7,7 @@ LL | x.zero(0) | unexpected argument of type `{integer}` | help: remove the extra argument | -note: associated function defined here +note: method defined here --> $DIR/method-call-err-msg.rs:5:8 | LL | fn zero(self) -> Foo { self } @@ -19,7 +19,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied LL | .one() | ^^^-- an argument of type `isize` is missing | -note: associated function defined here +note: method defined here --> $DIR/method-call-err-msg.rs:6:8 | LL | fn one(self, _: isize) -> Foo { self } @@ -35,7 +35,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied LL | .two(0); | ^^^--- an argument of type `isize` is missing | -note: associated function defined here +note: method defined here --> $DIR/method-call-err-msg.rs:7:8 | LL | fn two(self, _: isize, _: isize) -> Foo { self } @@ -72,7 +72,7 @@ error[E0061]: this method takes 3 arguments but 0 arguments were supplied LL | y.three::<usize>(); | ^^^^^^^^^^^^^^-- three arguments of type `usize`, `usize`, and `usize` are missing | -note: associated function defined here +note: method defined here --> $DIR/method-call-err-msg.rs:8:8 | LL | fn three<T>(self, _: T, _: T, _: T) -> Foo { self } diff --git a/tests/ui/methods/method-call-lifetime-args-fail.rs b/tests/ui/methods/method-call-lifetime-args-fail.rs index 6bf55844da8..1f13de094bb 100644 --- a/tests/ui/methods/method-call-lifetime-args-fail.rs +++ b/tests/ui/methods/method-call-lifetime-args-fail.rs @@ -14,9 +14,9 @@ impl S { fn method_call() { S.early(); // OK S.early::<'static>(); - //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument + //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument S.early::<'static, 'static, 'static>(); - //~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied + //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied let _: &u8 = S.life_and_type::<'static>(); S.life_and_type::<u8>(); S.life_and_type::<'static, u8>(); @@ -61,9 +61,9 @@ fn ufcs() { S::early(S); // OK S::early::<'static>(S); - //~^ ERROR this associated function takes 2 lifetime arguments but 1 lifetime argument + //~^ ERROR method takes 2 lifetime arguments but 1 lifetime argument S::early::<'static, 'static, 'static>(S); - //~^ ERROR this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied + //~^ ERROR method takes 2 lifetime arguments but 3 lifetime arguments were supplied let _: &u8 = S::life_and_type::<'static>(S); S::life_and_type::<u8>(S); S::life_and_type::<'static, u8>(S); diff --git a/tests/ui/methods/method-call-lifetime-args-fail.stderr b/tests/ui/methods/method-call-lifetime-args-fail.stderr index 249b48ab194..34526256f99 100644 --- a/tests/ui/methods/method-call-lifetime-args-fail.stderr +++ b/tests/ui/methods/method-call-lifetime-args-fail.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/method-call-lifetime-args-fail.rs:16:7 | LL | S.early::<'static>(); @@ -6,7 +6,7 @@ LL | S.early::<'static>(); | | | expected 2 lifetime arguments | -note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` +note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } @@ -16,7 +16,7 @@ help: add missing lifetime argument LL | S.early::<'static, 'static>(); | +++++++++ -error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied +error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied --> $DIR/method-call-lifetime-args-fail.rs:18:7 | LL | S.early::<'static, 'static, 'static>(); @@ -24,7 +24,7 @@ LL | S.early::<'static, 'static, 'static>(); | | | expected 2 lifetime arguments | -note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` +note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } @@ -198,7 +198,7 @@ note: the late bound lifetime parameter is introduced here LL | fn late_unused_early<'a, 'b>(self) -> &'b u8 { loop {} } | ^^ -error[E0107]: this associated function takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: method takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/method-call-lifetime-args-fail.rs:63:8 | LL | S::early::<'static>(S); @@ -206,7 +206,7 @@ LL | S::early::<'static>(S); | | | expected 2 lifetime arguments | -note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` +note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } @@ -216,7 +216,7 @@ help: add missing lifetime argument LL | S::early::<'static, 'static>(S); | +++++++++ -error[E0107]: this associated function takes 2 lifetime arguments but 3 lifetime arguments were supplied +error[E0107]: method takes 2 lifetime arguments but 3 lifetime arguments were supplied --> $DIR/method-call-lifetime-args-fail.rs:65:8 | LL | S::early::<'static, 'static, 'static>(S); @@ -224,7 +224,7 @@ LL | S::early::<'static, 'static, 'static>(S); | | | expected 2 lifetime arguments | -note: associated function defined here, with 2 lifetime parameters: `'a`, `'b` +note: method defined here, with 2 lifetime parameters: `'a`, `'b` --> $DIR/method-call-lifetime-args-fail.rs:6:8 | LL | fn early<'a, 'b>(self) -> (&'a u8, &'b u8) { loop {} } diff --git a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr index 82addab9479..4e83e4b77f1 100644 --- a/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr +++ b/tests/ui/methods/method-deref-to-same-trait-object-with-separate-params.stderr @@ -44,15 +44,15 @@ note: candidate #3 is defined in the trait `FinalFoo` | LL | fn foo(&self) -> u8; | ^^^^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | let z = X::foo(x); | ~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | let z = NuisanceFoo::foo(x); | ~~~~~~~~~~~~~~~~~~~ -help: disambiguate the associated function for candidate #3 +help: disambiguate the method for candidate #3 | LL | let z = FinalFoo::foo(x); | ~~~~~~~~~~~~~~~~ diff --git a/tests/ui/methods/method-self-arg-1.stderr b/tests/ui/methods/method-self-arg-1.stderr index 32ab8dced21..9241a8be58f 100644 --- a/tests/ui/methods/method-self-arg-1.stderr +++ b/tests/ui/methods/method-self-arg-1.stderr @@ -8,7 +8,7 @@ LL | Foo::bar(x); | | help: consider borrowing here: `&x` | arguments to this function are incorrect | -note: associated function defined here +note: method defined here --> $DIR/method-self-arg-1.rs:6:8 | LL | fn bar(&self) {} @@ -24,7 +24,7 @@ LL | Foo::bar(&42); | = note: expected reference `&Foo` found reference `&{integer}` -note: associated function defined here +note: method defined here --> $DIR/method-self-arg-1.rs:6:8 | LL | fn bar(&self) {} diff --git a/tests/ui/mismatched_types/issue-47706.stderr b/tests/ui/mismatched_types/issue-47706.stderr index d9d408844d0..69d6ee5cbd5 100644 --- a/tests/ui/mismatched_types/issue-47706.stderr +++ b/tests/ui/mismatched_types/issue-47706.stderr @@ -27,7 +27,7 @@ note: required by a bound in `foo` --> $DIR/issue-47706.rs:22:8 | LL | fn foo<F>(f: F) - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | F: Fn(), | ^^^^ required by this bound in `foo` diff --git a/tests/ui/nll/outlives-suggestion-simple.stderr b/tests/ui/nll/outlives-suggestion-simple.stderr index a8368c494ed..bcffd575aed 100644 --- a/tests/ui/nll/outlives-suggestion-simple.stderr +++ b/tests/ui/nll/outlives-suggestion-simple.stderr @@ -73,7 +73,7 @@ LL | impl<'a> Bar<'a> { LL | pub fn get<'b>(&self) -> &'b usize { | -- lifetime `'b` defined here LL | self.x - | ^^^^^^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | ^^^^^^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` @@ -85,7 +85,7 @@ LL | impl<'a> Baz<'a> { LL | fn get<'b>(&'b self) -> &'a i32 { | -- lifetime `'b` defined here LL | self.x - | ^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | ^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr index f05b0cd6538..40429fe756f 100644 --- a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr +++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr @@ -1,5 +1,10 @@ error[E0311]: the parameter type `Self` may not live long enough | +note: the parameter type `Self` must be valid for the lifetime `'a` as defined here... + --> $DIR/object-safety-supertrait-mentions-GAT.rs:9:26 + | +LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> { + | ^^ = help: consider adding an explicit lifetime bound `Self: 'a`... = note: ...so that the type `Self` will meet its required lifetime bounds... note: ...that is required by this bound diff --git a/tests/ui/privacy/privacy1.rs b/tests/ui/privacy/privacy1.rs index 3c9fa983dfd..fcb2108ab5f 100644 --- a/tests/ui/privacy/privacy1.rs +++ b/tests/ui/privacy/privacy1.rs @@ -106,7 +106,7 @@ mod foo { //~^ ERROR: associated function `bar` is private ::bar::baz::A.foo2(); //~ ERROR: module `baz` is private ::bar::baz::A.bar2(); //~ ERROR: module `baz` is private - //~^ ERROR: associated function `bar2` is private + //~^ ERROR: method `bar2` is private let _: isize = ::bar::B::foo(); //~ ERROR: trait `B` is private diff --git a/tests/ui/privacy/privacy1.stderr b/tests/ui/privacy/privacy1.stderr index 70e6fcb7a07..6ebed8ee062 100644 --- a/tests/ui/privacy/privacy1.stderr +++ b/tests/ui/privacy/privacy1.stderr @@ -190,14 +190,14 @@ LL | fn bar() {} LL | ::bar::baz::A::bar(); | ^^^ private associated function -error[E0624]: associated function `bar2` is private +error[E0624]: method `bar2` is private --> $DIR/privacy1.rs:108:23 | LL | fn bar2(&self) {} - | -------------- private associated function defined here + | -------------- private method defined here ... LL | ::bar::baz::A.bar2(); - | ^^^^ private associated function + | ^^^^ private method error: aborting due to 18 previous errors diff --git a/tests/ui/privacy/private-impl-method.rs b/tests/ui/privacy/private-impl-method.rs index f7be6726c5e..b5587920f1c 100644 --- a/tests/ui/privacy/private-impl-method.rs +++ b/tests/ui/privacy/private-impl-method.rs @@ -17,5 +17,5 @@ fn f() { fn main() { let s = a::Foo { x: 1 }; s.bar(); - s.foo(); //~ ERROR associated function `foo` is private + s.foo(); //~ ERROR method `foo` is private } diff --git a/tests/ui/privacy/private-impl-method.stderr b/tests/ui/privacy/private-impl-method.stderr index bb54dce7e7e..18e4531d112 100644 --- a/tests/ui/privacy/private-impl-method.stderr +++ b/tests/ui/privacy/private-impl-method.stderr @@ -1,11 +1,11 @@ -error[E0624]: associated function `foo` is private +error[E0624]: method `foo` is private --> $DIR/private-impl-method.rs:20:7 | LL | fn foo(&self) {} - | ------------- private associated function defined here + | ------------- private method defined here ... LL | s.foo(); - | ^^^ private associated function + | ^^^ private method error: aborting due to previous error diff --git a/tests/ui/privacy/private-method-cross-crate.rs b/tests/ui/privacy/private-method-cross-crate.rs index ab3bbdfe496..4da44e0682b 100644 --- a/tests/ui/privacy/private-method-cross-crate.rs +++ b/tests/ui/privacy/private-method-cross-crate.rs @@ -4,5 +4,5 @@ use cci_class_5::kitties::cat; fn main() { let nyan : cat = cat(52, 99); - nyan.nap(); //~ ERROR associated function `nap` is private + nyan.nap(); //~ ERROR method `nap` is private } diff --git a/tests/ui/privacy/private-method-cross-crate.stderr b/tests/ui/privacy/private-method-cross-crate.stderr index 93f6a7f2f61..e644440c827 100644 --- a/tests/ui/privacy/private-method-cross-crate.stderr +++ b/tests/ui/privacy/private-method-cross-crate.stderr @@ -1,13 +1,13 @@ -error[E0624]: associated function `nap` is private +error[E0624]: method `nap` is private --> $DIR/private-method-cross-crate.rs:7:8 | LL | nyan.nap(); - | ^^^ private associated function + | ^^^ private method | ::: $DIR/auxiliary/cci_class_5.rs:8:9 | LL | fn nap(&self) {} - | ------------- private associated function defined here + | ------------- private method defined here error: aborting due to previous error diff --git a/tests/ui/privacy/private-method-inherited.rs b/tests/ui/privacy/private-method-inherited.rs index 2f6454288ae..bc27027e886 100644 --- a/tests/ui/privacy/private-method-inherited.rs +++ b/tests/ui/privacy/private-method-inherited.rs @@ -10,5 +10,5 @@ mod a { fn main() { let x = a::Foo; - x.f(); //~ ERROR associated function `f` is private + x.f(); //~ ERROR method `f` is private } diff --git a/tests/ui/privacy/private-method-inherited.stderr b/tests/ui/privacy/private-method-inherited.stderr index 011a7fee478..0104a1b27e4 100644 --- a/tests/ui/privacy/private-method-inherited.stderr +++ b/tests/ui/privacy/private-method-inherited.stderr @@ -1,11 +1,11 @@ -error[E0624]: associated function `f` is private +error[E0624]: method `f` is private --> $DIR/private-method-inherited.rs:13:7 | LL | fn f(self) {} - | ---------- private associated function defined here + | ---------- private method defined here ... LL | x.f(); - | ^ private associated function + | ^ private method error: aborting due to previous error diff --git a/tests/ui/privacy/private-method.rs b/tests/ui/privacy/private-method.rs index 76a642cde1a..a9bea520e75 100644 --- a/tests/ui/privacy/private-method.rs +++ b/tests/ui/privacy/private-method.rs @@ -19,5 +19,5 @@ mod kitties { fn main() { let nyan : kitties::Cat = kitties::cat(52, 99); - nyan.nap(); //~ ERROR associated function `nap` is private + nyan.nap(); //~ ERROR method `nap` is private } diff --git a/tests/ui/privacy/private-method.stderr b/tests/ui/privacy/private-method.stderr index 17c7179dc36..42fec762265 100644 --- a/tests/ui/privacy/private-method.stderr +++ b/tests/ui/privacy/private-method.stderr @@ -1,11 +1,11 @@ -error[E0624]: associated function `nap` is private +error[E0624]: method `nap` is private --> $DIR/private-method.rs:22:8 | LL | fn nap(&self) {} - | ------------- private associated function defined here + | ------------- private method defined here ... LL | nyan.nap(); - | ^^^ private associated function + | ^^^ private method error: aborting due to previous error diff --git a/tests/ui/privacy/restricted/test.stderr b/tests/ui/privacy/restricted/test.stderr index 1acd221b42c..76f19525df5 100644 --- a/tests/ui/privacy/restricted/test.stderr +++ b/tests/ui/privacy/restricted/test.stderr @@ -54,14 +54,14 @@ error[E0616]: field `x` of struct `S` is private LL | S::default().x; | ^ private field -error[E0624]: associated function `f` is private +error[E0624]: method `f` is private --> $DIR/test.rs:32:18 | LL | pub(super) fn f(&self) {} - | ---------------------- private associated function defined here + | ---------------------- private method defined here ... LL | S::default().f(); - | ^ private associated function + | ^ private method error[E0624]: associated function `g` is private --> $DIR/test.rs:33:8 @@ -84,27 +84,27 @@ error[E0616]: field `z` of struct `Universe` is private LL | let _ = u.z; | ^ private field -error[E0624]: associated function `g` is private +error[E0624]: method `g` is private --> $DIR/test.rs:45:7 | LL | u.g(); - | ^ private associated function + | ^ private method | ::: $DIR/auxiliary/pub_restricted.rs:12:5 | LL | pub(crate) fn g(&self) {} - | ---------------------- private associated function defined here + | ---------------------- private method defined here -error[E0624]: associated function `h` is private +error[E0624]: method `h` is private --> $DIR/test.rs:46:7 | LL | u.h(); - | ^ private associated function + | ^ private method | ::: $DIR/auxiliary/pub_restricted.rs:13:5 | LL | pub(crate) fn h(&self) {} - | ---------------------- private associated function defined here + | ---------------------- private method defined here error: aborting due to 12 previous errors diff --git a/tests/ui/recursion_limit/issue_21102.rs b/tests/ui/recursion_limit/issue-105700.rs index e1fee46313d..e1fee46313d 100644 --- a/tests/ui/recursion_limit/issue_21102.rs +++ b/tests/ui/recursion_limit/issue-105700.rs diff --git a/tests/ui/recursion_limit/issue_21102.stderr b/tests/ui/recursion_limit/issue-105700.stderr index 1bd722c492b..9b1114e9ce6 100644 --- a/tests/ui/recursion_limit/issue_21102.stderr +++ b/tests/ui/recursion_limit/issue-105700.stderr @@ -1,10 +1,10 @@ error: recursion limit reached while expanding `#[invalid_attribute]` - --> $DIR/issue_21102.rs:6:1 + --> $DIR/issue-105700.rs:6:1 | LL | #![invalid_attribute] | ^^^^^^^^^^^^^^^^^^^^^ | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`issue_21102`) + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "8"]` attribute to your crate (`issue_105700`) error: aborting due to previous error diff --git a/tests/ui/regions/regions-early-bound-error-method.stderr b/tests/ui/regions/regions-early-bound-error-method.stderr index 7f10c051f29..a7746d8981e 100644 --- a/tests/ui/regions/regions-early-bound-error-method.stderr +++ b/tests/ui/regions/regions-early-bound-error-method.stderr @@ -6,7 +6,7 @@ LL | impl<'a> Box<'a> { LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { | -- lifetime `'b` defined here LL | g2.get() - | ^^^^^^^^ associated function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` + | ^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` | = help: consider adding the following bound: `'b: 'a` diff --git a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr index f7c75033c04..d0ceaec3b67 100644 --- a/tests/ui/regions/regions-free-region-ordering-incorrect.stderr +++ b/tests/ui/regions/regions-free-region-ordering-incorrect.stderr @@ -9,7 +9,7 @@ LL | / match self.next { LL | | Some(ref next) => next.get(), LL | | None => &self.val LL | | } - | |_________^ associated function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` + | |_________^ method was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` | = help: consider adding the following bound: `'a: 'b` diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs index 7c2e1aeeea6..46462c432a8 100644 --- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs +++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs @@ -8,6 +8,8 @@ // // 'a : 'b +#![warn(unused_lifetimes)] + fn test<'a,'b>(x: &'a i32) -> &'b i32 where 'a: 'static //~ WARN unnecessary lifetime parameter `'a` { diff --git a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr index 70ed418d5cb..9f03a6553ba 100644 --- a/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr +++ b/tests/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr @@ -1,10 +1,15 @@ warning: unnecessary lifetime parameter `'a` - --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:12:11 + --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:14:11 | LL | where 'a: 'static | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` +note: the lint level is defined here + --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:11:9 + | +LL | #![warn(unused_lifetimes)] + | ^^^^^^^^^^^^^^^^ warning: 1 warning emitted diff --git a/tests/ui/regions/regions-static-bound-rpass.rs b/tests/ui/regions/regions-static-bound-rpass.rs index 25232b455b6..e2ebb394d0a 100644 --- a/tests/ui/regions/regions-static-bound-rpass.rs +++ b/tests/ui/regions/regions-static-bound-rpass.rs @@ -1,5 +1,7 @@ // run-pass +#![warn(unused_lifetimes)] + fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a () where 'a: 'static { t } //~^ WARN unnecessary lifetime parameter `'a` diff --git a/tests/ui/regions/regions-static-bound-rpass.stderr b/tests/ui/regions/regions-static-bound-rpass.stderr index 9355a409d50..f0f3a4c5261 100644 --- a/tests/ui/regions/regions-static-bound-rpass.stderr +++ b/tests/ui/regions/regions-static-bound-rpass.stderr @@ -1,13 +1,18 @@ warning: unnecessary lifetime parameter `'a` - --> $DIR/regions-static-bound-rpass.rs:4:11 + --> $DIR/regions-static-bound-rpass.rs:6:11 | LL | where 'a: 'static { t } | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` +note: the lint level is defined here + --> $DIR/regions-static-bound-rpass.rs:3:9 + | +LL | #![warn(unused_lifetimes)] + | ^^^^^^^^^^^^^^^^ warning: unnecessary lifetime parameter `'a` - --> $DIR/regions-static-bound-rpass.rs:8:11 + --> $DIR/regions-static-bound-rpass.rs:10:11 | LL | where 'a: 'static { t } | ^^ @@ -15,7 +20,7 @@ LL | where 'a: 'static { t } = help: you can use the `'static` lifetime directly, in place of `'a` warning: unnecessary lifetime parameter `'b` - --> $DIR/regions-static-bound-rpass.rs:12:19 + --> $DIR/regions-static-bound-rpass.rs:14:19 | LL | where 'a: 'b, 'b: 'static { t } | ^^ diff --git a/tests/ui/regions/regions-static-bound.rs b/tests/ui/regions/regions-static-bound.rs index 4d2455470e2..e7aa8795f01 100644 --- a/tests/ui/regions/regions-static-bound.rs +++ b/tests/ui/regions/regions-static-bound.rs @@ -1,6 +1,8 @@ -fn static_id<'a,'b>(t: &'a ()) -> &'static () - where 'a: 'static { t } -//~^ WARN unnecessary lifetime parameter `'a` +#![warn(unused_lifetimes)] + +fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } +//~^ WARN lifetime parameter `'b` never used +//~| WARN unnecessary lifetime parameter `'a` fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } diff --git a/tests/ui/regions/regions-static-bound.stderr b/tests/ui/regions/regions-static-bound.stderr index 2886ec3ead5..b314e9fe85d 100644 --- a/tests/ui/regions/regions-static-bound.stderr +++ b/tests/ui/regions/regions-static-bound.stderr @@ -1,13 +1,27 @@ +warning: lifetime parameter `'b` never used + --> $DIR/regions-static-bound.rs:3:17 + | +LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } + | -^^ + | | + | help: elide the unused lifetime + | +note: the lint level is defined here + --> $DIR/regions-static-bound.rs:1:9 + | +LL | #![warn(unused_lifetimes)] + | ^^^^^^^^^^^^^^^^ + warning: unnecessary lifetime parameter `'a` - --> $DIR/regions-static-bound.rs:2:11 + --> $DIR/regions-static-bound.rs:3:53 | -LL | where 'a: 'static { t } - | ^^ +LL | fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } + | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` warning: unnecessary lifetime parameter `'b` - --> $DIR/regions-static-bound.rs:6:19 + --> $DIR/regions-static-bound.rs:8:19 | LL | where 'a: 'b, 'b: 'static { t } | ^^ @@ -15,7 +29,7 @@ LL | where 'a: 'b, 'b: 'static { t } = help: you can use the `'static` lifetime directly, in place of `'b` error: lifetime may not live long enough - --> $DIR/regions-static-bound.rs:10:5 + --> $DIR/regions-static-bound.rs:12:5 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { | -- lifetime `'a` defined here @@ -23,7 +37,7 @@ LL | t | ^ returning this value requires that `'a` must outlive `'static` error[E0521]: borrowed data escapes outside of function - --> $DIR/regions-static-bound.rs:15:5 + --> $DIR/regions-static-bound.rs:17:5 | LL | fn error(u: &(), v: &()) { | - - let's call the lifetime of this reference `'1` @@ -36,7 +50,7 @@ LL | static_id(&u); | argument requires that `'1` must outlive `'static` error[E0521]: borrowed data escapes outside of function - --> $DIR/regions-static-bound.rs:17:5 + --> $DIR/regions-static-bound.rs:19:5 | LL | fn error(u: &(), v: &()) { | - - let's call the lifetime of this reference `'2` @@ -49,6 +63,6 @@ LL | static_id_indirect(&v); | `v` escapes the function body here | argument requires that `'2` must outlive `'static` -error: aborting due to 3 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0521`. diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs new file mode 100644 index 00000000000..f37b27a82b3 --- /dev/null +++ b/tests/ui/regions/resolve-re-error-ice.rs @@ -0,0 +1,22 @@ +// check-pass + +// Allow this for now, can remove this UI test when this becomes a hard error. +#![allow(implied_bounds_entailment)] + +use std::collections::hash_map::{Keys, HashMap}; +use std::marker::PhantomData; + +trait MapAssertion<'a, K, V, R> { + fn key_set(&self) -> Subject<Keys<K, V>, (), R>; +} + +struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>); + +impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R> +{ + fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + todo!() + } +} + +fn main() {} diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr new file mode 100644 index 00000000000..e7003e1c32f --- /dev/null +++ b/tests/ui/regions/resolve-re-error-ice.stderr @@ -0,0 +1,15 @@ +Future incompatibility report: Future breakage diagnostic: +warning: impl method assumes more implied bounds than the corresponding trait method + --> $DIR/resolve-re-error-ice.rs:17:16 + | +LL | fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> { + | ^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>` + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572> +note: the lint level is defined here + --> $DIR/resolve-re-error-ice.rs:4:10 + | +LL | #![allow(implied_bounds_entailment)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/tests/ui/rfc-2091-track-caller/error-with-main.stderr b/tests/ui/rfc-2091-track-caller/error-with-main.stderr index 7e2ec352414..6d6562dae3b 100644 --- a/tests/ui/rfc-2091-track-caller/error-with-main.stderr +++ b/tests/ui/rfc-2091-track-caller/error-with-main.stderr @@ -2,7 +2,7 @@ error: `main` function is not allowed to be `#[track_caller]` --> $DIR/error-with-main.rs:1:1 | LL | #[track_caller] - | ^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ help: remove this annotation LL | fn main() { | --------- `main` function is not allowed to be `#[track_caller]` diff --git a/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr b/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr index dd0dac95e36..7639ae9f6a4 100644 --- a/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr +++ b/tests/ui/rfc-2457/mod_file_nonascii_forbidden.stderr @@ -12,7 +12,7 @@ error[E0754]: trying to load file for module `řųśť` with non-ascii identifie LL | mod řųśť; | ^^^^ | - = help: consider using `#[path]` attribute to specify filesystem path + = help: consider using the `#[path]` attribute to specify filesystem path error: aborting due to 2 previous errors diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs new file mode 100644 index 00000000000..730e268c091 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check-override.rs @@ -0,0 +1,19 @@ +// check-pass +#![feature(const_trait_impl, rustc_attrs)] + +#[const_trait] +trait Foo { + #[rustc_do_not_const_check] + fn into_iter(&self) { println!("FEAR ME!") } +} + + +impl const Foo for () { + fn into_iter(&self) { + // ^_^ + } +} + +const _: () = Foo::into_iter(&()); + +fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs new file mode 100644 index 00000000000..3c39c53de5f --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/do-not-const-check.rs @@ -0,0 +1,18 @@ +// check-pass +#![feature(const_trait_impl, rustc_attrs)] + +#[const_trait] +trait IntoIter { + fn into_iter(self); +} + +#[const_trait] +trait Hmm: Sized { + #[rustc_do_not_const_check] + fn chain<U>(self, other: U) where U: IntoIter, + { + other.into_iter() + } +} + +fn main() {} diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index 6180e1e0f2d..0b4c0a7fece 100644 --- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr +++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:52 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - - ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -16,7 +16,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:75 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - - ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -30,7 +30,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:64 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- - ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | -- - ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` | | | | | let's call the lifetime of this reference `'1` | lifetime `'a` defined here diff --git a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr index fccee5d4363..209dae9c1b3 100644 --- a/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr +++ b/tests/ui/self/arbitrary_self_types_pin_lifetime_mismatch.stderr @@ -2,7 +2,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:6:46 | LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } - | - - ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -16,7 +16,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:9:69 | LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } - | - - ^^^^^^^^^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | - - ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` @@ -30,7 +30,7 @@ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:15:58 | LL | fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } - | -- ---- has type `Pin<&'1 Foo>` ^^^ associated function was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` + | -- ---- has type `Pin<&'1 Foo>` ^^^ method was supposed to return data with lifetime `'1` but it is returning data with lifetime `'a` | | | lifetime `'a` defined here diff --git a/tests/ui/self/elision/lt-ref-self-async.stderr b/tests/ui/self/elision/lt-ref-self-async.stderr index 787afd4dc9d..29d60ed6635 100644 --- a/tests/ui/self/elision/lt-ref-self-async.stderr +++ b/tests/ui/self/elision/lt-ref-self-async.stderr @@ -6,7 +6,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/lt-ref-self.stderr b/tests/ui/self/elision/lt-ref-self.stderr index 49af638e4c6..216737a2c73 100644 --- a/tests/ui/self/elision/lt-ref-self.stderr +++ b/tests/ui/self/elision/lt-ref-self.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-mut-self-async.stderr b/tests/ui/self/elision/ref-mut-self-async.stderr index dff50aee918..62543ba5339 100644 --- a/tests/ui/self/elision/ref-mut-self-async.stderr +++ b/tests/ui/self/elision/ref-mut-self-async.stderr @@ -6,7 +6,7 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-mut-self.stderr b/tests/ui/self/elision/ref-mut-self.stderr index ccf1830167c..12b64a3f6dc 100644 --- a/tests/ui/self/elision/ref-mut-self.stderr +++ b/tests/ui/self/elision/ref-mut-self.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&mut self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-mut-struct-async.stderr b/tests/ui/self/elision/ref-mut-struct-async.stderr index 5b7ad026f9d..f8fb2e4a138 100644 --- a/tests/ui/self/elision/ref-mut-struct-async.stderr +++ b/tests/ui/self/elision/ref-mut-struct-async.stderr @@ -6,7 +6,7 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-mut-struct.stderr b/tests/ui/self/elision/ref-mut-struct.stderr index b9c71e8433c..cde16ce8ba4 100644 --- a/tests/ui/self/elision/ref-mut-struct.stderr +++ b/tests/ui/self/elision/ref-mut-struct.stderr @@ -6,7 +6,7 @@ LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-self-async.stderr b/tests/ui/self/elision/ref-self-async.stderr index 26ef9779be2..010d281b002 100644 --- a/tests/ui/self/elision/ref-self-async.stderr +++ b/tests/ui/self/elision/ref-self-async.stderr @@ -6,7 +6,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -96,7 +96,7 @@ LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-self.stderr b/tests/ui/self/elision/ref-self.stderr index 32448f3a677..35693257c99 100644 --- a/tests/ui/self/elision/ref-self.stderr +++ b/tests/ui/self/elision/ref-self.stderr @@ -6,7 +6,7 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -81,7 +81,7 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -96,7 +96,7 @@ LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-struct-async.stderr b/tests/ui/self/elision/ref-struct-async.stderr index edb5c54ab00..c9376d58f90 100644 --- a/tests/ui/self/elision/ref-struct-async.stderr +++ b/tests/ui/self/elision/ref-struct-async.stderr @@ -6,7 +6,7 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/self/elision/ref-struct.stderr b/tests/ui/self/elision/ref-struct.stderr index 4492ed4aafc..a3d3cebeba9 100644 --- a/tests/ui/self/elision/ref-struct.stderr +++ b/tests/ui/self/elision/ref-struct.stderr @@ -6,7 +6,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -21,7 +21,7 @@ LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -36,7 +36,7 @@ LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -51,7 +51,7 @@ LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | @@ -66,7 +66,7 @@ LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | | | let's call the lifetime of this reference `'2` LL | f - | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | ^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` | help: consider introducing a named lifetime parameter and update trait if needed | diff --git a/tests/ui/seq-args.rs b/tests/ui/seq-args.rs index a5ebeecd311..627dfcc3198 100644 --- a/tests/ui/seq-args.rs +++ b/tests/ui/seq-args.rs @@ -2,12 +2,12 @@ fn main() { trait Seq { } impl<T> Seq<T> for Vec<T> { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument /* ... */ } impl Seq<bool> for u32 { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument /* Treat the integer as a sequence of bits */ } } diff --git a/tests/ui/seq-args.stderr b/tests/ui/seq-args.stderr index c404d95748b..a5b0f8e98dc 100644 --- a/tests/ui/seq-args.stderr +++ b/tests/ui/seq-args.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/seq-args.rs:4:13 | LL | impl<T> Seq<T> for Vec<T> { @@ -12,7 +12,7 @@ note: trait defined here, with 0 generic parameters LL | trait Seq { } | ^^^ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/seq-args.rs:9:10 | LL | impl Seq<bool> for u32 { diff --git a/tests/ui/span/issue-37767.stderr b/tests/ui/span/issue-37767.stderr index f7732847a28..b612fdf16fc 100644 --- a/tests/ui/span/issue-37767.stderr +++ b/tests/ui/span/issue-37767.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in the trait `B` | LL | fn foo(&mut self) {} | ^^^^^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | A::foo(&a) | ~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | B::foo(&a) | ~~~~~~~~~~ @@ -39,11 +39,11 @@ note: candidate #2 is defined in the trait `D` | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | C::foo(&a) | ~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | D::foo(&a) | ~~~~~~~~~~ @@ -64,11 +64,11 @@ note: candidate #2 is defined in the trait `F` | LL | fn foo(self) {} | ^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | E::foo(a) | ~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | F::foo(a) | ~~~~~~~~~ diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr index 2b178990850..e01e1edab5a 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.full.stderr @@ -15,7 +15,7 @@ error[E0282]: type annotations needed --> $DIR/issue-42234-unknown-receiver-type.rs:15:10 | LL | .sum::<_>() - | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | help: consider specifying the generic argument | diff --git a/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr b/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr index d93d54e878b..a4b65256574 100644 --- a/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr +++ b/tests/ui/span/issue-42234-unknown-receiver-type.generic_arg.stderr @@ -15,7 +15,7 @@ error[E0282]: type annotations needed --> $DIR/issue-42234-unknown-receiver-type.rs:15:10 | LL | .sum::<_>() - | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | help: consider specifying the generic argument | diff --git a/tests/ui/span/missing-unit-argument.stderr b/tests/ui/span/missing-unit-argument.stderr index ef4d732b51d..ff89f775334 100644 --- a/tests/ui/span/missing-unit-argument.stderr +++ b/tests/ui/span/missing-unit-argument.stderr @@ -65,7 +65,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied LL | S.baz(); | ^^^-- an argument of type `()` is missing | -note: associated function defined here +note: method defined here --> $DIR/missing-unit-argument.rs:6:8 | LL | fn baz(self, (): ()) { } @@ -81,7 +81,7 @@ error[E0061]: this method takes 1 argument but 0 arguments were supplied LL | S.generic::<()>(); | ^^^^^^^^^^^^^-- an argument of type `()` is missing | -note: associated function defined here +note: method defined here --> $DIR/missing-unit-argument.rs:7:8 | LL | fn generic<T>(self, _: T) { } diff --git a/tests/ui/span/type-annotations-needed-expr.stderr b/tests/ui/span/type-annotations-needed-expr.stderr index 9dff6c64db4..65a90318a3c 100644 --- a/tests/ui/span/type-annotations-needed-expr.stderr +++ b/tests/ui/span/type-annotations-needed-expr.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/type-annotations-needed-expr.rs:2:39 | LL | let _ = (vec![1,2,3]).into_iter().sum() as f64; - | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | help: consider specifying the generic argument | diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.rs b/tests/ui/stability-attribute/unresolved_stability_lint.rs new file mode 100644 index 00000000000..818d228bc91 --- /dev/null +++ b/tests/ui/stability-attribute/unresolved_stability_lint.rs @@ -0,0 +1,8 @@ +#![feature(staged_api)] +#![stable(feature = "uwu", since = "1.0.0")] + +#[unstable(feature = "foo", issue = "none")] +impl Foo for () {} +//~^ ERROR cannot find trait `Foo` in this scope + +fn main() {} diff --git a/tests/ui/stability-attribute/unresolved_stability_lint.stderr b/tests/ui/stability-attribute/unresolved_stability_lint.stderr new file mode 100644 index 00000000000..11d6abcaf36 --- /dev/null +++ b/tests/ui/stability-attribute/unresolved_stability_lint.stderr @@ -0,0 +1,9 @@ +error[E0405]: cannot find trait `Foo` in this scope + --> $DIR/unresolved_stability_lint.rs:5:6 + | +LL | impl Foo for () {} + | ^^^ not found in this scope + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0405`. diff --git a/tests/ui/static/static-lifetime-bound.rs b/tests/ui/static/static-lifetime-bound.rs index b5da91ec3b6..847fe87b2ea 100644 --- a/tests/ui/static/static-lifetime-bound.rs +++ b/tests/ui/static/static-lifetime-bound.rs @@ -1,4 +1,4 @@ -fn f<'a: 'static>(_: &'a i32) {} //~WARN unnecessary lifetime parameter `'a` +fn f<'a: 'static>(_: &'a i32) {} fn main() { let x = 0; diff --git a/tests/ui/static/static-lifetime-bound.stderr b/tests/ui/static/static-lifetime-bound.stderr index e22411b13b7..19e55a6582e 100644 --- a/tests/ui/static/static-lifetime-bound.stderr +++ b/tests/ui/static/static-lifetime-bound.stderr @@ -1,11 +1,3 @@ -warning: unnecessary lifetime parameter `'a` - --> $DIR/static-lifetime-bound.rs:1:6 - | -LL | fn f<'a: 'static>(_: &'a i32) {} - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - error[E0597]: `x` does not live long enough --> $DIR/static-lifetime-bound.rs:5:7 | @@ -19,6 +11,6 @@ LL | f(&x); LL | } | - `x` dropped here while still borrowed -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0597`. diff --git a/tests/ui/statics/uninhabited-static.stderr b/tests/ui/statics/uninhabited-static.stderr index ef794bb36ac..437053a4476 100644 --- a/tests/ui/statics/uninhabited-static.stderr +++ b/tests/ui/statics/uninhabited-static.stderr @@ -53,10 +53,7 @@ warning: the type `Void` does not permit zero-initialization --> $DIR/uninhabited-static.rs:12:31 | LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/uninhabited-static.rs:4:1 @@ -75,10 +72,7 @@ warning: the type `Void` does not permit zero-initialization --> $DIR/uninhabited-static.rs:16:32 | LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done + | ^^^^^^^^^^^^^^^^^^^^^^^ this code causes undefined behavior when executed | note: enums with no inhabited variants have no valid value --> $DIR/uninhabited-static.rs:4:1 diff --git a/tests/ui/stats/hir-stats.stderr b/tests/ui/stats/hir-stats.stderr index 7d9ff2dfb4d..ee62d8f2d25 100644 --- a/tests/ui/stats/hir-stats.stderr +++ b/tests/ui/stats/hir-stats.stderr @@ -1,119 +1,119 @@ ast-stats-1 PRE EXPANSION AST STATS ast-stats-1 Name Accumulated Size Count Item Size ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 ExprField 48 ( 0.6%) 1 48 -ast-stats-1 GenericArgs 56 ( 0.8%) 1 56 -ast-stats-1 - AngleBracketed 56 ( 0.8%) 1 -ast-stats-1 Crate 56 ( 0.8%) 1 56 -ast-stats-1 Attribute 64 ( 0.9%) 2 32 -ast-stats-1 - Normal 32 ( 0.4%) 1 -ast-stats-1 - DocComment 32 ( 0.4%) 1 -ast-stats-1 Local 72 ( 1.0%) 1 72 -ast-stats-1 WherePredicate 72 ( 1.0%) 1 72 -ast-stats-1 - BoundPredicate 72 ( 1.0%) 1 -ast-stats-1 Arm 96 ( 1.3%) 2 48 -ast-stats-1 ForeignItem 96 ( 1.3%) 1 96 -ast-stats-1 - Fn 96 ( 1.3%) 1 -ast-stats-1 FieldDef 160 ( 2.2%) 2 80 -ast-stats-1 Stmt 160 ( 2.2%) 5 32 -ast-stats-1 - Local 32 ( 0.4%) 1 -ast-stats-1 - MacCall 32 ( 0.4%) 1 -ast-stats-1 - Expr 96 ( 1.3%) 3 -ast-stats-1 Param 160 ( 2.2%) 4 40 -ast-stats-1 FnDecl 200 ( 2.7%) 5 40 -ast-stats-1 Variant 240 ( 3.2%) 2 120 -ast-stats-1 GenericBound 288 ( 3.9%) 4 72 -ast-stats-1 - Trait 288 ( 3.9%) 4 -ast-stats-1 Block 288 ( 3.9%) 6 48 -ast-stats-1 AssocItem 416 ( 5.6%) 4 104 -ast-stats-1 - Type 208 ( 2.8%) 2 -ast-stats-1 - Fn 208 ( 2.8%) 2 -ast-stats-1 GenericParam 480 ( 6.5%) 5 96 -ast-stats-1 Expr 576 ( 7.8%) 8 72 -ast-stats-1 - Path 72 ( 1.0%) 1 -ast-stats-1 - Match 72 ( 1.0%) 1 -ast-stats-1 - Struct 72 ( 1.0%) 1 -ast-stats-1 - Lit 144 ( 1.9%) 2 -ast-stats-1 - Block 216 ( 2.9%) 3 -ast-stats-1 Pat 616 ( 8.3%) 7 88 -ast-stats-1 - Struct 88 ( 1.2%) 1 -ast-stats-1 - Wild 88 ( 1.2%) 1 -ast-stats-1 - Ident 440 ( 5.9%) 5 -ast-stats-1 PathSegment 720 ( 9.7%) 30 24 -ast-stats-1 Ty 896 (12.1%) 14 64 -ast-stats-1 - Ptr 64 ( 0.9%) 1 -ast-stats-1 - Ref 64 ( 0.9%) 1 -ast-stats-1 - ImplicitSelf 128 ( 1.7%) 2 -ast-stats-1 - Path 640 ( 8.6%) 10 -ast-stats-1 Item 1_656 (22.3%) 9 184 -ast-stats-1 - Trait 184 ( 2.5%) 1 -ast-stats-1 - Enum 184 ( 2.5%) 1 -ast-stats-1 - ForeignMod 184 ( 2.5%) 1 -ast-stats-1 - Impl 184 ( 2.5%) 1 -ast-stats-1 - Fn 368 ( 5.0%) 2 -ast-stats-1 - Use 552 ( 7.4%) 3 +ast-stats-1 GenericArgs 40 ( 0.6%) 1 40 +ast-stats-1 - AngleBracketed 40 ( 0.6%) 1 +ast-stats-1 Crate 40 ( 0.6%) 1 40 +ast-stats-1 ExprField 48 ( 0.7%) 1 48 +ast-stats-1 WherePredicate 56 ( 0.9%) 1 56 +ast-stats-1 - BoundPredicate 56 ( 0.9%) 1 +ast-stats-1 Attribute 64 ( 1.0%) 2 32 +ast-stats-1 - Normal 32 ( 0.5%) 1 +ast-stats-1 - DocComment 32 ( 0.5%) 1 +ast-stats-1 Local 72 ( 1.1%) 1 72 +ast-stats-1 Arm 96 ( 1.5%) 2 48 +ast-stats-1 ForeignItem 96 ( 1.5%) 1 96 +ast-stats-1 - Fn 96 ( 1.5%) 1 +ast-stats-1 FnDecl 120 ( 1.8%) 5 24 +ast-stats-1 FieldDef 160 ( 2.4%) 2 80 +ast-stats-1 Stmt 160 ( 2.4%) 5 32 +ast-stats-1 - Local 32 ( 0.5%) 1 +ast-stats-1 - MacCall 32 ( 0.5%) 1 +ast-stats-1 - Expr 96 ( 1.5%) 3 +ast-stats-1 Param 160 ( 2.4%) 4 40 +ast-stats-1 Block 192 ( 2.9%) 6 32 +ast-stats-1 Variant 208 ( 3.2%) 2 104 +ast-stats-1 GenericBound 224 ( 3.4%) 4 56 +ast-stats-1 - Trait 224 ( 3.4%) 4 +ast-stats-1 AssocItem 416 ( 6.3%) 4 104 +ast-stats-1 - Type 208 ( 3.2%) 2 +ast-stats-1 - Fn 208 ( 3.2%) 2 +ast-stats-1 GenericParam 480 ( 7.3%) 5 96 +ast-stats-1 Pat 504 ( 7.7%) 7 72 +ast-stats-1 - Struct 72 ( 1.1%) 1 +ast-stats-1 - Wild 72 ( 1.1%) 1 +ast-stats-1 - Ident 360 ( 5.5%) 5 +ast-stats-1 Expr 576 ( 8.8%) 8 72 +ast-stats-1 - Path 72 ( 1.1%) 1 +ast-stats-1 - Match 72 ( 1.1%) 1 +ast-stats-1 - Struct 72 ( 1.1%) 1 +ast-stats-1 - Lit 144 ( 2.2%) 2 +ast-stats-1 - Block 216 ( 3.3%) 3 +ast-stats-1 PathSegment 720 (11.0%) 30 24 +ast-stats-1 Ty 896 (13.7%) 14 64 +ast-stats-1 - Ptr 64 ( 1.0%) 1 +ast-stats-1 - Ref 64 ( 1.0%) 1 +ast-stats-1 - ImplicitSelf 128 ( 2.0%) 2 +ast-stats-1 - Path 640 ( 9.8%) 10 +ast-stats-1 Item 1_224 (18.7%) 9 136 +ast-stats-1 - Trait 136 ( 2.1%) 1 +ast-stats-1 - Enum 136 ( 2.1%) 1 +ast-stats-1 - ForeignMod 136 ( 2.1%) 1 +ast-stats-1 - Impl 136 ( 2.1%) 1 +ast-stats-1 - Fn 272 ( 4.2%) 2 +ast-stats-1 - Use 408 ( 6.2%) 3 ast-stats-1 ---------------------------------------------------------------- -ast-stats-1 Total 7_416 +ast-stats-1 Total 6_552 ast-stats-1 ast-stats-2 POST EXPANSION AST STATS ast-stats-2 Name Accumulated Size Count Item Size ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 ExprField 48 ( 0.6%) 1 48 -ast-stats-2 GenericArgs 56 ( 0.7%) 1 56 -ast-stats-2 - AngleBracketed 56 ( 0.7%) 1 -ast-stats-2 Crate 56 ( 0.7%) 1 56 -ast-stats-2 Local 72 ( 0.9%) 1 72 -ast-stats-2 WherePredicate 72 ( 0.9%) 1 72 -ast-stats-2 - BoundPredicate 72 ( 0.9%) 1 -ast-stats-2 Arm 96 ( 1.2%) 2 48 -ast-stats-2 ForeignItem 96 ( 1.2%) 1 96 -ast-stats-2 - Fn 96 ( 1.2%) 1 -ast-stats-2 InlineAsm 120 ( 1.5%) 1 120 -ast-stats-2 Attribute 128 ( 1.6%) 4 32 +ast-stats-2 GenericArgs 40 ( 0.6%) 1 40 +ast-stats-2 - AngleBracketed 40 ( 0.6%) 1 +ast-stats-2 Crate 40 ( 0.6%) 1 40 +ast-stats-2 ExprField 48 ( 0.7%) 1 48 +ast-stats-2 WherePredicate 56 ( 0.8%) 1 56 +ast-stats-2 - BoundPredicate 56 ( 0.8%) 1 +ast-stats-2 Local 72 ( 1.0%) 1 72 +ast-stats-2 Arm 96 ( 1.3%) 2 48 +ast-stats-2 ForeignItem 96 ( 1.3%) 1 96 +ast-stats-2 - Fn 96 ( 1.3%) 1 +ast-stats-2 InlineAsm 120 ( 1.7%) 1 120 +ast-stats-2 FnDecl 120 ( 1.7%) 5 24 +ast-stats-2 Attribute 128 ( 1.8%) 4 32 ast-stats-2 - DocComment 32 ( 0.4%) 1 -ast-stats-2 - Normal 96 ( 1.2%) 3 -ast-stats-2 FieldDef 160 ( 2.0%) 2 80 -ast-stats-2 Stmt 160 ( 2.0%) 5 32 +ast-stats-2 - Normal 96 ( 1.3%) 3 +ast-stats-2 FieldDef 160 ( 2.2%) 2 80 +ast-stats-2 Stmt 160 ( 2.2%) 5 32 ast-stats-2 - Local 32 ( 0.4%) 1 ast-stats-2 - Semi 32 ( 0.4%) 1 -ast-stats-2 - Expr 96 ( 1.2%) 3 -ast-stats-2 Param 160 ( 2.0%) 4 40 -ast-stats-2 FnDecl 200 ( 2.5%) 5 40 -ast-stats-2 Variant 240 ( 3.0%) 2 120 -ast-stats-2 GenericBound 288 ( 3.6%) 4 72 -ast-stats-2 - Trait 288 ( 3.6%) 4 -ast-stats-2 Block 288 ( 3.6%) 6 48 -ast-stats-2 AssocItem 416 ( 5.1%) 4 104 -ast-stats-2 - Type 208 ( 2.6%) 2 -ast-stats-2 - Fn 208 ( 2.6%) 2 -ast-stats-2 GenericParam 480 ( 5.9%) 5 96 -ast-stats-2 Pat 616 ( 7.6%) 7 88 -ast-stats-2 - Struct 88 ( 1.1%) 1 -ast-stats-2 - Wild 88 ( 1.1%) 1 -ast-stats-2 - Ident 440 ( 5.4%) 5 -ast-stats-2 Expr 648 ( 8.0%) 9 72 -ast-stats-2 - Path 72 ( 0.9%) 1 -ast-stats-2 - Match 72 ( 0.9%) 1 -ast-stats-2 - Struct 72 ( 0.9%) 1 -ast-stats-2 - InlineAsm 72 ( 0.9%) 1 -ast-stats-2 - Lit 144 ( 1.8%) 2 -ast-stats-2 - Block 216 ( 2.7%) 3 -ast-stats-2 PathSegment 792 ( 9.8%) 33 24 -ast-stats-2 Ty 896 (11.0%) 14 64 -ast-stats-2 - Ptr 64 ( 0.8%) 1 -ast-stats-2 - Ref 64 ( 0.8%) 1 -ast-stats-2 - ImplicitSelf 128 ( 1.6%) 2 -ast-stats-2 - Path 640 ( 7.9%) 10 -ast-stats-2 Item 2_024 (25.0%) 11 184 -ast-stats-2 - Trait 184 ( 2.3%) 1 -ast-stats-2 - Enum 184 ( 2.3%) 1 -ast-stats-2 - ExternCrate 184 ( 2.3%) 1 -ast-stats-2 - ForeignMod 184 ( 2.3%) 1 -ast-stats-2 - Impl 184 ( 2.3%) 1 -ast-stats-2 - Fn 368 ( 4.5%) 2 -ast-stats-2 - Use 736 ( 9.1%) 4 +ast-stats-2 - Expr 96 ( 1.3%) 3 +ast-stats-2 Param 160 ( 2.2%) 4 40 +ast-stats-2 Block 192 ( 2.7%) 6 32 +ast-stats-2 Variant 208 ( 2.9%) 2 104 +ast-stats-2 GenericBound 224 ( 3.1%) 4 56 +ast-stats-2 - Trait 224 ( 3.1%) 4 +ast-stats-2 AssocItem 416 ( 5.8%) 4 104 +ast-stats-2 - Type 208 ( 2.9%) 2 +ast-stats-2 - Fn 208 ( 2.9%) 2 +ast-stats-2 GenericParam 480 ( 6.7%) 5 96 +ast-stats-2 Pat 504 ( 7.0%) 7 72 +ast-stats-2 - Struct 72 ( 1.0%) 1 +ast-stats-2 - Wild 72 ( 1.0%) 1 +ast-stats-2 - Ident 360 ( 5.0%) 5 +ast-stats-2 Expr 648 ( 9.1%) 9 72 +ast-stats-2 - Path 72 ( 1.0%) 1 +ast-stats-2 - Match 72 ( 1.0%) 1 +ast-stats-2 - Struct 72 ( 1.0%) 1 +ast-stats-2 - InlineAsm 72 ( 1.0%) 1 +ast-stats-2 - Lit 144 ( 2.0%) 2 +ast-stats-2 - Block 216 ( 3.0%) 3 +ast-stats-2 PathSegment 792 (11.1%) 33 24 +ast-stats-2 Ty 896 (12.5%) 14 64 +ast-stats-2 - Ptr 64 ( 0.9%) 1 +ast-stats-2 - Ref 64 ( 0.9%) 1 +ast-stats-2 - ImplicitSelf 128 ( 1.8%) 2 +ast-stats-2 - Path 640 ( 8.9%) 10 +ast-stats-2 Item 1_496 (20.9%) 11 136 +ast-stats-2 - Trait 136 ( 1.9%) 1 +ast-stats-2 - Enum 136 ( 1.9%) 1 +ast-stats-2 - ExternCrate 136 ( 1.9%) 1 +ast-stats-2 - ForeignMod 136 ( 1.9%) 1 +ast-stats-2 - Impl 136 ( 1.9%) 1 +ast-stats-2 - Fn 272 ( 3.8%) 2 +ast-stats-2 - Use 544 ( 7.6%) 4 ast-stats-2 ---------------------------------------------------------------- -ast-stats-2 Total 8_112 +ast-stats-2 Total 7_152 ast-stats-2 hir-stats HIR STATS hir-stats Name Accumulated Size Count Item Size diff --git a/tests/ui/structs/struct-path-associated-type.rs b/tests/ui/structs/struct-path-associated-type.rs index 2dd7174a9be..74d9705d4b8 100644 --- a/tests/ui/structs/struct-path-associated-type.rs +++ b/tests/ui/structs/struct-path-associated-type.rs @@ -13,7 +13,7 @@ fn f<T: Tr>() { //~^ ERROR expected struct, variant or union type, found associated type let z = T::A::<u8> {}; //~^ ERROR expected struct, variant or union type, found associated type - //~| ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied + //~| ERROR associated type takes 0 generic arguments but 1 generic argument was supplied match S { T::A {} => {} //~^ ERROR expected struct, variant or union type, found associated type @@ -22,7 +22,7 @@ fn f<T: Tr>() { fn g<T: Tr<A = S>>() { let s = T::A {}; // OK - let z = T::A::<u8> {}; //~ ERROR this associated type takes 0 generic arguments but 1 generic argument was supplied + let z = T::A::<u8> {}; //~ ERROR associated type takes 0 generic arguments but 1 generic argument was supplied match S { T::A {} => {} // OK } diff --git a/tests/ui/structs/struct-path-associated-type.stderr b/tests/ui/structs/struct-path-associated-type.stderr index ca5f0b7e21e..acfddaf3760 100644 --- a/tests/ui/structs/struct-path-associated-type.stderr +++ b/tests/ui/structs/struct-path-associated-type.stderr @@ -4,7 +4,7 @@ error[E0071]: expected struct, variant or union type, found associated type LL | let s = T::A {}; | ^^^^ not a struct -error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied --> $DIR/struct-path-associated-type.rs:14:16 | LL | let z = T::A::<u8> {}; @@ -30,7 +30,7 @@ error[E0071]: expected struct, variant or union type, found associated type LL | T::A {} => {} | ^^^^ not a struct -error[E0107]: this associated type takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied --> $DIR/struct-path-associated-type.rs:25:16 | LL | let z = T::A::<u8> {}; diff --git a/tests/ui/structs/structure-constructor-type-mismatch.rs b/tests/ui/structs/structure-constructor-type-mismatch.rs index a03ef590cb3..21cd9d08b21 100644 --- a/tests/ui/structs/structure-constructor-type-mismatch.rs +++ b/tests/ui/structs/structure-constructor-type-mismatch.rs @@ -45,13 +45,13 @@ fn main() { y: 8, }; - let pt3 = PointF::<i32> { //~ ERROR this type alias takes 0 generic arguments but 1 generic argument + let pt3 = PointF::<i32> { //~ ERROR type alias takes 0 generic arguments but 1 generic argument x: 9, //~ ERROR mismatched types y: 10, //~ ERROR mismatched types }; match (Point { x: 1, y: 2 }) { - PointF::<u32> { .. } => {} //~ ERROR this type alias takes 0 generic arguments but 1 generic argument + PointF::<u32> { .. } => {} //~ ERROR type alias takes 0 generic arguments but 1 generic argument //~^ ERROR mismatched types } diff --git a/tests/ui/structs/structure-constructor-type-mismatch.stderr b/tests/ui/structs/structure-constructor-type-mismatch.stderr index 3e3f9ea06ef..63dda459396 100644 --- a/tests/ui/structs/structure-constructor-type-mismatch.stderr +++ b/tests/ui/structs/structure-constructor-type-mismatch.stderr @@ -52,7 +52,7 @@ LL | x: 7, | expected `f32`, found integer | help: use a float literal: `7.0` -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/structure-constructor-type-mismatch.rs:48:15 | LL | let pt3 = PointF::<i32> { @@ -84,7 +84,7 @@ LL | y: 10, | expected `f32`, found integer | help: use a float literal: `10.0` -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/structure-constructor-type-mismatch.rs:54:9 | LL | PointF::<u32> { .. } => {} diff --git a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr index afef38f1296..211cb1584ad 100644 --- a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr +++ b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr @@ -36,7 +36,7 @@ LL | let y: i32 = i32::max - 42; | | | fn(i32, i32) -> i32 {<i32 as Ord>::max} | -help: use parentheses to call this associated function +help: use parentheses to call this method | LL | let y: i32 = i32::max(/* i32 */, /* i32 */) - 42; | ++++++++++++++++++++++ diff --git a/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr index 4f981a16374..a137db8cdee 100644 --- a/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr +++ b/tests/ui/suggestions/fn-or-tuple-struct-without-args.stderr @@ -206,7 +206,7 @@ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:41:20 | LL | fn ban(&self) -> usize { 42 } - | ---------------------- associated function `ban` defined here + | ---------------------- method `ban` defined here ... LL | let _: usize = X::ban; | ----- ^^^^^^ expected `usize`, found fn item @@ -215,7 +215,7 @@ LL | let _: usize = X::ban; | = note: expected type `usize` found fn item `for<'a> fn(&'a X) -> usize {<X as T>::ban}` -help: use parentheses to call this associated function +help: use parentheses to call this method | LL | let _: usize = X::ban(/* &X */); | ++++++++++ @@ -224,7 +224,7 @@ error[E0308]: mismatched types --> $DIR/fn-or-tuple-struct-without-args.rs:42:20 | LL | fn bal(&self) -> usize; - | ----------------------- associated function `bal` defined here + | ----------------------- method `bal` defined here ... LL | let _: usize = X::bal; | ----- ^^^^^^ expected `usize`, found fn item @@ -233,7 +233,7 @@ LL | let _: usize = X::bal; | = note: expected type `usize` found fn item `for<'a> fn(&'a X) -> usize {<X as T>::bal}` -help: use parentheses to call this associated function +help: use parentheses to call this method | LL | let _: usize = X::bal(/* &X */); | ++++++++++ diff --git a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr index 864ab053520..fc5a521746a 100644 --- a/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr +++ b/tests/ui/suggestions/imm-ref-trait-object-literal-bound-regions.stderr @@ -12,7 +12,7 @@ note: required by a bound in `foo` --> $DIR/imm-ref-trait-object-literal-bound-regions.rs:11:20 | LL | fn foo<X>(_: X) - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | for<'b> &'b X: Trait, | ^^^^^ required by this bound in `foo` diff --git a/tests/ui/suggestions/issue-101421.rs b/tests/ui/suggestions/issue-101421.rs index b615997d1a9..1407ebd277c 100644 --- a/tests/ui/suggestions/issue-101421.rs +++ b/tests/ui/suggestions/issue-101421.rs @@ -8,5 +8,5 @@ impl Ice for () { fn main() { ().f::<()>(()); - //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied + //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied } diff --git a/tests/ui/suggestions/issue-101421.stderr b/tests/ui/suggestions/issue-101421.stderr index f8e1efb8820..2656ab3db0b 100644 --- a/tests/ui/suggestions/issue-101421.stderr +++ b/tests/ui/suggestions/issue-101421.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-101421.rs:10:8 | LL | ().f::<()>(()); @@ -6,7 +6,7 @@ LL | ().f::<()>(()); | | | expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/issue-101421.rs:2:8 | LL | fn f(&self, _: ()); diff --git a/tests/ui/suggestions/issue-104287.rs b/tests/ui/suggestions/issue-104287.rs index e3fa22a8f66..37b3339fa92 100644 --- a/tests/ui/suggestions/issue-104287.rs +++ b/tests/ui/suggestions/issue-104287.rs @@ -8,6 +8,6 @@ impl S { fn main() { let x = S; foo::<()>(x); - //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied + //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied //~| ERROR cannot find function `foo` in this scope } diff --git a/tests/ui/suggestions/issue-104287.stderr b/tests/ui/suggestions/issue-104287.stderr index 602a01828b2..ed59b2e7a2d 100644 --- a/tests/ui/suggestions/issue-104287.stderr +++ b/tests/ui/suggestions/issue-104287.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-104287.rs:10:5 | LL | foo::<()>(x); @@ -6,7 +6,7 @@ LL | foo::<()>(x); | | | expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/issue-104287.rs:6:8 | LL | fn foo(&self) {} diff --git a/tests/ui/suggestions/issue-84973.stderr b/tests/ui/suggestions/issue-84973.stderr index ae2bf5aac40..55c89884a5f 100644 --- a/tests/ui/suggestions/issue-84973.stderr +++ b/tests/ui/suggestions/issue-84973.stderr @@ -13,7 +13,7 @@ LL | G: SomeTrait, | ^^^^^^^^^ required by this bound in `Other::<'a, G>::new` LL | { LL | pub fn new(g: G) -> Self { - | --- required by a bound in this + | --- required by a bound in this associated function help: consider borrowing here | LL | let o = Other::new(&f); diff --git a/tests/ui/suggestions/issue-85347.rs b/tests/ui/suggestions/issue-85347.rs index 02b5fb61894..04d4c47d8e5 100644 --- a/tests/ui/suggestions/issue-85347.rs +++ b/tests/ui/suggestions/issue-85347.rs @@ -1,7 +1,7 @@ use std::ops::Deref; trait Foo { type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; - //~^ ERROR this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + //~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments were supplied //~| ERROR associated type bindings are not allowed here //~| HELP add missing } diff --git a/tests/ui/suggestions/issue-85347.stderr b/tests/ui/suggestions/issue-85347.stderr index 17c1b7dc4cc..f330b3c1fad 100644 --- a/tests/ui/suggestions/issue-85347.stderr +++ b/tests/ui/suggestions/issue-85347.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated type takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/issue-85347.rs:3:42 | LL | type Bar<'a>: Deref<Target = <Self>::Bar<Target = Self>>; diff --git a/tests/ui/suggestions/issue-89064.stderr b/tests/ui/suggestions/issue-89064.stderr index 93d8da226c8..be09dd89512 100644 --- a/tests/ui/suggestions/issue-89064.stderr +++ b/tests/ui/suggestions/issue-89064.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-89064.rs:17:16 | LL | let _ = A::foo::<S>(); @@ -20,7 +20,7 @@ LL - let _ = A::foo::<S>(); LL + let _ = A::foo(); | -error[E0107]: this associated function takes 0 generic arguments but 2 generic arguments were supplied +error[E0107]: associated function takes 0 generic arguments but 2 generic arguments were supplied --> $DIR/issue-89064.rs:22:16 | LL | let _ = B::bar::<S, S>(); @@ -42,7 +42,7 @@ LL - let _ = B::bar::<S, S>(); LL + let _ = B::bar(); | -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: associated function takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-89064.rs:27:21 | LL | let _ = A::<S>::foo::<S>(); @@ -56,7 +56,7 @@ note: associated function defined here, with 0 generic parameters LL | fn foo() {} | ^^^ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/issue-89064.rs:31:16 | LL | let _ = 42.into::<Option<_>>(); diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs index 24f5f782f35..cb734e8ba85 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.rs +++ b/tests/ui/suggestions/missing-lifetime-specifier.rs @@ -37,19 +37,19 @@ thread_local! { thread_local! { static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); - //~^ ERROR this union takes 2 lifetime arguments but 1 lifetime argument - //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this union takes 2 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR union takes 2 lifetime arguments but 1 lifetime argument + //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR union takes 2 lifetime arguments but 1 lifetime argument was supplied } thread_local! { static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); - //~^ ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied - //~| ERROR this trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~^ ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied + //~| ERROR trait takes 2 lifetime arguments but 1 lifetime argument was supplied //~| ERROR missing lifetime //~| ERROR missing lifetime } diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr index 997bbb5e9b5..21d2378382c 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.stderr +++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr @@ -133,7 +133,7 @@ LL | | } | = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from -error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:39:44 | LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -151,7 +151,7 @@ help: add missing lifetime argument LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:39:44 | LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -169,7 +169,7 @@ help: add missing lifetime argument LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:39:44 | LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -187,7 +187,7 @@ help: add missing lifetime argument LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:39:44 | LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -205,7 +205,7 @@ help: add missing lifetime argument LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this union takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:39:44 | LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -223,7 +223,7 @@ help: add missing lifetime argument LL | static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:47:45 | LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -241,7 +241,7 @@ help: add missing lifetime argument LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:47:45 | LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -259,7 +259,7 @@ help: add missing lifetime argument LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:47:45 | LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -277,7 +277,7 @@ help: add missing lifetime argument LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:47:45 | LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); @@ -295,7 +295,7 @@ help: add missing lifetime argument LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new()); | +++++++++ -error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied --> $DIR/missing-lifetime-specifier.rs:47:45 | LL | static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new()); diff --git a/tests/ui/suggestions/missing-type-param-used-in-param.stderr b/tests/ui/suggestions/missing-type-param-used-in-param.stderr index 4f7058a6492..3116c5a0a1c 100644 --- a/tests/ui/suggestions/missing-type-param-used-in-param.stderr +++ b/tests/ui/suggestions/missing-type-param-used-in-param.stderr @@ -1,4 +1,4 @@ -error[E0107]: this function takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: function takes 2 generic arguments but 1 generic argument was supplied --> $DIR/missing-type-param-used-in-param.rs:6:5 | LL | two_type_params::<String>(100); diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs index 2f540060a34..4066cd3b11a 100644 --- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs +++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.rs @@ -12,7 +12,7 @@ impl Foo<i32> for i32 { fn main() { 1.bar::<i32>(0); - //~^ ERROR this associated function takes 0 generic arguments but 1 generic argument was supplied + //~^ ERROR method takes 0 generic arguments but 1 generic argument was supplied //~| HELP consider moving this generic argument to the `Foo` trait, which takes up to 1 argument //~| HELP remove these generics } diff --git a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr index 9557220f6bb..bfdb35947ef 100644 --- a/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr +++ b/tests/ui/suggestions/move-generic-to-trait-in-method-with-params.stderr @@ -1,10 +1,10 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/move-generic-to-trait-in-method-with-params.rs:14:7 | LL | 1.bar::<i32>(0); | ^^^ expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/move-generic-to-trait-in-method-with-params.rs:4:8 | LL | fn bar(&self, _: T); diff --git a/tests/ui/suggestions/sugg-else-for-closure.stderr b/tests/ui/suggestions/sugg-else-for-closure.stderr index 7f05832bcd7..09553b93c45 100644 --- a/tests/ui/suggestions/sugg-else-for-closure.stderr +++ b/tests/ui/suggestions/sugg-else-for-closure.stderr @@ -15,7 +15,7 @@ LL | let _s = y.unwrap_or(|| x.split('.').nth(1).unwrap()); | ^^^^^^^^^^^^-------------------------------^ | | | this argument influences the return type of `unwrap_or` -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/option.rs:LL:COL help: try calling `unwrap_or_else` instead | diff --git a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr index f520d88c6ba..7deb9a4342d 100644 --- a/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr +++ b/tests/ui/suggestions/trait-with-missing-associated-type-restriction.stderr @@ -90,7 +90,7 @@ LL | fn func(&self) -> Self::A; LL | fn funk(&self, _: Self::A); LL | fn funq(&self) -> Self::A {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Trait::funq` -note: associated function defined here +note: method defined here --> $DIR/trait-with-missing-associated-type-restriction.rs:9:8 | LL | fn funk(&self, _: Self::A); diff --git a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr index fcff02e09db..4e3180e84d2 100644 --- a/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr +++ b/tests/ui/suggestions/type-ascription-instead-of-path-in-type.stderr @@ -18,7 +18,7 @@ LL | let _: Vec<A:B> = A::B; = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information = help: add `#![feature(associated_type_bounds)]` to the crate attributes to enable -error[E0107]: this struct takes at least 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes at least 1 generic argument but 0 generic arguments were supplied --> $DIR/type-ascription-instead-of-path-in-type.rs:6:12 | LL | let _: Vec<A:B> = A::B; diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs index 8b6e8cfd720..ed262fd39a5 100644 --- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs +++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.rs @@ -6,7 +6,7 @@ pub trait T<X, Y> { pub struct Foo { i: Box<dyn T<usize, usize, usize, usize, B=usize>>, //~^ ERROR must be specified - //~| ERROR this trait takes 2 generic arguments but 4 generic arguments were supplied + //~| ERROR trait takes 2 generic arguments but 4 generic arguments were supplied } diff --git a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr index 75b91923284..175a5fbba61 100644 --- a/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr +++ b/tests/ui/suggestions/use-type-argument-instead-of-assoc-type.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 2 generic arguments but 4 generic arguments were supplied +error[E0107]: trait takes 2 generic arguments but 4 generic arguments were supplied --> $DIR/use-type-argument-instead-of-assoc-type.rs:7:16 | LL | i: Box<dyn T<usize, usize, usize, usize, B=usize>>, diff --git a/tests/ui/tool-attributes/auxiliary/p1.rs b/tests/ui/tool-attributes/auxiliary/p1.rs new file mode 100644 index 00000000000..47195c7e9d6 --- /dev/null +++ b/tests/ui/tool-attributes/auxiliary/p1.rs @@ -0,0 +1,3 @@ +#![feature(rustc_attrs)] +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} diff --git a/tests/ui/tool-attributes/auxiliary/p2.rs b/tests/ui/tool-attributes/auxiliary/p2.rs new file mode 100644 index 00000000000..47195c7e9d6 --- /dev/null +++ b/tests/ui/tool-attributes/auxiliary/p2.rs @@ -0,0 +1,3 @@ +#![feature(rustc_attrs)] +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.rs b/tests/ui/tool-attributes/duplicate-diagnostic.rs new file mode 100644 index 00000000000..39c2ca1cb86 --- /dev/null +++ b/tests/ui/tool-attributes/duplicate-diagnostic.rs @@ -0,0 +1,13 @@ +// aux-build: p1.rs +// aux-build: p2.rs + +// error-pattern: duplicate diagnostic item in crate `p2` +// error-pattern: note: the diagnostic item is first defined in crate `p1` + +#![feature(rustc_attrs)] +extern crate p1; +extern crate p2; + +#[rustc_diagnostic_item = "Foo"] +pub struct Foo {} //~ ERROR duplicate diagnostic item found +fn main() {} diff --git a/tests/ui/tool-attributes/duplicate-diagnostic.stderr b/tests/ui/tool-attributes/duplicate-diagnostic.stderr new file mode 100644 index 00000000000..e315fdc7d84 --- /dev/null +++ b/tests/ui/tool-attributes/duplicate-diagnostic.stderr @@ -0,0 +1,12 @@ +error: duplicate diagnostic item in crate `p2`: `Foo`. + | + = note: the diagnostic item is first defined in crate `p1`. + +error: duplicate diagnostic item found: `Foo`. + --> $DIR/duplicate-diagnostic.rs:12:1 + | +LL | pub struct Foo {} + | ^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/tests/ui/traits/alias/ambiguous.stderr b/tests/ui/traits/alias/ambiguous.stderr index 0fe1a79678d..203bdc526f6 100644 --- a/tests/ui/traits/alias/ambiguous.stderr +++ b/tests/ui/traits/alias/ambiguous.stderr @@ -14,11 +14,11 @@ note: candidate #2 is defined in an impl of the trait `B` for the type `u8` | LL | fn foo(&self) {} | ^^^^^^^^^^^^^ -help: disambiguate the associated function for candidate #1 +help: disambiguate the method for candidate #1 | LL | A::foo(&t); | ~~~~~~~~~~ -help: disambiguate the associated function for candidate #2 +help: disambiguate the method for candidate #2 | LL | B::foo(&t); | ~~~~~~~~~~ diff --git a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr index 3ec288d1382..dc967d51298 100644 --- a/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr +++ b/tests/ui/traits/inductive-overflow/supertrait-auto-trait.stderr @@ -4,7 +4,7 @@ error[E0568]: auto traits cannot have super traits or lifetime bounds LL | auto trait Magic: Copy {} | -----^^^^^^ help: remove the super traits or lifetime bounds | | - | auto trait cannot have super traits or lifetime bounds + | auto traits cannot have super traits or lifetime bounds error[E0277]: the trait bound `NoClone: Copy` is not satisfied --> $DIR/supertrait-auto-trait.rs:16:23 diff --git a/tests/ui/traits/issue-52893.stderr b/tests/ui/traits/issue-52893.stderr index 006cb3a7b72..db807a38830 100644 --- a/tests/ui/traits/issue-52893.stderr +++ b/tests/ui/traits/issue-52893.stderr @@ -18,7 +18,7 @@ LL | builder.push(output); | ^^^^^^^^^^^^^------^ | | | this argument influences the return type of `push` -note: associated function defined here +note: method defined here --> $DIR/issue-52893.rs:11:8 | LL | fn push(self, other: T) -> Self::PushRes; diff --git a/tests/ui/traits/issue-77982.stderr b/tests/ui/traits/issue-77982.stderr index 0b57a8212bd..a397b0accc8 100644 --- a/tests/ui/traits/issue-77982.stderr +++ b/tests/ui/traits/issue-77982.stderr @@ -4,7 +4,7 @@ error[E0283]: type annotations needed LL | opts.get(opt.as_ref()); | ^^^ ------------ type must be known at this point | | - | cannot infer type of the type parameter `Q` declared on the associated function `get` + | cannot infer type of the type parameter `Q` declared on the method `get` | = note: multiple `impl`s satisfying `String: Borrow<_>` found in the following crates: `alloc`, `core`: - impl Borrow<str> for String; @@ -23,7 +23,7 @@ error[E0283]: type annotations needed LL | opts.get(opt.as_ref()); | ^^^ ------ type must be known at this point | | - | cannot infer type of the type parameter `Q` declared on the associated function `get` + | cannot infer type of the type parameter `Q` declared on the method `get` | = note: multiple `impl`s satisfying `String: AsRef<_>` found in the following crates: `alloc`, `std`: - impl AsRef<OsStr> for String; diff --git a/tests/ui/traits/item-privacy.rs b/tests/ui/traits/item-privacy.rs index 38d06b967bc..a3e1a22e7a8 100644 --- a/tests/ui/traits/item-privacy.rs +++ b/tests/ui/traits/item-privacy.rs @@ -69,7 +69,7 @@ fn check_method() { S.c(); // OK // a, b, c are resolved as inherent items, their traits don't need to be in scope let c = &S as &dyn C; - c.a(); //~ ERROR associated function `a` is private + c.a(); //~ ERROR method `a` is private c.b(); // OK c.c(); // OK @@ -81,7 +81,7 @@ fn check_method() { //~^ ERROR no function or associated item named `b` found S::c(&S); // OK // a, b, c are resolved as inherent items, their traits don't need to be in scope - <dyn C>::a(&S); //~ ERROR associated function `a` is private + <dyn C>::a(&S); //~ ERROR method `a` is private <dyn C>::b(&S); // OK C::c(&S); // OK } diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index 293cfbda86c..04995b3a17b 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -32,14 +32,14 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use method::B; | -error[E0624]: associated function `a` is private +error[E0624]: method `a` is private --> $DIR/item-privacy.rs:72:7 | LL | fn a(&self) { } - | ----------- private associated function defined here + | ----------- private method defined here ... LL | c.a(); - | ^ private associated function + | ^ private method error[E0599]: no function or associated item named `a` found for struct `S` in the current scope --> $DIR/item-privacy.rs:78:8 @@ -72,14 +72,14 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use method::B; | -error[E0624]: associated function `a` is private +error[E0624]: method `a` is private --> $DIR/item-privacy.rs:84:14 | LL | fn a(&self) { } - | ----------- private associated function defined here + | ----------- private method defined here ... LL | <dyn C>::a(&S); - | ^ private associated function + | ^ private method error[E0599]: no associated item named `A` found for struct `S` in the current scope --> $DIR/item-privacy.rs:97:8 diff --git a/tests/ui/traits/method-private.stderr b/tests/ui/traits/method-private.stderr index 8e991ec018c..55656f21e00 100644 --- a/tests/ui/traits/method-private.stderr +++ b/tests/ui/traits/method-private.stderr @@ -1,11 +1,11 @@ -error[E0624]: associated function `method` is private +error[E0624]: method `method` is private --> $DIR/method-private.rs:19:9 | LL | fn method(&self) {} - | ---------------- private associated function defined here + | ---------------- private method defined here ... LL | foo.method(); - | ^^^^^^ private associated function + | ^^^^^^ private method | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope; perhaps add a `use` for it: diff --git a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr index 6e6172eea47..e927f26e96d 100644 --- a/tests/ui/traits/multidispatch-convert-ambig-dest.stderr +++ b/tests/ui/traits/multidispatch-convert-ambig-dest.stderr @@ -29,7 +29,7 @@ note: required by a bound in `test` --> $DIR/multidispatch-convert-ambig-dest.rs:21:11 | LL | fn test<T,U>(_: T, _: U) - | ---- required by a bound in this + | ---- required by a bound in this function LL | where T : Convert<U> | ^^^^^^^^^^ required by this bound in `test` help: consider specifying the generic arguments diff --git a/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs new file mode 100644 index 00000000000..c886aeeda3e --- /dev/null +++ b/tests/ui/traits/new-solver/higher-ranked-dyn-bounds.rs @@ -0,0 +1,17 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Trait<'a> { + type Item: for<'b> Trait2<'b>; +} + +trait Trait2<'a> {} +impl Trait2<'_> for () {} + +fn needs_trait(_: Box<impl for<'a> Trait<'a> + ?Sized>) {} + +fn foo(x: Box<dyn for<'a> Trait<'a, Item = ()>>) { + needs_trait(x); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/new-solver/more-object-bound.rs new file mode 100644 index 00000000000..712759ef0e6 --- /dev/null +++ b/tests/ui/traits/new-solver/more-object-bound.rs @@ -0,0 +1,27 @@ +// compile-flags: -Ztrait-solver=next +// From #80800 + +trait SuperTrait { + type A; + type B; +} + +trait Trait: SuperTrait<A = <Self as SuperTrait>::B> {} + +fn transmute<A, B>(x: A) -> B { + foo::<A, B, dyn Trait<A = A, B = B>>(x) + //~^ ERROR type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait` +} + +fn foo<A, B, T: ?Sized>(x: T::A) -> B +where + T: Trait<B = B>, +{ + x +} + +static X: u8 = 0; +fn main() { + let x = transmute::<&u8, &[u8; 1_000_000]>(&X); + println!("{:?}", x[100_000]); +} diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr new file mode 100644 index 00000000000..208fdecb08f --- /dev/null +++ b/tests/ui/traits/new-solver/more-object-bound.stderr @@ -0,0 +1,19 @@ +error[E0283]: type annotations needed: cannot satisfy `dyn Trait<A = A, B = B>: Trait` + --> $DIR/more-object-bound.rs:12:5 + | +LL | foo::<A, B, dyn Trait<A = A, B = B>>(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: cannot satisfy `dyn Trait<A = A, B = B>: Trait` +note: required by a bound in `foo` + --> $DIR/more-object-bound.rs:18:8 + | +LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B + | --- required by a bound in this function +LL | where +LL | T: Trait<B = B>, + | ^^^^^^^^^^^^ required by this bound in `foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/traits/new-solver/object-unsafety.rs b/tests/ui/traits/new-solver/object-unsafety.rs new file mode 100644 index 00000000000..7bdd863a762 --- /dev/null +++ b/tests/ui/traits/new-solver/object-unsafety.rs @@ -0,0 +1,20 @@ +// compile-flags: -Ztrait-solver=next + +trait Setup { + type From: Copy; +} + +fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From { + *from +} + +pub fn copy_any<T>(t: &T) -> T { + copy::<dyn Setup<From=T>>(t) + //~^ ERROR the trait bound `dyn Setup<From = T>: Setup` is not satisfied +} + +fn main() { + let x = String::from("Hello, world"); + let y = copy_any(&x); + println!("{y}"); +} diff --git a/tests/ui/traits/new-solver/object-unsafety.stderr b/tests/ui/traits/new-solver/object-unsafety.stderr new file mode 100644 index 00000000000..198ac623df8 --- /dev/null +++ b/tests/ui/traits/new-solver/object-unsafety.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `dyn Setup<From = T>: Setup` is not satisfied + --> $DIR/object-unsafety.rs:12:12 + | +LL | copy::<dyn Setup<From=T>>(t) + | ^^^^^^^^^^^^^^^^^ the trait `Setup` is not implemented for `dyn Setup<From = T>` + | +note: required by a bound in `copy` + --> $DIR/object-unsafety.rs:7:12 + | +LL | fn copy<U: Setup + ?Sized>(from: &U::From) -> U::From { + | ^^^^^ required by this bound in `copy` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | pub fn copy_any<T>(t: &T) -> T where dyn Setup<From = T>: Setup { + | ++++++++++++++++++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr index 6480e490e8b..ed9b57cb1bd 100644 --- a/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr +++ b/tests/ui/traits/non_lifetime_binders/bad-sized-cond.stderr @@ -18,7 +18,7 @@ note: required by a bound in `foo` --> $DIR/bad-sized-cond.rs:6:15 | LL | pub fn foo() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | for<V> V: Sized, | ^^^^^ required by this bound in `foo` @@ -35,7 +35,7 @@ note: required by a bound in `bar` --> $DIR/bad-sized-cond.rs:12:15 | LL | pub fn bar() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | for<V> V: IntoIterator, | ^^^^^^^^^^^^ required by this bound in `bar` @@ -52,7 +52,7 @@ note: required by a bound in `bar` --> $DIR/bad-sized-cond.rs:12:15 | LL | pub fn bar() - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | for<V> V: IntoIterator, | ^^^^^^^^^^^^ required by this bound in `bar` diff --git a/tests/ui/traits/non_lifetime_binders/fail.stderr b/tests/ui/traits/non_lifetime_binders/fail.stderr index c3f4fd6a88e..7bd02550fb3 100644 --- a/tests/ui/traits/non_lifetime_binders/fail.stderr +++ b/tests/ui/traits/non_lifetime_binders/fail.stderr @@ -17,7 +17,7 @@ note: required by a bound in `fail` --> $DIR/fail.rs:10:15 | LL | fn fail() - | ---- required by a bound in this + | ---- required by a bound in this function LL | where LL | for<T> T: Trait, | ^^^^^ required by this bound in `fail` @@ -33,7 +33,7 @@ note: required by a bound in `auto_trait` --> $DIR/fail.rs:15:15 | LL | fn auto_trait() - | ---------- required by a bound in this + | ---------- required by a bound in this function LL | where LL | for<T> T: Send, | ^^^^ required by this bound in `auto_trait` diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs new file mode 100644 index 00000000000..5ff7089b993 --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.rs @@ -0,0 +1,14 @@ +// edition:2021 +// check-pass + +// Checks that test_type_match code doesn't ICE when predicates have late-bound types + +#![feature(non_lifetime_binders)] +//~^ WARN is incomplete and may not be safe to use + +async fn walk2<'a, T: 'a>(_: T) +where + for<F> F: 'a, +{} + +fn main() {} diff --git a/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr new file mode 100644 index 00000000000..3609bed28df --- /dev/null +++ b/tests/ui/traits/non_lifetime_binders/type-match-with-late-bound.stderr @@ -0,0 +1,11 @@ +warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/type-match-with-late-bound.rs:6:12 + | +LL | #![feature(non_lifetime_binders)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/traits/object/enforce-supertrait-projection.stderr b/tests/ui/traits/object/enforce-supertrait-projection.stderr index cbf09386654..848b4e69a4b 100644 --- a/tests/ui/traits/object/enforce-supertrait-projection.stderr +++ b/tests/ui/traits/object/enforce-supertrait-projection.stderr @@ -16,7 +16,7 @@ note: required by a bound in `foo` --> $DIR/enforce-supertrait-projection.rs:15:8 | LL | fn foo<A, B, T: ?Sized>(x: T::A) -> B - | --- required by a bound in this + | --- required by a bound in this function LL | where LL | T: Trait<B = B>, | ^^^^^^^^^^^^ required by this bound in `foo` diff --git a/tests/ui/traits/object/vs-lifetime.rs b/tests/ui/traits/object/vs-lifetime.rs index 14ae67cffd7..d3e6c0b217c 100644 --- a/tests/ui/traits/object/vs-lifetime.rs +++ b/tests/ui/traits/object/vs-lifetime.rs @@ -9,8 +9,8 @@ fn main() { let _: S<'static, dyn 'static +>; //~^ at least one trait is required for an object type let _: S<'static, 'static>; - //~^ ERROR this struct takes 1 lifetime argument but 2 lifetime arguments were supplied - //~| ERROR this struct takes 1 generic argument but 0 generic arguments were supplied + //~^ ERROR struct takes 1 lifetime argument but 2 lifetime arguments were supplied + //~| ERROR struct takes 1 generic argument but 0 generic arguments were supplied let _: S<dyn 'static +, 'static>; //~^ ERROR type provided when a lifetime was expected //~| ERROR at least one trait is required for an object type diff --git a/tests/ui/traits/object/vs-lifetime.stderr b/tests/ui/traits/object/vs-lifetime.stderr index 22446522852..a69cd140807 100644 --- a/tests/ui/traits/object/vs-lifetime.stderr +++ b/tests/ui/traits/object/vs-lifetime.stderr @@ -4,7 +4,7 @@ error[E0224]: at least one trait is required for an object type LL | let _: S<'static, dyn 'static +>; | ^^^^^^^^^^^^^ -error[E0107]: this struct takes 1 lifetime argument but 2 lifetime arguments were supplied +error[E0107]: struct takes 1 lifetime argument but 2 lifetime arguments were supplied --> $DIR/vs-lifetime.rs:11:12 | LL | let _: S<'static, 'static>; @@ -18,7 +18,7 @@ note: struct defined here, with 1 lifetime parameter: `'a` LL | struct S<'a, T>(&'a u8, T); | ^ -- -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/vs-lifetime.rs:11:12 | LL | let _: S<'static, 'static>; diff --git a/tests/ui/traits/test-2.rs b/tests/ui/traits/test-2.rs index 342928e882a..ffb778a0141 100644 --- a/tests/ui/traits/test-2.rs +++ b/tests/ui/traits/test-2.rs @@ -7,9 +7,9 @@ impl bar for u32 { fn dup(&self) -> u32 { *self } fn blah<X>(&self) {} } fn main() { 10.dup::<i32>(); - //~^ ERROR this associated function takes 0 generic arguments but 1 + //~^ ERROR method takes 0 generic arguments but 1 10.blah::<i32, i32>(); - //~^ ERROR this associated function takes 1 generic argument but 2 + //~^ ERROR method takes 1 generic argument but 2 (Box::new(10) as Box<dyn bar>).dup(); //~^ ERROR E0038 //~| ERROR E0038 diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr index eaa20b0b4f4..6c0e8b8af4b 100644 --- a/tests/ui/traits/test-2.stderr +++ b/tests/ui/traits/test-2.stderr @@ -1,4 +1,4 @@ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/test-2.rs:9:8 | LL | 10.dup::<i32>(); @@ -6,13 +6,13 @@ LL | 10.dup::<i32>(); | | | expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/test-2.rs:4:16 | LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } | ^^^ -error[E0107]: this associated function takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: method takes 1 generic argument but 2 generic arguments were supplied --> $DIR/test-2.rs:11:8 | LL | 10.blah::<i32, i32>(); @@ -20,7 +20,7 @@ LL | 10.blah::<i32, i32>(); | | | expected 1 generic argument | -note: associated function defined here, with 1 generic parameter: `X` +note: method defined here, with 1 generic parameter: `X` --> $DIR/test-2.rs:4:39 | LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); } diff --git a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr index 96a2fdc54db..164e88ede20 100644 --- a/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/arrays/should_require_well_defined_layout.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -31,7 +31,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -53,7 +53,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -75,7 +75,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -97,7 +97,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -119,7 +119,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr index 4da5fcea337..0f0f77f1683 100644 --- a/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr +++ b/tests/ui/transmutability/enums/repr/primitive_reprs_should_have_correct_length.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -32,7 +32,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -55,7 +55,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -78,7 +78,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -101,7 +101,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -124,7 +124,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -147,7 +147,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -170,7 +170,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -193,7 +193,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -216,7 +216,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -239,7 +239,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -262,7 +262,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -285,7 +285,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -308,7 +308,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -331,7 +331,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -354,7 +354,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -377,7 +377,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -400,7 +400,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -423,7 +423,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -446,7 +446,7 @@ note: required by a bound in `is_transmutable` --> $DIR/primitive_reprs_should_have_correct_length.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr index 510b8c56e5a..d456a746f5e 100644 --- a/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/enums/repr/should_require_well_defined_layout.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -55,7 +55,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -78,7 +78,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -101,7 +101,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -124,7 +124,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:14:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/enums/should_pad_variants.stderr b/tests/ui/transmutability/enums/should_pad_variants.stderr index a823503d594..f4988239df9 100644 --- a/tests/ui/transmutability/enums/should_pad_variants.stderr +++ b/tests/ui/transmutability/enums/should_pad_variants.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/enums/should_respect_endianness.stderr b/tests/ui/transmutability/enums/should_respect_endianness.stderr index 0845a5edf32..350583b0b85 100644 --- a/tests/ui/transmutability/enums/should_respect_endianness.stderr +++ b/tests/ui/transmutability/enums/should_respect_endianness.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_respect_endianness.rs:14:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/issue-101739-2.rs b/tests/ui/transmutability/issue-101739-2.rs index 964a7e49ee6..e5a56ccc9e0 100644 --- a/tests/ui/transmutability/issue-101739-2.rs +++ b/tests/ui/transmutability/issue-101739-2.rs @@ -15,7 +15,7 @@ mod assert { const ASSUME_VISIBILITY: bool, >() where - Dst: BikeshedIntrinsicFrom< //~ ERROR this trait takes at most 3 generic arguments but 6 generic arguments were supplied + Dst: BikeshedIntrinsicFrom< //~ ERROR trait takes at most 3 generic arguments but 6 generic arguments were supplied Src, Context, ASSUME_ALIGNMENT, diff --git a/tests/ui/transmutability/issue-101739-2.stderr b/tests/ui/transmutability/issue-101739-2.stderr index 1b3d202590d..420a9f33008 100644 --- a/tests/ui/transmutability/issue-101739-2.stderr +++ b/tests/ui/transmutability/issue-101739-2.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes at most 3 generic arguments but 6 generic arguments were supplied +error[E0107]: trait takes at most 3 generic arguments but 6 generic arguments were supplied --> $DIR/issue-101739-2.rs:18:14 | LL | Dst: BikeshedIntrinsicFrom< diff --git a/tests/ui/transmutability/primitives/bool.stderr b/tests/ui/transmutability/primitives/bool.stderr index 214b5e150ed..22decf15e54 100644 --- a/tests/ui/transmutability/primitives/bool.stderr +++ b/tests/ui/transmutability/primitives/bool.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/bool.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/primitives/numbers.stderr b/tests/ui/transmutability/primitives/numbers.stderr index 7cb7ca8e6db..c04a0e82aa2 100644 --- a/tests/ui/transmutability/primitives/numbers.stderr +++ b/tests/ui/transmutability/primitives/numbers.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -25,7 +25,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -41,7 +41,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -57,7 +57,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -73,7 +73,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -89,7 +89,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -105,7 +105,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -121,7 +121,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -137,7 +137,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -153,7 +153,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -169,7 +169,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -185,7 +185,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -201,7 +201,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -217,7 +217,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -233,7 +233,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -249,7 +249,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -265,7 +265,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -281,7 +281,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -297,7 +297,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -313,7 +313,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -329,7 +329,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -345,7 +345,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -361,7 +361,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -377,7 +377,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -393,7 +393,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -409,7 +409,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -425,7 +425,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -441,7 +441,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -457,7 +457,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -473,7 +473,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -489,7 +489,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -505,7 +505,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -521,7 +521,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -537,7 +537,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -553,7 +553,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -569,7 +569,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -585,7 +585,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -601,7 +601,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -617,7 +617,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -633,7 +633,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -649,7 +649,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -665,7 +665,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -681,7 +681,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -697,7 +697,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -713,7 +713,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -729,7 +729,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -745,7 +745,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -761,7 +761,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -777,7 +777,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -793,7 +793,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -809,7 +809,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -825,7 +825,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -841,7 +841,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -857,7 +857,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -873,7 +873,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -889,7 +889,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -905,7 +905,7 @@ note: required by a bound in `is_transmutable` --> $DIR/numbers.rs:12:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/primitives/unit.stderr b/tests/ui/transmutability/primitives/unit.stderr index 8cabe44a053..988cd33b3bf 100644 --- a/tests/ui/transmutability/primitives/unit.stderr +++ b/tests/ui/transmutability/primitives/unit.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/unit.rs:12:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/references.stderr b/tests/ui/transmutability/references.stderr index e9c7b144a82..eb3bd03fd31 100644 --- a/tests/ui/transmutability/references.stderr +++ b/tests/ui/transmutability/references.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/references.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr index 621dbee849f..d9aebac6417 100644 --- a/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/structs/repr/should_require_well_defined_layout.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -55,7 +55,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -78,7 +78,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -101,7 +101,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -124,7 +124,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -147,7 +147,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -170,7 +170,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -193,7 +193,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -216,7 +216,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -239,7 +239,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -262,7 +262,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr index 523bde85adf..aa0cbc51b1b 100644 --- a/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr +++ b/tests/ui/transmutability/unions/repr/should_require_well_defined_layout.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ @@ -32,7 +32,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_require_well_defined_layout.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/unions/should_pad_variants.stderr b/tests/ui/transmutability/unions/should_pad_variants.stderr index a823503d594..f4988239df9 100644 --- a/tests/ui/transmutability/unions/should_pad_variants.stderr +++ b/tests/ui/transmutability/unions/should_pad_variants.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_pad_variants.rs:13:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { | ______________^ diff --git a/tests/ui/transmutability/unions/should_reject_contraction.stderr b/tests/ui/transmutability/unions/should_reject_contraction.stderr index 41f0cedc3a3..fa7dcc3d22a 100644 --- a/tests/ui/transmutability/unions/should_reject_contraction.stderr +++ b/tests/ui/transmutability/unions/should_reject_contraction.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_contraction.rs:13:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/unions/should_reject_disjoint.stderr b/tests/ui/transmutability/unions/should_reject_disjoint.stderr index 4323f974066..880e4cd8940 100644 --- a/tests/ui/transmutability/unions/should_reject_disjoint.stderr +++ b/tests/ui/transmutability/unions/should_reject_disjoint.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` @@ -25,7 +25,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/should_reject_disjoint.rs:13:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY.and(Assume::VALIDITY) }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_maybe_transmutable` diff --git a/tests/ui/transmutability/unions/should_reject_intersecting.stderr b/tests/ui/transmutability/unions/should_reject_intersecting.stderr index e009888ae8d..501760b0809 100644 --- a/tests/ui/transmutability/unions/should_reject_intersecting.stderr +++ b/tests/ui/transmutability/unions/should_reject_intersecting.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:14:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` @@ -25,7 +25,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_intersecting.rs:14:14 | LL | pub fn is_transmutable<Src, Dst>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context, { Assume::SAFETY }> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr index d5d6d431b6f..afbba653b83 100644 --- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_field.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_if_dst_has_private_field.rs:13:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr index a1ca2ced53f..f14b5d8b2cb 100644 --- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_private_variant.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_if_dst_has_private_variant.rs:13:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr index 4e648664d5a..01ae8bea256 100644 --- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_field.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_if_dst_has_unreachable_field.rs:15:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr index bd72d64ccd7..20a680a7484 100644 --- a/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr +++ b/tests/ui/transmutability/visibility/should_reject_if_dst_has_unreachable_ty.stderr @@ -21,7 +21,7 @@ note: required by a bound in `is_transmutable` --> $DIR/should_reject_if_dst_has_unreachable_ty.rs:15:14 | LL | pub fn is_transmutable<Src, Dst, Context>() - | --------------- required by a bound in this + | --------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom<Src, Context> // safety is NOT assumed | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable` diff --git a/tests/ui/transmute/transmute-padding-ice.stderr b/tests/ui/transmute/transmute-padding-ice.stderr index c9233890f7a..87fd4fb6630 100644 --- a/tests/ui/transmute/transmute-padding-ice.stderr +++ b/tests/ui/transmute/transmute-padding-ice.stderr @@ -9,7 +9,7 @@ note: required by a bound in `is_maybe_transmutable` --> $DIR/transmute-padding-ice.rs:11:14 | LL | pub fn is_maybe_transmutable<Src, Dst>() - | --------------------- required by a bound in this + | --------------------- required by a bound in this function LL | where LL | Dst: BikeshedIntrinsicFrom< | ______________^ diff --git a/tests/ui/tuple/wrong_argument_ice-3.stderr b/tests/ui/tuple/wrong_argument_ice-3.stderr index 7143c959478..8b9dac6e291 100644 --- a/tests/ui/tuple/wrong_argument_ice-3.stderr +++ b/tests/ui/tuple/wrong_argument_ice-3.stderr @@ -11,7 +11,7 @@ LL | groups.push(new_group, vec![process]); | ^^^^^^^^^ = note: expected tuple `(Vec<String>, Vec<Process>)` found struct `Vec<String>` -note: associated function defined here +note: method defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: remove the extra argument | diff --git a/tests/ui/tuple/wrong_argument_ice.stderr b/tests/ui/tuple/wrong_argument_ice.stderr index f1b00ae0b92..213ca8f885c 100644 --- a/tests/ui/tuple/wrong_argument_ice.stderr +++ b/tests/ui/tuple/wrong_argument_ice.stderr @@ -4,7 +4,7 @@ error[E0061]: method takes 1 argument but 2 arguments were supplied LL | self.acc.push_back(self.current_provides, self.current_requires); | ^^^^^^^^^ | -note: associated function defined here +note: method defined here --> $SRC_DIR/alloc/src/collections/vec_deque/mod.rs:LL:COL help: wrap these arguments in parentheses to construct a tuple | diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs index 0031a4665c8..759a7fd7e05 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs +++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.rs @@ -62,10 +62,10 @@ fn main() { AliasFixed::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::TSVariant(()); - //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this type [E0109] - //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] // Struct variant @@ -80,10 +80,10 @@ fn main() { AliasFixed::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::SVariant { v: () }; - //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this type [E0109] - //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] // Unit variant @@ -98,8 +98,8 @@ fn main() { AliasFixed::UVariant::<()>; //~^ ERROR type arguments are not allowed on this type [E0109] AliasFixed::<()>::UVariant; - //~^ ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~^ ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] AliasFixed::<()>::UVariant::<()>; //~^ ERROR type arguments are not allowed on this type [E0109] - //~| ERROR this type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] + //~| ERROR type alias takes 0 generic arguments but 1 generic argument was supplied [E0107] } diff --git a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr index a922d7a5e41..758ff31ff70 100644 --- a/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr +++ b/tests/ui/type-alias-enum-variants/enum-variant-generic-args.stderr @@ -304,7 +304,7 @@ LL | AliasFixed::TSVariant::<()>(()); | | | not allowed on this type -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:64:5 | LL | AliasFixed::<()>::TSVariant(()); @@ -318,7 +318,7 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:66:5 | LL | AliasFixed::<()>::TSVariant::<()>(()); @@ -395,7 +395,7 @@ LL - AliasFixed::SVariant::<()> { v: () }; LL + AliasFixed::<()>::SVariant { v: () }; | -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:82:5 | LL | AliasFixed::<()>::SVariant { v: () }; @@ -409,7 +409,7 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:84:5 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; @@ -470,7 +470,7 @@ LL | AliasFixed::UVariant::<()>; | | | not allowed on this type -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:100:5 | LL | AliasFixed::<()>::UVariant; @@ -484,7 +484,7 @@ note: type alias defined here, with 0 generic parameters LL | type AliasFixed = Enum<()>; | ^^^^^^^^^^ -error[E0107]: this type alias takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: type alias takes 0 generic arguments but 1 generic argument was supplied --> $DIR/enum-variant-generic-args.rs:102:5 | LL | AliasFixed::<()>::UVariant::<()>; diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs index eeb5dca07f0..7c3a3a84406 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked.rs +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.rs @@ -6,7 +6,6 @@ type X<'a> = impl Into<&'static str> + From<&'a str>; fn f<'a: 'static>(t: &'a str) -> X<'a> { - //~^ WARNING unnecessary lifetime parameter t //~^ ERROR expected generic lifetime parameter, found `'static` } diff --git a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr index 94882597a62..962dedde09a 100644 --- a/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr +++ b/tests/ui/type-alias-impl-trait/bounds-are-checked.stderr @@ -1,13 +1,5 @@ -warning: unnecessary lifetime parameter `'a` - --> $DIR/bounds-are-checked.rs:8:6 - | -LL | fn f<'a: 'static>(t: &'a str) -> X<'a> { - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/bounds-are-checked.rs:10:5 + --> $DIR/bounds-are-checked.rs:9:5 | LL | type X<'a> = impl Into<&'static str> + From<&'a str>; | -- cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type @@ -15,6 +7,6 @@ LL | type X<'a> = impl Into<&'static str> + From<&'a str>; LL | t | ^ -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error For more information about this error, try `rustc --explain E0792`. diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs index 07f825aea50..6f9434255a8 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.rs @@ -4,7 +4,6 @@ mod test_lifetime_param { type Ty<'a> = impl Sized + 'a; fn defining(a: &str) -> Ty<'_> { a } fn assert_static<'a: 'static>() {} - //~^ WARN: unnecessary lifetime parameter `'a` fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } //~^ ERROR: lifetime may not live long enough } @@ -13,14 +12,12 @@ mod test_higher_kinded_lifetime_param { type Ty<'a> = impl Sized + 'a; fn defining(a: &str) -> Ty<'_> { a } fn assert_static<'a: 'static>() {} - //~^ WARN: unnecessary lifetime parameter `'a` fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } //~^ ERROR: lifetime may not live long enough } mod test_higher_kinded_lifetime_param2 { fn assert_static<'a: 'static>() {} - //~^ WARN: unnecessary lifetime parameter `'a` fn test<'a>() { assert_static::<'a>() } //~^ ERROR: lifetime may not live long enough } diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr index 887620a4d50..399775641f8 100644 --- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr +++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr @@ -1,41 +1,17 @@ -warning: unnecessary lifetime parameter `'a` - --> $DIR/implied_lifetime_wf_check3.rs:6:22 - | -LL | fn assert_static<'a: 'static>() {} - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - -warning: unnecessary lifetime parameter `'a` - --> $DIR/implied_lifetime_wf_check3.rs:15:22 - | -LL | fn assert_static<'a: 'static>() {} - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - -warning: unnecessary lifetime parameter `'a` - --> $DIR/implied_lifetime_wf_check3.rs:22:22 - | -LL | fn assert_static<'a: 'static>() {} - | ^^ - | - = help: you can use the `'static` lifetime directly, in place of `'a` - error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:8:43 + --> $DIR/implied_lifetime_wf_check3.rs:7:43 | LL | fn test<'a>() where Ty<'a>: 'static { assert_static::<'a>() } | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:17:46 + --> $DIR/implied_lifetime_wf_check3.rs:15:46 | LL | fn test<'a>() where for<'b> Ty<'b>: 'a { assert_static::<'a>() } | -- lifetime `'a` defined here ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:24:21 + --> $DIR/implied_lifetime_wf_check3.rs:21:21 | LL | fn test<'a>() { assert_static::<'a>() } | -- ^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` @@ -43,7 +19,7 @@ LL | fn test<'a>() { assert_static::<'a>() } | lifetime `'a` defined here error[E0310]: the parameter type `A` may not live long enough - --> $DIR/implied_lifetime_wf_check3.rs:32:41 + --> $DIR/implied_lifetime_wf_check3.rs:29:41 | LL | fn test<A>() where Ty<A>: 'static { assert_static::<A>() } | ^^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds @@ -53,6 +29,6 @@ help: consider adding an explicit lifetime bound... LL | fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() } | +++++++++ -error: aborting due to 4 previous errors; 3 warnings emitted +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0310`. diff --git a/tests/ui/type-alias-impl-trait/match-unification.rs b/tests/ui/type-alias-impl-trait/match-unification.rs new file mode 100644 index 00000000000..f5c2abc0efa --- /dev/null +++ b/tests/ui/type-alias-impl-trait/match-unification.rs @@ -0,0 +1,14 @@ +use std::fmt::Debug; + +// check-pass + +fn bar() -> impl Debug {} + +fn baz(b: bool) -> Option<impl Debug> { + match b { + true => baz(false), + false => Some(bar()), + } +} + +fn main() {} diff --git a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr index a31cf1a51cc..ff375b2ff86 100644 --- a/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr +++ b/tests/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr @@ -1,4 +1,4 @@ -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types --> $DIR/type-alias-impl-trait-fn-type.rs:6:20 | LL | type Foo = fn() -> impl Send; diff --git a/tests/ui/type-inference/sort_by_key.stderr b/tests/ui/type-inference/sort_by_key.stderr index 0a48d5756eb..de7b4b24899 100644 --- a/tests/ui/type-inference/sort_by_key.stderr +++ b/tests/ui/type-inference/sort_by_key.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/sort_by_key.rs:3:40 | LL | lst.sort_by_key(|&(v, _)| v.iter().sum()); - | ^^^ cannot infer type of the type parameter `S` declared on the associated function `sum` + | ^^^ cannot infer type of the type parameter `S` declared on the method `sum` | help: consider specifying the generic argument | diff --git a/tests/ui/type/type-check/point-at-inference-3.fixed b/tests/ui/type/type-check/point-at-inference-3.fixed index 1a960133ceb..edd4adf8bd2 100644 --- a/tests/ui/type/type-check/point-at-inference-3.fixed +++ b/tests/ui/type/type-check/point-at-inference-3.fixed @@ -7,6 +7,6 @@ fn main() { v.push(1i32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` //~| NOTE arguments to this method are incorrect - //~| NOTE associated function defined here + //~| NOTE method defined here //~| HELP change the type of the numeric literal from `u32` to `i32` } diff --git a/tests/ui/type/type-check/point-at-inference-3.rs b/tests/ui/type/type-check/point-at-inference-3.rs index 92910ae1a31..49d7b50075b 100644 --- a/tests/ui/type/type-check/point-at-inference-3.rs +++ b/tests/ui/type/type-check/point-at-inference-3.rs @@ -7,6 +7,6 @@ fn main() { v.push(1u32); //~ ERROR mismatched types //~^ NOTE expected `i32`, found `u32` //~| NOTE arguments to this method are incorrect - //~| NOTE associated function defined here + //~| NOTE method defined here //~| HELP change the type of the numeric literal from `u32` to `i32` } diff --git a/tests/ui/type/type-check/point-at-inference-3.stderr b/tests/ui/type/type-check/point-at-inference-3.stderr index 999c3148362..2c4907ed263 100644 --- a/tests/ui/type/type-check/point-at-inference-3.stderr +++ b/tests/ui/type/type-check/point-at-inference-3.stderr @@ -9,7 +9,7 @@ LL | v.push(1u32); | | | arguments to this method are incorrect | -note: associated function defined here +note: method defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL help: change the type of the numeric literal from `u32` to `i32` | diff --git a/tests/ui/type/type-check/point-at-inference-4.rs b/tests/ui/type/type-check/point-at-inference-4.rs index 7903e9e83cf..aea9b2c6c14 100644 --- a/tests/ui/type/type-check/point-at-inference-4.rs +++ b/tests/ui/type/type-check/point-at-inference-4.rs @@ -2,7 +2,7 @@ struct S<A, B>(Option<(A, B)>); impl<A, B> S<A, B> { fn infer(&self, a: A, b: B) {} - //~^ NOTE associated function defined here + //~^ NOTE method defined here //~| NOTE //~| NOTE } diff --git a/tests/ui/type/type-check/point-at-inference-4.stderr b/tests/ui/type/type-check/point-at-inference-4.stderr index fac9701e4a1..28833d2ed1c 100644 --- a/tests/ui/type/type-check/point-at-inference-4.stderr +++ b/tests/ui/type/type-check/point-at-inference-4.stderr @@ -4,7 +4,7 @@ error[E0061]: this method takes 2 arguments but 1 argument was supplied LL | s.infer(0i32); | ^^^^^------ an argument is missing | -note: associated function defined here +note: method defined here --> $DIR/point-at-inference-4.rs:4:8 | LL | fn infer(&self, a: A, b: B) {} diff --git a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr index 4d012cb156b..fbe6bfeebb1 100644 --- a/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr +++ b/tests/ui/type/wrong-call-return-type-due-to-generic-arg.stderr @@ -95,7 +95,7 @@ LL | let x: u16 = (S {}).method(0u32); | ^^^^^^^^^^^^^^----^ | | | this argument influences the return type of `method` -note: associated function defined here +note: method defined here --> $DIR/wrong-call-return-type-due-to-generic-arg.rs:7:8 | LL | fn method<T>(&self, x: T) -> T { diff --git a/tests/ui/typeck/bad-type-in-vec-push.stderr b/tests/ui/typeck/bad-type-in-vec-push.stderr index 882854acb1d..ae46050c91b 100644 --- a/tests/ui/typeck/bad-type-in-vec-push.stderr +++ b/tests/ui/typeck/bad-type-in-vec-push.stderr @@ -10,7 +10,7 @@ LL | result.push(vector); | = note: expected type `{integer}` found struct `Vec<_>` -note: associated function defined here +note: method defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0308]: mismatched types @@ -21,7 +21,7 @@ LL | x.push(""); | | | arguments to this method are incorrect | -note: associated function defined here +note: method defined here --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/issue-104513-ice.stderr b/tests/ui/typeck/issue-104513-ice.stderr index 42cfe38aed8..09187d7863a 100644 --- a/tests/ui/typeck/issue-104513-ice.stderr +++ b/tests/ui/typeck/issue-104513-ice.stderr @@ -4,7 +4,7 @@ error[E0405]: cannot find trait `Oops` in this scope LL | let _: S<impl Oops> = S; | ^^^^ not found in this scope -error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable binding +error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in variable bindings --> $DIR/issue-104513-ice.rs:3:14 | LL | let _: S<impl Oops> = S; diff --git a/tests/ui/typeck/issue-75883.rs b/tests/ui/typeck/issue-75883.rs index 885acc48231..c50ea0a086b 100644 --- a/tests/ui/typeck/issue-75883.rs +++ b/tests/ui/typeck/issue-75883.rs @@ -4,7 +4,7 @@ pub struct UI {} impl UI { pub fn run() -> Result<_> { - //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied + //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types let mut ui = UI {}; ui.interact(); @@ -13,7 +13,7 @@ impl UI { } pub fn interact(&mut self) -> Result<_> { - //~^ ERROR: this enum takes 2 generic arguments but 1 generic argument was supplied + //~^ ERROR: enum takes 2 generic arguments but 1 generic argument was supplied //~| ERROR: the placeholder `_` is not allowed within types on item signatures for return types unimplemented!(); } diff --git a/tests/ui/typeck/issue-75883.stderr b/tests/ui/typeck/issue-75883.stderr index f5adcabe3e9..a1ed0840675 100644 --- a/tests/ui/typeck/issue-75883.stderr +++ b/tests/ui/typeck/issue-75883.stderr @@ -1,4 +1,4 @@ -error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied --> $DIR/issue-75883.rs:6:21 | LL | pub fn run() -> Result<_> { @@ -11,7 +11,7 @@ help: add missing generic argument LL | pub fn run() -> Result<_, E> { | +++ -error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied +error[E0107]: enum takes 2 generic arguments but 1 generic argument was supplied --> $DIR/issue-75883.rs:15:35 | LL | pub fn interact(&mut self) -> Result<_> { diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr index 63936f9979f..3d2d53f5c76 100644 --- a/tests/ui/typeck/issue-84768.stderr +++ b/tests/ui/typeck/issue-84768.stderr @@ -21,7 +21,7 @@ LL | <F as FnOnce(&mut u8)>::call_once(f, 1) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^ | | | this argument influences the return type of `FnOnce` -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/ops/function.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs new file mode 100644 index 00000000000..5ff567cd07c --- /dev/null +++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.rs @@ -0,0 +1,6 @@ +// compile-flags: -Ztrait-solver=next +// known-bug: unknown + +fn main() { + (0u8 + 0u8) as char; +} diff --git a/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr new file mode 100644 index 00000000000..6b09ccd5214 --- /dev/null +++ b/tests/ui/typeck/lazy-norm/cast-checks-handling-projections.stderr @@ -0,0 +1,9 @@ +error[E0271]: type mismatch resolving `char == <u8 as Add>::Output` + --> $DIR/cast-checks-handling-projections.rs:5:5 + | +LL | (0u8 + 0u8) as char; + | ^^^^^^^^^^^ types differ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0271`. diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs index c463a8ad0c7..7ff9199f63c 100644 --- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs +++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.rs @@ -1,17 +1,17 @@ fn foo1<T:Copy<U>, U>(x: T) {} -//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied trait Trait: Copy<dyn Send> {} -//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied struct MyStruct1<T: Copy<T>>; -//~^ ERROR this trait takes 0 generic arguments but 1 generic argument was supplied +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied struct MyStruct2<'a, T: Copy<'a>>; -//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} -//~^ ERROR this trait takes 0 lifetime arguments but 1 lifetime argument was supplied -//~| ERROR this trait takes 0 generic arguments but 1 generic argument was supplied +//~^ ERROR trait takes 0 lifetime arguments but 1 lifetime argument was supplied +//~| ERROR trait takes 0 generic arguments but 1 generic argument was supplied fn main() { } diff --git a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr index 331540d1e42..a71fd953658 100644 --- a/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr +++ b/tests/ui/typeck/typeck-builtin-bound-type-parameters.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:1:11 | LL | fn foo1<T:Copy<U>, U>(x: T) {} @@ -6,7 +6,7 @@ LL | fn foo1<T:Copy<U>, U>(x: T) {} | | | expected 0 generic arguments -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:4:14 | LL | trait Trait: Copy<dyn Send> {} @@ -14,7 +14,7 @@ LL | trait Trait: Copy<dyn Send> {} | | | expected 0 generic arguments -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:7:21 | LL | struct MyStruct1<T: Copy<T>>; @@ -22,7 +22,7 @@ LL | struct MyStruct1<T: Copy<T>>; | | | expected 0 generic arguments -error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:10:25 | LL | struct MyStruct2<'a, T: Copy<'a>>; @@ -30,7 +30,7 @@ LL | struct MyStruct2<'a, T: Copy<'a>>; | | | expected 0 lifetime arguments -error[E0107]: this trait takes 0 lifetime arguments but 1 lifetime argument was supplied +error[E0107]: trait takes 0 lifetime arguments but 1 lifetime argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 | LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} @@ -38,7 +38,7 @@ LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} | | | expected 0 lifetime arguments -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/typeck-builtin-bound-type-parameters.rs:13:15 | LL | fn foo2<'a, T:Copy<'a, U>, U>(x: T) {} diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs index b96c5271339..a450dbb82d1 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.rs +++ b/tests/ui/typeck/typeck_type_placeholder_item.rs @@ -227,4 +227,6 @@ fn evens_squared(n: usize) -> _ { } const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); -//~^ ERROR the placeholder `_` is not allowed within types on item signatures for constants +//~^ ERROR the trait bound +//~| ERROR the trait bound +//~| ERROR the placeholder diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr index bc02547c65e..bc6c9fd0779 100644 --- a/tests/ui/typeck/typeck_type_placeholder_item.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr @@ -437,17 +437,37 @@ LL | fn evens_squared(n: usize) -> _ { | not allowed in type signatures | help: replace with an appropriate return type: `impl Iterator<Item = usize>` -error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants - --> $DIR/typeck_type_placeholder_item.rs:229:10 +error[E0277]: the trait bound `std::ops::Range<{integer}>: Iterator` is not satisfied + --> $DIR/typeck_type_placeholder_item.rs:229:22 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^ not allowed in type signatures + | ^^^^^^ `std::ops::Range<{integer}>` is not an iterator + | + = help: the trait `~const Iterator` is not implemented for `std::ops::Range<{integer}>` +note: the trait `Iterator` is implemented for `std::ops::Range<{integer}>`, but that implementation is not `const` + --> $DIR/typeck_type_placeholder_item.rs:229:14 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^^^^^ + +error[E0277]: the trait bound `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>: Iterator` is not satisfied + --> $DIR/typeck_type_placeholder_item.rs:229:45 | -note: however, the inferred type `Map<Filter<Range<i32>, [closure@typeck_type_placeholder_item.rs:229:29]>, [closure@typeck_type_placeholder_item.rs:229:49]>` cannot be named +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^^^ `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` is not an iterator + | + = help: the trait `~const Iterator` is not implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>` +note: the trait `Iterator` is implemented for `Filter<std::ops::Range<{integer}>, [closure@$DIR/typeck_type_placeholder_item.rs:229:29: 229:32]>`, but that implementation is not `const` --> $DIR/typeck_type_placeholder_item.rs:229:14 | LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants + --> $DIR/typeck_type_placeholder_item.rs:229:10 + | +LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x); + | ^ not allowed in type signatures error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:140:31 @@ -657,7 +677,7 @@ LL | const D: _ = 42; | not allowed in type signatures | help: replace with the correct type: `i32` -error: aborting due to 71 previous errors +error: aborting due to 73 previous errors -Some errors have detailed explanations: E0121, E0282, E0403. +Some errors have detailed explanations: E0121, E0277, E0282, E0403. For more information about an error, try `rustc --explain E0121`. diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs index 43e46c5b6c3..90b12ffdf77 100644 --- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs +++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.rs @@ -7,5 +7,5 @@ struct Foo<'a, T:'a> { pub fn main() { let c: Foo<_, _> = Foo { r: &5 }; - //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied + //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied } diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr index a89c6b85c78..c4e4aed2067 100644 --- a/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_1.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied --> $DIR/typeck_type_placeholder_lifetime_1.rs:9:12 | LL | let c: Foo<_, _> = Foo { r: &5 }; diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs index 178b8b1229a..e361312ddba 100644 --- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs +++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.rs @@ -7,5 +7,5 @@ struct Foo<'a, T:'a> { pub fn main() { let c: Foo<_, usize> = Foo { r: &5 }; - //~^ ERROR this struct takes 1 generic argument but 2 generic arguments were supplied + //~^ ERROR struct takes 1 generic argument but 2 generic arguments were supplied } diff --git a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr index f30766bdf01..302231777bd 100644 --- a/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr +++ b/tests/ui/typeck/typeck_type_placeholder_lifetime_2.stderr @@ -1,4 +1,4 @@ -error[E0107]: this struct takes 1 generic argument but 2 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 2 generic arguments were supplied --> $DIR/typeck_type_placeholder_lifetime_2.rs:9:12 | LL | let c: Foo<_, usize> = Foo { r: &5 }; diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.rs b/tests/ui/ufcs/ufcs-qpath-missing-params.rs index 766351634bb..6ab6580c0e6 100644 --- a/tests/ui/ufcs/ufcs-qpath-missing-params.rs +++ b/tests/ui/ufcs/ufcs-qpath-missing-params.rs @@ -15,6 +15,6 @@ fn main() { //~^ ERROR missing generics for <String as IntoCow>::into_cow::<str>("foo".to_string()); - //~^ ERROR this associated function takes 0 generic arguments but 1 + //~^ ERROR method takes 0 generic arguments but 1 //~| ERROR missing generics for } diff --git a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr index d0ec47d6132..2338871218b 100644 --- a/tests/ui/ufcs/ufcs-qpath-missing-params.stderr +++ b/tests/ui/ufcs/ufcs-qpath-missing-params.stderr @@ -30,7 +30,7 @@ help: add missing generic argument LL | <String as IntoCow<B>>::into_cow::<str>("foo".to_string()); | +++ -error[E0107]: this associated function takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: method takes 0 generic arguments but 1 generic argument was supplied --> $DIR/ufcs-qpath-missing-params.rs:17:26 | LL | <String as IntoCow>::into_cow::<str>("foo".to_string()); @@ -38,7 +38,7 @@ LL | <String as IntoCow>::into_cow::<str>("foo".to_string()); | | | expected 0 generic arguments | -note: associated function defined here, with 0 generic parameters +note: method defined here, with 0 generic parameters --> $DIR/ufcs-qpath-missing-params.rs:4:8 | LL | fn into_cow(self) -> Cow<'a, B>; diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr index e85144a31ca..96ac4321689 100644 --- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr +++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr @@ -28,7 +28,7 @@ LL | <i32 as Add<i32>>::add(1u32, 2); | ^^^^^^^^^^^^^^^^^^^^^^^----^^^^ | | | this argument influences the return type of `Add` -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the type of the numeric literal from `u32` to `i32` | @@ -50,7 +50,7 @@ LL | <i32 as Add<i32>>::add(1, 2u32); | ^^^^^^^^^^^^^^^^^^^^^^^^^^----^ | | | this argument influences the return type of `Add` -note: associated function defined here +note: method defined here --> $SRC_DIR/core/src/ops/arith.rs:LL:COL help: change the type of the numeric literal from `u32` to `i32` | diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs index 65f40075bd8..c575f507704 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs @@ -28,7 +28,7 @@ fn test<'a,'b>() { } fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) { - //~^ ERROR this trait takes 1 lifetime argument but 0 lifetime arguments were supplied + //~^ ERROR trait takes 1 lifetime argument but 0 lifetime arguments were supplied // Here, the omitted lifetimes are expanded to distinct things. same_type(x, y) } diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr index 016fc4dfb24..8814617814c 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 1 lifetime argument but 0 lifetime arguments were supplied +error[E0107]: trait takes 1 lifetime argument but 0 lifetime arguments were supplied --> $DIR/unboxed-closure-sugar-region.rs:30:51 | LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) { diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs index 462f6fb7b87..14d5646b508 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.rs @@ -7,7 +7,7 @@ struct Bar<A> { fn bar() { let x: Box<Bar()> = panic!(); //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait - //~| ERROR this struct takes 1 generic argument but 0 generic arguments + //~| ERROR struct takes 1 generic argument but 0 generic arguments } fn main() { } diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr index 29ea5735cad..27b22c2127b 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-1.stderr @@ -4,7 +4,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait LL | let x: Box<Bar()> = panic!(); | ^^^^^ only `Fn` traits may use parentheses -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/unboxed-closure-sugar-used-on-struct-1.rs:8:16 | LL | let x: Box<Bar()> = panic!(); diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs index bd61cbd8022..657b29204cd 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.rs @@ -6,7 +6,7 @@ struct Bar<A> { fn foo(b: Box<Bar()>) { //~^ ERROR parenthesized type parameters may only be used with a `Fn` trait - //~| ERROR this struct takes 1 generic argument but 0 generic arguments + //~| ERROR struct takes 1 generic argument but 0 generic arguments } fn main() { } diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr index 427ba3414f8..94e42a66c9e 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct.stderr @@ -4,7 +4,7 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait LL | fn foo(b: Box<Bar()>) { | ^^^^^ only `Fn` traits may use parentheses -error[E0107]: this struct takes 1 generic argument but 0 generic arguments were supplied +error[E0107]: struct takes 1 generic argument but 0 generic arguments were supplied --> $DIR/unboxed-closure-sugar-used-on-struct.rs:7:15 | LL | fn foo(b: Box<Bar()>) { diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs index f26ad8e93a1..dd47ae73a38 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs @@ -3,7 +3,7 @@ trait Three<A,B,C> { fn dummy(&self) -> (A,B,C); } fn foo(_: &dyn Three()) -//~^ ERROR this trait takes 3 generic arguments but 1 generic argument +//~^ ERROR trait takes 3 generic arguments but 1 generic argument //~| ERROR associated type `Output` not found {} diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr index ebaacf0a698..5d7fe3fa533 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters-3.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 3 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 3 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters-3.rs:5:16 | LL | fn foo(_: &dyn Three()) diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs index 4465b43a757..2c7e12f3257 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.rs @@ -3,25 +3,25 @@ trait Zero { fn dummy(&self); } fn foo1(_: dyn Zero()) { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| ERROR associated type `Output` not found for `Zero` } fn foo2(_: dyn Zero<usize>) { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument } fn foo3(_: dyn Zero < usize >) { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument } fn foo4(_: dyn Zero(usize)) { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| ERROR associated type `Output` not found for `Zero` } fn foo5(_: dyn Zero ( usize )) { - //~^ ERROR this trait takes 0 generic arguments but 1 generic argument + //~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| ERROR associated type `Output` not found for `Zero` } diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr index 9601e64c189..50b90553aa7 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-number-number-type-parameters.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:5:16 | LL | fn foo1(_: dyn Zero()) { @@ -18,7 +18,7 @@ error[E0220]: associated type `Output` not found for `Zero` LL | fn foo1(_: dyn Zero()) { | ^^^^^^ associated type `Output` not found -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:10:16 | LL | fn foo2(_: dyn Zero<usize>) { @@ -32,7 +32,7 @@ note: trait defined here, with 0 generic parameters LL | trait Zero { fn dummy(&self); } | ^^^^ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:14:16 | LL | fn foo3(_: dyn Zero < usize >) { @@ -46,7 +46,7 @@ note: trait defined here, with 0 generic parameters LL | trait Zero { fn dummy(&self); } | ^^^^ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:18:16 | LL | fn foo4(_: dyn Zero(usize)) { @@ -66,7 +66,7 @@ error[E0220]: associated type `Output` not found for `Zero` LL | fn foo4(_: dyn Zero(usize)) { | ^^^^^^^^^^^ associated type `Output` not found -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-number-number-type-parameters.rs:23:16 | LL | fn foo5(_: dyn Zero ( usize )) { diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs index 4bcf90552f9..ad60b0a0c77 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.rs @@ -3,7 +3,7 @@ trait Trait {} fn f<F:Trait(isize) -> isize>(x: F) {} -//~^ ERROR this trait takes 0 generic arguments but 1 generic argument +//~^ ERROR trait takes 0 generic arguments but 1 generic argument //~| ERROR associated type `Output` not found for `Trait` fn main() {} diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr index 3ff05fb2331..130b193d69c 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-wrong-trait.stderr @@ -1,4 +1,4 @@ -error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied --> $DIR/unboxed-closure-sugar-wrong-trait.rs:5:8 | LL | fn f<F:Trait(isize) -> isize>(x: F) {} diff --git a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr index 635ebbb71d0..846a44ce4d7 100644 --- a/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr +++ b/tests/ui/unboxed-closures/unboxed-closures-infer-fn-once-move-from-projection.stderr @@ -14,7 +14,7 @@ note: required by a bound in `foo` --> $DIR/unboxed-closures-infer-fn-once-move-from-projection.rs:4:14 | LL | fn foo<F>(f: F) - | --- required by a bound in this + | --- required by a bound in this function LL | where F: Fn() | ^^^^ required by this bound in `foo` diff --git a/tests/ui/unsized/issue-71659.stderr b/tests/ui/unsized/issue-71659.stderr index d7b95f55769..b57b3015e47 100644 --- a/tests/ui/unsized/issue-71659.stderr +++ b/tests/ui/unsized/issue-71659.stderr @@ -8,7 +8,7 @@ note: required by a bound in `Cast::cast` --> $DIR/issue-71659.rs:19:15 | LL | fn cast<T: ?Sized>(&self) -> &T - | ---- required by a bound in this + | ---- required by a bound in this associated function LL | where LL | Self: CastTo<T>, | ^^^^^^^^^ required by this bound in `Cast::cast` diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr index 30248a7a397..191a8ca8ebc 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.quiet.stderr @@ -8,7 +8,7 @@ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | LL | fn called() - | ------ required by a bound in this + | ------ required by a bound in this function LL | where LL | for<'b> fn(&'b ()): Foo, | ^^^ required by this bound in `called` diff --git a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr index 268cef6e275..f4c7acd5c58 100644 --- a/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr +++ b/tests/ui/where-clauses/higher-ranked-fn-type.verbose.stderr @@ -8,7 +8,7 @@ note: required by a bound in `called` --> $DIR/higher-ranked-fn-type.rs:12:25 | LL | fn called() - | ------ required by a bound in this + | ------ required by a bound in this function LL | where LL | for<'b> fn(&'b ()): Foo, | ^^^ required by this bound in `called` diff --git a/tests/ui/xc-private-method2.rs b/tests/ui/xc-private-method2.rs index 92946923f6e..f11b251082b 100644 --- a/tests/ui/xc-private-method2.rs +++ b/tests/ui/xc-private-method2.rs @@ -4,8 +4,8 @@ extern crate xc_private_method_lib; fn main() { let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); - //~^ ERROR associated function `meth_struct` is private + //~^ ERROR method `meth_struct` is private let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum(); - //~^ ERROR associated function `meth_enum` is private + //~^ ERROR method `meth_enum` is private } diff --git a/tests/ui/xc-private-method2.stderr b/tests/ui/xc-private-method2.stderr index b569882f8c1..af0c3cfcb2c 100644 --- a/tests/ui/xc-private-method2.stderr +++ b/tests/ui/xc-private-method2.stderr @@ -1,24 +1,24 @@ -error[E0624]: associated function `meth_struct` is private +error[E0624]: method `meth_struct` is private --> $DIR/xc-private-method2.rs:6:52 | LL | let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); - | ^^^^^^^^^^^ private associated function + | ^^^^^^^^^^^ private method | ::: $DIR/auxiliary/xc-private-method-lib.rs:12:5 | LL | fn meth_struct(&self) -> isize { - | ------------------------------ private associated function defined here + | ------------------------------ private method defined here -error[E0624]: associated function `meth_enum` is private +error[E0624]: method `meth_enum` is private --> $DIR/xc-private-method2.rs:9:55 | LL | let _ = xc_private_method_lib::Enum::Variant1(20).meth_enum(); - | ^^^^^^^^^ private associated function + | ^^^^^^^^^ private method | ::: $DIR/auxiliary/xc-private-method-lib.rs:27:5 | LL | fn meth_enum(&self) -> isize { - | ---------------------------- private associated function defined here + | ---------------------------- private method defined here error: aborting due to 2 previous errors |
