mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 14:52:56 +03:00
@@ -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
|
||||
|
||||
+56
-31
@@ -88,15 +88,6 @@ dependencies = [
|
||||
"yansi-term",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@@ -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",
|
||||
@@ -1216,12 +1206,6 @@ version = "0.1.13"
|
||||
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"
|
||||
@@ -1378,6 +1362,15 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[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"
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 @@ pub fn span(&self) -> Span {
|
||||
/// 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 @@ pub fn span(&self) -> Span {
|
||||
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 @@ pub fn to_ty(&self) -> Option<P<Ty>> {
|
||||
// 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 @@ pub fn is_potential_trivial_const_param(&self) -> bool {
|
||||
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 @@ pub fn to_ty(&self) -> Option<P<Ty>> {
|
||||
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 @@ pub fn peel_refs(&self) -> &Self {
|
||||
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 @@ pub fn from_self(attrs: AttrVec, eself: ExplicitSelf, eself_ident: Ident) -> Par
|
||||
/// 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);
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
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 @@ pub fn is_word(&self) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ pub fn span(&self) -> Span {
|
||||
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 @@ pub fn value_str(&self) -> Option<Symbol> {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
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;
|
||||
@@ -335,6 +335,17 @@ pub fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F)
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
@@ -358,6 +369,11 @@ pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<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_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) => {
|
||||
|
||||
@@ -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"
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ pub(super) fn lower_expr_mut(&mut self, e: &Expr) -> hir::Expr<'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 @@ fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
|
||||
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 @@ fn lower_legacy_const_generics(
|
||||
|
||||
// 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 @@ fn lower_expr_await(&mut self, dot_await_span: Span, expr: &Expr) -> hir::ExprKi
|
||||
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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
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 @@ fn lower_item_kind(
|
||||
.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 @@ fn lower_item_kind(
|
||||
&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 @@ fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
|
||||
}
|
||||
|
||||
/// 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 @@ fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'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 @@ fn lower_fn_body_block(
|
||||
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 @@ pub(super) fn lower_const_body(&mut self, span: Span, expr: Option<&Expr>) -> hi
|
||||
&[],
|
||||
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")),
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
@@ -52,23 +52,28 @@
|
||||
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 @@ macro_rules! arena_vec {
|
||||
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 @@ fn lower_assoc_ty_constraint(
|
||||
} 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 @@ fn lower_assoc_ty_constraint(
|
||||
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 @@ fn lower_assoc_ty_constraint(
|
||||
//
|
||||
// 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 @@ fn lower_assoc_ty_constraint(
|
||||
// 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 @@ fn lower_assoc_ty_constraint(
|
||||
// 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.
|
||||
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.
|
||||
|
||||
let impl_trait_node_id = self.next_node_id();
|
||||
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,
|
||||
);
|
||||
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() }
|
||||
})
|
||||
} else {
|
||||
// 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::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 }
|
||||
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 @@ fn lower_path_ty(
|
||||
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 @@ fn ty_tup(&mut self, span: Span, tys: &'hir [hir::Ty<'hir>]) -> hir::Ty<'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 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir>
|
||||
path
|
||||
}
|
||||
ImplTraitContext::FeatureGated(position, feature) => {
|
||||
self.tcx
|
||||
let guar = self
|
||||
.tcx
|
||||
.sess
|
||||
.create_feature_err(
|
||||
MisplacedImplTrait {
|
||||
@@ -1373,24 +1395,24 @@ fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'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)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -330,8 +330,8 @@ fn lower_expr_within_pat(&mut self, expr: &Expr, allow_paths: bool) -> &'hir 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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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}
|
||||
@@ -13,7 +13,6 @@
|
||||
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_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 @@ fn with_let_management(
|
||||
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 @@ fn check_gat_where(
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn err_handler(&self) -> &rustc_errors::Handler {
|
||||
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 @@ fn check_decl_no_pat(decl: &FnDecl, mut report_err: impl FnMut(Span, Option<Iden
|
||||
|
||||
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 @@ fn check_decl_num_args(&self, fn_decl: &FnDecl) {
|
||||
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 @@ fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
|
||||
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 @@ fn check_decl_attrs(&self, fn_decl: &FnDecl) {
|
||||
})
|
||||
.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 @@ fn check_decl_attrs(&self, fn_decl: &FnDecl) {
|
||||
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 @@ fn check_decl_self_param(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
|
||||
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 @@ fn check_type_no_bounds(&self, bounds: &[GenericBound], ctx: &str) {
|
||||
[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 @@ fn check_foreign_kind_bodyless(&self, ident: Ident, kind: &str, body: Option<Spa
|
||||
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 @@ fn check_foreign_fn_bodyless(&self, ident: Ident, body: Option<&Block>) {
|
||||
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 @@ fn current_extern_span(&self) -> Span {
|
||||
/// 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 @@ fn check_c_variadic_type(&self, fk: FnKind<'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 @@ fn check_item_named(&self, ident: Ident, kind: &str) {
|
||||
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 @@ fn deny_where_clause(&self, where_clause: &WhereClause, ident_span: Span) {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ fn check_generic_args_before_constraints(&self, data: &AngleBracketedArgs) {
|
||||
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 @@ fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
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 @@ fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
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 @@ fn visit_ty_common(&mut self, ty: &'a Ty) {
|
||||
}
|
||||
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 @@ fn maybe_lint_missing_abi(&mut self, span: Span, id: NodeId) {
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
}
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
}
|
||||
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 @@ fn visit_item(&mut self, item: &'a Item) {
|
||||
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 @@ fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) {
|
||||
// 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 @@ fn visit_generics(&mut self, generics: &'a Generics) {
|
||||
}
|
||||
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 @@ fn visit_generics(&mut self, generics: &'a Generics) {
|
||||
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 @@ fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
||||
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 @@ fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
|
||||
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 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
|
||||
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 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
|
||||
// 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 @@ fn visit_fn(&mut self, fk: FnKind<'a>, span: Span, id: NodeId) {
|
||||
)
|
||||
}
|
||||
} 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 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
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 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
}
|
||||
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 @@ fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
..
|
||||
}) => {
|
||||
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),
|
||||
}
|
||||
|
||||
@@ -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)]
|
||||
@@ -23,13 +26,6 @@ pub struct ForbiddenLetStable {
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
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::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 @@ fn check_late_bound_lifetime_defs(&self, params: &[ast::GenericParam]) {
|
||||
&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 @@ macro_rules! gate_doc { ($($name:ident => $feature:ident)*) => {
|
||||
|| 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 @@ fn visit_item(&mut self, i: &'a ast::Item) {
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ edition = "2021"
|
||||
[dependencies]
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
thin-vec = "0.2.12"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
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::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 @@ pub(crate) fn print_ty_fn(
|
||||
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,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
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),
|
||||
|
||||
@@ -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 rustc_ast::attr::*;
|
||||
|
||||
pub(crate) use rustc_ast::HashStableContext;
|
||||
|
||||
fluent_messages! { "../locales/en-US.ftl" }
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
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 @@ fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, ErrorGua
|
||||
);
|
||||
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,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
};
|
||||
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);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/// 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>>,
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ fn to_universe_info(self, base_universe: ty::UniverseIndex) -> UniverseInfo<'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,
|
||||
|
||||
@@ -1494,7 +1494,7 @@ pub(crate) fn report_borrowed_value_does_not_live_long_enough(
|
||||
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 @@ fn report_escaping_data(
|
||||
) -> 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);
|
||||
|
||||
@@ -660,10 +660,8 @@ fn report_escaping_data_error(
|
||||
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 @@ fn report_general_error(
|
||||
..
|
||||
} = 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);
|
||||
|
||||
@@ -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 @@
|
||||
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 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 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>,
|
||||
|
||||
@@ -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 @@
|
||||
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<'_>>,
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
};
|
||||
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 @@
|
||||
},
|
||||
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 @@ pub(crate) fn new(
|
||||
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 @@ pub(crate) fn new(
|
||||
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 @@ fn eval_if_eq(
|
||||
/// 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);
|
||||
|
||||
@@ -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 @@ pub(crate) fn infer_opaque_types(
|
||||
// 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 @@ pub(crate) fn infer_opaque_types(
|
||||
/// 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 @@ fn infer_opaque_definition_from_instantiation(
|
||||
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 @@ fn infer_opaque_definition_from_instantiation(
|
||||
// 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 @@ fn infer_opaque_definition_from_instantiation(
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ pub(crate) fn region_value_str(&self, r: N) -> String {
|
||||
/// 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>,
|
||||
}
|
||||
|
||||
@@ -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 @@ fn tcx(&self) -> TyCtxt<'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 @@ fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
|
||||
#[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 @@ fn visit_region(&mut self, region: &mut ty::Region<'tcx>, location: Location) {
|
||||
#[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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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 @@ pub(super) fn instantiate_canonical_with_fresh_inference_vars<T>(
|
||||
canonical: &Canonical<'tcx, T>,
|
||||
) -> T
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let old_universe = self.infcx.universe();
|
||||
|
||||
@@ -117,7 +117,7 @@ pub(super) fn normalize_and_prove_instantiated_predicates(
|
||||
|
||||
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>,
|
||||
) {
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
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 @@ fn convert(
|
||||
///
|
||||
/// 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) => {
|
||||
|
||||
@@ -270,12 +270,13 @@ pub(crate) fn create(mut self) -> CreateResult<'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,
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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 @@ fn initialized_at_exit(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool
|
||||
/// 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 @@ fn add_drop_live_facts_for(
|
||||
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);
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
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 @@
|
||||
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 @@ macro_rules! span_mirbug_and_err {
|
||||
/// - `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 @@ fn sanitize_place(
|
||||
|
||||
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 @@ fn sanitize_projection(
|
||||
|
||||
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 @@ fn field_ty(
|
||||
/// 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 @@ pub fn span(&self, body: &Body<'_>) -> Span {
|
||||
|
||||
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 @@ fn check_terminator(
|
||||
}
|
||||
};
|
||||
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 @@ fn prove_closure_bounds(
|
||||
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(
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
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 @@ fn create_next_universe(&mut self) -> ty::UniverseIndex {
|
||||
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(
|
||||
|
||||
@@ -20,15 +20,18 @@
|
||||
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 @@ pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) {
|
||||
}
|
||||
|
||||
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 @@ fn build(self) -> UniversalRegions<'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 @@ fn build(self) -> UniversalRegions<'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 @@ fn build(self) -> UniversalRegions<'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 @@ fn build(self) -> UniversalRegions<'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 @@ fn compute_inputs_and_output(
|
||||
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 @@ fn compute_inputs_and_output(
|
||||
};
|
||||
|
||||
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 @@ fn compute_inputs_and_output(
|
||||
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 @@ fn compute_inputs_and_output(
|
||||
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 @@ fn replace_free_regions_with_nll_infer_vars<T>(
|
||||
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 @@ fn replace_bound_regions_with_nll_infer_vars<T>(
|
||||
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 @@ fn replace_late_bound_regions_with_nll_infer_vars_in_item(
|
||||
);
|
||||
}
|
||||
|
||||
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 @@ fn replace_bound_regions_with_nll_infer_vars<T>(
|
||||
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 @@ fn replace_late_bound_regions_with_nll_infer_vars_in_recursive_scope(
|
||||
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 @@ fn replace_late_bound_regions_with_nll_infer_vars_in_item(
|
||||
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 @@ pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
|
||||
/// 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)))
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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 };
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
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: {}",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
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 @@ pub(super) fn build(mut self, mut cond_expr: P<Expr>, panic_path: Path) -> P<Exp
|
||||
|
||||
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 @@ fn build_initial_imports(&self) -> Stmt {
|
||||
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 @@ fn build_unlikely(&self, cond_expr: P<Expr>) -> P<Expr> {
|
||||
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 @@ fn manage_initial_capture(&mut self, expr: &mut P<Expr>, path_ident: Ident) {
|
||||
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 @@ fn manage_try_capture(&mut self, capture: Ident, curr_capture_idx: usize, expr:
|
||||
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 @@ fn manage_try_capture(&mut self, capture: Ident, curr_capture_idx: usize, expr:
|
||||
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 @@ fn manage_try_capture(&mut self, capture: Ident, curr_capture_idx: usize, expr:
|
||||
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 })))
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
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)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
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() {
|
||||
|
||||
@@ -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()),
|
||||
},
|
||||
|
||||
@@ -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())),
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
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 expr_for_field(
|
||||
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 expr_for_field(
|
||||
};
|
||||
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 expr_for_field(
|
||||
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 expr_for_field(
|
||||
};
|
||||
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 expr_for_field(
|
||||
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]))
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
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),
|
||||
|
||||
@@ -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)"),
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
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 @@ fn into_block(mut self, cx: &ExtCtxt<'_>, span: Span) -> P<ast::Block> {
|
||||
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 visit_mac_call(&mut self, mac: &ast::MacCall) {
|
||||
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 @@ fn create_derived_impl(
|
||||
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 @@ fn extract_arg_details(
|
||||
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 @@ fn expand_enum_method_body<'b>(
|
||||
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 @@ fn expand_enum_method_body<'b>(
|
||||
// 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 @@ fn expand_enum_method_body<'b>(
|
||||
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 @@ fn expand_enum_method_body<'b>(
|
||||
// (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 @@ fn expand_enum_method_body<'b>(
|
||||
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 @@ fn expand_enum_method_body<'b>(
|
||||
// ...
|
||||
// _ => ::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 @@ fn expand_enum_method_body<'b>(
|
||||
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 @@ fn create_struct_patterns(
|
||||
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 @@ fn create_struct_field_access_fields(
|
||||
} 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)]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
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 @@ pub fn to_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 @@ pub fn to_generics(
|
||||
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)`"),
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
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],
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
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)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
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 @@ fn allocator_fn(&self, method: &AllocatorMethod) -> Stmt {
|
||||
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 @@ fn attrs(&self) -> AttrVec {
|
||||
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 @@ fn arg_ty(
|
||||
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 @@ fn ret_ty(&self, ty: &AllocatorTy, expr: P<Expr>) -> (P<Ty>, P<Expr>) {
|
||||
(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")
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
|
||||
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 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,)*) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
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,
|
||||
);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
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)],
|
||||
),
|
||||
},
|
||||
),
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -374,7 +374,7 @@ fn target_spec(&self) -> &Target {
|
||||
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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -119,7 +119,7 @@ fn create_entry_fn(
|
||||
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 @@ fn create_entry_fn(
|
||||
tcx,
|
||||
ParamEnv::reveal_all(),
|
||||
start_def_id,
|
||||
tcx.intern_substs(&[main_ret_ty.into()]),
|
||||
tcx.mk_substs(&[main_ret_ty.into()]),
|
||||
)
|
||||
.unwrap()
|
||||
.unwrap()
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -383,7 +383,7 @@ fn eh_personality(&self) -> RValue<'gcc> {
|
||||
tcx,
|
||||
ty::ParamEnv::reveal_all(),
|
||||
def_id,
|
||||
tcx.intern_substs(&[]),
|
||||
ty::List::empty(),
|
||||
)
|
||||
.unwrap().unwrap(),
|
||||
),
|
||||
|
||||
@@ -73,7 +73,8 @@
|
||||
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::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 {});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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};
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
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.
|
||||
|
||||
@@ -520,14 +520,9 @@ fn eh_personality(&self) -> &'ll Value {
|
||||
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()) {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
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;
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
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 @@ pub mod llvm {
|
||||
mod va_arg;
|
||||
mod value;
|
||||
|
||||
fluent_messages! { "../locales/en-US.ftl" }
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LlvmCodegenBackend(());
|
||||
|
||||
@@ -246,6 +249,10 @@ pub fn new() -> Box<dyn CodegenBackend> {
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
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;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
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};
|
||||
|
||||
@@ -473,13 +473,13 @@ fn add_object(&mut self, path: &Path) {
|
||||
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 @@ fn add_no_exec(&mut self) {
|
||||
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 @@ fn add_object(&mut self, path: &Path) {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -476,7 +476,7 @@ fn create_entry_fn<'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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
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 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
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
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 @@ fn codegen_call_terminator(
|
||||
};
|
||||
|
||||
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 @@ fn get_personality_slot(&mut self, bx: &mut Bx) -> PlaceRef<'tcx, Bx::Value> {
|
||||
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);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
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(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user