diff options
Diffstat (limited to 'compiler')
307 files changed, 8145 insertions, 4355 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 5d9d0a5feca..54bd25d6471 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -36,7 +36,7 @@ use rustc_span::{Span, DUMMY_SP}; use std::convert::TryFrom; use std::fmt; use std::mem; -use thin_vec::ThinVec; +use thin_vec::{thin_vec, ThinVec}; /// A "Label" is an identifier of some point in sources, /// e.g. in the following code: @@ -90,7 +90,7 @@ pub struct Path { pub span: Span, /// The segments in the path: the things separated by `::`. /// Global paths begin with `kw::PathRoot`. - pub segments: Vec<PathSegment>, + pub segments: ThinVec<PathSegment>, pub tokens: Option<LazyAttrTokenStream>, } @@ -114,7 +114,7 @@ impl Path { // Convert a span and an identifier to the corresponding // one-segment path. pub fn from_ident(ident: Ident) -> Path { - Path { segments: vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None } + Path { segments: thin_vec![PathSegment::from_ident(ident)], span: ident.span, tokens: None } } pub fn is_global(&self) -> bool { @@ -175,9 +175,9 @@ impl GenericArgs { } pub fn span(&self) -> Span { - match *self { - AngleBracketed(ref data) => data.span, - Parenthesized(ref data) => data.span, + match self { + AngleBracketed(data) => data.span, + Parenthesized(data) => data.span, } } } @@ -312,8 +312,8 @@ pub enum GenericBound { impl GenericBound { pub fn span(&self) -> Span { match self { - GenericBound::Trait(ref t, ..) => t.span, - GenericBound::Outlives(ref l) => l.ident.span, + GenericBound::Trait(t, ..) => t.span, + GenericBound::Outlives(l) => l.ident.span, } } } @@ -718,10 +718,10 @@ 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<QSelf>, Path, Vec<PatField>, /* recovered */ bool), + Struct(Option<P<QSelf>>, Path, Vec<PatField>, /* recovered */ bool), /// A tuple struct/variant pattern (`Variant(x, y, .., z)`). - TupleStruct(Option<QSelf>, Path, Vec<P<Pat>>), + TupleStruct(Option<P<QSelf>>, Path, Vec<P<Pat>>), /// An or-pattern `A | B | C`. /// Invariant: `pats.len() >= 2`. @@ -731,7 +731,7 @@ pub enum PatKind { /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can /// only legally refer to associated constants. - Path(Option<QSelf>, Path), + Path(Option<P<QSelf>>, Path), /// A tuple pattern (`(a, b)`). Tuple(Vec<P<Pat>>), @@ -1115,23 +1115,23 @@ impl Expr { /// If this is not the case, name resolution does not resolve `N` when using /// `min_const_generics` as more complex expressions are not supported. pub fn is_potential_trivial_const_param(&self) -> bool { - let this = if let ExprKind::Block(ref block, None) = self.kind { - if block.stmts.len() == 1 { - if let StmtKind::Expr(ref expr) = block.stmts[0].kind { expr } else { self } - } else { - self - } + let this = if let ExprKind::Block(block, None) = &self.kind + && block.stmts.len() == 1 + && let StmtKind::Expr(expr) = &block.stmts[0].kind + { + expr } else { self }; - if let ExprKind::Path(None, ref path) = this.kind { - if path.segments.len() == 1 && path.segments[0].args.is_none() { - return true; - } + if let ExprKind::Path(None, path) = &this.kind + && path.segments.len() == 1 + && path.segments[0].args.is_none() + { + true + } else { + false } - - false } pub fn to_bound(&self) -> Option<GenericBound> { @@ -1272,6 +1272,18 @@ impl Expr { } } +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct Closure { + pub binder: ClosureBinder, + pub capture_clause: CaptureBy, + pub asyncness: Async, + pub movability: Movability, + pub fn_decl: P<FnDecl>, + pub body: P<Expr>, + /// The span of the argument block `|...|`. + pub fn_decl_span: Span, +} + /// Limit types of a range (inclusive or exclusive) #[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug)] pub enum RangeLimits { @@ -1281,6 +1293,20 @@ pub enum RangeLimits { Closed, } +/// A method call (e.g. `x.foo::<Bar, Baz>(a, b, c)`). +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct MethodCall { + /// The method name and its generic arguments, e.g. `foo::<Bar, Baz>`. + pub seg: PathSegment, + /// The receiver, e.g. `x`. + pub receiver: P<Expr>, + /// The arguments, e.g. `a, b, c`. + pub args: Vec<P<Expr>>, + /// The span of the function, without the dot and receiver e.g. `foo::<Bar, + /// Baz>(a, b, c)`. + pub span: Span, +} + #[derive(Clone, Encodable, Decodable, Debug)] pub enum StructRest { /// `..x`. @@ -1293,7 +1319,7 @@ pub enum StructRest { #[derive(Clone, Encodable, Decodable, Debug)] pub struct StructExpr { - pub qself: Option<QSelf>, + pub qself: Option<P<QSelf>>, pub path: Path, pub fields: Vec<ExprField>, pub rest: StructRest, @@ -1314,17 +1340,8 @@ pub enum ExprKind { /// This also represents calling the constructor of /// tuple-like ADTs such as tuple structs and enum variants. Call(P<Expr>, Vec<P<Expr>>), - /// A method call (`x.foo::<'static, Bar, Baz>(a, b, c, d)`) - /// - /// The `PathSegment` represents the method name and its generic arguments - /// (within the angle brackets). - /// The standalone `Expr` is the receiver expression. - /// The vector of `Expr` is the arguments. - /// `x.foo::<Bar, Baz>(a, b, c, d)` is represented as - /// `ExprKind::MethodCall(PathSegment { foo, [Bar, Baz] }, x, [a, b, c, d])`. - /// This `Span` is the span of the function, without the dot and receiver - /// (e.g. `foo(a, b)` in `x.foo(a, b)` - MethodCall(PathSegment, P<Expr>, Vec<P<Expr>>, Span), + /// 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>>), /// A binary operation (e.g., `a + b`, `a * b`). @@ -1363,9 +1380,7 @@ pub enum ExprKind { /// A `match` block. Match(P<Expr>, Vec<Arm>), /// A closure (e.g., `move |a, b, c| a + b + c`). - /// - /// The final span is the span of the argument block `|...|`. - Closure(ClosureBinder, CaptureBy, Async, Movability, P<FnDecl>, P<Expr>, Span), + Closure(Box<Closure>), /// A block (`'label: { ... }`). Block(P<Block>, Option<Label>), /// An async block (`async move { ... }`). @@ -1403,7 +1418,7 @@ pub enum ExprKind { /// parameters (e.g., `foo::bar::<baz>`). /// /// Optionally "qualified" (e.g., `<Vec<T> as SomeTrait>::SomeType`). - Path(Option<QSelf>, Path), + Path(Option<P<QSelf>>, Path), /// A referencing operation (`&a`, `&mut a`, `&raw const a` or `&raw mut a`). AddrOf(BorrowKind, Mutability, P<Expr>), @@ -1529,55 +1544,48 @@ pub enum ClosureBinder { #[derive(Clone, Encodable, Decodable, Debug)] pub struct MacCall { pub path: Path, - pub args: P<MacArgs>, + pub args: P<DelimArgs>, pub prior_type_ascription: Option<(Span, bool)>, } impl MacCall { pub fn span(&self) -> Span { - self.path.span.to(self.args.span().unwrap_or(self.path.span)) + self.path.span.to(self.args.dspan.entire()) } } -/// Arguments passed to an attribute or a function-like macro. +/// Arguments passed to an attribute macro. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgs { - /// No arguments - `#[attr]`. +pub enum AttrArgs { + /// No arguments: `#[attr]`. Empty, - /// Delimited arguments - `#[attr()/[]/{}]` or `mac!()/[]/{}`. - Delimited(DelimSpan, MacDelimiter, TokenStream), - /// Arguments of a key-value attribute - `#[attr = "value"]`. + /// Delimited arguments: `#[attr()/[]/{}]`. + Delimited(DelimArgs), + /// Arguments of a key-value attribute: `#[attr = "value"]`. Eq( /// Span of the `=` token. Span, /// The "value". - MacArgsEq, + AttrArgsEq, ), } -// The RHS of a `MacArgs::Eq` starts out as an expression. Once macro expansion -// is completed, all cases end up either as a literal, which is the form used -// after lowering to HIR, or as an error. +// The RHS of an `AttrArgs::Eq` starts out as an expression. Once macro +// expansion is completed, all cases end up either as a literal, which is the +// form used after lowering to HIR, or as an error. #[derive(Clone, Encodable, Decodable, Debug)] -pub enum MacArgsEq { +pub enum AttrArgsEq { Ast(P<Expr>), Hir(Lit), } -impl MacArgs { - pub fn delim(&self) -> Option<Delimiter> { - match self { - MacArgs::Delimited(_, delim, _) => Some(delim.to_token()), - MacArgs::Empty | MacArgs::Eq(..) => None, - } - } - +impl AttrArgs { pub fn span(&self) -> Option<Span> { match self { - MacArgs::Empty => None, - MacArgs::Delimited(dspan, ..) => Some(dspan.entire()), - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => None, + AttrArgs::Delimited(args) => Some(args.dspan.entire()), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => Some(eq_span.to(expr.span)), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting span: {:?}", lit); } } @@ -1587,39 +1595,29 @@ impl MacArgs { /// Proc macros see these tokens, for example. pub fn inner_tokens(&self) -> TokenStream { match self { - MacArgs::Empty => TokenStream::default(), - MacArgs::Delimited(.., tokens) => tokens.clone(), - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => TokenStream::from_ast(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => TokenStream::default(), + AttrArgs::Delimited(args) => args.tokens.clone(), + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => TokenStream::from_ast(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when getting inner tokens: {:?}", lit) } } } - - /// Whether a macro with these arguments needs a semicolon - /// when used as a standalone item or statement. - pub fn need_semicolon(&self) -> bool { - !matches!(self, MacArgs::Delimited(_, MacDelimiter::Brace, _)) - } } -impl<CTX> HashStable<CTX> for MacArgs +impl<CTX> HashStable<CTX> for AttrArgs where CTX: crate::HashStableContext, { fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { mem::discriminant(self).hash_stable(ctx, hasher); match self { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, delim, tokens) => { - dspan.hash_stable(ctx, hasher); - delim.hash_stable(ctx, hasher); - tokens.hash_stable(ctx, hasher); - } - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => args.hash_stable(ctx, hasher), + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => { unreachable!("hash_stable {:?}", expr); } - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) => { eq_span.hash_stable(ctx, hasher); lit.hash_stable(ctx, hasher); } @@ -1627,6 +1625,34 @@ where } } +/// Delimited arguments, as used in `#[attr()/[]/{}]` or `mac!()/[]/{}`. +#[derive(Clone, Encodable, Decodable, Debug)] +pub struct DelimArgs { + pub dspan: DelimSpan, + pub delim: MacDelimiter, + pub tokens: TokenStream, +} + +impl DelimArgs { + /// Whether a macro with these arguments needs a semicolon + /// when used as a standalone item or statement. + pub fn need_semicolon(&self) -> bool { + !matches!(self, DelimArgs { delim: MacDelimiter::Brace, .. }) + } +} + +impl<CTX> HashStable<CTX> for DelimArgs +where + CTX: crate::HashStableContext, +{ + fn hash_stable(&self, ctx: &mut CTX, hasher: &mut StableHasher) { + let DelimArgs { dspan, delim, tokens } = self; + dspan.hash_stable(ctx, hasher); + delim.hash_stable(ctx, hasher); + tokens.hash_stable(ctx, hasher); + } +} + #[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug, HashStable_Generic)] pub enum MacDelimiter { Parenthesis, @@ -1656,7 +1682,7 @@ impl MacDelimiter { /// Represents a macro definition. #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct MacroDef { - pub body: P<MacArgs>, + pub body: P<DelimArgs>, /// `true` if macro was defined with `macro_rules`. pub macro_rules: bool, } @@ -2006,7 +2032,7 @@ pub enum TyKind { /// "qualified", e.g., `<Vec<T> as SomeTrait>::SomeType`. /// /// Type parameters are stored in the `Path` itself. - Path(Option<QSelf>, Path), + Path(Option<P<QSelf>>, Path), /// A trait object type `Bound1 + Bound2 + Bound3` /// where `Bound` is a trait or a lifetime. TraitObject(GenericBounds, TraitObjectSyntax), @@ -2138,7 +2164,7 @@ impl InlineAsmTemplatePiece { #[derive(Clone, Encodable, Decodable, Debug)] pub struct InlineAsmSym { pub id: NodeId, - pub qself: Option<QSelf>, + pub qself: Option<P<QSelf>>, pub path: Path, } @@ -2378,9 +2404,9 @@ pub enum FnRetTy { impl FnRetTy { pub fn span(&self) -> Span { - match *self { - FnRetTy::Default(span) => span, - FnRetTy::Ty(ref ty) => ty.span, + match self { + &FnRetTy::Default(span) => span, + FnRetTy::Ty(ty) => ty.span, } } } @@ -2519,7 +2545,7 @@ impl<D: Decoder> Decodable<D> for AttrId { #[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)] pub struct AttrItem { pub path: Path, - pub args: MacArgs, + pub args: AttrArgs, pub tokens: Option<LazyAttrTokenStream>, } @@ -2642,14 +2668,14 @@ pub enum VariantData { impl VariantData { /// Return the fields of this variant. pub fn fields(&self) -> &[FieldDef] { - match *self { - VariantData::Struct(ref fields, ..) | VariantData::Tuple(ref fields, _) => fields, + match self { + VariantData::Struct(fields, ..) | VariantData::Tuple(fields, _) => fields, _ => &[], } } /// Return the `NodeId` of this variant's constructor, if it has one. - pub fn ctor_id(&self) -> Option<NodeId> { + pub fn ctor_node_id(&self) -> Option<NodeId> { match *self { VariantData::Struct(..) => None, VariantData::Tuple(_, id) | VariantData::Unit(id) => Some(id), @@ -3031,28 +3057,28 @@ mod size_asserts { static_assert_size!(AssocItemKind, 32); static_assert_size!(Attribute, 32); static_assert_size!(Block, 48); - static_assert_size!(Expr, 104); - static_assert_size!(ExprKind, 72); + static_assert_size!(Expr, 72); + static_assert_size!(ExprKind, 40); static_assert_size!(Fn, 184); static_assert_size!(ForeignItem, 96); static_assert_size!(ForeignItemKind, 24); static_assert_size!(GenericArg, 24); - static_assert_size!(GenericBound, 88); + static_assert_size!(GenericBound, 72); static_assert_size!(Generics, 72); - static_assert_size!(Impl, 200); + static_assert_size!(Impl, 184); static_assert_size!(Item, 184); static_assert_size!(ItemKind, 112); static_assert_size!(Lit, 48); static_assert_size!(LitKind, 24); static_assert_size!(Local, 72); static_assert_size!(Param, 40); - static_assert_size!(Pat, 120); - static_assert_size!(Path, 40); + static_assert_size!(Pat, 88); + static_assert_size!(Path, 24); static_assert_size!(PathSegment, 24); - static_assert_size!(PatKind, 96); + static_assert_size!(PatKind, 64); static_assert_size!(Stmt, 32); static_assert_size!(StmtKind, 16); - static_assert_size!(Ty, 96); - static_assert_size!(TyKind, 72); + static_assert_size!(Ty, 64); + static_assert_size!(TyKind, 40); // tidy-alphabetical-end } diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 07f982b7e86..2f7c7a29492 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,28 +1,27 @@ //! Functions dealing with attributes and meta items. use crate::ast; -use crate::ast::{AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; -use crate::ast::{Lit, LitKind}; -use crate::ast::{MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; +use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; +use crate::ast::{DelimArgs, Lit, LitKind}; +use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Path, PathSegment}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; - use rustc_data_structures::sync::WorkerLocal; use rustc_index::bit_set::GrowableBitSet; use rustc_span::source_map::BytePos; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; - use std::cell::Cell; use std::iter; #[cfg(debug_assertions)] use std::ops::BitXor; #[cfg(debug_assertions)] use std::sync::atomic::{AtomicU32, Ordering}; +use thin_vec::thin_vec; pub struct MarkedAttrs(GrowableBitSet<AttrId>); @@ -45,16 +44,16 @@ impl MarkedAttrs { impl NestedMetaItem { /// Returns the `MetaItem` if `self` is a `NestedMetaItem::MetaItem`. pub fn meta_item(&self) -> Option<&MetaItem> { - match *self { - NestedMetaItem::MetaItem(ref item) => Some(item), + match self { + NestedMetaItem::MetaItem(item) => Some(item), _ => None, } } /// Returns the `Lit` if `self` is a `NestedMetaItem::Literal`s. pub fn literal(&self) -> Option<&Lit> { - match *self { - NestedMetaItem::Literal(ref lit) => Some(lit), + match self { + NestedMetaItem::Literal(lit) => Some(lit), _ => None, } } @@ -117,18 +116,18 @@ impl NestedMetaItem { impl Attribute { #[inline] pub fn has_name(&self, name: Symbol) -> bool { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.path == name, + match &self.kind { + AttrKind::Normal(normal) => normal.item.path == name, AttrKind::DocComment(..) => false, } } /// For a single-segment attribute, returns its name; otherwise, returns `None`. pub fn ident(&self) -> Option<Ident> { - match self.kind { - AttrKind::Normal(ref normal) => { - if normal.item.path.segments.len() == 1 { - Some(normal.item.path.segments[0].ident) + match &self.kind { + AttrKind::Normal(normal) => { + if let [ident] = &*normal.item.path.segments { + Some(ident.ident) } else { None } @@ -141,17 +140,15 @@ impl Attribute { } pub fn value_str(&self) -> Option<Symbol> { - match self.kind { - AttrKind::Normal(ref normal) => { - normal.item.meta_kind().and_then(|kind| kind.value_str()) - } + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta_kind().and_then(|kind| kind.value_str()), AttrKind::DocComment(..) => None, } } pub fn meta_item_list(&self) -> Option<Vec<NestedMetaItem>> { - match self.kind { - AttrKind::Normal(ref normal) => match normal.item.meta_kind() { + match &self.kind { + AttrKind::Normal(normal) => match normal.item.meta_kind() { Some(MetaItemKind::List(list)) => Some(list), _ => None, }, @@ -161,7 +158,7 @@ impl Attribute { pub fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { - matches!(normal.item.args, MacArgs::Empty) + matches!(normal.item.args, AttrArgs::Empty) } else { false } @@ -192,8 +189,8 @@ impl MetaItem { } pub fn meta_item_list(&self) -> Option<&[NestedMetaItem]> { - match self.kind { - MetaItemKind::List(ref l) => Some(&l[..]), + match &self.kind { + MetaItemKind::List(l) => Some(&**l), _ => None, } } @@ -226,13 +223,13 @@ impl AttrItem { pub fn meta(&self, span: Span) -> Option<MetaItem> { Some(MetaItem { path: self.path.clone(), - kind: MetaItemKind::from_mac_args(&self.args)?, + kind: MetaItemKind::from_attr_args(&self.args)?, span, }) } pub fn meta_kind(&self) -> Option<MetaItemKind> { - MetaItemKind::from_mac_args(&self.args) + MetaItemKind::from_attr_args(&self.args) } } @@ -269,9 +266,9 @@ impl Attribute { /// * `#[doc = "doc"]` returns `Some("doc")`. /// * `#[doc(...)]` returns `None`. pub fn doc_str(&self) -> Option<Symbol> { - match self.kind { - AttrKind::DocComment(.., data) => Some(data), - AttrKind::Normal(ref normal) if normal.item.path == sym::doc => { + match &self.kind { + AttrKind::DocComment(.., data) => Some(*data), + AttrKind::Normal(normal) if normal.item.path == sym::doc => { normal.item.meta_kind().and_then(|kind| kind.value_str()) } _ => None, @@ -283,8 +280,8 @@ impl Attribute { } pub fn get_normal_item(&self) -> &AttrItem { - match self.kind { - AttrKind::Normal(ref normal) => &normal.item, + match &self.kind { + AttrKind::Normal(normal) => &normal.item, AttrKind::DocComment(..) => panic!("unexpected doc comment"), } } @@ -298,28 +295,28 @@ impl Attribute { /// Extracts the MetaItem from inside this Attribute. pub fn meta(&self) -> Option<MetaItem> { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.meta(self.span), + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta(self.span), AttrKind::DocComment(..) => None, } } pub fn meta_kind(&self) -> Option<MetaItemKind> { - match self.kind { - AttrKind::Normal(ref normal) => normal.item.meta_kind(), + match &self.kind { + AttrKind::Normal(normal) => normal.item.meta_kind(), AttrKind::DocComment(..) => None, } } pub fn tokens(&self) -> TokenStream { - match self.kind { - AttrKind::Normal(ref normal) => normal + match &self.kind { + AttrKind::Normal(normal) => normal .tokens .as_ref() .unwrap_or_else(|| panic!("attribute is missing tokens: {:?}", self)) .to_attr_token_stream() .to_tokenstream(), - AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( + &AttrKind::DocComment(comment_kind, data) => TokenStream::new(vec![TokenTree::Token( Token::new(token::DocComment(comment_kind, self.style, data), self.span), Spacing::Alone, )]), @@ -393,7 +390,7 @@ pub fn mk_attr( g: &AttrIdGenerator, style: AttrStyle, path: Path, - args: MacArgs, + args: AttrArgs, span: Span, ) -> Attribute { mk_attr_from_item(g, AttrItem { path, args, tokens: None }, None, style, span) @@ -416,12 +413,12 @@ pub fn mk_attr_from_item( /// Returns an inner attribute with the given value and span. pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Inner, item.path, item.kind.mac_args(item.span), item.span) + mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span) } /// Returns an outer attribute with the given value and span. pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Outer, item.path, item.kind.mac_args(item.span), item.span) + mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span) } pub fn mk_doc_comment( @@ -471,12 +468,12 @@ impl MetaItem { tokens.peek() { tokens.next(); - vec![PathSegment::from_ident(Ident::new(name, span))] + thin_vec![PathSegment::from_ident(Ident::new(name, span))] } else { break 'arm Path::from_ident(Ident::new(name, span)); } } else { - vec![PathSegment::path_root(span)] + thin_vec![PathSegment::path_root(span)] }; loop { if let Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }, _)) = @@ -497,17 +494,17 @@ impl MetaItem { let span = span.with_hi(segments.last().unwrap().ident.span.hi()); Path { span, segments, tokens: None } } - Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match *nt { - token::Nonterminal::NtMeta(ref item) => return item.meta(item.path.span), - token::Nonterminal::NtPath(ref path) => (**path).clone(), + Some(TokenTree::Token(Token { kind: token::Interpolated(nt), .. }, _)) => match &*nt { + token::Nonterminal::NtMeta(item) => return item.meta(item.path.span), + token::Nonterminal::NtPath(path) => (**path).clone(), _ => return None, }, _ => return None, }; let list_closing_paren_pos = tokens.peek().map(|tt| tt.span().hi()); let kind = MetaItemKind::from_tokens(tokens)?; - let hi = match kind { - MetaItemKind::NameValue(ref lit) => lit.span.hi(), + let hi = match &kind { + MetaItemKind::NameValue(lit) => lit.span.hi(), MetaItemKind::List(..) => list_closing_paren_pos.unwrap_or(path.span.hi()), _ => path.span.hi(), }; @@ -519,17 +516,17 @@ impl MetaItem { impl MetaItemKind { pub fn value_str(&self) -> Option<Symbol> { match self { - MetaItemKind::NameValue(ref v) => match v.kind { - LitKind::Str(ref s, _) => Some(*s), + MetaItemKind::NameValue(v) => match v.kind { + LitKind::Str(s, _) => Some(s), _ => None, }, _ => None, } } - pub fn mac_args(&self, span: Span) -> MacArgs { + pub fn attr_args(&self, span: Span) -> AttrArgs { match self { - MetaItemKind::Word => MacArgs::Empty, + MetaItemKind::Word => AttrArgs::Empty, MetaItemKind::NameValue(lit) => { let expr = P(ast::Expr { id: ast::DUMMY_NODE_ID, @@ -538,7 +535,7 @@ impl MetaItemKind { attrs: ast::AttrVec::new(), tokens: None, }); - MacArgs::Eq(span, MacArgsEq::Ast(expr)) + AttrArgs::Eq(span, AttrArgsEq::Ast(expr)) } MetaItemKind::List(list) => { let mut tts = Vec::new(); @@ -548,25 +545,25 @@ impl MetaItemKind { } tts.extend(item.token_trees()) } - MacArgs::Delimited( - DelimSpan::from_single(span), - MacDelimiter::Parenthesis, - TokenStream::new(tts), - ) + AttrArgs::Delimited(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: MacDelimiter::Parenthesis, + tokens: TokenStream::new(tts), + }) } } } fn token_trees(&self, span: Span) -> Vec<TokenTree> { - match *self { + match self { MetaItemKind::Word => vec![], - MetaItemKind::NameValue(ref lit) => { + MetaItemKind::NameValue(lit) => { vec![ TokenTree::token_alone(token::Eq, span), TokenTree::Token(lit.to_token(), Spacing::Alone), ] } - MetaItemKind::List(ref list) => { + MetaItemKind::List(list) => { let mut tokens = Vec::new(); for (i, item) in list.iter().enumerate() { if i > 0 { @@ -611,20 +608,22 @@ impl MetaItemKind { } } - fn from_mac_args(args: &MacArgs) -> Option<MetaItemKind> { + fn from_attr_args(args: &AttrArgs) -> Option<MetaItemKind> { match args { - MacArgs::Empty => Some(MetaItemKind::Word), - MacArgs::Delimited(_, MacDelimiter::Parenthesis, tokens) => { - MetaItemKind::list_from_tokens(tokens.clone()) - } - MacArgs::Delimited(..) => None, - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => match expr.kind { + AttrArgs::Empty => Some(MetaItemKind::Word), + AttrArgs::Delimited(DelimArgs { + dspan: _, + delim: MacDelimiter::Parenthesis, + tokens, + }) => MetaItemKind::list_from_tokens(tokens.clone()), + AttrArgs::Delimited(..) => None, + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { ast::ExprKind::Lit(token_lit) => Some(MetaItemKind::NameValue( - Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_mac_args"), + Lit::from_token_lit(token_lit, expr.span).expect("token_lit in from_attr_args"), )), _ => None, }, - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => Some(MetaItemKind::NameValue(lit.clone())), } } @@ -649,16 +648,16 @@ impl MetaItemKind { impl NestedMetaItem { pub fn span(&self) -> Span { - match *self { - NestedMetaItem::MetaItem(ref item) => item.span, - NestedMetaItem::Literal(ref lit) => lit.span, + match self { + NestedMetaItem::MetaItem(item) => item.span, + NestedMetaItem::Literal(lit) => lit.span, } } fn token_trees(&self) -> Vec<TokenTree> { - match *self { - NestedMetaItem::MetaItem(ref item) => item.token_trees(), - NestedMetaItem::Literal(ref lit) => { + match self { + NestedMetaItem::MetaItem(item) => item.token_trees(), + NestedMetaItem::Literal(lit) => { vec![TokenTree::Token(lit.to_token(), Spacing::Alone)] } } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 3ab8267263d..4e1dcb2842f 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -194,7 +194,7 @@ pub trait MutVisitor: Sized { noop_visit_path(p, self); } - fn visit_qself(&mut self, qs: &mut Option<QSelf>) { + fn visit_qself(&mut self, qs: &mut Option<P<QSelf>>) { noop_visit_qself(qs, self); } @@ -367,23 +367,27 @@ pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl, span }: &mut FnSig, vis } // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. -pub fn visit_mac_args<T: MutVisitor>(args: &mut MacArgs, vis: &mut T) { +pub fn visit_attr_args<T: MutVisitor>(args: &mut AttrArgs, vis: &mut T) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(dspan, _delim, tokens) => { - visit_delim_span(dspan, vis); - visit_tts(tokens, vis); - } - MacArgs::Eq(eq_span, MacArgsEq::Ast(expr)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(args) => visit_delim_args(args, vis), + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(expr)) => { vis.visit_span(eq_span); vis.visit_expr(expr); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when visiting mac args eq: {:?}", lit) } } } +// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. +pub fn visit_delim_args<T: MutVisitor>(args: &mut DelimArgs, vis: &mut T) { + let DelimArgs { dspan, delim: _, tokens } = args; + visit_delim_span(dspan, vis); + visit_tts(tokens, vis); +} + pub fn visit_delim_span<T: MutVisitor>(dspan: &mut DelimSpan, vis: &mut T) { vis.visit_span(&mut dspan.open); vis.visit_span(&mut dspan.close); @@ -439,15 +443,15 @@ pub fn noop_visit_constraint<T: MutVisitor>( ) { vis.visit_id(id); vis.visit_ident(ident); - if let Some(ref mut gen_args) = gen_args { + if let Some(gen_args) = gen_args { vis.visit_generic_args(gen_args); } match kind { - AssocConstraintKind::Equality { ref mut term } => match term { + AssocConstraintKind::Equality { term } => match term { Term::Ty(ty) => vis.visit_ty(ty), Term::Const(c) => vis.visit_anon_const(c), }, - AssocConstraintKind::Bound { ref mut bounds } => visit_bounds(bounds, vis), + AssocConstraintKind::Bound { bounds } => visit_bounds(bounds, vis), } vis.visit_span(span); } @@ -529,8 +533,9 @@ pub fn noop_visit_path<T: MutVisitor>(Path { segments, span, tokens }: &mut Path visit_lazy_tts(tokens, vis); } -pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) { - visit_opt(qself, |QSelf { ty, path_span, position: _ }| { +pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<P<QSelf>>, vis: &mut T) { + visit_opt(qself, |qself| { + let QSelf { ty, path_span, position: _ } = &mut **qself; vis.visit_ty(ty); vis.visit_span(path_span); }) @@ -600,7 +605,7 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { let NormalAttr { item: AttrItem { path, args, tokens }, tokens: attr_tokens } = &mut **normal; vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); visit_lazy_tts(attr_tokens, vis); } @@ -612,12 +617,12 @@ pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) { pub fn noop_visit_mac<T: MutVisitor>(mac: &mut MacCall, vis: &mut T) { let MacCall { path, args, prior_type_ascription: _ } = mac; vis.visit_path(path); - visit_mac_args(args, vis); + visit_delim_args(args, vis); } pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) { let MacroDef { body, macro_rules: _ } = macro_def; - visit_mac_args(body, vis); + visit_delim_args(body, vis); } pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) { @@ -791,7 +796,7 @@ pub fn visit_nonterminal<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T token::NtMeta(item) => { let AttrItem { path, args, tokens } = item.deref_mut(); vis.visit_path(path); - visit_mac_args(args, vis); + visit_attr_args(args, vis); visit_lazy_tts(tokens, vis); } token::NtPath(path) => vis.visit_path(path), @@ -879,7 +884,7 @@ pub fn noop_flat_map_generic_param<T: MutVisitor>( let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param; vis.visit_id(id); vis.visit_ident(ident); - if let Some(ref mut colon_span) = colon_span { + if let Some(colon_span) = colon_span { vis.visit_span(colon_span); } visit_attrs(attrs, vis); @@ -1303,12 +1308,17 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_expr(f); visit_exprs(args, vis); } - ExprKind::MethodCall(PathSegment { ident, id, args }, receiver, exprs, span) => { + ExprKind::MethodCall(box MethodCall { + seg: PathSegment { ident, id, args: seg_args }, + receiver, + args: call_args, + span, + }) => { vis.visit_ident(ident); vis.visit_id(id); - visit_opt(args, |args| vis.visit_generic_args(args)); + visit_opt(seg_args, |args| vis.visit_generic_args(args)); vis.visit_method_receiver_expr(receiver); - visit_exprs(exprs, vis); + visit_exprs(call_args, vis); vis.visit_span(span); } ExprKind::Binary(_binop, lhs, rhs) => { @@ -1353,12 +1363,20 @@ pub fn noop_visit_expr<T: MutVisitor>( vis.visit_expr(expr); arms.flat_map_in_place(|arm| vis.flat_map_arm(arm)); } - ExprKind::Closure(binder, _capture_by, asyncness, _movability, decl, body, span) => { + ExprKind::Closure(box Closure { + binder, + capture_clause: _, + asyncness, + movability: _, + fn_decl, + body, + fn_decl_span, + }) => { vis.visit_closure_binder(binder); vis.visit_asyncness(asyncness); - vis.visit_fn_decl(decl); + vis.visit_fn_decl(fn_decl); vis.visit_expr(body); - vis.visit_span(span); + vis.visit_span(fn_decl_span); } ExprKind::Block(blk, label) => { vis.visit_block(blk); diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index e0ff690e766..cb32925584c 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -601,9 +601,10 @@ impl Token { /// Returns `true` if the token is an interpolated path. fn is_path(&self) -> bool { - if let Interpolated(ref nt) = self.kind && let NtPath(..) = **nt { + if let Interpolated(nt) = &self.kind && let NtPath(..) = **nt { return true; } + false } @@ -611,7 +612,7 @@ impl Token { /// That is, is this a pre-parsed expression dropped into the token stream /// (which happens while parsing the result of macro expansion)? pub fn is_whole_expr(&self) -> bool { - if let Interpolated(ref nt) = self.kind + if let Interpolated(nt) = &self.kind && let NtExpr(_) | NtLiteral(_) | NtPath(_) | NtBlock(_) = **nt { return true; @@ -622,9 +623,10 @@ impl Token { // Is the token an interpolated block (`$b:block`)? pub fn is_whole_block(&self) -> bool { - if let Interpolated(ref nt) = self.kind && let NtBlock(..) = **nt { + if let Interpolated(nt) = &self.kind && let NtBlock(..) = **nt { return true; } + false } diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs index 6ea3db6d303..fbb4cf43a95 100644 --- a/compiler/rustc_ast/src/util/classify.rs +++ b/compiler/rustc_ast/src/util/classify.rs @@ -36,7 +36,6 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> { | Binary(_, _, e) | Box(e) | Break(_, Some(e)) - | Closure(.., e, _) | Let(_, e, _) | Range(_, Some(e), _) | Ret(Some(e)) @@ -44,6 +43,9 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> { | Yield(Some(e)) => { expr = e; } + Closure(closure) => { + expr = &closure.body; + } Async(..) | Block(..) | ForLoop(..) | If(..) | Loop(..) | Match(..) | Struct(..) | TryBlock(..) | While(..) => break Some(expr), _ => break None, diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs index b40ad6f700e..f65f1f069cb 100644 --- a/compiler/rustc_ast/src/util/parser.rs +++ b/compiler/rustc_ast/src/util/parser.rs @@ -377,26 +377,26 @@ pub fn needs_par_as_let_scrutinee(order: i8) -> bool { /// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and /// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not. pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool { - match value.kind { + match &value.kind { ast::ExprKind::Struct(..) => true, - ast::ExprKind::Assign(ref lhs, ref rhs, _) - | ast::ExprKind::AssignOp(_, ref lhs, ref rhs) - | ast::ExprKind::Binary(_, ref lhs, ref rhs) => { + ast::ExprKind::Assign(lhs, rhs, _) + | ast::ExprKind::AssignOp(_, lhs, rhs) + | ast::ExprKind::Binary(_, lhs, rhs) => { // X { y: 1 } + X { y: 2 } contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs) } - ast::ExprKind::Await(ref x) - | ast::ExprKind::Unary(_, ref x) - | ast::ExprKind::Cast(ref x, _) - | ast::ExprKind::Type(ref x, _) - | ast::ExprKind::Field(ref x, _) - | ast::ExprKind::Index(ref x, _) => { + ast::ExprKind::Await(x) + | ast::ExprKind::Unary(_, x) + | ast::ExprKind::Cast(x, _) + | ast::ExprKind::Type(x, _) + | ast::ExprKind::Field(x, _) + | ast::ExprKind::Index(x, _) => { // &X { y: 1 }, X { y: 1 }.y contains_exterior_struct_lit(&x) } - ast::ExprKind::MethodCall(_, ref receiver, _, _) => { + ast::ExprKind::MethodCall(box ast::MethodCall { receiver, .. }) => { // X { y: 1 }.bar(...) contains_exterior_struct_lit(&receiver) } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index da0545ce80c..5c69e535212 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -299,74 +299,68 @@ pub fn walk_trait_ref<'a, V: Visitor<'a>>(visitor: &mut V, trait_ref: &'a TraitR pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_vis(&item.vis); visitor.visit_ident(item.ident); - match item.kind { + match &item.kind { ItemKind::ExternCrate(_) => {} - ItemKind::Use(ref use_tree) => visitor.visit_use_tree(use_tree, item.id, false), - ItemKind::Static(ref typ, _, ref expr) | ItemKind::Const(_, ref typ, ref expr) => { + ItemKind::Use(use_tree) => visitor.visit_use_tree(use_tree, item.id, false), + ItemKind::Static(typ, _, expr) | ItemKind::Const(_, typ, expr) => { visitor.visit_ty(typ); walk_list!(visitor, visit_expr, expr); } - ItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + ItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Free, item.ident, sig, &item.vis, generics, body.as_deref()); visitor.visit_fn(kind, item.span, item.id) } - ItemKind::Mod(_unsafety, ref mod_kind) => match mod_kind { + ItemKind::Mod(_unsafety, mod_kind) => match mod_kind { ModKind::Loaded(items, _inline, _inner_span) => { walk_list!(visitor, visit_item, items) } ModKind::Unloaded => {} }, - ItemKind::ForeignMod(ref foreign_module) => { + ItemKind::ForeignMod(foreign_module) => { walk_list!(visitor, visit_foreign_item, &foreign_module.items); } - ItemKind::GlobalAsm(ref asm) => visitor.visit_inline_asm(asm), - ItemKind::TyAlias(box TyAlias { ref generics, ref bounds, ref ty, .. }) => { + ItemKind::GlobalAsm(asm) => visitor.visit_inline_asm(asm), + ItemKind::TyAlias(box TyAlias { generics, bounds, ty, .. }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_ty, ty); } - ItemKind::Enum(ref enum_definition, ref generics) => { + ItemKind::Enum(enum_definition, generics) => { visitor.visit_generics(generics); visitor.visit_enum_def(enum_definition) } ItemKind::Impl(box Impl { defaultness: _, unsafety: _, - ref generics, + generics, constness: _, polarity: _, - ref of_trait, - ref self_ty, - ref items, + of_trait, + self_ty, + items, }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_trait_ref, of_trait); visitor.visit_ty(self_ty); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Impl); } - ItemKind::Struct(ref struct_definition, ref generics) - | ItemKind::Union(ref struct_definition, ref generics) => { + ItemKind::Struct(struct_definition, generics) + | ItemKind::Union(struct_definition, generics) => { visitor.visit_generics(generics); visitor.visit_variant_data(struct_definition); } - ItemKind::Trait(box Trait { - unsafety: _, - is_auto: _, - ref generics, - ref bounds, - ref items, - }) => { + ItemKind::Trait(box Trait { unsafety: _, is_auto: _, generics, bounds, items }) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::SuperTraits); walk_list!(visitor, visit_assoc_item, items, AssocCtxt::Trait); } - ItemKind::TraitAlias(ref generics, ref bounds) => { + ItemKind::TraitAlias(generics, bounds) => { visitor.visit_generics(generics); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - ItemKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - ItemKind::MacroDef(ref ts) => visitor.visit_mac_def(ts, item.id), + ItemKind::MacCall(mac) => visitor.visit_mac_call(mac), + ItemKind::MacroDef(ts) => visitor.visit_mac_def(ts, item.id), } walk_list!(visitor, visit_attribute, &item.attrs); } @@ -399,39 +393,39 @@ pub fn walk_pat_field<'a, V: Visitor<'a>>(visitor: &mut V, fp: &'a PatField) { } pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) { - match typ.kind { - TyKind::Slice(ref ty) | TyKind::Paren(ref ty) => visitor.visit_ty(ty), - TyKind::Ptr(ref mutable_type) => visitor.visit_ty(&mutable_type.ty), - TyKind::Rptr(ref opt_lifetime, ref mutable_type) => { + match &typ.kind { + TyKind::Slice(ty) | TyKind::Paren(ty) => visitor.visit_ty(ty), + TyKind::Ptr(mutable_type) => visitor.visit_ty(&mutable_type.ty), + TyKind::Rptr(opt_lifetime, mutable_type) => { walk_list!(visitor, visit_lifetime, opt_lifetime, LifetimeCtxt::Rptr); visitor.visit_ty(&mutable_type.ty) } - TyKind::Tup(ref tuple_element_types) => { + TyKind::Tup(tuple_element_types) => { walk_list!(visitor, visit_ty, tuple_element_types); } - TyKind::BareFn(ref function_declaration) => { + TyKind::BareFn(function_declaration) => { walk_list!(visitor, visit_generic_param, &function_declaration.generic_params); walk_fn_decl(visitor, &function_declaration.decl); } - TyKind::Path(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { + TyKind::Path(maybe_qself, path) => { + if let Some(qself) = maybe_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, typ.id); } - TyKind::Array(ref ty, ref length) => { + TyKind::Array(ty, length) => { visitor.visit_ty(ty); visitor.visit_anon_const(length) } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::TraitObject); } - TyKind::ImplTrait(_, ref bounds) => { + TyKind::ImplTrait(_, bounds) => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl); } - TyKind::Typeof(ref expression) => visitor.visit_anon_const(expression), + TyKind::Typeof(expression) => visitor.visit_anon_const(expression), TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {} - TyKind::MacCall(ref mac) => visitor.visit_mac_call(mac), + TyKind::MacCall(mac) => visitor.visit_mac_call(mac), TyKind::Never | TyKind::CVarArgs => {} } } @@ -444,15 +438,15 @@ pub fn walk_path<'a, V: Visitor<'a>>(visitor: &mut V, path: &'a Path) { pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, id: NodeId) { visitor.visit_path(&use_tree.prefix, id); - match use_tree.kind { + match &use_tree.kind { UseTreeKind::Simple(rename, ..) => { // The extra IDs are handled during HIR lowering. - if let Some(rename) = rename { + if let &Some(rename) = rename { visitor.visit_ident(rename); } } UseTreeKind::Glob => {} - UseTreeKind::Nested(ref use_trees) => { + UseTreeKind::Nested(use_trees) => { for &(ref nested_tree, nested_id) in use_trees { visitor.visit_use_tree(nested_tree, nested_id, true); } @@ -462,7 +456,7 @@ pub fn walk_use_tree<'a, V: Visitor<'a>>(visitor: &mut V, use_tree: &'a UseTree, pub fn walk_path_segment<'a, V: Visitor<'a>>(visitor: &mut V, segment: &'a PathSegment) { visitor.visit_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { visitor.visit_generic_args(args); } } @@ -471,8 +465,8 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, generic_args: &'a GenericArgs) where V: Visitor<'a>, { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { + match generic_args { + GenericArgs::AngleBracketed(data) => { for arg in &data.args { match arg { AngleBracketedArg::Arg(a) => visitor.visit_generic_arg(a), @@ -480,7 +474,7 @@ where } } } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { walk_list!(visitor, visit_ty, &data.inputs); walk_fn_ret_ty(visitor, &data.output); } @@ -500,64 +494,64 @@ where pub fn walk_assoc_constraint<'a, V: Visitor<'a>>(visitor: &mut V, constraint: &'a AssocConstraint) { visitor.visit_ident(constraint.ident); - if let Some(ref gen_args) = constraint.gen_args { + if let Some(gen_args) = &constraint.gen_args { visitor.visit_generic_args(gen_args); } - match constraint.kind { - AssocConstraintKind::Equality { ref term } => match term { + match &constraint.kind { + AssocConstraintKind::Equality { term } => match term { Term::Ty(ty) => visitor.visit_ty(ty), Term::Const(c) => visitor.visit_anon_const(c), }, - AssocConstraintKind::Bound { ref bounds } => { + AssocConstraintKind::Bound { bounds } => { walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } } } pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { - match pattern.kind { - PatKind::TupleStruct(ref opt_qself, ref path, ref elems) => { - if let Some(ref qself) = *opt_qself { + match &pattern.kind { + PatKind::TupleStruct(opt_qself, path, elems) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id); walk_list!(visitor, visit_pat, elems); } - PatKind::Path(ref opt_qself, ref path) => { - if let Some(ref qself) = *opt_qself { + PatKind::Path(opt_qself, path) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id) } - PatKind::Struct(ref opt_qself, ref path, ref fields, _) => { - if let Some(ref qself) = *opt_qself { + PatKind::Struct(opt_qself, path, fields, _) => { + if let Some(qself) = opt_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, pattern.id); walk_list!(visitor, visit_pat_field, fields); } - PatKind::Box(ref subpattern) - | PatKind::Ref(ref subpattern, _) - | PatKind::Paren(ref subpattern) => visitor.visit_pat(subpattern), - PatKind::Ident(_, ident, ref optional_subpattern) => { - visitor.visit_ident(ident); + PatKind::Box(subpattern) | PatKind::Ref(subpattern, _) | PatKind::Paren(subpattern) => { + visitor.visit_pat(subpattern) + } + PatKind::Ident(_, ident, optional_subpattern) => { + visitor.visit_ident(*ident); walk_list!(visitor, visit_pat, optional_subpattern); } - PatKind::Lit(ref expression) => visitor.visit_expr(expression), - PatKind::Range(ref lower_bound, ref upper_bound, _) => { + PatKind::Lit(expression) => visitor.visit_expr(expression), + PatKind::Range(lower_bound, upper_bound, _) => { walk_list!(visitor, visit_expr, lower_bound); walk_list!(visitor, visit_expr, upper_bound); } PatKind::Wild | PatKind::Rest => {} - PatKind::Tuple(ref elems) | PatKind::Slice(ref elems) | PatKind::Or(ref elems) => { + PatKind::Tuple(elems) | PatKind::Slice(elems) | PatKind::Or(elems) => { walk_list!(visitor, visit_pat, elems); } - PatKind::MacCall(ref mac) => visitor.visit_mac_call(mac), + PatKind::MacCall(mac) => visitor.visit_mac_call(mac), } } pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignItem) { - let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; + let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; visitor.visit_vis(vis); visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); @@ -566,7 +560,7 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - ForeignItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + ForeignItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Foreign, ident, sig, vis, generics, body.as_deref()); visitor.visit_fn(kind, span, id); } @@ -582,11 +576,9 @@ pub fn walk_foreign_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a ForeignI } pub fn walk_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a GenericBound) { - match *bound { - GenericBound::Trait(ref typ, ref _modifier) => visitor.visit_poly_trait_ref(typ), - GenericBound::Outlives(ref lifetime) => { - visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound) - } + match bound { + GenericBound::Trait(typ, _modifier) => visitor.visit_poly_trait_ref(typ), + GenericBound::Outlives(lifetime) => visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound), } } @@ -594,10 +586,10 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi visitor.visit_ident(param.ident); walk_list!(visitor, visit_attribute, param.attrs.iter()); walk_list!(visitor, visit_param_bound, ¶m.bounds, BoundKind::Bound); - match param.kind { + match ¶m.kind { GenericParamKind::Lifetime => (), - GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default), - GenericParamKind::Const { ref ty, ref default, .. } => { + GenericParamKind::Type { default } => walk_list!(visitor, visit_ty, default), + GenericParamKind::Const { ty, default, .. } => { visitor.visit_ty(ty); if let Some(default) = default { visitor.visit_anon_const(default); @@ -621,24 +613,22 @@ pub fn walk_closure_binder<'a, V: Visitor<'a>>(visitor: &mut V, binder: &'a Clos } pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a WherePredicate) { - match *predicate { + match predicate { WherePredicate::BoundPredicate(WhereBoundPredicate { - ref bounded_ty, - ref bounds, - ref bound_generic_params, + bounded_ty, + bounds, + bound_generic_params, .. }) => { visitor.visit_ty(bounded_ty); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); walk_list!(visitor, visit_generic_param, bound_generic_params); } - WherePredicate::RegionPredicate(WhereRegionPredicate { - ref lifetime, ref bounds, .. - }) => { + WherePredicate::RegionPredicate(WhereRegionPredicate { lifetime, bounds, .. }) => { visitor.visit_lifetime(lifetime, LifetimeCtxt::Bound); walk_list!(visitor, visit_param_bound, bounds, BoundKind::Bound); } - WherePredicate::EqPredicate(WhereEqPredicate { ref lhs_ty, ref rhs_ty, .. }) => { + WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, .. }) => { visitor.visit_ty(lhs_ty); visitor.visit_ty(rhs_ty); } @@ -646,7 +636,7 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a } pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) { - if let FnRetTy::Ty(ref output_ty) = *ret_ty { + if let FnRetTy::Ty(output_ty) = ret_ty { visitor.visit_ty(output_ty) } } @@ -675,7 +665,7 @@ pub fn walk_fn<'a, V: Visitor<'a>>(visitor: &mut V, kind: FnKind<'a>) { } pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, ctxt: AssocCtxt) { - let Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = *item; + let &Item { id, span, ident, ref vis, ref attrs, ref kind, tokens: _ } = item; visitor.visit_vis(vis); visitor.visit_ident(ident); walk_list!(visitor, visit_attribute, attrs); @@ -684,7 +674,7 @@ pub fn walk_assoc_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a AssocItem, visitor.visit_ty(ty); walk_list!(visitor, visit_expr, expr); } - AssocItemKind::Fn(box Fn { defaultness: _, ref generics, ref sig, ref body }) => { + AssocItemKind::Fn(box Fn { defaultness: _, generics, sig, body }) => { let kind = FnKind::Fn(FnCtxt::Assoc(ctxt), ident, sig, vis, generics, body.as_deref()); visitor.visit_fn(kind, span, id); } @@ -717,13 +707,13 @@ pub fn walk_block<'a, V: Visitor<'a>>(visitor: &mut V, block: &'a Block) { } pub fn walk_stmt<'a, V: Visitor<'a>>(visitor: &mut V, statement: &'a Stmt) { - match statement.kind { - StmtKind::Local(ref local) => visitor.visit_local(local), - StmtKind::Item(ref item) => visitor.visit_item(item), - StmtKind::Expr(ref expr) | StmtKind::Semi(ref expr) => visitor.visit_expr(expr), + match &statement.kind { + StmtKind::Local(local) => visitor.visit_local(local), + StmtKind::Item(item) => visitor.visit_item(item), + StmtKind::Expr(expr) | StmtKind::Semi(expr) => visitor.visit_expr(expr), StmtKind::Empty => {} - StmtKind::MacCall(ref mac) => { - let MacCallStmt { ref mac, style: _, ref attrs, tokens: _ } = **mac; + StmtKind::MacCall(mac) => { + let MacCallStmt { mac, attrs, style: _, tokens: _ } = &**mac; visitor.visit_mac_call(mac); for attr in attrs.iter() { visitor.visit_attribute(attr); @@ -760,7 +750,7 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) } pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) { - if let Some(ref qself) = sym.qself { + if let Some(qself) = &sym.qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(&sym.path, sym.id); @@ -769,18 +759,18 @@ pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineA pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { walk_list!(visitor, visit_attribute, expression.attrs.iter()); - match expression.kind { - ExprKind::Box(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::Array(ref subexpressions) => { + match &expression.kind { + ExprKind::Box(subexpression) => visitor.visit_expr(subexpression), + ExprKind::Array(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::ConstBlock(ref anon_const) => visitor.visit_anon_const(anon_const), - ExprKind::Repeat(ref element, ref count) => { + ExprKind::ConstBlock(anon_const) => visitor.visit_anon_const(anon_const), + ExprKind::Repeat(element, count) => { visitor.visit_expr(element); visitor.visit_anon_const(count) } - ExprKind::Struct(ref se) => { - if let Some(ref qself) = se.qself { + ExprKind::Struct(se) => { + if let Some(qself) = &se.qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(&se.path, expression.id); @@ -791,116 +781,124 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { StructRest::None => {} } } - ExprKind::Tup(ref subexpressions) => { + ExprKind::Tup(subexpressions) => { walk_list!(visitor, visit_expr, subexpressions); } - ExprKind::Call(ref callee_expression, ref arguments) => { + ExprKind::Call(callee_expression, arguments) => { visitor.visit_expr(callee_expression); walk_list!(visitor, visit_expr, arguments); } - ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _span) => { - visitor.visit_path_segment(segment); + ExprKind::MethodCall(box MethodCall { seg, receiver, args, span: _ }) => { + visitor.visit_path_segment(seg); visitor.visit_expr(receiver); - walk_list!(visitor, visit_expr, arguments); + walk_list!(visitor, visit_expr, args); } - ExprKind::Binary(_, ref left_expression, ref right_expression) => { + ExprKind::Binary(_, left_expression, right_expression) => { visitor.visit_expr(left_expression); visitor.visit_expr(right_expression) } - ExprKind::AddrOf(_, _, ref subexpression) | ExprKind::Unary(_, ref subexpression) => { + ExprKind::AddrOf(_, _, subexpression) | ExprKind::Unary(_, subexpression) => { visitor.visit_expr(subexpression) } - ExprKind::Cast(ref subexpression, ref typ) | ExprKind::Type(ref subexpression, ref typ) => { + ExprKind::Cast(subexpression, typ) | ExprKind::Type(subexpression, typ) => { visitor.visit_expr(subexpression); visitor.visit_ty(typ) } - ExprKind::Let(ref pat, ref expr, _) => { + ExprKind::Let(pat, expr, _) => { visitor.visit_pat(pat); visitor.visit_expr(expr); } - ExprKind::If(ref head_expression, ref if_block, ref optional_else) => { + ExprKind::If(head_expression, if_block, optional_else) => { visitor.visit_expr(head_expression); visitor.visit_block(if_block); walk_list!(visitor, visit_expr, optional_else); } - ExprKind::While(ref subexpression, ref block, ref opt_label) => { + ExprKind::While(subexpression, block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_expr(subexpression); visitor.visit_block(block); } - ExprKind::ForLoop(ref pattern, ref subexpression, ref block, ref opt_label) => { + ExprKind::ForLoop(pattern, subexpression, block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_pat(pattern); visitor.visit_expr(subexpression); visitor.visit_block(block); } - ExprKind::Loop(ref block, ref opt_label) => { + ExprKind::Loop(block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); } - ExprKind::Match(ref subexpression, ref arms) => { + ExprKind::Match(subexpression, arms) => { visitor.visit_expr(subexpression); walk_list!(visitor, visit_arm, arms); } - ExprKind::Closure(ref binder, _, _, _, ref decl, ref body, _decl_span) => { - visitor.visit_fn(FnKind::Closure(binder, decl, body), expression.span, expression.id) + ExprKind::Closure(box Closure { + binder, + capture_clause: _, + asyncness: _, + movability: _, + fn_decl, + body, + fn_decl_span: _, + }) => { + visitor.visit_fn(FnKind::Closure(binder, fn_decl, body), expression.span, expression.id) } - ExprKind::Block(ref block, ref opt_label) => { + ExprKind::Block(block, opt_label) => { walk_list!(visitor, visit_label, opt_label); visitor.visit_block(block); } - ExprKind::Async(_, _, ref body) => { + ExprKind::Async(_, _, body) => { visitor.visit_block(body); } - ExprKind::Await(ref expr) => visitor.visit_expr(expr), - ExprKind::Assign(ref lhs, ref rhs, _) => { + ExprKind::Await(expr) => visitor.visit_expr(expr), + ExprKind::Assign(lhs, rhs, _) => { visitor.visit_expr(lhs); visitor.visit_expr(rhs); } - ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { + ExprKind::AssignOp(_, left_expression, right_expression) => { visitor.visit_expr(left_expression); visitor.visit_expr(right_expression); } - ExprKind::Field(ref subexpression, ident) => { + ExprKind::Field(subexpression, ident) => { visitor.visit_expr(subexpression); - visitor.visit_ident(ident); + visitor.visit_ident(*ident); } - ExprKind::Index(ref main_expression, ref index_expression) => { + ExprKind::Index(main_expression, index_expression) => { visitor.visit_expr(main_expression); visitor.visit_expr(index_expression) } - ExprKind::Range(ref start, ref end, _) => { + ExprKind::Range(start, end, _) => { walk_list!(visitor, visit_expr, start); walk_list!(visitor, visit_expr, end); } ExprKind::Underscore => {} - ExprKind::Path(ref maybe_qself, ref path) => { - if let Some(ref qself) = *maybe_qself { + ExprKind::Path(maybe_qself, path) => { + if let Some(qself) = maybe_qself { visitor.visit_ty(&qself.ty); } visitor.visit_path(path, expression.id) } - ExprKind::Break(ref opt_label, ref opt_expr) => { + ExprKind::Break(opt_label, opt_expr) => { walk_list!(visitor, visit_label, opt_label); walk_list!(visitor, visit_expr, opt_expr); } - ExprKind::Continue(ref opt_label) => { + ExprKind::Continue(opt_label) => { walk_list!(visitor, visit_label, opt_label); } - ExprKind::Ret(ref optional_expression) => { + ExprKind::Ret(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::Yeet(ref optional_expression) => { + ExprKind::Yeet(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::MacCall(ref mac) => visitor.visit_mac_call(mac), - ExprKind::Paren(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::InlineAsm(ref asm) => visitor.visit_inline_asm(asm), - ExprKind::Yield(ref optional_expression) => { + ExprKind::MacCall(mac) => visitor.visit_mac_call(mac), + ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression), + ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm), + ExprKind::Yield(optional_expression) => { walk_list!(visitor, visit_expr, optional_expression); } - ExprKind::Try(ref subexpression) => visitor.visit_expr(subexpression), - ExprKind::TryBlock(ref body) => visitor.visit_block(body), + ExprKind::Try(subexpression) => visitor.visit_expr(subexpression), + ExprKind::TryBlock(body) => visitor.visit_block(body), ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {} } @@ -927,18 +925,18 @@ pub fn walk_vis<'a, V: Visitor<'a>>(visitor: &mut V, vis: &'a Visibility) { } pub fn walk_attribute<'a, V: Visitor<'a>>(visitor: &mut V, attr: &'a Attribute) { - match attr.kind { - AttrKind::Normal(ref normal) => walk_mac_args(visitor, &normal.item.args), + match &attr.kind { + AttrKind::Normal(normal) => walk_attr_args(visitor, &normal.item.args), AttrKind::DocComment(..) => {} } } -pub fn walk_mac_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a MacArgs) { +pub fn walk_attr_args<'a, V: Visitor<'a>>(visitor: &mut V, args: &'a AttrArgs) { match args { - MacArgs::Empty => {} - MacArgs::Delimited(_dspan, _delim, _tokens) => {} - MacArgs::Eq(_eq_span, MacArgsEq::Ast(expr)) => visitor.visit_expr(expr), - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Empty => {} + AttrArgs::Delimited(_) => {} + AttrArgs::Eq(_eq_span, AttrArgsEq::Ast(expr)) => visitor.visit_expr(expr), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { unreachable!("in literal form when walking mac args eq: {:?}", lit) } } diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 450cdf246b1..db0d8b08a94 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -11,7 +11,7 @@ use super::LoweringContext; use rustc_ast::ptr::P; use rustc_ast::*; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::definitions::DefPathData; @@ -71,7 +71,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .emit(); } - let mut clobber_abis = FxHashMap::default(); + let mut clobber_abis = FxIndexMap::default(); if let Some(asm_arch) = asm_arch { for (abi_name, abi_span) in &asm.clobber_abis { match asm::InlineAsmClobberAbi::parse(asm_arch, &self.tcx.sess.target, *abi_name) { diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 01716859a9d..6855344356a 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -61,7 +61,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::Call(f, self.lower_exprs(args)) } } - ExprKind::MethodCall(ref seg, ref receiver, ref args, span) => { + ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, span }) => { let hir_seg = self.arena.alloc(self.lower_path_segment( e.span, seg, @@ -172,22 +172,22 @@ impl<'hir> LoweringContext<'_, 'hir> { }; self.lower_expr_await(dot_await_span, expr) } - ExprKind::Closure( + ExprKind::Closure(box Closure { ref binder, capture_clause, asyncness, movability, - ref decl, + ref fn_decl, ref body, fn_decl_span, - ) => { + }) => { if let Async::Yes { closure_id, .. } = asyncness { self.lower_expr_async_closure( binder, capture_clause, e.id, closure_id, - decl, + fn_decl, body, fn_decl_span, ) @@ -197,7 +197,7 @@ impl<'hir> LoweringContext<'_, 'hir> { capture_clause, e.id, movability, - decl, + fn_decl, body, fn_decl_span, ) @@ -588,17 +588,12 @@ impl<'hir> LoweringContext<'_, 'hir> { &mut self, capture_clause: CaptureBy, closure_node_id: NodeId, - ret_ty: Option<AstP<Ty>>, + ret_ty: Option<hir::FnRetTy<'hir>>, span: Span, async_gen_kind: hir::AsyncGeneratorKind, body: impl FnOnce(&mut Self) -> hir::Expr<'hir>, ) -> hir::ExprKind<'hir> { - let output = match ret_ty { - Some(ty) => hir::FnRetTy::Return( - self.lower_ty(&ty, &ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock)), - ), - None => hir::FnRetTy::DefaultReturn(self.lower_span(span)), - }; + let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span))); // Resume argument type. We let the compiler infer this to simplify the lowering. It is // fully constrained by `future::from_generator`. @@ -671,7 +666,7 @@ impl<'hir> LoweringContext<'_, 'hir> { kind: AttrKind::Normal(ptr::P(NormalAttr { item: AttrItem { path: Path::from_ident(Ident::new(sym::track_caller, span)), - args: MacArgs::Empty, + args: AttrArgs::Empty, tokens: None, }, tokens: None, @@ -1003,8 +998,13 @@ impl<'hir> LoweringContext<'_, 'hir> { // Transform `async |x: u8| -> X { ... }` into // `|x: u8| future_from_generator(|| -> X { ... })`. let body_id = this.lower_fn_body(&outer_decl, |this| { - let async_ret_ty = - if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; + let async_ret_ty = if let FnRetTy::Ty(ty) = &decl.output { + let itctx = ImplTraitContext::Disallowed(ImplTraitPosition::AsyncBlock); + Some(hir::FnRetTy::Return(this.lower_ty(&ty, &itctx))) + } else { + None + }; + let async_body = this.make_async_expr( capture_clause, inner_closure_id, @@ -1105,7 +1105,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_tuple_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a tuple struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { @@ -1125,7 +1125,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn extract_unit_struct_path<'a>( &mut self, expr: &'a Expr, - ) -> Option<(&'a Option<QSelf>, &'a Path)> { + ) -> Option<(&'a Option<AstP<QSelf>>, &'a Path)> { if let ExprKind::Path(qself, path) = &expr.kind { // Does the path resolve to something disallowed in a unit struct/variant pattern? if let Some(partial_res) = self.resolver.get_partial_res(expr.id) { diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 795ad113ef2..99b3ac864dd 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -6,7 +6,6 @@ use super::{FnDeclKind, LoweringContext, ParamMode}; use rustc_ast::ptr::P; use rustc_ast::visit::AssocCtxt; use rustc_ast::*; -use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sorted_map::SortedMap; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -20,8 +19,8 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi; use smallvec::{smallvec, SmallVec}; - use std::iter; +use thin_vec::ThinVec; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, @@ -67,7 +66,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { // HirId handling. bodies: Vec::new(), attrs: SortedMap::default(), - children: FxHashMap::default(), + children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, item_local_id_counter: hir::ItemLocalId::new(0), node_id_to_local_id: Default::default(), @@ -243,7 +242,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name), ItemKind::Use(ref use_tree) => { // Start with an empty prefix. - let prefix = Path { segments: vec![], span: use_tree.span, tokens: None }; + let prefix = Path { segments: ThinVec::new(), span: use_tree.span, tokens: None }; self.lower_use_tree(use_tree, &prefix, id, vis_span, ident, attrs) } @@ -471,7 +470,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ItemKind::TraitAlias(generics, bounds) } ItemKind::MacroDef(MacroDef { ref body, macro_rules }) => { - let body = P(self.lower_mac_args(body)); + let body = P(self.lower_delim_args(body)); let macro_kind = self.resolver.decl_macro_kind(self.local_def_id(id)); hir::ItemKind::Macro(ast::MacroDef { body, macro_rules }, macro_kind) } @@ -534,12 +533,12 @@ impl<'hir> LoweringContext<'_, 'hir> { for new_node_id in [id1, id2] { let new_id = self.local_def_id(new_node_id); let Some(res) = resolutions.next() else { + debug_assert!(self.children.iter().find(|(id, _)| id == &new_id).is_none()); // Associate an HirId to both ids even if there is no resolution. - let _old = self.children.insert( + self.children.push(( new_id, - hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)), + hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id))), ); - debug_assert!(_old.is_none()); continue; }; let ident = *ident; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 5ab75b1294b..bd1876d4284 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -34,7 +34,6 @@ #![feature(let_chains)] #![feature(never_type)] #![recursion_limit = "256"] -#![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -61,8 +60,8 @@ 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_middle::{bug, span_bug}; use rustc_session::parse::feature_err; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; @@ -107,7 +106,7 @@ struct LoweringContext<'a, 'hir> { /// Attributes inside the owner being lowered. attrs: SortedMap<hir::ItemLocalId, &'hir [Attribute]>, /// Collect items that were created by lowering the current owner. - children: FxHashMap<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>, + children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>, generator_kind: Option<hir::GeneratorKind>, @@ -611,8 +610,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.impl_trait_defs = current_impl_trait_defs; self.impl_trait_bounds = current_impl_trait_bounds; - let _old = self.children.insert(def_id, hir::MaybeOwner::Owner(info)); - debug_assert!(_old.is_none()) + debug_assert!(self.children.iter().find(|(id, _)| id == &def_id).is_none()); + self.children.push((def_id, hir::MaybeOwner::Owner(info))); } /// Installs the remapping `remap` in scope while `f` is being executed. @@ -719,8 +718,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { assert_ne!(local_id, hir::ItemLocalId::new(0)); if let Some(def_id) = self.opt_local_def_id(ast_node_id) { - // Do not override a `MaybeOwner::Owner` that may already here. - self.children.entry(def_id).or_insert(hir::MaybeOwner::NonOwner(hir_id)); + self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); self.local_id_to_def_id.insert(local_id, def_id); } @@ -913,7 +911,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AttrKind::Normal(ref normal) => AttrKind::Normal(P(NormalAttr { item: AttrItem { path: normal.item.path.clone(), - args: self.lower_mac_args(&normal.item.args), + args: self.lower_attr_args(&normal.item.args), tokens: None, }, tokens: None, @@ -933,32 +931,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } } - fn lower_mac_args(&self, args: &MacArgs) -> MacArgs { + fn lower_attr_args(&self, args: &AttrArgs) -> AttrArgs { match *args { - MacArgs::Empty => MacArgs::Empty, - MacArgs::Delimited(dspan, delim, ref tokens) => { - // This is either a non-key-value attribute, or a `macro_rules!` body. - // We either not have any nonterminals present (in the case of an attribute), - // or have tokens available for all nonterminals in the case of a nested - // `macro_rules`: e.g: - // - // ```rust - // macro_rules! outer { - // ($e:expr) => { - // macro_rules! inner { - // () => { $e } - // } - // } - // } - // ``` - // - // In both cases, we don't want to synthesize any tokens - MacArgs::Delimited(dspan, delim, tokens.flattened()) - } + AttrArgs::Empty => AttrArgs::Empty, + AttrArgs::Delimited(ref args) => AttrArgs::Delimited(self.lower_delim_args(args)), // This is an inert key-value attribute - it will never be visible to macros // after it gets lowered to HIR. Therefore, we can extract literals to handle // nonterminals in `#[doc]` (e.g. `#[doc = $e]`). - MacArgs::Eq(eq_span, MacArgsEq::Ast(ref expr)) => { + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(ref expr)) => { // In valid code the value always ends up as a single literal. Otherwise, a dummy // literal suffices because the error is handled elsewhere. let lit = if let ExprKind::Lit(token_lit) = expr.kind { @@ -977,14 +957,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { span: DUMMY_SP, } }; - MacArgs::Eq(eq_span, MacArgsEq::Hir(lit)) + AttrArgs::Eq(eq_span, AttrArgsEq::Hir(lit)) } - MacArgs::Eq(_, MacArgsEq::Hir(ref lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(ref lit)) => { unreachable!("in literal form when lowering mac args eq: {:?}", lit) } } } + fn lower_delim_args(&self, args: &DelimArgs) -> DelimArgs { + DelimArgs { dspan: args.dspan, delim: args.delim, tokens: args.tokens.flattened() } + } + /// Given an associated type constraint like one of these: /// /// ```ignore (illustrative) @@ -1210,7 +1194,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_path_ty( &mut self, t: &Ty, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, path: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, @@ -1467,17 +1451,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // frequently opened issues show. let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::OpaqueTy, span, None); - let opaque_ty_def_id = match origin { - hir::OpaqueTyOrigin::TyAlias => self.create_def( - self.current_hir_id_owner.def_id, - opaque_ty_node_id, - DefPathData::ImplTrait, - ), - hir::OpaqueTyOrigin::FnReturn(fn_def_id) => { - self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait) - } - hir::OpaqueTyOrigin::AsyncFn(..) => bug!("unreachable"), - }; + let opaque_ty_def_id = self.create_def( + self.current_hir_id_owner.def_id, + opaque_ty_node_id, + DefPathData::ImplTrait, + ); debug!(?opaque_ty_def_id); // Contains the new lifetime definitions created for the TAIT (if any). @@ -1839,9 +1817,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let opaque_ty_span = self.mark_span_with_reason(DesugaringKind::Async, span, None); - let opaque_ty_def_id = self.local_def_id(opaque_ty_node_id); let fn_def_id = self.local_def_id(fn_node_id); + let opaque_ty_def_id = + self.create_def(fn_def_id, opaque_ty_node_id, DefPathData::ImplTrait); + // When we create the opaque type for this async fn, it is going to have // to capture all the lifetimes involved in the signature (including in the // return type). This is done by introducing lifetime parameters for: diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index c6955741fd4..83d459d899b 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -19,7 +19,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { pub(crate) fn lower_qpath( &mut self, id: NodeId, - qself: &Option<QSelf>, + qself: &Option<ptr::P<QSelf>>, p: &Path, param_mode: ParamMode, itctx: &ImplTraitContext, diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 5f01f555b30..991f6e0ba22 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -11,10 +11,9 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser; -use rustc_ast::{self as ast, BlockCheckMode, Mutability, PatKind, RangeEnd, RangeSyntax}; -use rustc_ast::{attr, BindingAnnotation, ByRef, Term}; -use rustc_ast::{GenericArg, MacArgs, MacArgsEq}; -use rustc_ast::{GenericBound, SelfKind, TraitBoundModifier}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, Mutability, PatKind}; +use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; +use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_span::edition::Edition; @@ -466,26 +465,26 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere fn print_attr_item(&mut self, item: &ast::AttrItem, span: Span) { self.ibox(0); match &item.args { - MacArgs::Delimited(_, delim, tokens) => self.print_mac_common( + AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self.print_mac_common( Some(MacHeader::Path(&item.path)), false, None, - Some(delim.to_token()), + delim.to_token(), tokens, true, span, ), - MacArgs::Empty => { + AttrArgs::Empty => { self.print_path(&item.path, false, 0); } - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => { + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); let token_str = self.expr_to_string(expr); self.word(token_str); } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => { + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); @@ -544,7 +543,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere None, false, None, - Some(*delim), + *delim, tts, convert_dollar_crate, dspan.entire(), @@ -570,12 +569,12 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere header: Option<MacHeader<'_>>, has_bang: bool, ident: Option<Ident>, - delim: Option<Delimiter>, + delim: Delimiter, tts: &TokenStream, convert_dollar_crate: bool, span: Span, ) { - if delim == Some(Delimiter::Brace) { + if delim == Delimiter::Brace { self.cbox(INDENT_UNIT); } match header { @@ -591,7 +590,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere self.print_ident(ident); } match delim { - Some(Delimiter::Brace) => { + Delimiter::Brace => { if header.is_some() || has_bang || ident.is_some() { self.nbsp(); } @@ -605,7 +604,7 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere let empty = tts.is_empty(); self.bclose(span, empty); } - Some(delim) => { + delim => { let token_str = self.token_kind_to_string(&token::OpenDelim(delim)); self.word(token_str); self.ibox(0); @@ -614,11 +613,6 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere let token_str = self.token_kind_to_string(&token::CloseDelim(delim)); self.word(token_str); } - None => { - self.ibox(0); - self.print_tts(tts, convert_dollar_crate); - self.end(); - } } } @@ -639,8 +633,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere Some(MacHeader::Keyword(kw)), has_bang, Some(*ident), - macro_def.body.delim(), - ¯o_def.body.inner_tokens(), + macro_def.body.delim.to_token(), + ¯o_def.body.tokens.clone(), true, sp, ); @@ -1230,8 +1224,8 @@ impl<'a> State<'a> { Some(MacHeader::Path(&m.path)), true, None, - m.args.delim(), - &m.args.inner_tokens(), + m.args.delim.to_token(), + &m.args.tokens.clone(), true, m.span(), ); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index 86f1d6bfecd..1da40d2302e 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -121,7 +121,7 @@ impl<'a> State<'a> { fn print_expr_struct( &mut self, - qself: &Option<ast::QSelf>, + qself: &Option<P<ast::QSelf>>, path: &ast::Path, fields: &[ast::ExprField], rest: &ast::StructRest, @@ -307,8 +307,13 @@ impl<'a> State<'a> { ast::ExprKind::Call(ref func, ref args) => { self.print_expr_call(func, &args); } - ast::ExprKind::MethodCall(ref segment, ref receiver, ref args, _) => { - self.print_expr_method_call(segment, &receiver, &args); + ast::ExprKind::MethodCall(box ast::MethodCall { + ref seg, + ref receiver, + ref args, + .. + }) => { + self.print_expr_method_call(seg, &receiver, &args); } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { self.print_expr_binary(op, lhs, rhs); @@ -396,21 +401,21 @@ impl<'a> State<'a> { let empty = attrs.is_empty() && arms.is_empty(); self.bclose(expr.span, empty); } - ast::ExprKind::Closure( + ast::ExprKind::Closure(box ast::Closure { ref binder, capture_clause, asyncness, movability, - ref decl, + ref fn_decl, ref body, - _, - ) => { + fn_decl_span: _, + }) => { self.print_closure_binder(binder); self.print_movability(movability); self.print_asyncness(asyncness); self.print_capture_clause(capture_clause); - self.print_fn_params_and_ret(decl, true); + self.print_fn_params_and_ret(fn_decl, true); self.space(); self.print_expr(body); self.end(); // need to close a box diff --git a/compiler/rustc_baked_icu_data/Cargo.toml b/compiler/rustc_baked_icu_data/Cargo.toml new file mode 100644 index 00000000000..3477306dbfc --- /dev/null +++ b/compiler/rustc_baked_icu_data/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rustc_baked_icu_data" +version = "0.0.0" +edition = "2021" + +[dependencies] +icu_list = "1.0.0" +icu_locid = "1.0.0" +icu_provider = "1.0.1" +icu_provider_adapters = "1.0.0" +litemap = "0.6.0" +zerovec = "0.9.0" + +[features] +rustc_use_parallel_compiler = ['icu_provider/sync'] diff --git a/compiler/rustc_baked_icu_data/src/data/any.rs b/compiler/rustc_baked_icu_data/src/data/any.rs new file mode 100644 index 00000000000..e8e99be93f2 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/any.rs @@ -0,0 +1,42 @@ +// @generated +impl AnyProvider for BakedDataProvider { + fn load_any(&self, key: DataKey, req: DataRequest) -> Result<AnyResponse, DataError> { + const ANDLISTV1MARKER: ::icu_provider::DataKeyHash = + ::icu_list::provider::AndListV1Marker::KEY.hashed(); + const COLLATIONFALLBACKSUPPLEMENTV1MARKER: ::icu_provider::DataKeyHash = + ::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY + .hashed(); + const LOCALEFALLBACKLIKELYSUBTAGSV1MARKER: ::icu_provider::DataKeyHash = + ::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY + .hashed(); + const LOCALEFALLBACKPARENTSV1MARKER: ::icu_provider::DataKeyHash = + ::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY + .hashed(); + #[allow(clippy::match_single_binding)] + match key.hashed() { + ANDLISTV1MARKER => list::and_v1::DATA + .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()) + .copied() + .map(AnyPayload::from_static_ref) + .ok_or(DataErrorKind::MissingLocale), + COLLATIONFALLBACKSUPPLEMENTV1MARKER => fallback::supplement::co_v1::DATA + .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()) + .copied() + .map(AnyPayload::from_static_ref) + .ok_or(DataErrorKind::MissingLocale), + LOCALEFALLBACKLIKELYSUBTAGSV1MARKER => fallback::likelysubtags_v1::DATA + .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()) + .copied() + .map(AnyPayload::from_static_ref) + .ok_or(DataErrorKind::MissingLocale), + LOCALEFALLBACKPARENTSV1MARKER => fallback::parents_v1::DATA + .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()) + .copied() + .map(AnyPayload::from_static_ref) + .ok_or(DataErrorKind::MissingLocale), + _ => Err(DataErrorKind::MissingDataKey), + } + .map_err(|e| e.with_req(key, req)) + .map(|payload| AnyResponse { payload: Some(payload), metadata: Default::default() }) + } +} diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs new file mode 100644 index 00000000000..0a90c832e8c --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/fallback/likelysubtags_v1.rs @@ -0,0 +1,733 @@ +// @generated +type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackLikelySubtagsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ; +pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> = + litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]); +static UND: &DataStruct = + &::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1 { + l2s: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap::from_parts_unchecked( + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 97u8, 98u8, 0u8, 97u8, 98u8, 113u8, 97u8, 100u8, 112u8, 97u8, 100u8, 121u8, + 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 104u8, 111u8, 97u8, 106u8, + 116u8, 97u8, 107u8, 107u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, 97u8, + 112u8, 99u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8, + 114u8, 113u8, 97u8, 114u8, 115u8, 97u8, 114u8, 121u8, 97u8, 114u8, 122u8, + 97u8, 115u8, 0u8, 97u8, 115u8, 101u8, 97u8, 118u8, 0u8, 97u8, 118u8, 108u8, + 97u8, 119u8, 97u8, 98u8, 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 112u8, + 98u8, 97u8, 120u8, 98u8, 99u8, 113u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, + 98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8, + 0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8, + 104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 106u8, 105u8, + 98u8, 106u8, 106u8, 98u8, 108u8, 116u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, + 98u8, 112u8, 121u8, 98u8, 113u8, 105u8, 98u8, 114u8, 97u8, 98u8, 114u8, + 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 113u8, 98u8, 115u8, 116u8, 98u8, + 116u8, 118u8, 98u8, 117u8, 97u8, 98u8, 121u8, 110u8, 99u8, 99u8, 112u8, + 99u8, 101u8, 0u8, 99u8, 104u8, 109u8, 99u8, 104u8, 114u8, 99u8, 106u8, + 97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 109u8, 103u8, 99u8, + 111u8, 112u8, 99u8, 114u8, 0u8, 99u8, 114u8, 104u8, 99u8, 114u8, 107u8, + 99u8, 114u8, 108u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, + 0u8, 99u8, 118u8, 0u8, 100u8, 97u8, 114u8, 100u8, 99u8, 99u8, 100u8, 103u8, + 108u8, 100u8, 109u8, 102u8, 100u8, 111u8, 105u8, 100u8, 114u8, 104u8, + 100u8, 114u8, 115u8, 100u8, 116u8, 121u8, 100u8, 118u8, 0u8, 100u8, 122u8, + 0u8, 101u8, 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, + 115u8, 103u8, 101u8, 116u8, 116u8, 102u8, 97u8, 0u8, 102u8, 105u8, 97u8, + 102u8, 117u8, 98u8, 103u8, 97u8, 110u8, 103u8, 98u8, 109u8, 103u8, 98u8, + 122u8, 103u8, 101u8, 122u8, 103u8, 103u8, 110u8, 103u8, 106u8, 107u8, + 103u8, 106u8, 117u8, 103u8, 108u8, 107u8, 103u8, 109u8, 118u8, 103u8, + 111u8, 102u8, 103u8, 111u8, 109u8, 103u8, 111u8, 110u8, 103u8, 111u8, + 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 117u8, 0u8, 103u8, + 118u8, 114u8, 103u8, 119u8, 99u8, 103u8, 119u8, 116u8, 104u8, 97u8, 107u8, + 104u8, 97u8, 122u8, 104u8, 100u8, 121u8, 104u8, 101u8, 0u8, 104u8, 105u8, + 0u8, 104u8, 108u8, 117u8, 104u8, 109u8, 100u8, 104u8, 110u8, 100u8, 104u8, + 110u8, 101u8, 104u8, 110u8, 106u8, 104u8, 110u8, 111u8, 104u8, 111u8, 99u8, + 104u8, 111u8, 106u8, 104u8, 115u8, 110u8, 104u8, 121u8, 0u8, 105u8, 105u8, + 0u8, 105u8, 110u8, 104u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 106u8, + 97u8, 0u8, 106u8, 105u8, 0u8, 106u8, 109u8, 108u8, 107u8, 97u8, 0u8, 107u8, + 97u8, 97u8, 107u8, 97u8, 119u8, 107u8, 98u8, 100u8, 107u8, 98u8, 121u8, + 107u8, 100u8, 116u8, 107u8, 102u8, 114u8, 107u8, 102u8, 121u8, 107u8, + 104u8, 98u8, 107u8, 104u8, 110u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, + 107u8, 106u8, 103u8, 107u8, 107u8, 0u8, 107u8, 109u8, 0u8, 107u8, 110u8, + 0u8, 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, + 113u8, 121u8, 107u8, 114u8, 99u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8, + 107u8, 116u8, 98u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, 118u8, + 120u8, 107u8, 120u8, 99u8, 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, + 120u8, 112u8, 107u8, 121u8, 0u8, 107u8, 122u8, 104u8, 108u8, 97u8, 98u8, + 108u8, 97u8, 100u8, 108u8, 97u8, 104u8, 108u8, 98u8, 101u8, 108u8, 99u8, + 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, 108u8, 105u8, 102u8, + 108u8, 105u8, 115u8, 108u8, 107u8, 105u8, 108u8, 109u8, 110u8, 108u8, + 111u8, 0u8, 108u8, 114u8, 99u8, 108u8, 117u8, 122u8, 108u8, 119u8, 108u8, + 108u8, 122u8, 104u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 100u8, + 101u8, 109u8, 100u8, 102u8, 109u8, 100u8, 120u8, 109u8, 102u8, 97u8, 109u8, + 103u8, 112u8, 109u8, 107u8, 0u8, 109u8, 107u8, 105u8, 109u8, 108u8, 0u8, + 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, 114u8, + 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, 111u8, 109u8, + 116u8, 114u8, 109u8, 118u8, 121u8, 109u8, 119u8, 114u8, 109u8, 119u8, + 119u8, 109u8, 121u8, 0u8, 109u8, 121u8, 109u8, 109u8, 121u8, 118u8, 109u8, + 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 110u8, 110u8, 101u8, 0u8, + 110u8, 101u8, 119u8, 110u8, 110u8, 112u8, 110u8, 111u8, 100u8, 110u8, + 111u8, 101u8, 110u8, 111u8, 110u8, 110u8, 113u8, 111u8, 110u8, 115u8, + 107u8, 110u8, 115u8, 116u8, 111u8, 106u8, 0u8, 111u8, 106u8, 115u8, 111u8, + 114u8, 0u8, 111u8, 114u8, 117u8, 111u8, 115u8, 0u8, 111u8, 115u8, 97u8, + 111u8, 116u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, 112u8, 97u8, + 0u8, 112u8, 97u8, 108u8, 112u8, 101u8, 111u8, 112u8, 104u8, 108u8, 112u8, + 104u8, 110u8, 112u8, 107u8, 97u8, 112u8, 110u8, 116u8, 112u8, 112u8, 97u8, + 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 115u8, 0u8, 114u8, 97u8, + 106u8, 114u8, 104u8, 103u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, + 114u8, 107u8, 116u8, 114u8, 109u8, 116u8, 114u8, 117u8, 0u8, 114u8, 117u8, + 101u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, 115u8, 97u8, 104u8, 115u8, + 97u8, 116u8, 115u8, 97u8, 122u8, 115u8, 99u8, 107u8, 115u8, 99u8, 108u8, + 115u8, 100u8, 0u8, 115u8, 100u8, 104u8, 115u8, 103u8, 97u8, 115u8, 103u8, + 119u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, 104u8, 117u8, + 115u8, 105u8, 0u8, 115u8, 107u8, 114u8, 115u8, 109u8, 112u8, 115u8, 111u8, + 103u8, 115u8, 111u8, 117u8, 115u8, 114u8, 0u8, 115u8, 114u8, 98u8, 115u8, + 114u8, 120u8, 115u8, 119u8, 98u8, 115u8, 119u8, 118u8, 115u8, 121u8, 108u8, + 115u8, 121u8, 114u8, 116u8, 97u8, 0u8, 116u8, 97u8, 106u8, 116u8, 99u8, + 121u8, 116u8, 100u8, 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, + 116u8, 101u8, 0u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, + 108u8, 116u8, 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, + 105u8, 103u8, 116u8, 107u8, 116u8, 116u8, 114u8, 119u8, 116u8, 115u8, + 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 106u8, 116u8, 116u8, 0u8, 116u8, + 116u8, 115u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, + 118u8, 117u8, 100u8, 105u8, 117u8, 100u8, 109u8, 117u8, 103u8, 0u8, 117u8, + 103u8, 97u8, 117u8, 107u8, 0u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8, + 117u8, 114u8, 0u8, 118u8, 97u8, 105u8, 119u8, 97u8, 108u8, 119u8, 98u8, + 113u8, 119u8, 98u8, 114u8, 119u8, 110u8, 105u8, 119u8, 115u8, 103u8, 119u8, + 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 99u8, 111u8, 120u8, 99u8, 114u8, + 120u8, 108u8, 99u8, 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, + 110u8, 120u8, 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, + 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 105u8, 0u8, + 121u8, 117u8, 101u8, 122u8, 100u8, 106u8, 122u8, 103u8, 104u8, 122u8, + 104u8, 0u8, 122u8, 104u8, 120u8, 122u8, 107u8, 116u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 84u8, 105u8, 98u8, + 116u8, 67u8, 121u8, 114u8, 108u8, 65u8, 118u8, 115u8, 116u8, 65u8, 114u8, + 97u8, 98u8, 65u8, 104u8, 111u8, 109u8, 65u8, 114u8, 97u8, 98u8, 88u8, + 115u8, 117u8, 120u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, 105u8, + 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, + 65u8, 114u8, 109u8, 105u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, + 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 66u8, 101u8, 110u8, + 103u8, 83u8, 103u8, 110u8, 119u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, + 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 65u8, + 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 66u8, 97u8, 109u8, 117u8, + 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, + 98u8, 84u8, 97u8, 109u8, 108u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, + 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, + 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, 68u8, 101u8, 118u8, 97u8, + 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, + 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 118u8, 116u8, 66u8, 101u8, + 110u8, 103u8, 84u8, 105u8, 98u8, 116u8, 66u8, 101u8, 110u8, 103u8, 65u8, + 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, + 101u8, 118u8, 97u8, 66u8, 97u8, 115u8, 115u8, 69u8, 116u8, 104u8, 105u8, + 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, + 105u8, 67u8, 97u8, 107u8, 109u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, + 114u8, 108u8, 67u8, 104u8, 101u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, + 104u8, 97u8, 109u8, 65u8, 114u8, 97u8, 98u8, 83u8, 111u8, 121u8, 111u8, + 67u8, 111u8, 112u8, 116u8, 67u8, 97u8, 110u8, 115u8, 67u8, 121u8, 114u8, + 108u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, + 110u8, 115u8, 80u8, 97u8, 117u8, 99u8, 67u8, 121u8, 114u8, 108u8, 67u8, + 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, + 65u8, 114u8, 97u8, 98u8, 77u8, 101u8, 100u8, 102u8, 68u8, 101u8, 118u8, + 97u8, 77u8, 111u8, 110u8, 103u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, + 118u8, 97u8, 84u8, 104u8, 97u8, 97u8, 84u8, 105u8, 98u8, 116u8, 69u8, + 103u8, 121u8, 112u8, 75u8, 97u8, 108u8, 105u8, 71u8, 114u8, 101u8, 107u8, + 71u8, 111u8, 110u8, 109u8, 73u8, 116u8, 97u8, 108u8, 65u8, 114u8, 97u8, + 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, + 115u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, + 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 65u8, + 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, + 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, 97u8, 84u8, 101u8, 108u8, + 117u8, 71u8, 111u8, 116u8, 104u8, 67u8, 112u8, 114u8, 116u8, 66u8, 101u8, + 110u8, 103u8, 71u8, 117u8, 106u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, + 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 65u8, + 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 72u8, 101u8, 98u8, 114u8, + 68u8, 101u8, 118u8, 97u8, 72u8, 108u8, 117u8, 119u8, 80u8, 108u8, 114u8, + 100u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, + 110u8, 112u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 68u8, + 101u8, 118u8, 97u8, 72u8, 97u8, 110u8, 115u8, 65u8, 114u8, 109u8, 110u8, + 89u8, 105u8, 105u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 97u8, 110u8, + 115u8, 72u8, 101u8, 98u8, 114u8, 74u8, 112u8, 97u8, 110u8, 72u8, 101u8, + 98u8, 114u8, 68u8, 101u8, 118u8, 97u8, 71u8, 101u8, 111u8, 114u8, 67u8, + 121u8, 114u8, 108u8, 75u8, 97u8, 119u8, 105u8, 67u8, 121u8, 114u8, 108u8, + 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 68u8, 101u8, 118u8, + 97u8, 68u8, 101u8, 118u8, 97u8, 84u8, 97u8, 108u8, 117u8, 68u8, 101u8, + 118u8, 97u8, 77u8, 121u8, 109u8, 114u8, 65u8, 114u8, 97u8, 98u8, 76u8, + 97u8, 111u8, 111u8, 67u8, 121u8, 114u8, 108u8, 75u8, 104u8, 109u8, 114u8, + 75u8, 110u8, 100u8, 97u8, 75u8, 111u8, 114u8, 101u8, 67u8, 121u8, 114u8, + 108u8, 68u8, 101u8, 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, + 114u8, 108u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 69u8, + 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, + 65u8, 114u8, 97u8, 98u8, 69u8, 116u8, 104u8, 105u8, 68u8, 101u8, 118u8, + 97u8, 84u8, 104u8, 97u8, 105u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, + 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 76u8, 105u8, 110u8, 97u8, 72u8, + 101u8, 98u8, 114u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, + 84u8, 104u8, 97u8, 105u8, 76u8, 101u8, 112u8, 99u8, 67u8, 121u8, 114u8, + 108u8, 68u8, 101u8, 118u8, 97u8, 76u8, 105u8, 115u8, 117u8, 65u8, 114u8, + 97u8, 98u8, 84u8, 101u8, 108u8, 117u8, 76u8, 97u8, 111u8, 111u8, 65u8, + 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 84u8, 104u8, 97u8, 105u8, 72u8, + 97u8, 110u8, 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, + 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 69u8, 116u8, 104u8, + 105u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, + 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 77u8, 108u8, 121u8, 109u8, 67u8, + 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 77u8, 121u8, 109u8, 114u8, + 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 67u8, 121u8, 114u8, + 108u8, 77u8, 114u8, 111u8, 111u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, + 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 109u8, 110u8, 112u8, 77u8, + 121u8, 109u8, 114u8, 69u8, 116u8, 104u8, 105u8, 67u8, 121u8, 114u8, 108u8, + 77u8, 97u8, 110u8, 100u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, + 115u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 87u8, 99u8, + 104u8, 111u8, 76u8, 97u8, 110u8, 97u8, 68u8, 101u8, 118u8, 97u8, 82u8, + 117u8, 110u8, 114u8, 78u8, 107u8, 111u8, 111u8, 67u8, 97u8, 110u8, 115u8, + 84u8, 110u8, 115u8, 97u8, 67u8, 97u8, 110u8, 115u8, 67u8, 97u8, 110u8, + 115u8, 79u8, 114u8, 121u8, 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, + 114u8, 108u8, 79u8, 115u8, 103u8, 101u8, 65u8, 114u8, 97u8, 98u8, 79u8, + 114u8, 107u8, 104u8, 79u8, 117u8, 103u8, 114u8, 71u8, 117u8, 114u8, 117u8, + 80u8, 104u8, 108u8, 105u8, 88u8, 112u8, 101u8, 111u8, 65u8, 114u8, 97u8, + 98u8, 80u8, 104u8, 110u8, 120u8, 66u8, 114u8, 97u8, 104u8, 71u8, 114u8, + 101u8, 107u8, 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 97u8, 114u8, 65u8, + 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, 97u8, 82u8, + 111u8, 104u8, 103u8, 84u8, 102u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8, + 66u8, 101u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, + 108u8, 67u8, 121u8, 114u8, 108u8, 75u8, 97u8, 110u8, 97u8, 68u8, 101u8, + 118u8, 97u8, 67u8, 121u8, 114u8, 108u8, 79u8, 108u8, 99u8, 107u8, 83u8, + 97u8, 117u8, 114u8, 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, + 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 79u8, 103u8, 97u8, 109u8, + 69u8, 116u8, 104u8, 105u8, 84u8, 102u8, 110u8, 103u8, 77u8, 121u8, 109u8, + 114u8, 65u8, 114u8, 97u8, 98u8, 83u8, 105u8, 110u8, 104u8, 65u8, 114u8, + 97u8, 98u8, 83u8, 97u8, 109u8, 114u8, 83u8, 111u8, 103u8, 100u8, 84u8, + 104u8, 97u8, 105u8, 67u8, 121u8, 114u8, 108u8, 83u8, 111u8, 114u8, 97u8, + 68u8, 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 68u8, 101u8, 118u8, + 97u8, 66u8, 101u8, 110u8, 103u8, 83u8, 121u8, 114u8, 99u8, 84u8, 97u8, + 109u8, 108u8, 68u8, 101u8, 118u8, 97u8, 75u8, 110u8, 100u8, 97u8, 84u8, + 97u8, 108u8, 101u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, + 84u8, 101u8, 108u8, 117u8, 67u8, 121u8, 114u8, 108u8, 84u8, 104u8, 97u8, + 105u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, 118u8, 97u8, 68u8, 101u8, + 118u8, 97u8, 69u8, 116u8, 104u8, 105u8, 69u8, 116u8, 104u8, 105u8, 68u8, + 101u8, 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 71u8, 114u8, 101u8, 107u8, + 68u8, 101u8, 118u8, 97u8, 84u8, 105u8, 98u8, 116u8, 67u8, 121u8, 114u8, + 108u8, 84u8, 104u8, 97u8, 105u8, 84u8, 97u8, 110u8, 103u8, 84u8, 111u8, + 116u8, 111u8, 67u8, 121u8, 114u8, 108u8, 65u8, 103u8, 104u8, 98u8, 67u8, + 121u8, 114u8, 108u8, 65u8, 114u8, 97u8, 98u8, 85u8, 103u8, 97u8, 114u8, + 67u8, 121u8, 114u8, 108u8, 66u8, 101u8, 110u8, 103u8, 66u8, 101u8, 110u8, + 103u8, 65u8, 114u8, 97u8, 98u8, 86u8, 97u8, 105u8, 105u8, 69u8, 116u8, + 104u8, 105u8, 84u8, 101u8, 108u8, 117u8, 68u8, 101u8, 118u8, 97u8, 65u8, + 114u8, 97u8, 98u8, 71u8, 111u8, 110u8, 103u8, 68u8, 101u8, 118u8, 97u8, + 72u8, 97u8, 110u8, 115u8, 67u8, 104u8, 114u8, 115u8, 67u8, 97u8, 114u8, + 105u8, 76u8, 121u8, 99u8, 105u8, 76u8, 121u8, 100u8, 105u8, 71u8, 101u8, + 111u8, 114u8, 77u8, 97u8, 110u8, 105u8, 77u8, 101u8, 114u8, 99u8, 78u8, + 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 80u8, 114u8, 116u8, 105u8, + 83u8, 97u8, 114u8, 98u8, 68u8, 101u8, 118u8, 97u8, 72u8, 101u8, 98u8, + 114u8, 72u8, 97u8, 110u8, 116u8, 65u8, 114u8, 97u8, 98u8, 84u8, 102u8, + 110u8, 103u8, 72u8, 97u8, 110u8, 115u8, 78u8, 115u8, 104u8, 117u8, 75u8, + 105u8, 116u8, 115u8, + ]) + }, + ) + }, + lr2s: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap2d::from_parts_unchecked( + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 97u8, 122u8, 0u8, 104u8, 97u8, 0u8, 107u8, 107u8, 0u8, 107u8, 117u8, 0u8, + 107u8, 121u8, 0u8, 109u8, 97u8, 110u8, 109u8, 110u8, 0u8, 109u8, 115u8, + 0u8, 112u8, 97u8, 0u8, 114u8, 105u8, 102u8, 115u8, 100u8, 0u8, 115u8, + 114u8, 0u8, 116u8, 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, + 117u8, 122u8, 0u8, 121u8, 117u8, 101u8, 122u8, 104u8, 0u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 3u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 10u8, 0u8, 0u8, + 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 15u8, + 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 26u8, + 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, 29u8, 0u8, 0u8, 0u8, 44u8, 0u8, 0u8, + 0u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 73u8, 81u8, 0u8, 73u8, 82u8, 0u8, 82u8, 85u8, 0u8, 67u8, 77u8, 0u8, 83u8, + 68u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 73u8, 82u8, 0u8, 77u8, 78u8, + 0u8, 76u8, 66u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 71u8, 78u8, 0u8, + 67u8, 78u8, 0u8, 67u8, 67u8, 0u8, 80u8, 75u8, 0u8, 78u8, 76u8, 0u8, 73u8, + 78u8, 0u8, 77u8, 69u8, 0u8, 82u8, 79u8, 0u8, 82u8, 85u8, 0u8, 84u8, 82u8, + 0u8, 80u8, 75u8, 0u8, 75u8, 90u8, 0u8, 77u8, 78u8, 0u8, 78u8, 80u8, 0u8, + 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 65u8, 85u8, 0u8, 66u8, + 78u8, 0u8, 71u8, 66u8, 0u8, 71u8, 70u8, 0u8, 72u8, 75u8, 0u8, 73u8, 68u8, + 0u8, 77u8, 79u8, 0u8, 80u8, 65u8, 0u8, 80u8, 70u8, 0u8, 80u8, 72u8, 0u8, + 83u8, 82u8, 0u8, 84u8, 72u8, 0u8, 84u8, 87u8, 0u8, 85u8, 83u8, 0u8, 86u8, + 78u8, 0u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, + 108u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, + 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, + 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, + 110u8, 78u8, 107u8, 111u8, 111u8, 77u8, 111u8, 110u8, 103u8, 65u8, 114u8, + 97u8, 98u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, 116u8, 110u8, 68u8, 101u8, + 118u8, 97u8, 76u8, 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 76u8, + 97u8, 116u8, 110u8, 76u8, 97u8, 116u8, 110u8, 65u8, 114u8, 97u8, 98u8, + 67u8, 121u8, 114u8, 108u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, 118u8, + 97u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 72u8, 97u8, + 110u8, 115u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, + 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, + 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, + 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, + 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, 72u8, + 97u8, 110u8, 116u8, 72u8, 97u8, 110u8, 116u8, + ]) + }, + ) + }, + l2r: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap::from_parts_unchecked( + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 97u8, 97u8, 0u8, 97u8, 98u8, 0u8, 97u8, 98u8, 114u8, 97u8, 99u8, 101u8, + 97u8, 99u8, 104u8, 97u8, 100u8, 97u8, 97u8, 100u8, 112u8, 97u8, 100u8, + 121u8, 97u8, 101u8, 0u8, 97u8, 101u8, 98u8, 97u8, 102u8, 0u8, 97u8, 103u8, + 113u8, 97u8, 104u8, 111u8, 97u8, 106u8, 116u8, 97u8, 107u8, 0u8, 97u8, + 107u8, 107u8, 97u8, 108u8, 110u8, 97u8, 108u8, 116u8, 97u8, 109u8, 0u8, + 97u8, 109u8, 111u8, 97u8, 110u8, 0u8, 97u8, 110u8, 110u8, 97u8, 111u8, + 122u8, 97u8, 112u8, 100u8, 97u8, 114u8, 0u8, 97u8, 114u8, 99u8, 97u8, + 114u8, 110u8, 97u8, 114u8, 111u8, 97u8, 114u8, 113u8, 97u8, 114u8, 115u8, + 97u8, 114u8, 121u8, 97u8, 114u8, 122u8, 97u8, 115u8, 0u8, 97u8, 115u8, + 97u8, 97u8, 115u8, 101u8, 97u8, 115u8, 116u8, 97u8, 116u8, 106u8, 97u8, + 118u8, 0u8, 97u8, 119u8, 97u8, 97u8, 121u8, 0u8, 97u8, 122u8, 0u8, 98u8, + 97u8, 0u8, 98u8, 97u8, 108u8, 98u8, 97u8, 110u8, 98u8, 97u8, 112u8, 98u8, + 97u8, 114u8, 98u8, 97u8, 115u8, 98u8, 97u8, 120u8, 98u8, 98u8, 99u8, 98u8, + 98u8, 106u8, 98u8, 99u8, 105u8, 98u8, 101u8, 0u8, 98u8, 101u8, 106u8, 98u8, + 101u8, 109u8, 98u8, 101u8, 119u8, 98u8, 101u8, 122u8, 98u8, 102u8, 100u8, + 98u8, 102u8, 113u8, 98u8, 102u8, 116u8, 98u8, 102u8, 121u8, 98u8, 103u8, + 0u8, 98u8, 103u8, 99u8, 98u8, 103u8, 110u8, 98u8, 103u8, 120u8, 98u8, + 104u8, 98u8, 98u8, 104u8, 105u8, 98u8, 104u8, 111u8, 98u8, 105u8, 0u8, + 98u8, 105u8, 107u8, 98u8, 105u8, 110u8, 98u8, 106u8, 106u8, 98u8, 106u8, + 110u8, 98u8, 106u8, 116u8, 98u8, 107u8, 109u8, 98u8, 107u8, 117u8, 98u8, + 108u8, 97u8, 98u8, 108u8, 103u8, 98u8, 108u8, 116u8, 98u8, 109u8, 0u8, + 98u8, 109u8, 113u8, 98u8, 110u8, 0u8, 98u8, 111u8, 0u8, 98u8, 112u8, 121u8, + 98u8, 113u8, 105u8, 98u8, 113u8, 118u8, 98u8, 114u8, 0u8, 98u8, 114u8, + 97u8, 98u8, 114u8, 104u8, 98u8, 114u8, 120u8, 98u8, 115u8, 0u8, 98u8, + 115u8, 113u8, 98u8, 115u8, 115u8, 98u8, 116u8, 111u8, 98u8, 116u8, 118u8, + 98u8, 117u8, 97u8, 98u8, 117u8, 99u8, 98u8, 117u8, 103u8, 98u8, 117u8, + 109u8, 98u8, 118u8, 98u8, 98u8, 121u8, 110u8, 98u8, 121u8, 118u8, 98u8, + 122u8, 101u8, 99u8, 97u8, 0u8, 99u8, 97u8, 100u8, 99u8, 99u8, 104u8, 99u8, + 99u8, 112u8, 99u8, 101u8, 0u8, 99u8, 101u8, 98u8, 99u8, 103u8, 103u8, 99u8, + 104u8, 0u8, 99u8, 104u8, 107u8, 99u8, 104u8, 109u8, 99u8, 104u8, 111u8, + 99u8, 104u8, 112u8, 99u8, 104u8, 114u8, 99u8, 105u8, 99u8, 99u8, 106u8, + 97u8, 99u8, 106u8, 109u8, 99u8, 107u8, 98u8, 99u8, 108u8, 99u8, 99u8, + 109u8, 103u8, 99u8, 111u8, 0u8, 99u8, 111u8, 112u8, 99u8, 112u8, 115u8, + 99u8, 114u8, 0u8, 99u8, 114u8, 103u8, 99u8, 114u8, 104u8, 99u8, 114u8, + 107u8, 99u8, 114u8, 108u8, 99u8, 114u8, 115u8, 99u8, 115u8, 0u8, 99u8, + 115u8, 98u8, 99u8, 115u8, 119u8, 99u8, 116u8, 100u8, 99u8, 117u8, 0u8, + 99u8, 118u8, 0u8, 99u8, 121u8, 0u8, 100u8, 97u8, 0u8, 100u8, 97u8, 102u8, + 100u8, 97u8, 107u8, 100u8, 97u8, 114u8, 100u8, 97u8, 118u8, 100u8, 99u8, + 99u8, 100u8, 101u8, 0u8, 100u8, 101u8, 110u8, 100u8, 103u8, 114u8, 100u8, + 106u8, 101u8, 100u8, 109u8, 102u8, 100u8, 110u8, 106u8, 100u8, 111u8, + 105u8, 100u8, 114u8, 104u8, 100u8, 115u8, 98u8, 100u8, 116u8, 109u8, 100u8, + 116u8, 112u8, 100u8, 116u8, 121u8, 100u8, 117u8, 97u8, 100u8, 118u8, 0u8, + 100u8, 121u8, 111u8, 100u8, 121u8, 117u8, 100u8, 122u8, 0u8, 101u8, 98u8, + 117u8, 101u8, 101u8, 0u8, 101u8, 102u8, 105u8, 101u8, 103u8, 108u8, 101u8, + 103u8, 121u8, 101u8, 107u8, 121u8, 101u8, 108u8, 0u8, 101u8, 110u8, 0u8, + 101u8, 111u8, 0u8, 101u8, 115u8, 0u8, 101u8, 115u8, 103u8, 101u8, 115u8, + 117u8, 101u8, 116u8, 0u8, 101u8, 116u8, 116u8, 101u8, 117u8, 0u8, 101u8, + 119u8, 111u8, 101u8, 120u8, 116u8, 102u8, 97u8, 0u8, 102u8, 97u8, 110u8, + 102u8, 102u8, 0u8, 102u8, 102u8, 109u8, 102u8, 105u8, 0u8, 102u8, 105u8, + 97u8, 102u8, 105u8, 108u8, 102u8, 105u8, 116u8, 102u8, 106u8, 0u8, 102u8, + 111u8, 0u8, 102u8, 111u8, 110u8, 102u8, 114u8, 0u8, 102u8, 114u8, 99u8, + 102u8, 114u8, 112u8, 102u8, 114u8, 114u8, 102u8, 114u8, 115u8, 102u8, + 117u8, 98u8, 102u8, 117u8, 100u8, 102u8, 117u8, 102u8, 102u8, 117u8, 113u8, + 102u8, 117u8, 114u8, 102u8, 117u8, 118u8, 102u8, 118u8, 114u8, 102u8, + 121u8, 0u8, 103u8, 97u8, 0u8, 103u8, 97u8, 97u8, 103u8, 97u8, 103u8, 103u8, + 97u8, 110u8, 103u8, 97u8, 121u8, 103u8, 98u8, 109u8, 103u8, 98u8, 122u8, + 103u8, 99u8, 114u8, 103u8, 100u8, 0u8, 103u8, 101u8, 122u8, 103u8, 103u8, + 110u8, 103u8, 105u8, 108u8, 103u8, 106u8, 107u8, 103u8, 106u8, 117u8, + 103u8, 108u8, 0u8, 103u8, 108u8, 107u8, 103u8, 110u8, 0u8, 103u8, 111u8, + 109u8, 103u8, 111u8, 110u8, 103u8, 111u8, 114u8, 103u8, 111u8, 115u8, + 103u8, 111u8, 116u8, 103u8, 114u8, 99u8, 103u8, 114u8, 116u8, 103u8, 115u8, + 119u8, 103u8, 117u8, 0u8, 103u8, 117u8, 98u8, 103u8, 117u8, 99u8, 103u8, + 117u8, 114u8, 103u8, 117u8, 122u8, 103u8, 118u8, 0u8, 103u8, 118u8, 114u8, + 103u8, 119u8, 105u8, 104u8, 97u8, 0u8, 104u8, 97u8, 107u8, 104u8, 97u8, + 119u8, 104u8, 97u8, 122u8, 104u8, 101u8, 0u8, 104u8, 105u8, 0u8, 104u8, + 105u8, 102u8, 104u8, 105u8, 108u8, 104u8, 108u8, 117u8, 104u8, 109u8, + 100u8, 104u8, 110u8, 100u8, 104u8, 110u8, 101u8, 104u8, 110u8, 106u8, + 104u8, 110u8, 110u8, 104u8, 110u8, 111u8, 104u8, 111u8, 0u8, 104u8, 111u8, + 99u8, 104u8, 111u8, 106u8, 104u8, 114u8, 0u8, 104u8, 115u8, 98u8, 104u8, + 115u8, 110u8, 104u8, 116u8, 0u8, 104u8, 117u8, 0u8, 104u8, 117u8, 114u8, + 104u8, 121u8, 0u8, 104u8, 122u8, 0u8, 105u8, 97u8, 0u8, 105u8, 98u8, 97u8, + 105u8, 98u8, 98u8, 105u8, 100u8, 0u8, 105u8, 102u8, 101u8, 105u8, 103u8, + 0u8, 105u8, 105u8, 0u8, 105u8, 107u8, 0u8, 105u8, 108u8, 111u8, 105u8, + 110u8, 0u8, 105u8, 110u8, 104u8, 105u8, 111u8, 0u8, 105u8, 115u8, 0u8, + 105u8, 116u8, 0u8, 105u8, 117u8, 0u8, 105u8, 119u8, 0u8, 105u8, 122u8, + 104u8, 106u8, 97u8, 0u8, 106u8, 97u8, 109u8, 106u8, 98u8, 111u8, 106u8, + 103u8, 111u8, 106u8, 105u8, 0u8, 106u8, 109u8, 99u8, 106u8, 109u8, 108u8, + 106u8, 117u8, 116u8, 106u8, 118u8, 0u8, 106u8, 119u8, 0u8, 107u8, 97u8, + 0u8, 107u8, 97u8, 97u8, 107u8, 97u8, 98u8, 107u8, 97u8, 99u8, 107u8, 97u8, + 106u8, 107u8, 97u8, 109u8, 107u8, 97u8, 111u8, 107u8, 97u8, 119u8, 107u8, + 98u8, 100u8, 107u8, 98u8, 121u8, 107u8, 99u8, 103u8, 107u8, 99u8, 107u8, + 107u8, 100u8, 101u8, 107u8, 100u8, 104u8, 107u8, 100u8, 116u8, 107u8, + 101u8, 97u8, 107u8, 101u8, 110u8, 107u8, 102u8, 111u8, 107u8, 102u8, 114u8, + 107u8, 102u8, 121u8, 107u8, 103u8, 0u8, 107u8, 103u8, 101u8, 107u8, 103u8, + 112u8, 107u8, 104u8, 97u8, 107u8, 104u8, 98u8, 107u8, 104u8, 110u8, 107u8, + 104u8, 113u8, 107u8, 104u8, 116u8, 107u8, 104u8, 119u8, 107u8, 105u8, 0u8, + 107u8, 105u8, 117u8, 107u8, 106u8, 0u8, 107u8, 106u8, 103u8, 107u8, 107u8, + 0u8, 107u8, 107u8, 106u8, 107u8, 108u8, 0u8, 107u8, 108u8, 110u8, 107u8, + 109u8, 0u8, 107u8, 109u8, 98u8, 107u8, 110u8, 0u8, 107u8, 110u8, 102u8, + 107u8, 111u8, 0u8, 107u8, 111u8, 105u8, 107u8, 111u8, 107u8, 107u8, 111u8, + 115u8, 107u8, 112u8, 101u8, 107u8, 114u8, 99u8, 107u8, 114u8, 105u8, 107u8, + 114u8, 106u8, 107u8, 114u8, 108u8, 107u8, 114u8, 117u8, 107u8, 115u8, 0u8, + 107u8, 115u8, 98u8, 107u8, 115u8, 102u8, 107u8, 115u8, 104u8, 107u8, 116u8, + 114u8, 107u8, 117u8, 0u8, 107u8, 117u8, 109u8, 107u8, 118u8, 0u8, 107u8, + 118u8, 114u8, 107u8, 118u8, 120u8, 107u8, 119u8, 0u8, 107u8, 119u8, 107u8, + 107u8, 120u8, 108u8, 107u8, 120u8, 109u8, 107u8, 120u8, 112u8, 107u8, + 121u8, 0u8, 107u8, 122u8, 106u8, 107u8, 122u8, 116u8, 108u8, 97u8, 0u8, + 108u8, 97u8, 98u8, 108u8, 97u8, 100u8, 108u8, 97u8, 103u8, 108u8, 97u8, + 104u8, 108u8, 97u8, 106u8, 108u8, 98u8, 0u8, 108u8, 98u8, 101u8, 108u8, + 98u8, 119u8, 108u8, 99u8, 112u8, 108u8, 101u8, 112u8, 108u8, 101u8, 122u8, + 108u8, 103u8, 0u8, 108u8, 105u8, 0u8, 108u8, 105u8, 102u8, 108u8, 105u8, + 106u8, 108u8, 105u8, 108u8, 108u8, 105u8, 115u8, 108u8, 106u8, 112u8, + 108u8, 107u8, 105u8, 108u8, 107u8, 116u8, 108u8, 109u8, 110u8, 108u8, + 109u8, 111u8, 108u8, 110u8, 0u8, 108u8, 111u8, 0u8, 108u8, 111u8, 108u8, + 108u8, 111u8, 122u8, 108u8, 114u8, 99u8, 108u8, 116u8, 0u8, 108u8, 116u8, + 103u8, 108u8, 117u8, 0u8, 108u8, 117u8, 97u8, 108u8, 117u8, 111u8, 108u8, + 117u8, 121u8, 108u8, 117u8, 122u8, 108u8, 118u8, 0u8, 108u8, 119u8, 108u8, + 108u8, 122u8, 104u8, 108u8, 122u8, 122u8, 109u8, 97u8, 100u8, 109u8, 97u8, + 102u8, 109u8, 97u8, 103u8, 109u8, 97u8, 105u8, 109u8, 97u8, 107u8, 109u8, + 97u8, 110u8, 109u8, 97u8, 115u8, 109u8, 97u8, 122u8, 109u8, 100u8, 102u8, + 109u8, 100u8, 104u8, 109u8, 100u8, 114u8, 109u8, 101u8, 110u8, 109u8, + 101u8, 114u8, 109u8, 102u8, 97u8, 109u8, 102u8, 101u8, 109u8, 103u8, 0u8, + 109u8, 103u8, 104u8, 109u8, 103u8, 111u8, 109u8, 103u8, 112u8, 109u8, + 103u8, 121u8, 109u8, 104u8, 0u8, 109u8, 105u8, 0u8, 109u8, 105u8, 99u8, + 109u8, 105u8, 110u8, 109u8, 107u8, 0u8, 109u8, 108u8, 0u8, 109u8, 108u8, + 115u8, 109u8, 110u8, 0u8, 109u8, 110u8, 105u8, 109u8, 110u8, 119u8, 109u8, + 111u8, 0u8, 109u8, 111u8, 101u8, 109u8, 111u8, 104u8, 109u8, 111u8, 115u8, + 109u8, 114u8, 0u8, 109u8, 114u8, 100u8, 109u8, 114u8, 106u8, 109u8, 114u8, + 111u8, 109u8, 115u8, 0u8, 109u8, 116u8, 0u8, 109u8, 116u8, 114u8, 109u8, + 117u8, 97u8, 109u8, 117u8, 115u8, 109u8, 118u8, 121u8, 109u8, 119u8, 107u8, + 109u8, 119u8, 114u8, 109u8, 119u8, 118u8, 109u8, 119u8, 119u8, 109u8, + 120u8, 99u8, 109u8, 121u8, 0u8, 109u8, 121u8, 118u8, 109u8, 121u8, 120u8, + 109u8, 121u8, 122u8, 109u8, 122u8, 110u8, 110u8, 97u8, 0u8, 110u8, 97u8, + 110u8, 110u8, 97u8, 112u8, 110u8, 97u8, 113u8, 110u8, 98u8, 0u8, 110u8, + 99u8, 104u8, 110u8, 100u8, 0u8, 110u8, 100u8, 99u8, 110u8, 100u8, 115u8, + 110u8, 101u8, 0u8, 110u8, 101u8, 119u8, 110u8, 103u8, 0u8, 110u8, 103u8, + 108u8, 110u8, 104u8, 101u8, 110u8, 104u8, 119u8, 110u8, 105u8, 106u8, + 110u8, 105u8, 117u8, 110u8, 106u8, 111u8, 110u8, 108u8, 0u8, 110u8, 109u8, + 103u8, 110u8, 110u8, 0u8, 110u8, 110u8, 104u8, 110u8, 110u8, 112u8, 110u8, + 111u8, 0u8, 110u8, 111u8, 100u8, 110u8, 111u8, 101u8, 110u8, 111u8, 110u8, + 110u8, 113u8, 111u8, 110u8, 114u8, 0u8, 110u8, 115u8, 107u8, 110u8, 115u8, + 111u8, 110u8, 115u8, 116u8, 110u8, 117u8, 115u8, 110u8, 118u8, 0u8, 110u8, + 120u8, 113u8, 110u8, 121u8, 0u8, 110u8, 121u8, 109u8, 110u8, 121u8, 110u8, + 110u8, 122u8, 105u8, 111u8, 99u8, 0u8, 111u8, 106u8, 0u8, 111u8, 106u8, + 115u8, 111u8, 107u8, 97u8, 111u8, 109u8, 0u8, 111u8, 114u8, 0u8, 111u8, + 115u8, 0u8, 111u8, 115u8, 97u8, 111u8, 116u8, 107u8, 111u8, 117u8, 105u8, + 112u8, 97u8, 0u8, 112u8, 97u8, 103u8, 112u8, 97u8, 108u8, 112u8, 97u8, + 109u8, 112u8, 97u8, 112u8, 112u8, 97u8, 117u8, 112u8, 99u8, 100u8, 112u8, + 99u8, 109u8, 112u8, 100u8, 99u8, 112u8, 100u8, 116u8, 112u8, 101u8, 111u8, + 112u8, 102u8, 108u8, 112u8, 104u8, 110u8, 112u8, 105u8, 115u8, 112u8, + 107u8, 97u8, 112u8, 107u8, 111u8, 112u8, 108u8, 0u8, 112u8, 109u8, 115u8, + 112u8, 110u8, 116u8, 112u8, 111u8, 110u8, 112u8, 112u8, 97u8, 112u8, 113u8, + 109u8, 112u8, 114u8, 97u8, 112u8, 114u8, 100u8, 112u8, 114u8, 103u8, 112u8, + 115u8, 0u8, 112u8, 116u8, 0u8, 112u8, 117u8, 117u8, 113u8, 117u8, 0u8, + 113u8, 117u8, 99u8, 113u8, 117u8, 103u8, 114u8, 97u8, 106u8, 114u8, 99u8, + 102u8, 114u8, 101u8, 106u8, 114u8, 103u8, 110u8, 114u8, 104u8, 103u8, + 114u8, 105u8, 97u8, 114u8, 105u8, 102u8, 114u8, 106u8, 115u8, 114u8, 107u8, + 116u8, 114u8, 109u8, 0u8, 114u8, 109u8, 102u8, 114u8, 109u8, 111u8, 114u8, + 109u8, 116u8, 114u8, 109u8, 117u8, 114u8, 110u8, 0u8, 114u8, 110u8, 103u8, + 114u8, 111u8, 0u8, 114u8, 111u8, 98u8, 114u8, 111u8, 102u8, 114u8, 116u8, + 109u8, 114u8, 117u8, 0u8, 114u8, 117u8, 101u8, 114u8, 117u8, 103u8, 114u8, + 119u8, 0u8, 114u8, 119u8, 107u8, 114u8, 121u8, 117u8, 115u8, 97u8, 0u8, + 115u8, 97u8, 102u8, 115u8, 97u8, 104u8, 115u8, 97u8, 113u8, 115u8, 97u8, + 115u8, 115u8, 97u8, 116u8, 115u8, 97u8, 118u8, 115u8, 97u8, 122u8, 115u8, + 98u8, 112u8, 115u8, 99u8, 0u8, 115u8, 99u8, 107u8, 115u8, 99u8, 110u8, + 115u8, 99u8, 111u8, 115u8, 100u8, 0u8, 115u8, 100u8, 99u8, 115u8, 100u8, + 104u8, 115u8, 101u8, 0u8, 115u8, 101u8, 102u8, 115u8, 101u8, 104u8, 115u8, + 101u8, 105u8, 115u8, 101u8, 115u8, 115u8, 103u8, 0u8, 115u8, 103u8, 97u8, + 115u8, 103u8, 115u8, 115u8, 104u8, 105u8, 115u8, 104u8, 110u8, 115u8, + 105u8, 0u8, 115u8, 105u8, 100u8, 115u8, 107u8, 0u8, 115u8, 107u8, 114u8, + 115u8, 108u8, 0u8, 115u8, 108u8, 105u8, 115u8, 108u8, 121u8, 115u8, 109u8, + 0u8, 115u8, 109u8, 97u8, 115u8, 109u8, 100u8, 115u8, 109u8, 106u8, 115u8, + 109u8, 110u8, 115u8, 109u8, 112u8, 115u8, 109u8, 115u8, 115u8, 110u8, 0u8, + 115u8, 110u8, 98u8, 115u8, 110u8, 107u8, 115u8, 111u8, 0u8, 115u8, 111u8, + 103u8, 115u8, 111u8, 117u8, 115u8, 113u8, 0u8, 115u8, 114u8, 0u8, 115u8, + 114u8, 98u8, 115u8, 114u8, 110u8, 115u8, 114u8, 114u8, 115u8, 114u8, 120u8, + 115u8, 115u8, 0u8, 115u8, 115u8, 121u8, 115u8, 116u8, 0u8, 115u8, 116u8, + 113u8, 115u8, 117u8, 0u8, 115u8, 117u8, 107u8, 115u8, 117u8, 115u8, 115u8, + 118u8, 0u8, 115u8, 119u8, 0u8, 115u8, 119u8, 98u8, 115u8, 119u8, 99u8, + 115u8, 119u8, 103u8, 115u8, 119u8, 118u8, 115u8, 120u8, 110u8, 115u8, + 121u8, 108u8, 115u8, 121u8, 114u8, 115u8, 122u8, 108u8, 116u8, 97u8, 0u8, + 116u8, 97u8, 106u8, 116u8, 98u8, 119u8, 116u8, 99u8, 121u8, 116u8, 100u8, + 100u8, 116u8, 100u8, 103u8, 116u8, 100u8, 104u8, 116u8, 100u8, 117u8, + 116u8, 101u8, 0u8, 116u8, 101u8, 109u8, 116u8, 101u8, 111u8, 116u8, 101u8, + 116u8, 116u8, 103u8, 0u8, 116u8, 104u8, 0u8, 116u8, 104u8, 108u8, 116u8, + 104u8, 113u8, 116u8, 104u8, 114u8, 116u8, 105u8, 0u8, 116u8, 105u8, 103u8, + 116u8, 105u8, 118u8, 116u8, 107u8, 0u8, 116u8, 107u8, 108u8, 116u8, 107u8, + 114u8, 116u8, 107u8, 116u8, 116u8, 108u8, 0u8, 116u8, 108u8, 121u8, 116u8, + 109u8, 104u8, 116u8, 110u8, 0u8, 116u8, 111u8, 0u8, 116u8, 111u8, 103u8, + 116u8, 111u8, 107u8, 116u8, 112u8, 105u8, 116u8, 114u8, 0u8, 116u8, 114u8, + 117u8, 116u8, 114u8, 118u8, 116u8, 114u8, 119u8, 116u8, 115u8, 0u8, 116u8, + 115u8, 100u8, 116u8, 115u8, 102u8, 116u8, 115u8, 103u8, 116u8, 115u8, + 106u8, 116u8, 116u8, 0u8, 116u8, 116u8, 106u8, 116u8, 116u8, 115u8, 116u8, + 116u8, 116u8, 116u8, 117u8, 109u8, 116u8, 118u8, 108u8, 116u8, 119u8, + 113u8, 116u8, 120u8, 103u8, 116u8, 120u8, 111u8, 116u8, 121u8, 0u8, 116u8, + 121u8, 118u8, 116u8, 122u8, 109u8, 117u8, 100u8, 105u8, 117u8, 100u8, + 109u8, 117u8, 103u8, 0u8, 117u8, 103u8, 97u8, 117u8, 107u8, 0u8, 117u8, + 108u8, 105u8, 117u8, 109u8, 98u8, 117u8, 110u8, 114u8, 117u8, 110u8, 120u8, + 117u8, 114u8, 0u8, 117u8, 122u8, 0u8, 118u8, 97u8, 105u8, 118u8, 101u8, + 0u8, 118u8, 101u8, 99u8, 118u8, 101u8, 112u8, 118u8, 105u8, 0u8, 118u8, + 105u8, 99u8, 118u8, 108u8, 115u8, 118u8, 109u8, 102u8, 118u8, 109u8, 119u8, + 118u8, 111u8, 0u8, 118u8, 111u8, 116u8, 118u8, 114u8, 111u8, 118u8, 117u8, + 110u8, 119u8, 97u8, 0u8, 119u8, 97u8, 101u8, 119u8, 97u8, 108u8, 119u8, + 97u8, 114u8, 119u8, 98u8, 112u8, 119u8, 98u8, 113u8, 119u8, 98u8, 114u8, + 119u8, 108u8, 115u8, 119u8, 110u8, 105u8, 119u8, 111u8, 0u8, 119u8, 115u8, + 103u8, 119u8, 116u8, 109u8, 119u8, 117u8, 117u8, 120u8, 97u8, 118u8, 120u8, + 99u8, 111u8, 120u8, 99u8, 114u8, 120u8, 104u8, 0u8, 120u8, 108u8, 99u8, + 120u8, 108u8, 100u8, 120u8, 109u8, 102u8, 120u8, 109u8, 110u8, 120u8, + 109u8, 114u8, 120u8, 110u8, 97u8, 120u8, 110u8, 114u8, 120u8, 111u8, 103u8, + 120u8, 112u8, 114u8, 120u8, 115u8, 97u8, 120u8, 115u8, 114u8, 121u8, 97u8, + 111u8, 121u8, 97u8, 112u8, 121u8, 97u8, 118u8, 121u8, 98u8, 98u8, 121u8, + 105u8, 0u8, 121u8, 111u8, 0u8, 121u8, 114u8, 108u8, 121u8, 117u8, 97u8, + 121u8, 117u8, 101u8, 122u8, 97u8, 0u8, 122u8, 97u8, 103u8, 122u8, 100u8, + 106u8, 122u8, 101u8, 97u8, 122u8, 103u8, 104u8, 122u8, 104u8, 0u8, 122u8, + 104u8, 120u8, 122u8, 107u8, 116u8, 122u8, 108u8, 109u8, 122u8, 109u8, + 105u8, 122u8, 117u8, 0u8, 122u8, 122u8, 97u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 69u8, 84u8, 0u8, 71u8, 69u8, 0u8, 71u8, 72u8, 0u8, 73u8, 68u8, 0u8, 85u8, + 71u8, 0u8, 71u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 73u8, 82u8, + 0u8, 84u8, 78u8, 0u8, 90u8, 65u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, + 84u8, 78u8, 0u8, 71u8, 72u8, 0u8, 73u8, 81u8, 0u8, 88u8, 75u8, 0u8, 82u8, + 85u8, 0u8, 69u8, 84u8, 0u8, 78u8, 71u8, 0u8, 69u8, 83u8, 0u8, 78u8, 71u8, + 0u8, 73u8, 68u8, 0u8, 84u8, 71u8, 0u8, 69u8, 71u8, 0u8, 73u8, 82u8, 0u8, + 67u8, 76u8, 0u8, 66u8, 79u8, 0u8, 68u8, 90u8, 0u8, 83u8, 65u8, 0u8, 77u8, + 65u8, 0u8, 69u8, 71u8, 0u8, 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 85u8, 83u8, + 0u8, 69u8, 83u8, 0u8, 67u8, 65u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8, + 66u8, 79u8, 0u8, 65u8, 90u8, 0u8, 82u8, 85u8, 0u8, 80u8, 75u8, 0u8, 73u8, + 68u8, 0u8, 78u8, 80u8, 0u8, 65u8, 84u8, 0u8, 67u8, 77u8, 0u8, 67u8, 77u8, + 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 67u8, 73u8, 0u8, 66u8, 89u8, 0u8, + 83u8, 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 67u8, + 77u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 71u8, + 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8, + 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 86u8, 85u8, 0u8, 80u8, 72u8, 0u8, 78u8, + 71u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, 83u8, 78u8, 0u8, 67u8, 77u8, + 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 77u8, 89u8, 0u8, 86u8, 78u8, 0u8, + 77u8, 76u8, 0u8, 77u8, 76u8, 0u8, 66u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, + 78u8, 0u8, 73u8, 82u8, 0u8, 67u8, 73u8, 0u8, 70u8, 82u8, 0u8, 73u8, 78u8, + 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 66u8, 65u8, 0u8, 76u8, 82u8, 0u8, + 67u8, 77u8, 0u8, 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 82u8, 85u8, 0u8, 89u8, + 84u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 71u8, 81u8, 0u8, 69u8, 82u8, + 0u8, 67u8, 77u8, 0u8, 77u8, 76u8, 0u8, 69u8, 83u8, 0u8, 85u8, 83u8, 0u8, + 78u8, 71u8, 0u8, 66u8, 68u8, 0u8, 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 85u8, + 71u8, 0u8, 71u8, 85u8, 0u8, 70u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, 83u8, + 0u8, 67u8, 65u8, 0u8, 85u8, 83u8, 0u8, 85u8, 83u8, 0u8, 75u8, 72u8, 0u8, + 86u8, 78u8, 0u8, 73u8, 81u8, 0u8, 67u8, 65u8, 0u8, 77u8, 78u8, 0u8, 70u8, + 82u8, 0u8, 69u8, 71u8, 0u8, 80u8, 72u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, + 0u8, 85u8, 65u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 83u8, 67u8, 0u8, + 67u8, 90u8, 0u8, 80u8, 76u8, 0u8, 67u8, 65u8, 0u8, 77u8, 77u8, 0u8, 82u8, + 85u8, 0u8, 82u8, 85u8, 0u8, 71u8, 66u8, 0u8, 68u8, 75u8, 0u8, 67u8, 73u8, + 0u8, 85u8, 83u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, 73u8, 78u8, 0u8, + 68u8, 69u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 78u8, 69u8, 0u8, 78u8, + 71u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 68u8, 69u8, + 0u8, 77u8, 76u8, 0u8, 77u8, 89u8, 0u8, 78u8, 80u8, 0u8, 67u8, 77u8, 0u8, + 77u8, 86u8, 0u8, 83u8, 78u8, 0u8, 66u8, 70u8, 0u8, 66u8, 84u8, 0u8, 75u8, + 69u8, 0u8, 71u8, 72u8, 0u8, 78u8, 71u8, 0u8, 73u8, 84u8, 0u8, 69u8, 71u8, + 0u8, 77u8, 77u8, 0u8, 71u8, 82u8, 0u8, 85u8, 83u8, 0u8, 48u8, 48u8, 49u8, + 69u8, 83u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, 69u8, 69u8, 0u8, 73u8, + 84u8, 0u8, 69u8, 83u8, 0u8, 67u8, 77u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8, + 0u8, 71u8, 81u8, 0u8, 83u8, 78u8, 0u8, 77u8, 76u8, 0u8, 70u8, 73u8, 0u8, + 83u8, 68u8, 0u8, 80u8, 72u8, 0u8, 83u8, 69u8, 0u8, 70u8, 74u8, 0u8, 70u8, + 79u8, 0u8, 66u8, 74u8, 0u8, 70u8, 82u8, 0u8, 85u8, 83u8, 0u8, 70u8, 82u8, + 0u8, 68u8, 69u8, 0u8, 68u8, 69u8, 0u8, 67u8, 77u8, 0u8, 87u8, 70u8, 0u8, + 71u8, 78u8, 0u8, 78u8, 69u8, 0u8, 73u8, 84u8, 0u8, 78u8, 71u8, 0u8, 83u8, + 68u8, 0u8, 78u8, 76u8, 0u8, 73u8, 69u8, 0u8, 71u8, 72u8, 0u8, 77u8, 68u8, + 0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 73u8, 82u8, 0u8, + 71u8, 70u8, 0u8, 71u8, 66u8, 0u8, 69u8, 84u8, 0u8, 78u8, 80u8, 0u8, 75u8, + 73u8, 0u8, 80u8, 75u8, 0u8, 80u8, 75u8, 0u8, 69u8, 83u8, 0u8, 73u8, 82u8, + 0u8, 80u8, 89u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, + 78u8, 76u8, 0u8, 85u8, 65u8, 0u8, 67u8, 89u8, 0u8, 73u8, 78u8, 0u8, 67u8, + 72u8, 0u8, 73u8, 78u8, 0u8, 66u8, 82u8, 0u8, 67u8, 79u8, 0u8, 71u8, 72u8, + 0u8, 75u8, 69u8, 0u8, 73u8, 77u8, 0u8, 78u8, 80u8, 0u8, 67u8, 65u8, 0u8, + 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 65u8, 70u8, 0u8, 73u8, + 76u8, 0u8, 73u8, 78u8, 0u8, 70u8, 74u8, 0u8, 80u8, 72u8, 0u8, 84u8, 82u8, + 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 73u8, 78u8, 0u8, 85u8, 83u8, 0u8, + 80u8, 72u8, 0u8, 80u8, 75u8, 0u8, 80u8, 71u8, 0u8, 73u8, 78u8, 0u8, 73u8, + 78u8, 0u8, 72u8, 82u8, 0u8, 68u8, 69u8, 0u8, 67u8, 78u8, 0u8, 72u8, 84u8, + 0u8, 72u8, 85u8, 0u8, 67u8, 65u8, 0u8, 65u8, 77u8, 0u8, 78u8, 65u8, 0u8, + 48u8, 48u8, 49u8, 77u8, 89u8, 0u8, 78u8, 71u8, 0u8, 73u8, 68u8, 0u8, 84u8, + 71u8, 0u8, 78u8, 71u8, 0u8, 67u8, 78u8, 0u8, 85u8, 83u8, 0u8, 80u8, 72u8, + 0u8, 73u8, 68u8, 0u8, 82u8, 85u8, 0u8, 48u8, 48u8, 49u8, 73u8, 83u8, 0u8, + 73u8, 84u8, 0u8, 67u8, 65u8, 0u8, 73u8, 76u8, 0u8, 82u8, 85u8, 0u8, 74u8, + 80u8, 0u8, 74u8, 77u8, 0u8, 48u8, 48u8, 49u8, 67u8, 77u8, 0u8, 85u8, 65u8, + 0u8, 84u8, 90u8, 0u8, 78u8, 80u8, 0u8, 68u8, 75u8, 0u8, 73u8, 68u8, 0u8, + 73u8, 68u8, 0u8, 71u8, 69u8, 0u8, 85u8, 90u8, 0u8, 68u8, 90u8, 0u8, 77u8, + 77u8, 0u8, 78u8, 71u8, 0u8, 75u8, 69u8, 0u8, 77u8, 76u8, 0u8, 73u8, 68u8, + 0u8, 82u8, 85u8, 0u8, 78u8, 69u8, 0u8, 78u8, 71u8, 0u8, 90u8, 87u8, 0u8, + 84u8, 90u8, 0u8, 84u8, 71u8, 0u8, 84u8, 72u8, 0u8, 67u8, 86u8, 0u8, 67u8, + 77u8, 0u8, 67u8, 73u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 68u8, + 0u8, 73u8, 68u8, 0u8, 66u8, 82u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, + 73u8, 78u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, + 69u8, 0u8, 84u8, 82u8, 0u8, 78u8, 65u8, 0u8, 76u8, 65u8, 0u8, 75u8, 90u8, + 0u8, 67u8, 77u8, 0u8, 71u8, 76u8, 0u8, 75u8, 69u8, 0u8, 75u8, 72u8, 0u8, + 65u8, 79u8, 0u8, 73u8, 78u8, 0u8, 71u8, 87u8, 0u8, 75u8, 82u8, 0u8, 82u8, + 85u8, 0u8, 73u8, 78u8, 0u8, 70u8, 77u8, 0u8, 76u8, 82u8, 0u8, 82u8, 85u8, + 0u8, 83u8, 76u8, 0u8, 80u8, 72u8, 0u8, 82u8, 85u8, 0u8, 73u8, 78u8, 0u8, + 73u8, 78u8, 0u8, 84u8, 90u8, 0u8, 67u8, 77u8, 0u8, 68u8, 69u8, 0u8, 77u8, + 89u8, 0u8, 84u8, 82u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 73u8, 68u8, + 0u8, 80u8, 75u8, 0u8, 71u8, 66u8, 0u8, 67u8, 65u8, 0u8, 73u8, 78u8, 0u8, + 84u8, 72u8, 0u8, 80u8, 75u8, 0u8, 75u8, 71u8, 0u8, 77u8, 89u8, 0u8, 77u8, + 89u8, 0u8, 86u8, 65u8, 0u8, 71u8, 82u8, 0u8, 73u8, 76u8, 0u8, 84u8, 90u8, + 0u8, 80u8, 75u8, 0u8, 85u8, 71u8, 0u8, 76u8, 85u8, 0u8, 82u8, 85u8, 0u8, + 73u8, 68u8, 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 82u8, 85u8, 0u8, 85u8, + 71u8, 0u8, 78u8, 76u8, 0u8, 78u8, 80u8, 0u8, 73u8, 84u8, 0u8, 67u8, 65u8, + 0u8, 67u8, 78u8, 0u8, 73u8, 68u8, 0u8, 73u8, 82u8, 0u8, 85u8, 83u8, 0u8, + 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 67u8, 68u8, 0u8, 76u8, 65u8, 0u8, 67u8, + 68u8, 0u8, 90u8, 77u8, 0u8, 73u8, 82u8, 0u8, 76u8, 84u8, 0u8, 76u8, 86u8, + 0u8, 67u8, 68u8, 0u8, 67u8, 68u8, 0u8, 75u8, 69u8, 0u8, 75u8, 69u8, 0u8, + 73u8, 82u8, 0u8, 76u8, 86u8, 0u8, 84u8, 72u8, 0u8, 67u8, 78u8, 0u8, 84u8, + 82u8, 0u8, 73u8, 68u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, + 0u8, 73u8, 68u8, 0u8, 71u8, 77u8, 0u8, 75u8, 69u8, 0u8, 77u8, 88u8, 0u8, + 82u8, 85u8, 0u8, 80u8, 72u8, 0u8, 73u8, 68u8, 0u8, 83u8, 76u8, 0u8, 75u8, + 69u8, 0u8, 84u8, 72u8, 0u8, 77u8, 85u8, 0u8, 77u8, 71u8, 0u8, 77u8, 90u8, + 0u8, 67u8, 77u8, 0u8, 78u8, 80u8, 0u8, 84u8, 90u8, 0u8, 77u8, 72u8, 0u8, + 78u8, 90u8, 0u8, 67u8, 65u8, 0u8, 73u8, 68u8, 0u8, 77u8, 75u8, 0u8, 73u8, + 78u8, 0u8, 83u8, 68u8, 0u8, 77u8, 78u8, 0u8, 73u8, 78u8, 0u8, 77u8, 77u8, + 0u8, 82u8, 79u8, 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 66u8, 70u8, 0u8, + 73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 82u8, 85u8, 0u8, 66u8, 68u8, 0u8, 77u8, + 89u8, 0u8, 77u8, 84u8, 0u8, 73u8, 78u8, 0u8, 67u8, 77u8, 0u8, 85u8, 83u8, + 0u8, 80u8, 75u8, 0u8, 77u8, 76u8, 0u8, 73u8, 78u8, 0u8, 73u8, 68u8, 0u8, + 85u8, 83u8, 0u8, 90u8, 87u8, 0u8, 77u8, 77u8, 0u8, 82u8, 85u8, 0u8, 85u8, + 71u8, 0u8, 73u8, 82u8, 0u8, 73u8, 82u8, 0u8, 78u8, 82u8, 0u8, 67u8, 78u8, + 0u8, 73u8, 84u8, 0u8, 78u8, 65u8, 0u8, 78u8, 79u8, 0u8, 77u8, 88u8, 0u8, + 90u8, 87u8, 0u8, 77u8, 90u8, 0u8, 68u8, 69u8, 0u8, 78u8, 80u8, 0u8, 78u8, + 80u8, 0u8, 78u8, 65u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 88u8, + 0u8, 73u8, 68u8, 0u8, 78u8, 85u8, 0u8, 73u8, 78u8, 0u8, 78u8, 76u8, 0u8, + 67u8, 77u8, 0u8, 78u8, 79u8, 0u8, 67u8, 77u8, 0u8, 73u8, 78u8, 0u8, 78u8, + 79u8, 0u8, 84u8, 72u8, 0u8, 73u8, 78u8, 0u8, 83u8, 69u8, 0u8, 71u8, 78u8, + 0u8, 90u8, 65u8, 0u8, 67u8, 65u8, 0u8, 90u8, 65u8, 0u8, 73u8, 78u8, 0u8, + 83u8, 83u8, 0u8, 85u8, 83u8, 0u8, 67u8, 78u8, 0u8, 77u8, 87u8, 0u8, 84u8, + 90u8, 0u8, 85u8, 71u8, 0u8, 71u8, 72u8, 0u8, 70u8, 82u8, 0u8, 67u8, 65u8, + 0u8, 67u8, 65u8, 0u8, 67u8, 65u8, 0u8, 69u8, 84u8, 0u8, 73u8, 78u8, 0u8, + 71u8, 69u8, 0u8, 85u8, 83u8, 0u8, 77u8, 78u8, 0u8, 49u8, 52u8, 51u8, 73u8, + 78u8, 0u8, 80u8, 72u8, 0u8, 73u8, 82u8, 0u8, 80u8, 72u8, 0u8, 65u8, 87u8, + 0u8, 80u8, 87u8, 0u8, 70u8, 82u8, 0u8, 78u8, 71u8, 0u8, 85u8, 83u8, 0u8, + 67u8, 65u8, 0u8, 73u8, 82u8, 0u8, 68u8, 69u8, 0u8, 76u8, 66u8, 0u8, 83u8, + 66u8, 0u8, 73u8, 78u8, 0u8, 75u8, 69u8, 0u8, 80u8, 76u8, 0u8, 73u8, 84u8, + 0u8, 71u8, 82u8, 0u8, 70u8, 77u8, 0u8, 73u8, 78u8, 0u8, 67u8, 65u8, 0u8, + 80u8, 75u8, 0u8, 73u8, 82u8, 0u8, 48u8, 48u8, 49u8, 65u8, 70u8, 0u8, 66u8, + 82u8, 0u8, 71u8, 65u8, 0u8, 80u8, 69u8, 0u8, 71u8, 84u8, 0u8, 69u8, 67u8, + 0u8, 73u8, 78u8, 0u8, 82u8, 69u8, 0u8, 73u8, 68u8, 0u8, 73u8, 84u8, 0u8, + 77u8, 77u8, 0u8, 73u8, 78u8, 0u8, 77u8, 65u8, 0u8, 78u8, 80u8, 0u8, 66u8, + 68u8, 0u8, 67u8, 72u8, 0u8, 70u8, 73u8, 0u8, 67u8, 72u8, 0u8, 73u8, 82u8, + 0u8, 83u8, 69u8, 0u8, 66u8, 73u8, 0u8, 77u8, 90u8, 0u8, 82u8, 79u8, 0u8, + 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 70u8, 74u8, 0u8, 82u8, 85u8, 0u8, 85u8, + 65u8, 0u8, 83u8, 66u8, 0u8, 82u8, 87u8, 0u8, 84u8, 90u8, 0u8, 74u8, 80u8, + 0u8, 73u8, 78u8, 0u8, 71u8, 72u8, 0u8, 82u8, 85u8, 0u8, 75u8, 69u8, 0u8, + 73u8, 68u8, 0u8, 73u8, 78u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, 0u8, 84u8, + 90u8, 0u8, 73u8, 84u8, 0u8, 73u8, 78u8, 0u8, 73u8, 84u8, 0u8, 71u8, 66u8, + 0u8, 80u8, 75u8, 0u8, 73u8, 84u8, 0u8, 73u8, 82u8, 0u8, 78u8, 79u8, 0u8, + 67u8, 73u8, 0u8, 77u8, 90u8, 0u8, 77u8, 88u8, 0u8, 77u8, 76u8, 0u8, 67u8, + 70u8, 0u8, 73u8, 69u8, 0u8, 76u8, 84u8, 0u8, 77u8, 65u8, 0u8, 77u8, 77u8, + 0u8, 76u8, 75u8, 0u8, 69u8, 84u8, 0u8, 83u8, 75u8, 0u8, 80u8, 75u8, 0u8, + 83u8, 73u8, 0u8, 80u8, 76u8, 0u8, 73u8, 68u8, 0u8, 87u8, 83u8, 0u8, 83u8, + 69u8, 0u8, 65u8, 79u8, 0u8, 83u8, 69u8, 0u8, 70u8, 73u8, 0u8, 73u8, 76u8, + 0u8, 70u8, 73u8, 0u8, 90u8, 87u8, 0u8, 77u8, 89u8, 0u8, 77u8, 76u8, 0u8, + 83u8, 79u8, 0u8, 85u8, 90u8, 0u8, 84u8, 72u8, 0u8, 65u8, 76u8, 0u8, 82u8, + 83u8, 0u8, 73u8, 78u8, 0u8, 83u8, 82u8, 0u8, 83u8, 78u8, 0u8, 73u8, 78u8, + 0u8, 90u8, 65u8, 0u8, 69u8, 82u8, 0u8, 90u8, 65u8, 0u8, 68u8, 69u8, 0u8, + 73u8, 68u8, 0u8, 84u8, 90u8, 0u8, 71u8, 78u8, 0u8, 83u8, 69u8, 0u8, 84u8, + 90u8, 0u8, 89u8, 84u8, 0u8, 67u8, 68u8, 0u8, 68u8, 69u8, 0u8, 73u8, 78u8, + 0u8, 73u8, 68u8, 0u8, 66u8, 68u8, 0u8, 73u8, 81u8, 0u8, 80u8, 76u8, 0u8, + 73u8, 78u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 73u8, 78u8, 0u8, 67u8, + 78u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 77u8, 89u8, 0u8, 73u8, 78u8, + 0u8, 83u8, 76u8, 0u8, 85u8, 71u8, 0u8, 84u8, 76u8, 0u8, 84u8, 74u8, 0u8, + 84u8, 72u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 78u8, 80u8, 0u8, 69u8, + 84u8, 0u8, 69u8, 82u8, 0u8, 78u8, 71u8, 0u8, 84u8, 77u8, 0u8, 84u8, 75u8, + 0u8, 65u8, 90u8, 0u8, 78u8, 80u8, 0u8, 80u8, 72u8, 0u8, 65u8, 90u8, 0u8, + 78u8, 69u8, 0u8, 90u8, 65u8, 0u8, 84u8, 79u8, 0u8, 77u8, 87u8, 0u8, 48u8, + 48u8, 49u8, 80u8, 71u8, 0u8, 84u8, 82u8, 0u8, 84u8, 82u8, 0u8, 84u8, 87u8, + 0u8, 80u8, 75u8, 0u8, 90u8, 65u8, 0u8, 71u8, 82u8, 0u8, 78u8, 80u8, 0u8, + 80u8, 72u8, 0u8, 66u8, 84u8, 0u8, 82u8, 85u8, 0u8, 85u8, 71u8, 0u8, 84u8, + 72u8, 0u8, 65u8, 90u8, 0u8, 77u8, 87u8, 0u8, 84u8, 86u8, 0u8, 78u8, 69u8, + 0u8, 67u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 70u8, 0u8, 82u8, 85u8, 0u8, + 77u8, 65u8, 0u8, 82u8, 85u8, 0u8, 82u8, 85u8, 0u8, 67u8, 78u8, 0u8, 83u8, + 89u8, 0u8, 85u8, 65u8, 0u8, 70u8, 77u8, 0u8, 65u8, 79u8, 0u8, 73u8, 78u8, + 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 85u8, 90u8, 0u8, 76u8, 82u8, 0u8, + 90u8, 65u8, 0u8, 73u8, 84u8, 0u8, 82u8, 85u8, 0u8, 86u8, 78u8, 0u8, 83u8, + 88u8, 0u8, 66u8, 69u8, 0u8, 68u8, 69u8, 0u8, 77u8, 90u8, 0u8, 48u8, 48u8, + 49u8, 82u8, 85u8, 0u8, 69u8, 69u8, 0u8, 84u8, 90u8, 0u8, 66u8, 69u8, 0u8, + 67u8, 72u8, 0u8, 69u8, 84u8, 0u8, 80u8, 72u8, 0u8, 65u8, 85u8, 0u8, 73u8, + 78u8, 0u8, 73u8, 78u8, 0u8, 87u8, 70u8, 0u8, 75u8, 77u8, 0u8, 83u8, 78u8, + 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 67u8, 78u8, 0u8, 66u8, 82u8, 0u8, + 85u8, 90u8, 0u8, 84u8, 82u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, 0u8, 84u8, + 82u8, 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 83u8, 65u8, + 0u8, 73u8, 78u8, 0u8, 85u8, 71u8, 0u8, 73u8, 82u8, 0u8, 89u8, 69u8, 0u8, + 78u8, 80u8, 0u8, 77u8, 90u8, 0u8, 70u8, 77u8, 0u8, 67u8, 77u8, 0u8, 67u8, + 77u8, 0u8, 48u8, 48u8, 49u8, 78u8, 71u8, 0u8, 66u8, 82u8, 0u8, 77u8, 88u8, + 0u8, 72u8, 75u8, 0u8, 67u8, 78u8, 0u8, 83u8, 68u8, 0u8, 75u8, 77u8, 0u8, + 78u8, 76u8, 0u8, 77u8, 65u8, 0u8, 67u8, 78u8, 0u8, 67u8, 78u8, 0u8, 67u8, + 78u8, 0u8, 84u8, 71u8, 0u8, 77u8, 89u8, 0u8, 90u8, 65u8, 0u8, 84u8, 82u8, + 0u8, + ]) + }, + ) + }, + ls2r: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap2d::from_parts_unchecked( + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 97u8, 114u8, 99u8, 97u8, 122u8, 0u8, 99u8, 117u8, 0u8, 101u8, 110u8, 0u8, + 102u8, 102u8, 0u8, 103u8, 114u8, 99u8, 107u8, 107u8, 0u8, 107u8, 117u8, + 0u8, 107u8, 121u8, 0u8, 108u8, 105u8, 102u8, 109u8, 97u8, 110u8, 109u8, + 110u8, 0u8, 112u8, 97u8, 0u8, 112u8, 97u8, 108u8, 115u8, 100u8, 0u8, 116u8, + 103u8, 0u8, 117u8, 103u8, 0u8, 117u8, 110u8, 114u8, 117u8, 122u8, 0u8, + 121u8, 117u8, 101u8, 122u8, 104u8, 0u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 2u8, 0u8, 0u8, 0u8, 3u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 5u8, 0u8, 0u8, + 0u8, 6u8, 0u8, 0u8, 0u8, 7u8, 0u8, 0u8, 0u8, 8u8, 0u8, 0u8, 0u8, 10u8, 0u8, + 0u8, 0u8, 12u8, 0u8, 0u8, 0u8, 13u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, + 15u8, 0u8, 0u8, 0u8, 16u8, 0u8, 0u8, 0u8, 17u8, 0u8, 0u8, 0u8, 20u8, 0u8, + 0u8, 0u8, 21u8, 0u8, 0u8, 0u8, 22u8, 0u8, 0u8, 0u8, 23u8, 0u8, 0u8, 0u8, + 24u8, 0u8, 0u8, 0u8, 25u8, 0u8, 0u8, 0u8, 28u8, 0u8, 0u8, 0u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 78u8, 98u8, 97u8, 116u8, 80u8, 97u8, 108u8, 109u8, 65u8, 114u8, 97u8, 98u8, + 71u8, 108u8, 97u8, 103u8, 83u8, 104u8, 97u8, 119u8, 65u8, 100u8, 108u8, + 109u8, 76u8, 105u8, 110u8, 98u8, 65u8, 114u8, 97u8, 98u8, 65u8, 114u8, + 97u8, 98u8, 89u8, 101u8, 122u8, 105u8, 65u8, 114u8, 97u8, 98u8, 76u8, 97u8, + 116u8, 110u8, 76u8, 105u8, 109u8, 98u8, 78u8, 107u8, 111u8, 111u8, 77u8, + 111u8, 110u8, 103u8, 65u8, 114u8, 97u8, 98u8, 80u8, 104u8, 108u8, 112u8, + 68u8, 101u8, 118u8, 97u8, 75u8, 104u8, 111u8, 106u8, 83u8, 105u8, 110u8, + 100u8, 65u8, 114u8, 97u8, 98u8, 67u8, 121u8, 114u8, 108u8, 68u8, 101u8, + 118u8, 97u8, 65u8, 114u8, 97u8, 98u8, 72u8, 97u8, 110u8, 115u8, 66u8, + 111u8, 112u8, 111u8, 72u8, 97u8, 110u8, 98u8, 72u8, 97u8, 110u8, 116u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 74u8, 79u8, 0u8, 83u8, 89u8, 0u8, 73u8, 82u8, 0u8, 66u8, 71u8, 0u8, 71u8, + 66u8, 0u8, 71u8, 78u8, 0u8, 71u8, 82u8, 0u8, 67u8, 78u8, 0u8, 73u8, 81u8, + 0u8, 71u8, 69u8, 0u8, 67u8, 78u8, 0u8, 84u8, 82u8, 0u8, 73u8, 78u8, 0u8, + 71u8, 78u8, 0u8, 67u8, 78u8, 0u8, 80u8, 75u8, 0u8, 67u8, 78u8, 0u8, 73u8, + 78u8, 0u8, 73u8, 78u8, 0u8, 73u8, 78u8, 0u8, 80u8, 75u8, 0u8, 75u8, 90u8, + 0u8, 78u8, 80u8, 0u8, 65u8, 70u8, 0u8, 67u8, 78u8, 0u8, 84u8, 87u8, 0u8, + 84u8, 87u8, 0u8, 84u8, 87u8, 0u8, + ]) + }, + ) + }, + }; diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/mod.rs b/compiler/rustc_baked_icu_data/src/data/fallback/mod.rs new file mode 100644 index 00000000000..a485a5af64c --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/fallback/mod.rs @@ -0,0 +1,4 @@ +// @generated +pub mod likelysubtags_v1; +pub mod parents_v1; +pub mod supplement; diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs new file mode 100644 index 00000000000..f07b4b80649 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/fallback/parents_v1.rs @@ -0,0 +1,207 @@ +// @generated +type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: LocaleFallbackParentsV1Marker as :: icu_provider :: DataMarker > :: Yokeable ; +pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> = + litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]); +static UND: &DataStruct = &::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1 { + parents: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap::from_parts_unchecked( + unsafe { + ::zerovec::VarZeroVec::from_bytes_unchecked(&[ + 131u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 11u8, 0u8, 16u8, 0u8, 21u8, 0u8, + 26u8, 0u8, 31u8, 0u8, 36u8, 0u8, 41u8, 0u8, 46u8, 0u8, 51u8, 0u8, 56u8, 0u8, + 61u8, 0u8, 66u8, 0u8, 71u8, 0u8, 76u8, 0u8, 81u8, 0u8, 86u8, 0u8, 91u8, 0u8, + 96u8, 0u8, 101u8, 0u8, 106u8, 0u8, 111u8, 0u8, 116u8, 0u8, 121u8, 0u8, 126u8, + 0u8, 131u8, 0u8, 136u8, 0u8, 141u8, 0u8, 146u8, 0u8, 151u8, 0u8, 156u8, 0u8, + 161u8, 0u8, 166u8, 0u8, 171u8, 0u8, 176u8, 0u8, 181u8, 0u8, 186u8, 0u8, 191u8, + 0u8, 196u8, 0u8, 201u8, 0u8, 206u8, 0u8, 211u8, 0u8, 216u8, 0u8, 221u8, 0u8, + 226u8, 0u8, 231u8, 0u8, 236u8, 0u8, 241u8, 0u8, 246u8, 0u8, 251u8, 0u8, 0u8, + 1u8, 5u8, 1u8, 10u8, 1u8, 15u8, 1u8, 20u8, 1u8, 25u8, 1u8, 30u8, 1u8, 35u8, + 1u8, 40u8, 1u8, 45u8, 1u8, 50u8, 1u8, 55u8, 1u8, 60u8, 1u8, 65u8, 1u8, 70u8, + 1u8, 75u8, 1u8, 80u8, 1u8, 85u8, 1u8, 90u8, 1u8, 95u8, 1u8, 100u8, 1u8, 105u8, + 1u8, 110u8, 1u8, 115u8, 1u8, 120u8, 1u8, 125u8, 1u8, 130u8, 1u8, 135u8, 1u8, + 140u8, 1u8, 145u8, 1u8, 150u8, 1u8, 155u8, 1u8, 160u8, 1u8, 165u8, 1u8, 170u8, + 1u8, 175u8, 1u8, 180u8, 1u8, 185u8, 1u8, 190u8, 1u8, 195u8, 1u8, 200u8, 1u8, + 205u8, 1u8, 210u8, 1u8, 215u8, 1u8, 220u8, 1u8, 225u8, 1u8, 230u8, 1u8, 235u8, + 1u8, 240u8, 1u8, 245u8, 1u8, 250u8, 1u8, 255u8, 1u8, 4u8, 2u8, 9u8, 2u8, 14u8, + 2u8, 19u8, 2u8, 24u8, 2u8, 29u8, 2u8, 34u8, 2u8, 39u8, 2u8, 44u8, 2u8, 49u8, + 2u8, 54u8, 2u8, 59u8, 2u8, 64u8, 2u8, 71u8, 2u8, 73u8, 2u8, 75u8, 2u8, 77u8, + 2u8, 82u8, 2u8, 87u8, 2u8, 92u8, 2u8, 97u8, 2u8, 102u8, 2u8, 107u8, 2u8, 112u8, + 2u8, 117u8, 2u8, 122u8, 2u8, 127u8, 2u8, 132u8, 2u8, 101u8, 110u8, 45u8, 49u8, + 53u8, 48u8, 101u8, 110u8, 45u8, 65u8, 71u8, 101u8, 110u8, 45u8, 65u8, 73u8, + 101u8, 110u8, 45u8, 65u8, 84u8, 101u8, 110u8, 45u8, 65u8, 85u8, 101u8, 110u8, + 45u8, 66u8, 66u8, 101u8, 110u8, 45u8, 66u8, 69u8, 101u8, 110u8, 45u8, 66u8, + 77u8, 101u8, 110u8, 45u8, 66u8, 83u8, 101u8, 110u8, 45u8, 66u8, 87u8, 101u8, + 110u8, 45u8, 66u8, 90u8, 101u8, 110u8, 45u8, 67u8, 67u8, 101u8, 110u8, 45u8, + 67u8, 72u8, 101u8, 110u8, 45u8, 67u8, 75u8, 101u8, 110u8, 45u8, 67u8, 77u8, + 101u8, 110u8, 45u8, 67u8, 88u8, 101u8, 110u8, 45u8, 67u8, 89u8, 101u8, 110u8, + 45u8, 68u8, 69u8, 101u8, 110u8, 45u8, 68u8, 71u8, 101u8, 110u8, 45u8, 68u8, + 75u8, 101u8, 110u8, 45u8, 68u8, 77u8, 101u8, 110u8, 45u8, 69u8, 82u8, 101u8, + 110u8, 45u8, 70u8, 73u8, 101u8, 110u8, 45u8, 70u8, 74u8, 101u8, 110u8, 45u8, + 70u8, 75u8, 101u8, 110u8, 45u8, 70u8, 77u8, 101u8, 110u8, 45u8, 71u8, 66u8, + 101u8, 110u8, 45u8, 71u8, 68u8, 101u8, 110u8, 45u8, 71u8, 71u8, 101u8, 110u8, + 45u8, 71u8, 72u8, 101u8, 110u8, 45u8, 71u8, 73u8, 101u8, 110u8, 45u8, 71u8, + 77u8, 101u8, 110u8, 45u8, 71u8, 89u8, 101u8, 110u8, 45u8, 72u8, 75u8, 101u8, + 110u8, 45u8, 73u8, 69u8, 101u8, 110u8, 45u8, 73u8, 76u8, 101u8, 110u8, 45u8, + 73u8, 77u8, 101u8, 110u8, 45u8, 73u8, 78u8, 101u8, 110u8, 45u8, 73u8, 79u8, + 101u8, 110u8, 45u8, 74u8, 69u8, 101u8, 110u8, 45u8, 74u8, 77u8, 101u8, 110u8, + 45u8, 75u8, 69u8, 101u8, 110u8, 45u8, 75u8, 73u8, 101u8, 110u8, 45u8, 75u8, + 78u8, 101u8, 110u8, 45u8, 75u8, 89u8, 101u8, 110u8, 45u8, 76u8, 67u8, 101u8, + 110u8, 45u8, 76u8, 82u8, 101u8, 110u8, 45u8, 76u8, 83u8, 101u8, 110u8, 45u8, + 77u8, 71u8, 101u8, 110u8, 45u8, 77u8, 79u8, 101u8, 110u8, 45u8, 77u8, 83u8, + 101u8, 110u8, 45u8, 77u8, 84u8, 101u8, 110u8, 45u8, 77u8, 85u8, 101u8, 110u8, + 45u8, 77u8, 86u8, 101u8, 110u8, 45u8, 77u8, 87u8, 101u8, 110u8, 45u8, 77u8, + 89u8, 101u8, 110u8, 45u8, 78u8, 65u8, 101u8, 110u8, 45u8, 78u8, 70u8, 101u8, + 110u8, 45u8, 78u8, 71u8, 101u8, 110u8, 45u8, 78u8, 76u8, 101u8, 110u8, 45u8, + 78u8, 82u8, 101u8, 110u8, 45u8, 78u8, 85u8, 101u8, 110u8, 45u8, 78u8, 90u8, + 101u8, 110u8, 45u8, 80u8, 71u8, 101u8, 110u8, 45u8, 80u8, 75u8, 101u8, 110u8, + 45u8, 80u8, 78u8, 101u8, 110u8, 45u8, 80u8, 87u8, 101u8, 110u8, 45u8, 82u8, + 87u8, 101u8, 110u8, 45u8, 83u8, 66u8, 101u8, 110u8, 45u8, 83u8, 67u8, 101u8, + 110u8, 45u8, 83u8, 68u8, 101u8, 110u8, 45u8, 83u8, 69u8, 101u8, 110u8, 45u8, + 83u8, 71u8, 101u8, 110u8, 45u8, 83u8, 72u8, 101u8, 110u8, 45u8, 83u8, 73u8, + 101u8, 110u8, 45u8, 83u8, 76u8, 101u8, 110u8, 45u8, 83u8, 83u8, 101u8, 110u8, + 45u8, 83u8, 88u8, 101u8, 110u8, 45u8, 83u8, 90u8, 101u8, 110u8, 45u8, 84u8, + 67u8, 101u8, 110u8, 45u8, 84u8, 75u8, 101u8, 110u8, 45u8, 84u8, 79u8, 101u8, + 110u8, 45u8, 84u8, 84u8, 101u8, 110u8, 45u8, 84u8, 86u8, 101u8, 110u8, 45u8, + 84u8, 90u8, 101u8, 110u8, 45u8, 85u8, 71u8, 101u8, 110u8, 45u8, 86u8, 67u8, + 101u8, 110u8, 45u8, 86u8, 71u8, 101u8, 110u8, 45u8, 86u8, 85u8, 101u8, 110u8, + 45u8, 87u8, 83u8, 101u8, 110u8, 45u8, 90u8, 65u8, 101u8, 110u8, 45u8, 90u8, + 77u8, 101u8, 110u8, 45u8, 90u8, 87u8, 101u8, 115u8, 45u8, 65u8, 82u8, 101u8, + 115u8, 45u8, 66u8, 79u8, 101u8, 115u8, 45u8, 66u8, 82u8, 101u8, 115u8, 45u8, + 66u8, 90u8, 101u8, 115u8, 45u8, 67u8, 76u8, 101u8, 115u8, 45u8, 67u8, 79u8, + 101u8, 115u8, 45u8, 67u8, 82u8, 101u8, 115u8, 45u8, 67u8, 85u8, 101u8, 115u8, + 45u8, 68u8, 79u8, 101u8, 115u8, 45u8, 69u8, 67u8, 101u8, 115u8, 45u8, 71u8, + 84u8, 101u8, 115u8, 45u8, 72u8, 78u8, 101u8, 115u8, 45u8, 77u8, 88u8, 101u8, + 115u8, 45u8, 78u8, 73u8, 101u8, 115u8, 45u8, 80u8, 65u8, 101u8, 115u8, 45u8, + 80u8, 69u8, 101u8, 115u8, 45u8, 80u8, 82u8, 101u8, 115u8, 45u8, 80u8, 89u8, + 101u8, 115u8, 45u8, 83u8, 86u8, 101u8, 115u8, 45u8, 85u8, 83u8, 101u8, 115u8, + 45u8, 85u8, 89u8, 101u8, 115u8, 45u8, 86u8, 69u8, 104u8, 105u8, 45u8, 76u8, + 97u8, 116u8, 110u8, 104u8, 116u8, 110u8, 98u8, 110u8, 110u8, 112u8, 116u8, + 45u8, 65u8, 79u8, 112u8, 116u8, 45u8, 67u8, 72u8, 112u8, 116u8, 45u8, 67u8, + 86u8, 112u8, 116u8, 45u8, 70u8, 82u8, 112u8, 116u8, 45u8, 71u8, 81u8, 112u8, + 116u8, 45u8, 71u8, 87u8, 112u8, 116u8, 45u8, 76u8, 85u8, 112u8, 116u8, 45u8, + 77u8, 79u8, 112u8, 116u8, 45u8, 77u8, 90u8, 112u8, 116u8, 45u8, 83u8, 84u8, + 112u8, 116u8, 45u8, 84u8, 76u8, 122u8, 104u8, 45u8, 72u8, 97u8, 110u8, 116u8, + 45u8, 77u8, 79u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, + 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 49u8, 53u8, 48u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 48u8, 48u8, 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, + 49u8, 101u8, 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, + 110u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 48u8, 48u8, 49u8, 101u8, 115u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, + 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, + 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, + 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, + 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, + 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, + 57u8, 101u8, 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, + 115u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 115u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 52u8, 49u8, 57u8, 101u8, 110u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 73u8, 78u8, 0u8, 102u8, 114u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 1u8, 72u8, 84u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 110u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, + 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, + 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 112u8, 116u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 1u8, 80u8, 84u8, 0u8, 122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8, + 116u8, 1u8, 72u8, 75u8, 0u8, + ]) + }, + ) + }, +}; diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs new file mode 100644 index 00000000000..7df33c12e3d --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/co_v1.rs @@ -0,0 +1,41 @@ +// @generated +type DataStruct = < :: icu_provider_adapters :: fallback :: provider :: CollationFallbackSupplementV1Marker as :: icu_provider :: DataMarker > :: Yokeable ; +pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> = + litemap::LiteMap::from_sorted_store_unchecked(&[("und", UND)]); +static UND: &DataStruct = + &::icu_provider_adapters::fallback::provider::LocaleFallbackSupplementV1 { + parents: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap::from_parts_unchecked( + unsafe { + ::zerovec::VarZeroVec::from_bytes_unchecked(&[ + 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 121u8, 117u8, 101u8, + ]) + }, + unsafe { + ::zerovec::ZeroVec::from_bytes_unchecked(&[ + 122u8, 104u8, 0u8, 1u8, 72u8, 97u8, 110u8, 116u8, 0u8, 0u8, 0u8, 0u8, + ]) + }, + ) + }, + unicode_extension_defaults: unsafe { + #[allow(unused_unsafe)] + ::zerovec::ZeroMap2d::from_parts_unchecked( + unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[99u8, 111u8]) }, + unsafe { ::zerovec::ZeroVec::from_bytes_unchecked(&[2u8, 0u8, 0u8, 0u8]) }, + unsafe { + ::zerovec::VarZeroVec::from_bytes_unchecked(&[ + 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 122u8, 104u8, 122u8, 104u8, 45u8, + 72u8, 97u8, 110u8, 116u8, + ]) + }, + unsafe { + ::zerovec::VarZeroVec::from_bytes_unchecked(&[ + 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 6u8, 0u8, 112u8, 105u8, 110u8, 121u8, 105u8, + 110u8, 115u8, 116u8, 114u8, 111u8, 107u8, 101u8, + ]) + }, + ) + }, + }; diff --git a/compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs new file mode 100644 index 00000000000..62957134f07 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/fallback/supplement/mod.rs @@ -0,0 +1,2 @@ +// @generated +pub mod co_v1; diff --git a/compiler/rustc_baked_icu_data/src/data/list/and_v1.rs b/compiler/rustc_baked_icu_data/src/data/list/and_v1.rs new file mode 100644 index 00000000000..9cae549e118 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/list/and_v1.rs @@ -0,0 +1,1161 @@ +// @generated +type DataStruct = <::icu_list::provider::AndListV1Marker as ::icu_provider::DataMarker>::Yokeable; +pub static DATA: litemap::LiteMap<&str, &DataStruct, &[(&str, &DataStruct)]> = + litemap::LiteMap::from_sorted_store_unchecked(&[ + ("en", EN), + ("es", ES), + ("fr", FR), + ("it", IT), + ("ja", JA), + ("pt", PT), + ("ru", RU), + ("tr", TR), + ("und", UND), + ("zh", ZH_ZH_HANS), + ("zh-Hans", ZH_ZH_HANS), + ("zh-Hant", ZH_HANT), + ]); +static EN: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", and ", 6u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" and ", 5u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", & ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" & ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static ES: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" y ", 3u8) + }, + special_case: Some(::icu_list::provider::SpecialCasePattern { + condition: unsafe { + ::icu_list::provider::StringMatcher::from_dfa_bytes_unchecked(&[ + 114u8, 117u8, 115u8, 116u8, 45u8, 114u8, 101u8, 103u8, 101u8, 120u8, 45u8, + 97u8, 117u8, 116u8, 111u8, 109u8, 97u8, 116u8, 97u8, 45u8, 100u8, 102u8, 97u8, + 45u8, 115u8, 112u8, 97u8, 114u8, 115u8, 101u8, 0u8, 0u8, 255u8, 254u8, 0u8, + 0u8, 2u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 1u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 1u8, 2u8, 2u8, 2u8, 3u8, 4u8, 4u8, 5u8, 6u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, 7u8, + 7u8, 7u8, 7u8, 8u8, 9u8, 9u8, 9u8, 10u8, 11u8, 11u8, 12u8, 13u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, + 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 14u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, + 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 15u8, 16u8, 16u8, 16u8, + 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, 16u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, + 17u8, 17u8, 17u8, 17u8, 17u8, 17u8, 18u8, 18u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, + 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 19u8, 20u8, + 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 21u8, 22u8, + 23u8, 23u8, 24u8, 25u8, 25u8, 25u8, 26u8, 27u8, 27u8, 27u8, 27u8, 27u8, 27u8, + 27u8, 27u8, 27u8, 27u8, 27u8, 40u8, 1u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 128u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 5u8, + 0u8, 5u8, 5u8, 6u8, 6u8, 12u8, 12u8, 13u8, 13u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 83u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 2u8, 0u8, 0u8, 27u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, + 0u8, 0u8, 3u8, 0u8, 6u8, 6u8, 13u8, 13u8, 0u8, 0u8, 104u8, 0u8, 0u8, 0u8, + 104u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 14u8, 0u8, 0u8, 0u8, 2u8, 2u8, + 4u8, 7u8, 9u8, 9u8, 11u8, 14u8, 19u8, 19u8, 20u8, 20u8, 21u8, 21u8, 22u8, 22u8, + 23u8, 23u8, 24u8, 24u8, 25u8, 25u8, 26u8, 26u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, 0u8, 68u8, 0u8, 0u8, + 0u8, 191u8, 0u8, 0u8, 0u8, 206u8, 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 236u8, + 0u8, 0u8, 0u8, 221u8, 0u8, 0u8, 0u8, 251u8, 0u8, 0u8, 0u8, 10u8, 1u8, 0u8, 0u8, + 25u8, 1u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 68u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 17u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 16u8, 0u8, 0u8, + 191u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 16u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 17u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 15u8, 15u8, 0u8, 0u8, + 221u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 35u8, + 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, 0u8, 9u8, 0u8, 0u8, 0u8, 18u8, 0u8, 0u8, 0u8, + 18u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 35u8, 0u8, 0u8, + 0u8, 35u8, 0u8, 0u8, 0u8, + ]) + }, + pattern: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + }), + }, +]); +static FR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" et ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static IT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, +]); +static JA: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, +]); +static PT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" e ", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static RU: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" и ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static TR: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(" ve ", 4u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static UND: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked(", ", 2u8) + }, + special_case: None, + }, +]); +static ZH_HANT: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, +]); +static ZH_ZH_HANS: &DataStruct = &::icu_list::provider::ListFormatterPatternsV1([ + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("和", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, + ::icu_list::provider::ConditionalListJoinerPattern { + default: unsafe { + ::icu_list::provider::ListJoinerPattern::from_parts_unchecked("、", 3u8) + }, + special_case: None, + }, +]); diff --git a/compiler/rustc_baked_icu_data/src/data/list/mod.rs b/compiler/rustc_baked_icu_data/src/data/list/mod.rs new file mode 100644 index 00000000000..931822513cc --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/list/mod.rs @@ -0,0 +1,2 @@ +// @generated +pub mod and_v1; diff --git a/compiler/rustc_baked_icu_data/src/data/mod.rs b/compiler/rustc_baked_icu_data/src/data/mod.rs new file mode 100644 index 00000000000..a6a71c79cd1 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/data/mod.rs @@ -0,0 +1,90 @@ +// @generated +mod fallback; +mod list; +/// This data provider was programmatically generated by [`icu_datagen`]( +/// https://unicode-org.github.io/icu4x-docs/doc/icu_datagen/enum.Out.html#variant.Module). +#[non_exhaustive] +pub struct BakedDataProvider; +use ::icu_provider::prelude::*; +impl DataProvider<::icu_list::provider::AndListV1Marker> for BakedDataProvider { + fn load( + &self, + req: DataRequest, + ) -> Result<DataResponse<::icu_list::provider::AndListV1Marker>, DataError> { + Ok(DataResponse { + metadata: Default::default(), + payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from( + *list::and_v1::DATA + .get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()) + .ok_or_else(|| { + DataErrorKind::MissingLocale + .with_req(::icu_list::provider::AndListV1Marker::KEY, req) + })?, + ))), + }) + } +} +impl DataProvider<::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker> + for BakedDataProvider +{ + fn load( + &self, + req: DataRequest, + ) -> Result< + DataResponse< + ::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker, + >, + DataError, + > { + Ok(DataResponse { + metadata: Default::default(), + payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from( + *fallback::supplement::co_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| { + DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::CollationFallbackSupplementV1Marker::KEY, req) + })?, + ))), + }) + } +} +impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker> + for BakedDataProvider +{ + fn load( + &self, + req: DataRequest, + ) -> Result< + DataResponse< + ::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker, + >, + DataError, + > { + Ok(DataResponse { + metadata: Default::default(), + payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from( + *fallback::likelysubtags_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| { + DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackLikelySubtagsV1Marker::KEY, req) + })?, + ))), + }) + } +} +impl DataProvider<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker> + for BakedDataProvider +{ + fn load( + &self, + req: DataRequest, + ) -> Result< + DataResponse<::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker>, + DataError, + > { + Ok(DataResponse { + metadata: Default::default(), + payload: Some(DataPayload::from_owned(zerofrom::ZeroFrom::zero_from( + *fallback::parents_v1::DATA.get_by(|k| req.locale.strict_cmp(k.as_bytes()).reverse()).ok_or_else(|| { + DataErrorKind::MissingLocale.with_req(::icu_provider_adapters::fallback::provider::LocaleFallbackParentsV1Marker::KEY, req) + })?, + ))), + }) + } +} diff --git a/compiler/rustc_baked_icu_data/src/lib.rs b/compiler/rustc_baked_icu_data/src/lib.rs new file mode 100644 index 00000000000..4651e03f771 --- /dev/null +++ b/compiler/rustc_baked_icu_data/src/lib.rs @@ -0,0 +1,46 @@ +//! This crate contains pre-baked ICU4X data, generated by `icu4x-datagen`. The tool +//! fetches locale data from CLDR and transforms them into const code in statics that +//! ICU4X can load, via databake. `lib.rs` in this crate is manually written, but all +//! other code is generated. +//! +//! This crate can be regenerated when there's a new CLDR version, though that is unlikely +//! to result in changes in most cases (currently this only covers list formatting data, which +//! is rather stable). It may need to be regenerated when updating ICU4X versions, especially +//! across major versions, in case it fails to compile after an update. +//! +//! It must be regenerated when adding new locales to Rust, or if Rust's usage of ICU4X +//! grows to need more kinds of data. +//! +//! To regenerate the data, run this command: +//! +//! ```text +//! icu4x-datagen -W --pretty --fingerprint --use-separate-crates \ +//! --format mod -l en es fr it ja pt ru tr zh zh-Hans zh-Hant \ +//! -k list/and@1 fallback/likelysubtags@1 fallback/parents@1 fallback/supplement/co@1 \ +//! --cldr-tag latest --icuexport-tag latest -o src/data +//! ``` +#![allow(elided_lifetimes_in_paths)] + +mod data { + include!("data/mod.rs"); + include!("data/any.rs"); +} + +pub use data::BakedDataProvider; + +pub const fn baked_data_provider() -> BakedDataProvider { + data::BakedDataProvider +} + +pub mod supported_locales { + pub const EN: icu_locid::Locale = icu_locid::locale!("en"); + pub const ES: icu_locid::Locale = icu_locid::locale!("es"); + pub const FR: icu_locid::Locale = icu_locid::locale!("fr"); + pub const IT: icu_locid::Locale = icu_locid::locale!("it"); + pub const JA: icu_locid::Locale = icu_locid::locale!("ja"); + pub const PT: icu_locid::Locale = icu_locid::locale!("pt"); + pub const RU: icu_locid::Locale = icu_locid::locale!("ru"); + pub const TR: icu_locid::Locale = icu_locid::locale!("tr"); + pub const ZH_HANS: icu_locid::Locale = icu_locid::locale!("zh-Hans"); + pub const ZH_HANT: icu_locid::Locale = icu_locid::locale!("zh-Hant"); +} diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 9e0aa57b255..5f99d86b4ea 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -7,7 +7,7 @@ use rustc_errors::{ }; use rustc_hir as hir; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; -use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; +use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; use rustc_middle::mir::tcx::PlaceTy; @@ -489,12 +489,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // but the type has region variables, so erase those. tcx.infer_ctxt() .build() - .type_implements_trait( - default_trait, - tcx.erase_regions(ty), - ty::List::empty(), - param_env, - ) + .type_implements_trait(default_trait, [tcx.erase_regions(ty)], param_env) .must_apply_modulo_regions() }; @@ -606,7 +601,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { else { return; }; // Try to find predicates on *generic params* that would allow copying `ty` let infcx = tcx.infer_ctxt().build(); - let copy_did = infcx.tcx.lang_items().copy_trait().unwrap(); + let copy_did = infcx.tcx.require_lang_item(LangItem::Copy, Some(span)); let cause = ObligationCause::new( span, self.mir_hir_id(), @@ -1707,7 +1702,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(borrow_span, note); let tcx = self.infcx.tcx; - let ty_params = ty::List::empty(); let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; let return_ty = tcx.erase_regions(return_ty); @@ -1716,7 +1710,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) && self .infcx - .type_implements_trait(iter_trait, return_ty, ty_params, self.param_env) + .type_implements_trait(iter_trait, [return_ty], self.param_env) .must_apply_modulo_regions() { err.span_suggestion_hidden( diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 7f26af67c71..4c3216d9878 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { def.non_enum_variant() }; - if !including_tuple_field.0 && variant.ctor_kind == CtorKind::Fn { + if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) { return None; } Some(variant.fields[field.index()].name.to_string()) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 4a4887f1970..163170a1d1a 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -19,7 +19,7 @@ extern crate tracing; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_data_structures::vec_map::VecMap; -use rustc_errors::{Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; +use rustc_errors::{Diagnostic, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; @@ -192,13 +192,13 @@ fn do_mir_borrowck<'tcx>( } } - let mut errors = error::BorrowckErrors::new(); + let mut errors = error::BorrowckErrors::new(infcx.tcx); // Gather the upvars of a closure, if any. let tables = tcx.typeck_opt_const_arg(def); - if let Some(ErrorGuaranteed { .. }) = tables.tainted_by_errors { - infcx.set_tainted_by_errors(); - errors.set_tainted_by_errors(); + if let Some(e) = tables.tainted_by_errors { + infcx.set_tainted_by_errors(e); + errors.set_tainted_by_errors(e); } let upvars: Vec<_> = tables .closure_min_captures_flattened(def.did) @@ -2260,6 +2260,7 @@ mod error { use super::*; pub struct BorrowckErrors<'tcx> { + tcx: TyCtxt<'tcx>, /// This field keeps track of move errors that are to be reported for given move indices. /// /// There are situations where many errors can be reported for a single move out (see #53807) @@ -2282,19 +2283,24 @@ mod error { tainted_by_errors: Option<ErrorGuaranteed>, } - impl BorrowckErrors<'_> { - pub fn new() -> Self { + impl<'tcx> BorrowckErrors<'tcx> { + pub fn new(tcx: TyCtxt<'tcx>) -> Self { BorrowckErrors { + tcx, buffered_move_errors: BTreeMap::new(), buffered: Default::default(), tainted_by_errors: None, } } - // FIXME(eddyb) this is a suboptimal API because `tainted_by_errors` is - // set before any emission actually happens (weakening the guarantee). pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_, ErrorGuaranteed>) { - self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + if let None = self.tainted_by_errors { + self.tainted_by_errors = Some( + self.tcx + .sess + .delay_span_bug(t.span.clone(), "diagnostic buffered but not emitted"), + ) + } t.buffer(&mut self.buffered); } @@ -2302,8 +2308,8 @@ mod error { t.buffer(&mut self.buffered); } - pub fn set_tainted_by_errors(&mut self) { - self.tainted_by_errors = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + pub fn set_tainted_by_errors(&mut self, e: ErrorGuaranteed) { + self.tainted_by_errors = Some(e); } } diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index b48f9f97daa..b5e00f471d2 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -11,6 +11,7 @@ use std::ops::Index; /// Compactly stores a set of `R0 member of [R1...Rn]` constraints, /// indexed by the region `R0`. +#[derive(Debug)] pub(crate) struct MemberConstraintSet<'tcx, R> where R: Copy + Eq, @@ -31,6 +32,7 @@ where } /// Represents a `R0 member of [R1..Rn]` constraint +#[derive(Debug)] pub(crate) struct NllMemberConstraint<'tcx> { next_constraint: Option<NllMemberConstraintIndex>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index f8856b56d14..4a12e1b1b92 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -303,7 +303,10 @@ pub(crate) fn compute_regions<'cx, 'tcx>( if !nll_errors.is_empty() { // Suppress unhelpful extra errors in `infer_opaque_types`. - infcx.set_tainted_by_errors(); + infcx.set_tainted_by_errors(infcx.tcx.sess.delay_span_bug( + body.span, + "`compute_regions` tainted `infcx` with errors but did not emit any errors", + )); } let remapped_opaque_tys = regioncx.infer_opaque_types(&infcx, opaque_type_values); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 94e9e05e5d6..b35abbd107b 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -128,6 +128,7 @@ pub struct RegionInferenceContext<'tcx> { /// adds a new lower bound to the SCC it is analyzing: so you wind up /// with `'R: 'O` where `'R` is the pick-region and `'O` is the /// minimal viable option. +#[derive(Debug)] pub(crate) struct AppliedMemberConstraint { /// The SCC that was affected. (The "member region".) /// diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index dd222485daf..d82d4cc39fb 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; use rustc_data_structures::vec_map::VecMap; use rustc_hir::def_id::LocalDefId; use rustc_hir::OpaqueTyOrigin; @@ -7,9 +7,7 @@ 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::{ - self, OpaqueHiddenType, OpaqueTypeKey, ToPredicate, Ty, TyCtxt, TypeFoldable, -}; +use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::ObligationCtxt; @@ -63,17 +61,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { opaque_ty_decls: VecMap<OpaqueTypeKey<'tcx>, (OpaqueHiddenType<'tcx>, OpaqueTyOrigin)>, ) -> VecMap<LocalDefId, OpaqueHiddenType<'tcx>> { let mut result: VecMap<LocalDefId, OpaqueHiddenType<'tcx>> = VecMap::new(); + + let member_constraints: FxHashMap<_, _> = self + .member_constraints + .all_indices() + .map(|ci| (self.member_constraints[ci].key, ci)) + .collect(); + debug!(?member_constraints); + for (opaque_type_key, (concrete_type, origin)) in opaque_ty_decls { let substs = opaque_type_key.substs; debug!(?concrete_type, ?substs); let mut subst_regions = vec![self.universal_regions.fr_static]; - let universal_substs = infcx.tcx.fold_regions(substs, |region, _| { - if let ty::RePlaceholder(..) = region.kind() { - // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. - return region; - } - let vid = self.to_region_vid(region); + + let to_universal_region = |vid, subst_regions: &mut Vec<_>| { trace!(?vid); let scc = self.constraint_sccs.scc(vid); trace!(?scc); @@ -94,10 +96,33 @@ impl<'tcx> RegionInferenceContext<'tcx> { infcx.tcx.lifetimes.re_static } } + }; + + // Start by inserting universal regions from the member_constraint choice regions. + // This will ensure they get precedence when folding the regions in the concrete type. + if let Some(&ci) = member_constraints.get(&opaque_type_key) { + for &vid in self.member_constraints.choice_regions(ci) { + to_universal_region(vid, &mut subst_regions); + } + } + debug!(?subst_regions); + + // Next, insert universal regions from substs, so we can translate regions that appear + // in them but are not subject to member constraints, for instance closure substs. + let universal_substs = infcx.tcx.fold_regions(substs, |region, _| { + if let ty::RePlaceholder(..) = region.kind() { + // Higher kinded regions don't need remapping, they don't refer to anything outside of this the substs. + return region; + } + let vid = self.to_region_vid(region); + to_universal_region(vid, &mut subst_regions) }); + debug!(?universal_substs); + debug!(?subst_regions); - subst_regions.sort(); - subst_regions.dedup(); + // Deduplicate the set of regions while keeping the chosen order. + let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>(); + debug!(?subst_regions); let universal_concrete_type = infcx.tcx.fold_regions(concrete_type, |region, _| match *region { @@ -108,8 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap_or(infcx.tcx.lifetimes.re_erased), _ => region, }); - - debug!(?universal_concrete_type, ?universal_substs); + debug!(?universal_concrete_type); let opaque_type_key = OpaqueTypeKey { def_id: opaque_type_key.def_id, substs: universal_substs }; @@ -221,8 +245,8 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { instantiated_ty: OpaqueHiddenType<'tcx>, origin: OpaqueTyOrigin, ) -> Ty<'tcx> { - if self.is_tainted_by_errors() { - return self.tcx.ty_error(); + if let Some(e) = self.tainted_by_errors() { + return self.tcx.ty_error_with_guaranteed(e); } let definition_ty = instantiated_ty @@ -256,8 +280,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { // Require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())) - .to_predicate(infcx.tcx); + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into())); let id_substs = InternalSubsts::identity_for_item(self.tcx, def_id.to_def_id()); @@ -282,6 +305,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { } ocx.register_obligation(Obligation::misc( + infcx.tcx, instantiated_ty.span, body_id, param_env, diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index a581726a15c..d0cf8622a44 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -92,8 +92,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { trait_ref, constness: ty::BoundConstness::NotConst, polarity: ty::ImplPolarity::Positive, - })) - .to_predicate(self.tcx()), + })), locations, category, ); @@ -122,14 +121,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { pub(super) fn prove_predicates( &mut self, - predicates: impl IntoIterator<Item = impl ToPredicate<'tcx>>, + predicates: impl IntoIterator< + Item = impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug, + >, locations: Locations, category: ConstraintCategory<'tcx>, ) { for predicate in predicates { - let predicate = predicate.to_predicate(self.tcx()); - debug!("prove_predicates(predicate={:?}, locations={:?})", predicate, locations,); - self.prove_predicate(predicate, locations, category); } } @@ -137,11 +135,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self), level = "debug")] pub(super) fn prove_predicate( &mut self, - predicate: ty::Predicate<'tcx>, + predicate: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + std::fmt::Debug, locations: Locations, category: ConstraintCategory<'tcx>, ) { let param_env = self.param_env; + let predicate = predicate.to_predicate(self.tcx()); self.fully_perform_op( locations, category, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 6ccc29b09c0..7467212bed8 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -33,8 +33,7 @@ use rustc_middle::ty::subst::{SubstsRef, UserSubsts}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ self, Binder, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, Dynamic, - OpaqueHiddenType, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, - UserTypeAnnotationIndex, + OpaqueHiddenType, OpaqueTypeKey, RegionVid, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, }; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; @@ -548,10 +547,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { if let PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) = context { let tcx = self.tcx(); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Copy, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty.ty, &[]), - }; + let trait_ref = tcx.at(self.last_span).mk_trait_ref(LangItem::Copy, [place_ty.ty]); // To have a `Copy` operand, the type `T` of the // value must be `Copy`. Note that we prove that `T: Copy`, @@ -1069,8 +1065,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } self.prove_predicate( - ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(inferred_ty.into())), Locations::All(span), ConstraintCategory::TypeAnnotation, ); @@ -1275,10 +1270,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.check_rvalue(body, rv, location); if !self.unsized_feature_enabled() { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(place_ty, &[]), - }; + let trait_ref = + tcx.at(self.last_span).mk_trait_ref(LangItem::Sized, [place_ty]); self.prove_trait_ref( trait_ref, location.to_locations(), @@ -1566,10 +1559,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } None => { - if !self - .tcx() - .conservative_is_privately_uninhabited(self.param_env.and(sig.output())) - { + if !sig.output().is_privately_uninhabited(self.tcx(), self.param_env) { span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); } } @@ -1845,6 +1835,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { #[instrument(skip(self, body), level = "debug")] fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) { let tcx = self.tcx(); + let span = body.source_info(location).span; match rvalue { Rvalue::Aggregate(ak, ops) => { @@ -1868,12 +1859,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } Operand::Move(place) => { // Make sure that repeated elements implement `Copy`. - let span = body.source_info(location).span; let ty = place.ty(body, tcx).ty; - let trait_ref = ty::TraitRef::new( - tcx.require_lang_item(LangItem::Copy, Some(span)), - tcx.mk_substs_trait(ty, &[]), - ); + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Copy, [ty]); self.prove_trait_ref( trait_ref, @@ -1886,10 +1873,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } &Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, ty) => { - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [ty]); self.prove_trait_ref( trait_ref, @@ -1901,10 +1885,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::ShallowInitBox(operand, ty) => { self.check_operand(operand, location); - let trait_ref = ty::TraitRef { - def_id: tcx.require_lang_item(LangItem::Sized, Some(self.last_span)), - substs: tcx.mk_substs_trait(*ty, &[]), - }; + let trait_ref = tcx.at(span).mk_trait_ref(LangItem::Sized, [*ty]); self.prove_trait_ref( trait_ref, @@ -2001,11 +1982,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::Unsize) => { let &ty = ty; - let trait_ref = ty::TraitRef { - def_id: tcx - .require_lang_item(LangItem::CoerceUnsized, Some(self.last_span)), - substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]), - }; + let trait_ref = tcx + .at(span) + .mk_trait_ref(LangItem::CoerceUnsized, [op.ty(body, tcx), ty]); self.prove_trait_ref( trait_ref, diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index 94d51032866..b2702eafd33 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -2,9 +2,8 @@ use rustc_infer::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRe use rustc_infer::infer::NllRegionVariableOrigin; use rustc_infer::traits::PredicateObligations; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::TypeRelation; -use rustc_middle::ty::{self, Const, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::traits::query::Fallible; @@ -141,13 +140,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> ); } - // We don't have to worry about the equality of consts during borrow checking - // as consts always have a static lifetime. - // FIXME(oli-obk): is this really true? We can at least have HKL and with - // inline consts we may have further lifetimes that may be unsound to treat as - // 'static. - fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) {} - fn normalization() -> NormalizationStrategy { NormalizationStrategy::Eager } @@ -156,10 +148,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> true } - fn register_opaque_type_obligations( - &mut self, - obligations: PredicateObligations<'tcx>, - ) -> Result<(), TypeError<'tcx>> { + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.type_checker .fully_perform_op( self.locations, @@ -172,6 +161,5 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx> }, ) .unwrap(); - Ok(()) } } diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 119724b5049..8555c3593b3 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -4,7 +4,7 @@ use crate::edition_panic::use_panic_2021; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; -use rustc_ast::{Expr, ExprKind, MacArgs, MacCall, MacDelimiter, Path, PathSegment, UnOp}; +use rustc_ast::{DelimArgs, Expr, ExprKind, MacCall, MacDelimiter, Path, PathSegment, UnOp}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, PResult}; use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult}; @@ -54,11 +54,11 @@ pub fn expand_assert<'cx>( call_site_span, ExprKind::MacCall(P(MacCall { path: panic_path(), - args: P(MacArgs::Delimited( - DelimSpan::from_single(call_site_span), - MacDelimiter::Parenthesis, + args: P(DelimArgs { + dspan: DelimSpan::from_single(call_site_span), + delim: MacDelimiter::Parenthesis, tokens, - )), + }), prior_type_ascription: None, })), ); diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs index f72cd14bea0..220b7a8ad0f 100644 --- a/compiler/rustc_builtin_macros/src/assert/context.rs +++ b/compiler/rustc_builtin_macros/src/assert/context.rs @@ -3,8 +3,8 @@ use rustc_ast::{ ptr::P, token, tokenstream::{DelimSpan, TokenStream, TokenTree}, - BinOpKind, BorrowKind, Expr, ExprKind, ItemKind, MacArgs, MacCall, MacDelimiter, Mutability, - Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID, + BinOpKind, BorrowKind, DelimArgs, Expr, ExprKind, ItemKind, MacCall, MacDelimiter, MethodCall, + Mutability, Path, PathSegment, Stmt, StructRest, UnOp, UseTree, UseTreeKind, DUMMY_NODE_ID, }; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; @@ -181,11 +181,11 @@ impl<'cx, 'a> Context<'cx, 'a> { self.span, ExprKind::MacCall(P(MacCall { path: panic_path, - args: P(MacArgs::Delimited( - DelimSpan::from_single(self.span), - MacDelimiter::Parenthesis, - initial.into_iter().chain(captures).collect::<TokenStream>(), - )), + args: P(DelimArgs { + dspan: DelimSpan::from_single(self.span), + delim: MacDelimiter::Parenthesis, + tokens: initial.into_iter().chain(captures).collect::<TokenStream>(), + }), prior_type_ascription: None, })), ) @@ -242,9 +242,9 @@ impl<'cx, 'a> Context<'cx, 'a> { self.manage_cond_expr(prefix); self.manage_cond_expr(suffix); } - ExprKind::MethodCall(_, _,ref mut local_exprs, _) => { - for local_expr in local_exprs.iter_mut() { - self.manage_cond_expr(local_expr); + ExprKind::MethodCall(ref mut call) => { + for arg in call.args.iter_mut() { + self.manage_cond_expr(arg); } } ExprKind::Path(_, Path { ref segments, .. }) if let &[ref path_segment] = &segments[..] => { @@ -296,7 +296,7 @@ impl<'cx, 'a> Context<'cx, 'a> { | ExprKind::Block(_, _) | ExprKind::Box(_) | ExprKind::Break(_, _) - | ExprKind::Closure(_, _, _, _, _, _, _) + | ExprKind::Closure(_) | ExprKind::ConstBlock(_) | ExprKind::Continue(_) | ExprKind::Err @@ -442,12 +442,12 @@ fn expr_addr_of_mut(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> { fn expr_method_call( cx: &ExtCtxt<'_>, - path: PathSegment, + seg: PathSegment, receiver: P<Expr>, args: Vec<P<Expr>>, span: Span, ) -> P<Expr> { - cx.expr(span, ExprKind::MethodCall(path, receiver, args, span)) + cx.expr(span, ExprKind::MethodCall(Box::new(MethodCall { seg, receiver, args, span }))) } fn expr_paren(cx: &ExtCtxt<'_>, sp: Span, e: P<Expr>) -> P<Expr> { diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index f48c49f411c..3309fab224f 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -448,7 +448,8 @@ impl<'a> TraitDef<'a> { _ => unreachable!(), }; let container_id = cx.current_expansion.id.expn_data().parent.expect_local(); - let always_copy = has_no_type_params && cx.resolver.has_derive_copy(container_id); + let copy_fields = + is_packed && has_no_type_params && cx.resolver.has_derive_copy(container_id); let newitem = match item.kind { ast::ItemKind::Struct(ref struct_def, ref generics) => self.expand_struct_def( @@ -457,16 +458,14 @@ impl<'a> TraitDef<'a> { item.ident, generics, from_scratch, - is_packed, - always_copy, + copy_fields, ), ast::ItemKind::Enum(ref enum_def, ref generics) => { - // We ignore `is_packed`/`always_copy` here, because - // `repr(packed)` enums cause an error later on. + // We ignore `is_packed` here, because `repr(packed)` + // enums cause an error later on. // // This can only cause further compilation errors - // downstream in blatantly illegal code, so it - // is fine. + // downstream in blatantly illegal code, so it is fine. self.expand_enum_def(cx, enum_def, item.ident, generics, from_scratch) } ast::ItemKind::Union(ref struct_def, ref generics) => { @@ -477,8 +476,7 @@ impl<'a> TraitDef<'a> { item.ident, generics, from_scratch, - is_packed, - always_copy, + copy_fields, ) } else { cx.span_err(mitem.span, "this trait cannot be derived for unions"); @@ -748,8 +746,7 @@ impl<'a> TraitDef<'a> { type_ident: Ident, generics: &Generics, from_scratch: bool, - is_packed: bool, - always_copy: bool, + copy_fields: bool, ) -> P<ast::Item> { let field_tys: Vec<P<ast::Ty>> = struct_def.fields().iter().map(|field| field.ty.clone()).collect(); @@ -777,8 +774,7 @@ impl<'a> TraitDef<'a> { type_ident, &selflike_args, &nonselflike_args, - is_packed, - always_copy, + copy_fields, ) }; @@ -1016,19 +1012,9 @@ impl<'a> MethodDef<'a> { /// } /// } /// ``` - /// If the struct doesn't impl `Copy`, we use let-destructuring with `ref`: - /// ``` - /// # struct A { x: u8, y: u8 } - /// impl PartialEq for A { - /// fn eq(&self, other: &A) -> bool { - /// let Self { x: ref __self_0_0, y: ref __self_0_1 } = *self; - /// let Self { x: ref __self_1_0, y: ref __self_1_1 } = *other; - /// *__self_0_0 == *__self_1_0 && *__self_0_1 == *__self_1_1 - /// } - /// } - /// ``` - /// This latter case only works if the fields match the alignment required - /// by the `packed(N)` attribute. (We'll get errors later on if not.) + /// If the struct doesn't impl `Copy`, we use the normal `&self.x`. This + /// only works if the fields match the alignment required by the + /// `packed(N)` attribute. (We'll get errors later on if not.) fn expand_struct_method_body<'b>( &self, cx: &mut ExtCtxt<'_>, @@ -1037,51 +1023,19 @@ impl<'a> MethodDef<'a> { type_ident: Ident, selflike_args: &[P<Expr>], nonselflike_args: &[P<Expr>], - is_packed: bool, - always_copy: bool, + copy_fields: bool, ) -> BlockOrExpr { - let span = trait_.span; assert!(selflike_args.len() == 1 || selflike_args.len() == 2); - let mk_body = |cx, selflike_fields| { - self.call_substructure_method( - cx, - trait_, - type_ident, - nonselflike_args, - &Struct(struct_def, selflike_fields), - ) - }; - - if !is_packed { - let selflike_fields = - trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, false); - mk_body(cx, selflike_fields) - } else if always_copy { - let selflike_fields = - trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, true); - mk_body(cx, selflike_fields) - } else { - // Packed and not copy. Need to use ref patterns. - let prefixes: Vec<_> = - (0..selflike_args.len()).map(|i| format!("__self_{}", i)).collect(); - let selflike_fields = trait_.create_struct_pattern_fields(cx, struct_def, &prefixes); - let mut body = mk_body(cx, selflike_fields); - - let struct_path = cx.path(span, vec![Ident::new(kw::SelfUpper, type_ident.span)]); - let patterns = - trait_.create_struct_patterns(cx, struct_path, struct_def, &prefixes, ByRef::Yes); - - // Do the let-destructuring. - let mut stmts: Vec<_> = iter::zip(selflike_args, patterns) - .map(|(selflike_arg_expr, pat)| { - let selflike_arg_expr = cx.expr_deref(span, selflike_arg_expr.clone()); - cx.stmt_let_pat(span, pat, selflike_arg_expr) - }) - .collect(); - stmts.extend(std::mem::take(&mut body.0)); - BlockOrExpr(stmts, body.1) - } + let selflike_fields = + trait_.create_struct_field_access_fields(cx, selflike_args, struct_def, copy_fields); + self.call_substructure_method( + cx, + trait_, + type_ident, + nonselflike_args, + &Struct(struct_def, selflike_fields), + ) } fn expand_static_struct_method_body( @@ -1531,7 +1485,7 @@ impl<'a> TraitDef<'a> { cx: &mut ExtCtxt<'_>, selflike_args: &[P<Expr>], struct_def: &'a VariantData, - copy: bool, + copy_fields: bool, ) -> Vec<FieldInfo> { self.create_fields(struct_def, |i, struct_field, sp| { selflike_args @@ -1550,7 +1504,7 @@ impl<'a> TraitDef<'a> { }), ), ); - if copy { + if copy_fields { field_expr = cx.expr_block( cx.block(struct_field.span, vec![cx.stmt_expr(field_expr)]), ); diff --git a/compiler/rustc_builtin_macros/src/edition_panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs index 3f1a8b3bc2c..cae648cd11a 100644 --- a/compiler/rustc_builtin_macros/src/edition_panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -58,11 +58,11 @@ fn expand<'cx>( .collect(), tokens: None, }, - args: P(MacArgs::Delimited( - DelimSpan::from_single(sp), - MacDelimiter::Parenthesis, - tts, - )), + args: P(DelimArgs { + dspan: DelimSpan::from_single(sp), + delim: MacDelimiter::Parenthesis, + tokens: tts, + }), prior_type_ascription: None, })), ), diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 99059e788a0..1e22537c2ba 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -22,7 +22,19 @@ fn clif_sig_from_fn_abi<'tcx>( default_call_conv: CallConv, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, ) -> Signature { - let call_conv = match fn_abi.conv { + let call_conv = conv_to_call_conv(fn_abi.conv, default_call_conv); + + let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten(); + + let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); + // Sometimes the first param is an pointer to the place where the return value needs to be stored. + let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect(); + + Signature { params, returns, call_conv } +} + +pub(crate) fn conv_to_call_conv(c: Conv, default_call_conv: CallConv) -> CallConv { + match c { Conv::Rust | Conv::C => default_call_conv, Conv::RustCold => CallConv::Cold, Conv::X86_64SysV => CallConv::SystemV, @@ -38,15 +50,8 @@ fn clif_sig_from_fn_abi<'tcx>( | Conv::X86VectorCall | Conv::AmdGpuKernel | Conv::AvrInterrupt - | Conv::AvrNonBlockingInterrupt => todo!("{:?}", fn_abi.conv), - }; - let inputs = fn_abi.args.iter().map(|arg_abi| arg_abi.get_abi_param(tcx).into_iter()).flatten(); - - let (return_ptr, returns) = fn_abi.ret.get_abi_return(tcx); - // Sometimes the first param is an pointer to the place where the return value needs to be stored. - let params: Vec<_> = return_ptr.into_iter().chain(inputs).collect(); - - Signature { params, returns, call_conv } + | Conv::AvrNonBlockingInterrupt => todo!("{:?}", c), + } } pub(crate) fn get_function_sig<'tcx>( diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 5478caee57d..077f33bb99c 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -38,22 +38,8 @@ impl ConstantCx { pub(crate) fn check_constants(fx: &mut FunctionCx<'_, '_, '_>) -> bool { let mut all_constants_ok = true; for constant in &fx.mir.required_consts { - let unevaluated = match fx.monomorphize(constant.literal) { - ConstantKind::Ty(_) => unreachable!(), - ConstantKind::Unevaluated(uv, _) => uv, - ConstantKind::Val(..) => continue, - }; - - if let Err(err) = fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), unevaluated, None) { + if eval_mir_constant(fx, constant).is_none() { all_constants_ok = false; - match err { - ErrorHandled::Reported(_) => { - fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); - } - ErrorHandled::TooGeneric => { - span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); - } - } } } all_constants_ok @@ -80,15 +66,15 @@ pub(crate) fn codegen_tls_ref<'tcx>( } pub(crate) fn eval_mir_constant<'tcx>( - fx: &mut FunctionCx<'_, '_, 'tcx>, + fx: &FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, -) -> (ConstValue<'tcx>, Ty<'tcx>) { +) -> Option<(ConstValue<'tcx>, Ty<'tcx>)> { let constant_kind = fx.monomorphize(constant.literal); let uv = match constant_kind { ConstantKind::Ty(const_) => match const_.kind() { ty::ConstKind::Unevaluated(uv) => uv.expand(), ty::ConstKind::Value(val) => { - return (fx.tcx.valtree_to_const_val((const_.ty(), val)), const_.ty()); + return Some((fx.tcx.valtree_to_const_val((const_.ty(), val)), const_.ty())); } err => span_bug!( constant.span, @@ -102,22 +88,31 @@ pub(crate) fn eval_mir_constant<'tcx>( span_bug!(constant.span, "MIR constant refers to static"); } ConstantKind::Unevaluated(uv, _) => uv, - ConstantKind::Val(val, _) => return (val, constant_kind.ty()), + ConstantKind::Val(val, _) => return Some((val, constant_kind.ty())), }; - ( - fx.tcx.const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).unwrap_or_else(|_err| { - span_bug!(constant.span, "erroneous constant not captured by required_consts"); - }), - constant_kind.ty(), - ) + let val = fx + .tcx + .const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None) + .map_err(|err| match err { + ErrorHandled::Reported(_) => { + fx.tcx.sess.span_err(constant.span, "erroneous constant encountered"); + } + ErrorHandled::TooGeneric => { + span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); + } + }) + .ok(); + val.map(|val| (val, constant_kind.ty())) } pub(crate) fn codegen_constant_operand<'tcx>( fx: &mut FunctionCx<'_, '_, 'tcx>, constant: &Constant<'tcx>, ) -> CValue<'tcx> { - let (const_val, ty) = eval_mir_constant(fx, constant); + let (const_val, ty) = eval_mir_constant(fx, constant).unwrap_or_else(|| { + span_bug!(constant.span, "erroneous constant not captured by required_consts") + }); codegen_const_value(fx, const_val, ty) } @@ -453,20 +448,13 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant assert!(cx.todo.is_empty(), "{:?}", cx.todo); } +/// Used only for intrinsic implementations that need a compile-time constant pub(crate) fn mir_operand_get_const_val<'tcx>( fx: &FunctionCx<'_, '_, 'tcx>, operand: &Operand<'tcx>, ) -> Option<ConstValue<'tcx>> { match operand { - Operand::Constant(const_) => match fx.monomorphize(const_.literal) { - ConstantKind::Ty(const_) => Some( - const_.eval_for_mir(fx.tcx, ParamEnv::reveal_all()).try_to_value(fx.tcx).unwrap(), - ), - ConstantKind::Val(val, _) => Some(val), - ConstantKind::Unevaluated(uv, _) => { - Some(fx.tcx.const_eval_resolve(ParamEnv::reveal_all(), uv, None).unwrap()) - } - }, + Operand::Constant(const_) => Some(eval_mir_constant(fx, const_).unwrap().0), // FIXME(rust-lang/rust#85105): Casts like `IMM8 as u32` result in the const being stored // inside a temporary before being passed to the intrinsic requiring the const argument. // This code tries to find a single constant defining definition of the referenced local. diff --git a/compiler/rustc_codegen_cranelift/src/main_shim.rs b/compiler/rustc_codegen_cranelift/src/main_shim.rs index cae6312a607..f7434633ea4 100644 --- a/compiler/rustc_codegen_cranelift/src/main_shim.rs +++ b/compiler/rustc_codegen_cranelift/src/main_shim.rs @@ -63,10 +63,14 @@ pub(crate) fn maybe_create_entry_wrapper( AbiParam::new(m.target_config().pointer_type()), ], returns: vec![AbiParam::new(m.target_config().pointer_type() /*isize*/)], - call_conv: CallConv::triple_default(m.isa().triple()), + call_conv: crate::conv_to_call_conv( + tcx.sess.target.options.entry_abi, + CallConv::triple_default(m.isa().triple()), + ), }; - let cmain_func_id = m.declare_function("main", Linkage::Export, &cmain_sig).unwrap(); + let entry_name = tcx.sess.target.options.entry_name.as_ref(); + let cmain_func_id = m.declare_function(entry_name, Linkage::Export, &cmain_sig).unwrap(); let instance = Instance::mono(tcx, rust_main_def_id).polymorphize(tcx); diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 62a61eb8548..2e71c3665da 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -425,8 +425,9 @@ impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { - if self.get_declared_value("main").is_none() { - Some(self.declare_cfn("main", fn_type)) + let entry_name = self.sess().target.entry_name.as_ref(); + if self.get_declared_value(entry_name).is_none() { + Some(self.declare_entry_fn(entry_name, fn_type, ())) } else { // If the symbol already exists, it is an error: for example, the user wrote diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs index a619e2f7712..eae77508c97 100644 --- a/compiler/rustc_codegen_gcc/src/declare.rs +++ b/compiler/rustc_codegen_gcc/src/declare.rs @@ -65,13 +65,13 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> { global } - pub fn declare_cfn(&self, name: &str, _fn_type: Type<'gcc>) -> RValue<'gcc> { + pub fn declare_entry_fn(&self, name: &str, _fn_type: Type<'gcc>, callconv: () /*llvm::CCallConv*/) -> RValue<'gcc> { // TODO(antoyo): use the fn_type parameter. let const_string = self.context.new_type::<u8>().make_pointer().make_pointer(); let return_type = self.type_i32(); let variadic = false; self.linkage.set(FunctionType::Exported); - let func = declare_raw_fn(self, name, () /*llvm::CCallConv*/, return_type, &[self.type_i32(), const_string], variadic); + let func = declare_raw_fn(self, name, callconv, return_type, &[self.type_i32(), const_string], variadic); // NOTE: it is needed to set the current_func here as well, because get_fn() is not called // for the main function. *self.current_func.borrow_mut() = Some(func); diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs index d478efc863a..a6fd2a7de6b 100644 --- a/compiler/rustc_codegen_llvm/src/abi.rs +++ b/compiler/rustc_codegen_llvm/src/abi.rs @@ -398,23 +398,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> { } fn llvm_cconv(&self) -> llvm::CallConv { - match self.conv { - Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv, - Conv::RustCold => llvm::ColdCallConv, - Conv::AmdGpuKernel => llvm::AmdGpuKernel, - Conv::AvrInterrupt => llvm::AvrInterrupt, - Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt, - Conv::ArmAapcs => llvm::ArmAapcsCallConv, - Conv::Msp430Intr => llvm::Msp430Intr, - Conv::PtxKernel => llvm::PtxKernel, - Conv::X86Fastcall => llvm::X86FastcallCallConv, - Conv::X86Intr => llvm::X86_Intr, - Conv::X86Stdcall => llvm::X86StdcallCallConv, - Conv::X86ThisCall => llvm::X86_ThisCall, - Conv::X86VectorCall => llvm::X86_VectorCall, - Conv::X86_64SysV => llvm::X86_64_SysV, - Conv::X86_64Win64 => llvm::X86_64_Win64, - } + self.conv.into() } fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) { @@ -596,3 +580,25 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { llvm::get_param(self.llfn(), index as c_uint) } } + +impl From<Conv> for llvm::CallConv { + fn from(conv: Conv) -> Self { + match conv { + Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv, + Conv::RustCold => llvm::ColdCallConv, + Conv::AmdGpuKernel => llvm::AmdGpuKernel, + Conv::AvrInterrupt => llvm::AvrInterrupt, + Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt, + Conv::ArmAapcs => llvm::ArmAapcsCallConv, + Conv::Msp430Intr => llvm::Msp430Intr, + Conv::PtxKernel => llvm::PtxKernel, + Conv::X86Fastcall => llvm::X86FastcallCallConv, + Conv::X86Intr => llvm::X86_Intr, + Conv::X86Stdcall => llvm::X86StdcallCallConv, + Conv::X86ThisCall => llvm::X86_ThisCall, + Conv::X86VectorCall => llvm::X86_VectorCall, + Conv::X86_64SysV => llvm::X86_64_SysV, + Conv::X86_64Win64 => llvm::X86_64_Win64, + } + } +} diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs index 6f0d1b7ce84..70ff5c9617b 100644 --- a/compiler/rustc_codegen_llvm/src/callee.rs +++ b/compiler/rustc_codegen_llvm/src/callee.rs @@ -83,7 +83,20 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> let llfn = if tcx.sess.target.arch == "x86" && let Some(dllimport) = common::get_dllimport(tcx, instance_def_id, sym) { - cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi) + // Fix for https://github.com/rust-lang/rust/issues/104453 + // On x86 Windows, LLVM uses 'L' as the prefix for any private + // global symbols, so when we create an undecorated function symbol + // that begins with an 'L' LLVM misinterprets that as a private + // global symbol that it created and so fails the compilation at a + // later stage since such a symbol must have a definition. + // + // To avoid this, we set the Storage Class to "DllImport" so that + // LLVM will prefix the name with `__imp_`. Ideally, we'd like the + // existing logic below to set the Storage Class, but it has an + // exemption for MinGW for backwards compatability. + let llfn = cx.declare_fn(&common::i686_decorated_name(&dllimport, common::is_mingw_gnu_toolchain(&tcx.sess.target), true), fn_abi); + unsafe { llvm::LLVMSetDLLStorageClass(llfn, llvm::DLLStorageClass::DllImport); } + llfn } else { cx.declare_fn(sym, fn_abi) }; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index eaa2ccfc835..4dcc7cd5447 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -576,8 +576,14 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> { } fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> { - if self.get_declared_value("main").is_none() { - Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type)) + let entry_name = self.sess().target.entry_name.as_ref(); + if self.get_declared_value(entry_name).is_none() { + Some(self.declare_entry_fn( + entry_name, + self.sess().target.entry_abi.into(), + llvm::UnnamedAddr::Global, + fn_type, + )) } else { // If the symbol already exists, it is an error: for example, the user wrote // #[no_mangle] extern "C" fn main(..) {..} diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 163ccd9460c..d87117dffdc 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -998,7 +998,7 @@ fn build_struct_type_di_node<'ll, 'tcx>( .iter() .enumerate() .map(|(i, f)| { - let field_name = if variant_def.ctor_kind == CtorKind::Fn { + let field_name = if variant_def.ctor_kind() == Some(CtorKind::Fn) { // This is a tuple struct tuple_field_name(i) } else { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs index 129e336c7e4..53e8a291d1e 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs @@ -462,7 +462,7 @@ fn build_variant_names_type_di_node<'ll, 'tcx>( cx, "VariantNames", variant_names_enum_base_type(cx), - variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32() as u64)), + variants.map(|(variant_index, variant_name)| (variant_name, variant_index.as_u32().into())), containing_scope, ) } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 14044d0f99b..564ab351bd4 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -91,9 +91,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>( tag_base_type(cx, enum_type_and_layout), enum_adt_def.discriminants(cx.tcx).map(|(variant_index, discr)| { let name = Cow::from(enum_adt_def.variant(variant_index).name.as_str()); - // Is there anything we can do to support 128-bit C-Style enums? - let value = discr.val as u64; - (name, value) + (name, discr.val) }), containing_scope, ), @@ -147,14 +145,11 @@ fn tag_base_type<'ll, 'tcx>( /// This is a helper function and does not register anything in the type map by itself. /// /// `variants` is an iterator of (discr-value, variant-name). -/// -// NOTE: Handling of discriminant values is somewhat inconsistent. They can appear as u128, -// u64, and i64. Here everything gets mapped to i64 because that's what LLVM's API expects. fn build_enumeration_type_di_node<'ll, 'tcx>( cx: &CodegenCx<'ll, 'tcx>, type_name: &str, base_type: Ty<'tcx>, - enumerators: impl Iterator<Item = (Cow<'tcx, str>, u64)>, + enumerators: impl Iterator<Item = (Cow<'tcx, str>, u128)>, containing_scope: &'ll DIType, ) -> &'ll DIType { let is_unsigned = match base_type.kind() { @@ -162,21 +157,22 @@ fn build_enumeration_type_di_node<'ll, 'tcx>( ty::Uint(_) => true, _ => bug!("build_enumeration_type_di_node() called with non-integer tag type."), }; + let (size, align) = cx.size_and_align_of(base_type); let enumerator_di_nodes: SmallVec<Option<&'ll DIType>> = enumerators .map(|(name, value)| unsafe { + let value = [value as u64, (value >> 64) as u64]; Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), name.as_ptr().cast(), name.len(), - value as i64, + value.as_ptr(), + size.bits() as libc::c_uint, is_unsigned, )) }) .collect(); - let (size, align) = cx.size_and_align_of(base_type); - unsafe { llvm::LLVMRustDIBuilderCreateEnumerationType( DIB(cx), @@ -273,7 +269,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( |cx, struct_type_di_node| { (0..variant_layout.fields.count()) .map(|field_index| { - let field_name = if variant_def.ctor_kind != CtorKind::Fn { + let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) { // Fields have names Cow::from(variant_def.fields[field_index].name.as_str()) } else { diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs index f79ef11720d..dc21a02cec4 100644 --- a/compiler/rustc_codegen_llvm/src/declare.rs +++ b/compiler/rustc_codegen_llvm/src/declare.rs @@ -90,6 +90,28 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type) } + /// Declare an entry Function + /// + /// The ABI of this function can change depending on the target (although for now the same as + /// `declare_cfn`) + /// + /// If there’s a value with the same name already declared, the function will + /// update the declaration and return existing Value instead. + pub fn declare_entry_fn( + &self, + name: &str, + callconv: llvm::CallConv, + unnamed: llvm::UnnamedAddr, + fn_type: &'ll Type, + ) -> &'ll Value { + let visibility = if self.tcx.sess.target.default_hidden_visibility { + llvm::Visibility::Hidden + } else { + llvm::Visibility::Default + }; + declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type) + } + /// Declare a Rust function. /// /// If there’s a value with the same name already declared, the function will diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 8f7728da9dd..f4519849730 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2127,7 +2127,8 @@ extern "C" { Builder: &DIBuilder<'a>, Name: *const c_char, NameLen: size_t, - Value: i64, + Value: *const u64, + SizeInBits: c_uint, IsUnsigned: bool, ) -> &'a DIEnumerator; diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index 752f6b1ef40..22f534d909a 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -180,7 +180,8 @@ fn exported_symbols_provider_local<'tcx>( .collect(); if tcx.entry_fn(()).is_some() { - let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, "main")); + let exported_symbol = + ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref())); symbols.push(( exported_symbol, diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs index 4c6ab457c49..53ff3c24096 100644 --- a/compiler/rustc_codegen_ssa/src/mir/constant.rs +++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs @@ -42,7 +42,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { }; self.cx.tcx().const_eval_resolve(ty::ParamEnv::reveal_all(), uv, None).map_err(|err| { - self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + match err { + ErrorHandled::Reported(_) => { + self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered"); + } + ErrorHandled::TooGeneric => { + span_bug!(constant.span, "codegen encountered polymorphic constant: {:?}", err); + } + } err }) } diff --git a/compiler/rustc_const_eval/Cargo.toml b/compiler/rustc_const_eval/Cargo.toml index e09a6d1d6f5..51489e29360 100644 --- a/compiler/rustc_const_eval/Cargo.toml +++ b/compiler/rustc_const_eval/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] tracing = "0.1" +either = "1" rustc_apfloat = { path = "../rustc_apfloat" } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index f5942deaf9f..c777a840f3f 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -1,10 +1,7 @@ -use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr}; -use crate::interpret::eval_nullary_intrinsic; -use crate::interpret::{ - intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, - Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, - RefTracking, StackPopCleanup, -}; +use std::borrow::Cow; +use std::convert::TryInto; + +use either::{Left, Right}; use rustc_hir::def::DefKind; use rustc_middle::mir; @@ -16,8 +13,14 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::source_map::Span; use rustc_target::abi::{self, Abi}; -use std::borrow::Cow; -use std::convert::TryInto; + +use super::{CompileTimeEvalContext, CompileTimeInterpreter, ConstEvalErr}; +use crate::interpret::eval_nullary_intrinsic; +use crate::interpret::{ + intern_const_alloc_recursive, Allocation, ConstAlloc, ConstValue, CtfeValidationMode, GlobalId, + Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, + RefTracking, StackPopCleanup, +}; const NOTE_ON_UNDEFINED_BEHAVIOR_ERROR: &str = "The rules on what exactly is undefined behavior aren't clear, \ so this check might be overzealous. Please open an issue on the rustc \ @@ -135,14 +138,14 @@ pub(super) fn op_to_const<'tcx>( _ => false, }; let immediate = if try_as_immediate { - Err(ecx.read_immediate(op).expect("normalization works on validated constants")) + Right(ecx.read_immediate(op).expect("normalization works on validated constants")) } else { // It is guaranteed that any non-slice scalar pair is actually ByRef here. // When we come back from raw const eval, we are always by-ref. The only way our op here is // by-val is if we are in destructure_mir_constant, i.e., if this is (a field of) something that we // "tried to make immediate" before. We wouldn't do that for non-slice scalar pairs or // structs containing such. - op.try_as_mplace() + op.as_mplace_or_imm() }; debug!(?immediate); @@ -168,9 +171,9 @@ pub(super) fn op_to_const<'tcx>( } }; match immediate { - Ok(ref mplace) => to_const_value(mplace), + Left(ref mplace) => to_const_value(mplace), // see comment on `let try_as_immediate` above - Err(imm) => match *imm { + Right(imm) => match *imm { _ if imm.layout.is_zst() => ConstValue::ZeroSized, Immediate::Scalar(x) => ConstValue::Scalar(x), Immediate::ScalarPair(a, b) => { diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 35d58d2f638..04e68b96455 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -1,8 +1,12 @@ use rustc_hir::def::DefKind; +use rustc_hir::LangItem; use rustc_middle::mir; +use rustc_middle::mir::interpret::PointerArithmetic; +use rustc_middle::ty::layout::FnAbiOf; use rustc_middle::ty::{self, Ty, TyCtxt}; use std::borrow::Borrow; use std::hash::Hash; +use std::ops::ControlFlow; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::IndexEntry; @@ -17,58 +21,12 @@ use rustc_target::abi::{Align, Size}; use rustc_target::spec::abi::Abi as CallAbi; use crate::interpret::{ - self, compile_time_machine, AllocId, ConstAllocation, Frame, ImmTy, InterpCx, InterpResult, - OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind, + self, compile_time_machine, AllocId, ConstAllocation, FnVal, Frame, ImmTy, InterpCx, + InterpResult, OpTy, PlaceTy, Pointer, Scalar, StackPopUnwind, }; use super::error::*; -impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> { - /// "Intercept" a function call to a panic-related function - /// because we have something special to do for it. - /// If this returns successfully (`Ok`), the function should just be evaluated normally. - fn hook_special_const_fn( - &mut self, - instance: ty::Instance<'tcx>, - args: &[OpTy<'tcx>], - ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> { - // All `#[rustc_do_not_const_check]` functions should be hooked here. - let def_id = instance.def_id(); - - if Some(def_id) == self.tcx.lang_items().panic_display() - || Some(def_id) == self.tcx.lang_items().begin_panic_fn() - { - // &str or &&str - assert!(args.len() == 1); - - let mut msg_place = self.deref_operand(&args[0])?; - while msg_place.layout.ty.is_ref() { - msg_place = self.deref_operand(&msg_place.into())?; - } - - let msg = Symbol::intern(self.read_str(&msg_place)?); - let span = self.find_closest_untracked_caller_location(); - let (file, line, col) = self.location_triple_for_span(span); - return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into()); - } else if Some(def_id) == self.tcx.lang_items().panic_fmt() { - // For panic_fmt, call const_panic_fmt instead. - if let Some(const_panic_fmt) = self.tcx.lang_items().const_panic_fmt() { - return Ok(Some( - ty::Instance::resolve( - *self.tcx, - ty::ParamEnv::reveal_all(), - const_panic_fmt, - self.tcx.intern_substs(&[]), - ) - .unwrap() - .unwrap(), - )); - } - } - Ok(None) - } -} - /// Extra machine state for CTFE, and the Machine instance pub struct CompileTimeInterpreter<'mir, 'tcx> { /// For now, the number of terminators that can be evaluated before we throw a resource @@ -191,6 +149,125 @@ impl interpret::MayLeak for ! { } impl<'mir, 'tcx: 'mir> CompileTimeEvalContext<'mir, 'tcx> { + /// "Intercept" a function call, because we have something special to do for it. + /// All `#[rustc_do_not_const_check]` functions should be hooked here. + /// If this returns `Some` function, which may be `instance` or a different function with + /// compatible arguments, then evaluation should continue with that function. + /// If this returns `None`, the function call has been handled and the function has returned. + fn hook_special_const_fn( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OpTy<'tcx>], + dest: &PlaceTy<'tcx>, + ret: Option<mir::BasicBlock>, + ) -> InterpResult<'tcx, Option<ty::Instance<'tcx>>> { + let def_id = instance.def_id(); + + if Some(def_id) == self.tcx.lang_items().panic_display() + || Some(def_id) == self.tcx.lang_items().begin_panic_fn() + { + // &str or &&str + assert!(args.len() == 1); + + let mut msg_place = self.deref_operand(&args[0])?; + while msg_place.layout.ty.is_ref() { + msg_place = self.deref_operand(&msg_place.into())?; + } + + let msg = Symbol::intern(self.read_str(&msg_place)?); + let span = self.find_closest_untracked_caller_location(); + let (file, line, col) = self.location_triple_for_span(span); + return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into()); + } else if Some(def_id) == self.tcx.lang_items().panic_fmt() { + // For panic_fmt, call const_panic_fmt instead. + let const_def_id = self.tcx.require_lang_item(LangItem::ConstPanicFmt, None); + let new_instance = ty::Instance::resolve( + *self.tcx, + ty::ParamEnv::reveal_all(), + const_def_id, + instance.substs, + ) + .unwrap() + .unwrap(); + + return Ok(Some(new_instance)); + } else if Some(def_id) == self.tcx.lang_items().align_offset_fn() { + // For align_offset, we replace the function call if the pointer has no address. + match self.align_offset(instance, args, dest, ret)? { + ControlFlow::Continue(()) => return Ok(Some(instance)), + ControlFlow::Break(()) => return Ok(None), + } + } + Ok(Some(instance)) + } + + /// `align_offset(ptr, target_align)` needs special handling in const eval, because the pointer + /// may not have an address. + /// + /// If `ptr` does have a known address, then we return `CONTINUE` and the function call should + /// proceed as normal. + /// + /// If `ptr` doesn't have an address, but its underlying allocation's alignment is at most + /// `target_align`, then we call the function again with an dummy address relative to the + /// allocation. + /// + /// If `ptr` doesn't have an address and `target_align` is stricter than the underlying + /// allocation's alignment, then we return `usize::MAX` immediately. + fn align_offset( + &mut self, + instance: ty::Instance<'tcx>, + args: &[OpTy<'tcx>], + dest: &PlaceTy<'tcx>, + ret: Option<mir::BasicBlock>, + ) -> InterpResult<'tcx, ControlFlow<()>> { + assert_eq!(args.len(), 2); + + let ptr = self.read_pointer(&args[0])?; + let target_align = self.read_scalar(&args[1])?.to_machine_usize(self)?; + + if !target_align.is_power_of_two() { + throw_ub_format!("`align_offset` called with non-power-of-two align: {}", target_align); + } + + match self.ptr_try_get_alloc_id(ptr) { + Ok((alloc_id, offset, _extra)) => { + let (_size, alloc_align, _kind) = self.get_alloc_info(alloc_id); + + if target_align <= alloc_align.bytes() { + // Extract the address relative to the allocation base that is definitely + // sufficiently aligned and call `align_offset` again. + let addr = ImmTy::from_uint(offset.bytes(), args[0].layout).into(); + let align = ImmTy::from_uint(target_align, args[1].layout).into(); + let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?; + + // We replace the entire entire function call with a "tail call". + // Note that this happens before the frame of the original function + // is pushed on the stack. + self.eval_fn_call( + FnVal::Instance(instance), + (CallAbi::Rust, fn_abi), + &[addr, align], + /* with_caller_location = */ false, + dest, + ret, + StackPopUnwind::NotAllowed, + )?; + Ok(ControlFlow::BREAK) + } else { + // Not alignable in const, return `usize::MAX`. + let usize_max = Scalar::from_machine_usize(self.machine_usize_max(), self); + self.write_scalar(usize_max, dest)?; + self.return_to_block(ret)?; + Ok(ControlFlow::BREAK) + } + } + Err(_addr) => { + // The pointer has an address, continue with function call. + Ok(ControlFlow::CONTINUE) + } + } + } + /// See documentation on the `ptr_guaranteed_cmp` intrinsic. fn guaranteed_cmp(&mut self, a: Scalar, b: Scalar) -> InterpResult<'tcx, u8> { Ok(match (a, b) { @@ -271,8 +348,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, instance: ty::Instance<'tcx>, _abi: CallAbi, args: &[OpTy<'tcx>], - _dest: &PlaceTy<'tcx>, - _ret: Option<mir::BasicBlock>, + dest: &PlaceTy<'tcx>, + ret: Option<mir::BasicBlock>, _unwind: StackPopUnwind, // unwinding is not supported in consts ) -> InterpResult<'tcx, Option<(&'mir mir::Body<'tcx>, ty::Instance<'tcx>)>> { debug!("find_mir_or_eval_fn: {:?}", instance); @@ -291,7 +368,11 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } } - if let Some(new_instance) = ecx.hook_special_const_fn(instance, args)? { + let Some(new_instance) = ecx.hook_special_const_fn(instance, args, dest, ret)? else { + return Ok(None); + }; + + if new_instance != instance { // We call another const fn instead. // However, we return the *original* instance to make backtraces work out // (and we hope this does not confuse the FnAbi checks too much). @@ -300,13 +381,14 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, new_instance, _abi, args, - _dest, - _ret, + dest, + ret, _unwind, )? .map(|(body, _instance)| (body, instance))); } } + // This is a const fn. Call it. Ok(Some((ecx.load_mir(instance.def, None)?, instance))) } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index ed69d8554d2..79450fccfc4 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -2,6 +2,8 @@ use std::cell::Cell; use std::fmt; use std::mem; +use either::{Either, Left, Right}; + use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData}; use rustc_index::vec::IndexVec; use rustc_middle::mir; @@ -23,7 +25,7 @@ use super::{ MemPlaceMeta, Memory, MemoryKind, Operand, Place, PlaceTy, PointerArithmetic, Provenance, Scalar, StackPopJump, }; -use crate::transform::validate::equal_up_to_regions; +use crate::util; pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { /// Stores the `Machine` instance. @@ -121,13 +123,12 @@ pub struct Frame<'mir, 'tcx, Prov: Provenance = AllocId, Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Current position within the function //////////////////////////////////////////////////////////////////////////////// - /// If this is `Err`, we are not currently executing any particular statement in + /// If this is `Right`, we are not currently executing any particular statement in /// this frame (can happen e.g. during frame initialization, and during unwinding on /// frames without cleanup code). - /// We basically abuse `Result` as `Either`. /// /// Needs to be public because ConstProp does unspeakable things to it. - pub loc: Result<mir::Location, Span>, + pub loc: Either<mir::Location, Span>, } /// What we store about a frame in an interpreter backtrace. @@ -227,25 +228,24 @@ impl<'mir, 'tcx, Prov: Provenance> Frame<'mir, 'tcx, Prov> { impl<'mir, 'tcx, Prov: Provenance, Extra> Frame<'mir, 'tcx, Prov, Extra> { /// Get the current location within the Frame. /// - /// If this is `Err`, we are not currently executing any particular statement in + /// If this is `Left`, we are not currently executing any particular statement in /// this frame (can happen e.g. during frame initialization, and during unwinding on /// frames without cleanup code). - /// We basically abuse `Result` as `Either`. /// /// Used by priroda. - pub fn current_loc(&self) -> Result<mir::Location, Span> { + pub fn current_loc(&self) -> Either<mir::Location, Span> { self.loc } /// Return the `SourceInfo` of the current instruction. pub fn current_source_info(&self) -> Option<&mir::SourceInfo> { - self.loc.ok().map(|loc| self.body.source_info(loc)) + self.loc.left().map(|loc| self.body.source_info(loc)) } pub fn current_span(&self) -> Span { match self.loc { - Ok(loc) => self.body.source_info(loc).span, - Err(span) => span, + Left(loc) => self.body.source_info(loc).span, + Right(span) => span, } } } @@ -354,8 +354,8 @@ pub(super) fn mir_assign_valid_types<'tcx>( // Type-changing assignments can happen when subtyping is used. While // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type - // differences. So we compare ignoring lifetimes. - if equal_up_to_regions(tcx, param_env, src.ty, dest.ty) { + // differences. + if util::is_subtype(tcx, param_env, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when @@ -679,7 +679,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // first push a stack frame so we have access to the local substs let pre_frame = Frame { body, - loc: Err(body.span), // Span used for errors caused during preamble. + loc: Right(body.span), // Span used for errors caused during preamble. return_to_block, return_place: return_place.clone(), // empty local array, we fill it in below, after we are inside the stack frame and @@ -713,7 +713,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // done self.frame_mut().locals = locals; M::after_stack_push(self)?; - self.frame_mut().loc = Ok(mir::Location::START); + self.frame_mut().loc = Left(mir::Location::START); let span = info_span!("frame", "{}", instance); self.frame_mut().tracing_span.enter(span); @@ -724,7 +724,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Jump to the given block. #[inline] pub fn go_to_block(&mut self, target: mir::BasicBlock) { - self.frame_mut().loc = Ok(mir::Location { block: target, statement_index: 0 }); + self.frame_mut().loc = Left(mir::Location { block: target, statement_index: 0 }); } /// *Return* to the given `target` basic block. @@ -750,8 +750,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// unwinding, and doing so is UB. pub fn unwind_to_block(&mut self, target: StackPopUnwind) -> InterpResult<'tcx> { self.frame_mut().loc = match target { - StackPopUnwind::Cleanup(block) => Ok(mir::Location { block, statement_index: 0 }), - StackPopUnwind::Skip => Err(self.frame_mut().body.span), + StackPopUnwind::Cleanup(block) => Left(mir::Location { block, statement_index: 0 }), + StackPopUnwind::Skip => Right(self.frame_mut().body.span), StackPopUnwind::NotAllowed => { throw_ub_format!("unwinding past a stack frame that does not allow unwinding") } @@ -783,8 +783,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!( unwinding, match self.frame().loc { - Ok(loc) => self.body().basic_blocks[loc.block].is_cleanup, - Err(_) => true, + Left(loc) => self.body().basic_blocks[loc.block].is_cleanup, + Right(_) => true, } ); if unwinding && self.frame_idx() == 0 { diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 6fc2407b778..7940efcd2b1 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -243,6 +243,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let discr_val = self.read_discriminant(&place.into())?.0; self.write_scalar(discr_val, dest)?; } + sym::exact_div => { + let l = self.read_immediate(&args[0])?; + let r = self.read_immediate(&args[1])?; + self.exact_div(&l, &r, dest)?; + } sym::unchecked_shl | sym::unchecked_shr | sym::unchecked_add diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs index 0e3867557ad..7d94a22c43d 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics/caller_location.rs @@ -19,8 +19,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { debug!("find_closest_untracked_caller_location: checking frame {:?}", frame.instance); // Assert that the frame we look at is actually executing code currently - // (`loc` is `Err` when we are unwinding and the frame does not require cleanup). - let loc = frame.loc.unwrap(); + // (`loc` is `Right` when we are unwinding and the frame does not require cleanup). + let loc = frame.loc.left().unwrap(); // This could be a non-`Call` terminator (such as `Drop`), or not a terminator at all // (such as `box`). Use the normal span by default. diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index cf9202540c7..3eb2b3a0b1b 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -1,6 +1,8 @@ //! Functions concerning immediate values and operands, and reading from operands. //! All high-level functions to read from memory work on operands as sources. +use either::{Either, Left, Right}; + use rustc_hir::def::Namespace; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter}; @@ -261,9 +263,9 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { layout: TyAndLayout<'tcx>, cx: &impl HasDataLayout, ) -> InterpResult<'tcx, Self> { - match self.try_as_mplace() { - Ok(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()), - Err(imm) => { + match self.as_mplace_or_imm() { + Left(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()), + Right(imm) => { assert!( matches!(*imm, Immediate::Uninit), "Scalar/ScalarPair cannot be offset into" @@ -353,8 +355,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// Try returning an immediate for the operand. If the layout does not permit loading this as an /// immediate, return where in memory we can find the data. - /// Note that for a given layout, this operation will either always fail or always - /// succeed! Whether it succeeds depends on whether the layout can be represented + /// Note that for a given layout, this operation will either always return Left or Right! + /// succeed! Whether it returns Left depends on whether the layout can be represented /// in an `Immediate`, not on which data is stored there currently. /// /// This is an internal function that should not usually be used; call `read_immediate` instead. @@ -362,16 +364,16 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { pub fn read_immediate_raw( &self, src: &OpTy<'tcx, M::Provenance>, - ) -> InterpResult<'tcx, Result<ImmTy<'tcx, M::Provenance>, MPlaceTy<'tcx, M::Provenance>>> { - Ok(match src.try_as_mplace() { - Ok(ref mplace) => { + ) -> InterpResult<'tcx, Either<MPlaceTy<'tcx, M::Provenance>, ImmTy<'tcx, M::Provenance>>> { + Ok(match src.as_mplace_or_imm() { + Left(ref mplace) => { if let Some(val) = self.read_immediate_from_mplace_raw(mplace)? { - Ok(val) + Right(val) } else { - Err(*mplace) + Left(*mplace) } } - Err(val) => Ok(val), + Right(val) => Right(val), }) } @@ -390,7 +392,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) { span_bug!(self.cur_span(), "primitive read not possible for type: {:?}", op.layout.ty); } - let imm = self.read_immediate_raw(op)?.unwrap(); + let imm = self.read_immediate_raw(op)?.right().unwrap(); if matches!(*imm, Immediate::Uninit) { throw_ub!(InvalidUninitBytes(None)); } @@ -432,9 +434,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Basically we just transmute this place into an array following simd_size_and_type. // This only works in memory, but repr(simd) types should never be immediates anyway. assert!(op.layout.ty.is_simd()); - match op.try_as_mplace() { - Ok(mplace) => self.mplace_to_simd(&mplace), - Err(imm) => match *imm { + match op.as_mplace_or_imm() { + Left(mplace) => self.mplace_to_simd(&mplace), + Right(imm) => match *imm { Immediate::Uninit => { throw_ub!(InvalidUninitBytes(None)) } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 29d2312612e..c47cfe8bb69 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -2,6 +2,8 @@ //! into a place. //! All high-level functions to write to memory work on places as destinations. +use either::{Either, Left, Right}; + use rustc_ast::Mutability; use rustc_middle::mir; use rustc_middle::ty; @@ -252,36 +254,36 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { // These are defined here because they produce a place. impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> { #[inline(always)] - pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> { + pub fn as_mplace_or_imm(&self) -> Either<MPlaceTy<'tcx, Prov>, ImmTy<'tcx, Prov>> { match **self { Operand::Indirect(mplace) => { - Ok(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() }) + Left(MPlaceTy { mplace, layout: self.layout, align: self.align.unwrap() }) } - Operand::Immediate(imm) => Err(ImmTy::from_immediate(imm, self.layout)), + Operand::Immediate(imm) => Right(ImmTy::from_immediate(imm, self.layout)), } } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> { - self.try_as_mplace().unwrap() + self.as_mplace_or_imm().left().unwrap() } } impl<'tcx, Prov: Provenance> PlaceTy<'tcx, Prov> { /// A place is either an mplace or some local. #[inline] - pub fn try_as_mplace(&self) -> Result<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> { + pub fn as_mplace_or_local(&self) -> Either<MPlaceTy<'tcx, Prov>, (usize, mir::Local)> { match **self { - Place::Ptr(mplace) => Ok(MPlaceTy { mplace, layout: self.layout, align: self.align }), - Place::Local { frame, local } => Err((frame, local)), + Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout, align: self.align }), + Place::Local { frame, local } => Right((frame, local)), } } #[inline(always)] #[cfg_attr(debug_assertions, track_caller)] // only in debug builds due to perf (see #98980) pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> { - self.try_as_mplace().unwrap() + self.as_mplace_or_local().left().unwrap() } } @@ -569,9 +571,9 @@ where } pub fn write_uninit(&mut self, dest: &PlaceTy<'tcx, M::Provenance>) -> InterpResult<'tcx> { - let mplace = match dest.try_as_mplace() { - Ok(mplace) => mplace, - Err((frame, local)) => { + let mplace = match dest.as_mplace_or_local() { + Left(mplace) => mplace, + Right((frame, local)) => { match M::access_local_mut(self, frame, local)? { Operand::Immediate(local) => { *local = Immediate::Uninit; @@ -639,7 +641,7 @@ where // Let us see if the layout is simple so we take a shortcut, // avoid force_allocation. let src = match self.read_immediate_raw(src)? { - Ok(src_val) => { + Right(src_val) => { // FIXME(const_prop): Const-prop can possibly evaluate an // unsized copy operation when it thinks that the type is // actually sized, due to a trivially false where-clause @@ -669,7 +671,7 @@ where ) }; } - Err(mplace) => mplace, + Left(mplace) => mplace, }; // Slow path, this does not fit into an immediate. Just memcpy. trace!("copy_op: {:?} <- {:?}: {}", *dest, src, dest.layout.ty); diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 6b2e2bb8aca..4966fd6ea80 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -7,6 +7,8 @@ //! but we still need to do bounds checking and adjust the layout. To not duplicate that with MPlaceTy, we actually //! implement the logic on OpTy, and MPlaceTy calls that. +use either::{Left, Right}; + use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::LayoutOf; @@ -84,13 +86,13 @@ where base: &OpTy<'tcx, M::Provenance>, field: usize, ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> { - let base = match base.try_as_mplace() { - Ok(ref mplace) => { + let base = match base.as_mplace_or_imm() { + Left(ref mplace) => { // We can reuse the mplace field computation logic for indirect operands. let field = self.mplace_field(mplace, field)?; return Ok(field.into()); } - Err(value) => value, + Right(value) => value, }; let field_layout = base.layout.field(self, field); diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 3c286fa61be..73f8bf4362e 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -2,6 +2,8 @@ //! //! The main entry point is the `step` method. +use either::Either; + use rustc_middle::mir; use rustc_middle::mir::interpret::{InterpResult, Scalar}; use rustc_middle::ty::layout::LayoutOf; @@ -46,7 +48,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(false); } - let Ok(loc) = self.frame().loc else { + let Either::Left(loc) = self.frame().loc else { // We are unwinding and this fn has no cleanup code. // Just go on unwinding. trace!("unwinding: skipping frame"); @@ -61,7 +63,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Make sure we are not updating `statement_index` of the wrong frame. assert_eq!(old_frames, self.frame_idx()); // Advance the program counter. - self.frame_mut().loc.as_mut().unwrap().statement_index += 1; + self.frame_mut().loc.as_mut().left().unwrap().statement_index += 1; return Ok(true); } @@ -305,7 +307,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.eval_terminator(terminator)?; if !self.stack().is_empty() { - if let Ok(loc) = self.frame().loc { + if let Either::Left(loc) = self.frame().loc { info!("// executing {:?}", loc.block); } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 8aa56c275d9..cd7a472c0f0 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -8,6 +8,8 @@ use std::convert::TryFrom; use std::fmt::{Display, Write}; use std::num::NonZeroUsize; +use either::{Left, Right}; + use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; @@ -852,9 +854,9 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> return Ok(()); } // Now that we definitely have a non-ZST array, we know it lives in memory. - let mplace = match op.try_as_mplace() { - Ok(mplace) => mplace, - Err(imm) => match *imm { + let mplace = match op.as_mplace_or_imm() { + Left(mplace) => mplace, + Right(imm) => match *imm { Immediate::Uninit => throw_validation_failure!(self.path, { "uninitialized bytes" }), Immediate::Scalar(..) | Immediate::ScalarPair(..) => diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 5a8b3e30b9f..36956f5dd6d 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -732,7 +732,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { polarity: ty::ImplPolarity::Positive, }); let obligation = - Obligation::new(ObligationCause::dummy(), param_env, poly_trait_pred); + Obligation::new(tcx, ObligationCause::dummy(), param_env, poly_trait_pred); let implsrc = { let infcx = tcx.infer_ctxt().build(); @@ -816,6 +816,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { if !nonconst_call_permission { let obligation = Obligation::new( + tcx, ObligationCause::dummy_with_span(*fn_span), param_env, tcx.mk_predicate( diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs index 25b420bed17..b90e0962ce6 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs @@ -62,7 +62,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { } fn is_async(&self) -> bool { - self.tcx.asyncness(self.def_id()) == hir::IsAsync::Async + self.tcx.asyncness(self.def_id()).is_async() } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index b28d7019491..c62c6651587 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -1,7 +1,7 @@ //! Concrete error types for all operations which may be invalid in a certain const context. use hir::def_id::LocalDefId; -use hir::ConstContext; +use hir::{ConstContext, LangItem}; use rustc_errors::{ error_code, struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, }; @@ -147,6 +147,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { } Adt(..) => { let obligation = Obligation::new( + tcx, ObligationCause::dummy(), param_env, Binder::dummy(TraitPredicate { @@ -303,7 +304,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { err.span_note(deref_target, "deref defined here"); } - diag_trait(&mut err, self_ty, tcx.lang_items().deref_trait().unwrap()); + diag_trait(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, Some(span))); err } _ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentV1Methods) => { diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index d995d533ca3..e7b3df9b728 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -153,16 +153,12 @@ impl Qualif for NeedsNonConstDrop { return false; } - let destruct = cx.tcx.require_lang_item(LangItem::Destruct, None); - let obligation = Obligation::new( - ObligationCause::dummy(), + cx.tcx, + ObligationCause::dummy_with_span(cx.body.span), cx.param_env, ty::Binder::dummy(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: destruct, - substs: cx.tcx.mk_substs_trait(ty, &[]), - }, + trait_ref: cx.tcx.at(cx.body.span).mk_trait_ref(LangItem::Destruct, [ty]), constness: ty::BoundConstness::ConstIfConst, polarity: ty::ImplPolarity::Positive, }), @@ -351,7 +347,11 @@ where // FIXME(valtrees): check whether const qualifs should behave the same // way for type and mir constants. let uneval = match constant.literal { - ConstantKind::Ty(ct) if matches!(ct.kind(), ty::ConstKind::Param(_)) => None, + ConstantKind::Ty(ct) + if matches!(ct.kind(), ty::ConstKind::Param(_) | ty::ConstKind::Error(_)) => + { + None + } ConstantKind::Ty(c) => bug!("expected ConstKind::Param here, found {:?}", c), ConstantKind::Unevaluated(uv, _) => Some(uv), ConstantKind::Val(..) => None, diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 81b82a21fa1..860dee58980 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -2,7 +2,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_index::bit_set::BitSet; -use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::visit::NonUseContext::VarDebugInfo; use rustc_middle::mir::visit::{PlaceContext, Visitor}; @@ -12,8 +11,7 @@ use rustc_middle::mir::{ ProjectionElem, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK, }; -use rustc_middle::ty::fold::BottomUpFolder; -use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable}; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -70,44 +68,6 @@ impl<'tcx> MirPass<'tcx> for Validator { } } -/// Returns whether the two types are equal up to lifetimes. -/// All lifetimes, including higher-ranked ones, get ignored for this comparison. -/// (This is unlike the `erasing_regions` methods, which keep higher-ranked lifetimes for soundness reasons.) -/// -/// The point of this function is to approximate "equal up to subtyping". However, -/// the approximation is incorrect as variance is ignored. -pub fn equal_up_to_regions<'tcx>( - tcx: TyCtxt<'tcx>, - param_env: ParamEnv<'tcx>, - src: Ty<'tcx>, - dest: Ty<'tcx>, -) -> bool { - // Fast path. - if src == dest { - return true; - } - - // Normalize lifetimes away on both sides, then compare. - let normalize = |ty: Ty<'tcx>| { - tcx.try_normalize_erasing_regions(param_env, ty).unwrap_or(ty).fold_with( - &mut BottomUpFolder { - tcx, - // FIXME: We erase all late-bound lifetimes, but this is not fully correct. - // If you have a type like `<for<'a> fn(&'a u32) as SomeTrait>::Assoc`, - // this is not necessarily equivalent to `<fn(&'static u32) as SomeTrait>::Assoc`, - // since one may have an `impl SomeTrait for fn(&32)` and - // `impl SomeTrait for fn(&'static u32)` at the same time which - // specify distinct values for Assoc. (See also #56105) - lt_op: |_| tcx.lifetimes.re_erased, - // Leave consts and types unchanged. - ct_op: |ct| ct, - ty_op: |ty| ty, - }, - ) - }; - tcx.infer_ctxt().build().can_eq(param_env, normalize(src), normalize(dest)).is_ok() -} - struct TypeChecker<'a, 'tcx> { when: &'a str, body: &'a Body<'tcx>, @@ -183,22 +143,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - // Normalize projections and things like that. - // Type-changing assignments can happen when subtyping is used. While - // all normal lifetimes are erased, higher-ranked types with their - // late-bound lifetimes are still around and can lead to type - // differences. So we compare ignoring lifetimes. - - // First, try with reveal_all. This might not work in some cases, as the predicates - // can be cleared in reveal_all mode. We try the reveal first anyways as it is used - // by some other passes like inlining as well. - let param_env = self.param_env.with_reveal_all_normalized(self.tcx); - if equal_up_to_regions(self.tcx, param_env, src, dest) { - return true; - } - - // If this fails, we can try it without the reveal. - equal_up_to_regions(self.tcx, self.param_env, src, dest) + crate::util::is_subtype(self.tcx, self.param_env, src, dest) } } diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs index 5446ccb1a47..b38a6c55138 100644 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ b/compiler/rustc_const_eval/src/util/call_kind.rs @@ -3,7 +3,7 @@ //! context. use rustc_hir::def_id::DefId; -use rustc_hir::lang_items; +use rustc_hir::{lang_items, LangItem}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AssocItemContainer, DefIdTree, Instance, ParamEnv, Ty, TyCtxt}; use rustc_span::symbol::Ident; @@ -26,7 +26,7 @@ impl CallDesugaringKind { match self { Self::ForLoopIntoIter => tcx.get_diagnostic_item(sym::IntoIterator).unwrap(), Self::QuestionBranch | Self::TryBlockFromOutput => { - tcx.lang_items().try_trait().unwrap() + tcx.require_lang_item(LangItem::Try, None) } Self::QuestionFromResidual => tcx.get_diagnostic_item(sym::FromResidual).unwrap(), } diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs new file mode 100644 index 00000000000..a9cb191cc59 --- /dev/null +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -0,0 +1,63 @@ +//! Routines to check for relations between fully inferred types. +//! +//! FIXME: Move this to a more general place. The utility of this extends to +//! other areas of the compiler as well. + +use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; +use rustc_infer::traits::ObligationCause; +use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; +use rustc_trait_selection::traits::ObligationCtxt; + +/// Returns whether the two types are equal up to subtyping. +/// +/// This is used in case we don't know the expected subtyping direction +/// and still want to check whether anything is broken. +pub fn is_equal_up_to_subtyping<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + src: Ty<'tcx>, + dest: Ty<'tcx>, +) -> bool { + // Fast path. + if src == dest { + return true; + } + + // Check for subtyping in either direction. + is_subtype(tcx, param_env, src, dest) || is_subtype(tcx, param_env, dest, src) +} + +/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. +/// +/// This mostly ignores opaque types as it can be used in constraining contexts +/// while still computing the final underlying type. +pub fn is_subtype<'tcx>( + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + src: Ty<'tcx>, + dest: Ty<'tcx>, +) -> bool { + if src == dest { + return true; + } + + let mut builder = + tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble); + let infcx = builder.build(); + let ocx = ObligationCtxt::new(&infcx); + let cause = ObligationCause::dummy(); + let src = ocx.normalize(cause.clone(), param_env, src); + let dest = ocx.normalize(cause.clone(), param_env, dest); + match ocx.sub(&cause, param_env, src, dest) { + Ok(()) => {} + Err(_) => return false, + }; + let errors = ocx.select_all_or_error(); + // With `Reveal::All`, opaque types get normalized away, with `Reveal::UserFacing` + // we would get unification errors because we're unable to look into opaque types, + // even if they're constrained in our current function. + // + // It seems very unlikely that this hides any bugs. + let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types(); + errors.is_empty() +} diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 4d0f81a4060..76ea5a24e69 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -2,6 +2,7 @@ pub mod aggregate; mod alignment; mod call_kind; pub mod collect_writes; +mod compare_types; mod find_self_call; mod might_permit_raw_init; mod type_name; @@ -9,6 +10,7 @@ mod type_name; pub use self::aggregate::expand_aggregate; pub use self::alignment::is_disaligned; pub use self::call_kind::{call_kind, CallDesugaringKind, CallKind}; +pub use self::compare_types::{is_equal_up_to_subtyping, is_subtype}; pub use self::find_self_call::find_self_call; pub use self::might_permit_raw_init::might_permit_raw_init; pub use self::type_name::type_name; diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 08a6d69b8e4..14c8c88028b 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -74,7 +74,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { fn print_dyn_existential( self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { self.pretty_print_dyn_existential(predicates) } diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs index a3d3f988344..84cb417dd89 100644 --- a/compiler/rustc_data_structures/src/functor.rs +++ b/compiler/rustc_data_structures/src/functor.rs @@ -34,43 +34,11 @@ impl<T> IdFunctor for Vec<T> { type Inner = T; #[inline] - fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E> + fn try_map_id<F, E>(self, f: F) -> Result<Self, E> where F: FnMut(Self::Inner) -> Result<Self::Inner, E>, { - struct HoleVec<T> { - vec: Vec<mem::ManuallyDrop<T>>, - hole: Option<usize>, - } - - impl<T> Drop for HoleVec<T> { - fn drop(&mut self) { - unsafe { - for (index, slot) in self.vec.iter_mut().enumerate() { - if self.hole != Some(index) { - mem::ManuallyDrop::drop(slot); - } - } - } - } - } - - unsafe { - let (ptr, length, capacity) = self.into_raw_parts(); - let vec = Vec::from_raw_parts(ptr.cast(), length, capacity); - let mut hole_vec = HoleVec { vec, hole: None }; - - for (index, slot) in hole_vec.vec.iter_mut().enumerate() { - hole_vec.hole = Some(index); - let original = mem::ManuallyDrop::take(slot); - let mapped = f(original)?; - *slot = mem::ManuallyDrop::new(mapped); - hole_vec.hole = None; - } - - mem::forget(hole_vec); - Ok(Vec::from_raw_parts(ptr, length, capacity)) - } + self.into_iter().map(f).collect() } } diff --git a/compiler/rustc_driver/src/lib.rs b/compiler/rustc_driver/src/lib.rs index e043368fdfe..8a712cec852 100644 --- a/compiler/rustc_driver/src/lib.rs +++ b/compiler/rustc_driver/src/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(is_terminal)] #![feature(once_cell)] #![feature(decl_macro)] #![recursion_limit = "256"] @@ -27,7 +28,6 @@ use rustc_feature::find_gated_cfg; use rustc_interface::util::{self, collect_crate_types, get_codegen_backend}; use rustc_interface::{interface, Queries}; use rustc_lint::LintStore; -use rustc_log::stdout_isatty; use rustc_metadata::locator; use rustc_save_analysis as save; use rustc_save_analysis::DumpHandler; @@ -48,7 +48,7 @@ use std::default::Default; use std::env; use std::ffi::OsString; use std::fs; -use std::io::{self, Read, Write}; +use std::io::{self, IsTerminal, Read, Write}; use std::panic::{self, catch_unwind}; use std::path::PathBuf; use std::process::{self, Command, Stdio}; @@ -515,7 +515,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) { } text.push('\n'); } - if stdout_isatty() { + if io::stdout().is_terminal() { show_content_with_pager(&text); } else { print!("{}", text); diff --git a/compiler/rustc_error_codes/src/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md index e1dcfefebcd..85e5faada22 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0760.md +++ b/compiler/rustc_error_codes/src/error_codes/E0760.md @@ -1,9 +1,11 @@ +#### Note: this error code is no longer emitted by the compiler. + `async fn`/`impl trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope. Erroneous code example: -```compile_fail,E0760,edition2018 +```compile_fail,edition2018 struct S<'a>(&'a i32); impl<'a> S<'a> { diff --git a/compiler/rustc_error_messages/Cargo.toml b/compiler/rustc_error_messages/Cargo.toml index 9945f337995..0c705d2ecf5 100644 --- a/compiler/rustc_error_messages/Cargo.toml +++ b/compiler/rustc_error_messages/Cargo.toml @@ -9,9 +9,17 @@ edition = "2021" fluent-bundle = "0.15.2" fluent-syntax = "0.11" intl-memoizer = "0.5.1" +rustc_baked_icu_data = { path = "../rustc_baked_icu_data" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } rustc_macros = { path = "../rustc_macros" } tracing = "0.1" unic-langid = { version = "0.9.0", features = ["macros"] } +icu_list = "1.0.0" +writeable = "0.5.0" +icu_locid = "1.0.0" +icu_provider_adapters = "1.0.0" + +[features] +rustc_use_parallel_compiler = ['rustc_baked_icu_data/rustc_use_parallel_compiler'] diff --git a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl index de47ada8264..2cd4733220e 100644 --- a/compiler/rustc_error_messages/locales/en-US/borrowck.ftl +++ b/compiler/rustc_error_messages/locales/en-US/borrowck.ftl @@ -24,9 +24,6 @@ borrowck_var_does_not_need_mut = variable does not need to be mutable .suggestion = remove this `mut` -borrowck_const_not_used_in_type_alias = - const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias - borrowck_var_cannot_escape_closure = captured variable cannot escape `FnMut` closure body .note = `FnMut` closures only have access to their captured variables while they are executing... diff --git a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl index d27edd47470..0894bbcaad4 100644 --- a/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl +++ b/compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl @@ -1,8 +1,3 @@ -hir_analysis_field_multiply_specified_in_initializer = - field `{$ident}` specified more than once - .label = used more than once - .previous_use_label = first use of `{$ident}` - hir_analysis_unrecognized_atomic_operation = unrecognized atomic operation function: `{$op}` .label = unrecognized atomic operation @@ -54,44 +49,16 @@ hir_analysis_assoc_type_binding_not_allowed = associated type bindings are not allowed here .label = associated type not allowed here -hir_analysis_functional_record_update_on_non_struct = - functional record update syntax requires a struct - hir_analysis_typeof_reserved_keyword_used = `typeof` is a reserved keyword but unimplemented .suggestion = consider replacing `typeof(...)` with an actual type .label = reserved keyword -hir_analysis_return_stmt_outside_of_fn_body = - return statement outside of function body - .encl_body_label = the return is part of this body... - .encl_fn_label = ...not the enclosing function body - -hir_analysis_yield_expr_outside_of_generator = - yield expression outside of generator literal - -hir_analysis_struct_expr_non_exhaustive = - cannot create non-exhaustive {$what} using struct expression - -hir_analysis_method_call_on_unknown_type = - the type of this value must be known to call a method on a raw pointer on it - hir_analysis_value_of_associated_struct_already_specified = the value of the associated type `{$item_name}` (from trait `{$def_path}`) is already specified .label = re-bound here .previous_bound_label = `{$item_name}` bound here first -hir_analysis_address_of_temporary_taken = cannot take address of a temporary - .label = temporary value - -hir_analysis_add_return_type_add = try adding a return type - -hir_analysis_add_return_type_missing_here = a return type might be missing here - -hir_analysis_expected_default_return_type = expected `()` because of default return type - -hir_analysis_expected_return_type = expected `{$expected}` because of return type - hir_analysis_unconstrained_opaque_type = unconstrained opaque type .note = `{$name}` must be used in combination with a concrete type within the same {$what} @@ -134,10 +101,6 @@ hir_analysis_extern_crate_not_idiomatic = hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(linker)` -hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` - -hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function - hir_analysis_const_impl_for_non_const_trait = const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]` .suggestion = mark `{$trait_name}` as const @@ -150,6 +113,3 @@ hir_analysis_const_bound_for_non_const_trait = hir_analysis_self_in_impl_self = `Self` is not valid in the self type of an impl block .note = replace `Self` with a different type - -hir_analysis_op_trait_generic_params = - `{$method_name}` must not have any generic parameters diff --git a/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl new file mode 100644 index 00000000000..0612dbae0b6 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/hir_typeck.ftl @@ -0,0 +1,48 @@ +hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression +hir_typeck_fru_expr = this expression does not end in a comma... +hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax +hir_typeck_fru_suggestion = + to set the remaining fields{$expr -> + [NONE]{""} + *[other] {" "}from `{$expr}` + }, separate the last named field with a comma + +hir_typeck_field_multiply_specified_in_initializer = + field `{$ident}` specified more than once + .label = used more than once + .previous_use_label = first use of `{$ident}` + +hir_typeck_return_stmt_outside_of_fn_body = + return statement outside of function body + .encl_body_label = the return is part of this body... + .encl_fn_label = ...not the enclosing function body + +hir_typeck_yield_expr_outside_of_generator = + yield expression outside of generator literal + +hir_typeck_struct_expr_non_exhaustive = + cannot create non-exhaustive {$what} using struct expression + +hir_typeck_method_call_on_unknown_type = + the type of this value must be known to call a method on a raw pointer on it + +hir_typeck_functional_record_update_on_non_struct = + functional record update syntax requires a struct + +hir_typeck_address_of_temporary_taken = cannot take address of a temporary + .label = temporary value + +hir_typeck_add_return_type_add = try adding a return type + +hir_typeck_add_return_type_missing_here = a return type might be missing here + +hir_typeck_expected_default_return_type = expected `()` because of default return type + +hir_typeck_expected_return_type = expected `{$expected}` because of return type + +hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` + +hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function + +hir_typeck_op_trait_generic_params = + `{$method_name}` must not have any generic parameters diff --git a/compiler/rustc_error_messages/locales/en-US/metadata.ftl b/compiler/rustc_error_messages/locales/en-US/metadata.ftl index c292ae9b32a..d1e1fd54db9 100644 --- a/compiler/rustc_error_messages/locales/en-US/metadata.ftl +++ b/compiler/rustc_error_messages/locales/en-US/metadata.ftl @@ -275,7 +275,7 @@ metadata_crate_location_unknown_type = extern location for {$crate_name} is of an unknown type: {$path} metadata_lib_filename_form = - file name should be lib*.rlib or {dll_prefix}*.{dll_suffix} + file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix} metadata_multiple_import_name_type = multiple `import_name_type` arguments in a single `#[link]` attribute diff --git a/compiler/rustc_error_messages/locales/en-US/middle.ftl b/compiler/rustc_error_messages/locales/en-US/middle.ftl index 81d8e8a473b..4f4e5c6a2c9 100644 --- a/compiler/rustc_error_messages/locales/en-US/middle.ftl +++ b/compiler/rustc_error_messages/locales/en-US/middle.ftl @@ -31,3 +31,6 @@ middle_cannot_be_normalized = middle_strict_coherence_needs_negative_coherence = to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled .label = due to this attribute + +middle_const_not_used_in_type_alias = + const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias diff --git a/compiler/rustc_error_messages/locales/en-US/parse.ftl b/compiler/rustc_error_messages/locales/en-US/parse.ftl new file mode 100644 index 00000000000..114b7ec1628 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/parse.ftl @@ -0,0 +1,364 @@ +parse_struct_literal_body_without_path = + struct literal body without path + .suggestion = you might have forgotten to add the struct literal inside the block + +parse_maybe_report_ambiguous_plus = + ambiguous `+` in a type + .suggestion = use parentheses to disambiguate + +parse_maybe_recover_from_bad_type_plus = + expected a path on the left-hand side of `+`, not `{$ty}` + +parse_add_paren = try adding parentheses + +parse_forgot_paren = perhaps you forgot parentheses? + +parse_expect_path = expected a path + +parse_maybe_recover_from_bad_qpath_stage_2 = + missing angle brackets in associated item path + .suggestion = try: `{$ty}` + +parse_incorrect_semicolon = + expected item, found `;` + .suggestion = remove this semicolon + .help = {$name} declarations are not followed by a semicolon + +parse_incorrect_use_of_await = + incorrect use of `await` + .parentheses_suggestion = `await` is not a method call, remove the parentheses + .postfix_suggestion = `await` is a postfix operation + +parse_in_in_typo = + expected iterable, found keyword `in` + .suggestion = remove the duplicated `in` + +parse_invalid_variable_declaration = + invalid variable declaration + +parse_switch_mut_let_order = + switch the order of `mut` and `let` +parse_missing_let_before_mut = missing keyword +parse_use_let_not_auto = write `let` instead of `auto` to introduce a new variable +parse_use_let_not_var = write `let` instead of `var` to introduce a new variable + +parse_invalid_comparison_operator = invalid comparison operator `{$invalid}` + .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}` + .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` + +parse_invalid_logical_operator = `{$incorrect}` is not a logical operator + .note = unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators + .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction + .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction + +parse_tilde_is_not_unary_operator = `~` cannot be used as a unary operator + .suggestion = use `!` to perform bitwise not + +parse_unexpected_if_with_if = unexpected `if` in the condition expression + .suggestion = remove the `if` + +parse_unexpected_token_after_not = unexpected {$negated_desc} after identifier +parse_unexpected_token_after_not_bitwise = use `!` to perform bitwise not +parse_unexpected_token_after_not_logical = use `!` to perform logical negation +parse_unexpected_token_after_not_default = use `!` to perform logical negation or bitwise not + +parse_malformed_loop_label = malformed loop label + .suggestion = use the correct loop label format + +parse_lifetime_in_borrow_expression = borrow expressions cannot be annotated with lifetimes + .suggestion = remove the lifetime annotation + .label = annotated with lifetime here + +parse_field_expression_with_generic = field expressions cannot have generic arguments + +parse_macro_invocation_with_qualified_path = macros cannot use qualified paths + +parse_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label + .suggestion_remove_label = consider removing the label + .suggestion_enclose_in_block = consider enclosing expression in a block + +parse_require_colon_after_labeled_expression = labeled expression must be followed by `:` + .note = labels are used before loops and blocks, allowing e.g., `break 'label` to them + .label = the label + .suggestion = add `:` after the label + +parse_do_catch_syntax_removed = found removed `do catch` syntax + .note = following RFC #2388, the new non-placeholder syntax is `try` + .suggestion = replace with the new syntax + +parse_float_literal_requires_integer_part = float literals must have an integer part + .suggestion = must have an integer part + +parse_missing_semicolon_before_array = expected `;`, found `[` + .suggestion = consider adding `;` here + +parse_invalid_block_macro_segment = cannot use a `block` macro fragment here + .label = the `block` fragment is within this context + +parse_expect_dotdot_not_dotdotdot = expected `..`, found `...` + .suggestion = use `..` to fill in the rest of the fields + +parse_if_expression_missing_then_block = this `if` expression is missing a block after the condition + .add_then_block = add a block here + .condition_possibly_unfinished = this binary operation is possibly unfinished + +parse_if_expression_missing_condition = missing condition for `if` expression + .condition_label = expected condition here + .block_label = if this block is the condition of the `if` expression, then it must be followed by another block + +parse_expected_expression_found_let = expected expression, found `let` statement + +parse_expect_eq_instead_of_eqeq = expected `=`, found `==` + .suggestion = consider using `=` here + +parse_expected_else_block = expected `{"{"}`, found {$first_tok} + .label = expected an `if` or a block after this `else` + .suggestion = add an `if` if this is the condition of a chained `else if` statement + +parse_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches + .branch_label = the attributes are attached to this branch + .ctx_label = the branch belongs to this `{$ctx}` + .suggestion = remove the attributes + +parse_missing_in_in_for_loop = missing `in` in `for` loop + .use_in_not_of = try using `in` here instead + .add_in = try adding `in` here + +parse_missing_comma_after_match_arm = expected `,` following `match` arm + .suggestion = missing a comma here to end this `match` arm + +parse_catch_after_try = keyword `catch` cannot follow a `try` block + .help = try using `match` on the result of the `try` block instead + +parse_comma_after_base_struct = cannot use a comma after the base struct + .note = the base struct must always be the last field + .suggestion = remove this comma + +parse_eq_field_init = expected `:`, found `=` + .suggestion = replace equals symbol with a colon + +parse_dotdotdot = unexpected token: `...` + .suggest_exclusive_range = use `..` for an exclusive range + .suggest_inclusive_range = or `..=` for an inclusive range + +parse_left_arrow_operator = unexpected token: `<-` + .suggestion = if you meant to write a comparison against a negative value, add a space in between `<` and `-` + +parse_remove_let = expected pattern, found `let` + .suggestion = remove the unnecessary `let` keyword + +parse_use_eq_instead = unexpected `==` + .suggestion = try using `=` instead + +parse_use_empty_block_not_semi = expected { "`{}`" }, found `;` + .suggestion = try using { "`{}`" } instead + +parse_comparison_interpreted_as_generic = + `<` is interpreted as a start of generic arguments for `{$type}`, not a comparison + .label_args = interpreted as generic arguments + .label_comparison = not interpreted as comparison + .suggestion = try comparing the cast value + +parse_shift_interpreted_as_generic = + `<<` is interpreted as a start of generic arguments for `{$type}`, not a shift + .label_args = interpreted as generic arguments + .label_comparison = not interpreted as shift + .suggestion = try shifting the cast value + +parse_found_expr_would_be_stmt = expected expression, found `{$token}` + .label = expected expression + +parse_leading_plus_not_supported = leading `+` is not supported + .label = unexpected `+` + .suggestion_remove_plus = try removing the `+` + +parse_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call arguments + .suggestion_braces_for_struct = if `{$type}` is a struct, use braces as delimiters + .suggestion_no_fields_for_fn = if `{$type}` is a function, use the arguments directly + +parse_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression + +parse_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses + +parse_array_brackets_instead_of_braces = this is a block expression, not an array + .suggestion = to make an array, use square brackets instead of curly braces + +parse_match_arm_body_without_braces = `match` arm body without braces + .label_statements = {$num_statements -> + [one] this statement is not surrounded by a body + *[other] these statements are not surrounded by a body + } + .label_arrow = while parsing the `match` arm starting here + .suggestion_add_braces = surround the {$num_statements -> + [one] statement + *[other] statements + } with a body + .suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression + +parse_struct_literal_not_allowed_here = struct literals are not allowed here + .suggestion = surround the struct literal with parentheses + +parse_invalid_interpolated_expression = invalid interpolated expression + +parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid + .label = invalid suffix `{$suffix}` + .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases + .tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access + .tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information + +parse_non_string_abi_literal = non-string ABI literal + .suggestion = specify the ABI with a string literal + +parse_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}` + .label_unmatched = mismatched closing delimiter + .label_opening_candidate = closing delimiter possibly meant for this + .label_unclosed = unclosed delimiter + +parse_incorrect_visibility_restriction = incorrect visibility restriction + .help = some possible visibility restrictions are: + `pub(crate)`: visible only on the current crate + `pub(super)`: visible only in the current module's parent + `pub(in path::to::module)`: visible only on the specified path + .suggestion = make this visible only to module `{$inner_str}` with `in` + +parse_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is not allowed + +parse_expected_statement_after_outer_attr = expected statement after outer attribute + +parse_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything + .help = doc comments must come before what they document, if a comment was intended use `//` + .suggestion = missing comma here + +parse_const_let_mutually_exclusive = `const` and `let` are mutually exclusive + .suggestion = remove `let` + +parse_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` +parse_invalid_curly_in_let_else = right curly brace `{"}"}` before `else` in a `let...else` statement not allowed + +parse_compound_assignment_expression_in_let = can't reassign to an uninitialized variable + .suggestion = initialize the variable + .help = if you meant to overwrite, remove the `let` binding + +parse_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes + .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) + +parse_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` + +parse_label_inner_attr_does_not_annotate_this = the inner attribute doesn't annotate this {$item} +parse_sugg_change_inner_attr_to_outer = to annotate the {$item}, change the attribute from inner to outer style + +parse_inner_attr_not_permitted_after_outer_doc_comment = an inner attribute is not permitted following an outer doc comment + .label_attr = not permitted following an outer doc comment + .label_prev_doc_comment = previous doc comment + .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} + .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} + +parse_inner_attr_not_permitted_after_outer_attr = an inner attribute is not permitted following an outer attribute + .label_attr = not permitted following an outer attribute + .label_prev_attr = previous outer attribute + .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} + .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} + +parse_inner_attr_not_permitted = an inner attribute is not permitted in this context + .label_does_not_annotate_this = {parse_label_inner_attr_does_not_annotate_this} + .sugg_change_inner_to_outer = {parse_sugg_change_inner_attr_to_outer} + +parse_inner_attr_explanation = inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files +parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them + +parse_inner_doc_comment_not_permitted = expected outer doc comment + .note = inner doc comments like this (starting with `//!` or `/*!`) can only appear before items + .suggestion = you might have meant to write a regular comment + .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} + .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style + +parse_expected_identifier_found_reserved_identifier_str = expected identifier, found reserved identifier `{$token}` +parse_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token}` +parse_expected_identifier_found_reserved_keyword_str = expected identifier, found reserved keyword `{$token}` +parse_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token}` +parse_expected_identifier_found_str = expected identifier, found `{$token}` + +parse_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier +parse_expected_identifier_found_keyword = expected identifier, found keyword +parse_expected_identifier_found_reserved_keyword = expected identifier, found reserved keyword +parse_expected_identifier_found_doc_comment = expected identifier, found doc comment +parse_expected_identifier = expected identifier + +parse_sugg_escape_to_use_as_identifier = escape `{$ident_name}` to use it as an identifier + +parse_sugg_remove_comma = remove this comma + +parse_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}` +parse_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}` +parse_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token}` +parse_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token}` +parse_expected_semi_found_str = expected `;`, found `{$token}` + +parse_sugg_change_this_to_semi = change this to `;` +parse_sugg_add_semi = add `;` here +parse_label_unexpected_token = unexpected token + +parse_unmatched_angle_brackets = {$num_extra_brackets -> + [one] unmatched angle bracket + *[other] unmatched angle brackets + } + .suggestion = {$num_extra_brackets -> + [one] remove extra angle bracket + *[other] remove extra angle brackets + } + +parse_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets + .suggestion = surround the type parameters with angle brackets + +parse_comparison_operators_cannot_be_chained = comparison operators cannot be chained + .sugg_parentheses_for_function_args = or use `(...)` if you meant to specify fn arguments + .sugg_split_comparison = split the comparison into two + .sugg_parenthesize = parenthesize the comparison +parse_sugg_turbofish_syntax = use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments + +parse_question_mark_in_type = invalid `?` in type + .label = `?` is only allowed on expressions, not types + .suggestion = if you meant to express that the type might not contain a value, use the `Option` wrapper type + +parse_unexpected_parentheses_in_for_head = unexpected parentheses surrounding `for` loop head + .suggestion = remove parentheses in `for` loop + +parse_doc_comment_on_param_type = documentation comments cannot be applied to a function parameter's type + .label = doc comments are not allowed here + +parse_attribute_on_param_type = attributes cannot be applied to a function parameter's type + .label = attributes are not allowed here + +parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies + .suggestion = give this argument a name or use an underscore to ignore it + +parse_self_param_not_first = unexpected `self` parameter in function + .label = must be the first parameter of an associated function + +parse_const_generic_without_braces = expressions must be enclosed in braces to be used as const generic arguments + .suggestion = enclose the `const` expression in braces + +parse_unexpected_const_param_declaration = unexpected `const` parameter declaration + .label = expected a `const` expression, not a parameter declaration + .suggestion = `const` parameters must be declared for the `impl` + +parse_unexpected_const_in_generic_param = expected lifetime, type, or constant, found keyword `const` + .suggestion = the `const` keyword is only needed in the definition of the type + +parse_async_move_order_incorrect = the order of `move` and `async` is incorrect + .suggestion = try switching the order + +parse_double_colon_in_bound = expected `:` followed by trait or lifetime + .suggestion = use single colon + +parse_fn_ptr_with_generics = function pointer types may not have generic parameters + .suggestion = consider moving the lifetime {$arity -> + [one] parameter + *[other] parameters + } to {$for_param_list_exists -> + [true] the + *[false] a + } `for` parameter list + +parse_invalid_identifier_with_leading_number = expected identifier, found number literal + .label = identifiers cannot start with a number diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl deleted file mode 100644 index 4c7ce30097c..00000000000 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ /dev/null @@ -1,389 +0,0 @@ -parser_struct_literal_body_without_path = - struct literal body without path - .suggestion = you might have forgotten to add the struct literal inside the block - -parser_maybe_report_ambiguous_plus = - ambiguous `+` in a type - .suggestion = use parentheses to disambiguate - -parser_maybe_recover_from_bad_type_plus = - expected a path on the left-hand side of `+`, not `{$ty}` - -parser_add_paren = try adding parentheses - -parser_forgot_paren = perhaps you forgot parentheses? - -parser_expect_path = expected a path - -parser_maybe_recover_from_bad_qpath_stage_2 = - missing angle brackets in associated item path - .suggestion = try: `{$ty}` - -parser_incorrect_semicolon = - expected item, found `;` - .suggestion = remove this semicolon - .help = {$name} declarations are not followed by a semicolon - -parser_incorrect_use_of_await = - incorrect use of `await` - .parentheses_suggestion = `await` is not a method call, remove the parentheses - .postfix_suggestion = `await` is a postfix operation - -parser_in_in_typo = - expected iterable, found keyword `in` - .suggestion = remove the duplicated `in` - -parser_invalid_variable_declaration = - invalid variable declaration - -parser_switch_mut_let_order = - switch the order of `mut` and `let` -parser_missing_let_before_mut = missing keyword -parser_use_let_not_auto = write `let` instead of `auto` to introduce a new variable -parser_use_let_not_var = write `let` instead of `var` to introduce a new variable - -parser_invalid_comparison_operator = invalid comparison operator `{$invalid}` - .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}` - .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` - -parser_invalid_logical_operator = `{$incorrect}` is not a logical operator - .note = unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators - .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction - .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction - -parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator - .suggestion = use `!` to perform bitwise not - -parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier -parser_unexpected_token_after_not_bitwise = use `!` to perform bitwise not -parser_unexpected_token_after_not_logical = use `!` to perform logical negation -parser_unexpected_token_after_not_default = use `!` to perform logical negation or bitwise not - -parser_malformed_loop_label = malformed loop label - .suggestion = use the correct loop label format - -parser_lifetime_in_borrow_expression = borrow expressions cannot be annotated with lifetimes - .suggestion = remove the lifetime annotation - .label = annotated with lifetime here - -parser_field_expression_with_generic = field expressions cannot have generic arguments - -parser_macro_invocation_with_qualified_path = macros cannot use qualified paths - -parser_unexpected_token_after_label = expected `while`, `for`, `loop` or `{"{"}` after a label - .suggestion_remove_label = consider removing the label - .suggestion_enclose_in_block = consider enclosing expression in a block - -parser_require_colon_after_labeled_expression = labeled expression must be followed by `:` - .note = labels are used before loops and blocks, allowing e.g., `break 'label` to them - .label = the label - .suggestion = add `:` after the label - -parser_do_catch_syntax_removed = found removed `do catch` syntax - .note = following RFC #2388, the new non-placeholder syntax is `try` - .suggestion = replace with the new syntax - -parser_float_literal_requires_integer_part = float literals must have an integer part - .suggestion = must have an integer part - -parser_invalid_int_literal_width = invalid width `{$width}` for integer literal - .help = valid widths are 8, 16, 32, 64 and 128 - -parser_invalid_num_literal_base_prefix = invalid base prefix for number literal - .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase - .suggestion = try making the prefix lowercase - -parser_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal - .label = invalid suffix `{$suffix}` - .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) - -parser_invalid_float_literal_width = invalid width `{$width}` for float literal - .help = valid widths are 32 and 64 - -parser_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal - .label = invalid suffix `{$suffix}` - .help = valid suffixes are `f32` and `f64` - -parser_int_literal_too_large = integer literal is too large - -parser_missing_semicolon_before_array = expected `;`, found `[` - .suggestion = consider adding `;` here - -parser_invalid_block_macro_segment = cannot use a `block` macro fragment here - .label = the `block` fragment is within this context - -parser_expect_dotdot_not_dotdotdot = expected `..`, found `...` - .suggestion = use `..` to fill in the rest of the fields - -parser_if_expression_missing_then_block = this `if` expression is missing a block after the condition - .add_then_block = add a block here - .condition_possibly_unfinished = this binary operation is possibly unfinished - -parser_if_expression_missing_condition = missing condition for `if` expression - .condition_label = expected condition here - .block_label = if this block is the condition of the `if` expression, then it must be followed by another block - -parser_expected_expression_found_let = expected expression, found `let` statement - -parser_expect_eq_instead_of_eqeq = expected `=`, found `==` - .suggestion = consider using `=` here - -parser_expected_else_block = expected `{"{"}`, found {$first_tok} - .label = expected an `if` or a block after this `else` - .suggestion = add an `if` if this is the condition of a chained `else if` statement - -parser_outer_attribute_not_allowed_on_if_else = outer attributes are not allowed on `if` and `else` branches - .branch_label = the attributes are attached to this branch - .ctx_label = the branch belongs to this `{$ctx}` - .suggestion = remove the attributes - -parser_missing_in_in_for_loop = missing `in` in `for` loop - .use_in_not_of = try using `in` here instead - .add_in = try adding `in` here - -parser_missing_comma_after_match_arm = expected `,` following `match` arm - .suggestion = missing a comma here to end this `match` arm - -parser_catch_after_try = keyword `catch` cannot follow a `try` block - .help = try using `match` on the result of the `try` block instead - -parser_comma_after_base_struct = cannot use a comma after the base struct - .note = the base struct must always be the last field - .suggestion = remove this comma - -parser_eq_field_init = expected `:`, found `=` - .suggestion = replace equals symbol with a colon - -parser_dotdotdot = unexpected token: `...` - .suggest_exclusive_range = use `..` for an exclusive range - .suggest_inclusive_range = or `..=` for an inclusive range - -parser_left_arrow_operator = unexpected token: `<-` - .suggestion = if you meant to write a comparison against a negative value, add a space in between `<` and `-` - -parser_remove_let = expected pattern, found `let` - .suggestion = remove the unnecessary `let` keyword - -parser_use_eq_instead = unexpected `==` - .suggestion = try using `=` instead - -parser_use_empty_block_not_semi = expected { "`{}`" }, found `;` - .suggestion = try using { "`{}`" } instead - -parser_comparison_interpreted_as_generic = - `<` is interpreted as a start of generic arguments for `{$type}`, not a comparison - .label_args = interpreted as generic arguments - .label_comparison = not interpreted as comparison - .suggestion = try comparing the cast value - -parser_shift_interpreted_as_generic = - `<<` is interpreted as a start of generic arguments for `{$type}`, not a shift - .label_args = interpreted as generic arguments - .label_comparison = not interpreted as shift - .suggestion = try shifting the cast value - -parser_found_expr_would_be_stmt = expected expression, found `{$token}` - .label = expected expression - -parser_leading_plus_not_supported = leading `+` is not supported - .label = unexpected `+` - .suggestion_remove_plus = try removing the `+` - -parser_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call arguments - .suggestion_braces_for_struct = if `{$type}` is a struct, use braces as delimiters - .suggestion_no_fields_for_fn = if `{$type}` is a function, use the arguments directly - -parser_labeled_loop_in_break = parentheses are required around this expression to avoid confusion with a labeled break expression - -parser_sugg_wrap_expression_in_parentheses = wrap the expression in parentheses - -parser_array_brackets_instead_of_braces = this is a block expression, not an array - .suggestion = to make an array, use square brackets instead of curly braces - -parser_match_arm_body_without_braces = `match` arm body without braces - .label_statements = {$num_statements -> - [one] this statement is not surrounded by a body - *[other] these statements are not surrounded by a body - } - .label_arrow = while parsing the `match` arm starting here - .suggestion_add_braces = surround the {$num_statements -> - [one] statement - *[other] statements - } with a body - .suggestion_use_comma_not_semicolon = use a comma to end a `match` arm expression - -parser_struct_literal_not_allowed_here = struct literals are not allowed here - .suggestion = surround the struct literal with parentheses - -parser_invalid_interpolated_expression = invalid interpolated expression - -parser_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported -parser_octal_float_literal_not_supported = octal float literal is not supported -parser_binary_float_literal_not_supported = binary float literal is not supported -parser_not_supported = not supported - -parser_invalid_literal_suffix = suffixes on {$kind} literals are invalid - .label = invalid suffix `{$suffix}` - -parser_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are invalid - .label = invalid suffix `{$suffix}` - .tuple_exception_line_1 = `{$suffix}` is *temporarily* accepted on tuple index fields as it was incorrectly accepted on stable for a few releases - .tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access - .tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information - -parser_non_string_abi_literal = non-string ABI literal - .suggestion = specify the ABI with a string literal - -parser_mismatched_closing_delimiter = mismatched closing delimiter: `{$delimiter}` - .label_unmatched = mismatched closing delimiter - .label_opening_candidate = closing delimiter possibly meant for this - .label_unclosed = unclosed delimiter - -parser_incorrect_visibility_restriction = incorrect visibility restriction - .help = some possible visibility restrictions are: - `pub(crate)`: visible only on the current crate - `pub(super)`: visible only in the current module's parent - `pub(in path::to::module)`: visible only on the specified path - .suggestion = make this visible only to module `{$inner_str}` with `in` - -parser_assignment_else_not_allowed = <assignment> ... else {"{"} ... {"}"} is not allowed - -parser_expected_statement_after_outer_attr = expected statement after outer attribute - -parser_doc_comment_does_not_document_anything = found a documentation comment that doesn't document anything - .help = doc comments must come before what they document, if a comment was intended use `//` - .suggestion = missing comma here - -parser_const_let_mutually_exclusive = `const` and `let` are mutually exclusive - .suggestion = remove `let` - -parser_invalid_expression_in_let_else = a `{$operator}` expression cannot be directly assigned in `let...else` -parser_invalid_curly_in_let_else = right curly brace `{"}"}` before `else` in a `let...else` statement not allowed - -parser_compound_assignment_expression_in_let = can't reassign to an uninitialized variable - .suggestion = initialize the variable - .help = if you meant to overwrite, remove the `let` binding - -parser_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes - .help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) - -parser_invalid_meta_item = expected unsuffixed literal or identifier, found `{$token}` - -parser_label_inner_attr_does_not_annotate_this = the inner attribute doesn't annotate this {$item} -parser_sugg_change_inner_attr_to_outer = to annotate the {$item}, change the attribute from inner to outer style - -parser_inner_attr_not_permitted_after_outer_doc_comment = an inner attribute is not permitted following an outer doc comment - .label_attr = not permitted following an outer doc comment - .label_prev_doc_comment = previous doc comment - .label_does_not_annotate_this = {parser_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parser_sugg_change_inner_attr_to_outer} - -parser_inner_attr_not_permitted_after_outer_attr = an inner attribute is not permitted following an outer attribute - .label_attr = not permitted following an outer attribute - .label_prev_attr = previous outer attribute - .label_does_not_annotate_this = {parser_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parser_sugg_change_inner_attr_to_outer} - -parser_inner_attr_not_permitted = an inner attribute is not permitted in this context - .label_does_not_annotate_this = {parser_label_inner_attr_does_not_annotate_this} - .sugg_change_inner_to_outer = {parser_sugg_change_inner_attr_to_outer} - -parser_inner_attr_explanation = inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files -parser_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them - -parser_inner_doc_comment_not_permitted = expected outer doc comment - .note = inner doc comments like this (starting with `//!` or `/*!`) can only appear before items - .suggestion = you might have meant to write a regular comment - .label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item} - .sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style - -parser_expected_identifier_found_reserved_identifier_str = expected identifier, found reserved identifier `{$token}` -parser_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token}` -parser_expected_identifier_found_reserved_keyword_str = expected identifier, found reserved keyword `{$token}` -parser_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token}` -parser_expected_identifier_found_str = expected identifier, found `{$token}` - -parser_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier -parser_expected_identifier_found_keyword = expected identifier, found keyword -parser_expected_identifier_found_reserved_keyword = expected identifier, found reserved keyword -parser_expected_identifier_found_doc_comment = expected identifier, found doc comment -parser_expected_identifier = expected identifier - -parser_sugg_escape_to_use_as_identifier = escape `{$ident_name}` to use it as an identifier - -parser_sugg_remove_comma = remove this comma - -parser_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token}` -parser_expected_semi_found_keyword_str = expected `;`, found keyword `{$token}` -parser_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token}` -parser_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token}` -parser_expected_semi_found_str = expected `;`, found `{$token}` - -parser_sugg_change_this_to_semi = change this to `;` -parser_sugg_add_semi = add `;` here -parser_label_unexpected_token = unexpected token - -parser_unmatched_angle_brackets = {$num_extra_brackets -> - [one] unmatched angle bracket - *[other] unmatched angle brackets - } - .suggestion = {$num_extra_brackets -> - [one] remove extra angle bracket - *[other] remove extra angle brackets - } - -parser_generic_parameters_without_angle_brackets = generic parameters without surrounding angle brackets - .suggestion = surround the type parameters with angle brackets - -parser_comparison_operators_cannot_be_chained = comparison operators cannot be chained - .sugg_parentheses_for_function_args = or use `(...)` if you meant to specify fn arguments - .sugg_split_comparison = split the comparison into two - .sugg_parenthesize = parenthesize the comparison -parser_sugg_turbofish_syntax = use `::<...>` instead of `<...>` to specify lifetime, type, or const arguments - -parser_question_mark_in_type = invalid `?` in type - .label = `?` is only allowed on expressions, not types - .suggestion = if you meant to express that the type might not contain a value, use the `Option` wrapper type - -parser_unexpected_parentheses_in_for_head = unexpected parentheses surrounding `for` loop head - .suggestion = remove parentheses in `for` loop - -parser_doc_comment_on_param_type = documentation comments cannot be applied to a function parameter's type - .label = doc comments are not allowed here - -parser_attribute_on_param_type = attributes cannot be applied to a function parameter's type - .label = attributes are not allowed here - -parser_pattern_method_param_without_body = patterns aren't allowed in methods without bodies - .suggestion = give this argument a name or use an underscore to ignore it - -parser_self_param_not_first = unexpected `self` parameter in function - .label = must be the first parameter of an associated function - -parser_const_generic_without_braces = expressions must be enclosed in braces to be used as const generic arguments - .suggestion = enclose the `const` expression in braces - -parser_unexpected_const_param_declaration = unexpected `const` parameter declaration - .label = expected a `const` expression, not a parameter declaration - .suggestion = `const` parameters must be declared for the `impl` - -parser_unexpected_const_in_generic_param = expected lifetime, type, or constant, found keyword `const` - .suggestion = the `const` keyword is only needed in the definition of the type - -parser_async_move_order_incorrect = the order of `move` and `async` is incorrect - .suggestion = try switching the order - -parser_double_colon_in_bound = expected `:` followed by trait or lifetime - .suggestion = use single colon - -parser_fn_ptr_with_generics = function pointer types may not have generic parameters - .suggestion = consider moving the lifetime {$arity -> - [one] parameter - *[other] parameters - } to {$for_param_list_exists -> - [true] the - *[false] a - } `for` parameter list - -parser_invalid_identifier_with_leading_number = expected identifier, found number literal - .label = identifiers cannot start with a number diff --git a/compiler/rustc_error_messages/locales/en-US/resolve.ftl b/compiler/rustc_error_messages/locales/en-US/resolve.ftl new file mode 100644 index 00000000000..817bb83ed78 --- /dev/null +++ b/compiler/rustc_error_messages/locales/en-US/resolve.ftl @@ -0,0 +1,211 @@ +resolve_parent_module_reset_for_binding = + parent module is reset for binding + +resolve_ampersand_used_without_explicit_lifetime_name = + `&` without an explicit lifetime name cannot be used here + .note = explicit lifetime name needed here + +resolve_underscore_lifetime_name_cannot_be_used_here = + `'_` cannot be used here + .note = `'_` is a reserved lifetime name + +resolve_crate_may_not_be_imported = + `$crate` may not be imported + +resolve_crate_root_imports_must_be_named_explicitly = + crate root imports need to be explicitly named: `use crate as name;` + +resolve_generic_params_from_outer_function = + can't use generic parameters from outer function + .label = use of generic parameter from outer function + .suggestion = try using a local generic parameter instead + +resolve_self_type_implicitly_declared_by_impl = + `Self` type implicitly declared here, by this `impl` + +resolve_cannot_use_self_type_here = + can't use `Self` here + +resolve_use_a_type_here_instead = + use a type here instead + +resolve_type_param_from_outer_fn = + type parameter from outer function + +resolve_const_param_from_outer_fn = + const parameter from outer function + +resolve_try_using_local_generic_parameter = + try using a local generic parameter instead + +resolve_try_adding_local_generic_param_on_method = + try adding a local generic parameter in this method instead + +resolve_help_try_using_local_generic_param = + try using a local generic paramter instead + +resolve_name_is_already_used_as_generic_parameter = + the name `{$name}` is already used for a generic parameter in this item's generic parameters + .label = already used + .first_use_of_name = first use of `{$name}` + +resolve_method_not_member_of_trait = + method `{$method}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_fn_with_similar_name_exists = + there is an associated function with a similar name + +resolve_type_not_member_of_trait = + type `{$type_}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_type_with_similar_name_exists = + there is an associated type with a similar name + +resolve_const_not_member_of_trait = + const `{$const_}` is not a member of trait `{$trait_}` + .label = not a member of trait `{$trait_}` + +resolve_associated_const_with_similar_name_exists = + there is an associated constant with a similar name + +resolve_variable_bound_with_different_mode = + variable `{$variable_name}` is bound inconsistently across alternatives separated by `|` + .label = bound in different ways + .first_binding_span = first binding + +resolve_ident_bound_more_than_once_in_parameter_list = + identifier `{$identifier}` is bound more than once in this parameter list + .label = used as parameter more than once + +resolve_ident_bound_more_than_once_in_same_pattern = + identifier `{$identifier}` is bound more than once in the same pattern + .label = used in a pattern more than once + +resolve_undeclared_label = + use of undeclared label `{$name}` + .label = undeclared label `{$name}` + +resolve_label_with_similar_name_reachable = + a label with a similar name is reachable + +resolve_try_using_similarly_named_label = + try using similarly named label + +resolve_unreachable_label_with_similar_name_exists = + a label with a similar name exists but is unreachable + +resolve_self_import_can_only_appear_once_in_the_list = + `self` import can only appear once in an import list + .label = can only appear once in an import list + +resolve_self_import_only_in_import_list_with_non_empty_prefix = + `self` import can only appear in an import list with a non-empty prefix + .label = can only appear in an import list with a non-empty prefix + +resolve_cannot_capture_dynamic_environment_in_fn_item = + can't capture dynamic environment in a fn item + .help = use the `|| {"{"} ... {"}"}` closure form instead + +resolve_attempt_to_use_non_constant_value_in_constant = + attempt to use a non-constant value in a constant + +resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion = + consider using `{$suggestion}` instead of `{$current}` + +resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion = + non-constant value + +resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion = + this would need to be a `{$suggestion}` + +resolve_self_imports_only_allowed_within = + `self` imports are only allowed within a {"{"} {"}"} list + +resolve_self_imports_only_allowed_within_suggestion = + consider importing the module directly + +resolve_self_imports_only_allowed_within_multipart_suggestion = + alternatively, use the multi-path `use` syntax to import `self` + +resolve_binding_shadows_something_unacceptable = + {$shadowing_binding}s cannot shadow {$shadowed_binding}s + .label = cannot be named the same as {$article} {$shadowed_binding} + .label_shadowed_binding = the {$shadowed_binding} `{$name}` is {$participle} here + +resolve_binding_shadows_something_unacceptable_suggestion = + try specify the pattern arguments + +resolve_forward_declared_generic_param = + generic parameters with a default cannot use forward declared identifiers + .label = defaulted generic parameters cannot be forward declared + +resolve_param_in_ty_of_const_param = + the type of const parameters must not depend on other generic parameters + .label = the type must not depend on the parameter `{$name}` + +resolve_self_in_generic_param_default = + generic parameters cannot use `Self` in their defaults + .label = `Self` in generic parameter default + +resolve_param_in_non_trivial_anon_const = + generic parameters may not be used in const operations + .label = cannot perform const operation using `{$name}` + +resolve_param_in_non_trivial_anon_const_help = + use `#![feature(generic_const_exprs)]` to allow generic const expressions + +resolve_param_in_non_trivial_anon_const_sub_type = + type parameters may not be used in const expressions + +resolve_param_in_non_trivial_anon_const_sub_non_type = + const parameters may only be used as standalone arguments, i.e. `{$name}` + +resolve_unreachable_label = + use of unreachable label `{$name}` + .label = unreachable label `{$name}` + .label_definition_span = unreachable label defined here + .note = labels are unreachable through functions, closures, async blocks and modules + +resolve_unreachable_label_suggestion_use_similarly_named = + try using similarly named label + +resolve_unreachable_label_similar_name_reachable = + a label with a similar name is reachable + +resolve_unreachable_label_similar_name_unreachable = + a label with a similar name exists but is also unreachable + +resolve_trait_impl_mismatch = + item `{$name}` is an associated {$kind}, which doesn't match its trait `{$trait_path}` + .label = does not match trait + .label_trait_item = item in trait + +resolve_invalid_asm_sym = + invalid `sym` operand + .label = is a local variable + .help = `sym` operands must refer to either a function or a static + +resolve_trait_impl_duplicate = + duplicate definitions with name `{$name}`: + .label = duplicate definition + .old_span_label = previous definition here + .trait_item_span = item in trait + +resolve_relative_2018 = + relative paths are not supported in visibilities in 2018 edition or later + .suggestion = try + +resolve_ancestor_only = + visibilities can only be restricted to ancestor modules + +resolve_expected_found = + expected module, found {$res} `{$path_str}` + .label = not a module + +resolve_indeterminate = + cannot determine resolution for the visibility + +resolve_module_only = + visibility must resolve to a module diff --git a/compiler/rustc_error_messages/locales/en-US/session.ftl b/compiler/rustc_error_messages/locales/en-US/session.ftl index e2277923072..983eb926213 100644 --- a/compiler/rustc_error_messages/locales/en-US/session.ftl +++ b/compiler/rustc_error_messages/locales/en-US/session.ftl @@ -58,3 +58,31 @@ session_expr_parentheses_needed = parentheses are required to parse this as an e session_skipping_const_checks = skipping const checks session_unleashed_feature_help_named = skipping check for `{$gate}` feature session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate + +session_hexadecimal_float_literal_not_supported = hexadecimal float literal is not supported +session_octal_float_literal_not_supported = octal float literal is not supported +session_binary_float_literal_not_supported = binary float literal is not supported +session_not_supported = not supported + +session_invalid_literal_suffix = suffixes on {$kind} literals are invalid + .label = invalid suffix `{$suffix}` + +session_invalid_num_literal_base_prefix = invalid base prefix for number literal + .note = base prefixes (`0xff`, `0b1010`, `0o755`) are lowercase + .suggestion = try making the prefix lowercase + +session_invalid_num_literal_suffix = invalid suffix `{$suffix}` for number literal + .label = invalid suffix `{$suffix}` + .help = the suffix must be one of the numeric types (`u32`, `isize`, `f32`, etc.) + +session_invalid_float_literal_width = invalid width `{$width}` for float literal + .help = valid widths are 32 and 64 + +session_invalid_float_literal_suffix = invalid suffix `{$suffix}` for float literal + .label = invalid suffix `{$suffix}` + .help = valid suffixes are `f32` and `f64` + +session_int_literal_too_large = integer literal is too large + +session_invalid_int_literal_width = invalid width `{$width}` for integer literal + .help = valid widths are 8, 16, 32, 64 and 128 diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 0b1b75471a6..418ba3c74d7 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -10,6 +10,7 @@ extern crate tracing; use fluent_bundle::FluentResource; use fluent_syntax::parser::ParserError; +use icu_provider_adapters::fallback::{LocaleFallbackProvider, LocaleFallbacker}; use rustc_data_structures::sync::Lrc; use rustc_macros::{fluent_messages, Decodable, Encodable}; use rustc_span::Span; @@ -30,8 +31,7 @@ use intl_memoizer::concurrent::IntlLangMemoizer; #[cfg(not(parallel_compiler))] use intl_memoizer::IntlLangMemoizer; -pub use fluent_bundle::{self, FluentArgs, FluentError, FluentValue}; - +pub use fluent_bundle::{self, types::FluentType, FluentArgs, FluentError, FluentValue}; pub use unic_langid::{langid, LanguageIdentifier}; // Generates `DEFAULT_LOCALE_RESOURCES` static and `fluent_generated` module. @@ -51,6 +51,7 @@ fluent_messages! { errors => "../locales/en-US/errors.ftl", expand => "../locales/en-US/expand.ftl", hir_analysis => "../locales/en-US/hir_analysis.ftl", + hir_typeck => "../locales/en-US/hir_typeck.ftl", infer => "../locales/en-US/infer.ftl", interface => "../locales/en-US/interface.ftl", lint => "../locales/en-US/lint.ftl", @@ -58,11 +59,12 @@ fluent_messages! { middle => "../locales/en-US/middle.ftl", mir_dataflow => "../locales/en-US/mir_dataflow.ftl", monomorphize => "../locales/en-US/monomorphize.ftl", - parser => "../locales/en-US/parser.ftl", + parse => "../locales/en-US/parse.ftl", passes => "../locales/en-US/passes.ftl", plugin_impl => "../locales/en-US/plugin_impl.ftl", privacy => "../locales/en-US/privacy.ftl", query_system => "../locales/en-US/query_system.ftl", + resolve => "../locales/en-US/resolve.ftl", save_analysis => "../locales/en-US/save_analysis.ftl", session => "../locales/en-US/session.ftl", symbol_mangling => "../locales/en-US/symbol_mangling.ftl", @@ -541,3 +543,92 @@ impl From<Vec<Span>> for MultiSpan { MultiSpan::from_spans(spans) } } + +fn icu_locale_from_unic_langid(lang: LanguageIdentifier) -> Option<icu_locid::Locale> { + icu_locid::Locale::try_from_bytes(lang.to_string().as_bytes()).ok() +} + +pub fn fluent_value_from_str_list_sep_by_and<'source>( + l: Vec<Cow<'source, str>>, +) -> FluentValue<'source> { + // Fluent requires 'static value here for its AnyEq usages. + #[derive(Clone, PartialEq, Debug)] + struct FluentStrListSepByAnd(Vec<String>); + + impl FluentType for FluentStrListSepByAnd { + fn duplicate(&self) -> Box<dyn FluentType + Send> { + Box::new(self.clone()) + } + + fn as_string(&self, intls: &intl_memoizer::IntlLangMemoizer) -> Cow<'static, str> { + let result = intls + .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| { + list_formatter.format_to_string(self.0.iter()) + }) + .unwrap(); + Cow::Owned(result) + } + + #[cfg(not(parallel_compiler))] + fn as_string_threadsafe( + &self, + _intls: &intl_memoizer::concurrent::IntlLangMemoizer, + ) -> Cow<'static, str> { + unreachable!("`as_string_threadsafe` is not used in non-parallel rustc") + } + + #[cfg(parallel_compiler)] + fn as_string_threadsafe( + &self, + intls: &intl_memoizer::concurrent::IntlLangMemoizer, + ) -> Cow<'static, str> { + let result = intls + .with_try_get::<MemoizableListFormatter, _, _>((), |list_formatter| { + list_formatter.format_to_string(self.0.iter()) + }) + .unwrap(); + Cow::Owned(result) + } + } + + struct MemoizableListFormatter(icu_list::ListFormatter); + + impl std::ops::Deref for MemoizableListFormatter { + type Target = icu_list::ListFormatter; + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl intl_memoizer::Memoizable for MemoizableListFormatter { + type Args = (); + type Error = (); + + fn construct(lang: LanguageIdentifier, _args: Self::Args) -> Result<Self, Self::Error> + where + Self: Sized, + { + let baked_data_provider = rustc_baked_icu_data::baked_data_provider(); + let locale_fallbacker = + LocaleFallbacker::try_new_with_any_provider(&baked_data_provider) + .expect("Failed to create fallback provider"); + let data_provider = + LocaleFallbackProvider::new_with_fallbacker(baked_data_provider, locale_fallbacker); + let locale = icu_locale_from_unic_langid(lang) + .unwrap_or_else(|| rustc_baked_icu_data::supported_locales::EN); + let list_formatter = + icu_list::ListFormatter::try_new_and_with_length_with_any_provider( + &data_provider, + &locale.into(), + icu_list::ListLength::Wide, + ) + .expect("Failed to create list formatter"); + + Ok(MemoizableListFormatter(list_formatter)) + } + } + + let l = l.into_iter().map(|x| x.into_owned()).collect(); + + FluentValue::Custom(Box::new(FluentStrListSepByAnd(l))) +} diff --git a/compiler/rustc_errors/Cargo.toml b/compiler/rustc_errors/Cargo.toml index 7803a0792e1..dee7a31ec20 100644 --- a/compiler/rustc_errors/Cargo.toml +++ b/compiler/rustc_errors/Cargo.toml @@ -18,7 +18,6 @@ rustc_target = { path = "../rustc_target" } rustc_hir = { path = "../rustc_hir" } rustc_lint_defs = { path = "../rustc_lint_defs" } unicode-width = "0.1.4" -atty = "0.2" termcolor = "1.0" annotate-snippets = "0.9" termize = "0.1.1" @@ -27,3 +26,6 @@ serde_json = "1.0.59" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = [ "handleapi", "synchapi", "winbase" ] } + +[features] +rustc_use_parallel_compiler = ['rustc_error_messages/rustc_use_parallel_compiler'] diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 66c986977ec..7d5e4723a6d 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -4,6 +4,7 @@ use crate::{ SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle, }; use rustc_data_structures::fx::FxHashMap; +use rustc_error_messages::fluent_value_from_str_list_sep_by_and; use rustc_error_messages::FluentValue; use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_span::edition::LATEST_STABLE_EDITION; @@ -34,6 +35,7 @@ pub type DiagnosticArgName<'source> = Cow<'source, str>; pub enum DiagnosticArgValue<'source> { Str(Cow<'source, str>), Number(usize), + StrListSepByAnd(Vec<Cow<'source, str>>), } /// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic` @@ -49,6 +51,9 @@ impl<'source> IntoDiagnosticArg for DiagnosticArgValue<'source> { match self { DiagnosticArgValue::Str(s) => DiagnosticArgValue::Str(Cow::Owned(s.into_owned())), DiagnosticArgValue::Number(n) => DiagnosticArgValue::Number(n), + DiagnosticArgValue::StrListSepByAnd(l) => DiagnosticArgValue::StrListSepByAnd( + l.into_iter().map(|s| Cow::Owned(s.into_owned())).collect(), + ), } } } @@ -58,6 +63,7 @@ impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> { match self { DiagnosticArgValue::Str(s) => From::from(s), DiagnosticArgValue::Number(n) => From::from(n), + DiagnosticArgValue::StrListSepByAnd(l) => fluent_value_from_str_list_sep_by_and(l), } } } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index c6035705e39..7155db32e53 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -11,7 +11,6 @@ use rustc_target::abi::TargetDataLayoutErrors; use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; use std::borrow::Cow; use std::fmt; -use std::fmt::Write; use std::num::ParseIntError; use std::path::{Path, PathBuf}; use std::process::ExitStatus; @@ -191,23 +190,15 @@ impl From<Vec<Symbol>> for DiagnosticSymbolList { impl IntoDiagnosticArg for DiagnosticSymbolList { fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { - // FIXME: replace the logic here with a real list formatter - let symbols = match &self.0[..] { - [symbol] => format!("`{symbol}`"), - [symbol, last] => { - format!("`{symbol}` and `{last}`",) - } - [symbols @ .., last] => { - let mut result = String::new(); - for symbol in symbols { - write!(result, "`{symbol}`, ").unwrap(); - } - write!(result, "and `{last}`").unwrap(); - result - } - [] => unreachable!(), - }; - DiagnosticArgValue::Str(Cow::Owned(symbols)) + DiagnosticArgValue::StrListSepByAnd( + self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), + ) + } +} + +impl<Id> IntoDiagnosticArg for hir::def::Res<Id> { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Borrowed(self.descr())) } } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 55c7997a513..bc136aea44d 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -28,8 +28,8 @@ use rustc_error_messages::FluentArgs; use rustc_span::hygiene::{ExpnKind, MacroKind}; use std::borrow::Cow; use std::cmp::{max, min, Reverse}; -use std::io; use std::io::prelude::*; +use std::io::{self, IsTerminal}; use std::iter; use std::path::Path; use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream}; @@ -619,14 +619,14 @@ impl ColorConfig { fn to_color_choice(self) -> ColorChoice { match self { ColorConfig::Always => { - if atty::is(atty::Stream::Stderr) { + if io::stderr().is_terminal() { ColorChoice::Always } else { ColorChoice::AlwaysAnsi } } ColorConfig::Never => ColorChoice::Never, - ColorConfig::Auto if atty::is(atty::Stream::Stderr) => ColorChoice::Auto, + ColorConfig::Auto if io::stderr().is_terminal() => ColorChoice::Auto, ColorConfig::Auto => ColorChoice::Never, } } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 170d4341ae7..f8747386c04 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -5,6 +5,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(drain_filter)] #![feature(if_let_guard)] +#![feature(is_terminal)] #![feature(adt_const_params)] #![feature(let_chains)] #![feature(never_type)] @@ -466,6 +467,9 @@ pub enum StashKey { /// When an invalid lifetime e.g. `'2` should be reinterpreted /// as a char literal in the parser LifetimeIsChar, + /// Maybe there was a typo where a comma was forgotten before + /// FRU syntax + MaybeFruTypo, } fn default_track_diagnostic(_: &Diagnostic) {} @@ -644,13 +648,14 @@ impl Handler { inner.stashed_diagnostics = Default::default(); } - /// Stash a given diagnostic with the given `Span` and `StashKey` as the key for later stealing. + /// Stash a given diagnostic with the given `Span` and [`StashKey`] as the key. + /// Retrieve a stashed diagnostic with `steal_diagnostic`. pub fn stash_diagnostic(&self, span: Span, key: StashKey, diag: Diagnostic) { let mut inner = self.inner.borrow_mut(); inner.stash((span, key), diag); } - /// Steal a previously stashed diagnostic with the given `Span` and `StashKey` as the key. + /// Steal a previously stashed diagnostic with the given `Span` and [`StashKey`] as the key. pub fn steal_diagnostic(&self, span: Span, key: StashKey) -> Option<DiagnosticBuilder<'_, ()>> { let mut inner = self.inner.borrow_mut(); inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) diff --git a/compiler/rustc_expand/Cargo.toml b/compiler/rustc_expand/Cargo.toml index 4ee7b6c42bb..192f54171ce 100644 --- a/compiler/rustc_expand/Cargo.toml +++ b/compiler/rustc_expand/Cargo.toml @@ -8,20 +8,21 @@ build = false doctest = false [dependencies] -rustc_serialize = { path = "../rustc_serialize" } -tracing = "0.1" -rustc_span = { path = "../rustc_span" } -rustc_ast_pretty = { path = "../rustc_ast_pretty" } +crossbeam-channel = "0.5.0" rustc_ast_passes = { path = "../rustc_ast_passes" } +rustc_ast = { path = "../rustc_ast" } +rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } +rustc_lexer = { path = "../rustc_lexer" } rustc_lint_defs = { path = "../rustc_lint_defs" } rustc_macros = { path = "../rustc_macros" } -rustc_lexer = { path = "../rustc_lexer" } rustc_parse = { path = "../rustc_parse" } +rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } +rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } -rustc_ast = { path = "../rustc_ast" } -crossbeam-channel = "0.5.0" +thin-vec = "0.2.8" +tracing = "0.1" diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 95fff929d46..bdcd5334949 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -507,7 +507,7 @@ impl MacResult for MacEager { return Some(p); } if let Some(e) = self.expr { - if let ast::ExprKind::Lit(_) = e.kind { + if matches!(e.kind, ast::ExprKind::Lit(_) | ast::ExprKind::IncludedBytes(_)) { return Some(P(ast::Pat { id: ast::DUMMY_NODE_ID, span: e.span, @@ -1436,7 +1436,7 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &ParseSess) -> bool { let crate_matches = if c.starts_with("allsorts-rental") { true } else { - let mut version = c.trim_start_matches("rental-").split("."); + let mut version = c.trim_start_matches("rental-").split('.'); version.next() == Some("0") && version.next() == Some("5") && version diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 8aa72e142f8..e17cba1478a 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -1,13 +1,12 @@ use crate::base::ExtCtxt; - use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Expr, LocalKind, PatKind, UnOp}; use rustc_data_structures::sync::Lrc; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; - use rustc_span::Span; +use thin_vec::ThinVec; impl<'a> ExtCtxt<'a> { pub fn path(&self, span: Span, strs: Vec<Ident>) -> ast::Path { @@ -28,7 +27,7 @@ impl<'a> ExtCtxt<'a> { ) -> ast::Path { assert!(!idents.is_empty()); let add_root = global && !idents[0].is_path_segment_keyword(); - let mut segments = Vec::with_capacity(idents.len() + add_root as usize); + let mut segments = ThinVec::with_capacity(idents.len() + add_root as usize); if add_root { segments.push(ast::PathSegment::path_root(span)); } @@ -532,15 +531,15 @@ impl<'a> ExtCtxt<'a> { // here, but that's not entirely clear. self.expr( span, - ast::ExprKind::Closure( - ast::ClosureBinder::NotPresent, - ast::CaptureBy::Ref, - ast::Async::No, - ast::Movability::Movable, + ast::ExprKind::Closure(Box::new(ast::Closure { + binder: ast::ClosureBinder::NotPresent, + capture_clause: ast::CaptureBy::Ref, + asyncness: ast::Async::No, + movability: ast::Movability::Movable, fn_decl, body, - span, - ), + fn_decl_span: span, + })), ) } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 3d37e2c6568..c2b1b96cd64 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1,7 +1,7 @@ use crate::base::*; use crate::config::StripUnconfigured; use crate::hygiene::SyntaxContext; -use crate::mbe::macro_rules::annotate_err_with_kind; +use crate::mbe::diagnostics::annotate_err_with_kind; use crate::module::{mod_dir_path, parse_external_mod, DirOwnership, ParsedExternalMod}; use crate::placeholders::{placeholder, PlaceholderExpander}; @@ -11,9 +11,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor}; -use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrStyle, AttrVec, ExprKind, ForeignItemKind}; -use rustc_ast::{HasAttrs, HasNodeId}; -use rustc_ast::{Inline, ItemKind, MacArgs, MacStmtStyle, MetaItemKind, ModKind}; +use rustc_ast::{AssocItemKind, AstNodeWrapper, AttrArgs, AttrStyle, AttrVec, ExprKind}; +use rustc_ast::{ForeignItemKind, HasAttrs, HasNodeId}; +use rustc_ast::{Inline, ItemKind, MacStmtStyle, MetaItemKind, ModKind}; use rustc_ast::{NestedMetaItem, NodeId, PatKind, StmtKind, TyKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::map_in_place::MapInPlace; @@ -654,7 +654,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { ExpandResult::Ready(match invoc.kind { InvocationKind::Bang { mac, .. } => match ext { SyntaxExtensionKind::Bang(expander) => { - let Ok(tok_result) = expander.expand(self.cx, span, mac.args.inner_tokens()) else { + let Ok(tok_result) = expander.expand(self.cx, span, mac.args.tokens.clone()) else { return ExpandResult::Ready(fragment_kind.dummy(span)); }; self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span) @@ -662,7 +662,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { SyntaxExtensionKind::LegacyBang(expander) => { let prev = self.cx.current_expansion.prior_type_ascription; self.cx.current_expansion.prior_type_ascription = mac.prior_type_ascription; - let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens()); + let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone()); let result = if let Some(result) = fragment_kind.make_from(tok_result) { result } else { @@ -706,7 +706,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => item.to_tokens(), }; let attr_item = attr.unwrap_normal_item(); - if let MacArgs::Eq(..) = attr_item.args { + if let AttrArgs::Eq(..) = attr_item.args { self.cx.span_err(span, "key-value macro attributes are not supported"); } let inner_tokens = attr_item.args.inner_tokens(); diff --git a/compiler/rustc_expand/src/mbe.rs b/compiler/rustc_expand/src/mbe.rs index 63bafd7b046..a43b2a00188 100644 --- a/compiler/rustc_expand/src/mbe.rs +++ b/compiler/rustc_expand/src/mbe.rs @@ -3,6 +3,7 @@ //! why we call this module `mbe`. For external documentation, prefer the //! official terminology: "declarative macros". +pub(crate) mod diagnostics; pub(crate) mod macro_check; pub(crate) mod macro_parser; pub(crate) mod macro_rules; diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs new file mode 100644 index 00000000000..197f056917f --- /dev/null +++ b/compiler/rustc_expand/src/mbe/diagnostics.rs @@ -0,0 +1,257 @@ +use std::borrow::Cow; + +use crate::base::{DummyResult, ExtCtxt, MacResult}; +use crate::expand::{parse_ast_fragment, AstFragmentKind}; +use crate::mbe::{ + macro_parser::{MatcherLoc, NamedParseResult, ParseResult::*, TtParser}, + macro_rules::{try_match_macro, Tracker}, +}; +use rustc_ast::token::{self, Token}; +use rustc_ast::tokenstream::TokenStream; +use rustc_ast_pretty::pprust; +use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage}; +use rustc_parse::parser::{Parser, Recovery}; +use rustc_span::source_map::SourceMap; +use rustc_span::symbol::Ident; +use rustc_span::Span; + +use super::macro_rules::{parser_from_cx, NoopTracker}; + +pub(super) fn failed_to_match_macro<'cx>( + cx: &'cx mut ExtCtxt<'_>, + sp: Span, + def_span: Span, + name: Ident, + arg: TokenStream, + lhses: &[Vec<MatcherLoc>], +) -> Box<dyn MacResult + 'cx> { + let sess = &cx.sess.parse_sess; + + // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics. + let mut tracker = CollectTrackerAndEmitter::new(cx, sp); + + let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker); + + if try_success_result.is_ok() { + // Nonterminal parser recovery might turn failed matches into successful ones, + // but for that it must have emitted an error already + tracker.cx.sess.delay_span_bug(sp, "Macro matching returned a success on the second try"); + } + + if let Some(result) = tracker.result { + // An irrecoverable error occurred and has been emitted. + return result; + } + + let Some((token, label, remaining_matcher)) = tracker.best_failure else { + return DummyResult::any(sp); + }; + + let span = token.span.substitute_dummy(sp); + + let mut err = cx.struct_span_err(span, &parse_failure_msg(&token)); + err.span_label(span, label); + if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) { + err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro"); + } + + annotate_doc_comment(&mut err, sess.source_map(), span); + + if let Some(span) = remaining_matcher.span() { + err.span_note(span, format!("while trying to match {remaining_matcher}")); + } else { + err.note(format!("while trying to match {remaining_matcher}")); + } + + // Check whether there's a missing comma in this macro call, like `println!("{}" a);` + if let Some((arg, comma_span)) = arg.add_comma() { + for lhs in lhses { + let parser = parser_from_cx(sess, arg.clone(), Recovery::Allowed); + let mut tt_parser = TtParser::new(name); + + if let Success(_) = + tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) + { + if comma_span.is_dummy() { + err.note("you might be missing a comma"); + } else { + err.span_suggestion_short( + comma_span, + "missing comma here", + ", ", + Applicability::MachineApplicable, + ); + } + } + } + } + err.emit(); + cx.trace_macros_diag(); + DummyResult::any(sp) +} + +/// The tracker used for the slow error path that collects useful info for diagnostics. +struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> { + cx: &'a mut ExtCtxt<'cx>, + remaining_matcher: Option<&'matcher MatcherLoc>, + /// Which arm's failure should we report? (the one furthest along) + best_failure: Option<(Token, &'static str, MatcherLoc)>, + root_span: Span, + result: Option<Box<dyn MacResult + 'cx>>, +} + +impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> { + fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) { + if self.remaining_matcher.is_none() + || (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof) + { + self.remaining_matcher = Some(matcher); + } + } + + fn after_arm(&mut self, result: &NamedParseResult) { + match result { + Success(_) => { + // Nonterminal parser recovery might turn failed matches into successful ones, + // but for that it must have emitted an error already + self.cx.sess.delay_span_bug( + self.root_span, + "should not collect detailed info for successful macro match", + ); + } + Failure(token, msg) => match self.best_failure { + Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {} + _ => { + self.best_failure = Some(( + token.clone(), + msg, + self.remaining_matcher + .expect("must have collected matcher already") + .clone(), + )) + } + }, + Error(err_sp, msg) => { + let span = err_sp.substitute_dummy(self.root_span); + self.cx.struct_span_err(span, msg).emit(); + self.result = Some(DummyResult::any(span)); + } + ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)), + } + } + + fn description() -> &'static str { + "detailed" + } + + fn recovery() -> Recovery { + Recovery::Allowed + } +} + +impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> { + fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self { + Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None } + } +} + +pub(super) fn emit_frag_parse_err( + mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>, + parser: &Parser<'_>, + orig_parser: &mut Parser<'_>, + site_span: Span, + arm_span: Span, + kind: AstFragmentKind, +) { + // FIXME(davidtwco): avoid depending on the error message text + if parser.token == token::Eof + && let DiagnosticMessage::Str(message) = &e.message[0].0 + && message.ends_with(", found `<eof>`") + { + let msg = &e.message[0]; + e.message[0] = ( + DiagnosticMessage::Str(format!( + "macro expansion ends with an incomplete expression: {}", + message.replace(", found `<eof>`", ""), + )), + msg.1, + ); + if !e.span.is_dummy() { + // early end of macro arm (#52866) + e.replace_span_with(parser.token.span.shrink_to_hi()); + } + } + if e.span.is_dummy() { + // Get around lack of span in error (#30128) + e.replace_span_with(site_span); + if !parser.sess.source_map().is_imported(arm_span) { + e.span_label(arm_span, "in this macro arm"); + } + } else if parser.sess.source_map().is_imported(parser.token.span) { + e.span_label(site_span, "in this macro invocation"); + } + match kind { + // Try a statement if an expression is wanted but failed and suggest adding `;` to call. + AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) { + Err(err) => err.cancel(), + Ok(_) => { + e.note( + "the macro call doesn't expand to an expression, but it can expand to a statement", + ); + e.span_suggestion_verbose( + site_span.shrink_to_hi(), + "add `;` to interpret the expansion as a statement", + ";", + Applicability::MaybeIncorrect, + ); + } + }, + _ => annotate_err_with_kind(&mut e, kind, site_span), + }; + e.emit(); +} + +pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) { + match kind { + AstFragmentKind::Ty => { + err.span_label(span, "this macro call doesn't expand to a type"); + } + AstFragmentKind::Pat => { + err.span_label(span, "this macro call doesn't expand to a pattern"); + } + _ => {} + }; +} + +#[derive(Subdiagnostic)] +enum ExplainDocComment { + #[label(expand_explain_doc_comment_inner)] + Inner { + #[primary_span] + span: Span, + }, + #[label(expand_explain_doc_comment_outer)] + Outer { + #[primary_span] + span: Span, + }, +} + +pub(super) fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) { + if let Ok(src) = sm.span_to_snippet(span) { + if src.starts_with("///") || src.starts_with("/**") { + err.subdiagnostic(ExplainDocComment::Outer { span }); + } else if src.starts_with("//!") || src.starts_with("/*!") { + err.subdiagnostic(ExplainDocComment::Inner { span }); + } + } +} + +/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For +/// other tokens, this is "unexpected token...". +pub(super) fn parse_failure_msg(tok: &Token) -> String { + match tok.kind { + token::Eof => "unexpected end of macro invocation".to_string(), + _ => format!("no rules expected the token `{}`", pprust::token_to_string(tok),), + } +} diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index c02680b77fb..2dbb90e2190 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -2,6 +2,7 @@ use crate::base::{DummyResult, ExtCtxt, MacResult, TTMacroExpander}; use crate::base::{SyntaxExtension, SyntaxExtensionKind}; use crate::expand::{ensure_complete_parse, parse_ast_fragment, AstFragment, AstFragmentKind}; use crate::mbe; +use crate::mbe::diagnostics::{annotate_doc_comment, parse_failure_msg}; use crate::mbe::macro_check; use crate::mbe::macro_parser::{Error, ErrorReported, Failure, Success, TtParser}; use crate::mbe::macro_parser::{MatchedSeq, MatchedTokenTree, MatcherLoc}; @@ -14,9 +15,7 @@ use rustc_ast::{NodeId, DUMMY_NODE_ID}; use rustc_ast_pretty::pprust; use rustc_attr::{self as attr, TransparencyError}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; -use rustc_errors::{ - Applicability, Diagnostic, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, -}; +use rustc_errors::{Applicability, ErrorGuaranteed}; use rustc_feature::Features; use rustc_lint_defs::builtin::{ RUST_2021_INCOMPATIBLE_OR_PATTERNS, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, @@ -27,7 +26,6 @@ use rustc_session::parse::ParseSess; use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::Transparency; -use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, MacroRulesNormalizedIdent}; use rustc_span::Span; @@ -35,6 +33,7 @@ use std::borrow::Cow; use std::collections::hash_map::Entry; use std::{mem, slice}; +use super::diagnostics; use super::macro_parser::{NamedMatches, NamedParseResult}; pub(crate) struct ParserAnyMacro<'a> { @@ -51,74 +50,6 @@ pub(crate) struct ParserAnyMacro<'a> { is_local: bool, } -pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) { - match kind { - AstFragmentKind::Ty => { - err.span_label(span, "this macro call doesn't expand to a type"); - } - AstFragmentKind::Pat => { - err.span_label(span, "this macro call doesn't expand to a pattern"); - } - _ => {} - }; -} - -fn emit_frag_parse_err( - mut e: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed>, - parser: &Parser<'_>, - orig_parser: &mut Parser<'_>, - site_span: Span, - arm_span: Span, - kind: AstFragmentKind, -) { - // FIXME(davidtwco): avoid depending on the error message text - if parser.token == token::Eof - && let DiagnosticMessage::Str(message) = &e.message[0].0 - && message.ends_with(", found `<eof>`") - { - let msg = &e.message[0]; - e.message[0] = ( - DiagnosticMessage::Str(format!( - "macro expansion ends with an incomplete expression: {}", - message.replace(", found `<eof>`", ""), - )), - msg.1, - ); - if !e.span.is_dummy() { - // early end of macro arm (#52866) - e.replace_span_with(parser.token.span.shrink_to_hi()); - } - } - if e.span.is_dummy() { - // Get around lack of span in error (#30128) - e.replace_span_with(site_span); - if !parser.sess.source_map().is_imported(arm_span) { - e.span_label(arm_span, "in this macro arm"); - } - } else if parser.sess.source_map().is_imported(parser.token.span) { - e.span_label(site_span, "in this macro invocation"); - } - match kind { - // Try a statement if an expression is wanted but failed and suggest adding `;` to call. - AstFragmentKind::Expr => match parse_ast_fragment(orig_parser, AstFragmentKind::Stmts) { - Err(err) => err.cancel(), - Ok(_) => { - e.note( - "the macro call doesn't expand to an expression, but it can expand to a statement", - ); - e.span_suggestion_verbose( - site_span.shrink_to_hi(), - "add `;` to interpret the expansion as a statement", - ";", - Applicability::MaybeIncorrect, - ); - } - }, - _ => annotate_err_with_kind(&mut e, kind, site_span), - }; - e.emit(); -} - impl<'a> ParserAnyMacro<'a> { pub(crate) fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment { let ParserAnyMacro { @@ -134,7 +65,7 @@ impl<'a> ParserAnyMacro<'a> { let fragment = match parse_ast_fragment(parser, kind) { Ok(f) => f, Err(err) => { - emit_frag_parse_err(err, parser, snapshot, site_span, arm_span, kind); + diagnostics::emit_frag_parse_err(err, parser, snapshot, site_span, arm_span, kind); return kind.dummy(site_span); } }; @@ -224,7 +155,7 @@ pub(super) trait Tracker<'matcher> { } /// A noop tracker that is used in the hot path of the expansion, has zero overhead thanks to monomorphization. -struct NoopTracker; +pub(super) struct NoopTracker; impl<'matcher> Tracker<'matcher> for NoopTracker { fn before_match_loc(&mut self, _: &TtParser, _: &'matcher MatcherLoc) {} @@ -331,135 +262,10 @@ fn expand_macro<'cx>( } } - // An error occurred, try the expansion again, tracking the expansion closely for better diagnostics. - let mut tracker = CollectTrackerAndEmitter::new(cx, sp); - - let try_success_result = try_match_macro(sess, name, &arg, lhses, &mut tracker); - - if try_success_result.is_ok() { - // Nonterminal parser recovery might turn failed matches into successful ones, - // but for that it must have emitted an error already - tracker.cx.sess.delay_span_bug(sp, "Macro matching returned a success on the second try"); - } - - if let Some(result) = tracker.result { - // An irrecoverable error occurred and has been emitted. - return result; - } - - let Some((token, label, remaining_matcher)) = tracker.best_failure else { - return DummyResult::any(sp); - }; - - let span = token.span.substitute_dummy(sp); - - let mut err = cx.struct_span_err(span, &parse_failure_msg(&token)); - err.span_label(span, label); - if !def_span.is_dummy() && !cx.source_map().is_imported(def_span) { - err.span_label(cx.source_map().guess_head_span(def_span), "when calling this macro"); - } - - annotate_doc_comment(&mut err, sess.source_map(), span); - - if let Some(span) = remaining_matcher.span() { - err.span_note(span, format!("while trying to match {remaining_matcher}")); - } else { - err.note(format!("while trying to match {remaining_matcher}")); - } - - // Check whether there's a missing comma in this macro call, like `println!("{}" a);` - if let Some((arg, comma_span)) = arg.add_comma() { - for lhs in lhses { - let parser = parser_from_cx(sess, arg.clone(), Recovery::Allowed); - let mut tt_parser = TtParser::new(name); - - if let Success(_) = - tt_parser.parse_tt(&mut Cow::Borrowed(&parser), lhs, &mut NoopTracker) - { - if comma_span.is_dummy() { - err.note("you might be missing a comma"); - } else { - err.span_suggestion_short( - comma_span, - "missing comma here", - ", ", - Applicability::MachineApplicable, - ); - } - } - } - } - err.emit(); - cx.trace_macros_diag(); - DummyResult::any(sp) + diagnostics::failed_to_match_macro(cx, sp, def_span, name, arg, lhses) } -/// The tracker used for the slow error path that collects useful info for diagnostics. -struct CollectTrackerAndEmitter<'a, 'cx, 'matcher> { - cx: &'a mut ExtCtxt<'cx>, - remaining_matcher: Option<&'matcher MatcherLoc>, - /// Which arm's failure should we report? (the one furthest along) - best_failure: Option<(Token, &'static str, MatcherLoc)>, - root_span: Span, - result: Option<Box<dyn MacResult + 'cx>>, -} - -impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx, 'matcher> { - fn before_match_loc(&mut self, parser: &TtParser, matcher: &'matcher MatcherLoc) { - if self.remaining_matcher.is_none() - || (parser.has_no_remaining_items_for_step() && *matcher != MatcherLoc::Eof) - { - self.remaining_matcher = Some(matcher); - } - } - - fn after_arm(&mut self, result: &NamedParseResult) { - match result { - Success(_) => { - // Nonterminal parser recovery might turn failed matches into successful ones, - // but for that it must have emitted an error already - self.cx.sess.delay_span_bug( - self.root_span, - "should not collect detailed info for successful macro match", - ); - } - Failure(token, msg) => match self.best_failure { - Some((ref best_token, _, _)) if best_token.span.lo() >= token.span.lo() => {} - _ => { - self.best_failure = Some(( - token.clone(), - msg, - self.remaining_matcher - .expect("must have collected matcher already") - .clone(), - )) - } - }, - Error(err_sp, msg) => { - let span = err_sp.substitute_dummy(self.root_span); - self.cx.struct_span_err(span, msg).emit(); - self.result = Some(DummyResult::any(span)); - } - ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)), - } - } - - fn description() -> &'static str { - "detailed" - } - - fn recovery() -> Recovery { - Recovery::Allowed - } -} - -impl<'a, 'cx> CollectTrackerAndEmitter<'a, 'cx, '_> { - fn new(cx: &'a mut ExtCtxt<'cx>, root_span: Span) -> Self { - Self { cx, remaining_matcher: None, best_failure: None, root_span, result: None } - } -} - -enum CanRetry { +pub(super) enum CanRetry { Yes, /// We are not allowed to retry macro expansion as a fatal error has been emitted already. No(ErrorGuaranteed), @@ -469,7 +275,7 @@ enum CanRetry { /// and nothing if it failed. On failure, it's the callers job to use `track` accordingly to record all errors /// correctly. #[instrument(level = "debug", skip(sess, arg, lhses, track), fields(tracking = %T::description()))] -fn try_match_macro<'matcher, T: Tracker<'matcher>>( +pub(super) fn try_match_macro<'matcher, T: Tracker<'matcher>>( sess: &ParseSess, name: Ident, arg: &TokenStream, @@ -495,7 +301,6 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>( // hacky, but speeds up the `html5ever` benchmark significantly. (Issue // 68836 suggests a more comprehensive but more complex change to deal with // this situation.) - // FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match. let parser = parser_from_cx(sess, arg.clone(), T::recovery()); // Try each arm's matchers. let mut tt_parser = TtParser::new(name); @@ -578,7 +383,7 @@ pub fn compile_declarative_macro( // Parse the macro_rules! invocation let (macro_rules, body) = match &def.kind { - ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.inner_tokens()), + ast::ItemKind::MacroDef(def) => (def.macro_rules, def.body.tokens.clone()), _ => unreachable!(), }; @@ -770,30 +575,6 @@ pub fn compile_declarative_macro( (mk_syn_ext(expander), rule_spans) } -#[derive(Subdiagnostic)] -enum ExplainDocComment { - #[label(expand_explain_doc_comment_inner)] - Inner { - #[primary_span] - span: Span, - }, - #[label(expand_explain_doc_comment_outer)] - Outer { - #[primary_span] - span: Span, - }, -} - -fn annotate_doc_comment(err: &mut Diagnostic, sm: &SourceMap, span: Span) { - if let Ok(src) = sm.span_to_snippet(span) { - if src.starts_with("///") || src.starts_with("/**") { - err.subdiagnostic(ExplainDocComment::Outer { span }); - } else if src.starts_with("//!") || src.starts_with("/*!") { - err.subdiagnostic(ExplainDocComment::Inner { span }); - } - } -} - fn check_lhs_nt_follows(sess: &ParseSess, def: &ast::Item, lhs: &mbe::TokenTree) -> bool { // lhs is going to be like TokenTree::Delimited(...), where the // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens. @@ -1578,15 +1359,6 @@ fn quoted_tt_to_string(tt: &mbe::TokenTree) -> String { } } -fn parser_from_cx(sess: &ParseSess, tts: TokenStream, recovery: Recovery) -> Parser<'_> { +pub(super) fn parser_from_cx(sess: &ParseSess, tts: TokenStream, recovery: Recovery) -> Parser<'_> { Parser::new(sess, tts, true, rustc_parse::MACRO_ARGUMENTS).recovery(recovery) } - -/// Generates an appropriate parsing failure message. For EOF, this is "unexpected end...". For -/// other tokens, this is "unexpected token...". -fn parse_failure_msg(tok: &Token) -> String { - match tok.kind { - token::Eof => "unexpected end of macro invocation".to_string(), - _ => format!("no rules expected the token `{}`", pprust::token_to_string(tok),), - } -} diff --git a/compiler/rustc_expand/src/parse/tests.rs b/compiler/rustc_expand/src/parse/tests.rs index a3c631d3318..e49f112bf20 100644 --- a/compiler/rustc_expand/src/parse/tests.rs +++ b/compiler/rustc_expand/src/parse/tests.rs @@ -291,7 +291,7 @@ fn ttdelim_span() { .unwrap(); let tts: Vec<_> = match expr.kind { - ast::ExprKind::MacCall(ref mac) => mac.args.inner_tokens().into_trees().collect(), + ast::ExprKind::MacCall(ref mac) => mac.args.tokens.clone().into_trees().collect(), _ => panic!("not a macro"), }; diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs index faaf3b3fea5..03bb5c1dfe4 100644 --- a/compiler/rustc_expand/src/placeholders.rs +++ b/compiler/rustc_expand/src/placeholders.rs @@ -1,14 +1,12 @@ use crate::expand::{AstFragment, AstFragmentKind}; - use rustc_ast as ast; use rustc_ast::mut_visit::*; use rustc_ast::ptr::P; +use rustc_data_structures::fx::FxHashMap; use rustc_span::source_map::DUMMY_SP; use rustc_span::symbol::Ident; - use smallvec::{smallvec, SmallVec}; - -use rustc_data_structures::fx::FxHashMap; +use thin_vec::ThinVec; pub fn placeholder( kind: AstFragmentKind, @@ -17,8 +15,12 @@ pub fn placeholder( ) -> AstFragment { fn mac_placeholder() -> P<ast::MacCall> { P(ast::MacCall { - path: ast::Path { span: DUMMY_SP, segments: Vec::new(), tokens: None }, - args: P(ast::MacArgs::Empty), + path: ast::Path { span: DUMMY_SP, segments: ThinVec::new(), tokens: None }, + args: P(ast::DelimArgs { + dspan: ast::tokenstream::DelimSpan::dummy(), + delim: ast::MacDelimiter::Parenthesis, + tokens: ast::tokenstream::TokenStream::new(Vec::new()), + }), prior_type_ascription: None, }) } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 5cf2fdde392..9ca63c393c6 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -419,6 +419,8 @@ declare_features! ( (active, if_let_guard, "1.47.0", Some(51114), None), /// Allows `impl Trait` as output type in `Fn` traits in return position of functions. (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None), + /// Allows referencing `Self` and projections in impl-trait. + (active, impl_trait_projections, "CURRENT_RUSTC_VERSION", Some(103532), None), /// Allows using imported `main` function (active, imported_main, "1.53.0", Some(28937), None), /// Allows associated types in inherent impls. @@ -506,6 +508,8 @@ declare_features! ( (active, stmt_expr_attributes, "1.6.0", Some(15701), None), /// Allows lints part of the strict provenance effort. (active, strict_provenance, "1.61.0", Some(95228), None), + /// Allows string patterns to dereference values to match them. + (active, string_deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), None), /// Allows the use of `#[target_feature]` on safe functions. (active, target_feature_11, "1.45.0", Some(69098), None), /// Allows using `#[thread_local]` on `static` items. diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index 4ef4aad902c..149cf4ece37 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -28,8 +28,6 @@ pub enum CtorKind { Fn, /// Constructor constant automatically created by a unit struct/variant. Const, - /// Unusable name in value namespace created by a struct variant. - Fictive, } /// An attribute that is not a macro; e.g., `#[inline]` or `#[rustfmt::skip]`. @@ -132,13 +130,9 @@ impl DefKind { DefKind::Variant => "variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Fn) => "tuple variant", DefKind::Ctor(CtorOf::Variant, CtorKind::Const) => "unit variant", - DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive) => "struct variant", DefKind::Struct => "struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct", DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct", - DefKind::Ctor(CtorOf::Struct, CtorKind::Fictive) => { - panic!("impossible struct constructor") - } DefKind::OpaqueTy => "opaque type", DefKind::ImplTraitPlaceholder => "opaque type in trait", DefKind::TyAlias => "type alias", @@ -562,19 +556,11 @@ impl<T> PerNS<Option<T>> { } impl CtorKind { - pub fn from_ast(vdata: &ast::VariantData) -> CtorKind { - match *vdata { - ast::VariantData::Tuple(..) => CtorKind::Fn, - ast::VariantData::Unit(..) => CtorKind::Const, - ast::VariantData::Struct(..) => CtorKind::Fictive, - } - } - - pub fn from_hir(vdata: &hir::VariantData<'_>) -> CtorKind { + pub fn from_ast(vdata: &ast::VariantData) -> Option<(CtorKind, NodeId)> { match *vdata { - hir::VariantData::Tuple(..) => CtorKind::Fn, - hir::VariantData::Unit(..) => CtorKind::Const, - hir::VariantData::Struct(..) => CtorKind::Fictive, + ast::VariantData::Tuple(_, node_id) => Some((CtorKind::Fn, node_id)), + ast::VariantData::Unit(node_id) => Some((CtorKind::Const, node_id)), + ast::VariantData::Struct(..) => None, } } } diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7d8b859a6b4..473a04f33a9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2720,6 +2720,12 @@ pub enum IsAsync { NotAsync, } +impl IsAsync { + pub fn is_async(self) -> bool { + self == IsAsync::Async + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, Encodable, Decodable, HashStable_Generic)] pub enum Defaultness { Default { has_value: bool }, @@ -2907,20 +2913,29 @@ impl<'hir> VariantData<'hir> { } } - /// Return the `LocalDefId` of this variant's constructor, if it has one. - pub fn ctor_def_id(&self) -> Option<LocalDefId> { + pub fn ctor(&self) -> Option<(CtorKind, HirId, LocalDefId)> { match *self { - VariantData::Struct(_, _) => None, - VariantData::Tuple(_, _, def_id) | VariantData::Unit(_, def_id) => Some(def_id), + VariantData::Tuple(_, hir_id, def_id) => Some((CtorKind::Fn, hir_id, def_id)), + VariantData::Unit(hir_id, def_id) => Some((CtorKind::Const, hir_id, def_id)), + VariantData::Struct(..) => None, } } + #[inline] + pub fn ctor_kind(&self) -> Option<CtorKind> { + self.ctor().map(|(kind, ..)| kind) + } + /// Return the `HirId` of this variant's constructor, if it has one. + #[inline] pub fn ctor_hir_id(&self) -> Option<HirId> { - match *self { - VariantData::Struct(_, _) => None, - VariantData::Tuple(_, hir_id, _) | VariantData::Unit(hir_id, _) => Some(hir_id), - } + self.ctor().map(|(_, hir_id, _)| hir_id) + } + + /// Return the `LocalDefId` of this variant's constructor, if it has one. + #[inline] + pub fn ctor_def_id(&self) -> Option<LocalDefId> { + self.ctor().map(|(.., def_id)| def_id) } } @@ -3579,9 +3594,16 @@ mod size_asserts { static_assert_size!(Res, 12); static_assert_size!(Stmt<'_>, 32); static_assert_size!(StmtKind<'_>, 16); + // tidy-alphabetical-end + // FIXME: move the tidy directive to the end after the next bootstrap bump + #[cfg(bootstrap)] static_assert_size!(TraitItem<'_>, 88); + #[cfg(not(bootstrap))] + static_assert_size!(TraitItem<'_>, 80); + #[cfg(bootstrap)] static_assert_size!(TraitItemKind<'_>, 48); + #[cfg(not(bootstrap))] + static_assert_size!(TraitItemKind<'_>, 40); static_assert_size!(Ty<'_>, 48); static_assert_size!(TyKind<'_>, 32); - // tidy-alphabetical-end } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index a55224d1097..b68dd25996b 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -95,6 +95,14 @@ macro_rules! language_item_table { } } + /// Returns the name of the `LangItem` enum variant. + // This method is used by Clippy for internal lints. + pub fn variant_name(self) -> &'static str { + match self { + $( LangItem::$variant => stringify!($variant), )* + } + } + pub fn target(self) -> Target { match self { $( LangItem::$variant => $target, )* @@ -270,6 +278,8 @@ language_item_table! { TryTraitBranch, sym::branch, branch_fn, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; TryTraitFromYeet, sym::from_yeet, from_yeet_fn, Target::Fn, GenericRequirement::None; + PointerSized, sym::pointer_sized, pointer_sized, Target::Trait, GenericRequirement::Exact(0); + PollReady, sym::Ready, poll_ready_variant, Target::Variant, GenericRequirement::None; PollPending, sym::Pending, poll_pending_variant, Target::Variant, GenericRequirement::None; @@ -302,6 +312,8 @@ language_item_table! { Range, sym::Range, range_struct, Target::Struct, GenericRequirement::None; RangeToInclusive, sym::RangeToInclusive, range_to_inclusive_struct, Target::Struct, GenericRequirement::None; RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; + + String, sym::String, string, Target::Struct, GenericRequirement::None; } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 16c40cf1299..e744ed2dcc5 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -115,7 +115,7 @@ pub trait AstConv<'tcx> { /// (e.g., resolve) that is translated into a ty-error. This is /// used to help suppress derived errors typeck might otherwise /// report. - fn set_tainted_by_errors(&self); + fn set_tainted_by_errors(&self, e: ErrorGuaranteed); fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span); } @@ -2620,8 +2620,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } } Res::Err => { - self.set_tainted_by_errors(); - self.tcx().ty_error() + let e = self + .tcx() + .sess + .delay_span_bug(path.span, "path with `Res:Err` but no error emitted"); + self.set_tainted_by_errors(e); + self.tcx().ty_error_with_guaranteed(e) } _ => span_bug!(span, "unexpected resolution: {:?}", path.res), } @@ -2773,35 +2777,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let substs = InternalSubsts::for_item(tcx, def_id, |param, _| { if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) { // Our own parameters are the resolved lifetimes. - if let GenericParamDefKind::Lifetime = param.kind { - if let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] { - self.ast_region_to_region(lifetime, None).into() - } else { - bug!() - } - } else { - bug!() - } + let GenericParamDefKind::Lifetime { .. } = param.kind else { bug!() }; + let hir::GenericArg::Lifetime(lifetime) = &lifetimes[i] else { bug!() }; + self.ast_region_to_region(lifetime, None).into() } else { - match param.kind { - // For RPIT (return position impl trait), only lifetimes - // mentioned in the impl Trait predicate are captured by - // the opaque type, so the lifetime parameters from the - // parent item need to be replaced with `'static`. - // - // For `impl Trait` in the types of statics, constants, - // locals and type aliases. These capture all parent - // lifetimes, so they can use their identity subst. - GenericParamDefKind::Lifetime - if matches!( - origin, - hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) - ) => - { - tcx.lifetimes.re_static.into() - } - _ => tcx.mk_param_from_def(param), - } + tcx.mk_param_from_def(param) } }); debug!("impl_trait_ty_to_ty: substs={:?}", substs); @@ -2978,6 +2958,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { Some(tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), ty)) } + #[instrument(level = "trace", skip(self, generate_err))] fn validate_late_bound_regions( &self, constrained_regions: FxHashSet<ty::BoundRegionKind>, @@ -3019,7 +3000,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn compute_object_lifetime_bound( &self, span: Span, - existential_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Option<ty::Region<'tcx>> // if None, use the default { let tcx = self.tcx(); diff --git a/compiler/rustc_hir_analysis/src/bounds.rs b/compiler/rustc_hir_analysis/src/bounds.rs index 6a28bb16a20..3e3544ce666 100644 --- a/compiler/rustc_hir_analysis/src/bounds.rs +++ b/compiler/rustc_hir_analysis/src/bounds.rs @@ -60,13 +60,10 @@ impl<'tcx> Bounds<'tcx> { { // If it could be sized, and is, add the `Sized` predicate. let sized_predicate = self.implicitly_sized.and_then(|span| { - tcx.lang_items().sized_trait().map(move |sized| { - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id: sized, - substs: tcx.mk_substs_trait(param_ty, &[]), - }); - (trait_ref.without_const().to_predicate(tcx), span) - }) + // FIXME: use tcx.at(span).mk_trait_ref(LangItem::Sized) here? This may make no-core code harder to write. + let sized = tcx.lang_items().sized_trait()?; + let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(sized, [param_ty])); + Some((trait_ref.without_const().to_predicate(tcx), span)) }); let region_preds = self.region_bounds.iter().map(move |&(region_bound, span)| { diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index 0ba5e615101..069b405423c 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -10,6 +10,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::{ItemKind, Node, PathSegment}; +use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor; use rustc_infer::infer::outlives::env::OutlivesEnvironment; use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt}; use rustc_infer::traits::Obligation; @@ -19,9 +20,7 @@ use rustc_middle::middle::stability::EvalResult; use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{ - self, ParamEnv, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, -}; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable}; use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; @@ -231,7 +230,9 @@ fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) { let substs = InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id()); let span = tcx.def_span(item.owner_id.def_id); - check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span); + if !tcx.features().impl_trait_projections { + check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span); + } if tcx.type_of(item.owner_id.def_id).references_error() { return; } @@ -240,6 +241,7 @@ fn check_opaque<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) { } check_opaque_meets_bounds(tcx, item.owner_id.def_id, substs, span, &origin); } + /// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result /// in "inheriting lifetimes". #[instrument(level = "debug", skip(tcx, span))] @@ -251,39 +253,11 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( let item = tcx.hir().expect_item(def_id); debug!(?item, ?span); - struct FoundParentLifetime; - struct FindParentLifetimeVisitor<'tcx>(&'tcx ty::Generics); - impl<'tcx> ty::visit::TypeVisitor<'tcx> for FindParentLifetimeVisitor<'tcx> { - type BreakTy = FoundParentLifetime; - - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - debug!("FindParentLifetimeVisitor: r={:?}", r); - if let ty::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = *r { - if index < self.0.parent_count as u32 { - return ControlFlow::Break(FoundParentLifetime); - } else { - return ControlFlow::CONTINUE; - } - } - - r.super_visit_with(self) - } - - fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { - if let ty::ConstKind::Unevaluated(..) = c.kind() { - // FIXME(#72219) We currently don't detect lifetimes within substs - // which would violate this check. Even though the particular substitution is not used - // within the const, this should still be fixed. - return ControlFlow::CONTINUE; - } - c.super_visit_with(self) - } - } - struct ProhibitOpaqueVisitor<'tcx> { tcx: TyCtxt<'tcx>, opaque_identity_ty: Ty<'tcx>, - generics: &'tcx ty::Generics, + parent_count: u32, + references_parent_regions: bool, selftys: Vec<(Span, Option<String>)>, } @@ -291,12 +265,25 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> { - debug!("check_opaque_for_inheriting_lifetimes: (visit_ty) t={:?}", t); + debug!(?t, "root_visit_ty"); if t == self.opaque_identity_ty { ControlFlow::CONTINUE } else { - t.super_visit_with(&mut FindParentLifetimeVisitor(self.generics)) - .map_break(|FoundParentLifetime| t) + t.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, + op: |region| { + if let ty::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = *region + && index < self.parent_count + { + self.references_parent_regions= true; + } + }, + }); + if self.references_parent_regions { + ControlFlow::Break(t) + } else { + ControlFlow::CONTINUE + } } } } @@ -329,15 +316,20 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( if let ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), + in_trait, .. }) = item.kind { + let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); + let opaque_identity_ty = if in_trait { + tcx.mk_projection(def_id.to_def_id(), substs) + } else { + tcx.mk_opaque(def_id.to_def_id(), substs) + }; let mut visitor = ProhibitOpaqueVisitor { - opaque_identity_ty: tcx.mk_opaque( - def_id.to_def_id(), - InternalSubsts::identity_for_item(tcx, def_id.to_def_id()), - ), - generics: tcx.generics_of(def_id), + opaque_identity_ty, + parent_count: tcx.generics_of(def_id).parent_count as u32, + references_parent_regions: false, tcx, selftys: vec![], }; @@ -345,10 +337,6 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( .explicit_item_bounds(def_id) .iter() .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor)); - debug!( - "check_opaque_for_inheriting_lifetimes: prohibit_opaque={:?}, visitor.opaque_identity_ty={:?}, visitor.generics={:?}", - prohibit_opaque, visitor.opaque_identity_ty, visitor.generics - ); if let Some(ty) = prohibit_opaque.break_value() { visitor.visit_item(&item); @@ -359,15 +347,16 @@ pub(super) fn check_opaque_for_inheriting_lifetimes<'tcx>( _ => unreachable!(), }; - let mut err = struct_span_err!( - tcx.sess, + let mut err = feature_err( + &tcx.sess.parse_sess, + sym::impl_trait_projections, span, - E0760, - "`{}` return type cannot contain a projection or `Self` that references lifetimes from \ - a parent scope", - if is_async { "async fn" } else { "impl Trait" }, + &format!( + "`{}` return type cannot contain a projection or `Self` that references \ + lifetimes from a parent scope", + if is_async { "async fn" } else { "impl Trait" }, + ), ); - for (span, name) in visitor.selftys { err.span_suggestion( span, @@ -451,8 +440,8 @@ fn check_opaque_meets_bounds<'tcx>( let misc_cause = traits::ObligationCause::misc(span, hir_id); - match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_ty) { - Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok), + match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) { + Ok(()) => {} Err(ty_err) => { tcx.sess.delay_span_bug( span, @@ -464,9 +453,8 @@ fn check_opaque_meets_bounds<'tcx>( // Additionally require the hidden type to be well-formed with only the generics of the opaque type. // Defining use functions may have more bounds than the opaque type, which is ok, as long as the // hidden type is well formed even without those bounds. - let predicate = - ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())).to_predicate(tcx); - ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate)); + let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_ty.into())); + ocx.register_obligation(Obligation::new(tcx, misc_cause, param_env, predicate)); // Check that all obligations are satisfied by the implementation's // version. @@ -1177,7 +1165,7 @@ fn check_enum<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { } if def.repr().int.is_none() { - let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind, CtorKind::Const); + let is_unit = |var: &ty::VariantDef| matches!(var.ctor_kind(), Some(CtorKind::Const)); let has_disr = |var: &ty::VariantDef| matches!(var.discr, ty::VariantDiscr::Explicit(_)); let has_non_units = def.variants().iter().any(|var| !is_unit(var)); diff --git a/compiler/rustc_hir_analysis/src/check/compare_method.rs b/compiler/rustc_hir_analysis/src/check/compare_method.rs index 7c99896b457..bf4e5126bfa 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_method.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_method.rs @@ -14,10 +14,8 @@ use rustc_infer::traits::util; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::util::ExplicitSelf; use rustc_middle::ty::{ - self, AssocItem, DefIdTree, TraitRef, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeVisitable, + self, DefIdTree, InternalSubsts, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, }; -use rustc_middle::ty::{FnSig, InternalSubsts}; use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt}; use rustc_span::Span; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt; @@ -51,11 +49,11 @@ pub(crate) fn compare_impl_method<'tcx>( return; } - if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) { + if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span, false) { return; } - if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m) { + if let Err(_) = compare_generic_param_kinds(tcx, impl_m, trait_m, false) { return; } @@ -144,9 +142,9 @@ pub(crate) fn compare_impl_method<'tcx>( #[instrument(level = "debug", skip(tcx, impl_m_span, impl_trait_ref))] fn compare_predicate_entailment<'tcx>( tcx: TyCtxt<'tcx>, - impl_m: &AssocItem, + impl_m: &ty::AssocItem, impl_m_span: Span, - trait_m: &AssocItem, + trait_m: &ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { let trait_to_impl_substs = impl_trait_ref.substs; @@ -157,8 +155,7 @@ fn compare_predicate_entailment<'tcx>( // FIXME(@lcnr): remove that after removing `cause.body_id` from // obligations. let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local()); - // We sometimes modify the span further down. - let mut cause = ObligationCause::new( + let cause = ObligationCause::new( impl_m_span, impl_m_hir_id, ObligationCauseCode::CompareImplItemObligation { @@ -238,7 +235,7 @@ fn compare_predicate_entailment<'tcx>( kind: impl_m.kind, }, ); - ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate)); + ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } // We now need to check that the signature of the impl method is @@ -291,30 +288,19 @@ fn compare_predicate_entailment<'tcx>( // type would be more appropriate. In other places we have a `Vec<Span>` // corresponding to their `Vec<Predicate>`, but we don't have that here. // Fixing this would improve the output of test `issue-83765.rs`. - let mut result = ocx.sup(&cause, param_env, trait_fty, impl_fty); - - // HACK(RPITIT): #101614. When we are trying to infer the hidden types for - // RPITITs, we need to equate the output tys instead of just subtyping. If - // we just use `sup` above, we'll end up `&'static str <: _#1t`, which causes - // us to infer `_#1t = #'_#2r str`, where `'_#2r` is unconstrained, which gets - // fixed up to `ReEmpty`, and which is certainly not what we want. - if trait_fty.has_infer_types() { - result = - result.and_then(|()| ocx.eq(&cause, param_env, trait_sig.output(), impl_sig.output())); - } + let result = ocx.sup(&cause, param_env, trait_fty, impl_fty); if let Err(terr) = result { debug!(?terr, "sub_types failed: impl ty {:?}, trait ty {:?}", impl_fty, trait_fty); let emitted = report_trait_method_mismatch( - tcx, - &mut cause, &infcx, + cause, terr, (trait_m, trait_fty), (impl_m, impl_fty), - &trait_sig, - &impl_trait_ref, + trait_sig, + impl_trait_ref, ); return Err(emitted); } @@ -352,11 +338,15 @@ pub fn collect_trait_impl_trait_tys<'tcx>( let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap(); let param_env = tcx.param_env(def_id); + // First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later. + compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id), true)?; + compare_generic_param_kinds(tcx, impl_m, trait_m, true)?; + let trait_to_impl_substs = impl_trait_ref.substs; let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local()); let return_span = tcx.hir().fn_decl_by_hir_id(impl_m_hir_id).unwrap().output.span(); - let mut cause = ObligationCause::new( + let cause = ObligationCause::new( return_span, impl_m_hir_id, ObligationCauseCode::CompareImplItemObligation { @@ -376,6 +366,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>( let infcx = &tcx.infer_ctxt().build(); let ocx = ObligationCtxt::new(infcx); + // Normalize the impl signature with fresh variables for lifetime inference. let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id); let impl_sig = ocx.normalize( norm_cause.clone(), @@ -388,6 +379,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>( ); let impl_return_ty = impl_sig.output(); + // Normalize the trait signature with liberated bound vars, passing it through + // the ImplTraitInTraitCollector, which gathers all of the RPITITs and replaces + // them with inference variables. + // We will use these inference variables to collect the hidden types of RPITITs. let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id); let unnormalized_trait_sig = tcx .liberate_late_bound_regions( @@ -402,10 +397,8 @@ pub fn collect_trait_impl_trait_tys<'tcx>( unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()), ); - match infcx.at(&cause, param_env).eq(trait_return_ty, impl_return_ty) { - Ok(infer::InferOk { value: (), obligations }) => { - ocx.register_obligations(obligations); - } + match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) { + Ok(()) => {} Err(terr) => { let mut diag = struct_span_err!( tcx.sess, @@ -442,24 +435,21 @@ pub fn collect_trait_impl_trait_tys<'tcx>( // the lifetimes of the return type, but do this after unifying just the // return types, since we want to avoid duplicating errors from // `compare_predicate_entailment`. - match infcx.at(&cause, param_env).eq(trait_fty, impl_fty) { - Ok(infer::InferOk { value: (), obligations }) => { - ocx.register_obligations(obligations); - } + match ocx.eq(&cause, param_env, trait_fty, impl_fty) { + Ok(()) => {} Err(terr) => { // This function gets called during `compare_predicate_entailment` when normalizing a // signature that contains RPITIT. When the method signatures don't match, we have to // emit an error now because `compare_predicate_entailment` will not report the error // when normalization fails. let emitted = report_trait_method_mismatch( - tcx, - &mut cause, infcx, + cause, terr, (trait_m, trait_fty), (impl_m, impl_fty), - &trait_sig, - &impl_trait_ref, + trait_sig, + impl_trait_ref, ); return Err(emitted); } @@ -521,7 +511,13 @@ pub fn collect_trait_impl_trait_tys<'tcx>( let num_trait_substs = trait_to_impl_substs.len(); let num_impl_substs = tcx.generics_of(impl_m.container_id(tcx)).params.len(); let ty = tcx.fold_regions(ty, |region, _| { - let (ty::ReFree(_) | ty::ReEarlyBound(_)) = region.kind() else { return region; }; + match region.kind() { + // Remap all free regions, which correspond to late-bound regions in the function. + ty::ReFree(_) => {} + // Remap early-bound regions as long as they don't come from the `impl` itself. + ty::ReEarlyBound(ebr) if tcx.parent(ebr.def_id) != impl_m.container_id(tcx) => {} + _ => return region, + } let Some(ty::ReEarlyBound(e)) = map.get(®ion.into()).map(|r| r.expect_region().kind()) else { tcx @@ -605,6 +601,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { ); self.ocx.register_obligation(traits::Obligation::new( + self.tcx(), ObligationCause::new( self.span, self.body_id, @@ -622,23 +619,21 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> { } fn report_trait_method_mismatch<'tcx>( - tcx: TyCtxt<'tcx>, - cause: &mut ObligationCause<'tcx>, infcx: &InferCtxt<'tcx>, + mut cause: ObligationCause<'tcx>, terr: TypeError<'tcx>, - (trait_m, trait_fty): (&AssocItem, Ty<'tcx>), - (impl_m, impl_fty): (&AssocItem, Ty<'tcx>), - trait_sig: &FnSig<'tcx>, - impl_trait_ref: &TraitRef<'tcx>, + (trait_m, trait_fty): (&ty::AssocItem, Ty<'tcx>), + (impl_m, impl_fty): (&ty::AssocItem, Ty<'tcx>), + trait_sig: ty::FnSig<'tcx>, + impl_trait_ref: ty::TraitRef<'tcx>, ) -> ErrorGuaranteed { + let tcx = infcx.tcx; let (impl_err_span, trait_err_span) = extract_spans_for_error_reporting(&infcx, terr, &cause, impl_m, trait_m); - cause.span = impl_err_span; - let mut diag = struct_span_err!( tcx.sess, - cause.span(), + impl_err_span, E0053, "method `{}` has an incompatible type for trait", trait_m.name @@ -681,9 +676,7 @@ fn report_trait_method_mismatch<'tcx>( // Suggestion to change output type. We do not suggest in `async` functions // to avoid complex logic or incorrect output. match tcx.hir().expect_impl_item(impl_m.def_id.expect_local()).kind { - ImplItemKind::Fn(ref sig, _) - if sig.header.asyncness == hir::IsAsync::NotAsync => - { + ImplItemKind::Fn(ref sig, _) if !sig.header.asyncness.is_async() => { let msg = "change the output type to match the trait"; let ap = Applicability::MachineApplicable; match sig.decl.output { @@ -711,6 +704,7 @@ fn report_trait_method_mismatch<'tcx>( _ => {} } + cause.span = impl_err_span; infcx.err_ctxt().note_type_err( &mut diag, &cause, @@ -921,9 +915,9 @@ fn compare_self_type<'tcx>( fn compare_number_of_generics<'tcx>( tcx: TyCtxt<'tcx>, impl_: &ty::AssocItem, - _impl_span: Span, trait_: &ty::AssocItem, trait_span: Option<Span>, + delay: bool, ) -> Result<(), ErrorGuaranteed> { let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts(); let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts(); @@ -1053,7 +1047,7 @@ fn compare_number_of_generics<'tcx>( err.span_label(*span, "`impl Trait` introduces an implicit type parameter"); } - let reported = err.emit(); + let reported = err.emit_unless(delay); err_occurred = Some(reported); } } @@ -1305,6 +1299,7 @@ fn compare_generic_param_kinds<'tcx>( tcx: TyCtxt<'tcx>, impl_item: &ty::AssocItem, trait_item: &ty::AssocItem, + delay: bool, ) -> Result<(), ErrorGuaranteed> { assert_eq!(impl_item.kind, trait_item.kind); @@ -1362,7 +1357,7 @@ fn compare_generic_param_kinds<'tcx>( err.span_label(impl_header_span, ""); err.span_label(param_impl_span, make_param_message("found", param_impl)); - let reported = err.emit(); + let reported = err.emit_unless(delay); return Err(reported); } } @@ -1488,9 +1483,9 @@ pub(crate) fn compare_ty_impl<'tcx>( debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref); let _: Result<(), ErrorGuaranteed> = (|| { - compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?; + compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span, false)?; - compare_generic_param_kinds(tcx, impl_ty, trait_ty)?; + compare_generic_param_kinds(tcx, impl_ty, trait_ty, false)?; let sp = tcx.def_span(impl_ty.def_id); compare_type_predicate_entailment(tcx, impl_ty, sp, trait_ty, impl_trait_ref)?; @@ -1579,7 +1574,7 @@ fn compare_type_predicate_entailment<'tcx>( }, ); ocx.register_obligations(obligations); - ocx.register_obligation(traits::Obligation::new(cause, param_env, predicate)); + ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate)); } // Check that all obligations are satisfied by the implementation's @@ -1784,7 +1779,7 @@ pub fn check_type_bounds<'tcx>( .subst_iter_copied(tcx, rebased_substs) .map(|(concrete_ty_bound, span)| { debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound); - traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound) + traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound) }) .collect(); debug!("check_type_bounds: item_bounds={:?}", obligations); diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/dropck.rs index a74016e220e..e0b465bab16 100644 --- a/compiler/rustc_hir_analysis/src/check/dropck.rs +++ b/compiler/rustc_hir_analysis/src/check/dropck.rs @@ -244,6 +244,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { self.tcx } + fn intercrate(&self) -> bool { + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -256,6 +260,10 @@ impl<'tcx> TypeRelation<'tcx> for SimpleEqRelation<'tcx> { true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index efb34e4ff65..7119f3a2386 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -14,8 +14,8 @@ use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::query::Providers; use rustc_middle::ty::trait_def::TraitSpecializationKind; use rustc_middle::ty::{ - self, AdtKind, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TyCtxt, TypeFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitor, + self, AdtKind, DefIdTree, GenericParamDefKind, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitor, }; use rustc_middle::ty::{GenericArgKind, InternalSubsts}; use rustc_session::parse::feature_err; @@ -75,9 +75,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // for a type to be WF, we do not need to check if const trait predicates satisfy. let param_env = self.param_env.without_const(); self.ocx.register_obligation(traits::Obligation::new( + self.tcx(), cause, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), )); } } @@ -1111,12 +1112,12 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b traits::MiscObligation, ); wfcx.register_obligation(traits::Obligation::new( + tcx, cause, wfcx.param_env, ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( ty::Const::from_anon_const(tcx, discr_def_id.expect_local()), - )) - .to_predicate(tcx), + )), )); } } @@ -1453,7 +1454,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id wfcx.body_id, traits::ItemObligation(def_id.to_def_id()), ); - traits::Obligation::new(cause, wfcx.param_env, pred) + traits::Obligation::new(tcx, cause, wfcx.param_env, pred) }); let predicates = predicates.0.instantiate_identity(tcx); @@ -1538,7 +1539,6 @@ fn check_fn_or_method<'tcx>( check_return_position_impl_trait_in_trait_bounds( tcx, - wfcx, def_id, sig.output(), hir_decl.output.span(), @@ -1574,9 +1574,9 @@ fn check_fn_or_method<'tcx>( /// Basically `check_associated_type_bounds`, but separated for now and should be /// deduplicated when RPITITs get lowered into real associated items. +#[tracing::instrument(level = "trace", skip(tcx))] fn check_return_position_impl_trait_in_trait_bounds<'tcx>( tcx: TyCtxt<'tcx>, - wfcx: &WfCheckingCtxt<'_, 'tcx>, fn_def_id: LocalDefId, fn_output: Ty<'tcx>, span: Span, @@ -1590,18 +1590,22 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder && tcx.impl_trait_in_trait_parent(proj.item_def_id) == fn_def_id.to_def_id() { - let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { - let normalized_bound = wfcx.normalize(span, None, bound); - traits::wf::predicate_obligations( - wfcx.infcx, - wfcx.param_env, - wfcx.body_id, - normalized_bound, - bound_span, - ) + // Create a new context, since we want the opaque's ParamEnv and not the parent's. + let span = tcx.def_span(proj.item_def_id); + enter_wf_checking_ctxt(tcx, span, proj.item_def_id.expect_local(), |wfcx| { + let bounds = wfcx.tcx().explicit_item_bounds(proj.item_def_id); + let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { + let normalized_bound = wfcx.normalize(span, None, bound); + traits::wf::predicate_obligations( + wfcx.infcx, + wfcx.param_env, + wfcx.body_id, + normalized_bound, + bound_span, + ) + }); + wfcx.register_obligations(wf_obligations); }); - wfcx.register_obligations(wf_obligations); } } } @@ -1718,7 +1722,7 @@ fn receiver_is_valid<'tcx>( // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it. autoderef.next(); - let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, None); + let receiver_trait_def_id = tcx.require_lang_item(LangItem::Receiver, Some(span)); // Keep dereferencing `receiver_ty` until we get to `self_ty`. loop { @@ -1778,13 +1782,9 @@ fn receiver_is_implemented<'tcx>( receiver_ty: Ty<'tcx>, ) -> bool { let tcx = wfcx.tcx(); - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id: receiver_trait_def_id, - substs: tcx.mk_substs_trait(receiver_ty, &[]), - }); + let trait_ref = ty::Binder::dummy(tcx.mk_trait_ref(receiver_trait_def_id, [receiver_ty])); - let obligation = - traits::Obligation::new(cause, wfcx.param_env, trait_ref.without_const().to_predicate(tcx)); + let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref.without_const()); if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) { true @@ -1931,6 +1931,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { } let obligation = traits::Obligation::new( + tcx, traits::ObligationCause::new(span, self.body_id, traits::TrivialBound), empty_env, pred, diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 6f74ef3ccad..11661215ae1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -114,7 +114,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) { traits::ObligationCause::dummy_with_span(field_ty_span), param_env, ty, - tcx.lang_items().copy_trait().unwrap(), + tcx.require_lang_item(LangItem::Copy, Some(span)), ) { let error_predicate = error.obligation.predicate; // Only note if it's not the root obligation, otherwise it's trivial and @@ -315,8 +315,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: cause.clone(), dispatch_from_dyn_trait, 0, - field.ty(tcx, substs_a), - &[field.ty(tcx, substs_b).into()], + [field.ty(tcx, substs_a), field.ty(tcx, substs_b)], ) }), ); @@ -558,7 +557,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // Register an obligation for `A: Trait<B>`. let cause = traits::ObligationCause::misc(span, impl_hir_id); let predicate = - predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, source, &[target.into()]); + predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]); let errors = traits::fully_solve_obligation(&infcx, predicate); if !errors.is_empty() { infcx.err_ctxt().report_fulfillment_errors(&errors, None); diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 71c932d747b..d66b6585fb6 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, DelayDm}; use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_hir as hir; -use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::util::IgnoreRegions; use rustc_middle::ty::{ @@ -47,58 +46,6 @@ fn do_orphan_check_impl<'tcx>( let sp = tcx.def_span(def_id); let tr = impl_.of_trait.as_ref().unwrap(); - // Ensure no opaque types are present in this impl header. See issues #76202 and #86411 for examples, - // and #84660 where it would otherwise allow unsoundness. - if trait_ref.has_opaque_types() { - trace!("{:#?}", item); - // First we find the opaque type in question. - for ty in trait_ref.substs { - for ty in ty.walk() { - let ty::subst::GenericArgKind::Type(ty) = ty.unpack() else { continue }; - let ty::Opaque(def_id, _) = *ty.kind() else { continue }; - trace!(?def_id); - - // Then we search for mentions of the opaque type's type alias in the HIR - struct SpanFinder<'tcx> { - sp: Span, - def_id: DefId, - tcx: TyCtxt<'tcx>, - } - impl<'v, 'tcx> hir::intravisit::Visitor<'v> for SpanFinder<'tcx> { - #[instrument(level = "trace", skip(self, _id))] - fn visit_path(&mut self, path: &'v hir::Path<'v>, _id: hir::HirId) { - // You can't mention an opaque type directly, so we look for type aliases - if let hir::def::Res::Def(hir::def::DefKind::TyAlias, def_id) = path.res { - // And check if that type alias's type contains the opaque type we're looking for - for arg in self.tcx.type_of(def_id).walk() { - if let GenericArgKind::Type(ty) = arg.unpack() { - if let ty::Opaque(def_id, _) = *ty.kind() { - if def_id == self.def_id { - // Finally we update the span to the mention of the type alias - self.sp = path.span; - return; - } - } - } - } - } - hir::intravisit::walk_path(self, path) - } - } - - let mut visitor = SpanFinder { sp, def_id, tcx }; - hir::intravisit::walk_item(&mut visitor, item); - let reported = tcx - .sess - .struct_span_err(visitor.sp, "cannot implement trait on type alias impl trait") - .span_note(tcx.def_span(def_id), "type alias impl trait defined here") - .emit(); - return Err(reported); - } - } - span_bug!(sp, "opaque type not found, but `has_opaque_types` is set") - } - match traits::orphan_check(tcx, item.owner_id.to_def_id()) { Ok(()) => {} Err(err) => emit_orphan_check_error( diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 2f64a88f03a..9b8cc884e18 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -24,7 +24,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey}; use rustc_hir as hir; -use rustc_hir::def::CtorKind; use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS; @@ -518,7 +517,7 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { ty } - fn set_tainted_by_errors(&self) { + fn set_tainted_by_errors(&self, _: ErrorGuaranteed) { // There's no obvious place to track this, so just let it go. } @@ -794,7 +793,7 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { // Convert the ctor, if any. This also registers the variant as // an item. - if let Some(ctor_def_id) = variant.ctor_def_id { + if let Some(ctor_def_id) = variant.ctor_def_id() { convert_variant_ctor(tcx, ctor_def_id.expect_local()); } } @@ -803,7 +802,6 @@ fn convert_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { fn convert_variant( tcx: TyCtxt<'_>, variant_did: Option<LocalDefId>, - ctor_did: Option<LocalDefId>, ident: Ident, discr: ty::VariantDiscr, def: &hir::VariantData<'_>, @@ -840,10 +838,9 @@ fn convert_variant( ty::VariantDef::new( ident.name, variant_did.map(LocalDefId::to_def_id), - ctor_did.map(LocalDefId::to_def_id), + def.ctor().map(|(kind, _, def_id)| (kind, def_id.to_def_id())), discr, fields, - CtorKind::from_hir(def), adt_kind, parent_did.to_def_id(), recovered, @@ -882,7 +879,6 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> { convert_variant( tcx, Some(v.def_id), - v.data.ctor_def_id(), v.ident, discr, &v.data, @@ -894,35 +890,23 @@ fn adt_def<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::AdtDef<'tcx> { (AdtKind::Enum, variants) } - ItemKind::Struct(ref def, _) => { - let variants = std::iter::once(convert_variant( - tcx, - None, - def.ctor_def_id(), - item.ident, - ty::VariantDiscr::Relative(0), - def, - AdtKind::Struct, - def_id, - )) - .collect(); - - (AdtKind::Struct, variants) - } - ItemKind::Union(ref def, _) => { + ItemKind::Struct(ref def, _) | ItemKind::Union(ref def, _) => { + let adt_kind = match item.kind { + ItemKind::Struct(..) => AdtKind::Struct, + _ => AdtKind::Union, + }; let variants = std::iter::once(convert_variant( tcx, None, - def.ctor_def_id(), item.ident, ty::VariantDiscr::Relative(0), def, - AdtKind::Union, + adt_kind, def_id, )) .collect(); - (AdtKind::Union, variants) + (adt_kind, variants) } _ => bug!(), }; @@ -1171,7 +1155,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { compute_sig_of_foreign_fn_decl(tcx, def_id.to_def_id(), fn_decl, abi) } - Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor_hir_id().is_some() => { + Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => { let ty = tcx.type_of(tcx.hir().get_parent_item(hir_id)); let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id)); ty::Binder::dummy(tcx.mk_fn_sig( diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index e2da580de0c..c3f1bb457f7 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -84,60 +84,30 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP Node::ImplItem(item) => item.generics, - Node::Item(item) => { - match item.kind { - ItemKind::Impl(ref impl_) => { - if impl_.defaultness.is_default() { - is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy); - } - &impl_.generics + Node::Item(item) => match item.kind { + ItemKind::Impl(ref impl_) => { + if impl_.defaultness.is_default() { + is_default_impl_trait = tcx.impl_trait_ref(def_id).map(ty::Binder::dummy); } - ItemKind::Fn(.., ref generics, _) - | ItemKind::TyAlias(_, ref generics) - | ItemKind::Enum(_, ref generics) - | ItemKind::Struct(_, ref generics) - | ItemKind::Union(_, ref generics) => *generics, - - ItemKind::Trait(_, _, ref generics, ..) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id)); - *generics - } - ItemKind::TraitAlias(ref generics, _) => { - is_trait = Some(ty::TraitRef::identity(tcx, def_id)); - *generics - } - ItemKind::OpaqueTy(OpaqueTy { - origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..), - .. - }) => { - // return-position impl trait - // - // We don't inherit predicates from the parent here: - // If we have, say `fn f<'a, T: 'a>() -> impl Sized {}` - // then the return type is `f::<'static, T>::{{opaque}}`. - // - // If we inherited the predicates of `f` then we would - // require that `T: 'static` to show that the return - // type is well-formed. - // - // The only way to have something with this opaque type - // is from the return type of the containing function, - // which will ensure that the function's predicates - // hold. - return ty::GenericPredicates { parent: None, predicates: &[] }; - } - ItemKind::OpaqueTy(OpaqueTy { - ref generics, - origin: hir::OpaqueTyOrigin::TyAlias, - .. - }) => { - // type-alias impl trait - generics - } - - _ => NO_GENERICS, + &impl_.generics } - } + ItemKind::Fn(.., ref generics, _) + | ItemKind::TyAlias(_, ref generics) + | ItemKind::Enum(_, ref generics) + | ItemKind::Struct(_, ref generics) + | ItemKind::Union(_, ref generics) => *generics, + + ItemKind::Trait(_, _, ref generics, ..) => { + is_trait = Some(ty::TraitRef::identity(tcx, def_id)); + *generics + } + ItemKind::TraitAlias(ref generics, _) => { + is_trait = Some(ty::TraitRef::identity(tcx, def_id)); + *generics + } + ItemKind::OpaqueTy(OpaqueTy { ref generics, .. }) => generics, + _ => NO_GENERICS, + }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Static(..) => NO_GENERICS, @@ -181,6 +151,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP trace!(?predicates); trace!(?ast_generics); + trace!(?generics); // Collect the predicates that were written inline by the user on each // type parameter (e.g., `<T: Foo>`). @@ -299,6 +270,54 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP ); } + // Opaque types duplicate some of their generic parameters. + // We create bi-directional Outlives predicates between the original + // and the duplicated parameter, to ensure that they do not get out of sync. + if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node { + let opaque_ty_id = tcx.hir().get_parent_node(hir_id); + let opaque_ty_node = tcx.hir().get(opaque_ty_id); + let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else { + bug!("unexpected {opaque_ty_node:?}") + }; + debug!(?lifetimes); + for (arg, duplicate) in std::iter::zip(lifetimes, ast_generics.params) { + let hir::GenericArg::Lifetime(arg) = arg else { bug!() }; + let orig_region = <dyn AstConv<'_>>::ast_region_to_region(&icx, &arg, None); + if !matches!(orig_region.kind(), ty::ReEarlyBound(..)) { + // Only early-bound regions can point to the original generic parameter. + continue; + } + + let hir::GenericParamKind::Lifetime { .. } = duplicate.kind else { continue }; + let dup_def = tcx.hir().local_def_id(duplicate.hir_id).to_def_id(); + + let Some(dup_index) = generics.param_def_id_to_index(tcx, dup_def) else { bug!() }; + + let dup_region = tcx.mk_region(ty::ReEarlyBound(ty::EarlyBoundRegion { + def_id: dup_def, + index: dup_index, + name: duplicate.name.ident().name, + })); + predicates.push(( + ty::Binder::dummy(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate( + orig_region, + dup_region, + ))) + .to_predicate(icx.tcx), + duplicate.span, + )); + predicates.push(( + ty::Binder::dummy(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate( + dup_region, + orig_region, + ))) + .to_predicate(icx.tcx), + duplicate.span, + )); + } + debug!(?predicates); + } + ty::GenericPredicates { parent: generics.parent, predicates: tcx.arena.alloc_from_iter(predicates), diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index b0fdfcf38a6..4f9d5826583 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -5,7 +5,7 @@ use rustc_hir::{ForeignItem, ForeignItemKind, HirId}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder}; +use rustc_middle::ty::{self, Region, TyCtxt, TypeFoldable, TypeFolder}; use rustc_trait_selection::traits; pub fn provide(providers: &mut Providers) { @@ -74,10 +74,10 @@ fn diagnostic_hir_wf_check<'tcx>( let errors = traits::fully_solve_obligation( &infcx, traits::Obligation::new( + self.tcx, cause, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())) - .to_predicate(self.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(tcx_ty.into())), ), ); if !errors.is_empty() { diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 55cca0cd2d7..bae43138b4d 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -517,6 +517,7 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 7534482cce9..f0381353551 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -59,6 +59,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => (), } } diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index 4359124646d..9c77387c238 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -728,7 +728,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { && let Some(trait_path_segment) = path.segments.get(0) { let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params(); - if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait { + if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self + { if let Some(span) = self.gen_args.span_ext() && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { let sugg = vec![ diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index eaf0310d57a..6ce0c18bf45 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -72,8 +72,8 @@ pub fn add_constraints_from_crate<'a, 'tcx>( let adt = tcx.adt_def(def_id); for variant in adt.variants() { - if let Some(ctor) = variant.ctor_def_id { - constraint_cx.build_constraints_for_item(ctor.expect_local()); + if let Some(ctor_def_id) = variant.ctor_def_id() { + constraint_cx.build_constraints_for_item(ctor_def_id.expect_local()); } } } diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs index 82103c5a03b..b6137f89cad 100644 --- a/compiler/rustc_hir_analysis/src/variance/mod.rs +++ b/compiler/rustc_hir_analysis/src/variance/mod.rs @@ -5,9 +5,10 @@ use rustc_arena::DroplessArena; use rustc_hir::def::DefKind; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt}; +use rustc_middle::ty::{self, CrateVariancesMap, TyCtxt, TypeSuperVisitable, TypeVisitable}; +use std::ops::ControlFlow; /// Defines the `TermsContext` basically houses an arena where we can /// allocate terms. @@ -50,6 +51,9 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { | DefKind::Union | DefKind::Variant | DefKind::Ctor(..) => {} + DefKind::OpaqueTy | DefKind::ImplTraitPlaceholder => { + return variance_of_opaque(tcx, item_def_id.expect_local()); + } _ => { // Variance not relevant. span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item") @@ -61,3 +65,89 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { let crate_map = tcx.crate_variances(()); crate_map.variances.get(&item_def_id).copied().unwrap_or(&[]) } + +#[instrument(level = "trace", skip(tcx), ret)] +fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] { + let generics = tcx.generics_of(item_def_id); + + // Opaque types may only use regions that are bound. So for + // ```rust + // type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b; + // ``` + // we may not use `'c` in the hidden type. + struct OpaqueTypeLifetimeCollector { + variances: Vec<ty::Variance>, + } + + impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector { + #[instrument(level = "trace", skip(self), ret)] + fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { + if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() { + self.variances[ebr.index as usize] = ty::Invariant; + } + r.super_visit_with(self) + } + } + + // By default, RPIT are invariant wrt type and const generics, but they are bivariant wrt + // lifetime generics. + let mut variances: Vec<_> = std::iter::repeat(ty::Invariant).take(generics.count()).collect(); + + // Mark all lifetimes from parent generics as unused (Bivariant). + // This will be overridden later if required. + { + let mut generics = generics; + while let Some(def_id) = generics.parent { + generics = tcx.generics_of(def_id); + for param in &generics.params { + match param.kind { + ty::GenericParamDefKind::Lifetime => { + variances[param.index as usize] = ty::Bivariant; + } + ty::GenericParamDefKind::Type { .. } + | ty::GenericParamDefKind::Const { .. } => {} + } + } + } + } + + let mut collector = OpaqueTypeLifetimeCollector { variances }; + let id_substs = ty::InternalSubsts::identity_for_item(tcx, item_def_id.to_def_id()); + for pred in tcx.bound_explicit_item_bounds(item_def_id.to_def_id()).transpose_iter() { + let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); + debug!(?pred); + + // We only ignore opaque type substs if the opaque type is the outermost type. + // The opaque type may be nested within itself via recursion in e.g. + // type Foo<'a> = impl PartialEq<Foo<'a>>; + // which thus mentions `'a` and should thus accept hidden types that borrow 'a + // instead of requiring an additional `+ 'a`. + match pred.kind().skip_binder() { + ty::PredicateKind::Trait(ty::TraitPredicate { + trait_ref: ty::TraitRef { def_id: _, substs }, + constness: _, + polarity: _, + }) => { + for subst in &substs[1..] { + subst.visit_with(&mut collector); + } + } + ty::PredicateKind::Projection(ty::ProjectionPredicate { + projection_ty: ty::ProjectionTy { substs, item_def_id: _ }, + term, + }) => { + for subst in &substs[1..] { + subst.visit_with(&mut collector); + } + term.visit_with(&mut collector); + } + ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_, region)) => { + region.visit_with(&mut collector); + } + _ => { + pred.visit_with(&mut collector); + } + } + } + tcx.arena.alloc_from_iter(collector.variances.into_iter()) +} diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs index 1f763011e06..58e8f474761 100644 --- a/compiler/rustc_hir_analysis/src/variance/terms.rs +++ b/compiler/rustc_hir_analysis/src/variance/terms.rs @@ -91,8 +91,8 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>( let adt = tcx.adt_def(def_id); for variant in adt.variants() { - if let Some(ctor) = variant.ctor_def_id { - terms_cx.add_inferreds_for_item(ctor.expect_local()); + if let Some(ctor_def_id) = variant.ctor_def_id() { + terms_cx.add_inferreds_for_item(ctor_def_id.expect_local()); } } } diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 6a4a6a5b0a5..31432bb6e41 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -4,7 +4,7 @@ use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_hir::{self as hir, ExprKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::traits::Obligation; -use rustc_middle::ty::{self, ToPredicate, Ty}; +use rustc_middle::ty::{self, Ty}; use rustc_span::Span; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ @@ -538,23 +538,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .bound_explicit_item_bounds(rpit_def_id) .subst_iter_copied(self.tcx, substs) { - let pred = match pred.kind().skip_binder() { - ty::PredicateKind::Trait(mut trait_pred) => { + let pred = pred.kind().rebind(match pred.kind().skip_binder() { + ty::PredicateKind::Trait(trait_pred) => { assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty); - trait_pred.trait_ref.substs = - self.tcx.mk_substs_trait(ty, &trait_pred.trait_ref.substs[1..]); - pred.kind().rebind(trait_pred).to_predicate(self.tcx) + ty::PredicateKind::Trait(trait_pred.with_self_type(self.tcx, ty)) } ty::PredicateKind::Projection(mut proj_pred) => { assert_eq!(proj_pred.projection_ty.self_ty(), opaque_ty); - proj_pred.projection_ty.substs = self - .tcx - .mk_substs_trait(ty, &proj_pred.projection_ty.substs[1..]); - pred.kind().rebind(proj_pred).to_predicate(self.tcx) + proj_pred.projection_ty.substs = self.tcx.mk_substs_trait( + ty, + proj_pred.projection_ty.substs.iter().skip(1), + ); + ty::PredicateKind::Projection(proj_pred) } _ => continue, - }; + }); if !self.predicate_must_hold_modulo_regions(&Obligation::new( + self.tcx, ObligationCause::misc(span, self.body_id), self.param_env, pred, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index ed2218b8746..42aa3bcee49 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -6,7 +6,7 @@ use crate::type_error_struct; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{struct_span_err, Applicability, Diagnostic, StashKey}; use rustc_hir as hir; -use rustc_hir::def::{self, Namespace, Res}; +use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def_id::DefId; use rustc_infer::{ infer, @@ -380,6 +380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { predicates.predicates.iter().zip(&predicates.spans) { let obligation = Obligation::new( + self.tcx, ObligationCause::dummy_with_span(callee_expr.span), self.param_env, *predicate, @@ -594,7 +595,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let mut unit_variant = None; if let hir::ExprKind::Path(qpath) = &callee_expr.kind - && let Res::Def(def::DefKind::Ctor(kind, def::CtorKind::Const), _) + && let Res::Def(def::DefKind::Ctor(kind, CtorKind::Const), _) = self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id) // Only suggest removing parens if there are no arguments && arg_exprs.is_empty() diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 7d3129f7ea7..5e1e44dcb6d 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -33,6 +33,7 @@ use super::FnCtxt; use crate::type_error_struct; use rustc_errors::{struct_span_err, Applicability, DelayDm, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; +use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::AllowTwoPhase; use rustc_middle::ty::cast::{CastKind, CastTy}; @@ -67,7 +68,7 @@ pub struct CastCheck<'tcx> { /// The kind of pointer and associated metadata (thin, length or vtable) - we /// only allow casts between fat pointers if their metadata have the same /// kind. -#[derive(Copy, Clone, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, TypeVisitable, TypeFoldable)] enum PointerKind<'tcx> { /// No metadata attached, ie pointer to sized type or foreign type Thin, @@ -76,11 +77,11 @@ enum PointerKind<'tcx> { /// Slice Length, /// The unsize info of this projection - OfProjection(&'tcx ty::ProjectionTy<'tcx>), + OfProjection(ty::ProjectionTy<'tcx>), /// The unsize info of this opaque ty OfOpaque(DefId, SubstsRef<'tcx>), /// The unsize info of this parameter - OfParam(&'tcx ty::ParamTy), + OfParam(ty::ParamTy), } impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -118,9 +119,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Pointers to foreign types are thin, despite being unsized ty::Foreign(..) => Some(PointerKind::Thin), // We should really try to normalize here. - ty::Projection(ref pi) => Some(PointerKind::OfProjection(pi)), + ty::Projection(pi) => Some(PointerKind::OfProjection(pi)), ty::Opaque(def_id, substs) => Some(PointerKind::OfOpaque(def_id, substs)), - ty::Param(ref p) => Some(PointerKind::OfParam(p)), + ty::Param(p) => Some(PointerKind::OfParam(p)), // Insufficient type information. ty::Placeholder(..) | ty::Bound(..) | ty::Infer(_) => None, @@ -497,10 +498,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { let ty = fcx.tcx.erase_regions(ty); let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty); let expr_ty = fcx.tcx.erase_regions(expr_ty); - let ty_params = fcx.tcx.mk_substs_trait(expr_ty, &[]); if fcx .infcx - .type_implements_trait(from_trait, ty, ty_params, fcx.param_env) + .type_implements_trait(from_trait, [ty, expr_ty], fcx.param_env) .must_apply_modulo_regions() { label = false; @@ -909,7 +909,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { } // vtable kinds must match - if cast_kind == expr_kind { + if fcx.tcx.erase_regions(cast_kind) == fcx.tcx.erase_regions(expr_kind) { Ok(CastKind::PtrPtrCast) } else { Err(CastError::DifferingKinds) diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs index 1578cddd490..b9e90e47e50 100644 --- a/compiler/rustc_hir_typeck/src/check.rs +++ b/compiler/rustc_hir_typeck/src/check.rs @@ -102,7 +102,7 @@ pub(super) fn check_fn<'a, 'tcx>( inherited.typeck_results.borrow_mut().liberated_fn_sigs_mut().insert(fn_id, fn_sig); - if let ty::Dynamic(..) = declared_ret_ty.kind() { + if let ty::Dynamic(_, _, ty::Dyn) = declared_ret_ty.kind() { // FIXME: We need to verify that the return type is `Sized` after the return expression has // been evaluated so that we have types available for all the nodes being returned, but that // requires the coerced evaluated type to be stored. Moving `check_return_expr` before this diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 71949b42118..43c7127b0d4 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -55,7 +55,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeAndMut}; +use rustc_middle::ty::{self, Ty, TypeAndMut}; use rustc_session::parse::feature_err; use rustc_span::symbol::sym; use rustc_span::{self, BytePos, DesugaringKind, Span}; @@ -278,13 +278,13 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { for &source_ty in &[a, b] { if source_ty != target_ty { obligations.push(Obligation::new( + self.tcx(), self.cause.clone(), self.param_env, ty::Binder::dummy(ty::PredicateKind::Coerce(ty::CoercePredicate { a: source_ty, b: target_ty, - })) - .to_predicate(self.tcx()), + })), )); } } @@ -630,8 +630,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { cause, coerce_unsized_did, 0, - coerce_source, - &[coerce_target.into()] + [coerce_source, coerce_target] )]; let mut has_unsized_tuple_coercion = false; @@ -669,7 +668,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { continue; } }; - match selcx.select(&obligation.with(trait_pred)) { + match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) { // Uncertain or unimplemented. Ok(None) => { if trait_pred.def_id() == unsize_did { @@ -748,7 +747,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { &self, a: Ty<'tcx>, b: Ty<'tcx>, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, b_region: ty::Region<'tcx>, ) -> CoerceResult<'tcx> { if !self.tcx.features().dyn_star { @@ -775,7 +774,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // Check the obligations of the cast -- for example, when casting // `usize` to `dyn* Clone + 'static`: - let obligations = predicates + let mut obligations: Vec<_> = predicates .iter() .map(|predicate| { // For each existential predicate (e.g., `?Self: Clone`) substitute @@ -783,17 +782,34 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // and then require that the resulting predicate (e.g., `usize: Clone`) // holds (it does). let predicate = predicate.with_self_ty(self.tcx, a); - Obligation::new(self.cause.clone(), self.param_env, predicate) + Obligation::new(self.tcx, self.cause.clone(), self.param_env, predicate) }) - // Enforce the region bound (e.g., `usize: 'static`, in our example). - .chain([Obligation::new( + .chain([ + // Enforce the region bound (e.g., `usize: 'static`, in our example). + Obligation::new( + self.tcx, + self.cause.clone(), + self.param_env, + ty::Binder::dummy(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate( + a, b_region, + ))), + ), + ]) + .collect(); + + // Enforce that the type is `usize`/pointer-sized. For now, only those + // can be coerced to `dyn*`, except for `dyn* -> dyn*` upcasts. + if !a.is_dyn_star() { + obligations.push(Obligation::new( + self.tcx, self.cause.clone(), self.param_env, - self.tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::TypeOutlives( - ty::OutlivesPredicate(a, b_region), - ))), - )]) - .collect(); + ty::Binder::dummy( + self.tcx.at(self.cause.span).mk_trait_ref(hir::LangItem::PointerSized, [a]), + ) + .to_poly_trait_predicate(), + )); + } Ok(InferOk { value: (vec![Adjustment { kind: Adjust::DynStar, target: b }], b), @@ -1068,8 +1084,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.infcx .type_implements_trait( self.tcx.lang_items().deref_mut_trait()?, - expr_ty, - ty::List::empty(), + [expr_ty], self.param_env, ) .may_apply() @@ -1543,7 +1558,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { // Mark that we've failed to coerce the types here to suppress // any superfluous errors we might encounter while trying to // emit or provide suggestions on how to fix the initial error. - fcx.set_tainted_by_errors(); + fcx.set_tainted_by_errors( + fcx.tcx.sess.delay_span_bug(cause.span, "coercion error but no error emitted"), + ); let (expected, found) = if label_expression_as_expected { // In the case where this is a "forced unit", like // `break`, we want to call the `()` "expected" diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 9ca7730daa6..934d1240442 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -2,6 +2,7 @@ use crate::FnCtxt; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_hir as hir; +use rustc_hir::def::CtorKind; use rustc_hir::lang_items::LangItem; use rustc_hir::{is_range_literal, Node}; use rustc_infer::infer::InferOk; @@ -154,7 +155,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(e) => e, }; - self.set_tainted_by_errors(); + self.set_tainted_by_errors(self.tcx.sess.delay_span_bug( + expr.span, + "`TypeError` when attempting coercion but no error emitted", + )); let expr = expr.peel_drop_temps(); let cause = self.misc(expr.span); let expr_ty = self.resolve_vars_with_obligations(checked_ty); @@ -401,27 +405,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(path) = variant_path.strip_prefix("std::prelude::") && let Some((_, path)) = path.split_once("::") { - return Some((path.to_string(), variant.ctor_kind, sole_field.name, note_about_variant_field_privacy)); + return Some((path.to_string(), variant.ctor_kind(), sole_field.name, note_about_variant_field_privacy)); } - Some((variant_path, variant.ctor_kind, sole_field.name, note_about_variant_field_privacy)) + Some((variant_path, variant.ctor_kind(), sole_field.name, note_about_variant_field_privacy)) } else { None } }) .collect(); - let suggestions_for = |variant: &_, ctor, field_name| { + let suggestions_for = |variant: &_, ctor_kind, field_name| { let prefix = match self.maybe_get_struct_pattern_shorthand_field(expr) { Some(ident) => format!("{ident}: "), None => String::new(), }; - let (open, close) = match ctor { - hir::def::CtorKind::Fn => ("(".to_owned(), ")"), - hir::def::CtorKind::Fictive => (format!(" {{ {field_name}: "), " }"), + let (open, close) = match ctor_kind { + Some(CtorKind::Fn) => ("(".to_owned(), ")"), + None => (format!(" {{ {field_name}: "), " }"), // unit variants don't have fields - hir::def::CtorKind::Const => unreachable!(), + Some(CtorKind::Const) => unreachable!(), }; // Suggest constructor as deep into the block tree as possible. diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index afac6e7d94a..507272fdec5 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -1,10 +1,11 @@ -//! Errors emitted by `rustc_hir_analysis`. +//! Errors emitted by `rustc_hir_typeck`. +use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, MultiSpan, SubdiagnosticMessage}; use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_middle::ty::Ty; use rustc_span::{symbol::Ident, Span}; #[derive(Diagnostic)] -#[diag(hir_analysis_field_multiply_specified_in_initializer, code = "E0062")] +#[diag(hir_typeck_field_multiply_specified_in_initializer, code = "E0062")] pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] @@ -15,7 +16,7 @@ pub struct FieldMultiplySpecifiedInInitializer { } #[derive(Diagnostic)] -#[diag(hir_analysis_return_stmt_outside_of_fn_body, code = "E0572")] +#[diag(hir_typeck_return_stmt_outside_of_fn_body, code = "E0572")] pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, @@ -26,14 +27,14 @@ pub struct ReturnStmtOutsideOfFnBody { } #[derive(Diagnostic)] -#[diag(hir_analysis_yield_expr_outside_of_generator, code = "E0627")] +#[diag(hir_typeck_yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_analysis_struct_expr_non_exhaustive, code = "E0639")] +#[diag(hir_typeck_struct_expr_non_exhaustive, code = "E0639")] pub struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -41,21 +42,21 @@ pub struct StructExprNonExhaustive { } #[derive(Diagnostic)] -#[diag(hir_analysis_method_call_on_unknown_type, code = "E0699")] +#[diag(hir_typeck_method_call_on_unknown_type, code = "E0699")] pub struct MethodCallOnUnknownType { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_analysis_functional_record_update_on_non_struct, code = "E0436")] +#[diag(hir_typeck_functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(hir_analysis_address_of_temporary_taken, code = "E0745")] +#[diag(hir_typeck_address_of_temporary_taken, code = "E0745")] pub struct AddressOfTemporaryTaken { #[primary_span] #[label] @@ -65,7 +66,7 @@ pub struct AddressOfTemporaryTaken { #[derive(Subdiagnostic)] pub enum AddReturnTypeSuggestion { #[suggestion( - hir_analysis_add_return_type_add, + hir_typeck_add_return_type_add, code = "-> {found} ", applicability = "machine-applicable" )] @@ -75,7 +76,7 @@ pub enum AddReturnTypeSuggestion { found: String, }, #[suggestion( - hir_analysis_add_return_type_missing_here, + hir_typeck_add_return_type_missing_here, code = "-> _ ", applicability = "has-placeholders" )] @@ -87,12 +88,12 @@ pub enum AddReturnTypeSuggestion { #[derive(Subdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(hir_analysis_expected_default_return_type)] + #[label(hir_typeck_expected_default_return_type)] Unit { #[primary_span] span: Span, }, - #[label(hir_analysis_expected_return_type)] + #[label(hir_typeck_expected_return_type)] Other { #[primary_span] span: Span, @@ -101,10 +102,10 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } #[derive(Diagnostic)] -#[diag(hir_analysis_missing_parentheses_in_range, code = "E0689")] +#[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")] pub struct MissingParentheseInRange { #[primary_span] - #[label(hir_analysis_missing_parentheses_in_range)] + #[label(hir_typeck_missing_parentheses_in_range)] pub span: Span, pub ty_str: String, pub method_name: String, @@ -114,7 +115,7 @@ pub struct MissingParentheseInRange { #[derive(Subdiagnostic)] #[multipart_suggestion( - hir_analysis_add_missing_parentheses_in_range, + hir_typeck_add_missing_parentheses_in_range, style = "verbose", applicability = "maybe-incorrect" )] @@ -127,9 +128,47 @@ pub struct AddMissingParenthesesInRange { } #[derive(Diagnostic)] -#[diag(hir_analysis_op_trait_generic_params)] +#[diag(hir_typeck_op_trait_generic_params)] pub struct OpMethodGenericParams { #[primary_span] pub span: Span, pub method_name: String, } + +pub struct TypeMismatchFruTypo { + /// Span of the LHS of the range + pub expr_span: Span, + /// Span of the `..RHS` part of the range + pub fru_span: Span, + /// Rendered expression of the RHS of the range + pub expr: Option<String>, +} + +impl AddToDiagnostic for TypeMismatchFruTypo { + fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) + where + F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage, + { + diag.set_arg("expr", self.expr.as_deref().unwrap_or("NONE")); + + // Only explain that `a ..b` is a range if it's split up + if self.expr_span.between(self.fru_span).is_empty() { + diag.span_note( + self.expr_span.to(self.fru_span), + rustc_errors::fluent::hir_typeck_fru_note, + ); + } else { + let mut multispan: MultiSpan = vec![self.expr_span, self.fru_span].into(); + multispan.push_span_label(self.expr_span, rustc_errors::fluent::hir_typeck_fru_expr); + multispan.push_span_label(self.fru_span, rustc_errors::fluent::hir_typeck_fru_expr2); + diag.span_note(multispan, rustc_errors::fluent::hir_typeck_fru_note); + } + + diag.span_suggestion( + self.expr_span.shrink_to_hi(), + rustc_errors::fluent::hir_typeck_fru_suggestion, + ", ", + Applicability::MaybeIncorrect, + ); + } +} diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 13a03b33de8..91f65b8c0f2 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -5,6 +5,7 @@ use crate::cast; use crate::coercion::CoerceMany; use crate::coercion::DynamicCoerceMany; +use crate::errors::TypeMismatchFruTypo; use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive}; use crate::errors::{ FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, @@ -527,12 +528,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.resolve_ty_and_res_fully_qualified_call(qpath, expr.hir_id, expr.span); let ty = match res { Res::Err => { - self.set_tainted_by_errors(); - tcx.ty_error() + let e = + self.tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); + self.set_tainted_by_errors(e); + tcx.ty_error_with_guaranteed(e) } - Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { - report_unexpected_variant_res(tcx, res, qpath, expr.span); - tcx.ty_error() + Res::Def(DefKind::Variant, _) => { + let e = report_unexpected_variant_res(tcx, res, qpath, expr.span, "E0533", "value"); + tcx.ty_error_with_guaranteed(e) } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, }; @@ -1115,9 +1118,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let lhs_deref_ty_is_sized = self .infcx .type_implements_trait( - self.tcx.lang_items().sized_trait().unwrap(), - lhs_deref_ty, - ty::List::empty(), + self.tcx.require_lang_item(LangItem::Sized, None), + [lhs_deref_ty], self.param_env, ) .may_apply(); @@ -1614,10 +1616,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_coerce_diag(&field.expr, ty, field_type, None, AllowTwoPhase::No); if let Some(mut diag) = diag { - if idx == ast_fields.len() - 1 && remaining_fields.is_empty() { - self.suggest_fru_from_range(field, variant, substs, &mut diag); + if idx == ast_fields.len() - 1 { + if remaining_fields.is_empty() { + self.suggest_fru_from_range(field, variant, substs, &mut diag); + diag.emit(); + } else { + diag.stash(field.span, StashKey::MaybeFruTypo); + } + } else { + diag.emit(); } - diag.emit(); } } @@ -1875,19 +1883,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .map(|adt| adt.did()) != range_def_id { - let instead = self + // Suppress any range expr type mismatches + if let Some(mut diag) = self + .tcx + .sess + .diagnostic() + .steal_diagnostic(last_expr_field.span, StashKey::MaybeFruTypo) + { + diag.delay_as_bug(); + } + + // Use a (somewhat arbitrary) filtering heuristic to avoid printing + // expressions that are either too long, or have control character + //such as newlines in them. + let expr = self .tcx .sess .source_map() .span_to_snippet(range_end.expr.span) - .map(|s| format!(" from `{s}`")) - .unwrap_or_default(); - err.span_suggestion( - range_start.span.shrink_to_hi(), - &format!("to set the remaining fields{instead}, separate the last named field with a comma"), - ",", - Applicability::MaybeIncorrect, - ); + .ok() + .filter(|s| s.len() < 25 && !s.contains(|c: char| c.is_control())); + + let fru_span = self + .tcx + .sess + .source_map() + .span_extend_while(range_start.span, |c| c.is_whitespace()) + .unwrap_or(range_start.span).shrink_to_hi().to(range_end.span); + + err.subdiagnostic(TypeMismatchFruTypo { + expr_span: range_start.span, + fru_span, + expr, + }); } } @@ -1962,7 +1990,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr_span: Span, ) { if variant.is_recovered() { - self.set_tainted_by_errors(); + self.set_tainted_by_errors( + self.tcx + .sess + .delay_span_bug(expr_span, "parser recovered but no error was emitted"), + ); return; } let mut err = self.err_ctxt().type_error_struct_with_diag( @@ -1992,8 +2024,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); let variant_ident_span = self.tcx.def_ident_span(variant.def_id).unwrap(); - match variant.ctor_kind { - CtorKind::Fn => match ty.kind() { + match variant.ctor_kind() { + Some(CtorKind::Fn) => match ty.kind() { ty::Adt(adt, ..) if adt.is_enum() => { err.span_label( variant_ident_span, diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs index 5d44092a5f6..ac6b0924ab5 100644 --- a/compiler/rustc_hir_typeck/src/fallback.rs +++ b/compiler/rustc_hir_typeck/src/fallback.rs @@ -104,7 +104,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> { // type, `?T` is not considered unsolved, but `?I` is. The // same is true for float variables.) let fallback = match ty.kind() { - _ if self.is_tainted_by_errors() => self.tcx.ty_error(), + _ if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), ty::Infer(ty::IntVar(_)) => self.tcx.types.i32, ty::Infer(ty::FloatVar(_)) => self.tcx.types.f64, _ => match diverging_fallback.get(&ty) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 97d05b4f95c..c7bfe99aa9a 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -22,8 +22,7 @@ use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::{ - self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, ToPredicate, Ty, - UserType, + self, AdtKind, CanonicalUserType, DefIdTree, EarlyBinder, GenericParamDefKind, Ty, UserType, }; use rustc_middle::ty::{GenericArgKind, InternalSubsts, SubstsRef, UserSelfTy, UserSubsts}; use rustc_session::lint; @@ -141,8 +140,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("write_ty({:?}, {:?}) in fcx {}", id, self.resolve_vars_if_possible(ty), self.tag()); self.typeck_results.borrow_mut().node_types_mut().insert(id, ty); - if ty.references_error() { - self.set_tainted_by_errors(); + if let Err(e) = ty.error_reported() { + self.set_tainted_by_errors(e); } } @@ -529,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => t, - None if self.is_tainted_by_errors() => self.tcx.ty_error(), + None if let Some(e) = self.tainted_by_errors() => self.tcx.ty_error_with_guaranteed(e), None => { bug!( "no type for node {}: {} in fcx {}", @@ -544,7 +543,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { pub fn node_ty_opt(&self, id: hir::HirId) -> Option<Ty<'tcx>> { match self.typeck_results.borrow().node_types().get(id) { Some(&t) => Some(t), - None if self.is_tainted_by_errors() => Some(self.tcx.ty_error()), + None if let Some(e) = self.tainted_by_errors() => Some(self.tcx.ty_error_with_guaranteed(e)), None => None, } } @@ -559,9 +558,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // WF obligations never themselves fail, so no real need to give a detailed cause: let cause = traits::ObligationCause::new(span, self.body_id, code); self.register_predicate(traits::Obligation::new( + self.tcx, cause, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(self.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), )); } @@ -702,6 +702,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // code is looking for a self type of an unresolved // inference variable. | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, }, ) @@ -1148,9 +1149,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { explicit_late_bound = ExplicitLateBound::Yes; } - if let Err(GenericArgCountMismatch { reported: Some(_), .. }) = arg_count.correct { + if let Err(GenericArgCountMismatch { reported: Some(e), .. }) = arg_count.correct { infer_args_for_err.insert(index); - self.set_tainted_by_errors(); // See issue #53251. + self.set_tainted_by_errors(e); // See issue #53251. } } @@ -1164,11 +1165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match *ty.kind() { ty::Adt(adt_def, substs) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); - let ctor_def_id = variant.ctor_def_id.unwrap(); - ( - Res::Def(DefKind::Ctor(CtorOf::Struct, variant.ctor_kind), ctor_def_id), - Some(substs), - ) + let (ctor_kind, ctor_def_id) = variant.ctor.unwrap(); + (Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id), Some(substs)) } _ => { let mut err = tcx.sess.struct_span_err( @@ -1440,12 +1438,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if !ty.is_ty_var() { ty } else { - if !self.is_tainted_by_errors() { + let e = self.tainted_by_errors().unwrap_or_else(|| { self.err_ctxt() .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true) - .emit(); - } - let err = self.tcx.ty_error(); + .emit() + }); + let err = self.tcx.ty_error_with_guaranteed(e); self.demand_suptype(sp, err, ty); err } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8cf70eb5431..a31ab9c8b23 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -73,7 +73,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let ty = self.typeck_results.borrow().expr_ty_adjusted(expr); let ty = self.resolve_vars_if_possible(ty); if ty.has_non_region_infer() { - assert!(self.is_tainted_by_errors()); self.tcx.ty_error() } else { self.tcx.erase_regions(ty) @@ -512,8 +511,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tys.into_iter().any(|ty| ty.references_error() || ty.is_ty_var()) } - self.set_tainted_by_errors(); let tcx = self.tcx; + // FIXME: taint after emitting errors and pass through an `ErrorGuaranteed` + self.set_tainted_by_errors( + tcx.sess.delay_span_bug(call_span, "no errors reported for args"), + ); // Get the argument span in the context of the call span so that // suggestions and labels are (more) correct when an arg is a @@ -1208,7 +1210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id); let variant = match def { Res::Err => { - self.set_tainted_by_errors(); + self.set_tainted_by_errors( + self.tcx.sess.delay_span_bug(path_span, "`Res::Err` but no error emitted"), + ); return None; } Res::Def(DefKind::Variant, _) => match ty.kind() { @@ -2150,6 +2154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ), ); let obligation = traits::Obligation::new( + self.tcx, traits::ObligationCause::dummy(), self.param_env, ty::Binder::dummy(ty::TraitPredicate { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index d5e4b6de581..177d521d280 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -4,6 +4,7 @@ mod checks; mod suggestions; pub use _impl::*; +use rustc_errors::ErrorGuaranteed; pub use suggestions::*; use crate::coercion::DynamicCoerceMany; @@ -289,8 +290,8 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } } - fn set_tainted_by_errors(&self) { - self.infcx.set_tainted_by_errors() + fn set_tainted_by_errors(&self, e: ErrorGuaranteed) { + self.infcx.set_tainted_by_errors(e) } fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, _span: Span) { diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 06e6e4350fc..b5aa8cd6e7c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -464,7 +464,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ref_cnt += 1; } if let ty::Adt(adt, _) = peeled.kind() - && self.tcx.is_diagnostic_item(sym::String, adt.did()) + && Some(adt.did()) == self.tcx.lang_items().string() { err.span_suggestion_verbose( expr.span.shrink_to_hi(), @@ -1090,14 +1090,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let Some(into_def_id) = self.tcx.get_diagnostic_item(sym::Into) && self.predicate_must_hold_modulo_regions(&traits::Obligation::new( + self.tcx, self.misc(expr.span), self.param_env, - ty::Binder::dummy(ty::TraitRef { - def_id: into_def_id, - substs: self.tcx.mk_substs_trait(expr_ty, &[expected_ty.into()]), - }) - .to_poly_trait_predicate() - .to_predicate(self.tcx), + ty::Binder::dummy(self.tcx.mk_trait_ref( + into_def_id, + [expr_ty, expected_ty] + )) + .to_poly_trait_predicate(), )) { let sugg = if expr.precedence().order() >= PREC_POSTFIX { diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs index 122ad7009cb..a78b294181c 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs @@ -217,7 +217,7 @@ impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> { let ty = self.tcx.erase_regions(ty); let m = self.tcx.parent_module(expr.hir_id).to_def_id(); let param_env = self.tcx.param_env(m.expect_local()); - if self.tcx.is_ty_uninhabited_from(m, ty, param_env) { + if !ty.is_inhabited_from(self.tcx, m, param_env) { // This function will not return. We model this fact as an infinite loop. self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1); } diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs index 7bbfb70f2c3..bd3589c6c43 100644 --- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs +++ b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs @@ -542,10 +542,10 @@ fn check_must_not_suspend_ty<'tcx>( data: SuspendCheckData<'_, 'tcx>, ) -> bool { if ty.is_unit() - // FIXME: should this check `is_ty_uninhabited_from`. This query is not available in this stage + // FIXME: should this check `Ty::is_inhabited_from`. This query is not available in this stage // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in // `must_use` - // || fcx.tcx.is_ty_uninhabited_from(fcx.tcx.parent_module(hir_id).to_def_id(), ty, fcx.param_env) + // || !ty.is_inhabited_from(fcx.tcx, fcx.tcx.parent_module(hir_id).to_def_id(), fcx.param_env) { return false; } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 9812d96fcc3..c2dc1402465 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -3,7 +3,7 @@ use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; use rustc_target::abi::{Pointer, VariantIdx}; use super::FnCtxt; @@ -46,7 +46,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let from = normalize(from); let to = normalize(to); trace!(?from, ?to); - + if from.has_non_region_infer() || to.has_non_region_infer() { + tcx.sess.delay_span_bug(span, "argument to transmute has inference variables"); + return; + } // Transmutes that are only changing lifetimes are always ok. if from == to { return; diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 6fd609aeaa0..5104b448023 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -53,9 +53,9 @@ use crate::check::check_fn; use crate::coercion::DynamicCoerceMany; use crate::gather_locals::GatherLocalsVisitor; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{struct_span_err, MultiSpan}; +use rustc_errors::{struct_span_err, DiagnosticId, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::Res; +use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::Visitor; use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; @@ -344,7 +344,7 @@ fn typeck_with_fallback<'tcx>( fcx.select_all_obligations_or_error(); - if !fcx.infcx.is_tainted_by_errors() { + if let None = fcx.infcx.tainted_by_errors() { fcx.check_transmutes(); } @@ -428,16 +428,33 @@ impl<'tcx> EnclosingBreakables<'tcx> { } } -fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, qpath: &hir::QPath<'_>, span: Span) { - struct_span_err!( - tcx.sess, +fn report_unexpected_variant_res( + tcx: TyCtxt<'_>, + res: Res, + qpath: &hir::QPath<'_>, + span: Span, + err_code: &str, + expected: &str, +) -> ErrorGuaranteed { + let res_descr = match res { + Res::Def(DefKind::Variant, _) => "struct variant", + _ => res.descr(), + }; + let path_str = rustc_hir_pretty::qpath_to_string(qpath); + let mut err = tcx.sess.struct_span_err_with_code( span, - E0533, - "expected unit struct, unit variant or constant, found {} `{}`", - res.descr(), - rustc_hir_pretty::qpath_to_string(qpath), - ) - .emit(); + format!("expected {expected}, found {res_descr} `{path_str}`"), + DiagnosticId::Error(err_code.into()), + ); + match res { + Res::Def(DefKind::Fn | DefKind::AssocFn, _) if err_code == "E0164" => { + let patterns_url = "https://doc.rust-lang.org/book/ch18-00-patterns.html"; + err.span_label(span, "`fn` calls are not allowed in patterns"); + err.help(format!("for more information, visit {patterns_url}")) + } + _ => err.span_label(span, format!("not a {expected}")), + } + .emit() } /// Controls whether the arguments are tupled. This is used for the call diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 362f1c34300..0b5dc946c1d 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -133,7 +133,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { } fn is_tainted_by_errors(&self) -> bool { - self.infcx.is_tainted_by_errors() + self.infcx.tainted_by_errors().is_some() } fn resolve_type_vars_or_error( diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index 3f390cba3e7..9b1f0cff074 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -20,7 +20,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::{self, InferOk}; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; -use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, ToPredicate, Ty, TypeVisitable}; +use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, Ty, TypeVisitable}; use rustc_span::symbol::Ident; use rustc_span::Span; use rustc_trait_selection::traits; @@ -293,10 +293,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let poly_trait_ref = ty::Binder::dummy(trait_ref); ( traits::Obligation::misc( + self.tcx, span, self.body_id, self.param_env, - poly_trait_ref.without_const().to_predicate(self.tcx), + poly_trait_ref.without_const(), ), substs, ) @@ -335,6 +336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ( traits::Obligation::new( + self.tcx, traits::ObligationCause::new( span, self.body_id, @@ -346,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }, ), self.param_env, - poly_trait_ref.without_const().to_predicate(self.tcx), + poly_trait_ref.without_const(), ), substs, ) @@ -523,9 +525,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_ty, obligation ); obligations.push(traits::Obligation::new( + tcx, cause, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(method_ty.into())), )); let callee = MethodCallee { def_id, substs, sig: fn_sig }; @@ -563,6 +566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let tcx = self.tcx; // Check if we have an enum variant. + let mut struct_variant = None; if let ty::Adt(adt_def, _) = self_ty.kind() { if adt_def.is_enum() { let variant_def = adt_def @@ -570,16 +574,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .find(|vd| tcx.hygienic_eq(method_name, vd.ident(tcx), adt_def.did())); if let Some(variant_def) = variant_def { - // Braced variants generate unusable names in value namespace (reserved for - // possible future use), so variants resolved as associated items may refer to - // them as well. It's ok to use the variant's id as a ctor id since an - // error will be reported on any use of such resolution anyway. - let ctor_def_id = variant_def.ctor_def_id.unwrap_or(variant_def.def_id); - tcx.check_stability(ctor_def_id, Some(expr_id), span, Some(method_name.span)); - return Ok(( - DefKind::Ctor(CtorOf::Variant, variant_def.ctor_kind), - ctor_def_id, - )); + if let Some((ctor_kind, ctor_def_id)) = variant_def.ctor { + tcx.check_stability( + ctor_def_id, + Some(expr_id), + span, + Some(method_name.span), + ); + return Ok((DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id)); + } else { + struct_variant = Some((DefKind::Variant, variant_def.def_id)); + } } } } @@ -591,7 +596,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, expr_id, ProbeScope::TraitsInScope, - )?; + ); + let pick = match (pick, struct_variant) { + // Fall back to a resolution that will produce an error later. + (Err(_), Some(res)) => return Ok(res), + (pick, _) => pick?, + }; pick.maybe_emit_unstable_name_collision_hint(self.tcx, span, expr_id); diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs index 3c98a2aa3ab..89746ce54a6 100644 --- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs +++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs @@ -8,7 +8,7 @@ use hir::ItemKind; use rustc_ast::Mutability; use rustc_errors::Applicability; use rustc_hir as hir; -use rustc_middle::ty::subst::InternalSubsts; +use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_middle::ty::{Adt, Array, Ref, Ty}; use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS; use rustc_span::symbol::kw::{Empty, Underscore}; @@ -227,14 +227,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // If we know it does not, we don't need to warn. if method_name.name == sym::from_iter { if let Some(trait_def_id) = self.tcx.get_diagnostic_item(sym::FromIterator) { + let any_type = self.infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::MiscVariable, + span, + }); if !self .infcx - .type_implements_trait( - trait_def_id, - self_ty, - InternalSubsts::empty(), - self.param_env, - ) + .type_implements_trait(trait_def_id, [self_ty, any_type], self.param_env) .may_apply() { return; diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 46a76085189..44c3edf06a8 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -19,7 +19,8 @@ use rustc_middle::middle::stability; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::AssocItem; use rustc_middle::ty::GenericParamDefKind; -use rustc_middle::ty::{self, ParamEnvAnd, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::ToPredicate; +use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFoldable, TypeVisitable}; use rustc_middle::ty::{InternalSubsts, SubstsRef}; use rustc_session::lint; use rustc_span::def_id::DefId; @@ -802,6 +803,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } }); @@ -1429,7 +1431,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> { let cause = traits::ObligationCause::misc(self.span, self.body_id); let predicate = ty::Binder::dummy(trait_ref).to_poly_trait_predicate(); - let obligation = traits::Obligation::new(cause, self.param_env, predicate); + let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, predicate); traits::SelectionContext::new(self).select(&obligation) } @@ -1560,7 +1562,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { let predicate = ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx); parent_pred = Some(predicate); - let obligation = traits::Obligation::new(cause, self.param_env, predicate); + let obligation = + traits::Obligation::new(self.tcx, cause, self.param_env, predicate); if !self.predicate_may_hold(&obligation) { result = ProbeResult::NoMatch; if self.probe(|_| { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 19f56c73823..d0ea2b0e664 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -23,7 +23,7 @@ use rustc_middle::traits::util::supertraits; use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fast_reject::{simplify_type, TreatParams}; use rustc_middle::ty::print::with_crate_prefix; -use rustc_middle::ty::{self, DefIdTree, GenericArgKind, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, DefIdTree, GenericArgKind, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{IsSuggestable, ToPolyTraitRef}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; @@ -68,22 +68,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.autoderef(span, ty).any(|(ty, _)| { info!("check deref {:?} impl FnOnce", ty); self.probe(|_| { - let fn_once_substs = tcx.mk_substs_trait( - ty, - &[self - .next_ty_var(TypeVariableOrigin { + let trait_ref = tcx.mk_trait_ref( + fn_once, + [ + ty, + self.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span, - }) - .into()], + }), + ], ); - let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs); let poly_trait_ref = ty::Binder::dummy(trait_ref); let obligation = Obligation::misc( + tcx, span, self.body_id, self.param_env, - poly_trait_ref.without_const().to_predicate(tcx), + poly_trait_ref.without_const(), ); self.predicate_may_hold(&obligation) }) @@ -113,7 +114,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let report_candidates = |span: Span, err: &mut Diagnostic, sources: &mut Vec<CandidateSource>, - sugg_span: Span| { + sugg_span: Option<Span>| { sources.sort(); sources.dedup(); // Dynamic limit to avoid hiding just one candidate, which is silly. @@ -174,7 +175,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.note(¬e_str); } - if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { + if let Some(sugg_span) = sugg_span + && let Some(trait_ref) = self.tcx.impl_trait_ref(impl_did) { let path = self.tcx.def_path_str(trait_ref.def_id); let ty = match item.kind { @@ -223,20 +225,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_note(item_span, msg); None }; - let path = self.tcx.def_path_str(trait_did); - print_disambiguation_help( - item_name, - args, - err, - path, - rcvr_ty, - item.kind, - item.def_id, - sugg_span, - idx, - self.tcx.sess.source_map(), - item.fn_has_self_parameter, - ); + if let Some(sugg_span) = sugg_span { + let path = self.tcx.def_path_str(trait_did); + print_disambiguation_help( + item_name, + args, + err, + path, + rcvr_ty, + item.kind, + item.def_id, + sugg_span, + idx, + self.tcx.sess.source_map(), + item.fn_has_self_parameter, + ); + } } } } @@ -406,9 +410,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg_span, ); - report_candidates(span, &mut err, &mut static_candidates, sugg_span); + report_candidates(span, &mut err, &mut static_candidates, None); } else if static_candidates.len() > 1 { - report_candidates(span, &mut err, &mut static_candidates, sugg_span); + report_candidates(span, &mut err, &mut static_candidates, Some(sugg_span)); } let mut bound_spans = vec![]; @@ -817,10 +821,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty.is_str() || matches!( ty.kind(), - ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did()) + ty::Adt(adt, _) if Some(adt.did()) == self.tcx.lang_items().string() ) } - ty::Adt(adt, _) => self.tcx.is_diagnostic_item(sym::String, adt.did()), + ty::Adt(adt, _) => Some(adt.did()) == self.tcx.lang_items().string(), _ => false, }; if is_string_or_ref_str && item_name.name == sym::iter { @@ -1014,7 +1018,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); err.span_label(item_name.span, format!("multiple `{}` found", item_name)); - report_candidates(span, &mut err, &mut sources, sugg_span); + report_candidates(span, &mut err, &mut sources, Some(sugg_span)); err.emit(); } @@ -1914,12 +1918,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Str | ty::Projection(_) | ty::Param(_) => format!("{deref_ty}"), - // we need to test something like <&[_]>::len + // we need to test something like <&[_]>::len or <(&[u32])>::len // and Vec::function(); - // <&[_]>::len doesn't need an extra "<>" between + // <&[_]>::len or <&[u32]>::len doesn't need an extra "<>" between // but for Adt type like Vec::function() // we would suggest <[_]>::function(); - _ if self.tcx.sess.source_map().span_wrapped_by_angle_bracket(ty.span) => format!("{deref_ty}"), + _ if self.tcx.sess.source_map().span_wrapped_by_angle_or_parentheses(ty.span) => format!("{deref_ty}"), _ => format!("<{deref_ty}>"), }; err.span_suggestion_verbose( diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index 38b3dd218a9..adc7a21f265 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -556,9 +556,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let rm_borrow_msg = "remove the borrow to obtain an owned `String`"; let to_owned_msg = "create an owned `String` from a string reference"; + let string_type = self.tcx.lang_items().string(); let is_std_string = |ty: Ty<'tcx>| { - ty.ty_adt_def() - .map_or(false, |ty_def| self.tcx.is_diagnostic_item(sym::String, ty_def.did())) + ty.ty_adt_def().map_or(false, |ty_def| Some(ty_def.did()) == string_type) }; match (lhs_ty.kind(), rhs_ty.kind()) { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index eb10f3e2c10..2fe1b1d8999 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -401,6 +401,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + if self.tcx.features().string_deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind { + let tcx = self.tcx; + let expected = self.resolve_vars_if_possible(expected); + pat_ty = match expected.kind() { + ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected, + ty::Str => tcx.mk_static_str(), + _ => pat_ty, + }; + } + // Somewhat surprising: in this case, the subtyping relation goes the // opposite way as the other cases. Actually what we really want is not // a subtyping relation at all but rather that there exists a LUB @@ -839,12 +849,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (res, opt_ty, segments) = path_resolution; match res { Res::Err => { - self.set_tainted_by_errors(); - return tcx.ty_error(); + let e = tcx.sess.delay_span_bug(qpath.span(), "`Res::Err` but no error emitted"); + self.set_tainted_by_errors(e); + return tcx.ty_error_with_guaranteed(e); } - Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => { - report_unexpected_variant_res(tcx, res, qpath, pat.span); - return tcx.ty_error(); + Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::Variant, _) => { + let expected = "unit struct, unit variant or constant"; + let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0533", expected); + return tcx.ty_error_with_guaranteed(e); } Res::SelfCtor(..) | Res::Def( @@ -985,65 +997,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ti: TopInfo<'tcx>, ) -> Ty<'tcx> { let tcx = self.tcx; - let on_error = || { + let on_error = |e| { for pat in subpats { - self.check_pat(pat, tcx.ty_error(), def_bm, ti); + self.check_pat(pat, tcx.ty_error_with_guaranteed(e), def_bm, ti); } }; let report_unexpected_res = |res: Res| { - let sm = tcx.sess.source_map(); - let path_str = sm - .span_to_snippet(sm.span_until_char(pat.span, '(')) - .map_or_else(|_| String::new(), |s| format!(" `{}`", s.trim_end())); - let msg = format!( - "expected tuple struct or tuple variant, found {}{}", - res.descr(), - path_str - ); - - let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{msg}"); - match res { - Res::Def(DefKind::Fn | DefKind::AssocFn, _) => { - err.span_label(pat.span, "`fn` calls are not allowed in patterns"); - err.help( - "for more information, visit \ - https://doc.rust-lang.org/book/ch18-00-patterns.html", - ); - } - _ => { - err.span_label(pat.span, "not a tuple variant or struct"); - } - } - err.emit(); - on_error(); + let expected = "tuple struct or tuple variant"; + let e = report_unexpected_variant_res(tcx, res, qpath, pat.span, "E0164", expected); + on_error(e); + e }; // Resolve the path and check the definition for errors. let (res, opt_ty, segments) = self.resolve_ty_and_res_fully_qualified_call(qpath, pat.hir_id, pat.span); if res == Res::Err { - self.set_tainted_by_errors(); - on_error(); - return self.tcx.ty_error(); + let e = tcx.sess.delay_span_bug(pat.span, "`Res:Err` but no error emitted"); + self.set_tainted_by_errors(e); + on_error(e); + return tcx.ty_error_with_guaranteed(e); } // Type-check the path. let (pat_ty, res) = self.instantiate_value_path(segments, opt_ty, res, pat.span, pat.hir_id); if !pat_ty.is_fn() { - report_unexpected_res(res); - return tcx.ty_error(); + let e = report_unexpected_res(res); + return tcx.ty_error_with_guaranteed(e); } let variant = match res { Res::Err => { - self.set_tainted_by_errors(); - on_error(); - return tcx.ty_error(); + let e = tcx.sess.delay_span_bug(pat.span, "`Res::Err` but no error emitted"); + self.set_tainted_by_errors(e); + on_error(e); + return tcx.ty_error_with_guaranteed(e); } Res::Def(DefKind::AssocConst | DefKind::AssocFn, _) => { - report_unexpected_res(res); - return tcx.ty_error(); + let e = report_unexpected_res(res); + return tcx.ty_error_with_guaranteed(e); } Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => tcx.expect_variant_res(res), _ => bug!("unexpected pattern resolution: {:?}", res), @@ -1082,9 +1075,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Pattern has wrong number of fields. - self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); - on_error(); - return tcx.ty_error(); + let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); + on_error(e); + return tcx.ty_error_with_guaranteed(e); } pat_ty } @@ -1098,7 +1091,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [ty::FieldDef], expected: Ty<'tcx>, had_err: bool, - ) { + ) -> ErrorGuaranteed { let subpats_ending = pluralize!(subpats.len()); let fields_ending = pluralize!(fields.len()); @@ -1245,7 +1238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - err.emit(); + err.emit() } fn check_pat_tuple( @@ -1467,8 +1460,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // if this is a tuple struct, then all field names will be numbers // so if any fields in a struct pattern use shorthand syntax, they will // be invalid identifiers (for example, Foo { 0, 1 }). - if let (CtorKind::Fn, PatKind::Struct(qpath, field_patterns, ..)) = - (variant.ctor_kind, &pat.kind) + if let (Some(CtorKind::Fn), PatKind::Struct(qpath, field_patterns, ..)) = + (variant.ctor_kind(), &pat.kind) { let has_shorthand_field_name = field_patterns.iter().any(|field| field.is_shorthand); if has_shorthand_field_name { @@ -1645,7 +1638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { fields: &'tcx [hir::PatField<'tcx>], variant: &ty::VariantDef, ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> { - if let (CtorKind::Fn, PatKind::Struct(qpath, ..)) = (variant.ctor_kind, &pat.kind) { + if let (Some(CtorKind::Fn), PatKind::Struct(qpath, ..)) = (variant.ctor_kind(), &pat.kind) { let path = rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| { s.print_qpath(qpath, false) }); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4dea40829f6..68f119adc7a 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -970,12 +970,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { check_trait .map(|check_trait| { self.infcx - .type_implements_trait( - check_trait, - ty, - self.tcx.mk_substs_trait(ty, &[]), - self.param_env, - ) + .type_implements_trait(check_trait, [ty], self.param_env) .must_apply_modulo_regions() }) .unwrap_or(false), @@ -999,12 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { check_trait .map(|check_trait| { self.infcx - .type_implements_trait( - check_trait, - ty, - self.tcx.mk_substs_trait(ty, &[]), - self.param_env, - ) + .type_implements_trait(check_trait, [ty], self.param_env) .must_apply_modulo_regions() }) .unwrap_or(false), @@ -1347,14 +1337,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let is_drop_defined_for_ty = |ty: Ty<'tcx>| { let drop_trait = self.tcx.require_lang_item(hir::LangItem::Drop, Some(closure_span)); - let ty_params = self.tcx.mk_substs_trait(base_path_ty, &[]); self.infcx - .type_implements_trait( - drop_trait, - ty, - ty_params, - self.tcx.param_env(closure_def_id), - ) + .type_implements_trait(drop_trait, [ty], self.tcx.param_env(closure_def_id)) .must_apply_modulo_regions() }; diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index 2eca40d678a..6c2ee35fa50 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -83,10 +83,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { wbcx.typeck_results.treat_byte_string_as_slice = mem::take(&mut self.typeck_results.borrow_mut().treat_byte_string_as_slice); - if self.is_tainted_by_errors() { - // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - wbcx.typeck_results.tainted_by_errors = - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + if let Some(e) = self.tainted_by_errors() { + wbcx.typeck_results.tainted_by_errors = Some(e); } debug!("writeback: typeck results for {:?} are {:#?}", item_def_id, wbcx.typeck_results); @@ -674,10 +672,8 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> { // We may have introduced e.g. `ty::Error`, if inference failed, make sure // to mark the `TypeckResults` as tainted in that case, so that downstream // users of the typeck results don't produce extra errors, or worse, ICEs. - if resolver.replaced_with_error { - // FIXME(eddyb) keep track of `ErrorGuaranteed` from where the error was emitted. - self.typeck_results.tainted_by_errors = - Some(ErrorGuaranteed::unchecked_claim_error_was_emitted()); + if let Some(e) = resolver.replaced_with_error { + self.typeck_results.tainted_by_errors = Some(e); } x @@ -708,8 +704,8 @@ struct Resolver<'cx, 'tcx> { span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, - /// Set to `true` if any `Ty` or `ty::Const` had to be replaced with an `Error`. - replaced_with_error: bool, + /// Set to `Some` if any `Ty` or `ty::Const` had to be replaced with an `Error`. + replaced_with_error: Option<ErrorGuaranteed>, } impl<'cx, 'tcx> Resolver<'cx, 'tcx> { @@ -718,12 +714,14 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { span: &'cx dyn Locatable, body: &'tcx hir::Body<'tcx>, ) -> Resolver<'cx, 'tcx> { - Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false } + Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: None } } - fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) { - if !self.tcx.sess.has_errors().is_some() { - self.infcx + fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed { + match self.tcx.sess.has_errors() { + Some(e) => e, + None => self + .infcx .err_ctxt() .emit_inference_failure_err( Some(self.body.id()), @@ -732,7 +730,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { E0282, false, ) - .emit(); + .emit(), } } } @@ -773,9 +771,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { } Err(_) => { debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t); - self.report_error(t); - self.replaced_with_error = true; - self.tcx().ty_error() + let e = self.report_error(t); + self.replaced_with_error = Some(e); + self.tcx().ty_error_with_guaranteed(e) } } } @@ -790,9 +788,9 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> { Ok(ct) => self.tcx.erase_regions(ct), Err(_) => { debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct); - self.report_error(ct); - self.replaced_with_error = true; - self.tcx().const_error(ct.ty()) + let e = self.report_error(ct); + self.replaced_with_error = Some(e); + self.tcx().const_error_with_guaranteed(ct.ty(), e) } } } diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs index 5ff3779fa14..2483ab724a4 100644 --- a/compiler/rustc_infer/src/infer/at.rs +++ b/compiler/rustc_infer/src/infer/at.rs @@ -81,6 +81,7 @@ impl<'tcx> InferCtxt<'tcx> { .normalize_fn_sig_for_diagnostic .as_ref() .map(|f| f.clone()), + intercrate: self.intercrate, } } } diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index a299a3e578d..b4a427a5d41 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -23,11 +23,10 @@ use rustc_index::vec::Idx; use rustc_index::vec::IndexVec; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::error::TypeError; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, BoundVar, Const, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; use std::fmt::Debug; use std::iter; @@ -581,9 +580,9 @@ impl<'tcx> InferCtxt<'tcx> { span_bug!(cause.span, "unexpected const outlives {:?}", predicate); } }; - let predicate = predicate.0.rebind(atom).to_predicate(self.tcx); + let predicate = predicate.0.rebind(atom); - Obligation::new(cause, param_env, predicate) + Obligation::new(self.tcx, cause, param_env, predicate) } /// Given two sets of values for the same set of canonical variables, unify them. @@ -729,10 +728,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { }); } - fn const_equate(&mut self, _a: Const<'tcx>, _b: Const<'tcx>) { - span_bug!(self.cause.span(), "generic_const_exprs: unreachable `const_equate`"); - } - fn normalization() -> NormalizationStrategy { NormalizationStrategy::Eager } @@ -741,11 +736,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { true } - fn register_opaque_type_obligations( - &mut self, - obligations: PredicateObligations<'tcx>, - ) -> Result<(), TypeError<'tcx>> { + fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) { self.obligations.extend(obligations); - Ok(()) } } diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs index a973bf54b05..eec938cefbb 100644 --- a/compiler/rustc_infer/src/infer/combine.rs +++ b/compiler/rustc_infer/src/infer/combine.rs @@ -37,7 +37,7 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, InferConst, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, InferConst, Ty, TyCtxt, TypeVisitable}; use rustc_middle::ty::{IntType, UintType}; use rustc_span::{Span, DUMMY_SP}; @@ -347,10 +347,10 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { if needs_wf { self.obligations.push(Obligation::new( + self.tcx(), self.trace.cause.clone(), self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())) - .to_predicate(self.infcx.tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(b_ty.into())), )); } @@ -444,9 +444,19 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> { ty::PredicateKind::ConstEquate(b, a) }; self.obligations.push(Obligation::new( + self.tcx(), self.trace.cause.clone(), self.param_env, - ty::Binder::dummy(predicate).to_predicate(self.tcx()), + ty::Binder::dummy(predicate), + )); + } + + pub fn mark_ambiguous(&mut self) { + self.obligations.push(Obligation::new( + self.tcx(), + self.trace.cause.clone(), + self.param_env, + ty::Binder::dummy(ty::PredicateKind::Ambiguous), )); } } @@ -520,6 +530,11 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.infcx.tcx } + + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -532,6 +547,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { true } + fn mark_ambiguous(&mut self) { + span_bug!(self.cause.span, "opaque types are handled in `tys`"); + } + fn binders<T>( &mut self, a: ty::Binder<'tcx, T>, @@ -563,6 +582,7 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { &opt_variances, a_subst, b_subst, + true, ) } } @@ -655,6 +675,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> { // relatable. Ok(t) } + ty::Opaque(def_id, substs) => { + let s = self.relate(substs, substs)?; + Ok(if s == substs { t } else { self.infcx.tcx.mk_opaque(def_id, s) }) + } _ => relate::super_relate_tys(self, t, t), }?; @@ -797,6 +821,11 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { self.infcx.tcx } + fn intercrate(&self) -> bool { + assert!(!self.infcx.intercrate); + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -809,6 +838,10 @@ impl<'tcx> TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> { true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs index 59728148a84..8682f4d3b7a 100644 --- a/compiler/rustc_infer/src/infer/equate.rs +++ b/compiler/rustc_infer/src/infer/equate.rs @@ -32,6 +32,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.fields.tcx() } + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.fields.param_env } @@ -40,6 +44,10 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> { self.a_is_expected } + fn mark_ambiguous(&mut self) { + self.fields.mark_ambiguous(); + } + fn relate_item_substs( &mut self, _item_def_id: DefId, diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 22f32251f6d..0dee3be7054 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -65,7 +65,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticStyledString, MultiSpan}; use rustc_hir as hir; -use rustc_hir::def::DefKind; +use rustc_hir::def::{CtorKind, DefKind}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; @@ -261,6 +261,7 @@ fn label_msg_span( } } +#[instrument(level = "trace", skip(tcx))] pub fn unexpected_hidden_region_diagnostic<'tcx>( tcx: TyCtxt<'tcx>, span: Span, @@ -542,7 +543,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { Err(NonTrivialPath) } @@ -1966,7 +1967,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .variants() .iter() .filter(|variant| { - variant.fields.len() == 1 && variant.ctor_kind == hir::def::CtorKind::Fn + variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) }) .filter_map(|variant| { let sole_field = &variant.fields[0]; @@ -2936,6 +2937,11 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { self.0.tcx } + fn intercrate(&self) -> bool { + assert!(!self.0.intercrate); + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { // Unused, only for consts which we treat as always equal ty::ParamEnv::empty() @@ -2949,6 +2955,10 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> { true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: relate::Relate<'tcx>>( &mut self, _variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/glb.rs index 6ffefcb7a28..7f27b35a54e 100644 --- a/compiler/rustc_infer/src/infer/glb.rs +++ b/compiler/rustc_infer/src/infer/glb.rs @@ -30,6 +30,11 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { "Glb" } + fn intercrate(&self) -> bool { + assert!(!self.fields.infcx.intercrate); + false + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } @@ -42,6 +47,10 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> { self.a_is_expected } + fn mark_ambiguous(&mut self) { + bug!("mark_ambiguous used outside of coherence"); + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/lub.rs index d6e56fcb7fd..97ed4729bd0 100644 --- a/compiler/rustc_infer/src/infer/lub.rs +++ b/compiler/rustc_infer/src/infer/lub.rs @@ -30,6 +30,11 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { "Lub" } + fn intercrate(&self) -> bool { + assert!(!self.fields.infcx.intercrate); + false + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.tcx() } @@ -42,6 +47,10 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> { self.a_is_expected } + fn mark_ambiguous(&mut self) { + bug!("mark_ambiguous used outside of coherence"); + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index fd3b3e4d59f..2798477d181 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -34,7 +34,7 @@ pub use rustc_middle::ty::IntVarValue; use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid}; use rustc_span::symbol::Symbol; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::Span; use std::cell::{Cell, RefCell}; use std::fmt; @@ -337,6 +337,26 @@ pub struct InferCtxt<'tcx> { normalize_fn_sig_for_diagnostic: Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, + + /// During coherence we have to assume that other crates may add + /// additional impls which we currently don't know about. + /// + /// To deal with this evaluation should be conservative + /// and consider the possibility of impls from outside this crate. + /// This comes up primarily when resolving ambiguity. Imagine + /// there is some trait reference `$0: Bar` where `$0` is an + /// inference variable. If `intercrate` is true, then we can never + /// say for sure that this reference is not implemented, even if + /// there are *no impls at all for `Bar`*, because `$0` could be + /// bound to some type that in a downstream crate that implements + /// `Bar`. + /// + /// Outside of coherence we set this to false because we are only + /// interested in types that the user could actually have written. + /// In other words, we consider `$0: Bar` to be unimplemented if + /// there is no type that the user could *actually name* that + /// would satisfy it. This avoids crippling inference, basically. + pub intercrate: bool, } /// See the `error_reporting` module for more details. @@ -552,6 +572,8 @@ pub struct InferCtxtBuilder<'tcx> { tcx: TyCtxt<'tcx>, defining_use_anchor: DefiningAnchor, considering_regions: bool, + /// Whether we are in coherence mode. + intercrate: bool, normalize_fn_sig_for_diagnostic: Option<Lrc<dyn Fn(&InferCtxt<'tcx>, ty::PolyFnSig<'tcx>) -> ty::PolyFnSig<'tcx>>>, } @@ -567,6 +589,7 @@ impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> { defining_use_anchor: DefiningAnchor::Error, considering_regions: true, normalize_fn_sig_for_diagnostic: None, + intercrate: false, } } } @@ -583,6 +606,11 @@ impl<'tcx> InferCtxtBuilder<'tcx> { self } + pub fn intercrate(mut self) -> Self { + self.intercrate = true; + self + } + pub fn ignoring_regions(mut self) -> Self { self.considering_regions = false; self @@ -622,6 +650,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { defining_use_anchor, considering_regions, ref normalize_fn_sig_for_diagnostic, + intercrate, } = *self; InferCtxt { tcx, @@ -641,6 +670,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { normalize_fn_sig_for_diagnostic: normalize_fn_sig_for_diagnostic .as_ref() .map(|f| f.clone()), + intercrate, } } } @@ -1208,7 +1238,8 @@ impl<'tcx> InferCtxt<'tcx> { /// reporting errors that often occur as a result of earlier /// errors, but where it's hard to be 100% sure (e.g., unresolved /// inference variables, regionck errors). - pub fn is_tainted_by_errors(&self) -> bool { + #[must_use = "this method does not have any side effects"] + pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> { debug!( "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \ tainted_by_errors={})", @@ -1217,19 +1248,25 @@ impl<'tcx> InferCtxt<'tcx> { self.tainted_by_errors.get().is_some() ); + if let Some(e) = self.tainted_by_errors.get() { + return Some(e); + } + if self.tcx.sess.err_count() > self.err_count_on_creation { - return true; // errors reported since this infcx was made + // errors reported since this infcx was made + let e = self.tcx.sess.has_errors().unwrap(); + self.set_tainted_by_errors(e); + return Some(e); } - self.tainted_by_errors.get().is_some() + + None } /// Set the "tainted by errors" flag to true. We call this when we /// observe an error from a prior pass. - pub fn set_tainted_by_errors(&self) { - debug!("set_tainted_by_errors()"); - self.tainted_by_errors.set(Some( - self.tcx.sess.delay_span_bug(DUMMY_SP, "`InferCtxt` incorrectly tainted by errors"), - )); + pub fn set_tainted_by_errors(&self, e: ErrorGuaranteed) { + debug!("set_tainted_by_errors(ErrorGuaranteed)"); + self.tainted_by_errors.set(Some(e)); } pub fn skip_region_resolution(&self) { @@ -1270,7 +1307,7 @@ impl<'tcx> InferCtxt<'tcx> { let mut inner = self.inner.borrow_mut(); let inner = &mut *inner; assert!( - self.is_tainted_by_errors() || inner.region_obligations.is_empty(), + self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(), "region_obligations not empty: {:#?}", inner.region_obligations ); @@ -1707,7 +1744,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ) { let errors = self.resolve_regions(outlives_env); - if !self.is_tainted_by_errors() { + if let None = self.tainted_by_errors() { // As a heuristic, just skip reporting region errors // altogether if other errors have been reported while // this infcx was in use. This is totally hokey but diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs index 600f94f095e..4f8460955c3 100644 --- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs +++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs @@ -25,7 +25,7 @@ use crate::infer::combine::ConstEquateRelation; use crate::infer::InferCtxt; use crate::infer::{ConstVarValue, ConstVariableValue}; use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::traits::PredicateObligation; +use crate::traits::{Obligation, PredicateObligation}; use rustc_data_structures::fx::FxHashMap; use rustc_middle::traits::ObligationCause; use rustc_middle::ty::error::TypeError; @@ -92,11 +92,7 @@ pub trait TypeRelatingDelegate<'tcx> { info: ty::VarianceDiagInfo<'tcx>, ); - fn const_equate(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>); - fn register_opaque_type_obligations( - &mut self, - obligations: Vec<PredicateObligation<'tcx>>, - ) -> Result<(), TypeError<'tcx>>; + fn register_obligations(&mut self, obligations: Vec<PredicateObligation<'tcx>>); /// Creates a new universe index. Used when instantiating placeholders. fn create_next_universe(&mut self) -> ty::UniverseIndex; @@ -419,7 +415,7 @@ where .infcx .handle_opaque_type(a, b, true, &cause, self.delegate.param_env())? .obligations; - self.delegate.register_opaque_type_obligations(obligations)?; + self.delegate.register_obligations(obligations); trace!(a = ?a.kind(), b = ?b.kind(), "opaque type instantiated"); Ok(a) } @@ -531,6 +527,10 @@ where self.infcx.tcx } + fn intercrate(&self) -> bool { + self.infcx.intercrate + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.delegate.param_env() } @@ -543,6 +543,17 @@ where true } + fn mark_ambiguous(&mut self) { + let cause = ObligationCause::dummy_with_span(self.delegate.span()); + let param_env = self.delegate.param_env(); + self.delegate.register_obligations(vec![Obligation::new( + self.tcx(), + cause, + param_env, + ty::Binder::dummy(ty::PredicateKind::Ambiguous), + )]); + } + #[instrument(skip(self, info), level = "trace", ret)] fn relate_with_variance<T: Relate<'tcx>>( &mut self, @@ -556,8 +567,9 @@ where self.ambient_variance_info = self.ambient_variance_info.xform(info); debug!(?self.ambient_variance); - - let r = self.relate(a, b)?; + // In a bivariant context this always succeeds. + let r = + if self.ambient_variance == ty::Variance::Bivariant { a } else { self.relate(a, b)? }; self.ambient_variance = old_ambient_variance; @@ -799,8 +811,12 @@ impl<'tcx, D> ConstEquateRelation<'tcx> for TypeRelating<'_, 'tcx, D> where D: TypeRelatingDelegate<'tcx>, { - fn const_equate_obligation(&mut self, a: ty::Const<'tcx>, b: ty::Const<'tcx>) { - self.delegate.const_equate(a, b); + fn const_equate_obligation(&mut self, _a: ty::Const<'tcx>, _b: ty::Const<'tcx>) { + // We don't have to worry about the equality of consts during borrow checking + // as consts always have a static lifetime. + // FIXME(oli-obk): is this really true? We can at least have HKL and with + // inline consts we may have further lifetimes that may be unsound to treat as + // 'static. } } @@ -897,6 +913,11 @@ where self.infcx.tcx } + fn intercrate(&self) -> bool { + assert!(!self.infcx.intercrate); + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.delegate.param_env() } @@ -909,6 +930,10 @@ where true } + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, variance: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs index a982f11f718..8d3d002cb27 100644 --- a/compiler/rustc_infer/src/infer/opaque_types.rs +++ b/compiler/rustc_infer/src/infer/opaque_types.rs @@ -332,32 +332,11 @@ impl<'tcx> InferCtxt<'tcx> { concrete_ty: Ty<'tcx>, span: Span, ) { - let def_id = opaque_type_key.def_id; - - let tcx = self.tcx; - let concrete_ty = self.resolve_vars_if_possible(concrete_ty); - debug!(?concrete_ty); - let first_own_region = match self.opaque_ty_origin_unchecked(def_id, span) { - hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => { - // We lower - // - // fn foo<'l0..'ln>() -> impl Trait<'l0..'lm> - // - // into - // - // type foo::<'p0..'pn>::Foo<'q0..'qm> - // fn foo<l0..'ln>() -> foo::<'static..'static>::Foo<'l0..'lm>. - // - // For these types we only iterate over `'l0..lm` below. - tcx.generics_of(def_id).parent_count - } - // These opaque type inherit all lifetime parameters from their - // parent, so we have to check them all. - hir::OpaqueTyOrigin::TyAlias => 0, - }; + let variances = self.tcx.variances_of(opaque_type_key.def_id); + debug!(?variances); // For a case like `impl Foo<'a, 'b>`, we would generate a constraint // `'r in ['a, 'b, 'static]` for each region `'r` that appears in the @@ -370,9 +349,12 @@ impl<'tcx> InferCtxt<'tcx> { // type can be equal to any of the region parameters of the // opaque type definition. let choice_regions: Lrc<Vec<ty::Region<'tcx>>> = Lrc::new( - opaque_type_key.substs[first_own_region..] + opaque_type_key + .substs .iter() - .filter_map(|arg| match arg.unpack() { + .enumerate() + .filter(|(i, _)| variances[*i] == ty::Variance::Invariant) + .filter_map(|(_, arg)| match arg.unpack() { GenericArgKind::Lifetime(r) => Some(r), GenericArgKind::Type(_) | GenericArgKind::Const(_) => None, }) @@ -381,6 +363,7 @@ impl<'tcx> InferCtxt<'tcx> { ); concrete_ty.visit_with(&mut ConstrainOpaqueTypeRegionVisitor { + tcx: self.tcx, op: |r| self.member_constraint(opaque_type_key, span, concrete_ty, r, &choice_regions), }); } @@ -440,11 +423,12 @@ impl<'tcx> InferCtxt<'tcx> { // // We ignore any type parameters because impl trait values are assumed to // capture all the in-scope type parameters. -struct ConstrainOpaqueTypeRegionVisitor<OP> { - op: OP, +pub struct ConstrainOpaqueTypeRegionVisitor<'tcx, OP: FnMut(ty::Region<'tcx>)> { + pub tcx: TyCtxt<'tcx>, + pub op: OP, } -impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<OP> +impl<'tcx, OP> TypeVisitor<'tcx> for ConstrainOpaqueTypeRegionVisitor<'tcx, OP> where OP: FnMut(ty::Region<'tcx>), { @@ -490,6 +474,31 @@ where substs.as_generator().yield_ty().visit_with(self); substs.as_generator().resume_ty().visit_with(self); } + + ty::Opaque(def_id, ref substs) => { + // Skip lifetime paramters that are not captures. + let variances = self.tcx.variances_of(*def_id); + + for (v, s) in std::iter::zip(variances, substs.iter()) { + if *v != ty::Variance::Bivariant { + s.visit_with(self); + } + } + } + + ty::Projection(proj) + if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder => + { + // Skip lifetime paramters that are not captures. + let variances = self.tcx.variances_of(proj.item_def_id); + + for (v, s) in std::iter::zip(variances, proj.substs.iter()) { + if *v != ty::Variance::Bivariant { + s.visit_with(self); + } + } + } + _ => { ty.super_visit_with(self); } @@ -595,7 +604,12 @@ impl<'tcx> InferCtxt<'tcx> { } // Require that the predicate holds for the concrete type. debug!(?predicate); - obligations.push(traits::Obligation::new(cause.clone(), param_env, predicate)); + obligations.push(traits::Obligation::new( + self.tcx, + cause.clone(), + param_env, + predicate, + )); } Ok(InferOk { value: (), obligations }) } diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index 2d19d1823fd..8f780579451 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -29,6 +29,7 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => { Some(OutlivesBound::RegionSubRegion(r_b, r_a)) diff --git a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs index a5c21f0fb9b..5d204dd70ed 100644 --- a/compiler/rustc_infer/src/infer/outlives/test_type_match.rs +++ b/compiler/rustc_infer/src/infer/outlives/test_type_match.rs @@ -136,6 +136,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn tag(&self) -> &'static str { "Match" } + + fn intercrate(&self) -> bool { + false + } + fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -146,6 +151,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { true } // irrelevant + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_infer/src/infer/projection.rs b/compiler/rustc_infer/src/infer/projection.rs index 9f12bc972a8..eb6deee291c 100644 --- a/compiler/rustc_infer/src/infer/projection.rs +++ b/compiler/rustc_infer/src/infer/projection.rs @@ -1,5 +1,5 @@ use rustc_middle::traits::ObligationCause; -use rustc_middle::ty::{self, ToPredicate, Ty}; +use rustc_middle::ty::{self, Ty}; use crate::traits::{Obligation, PredicateObligation}; @@ -28,12 +28,8 @@ impl<'tcx> InferCtxt<'tcx> { }); let projection = ty::Binder::dummy(ty::ProjectionPredicate { projection_ty, term: ty_var.into() }); - let obligation = Obligation::with_depth( - cause, - recursion_depth, - param_env, - projection.to_predicate(self.tcx), - ); + let obligation = + Obligation::with_depth(self.tcx, cause, recursion_depth, param_env, projection); obligations.push(obligation); ty_var } diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs index 97354ba5d1b..2c6987cc3f4 100644 --- a/compiler/rustc_infer/src/infer/sub.rs +++ b/compiler/rustc_infer/src/infer/sub.rs @@ -6,7 +6,7 @@ use crate::traits::Obligation; use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation}; use rustc_middle::ty::visit::TypeVisitable; use rustc_middle::ty::TyVar; -use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt}; +use rustc_middle::ty::{self, Ty, TyCtxt}; use std::mem; /// Ensures `a` is made a subtype of `b`. Returns `a` on success. @@ -35,6 +35,11 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { fn tag(&self) -> &'static str { "Sub" } + + fn intercrate(&self) -> bool { + self.fields.infcx.intercrate + } + fn tcx(&self) -> TyCtxt<'tcx> { self.fields.infcx.tcx } @@ -47,6 +52,10 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { self.a_is_expected } + fn mark_ambiguous(&mut self) { + self.fields.mark_ambiguous() + } + fn with_cause<F, R>(&mut self, cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -95,14 +104,14 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { // can't make progress on `A <: B` if both A and B are // type variables, so record an obligation. self.fields.obligations.push(Obligation::new( + self.tcx(), self.fields.trace.cause.clone(), self.fields.param_env, ty::Binder::dummy(ty::PredicateKind::Subtype(ty::SubtypePredicate { a_is_expected: self.a_is_expected, a, b, - })) - .to_predicate(self.tcx()), + })), )); Ok(a) @@ -116,9 +125,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> { Ok(a) } - (&ty::Error(_), _) | (_, &ty::Error(_)) => { - infcx.set_tainted_by_errors(); - Ok(self.tcx().ty_error()) + (&ty::Error(e), _) | (_, &ty::Error(e)) => { + infcx.set_tainted_by_errors(e); + Ok(self.tcx().ty_error_with_guaranteed(e)) } (&ty::Opaque(a_def_id, _), &ty::Opaque(b_def_id, _)) if a_def_id == b_def_id => { diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index b2b985a22ac..54224c9b5de 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -27,7 +27,7 @@ pub trait TraitEngine<'tcx>: 'tcx { def_id: DefId, cause: ObligationCause<'tcx>, ) { - let trait_ref = ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = infcx.tcx.mk_trait_ref(def_id, [ty]); self.register_predicate_obligation( infcx, Obligation { diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index c8600ded987..a9e6241bf6b 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -10,7 +10,7 @@ pub mod util; use rustc_hir as hir; use rustc_middle::ty::error::{ExpectedFound, TypeError}; -use rustc_middle::ty::{self, Const, Ty, TyCtxt}; +use rustc_middle::ty::{self, Const, ToPredicate, Ty, TyCtxt}; use rustc_span::Span; pub use self::FulfillmentErrorCode::*; @@ -124,38 +124,41 @@ pub enum FulfillmentErrorCode<'tcx> { impl<'tcx, O> Obligation<'tcx, O> { pub fn new( + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, - predicate: O, + predicate: impl ToPredicate<'tcx, O>, ) -> Obligation<'tcx, O> { - Obligation { cause, param_env, recursion_depth: 0, predicate } + Self::with_depth(tcx, cause, 0, param_env, predicate) } pub fn with_depth( + tcx: TyCtxt<'tcx>, cause: ObligationCause<'tcx>, recursion_depth: usize, param_env: ty::ParamEnv<'tcx>, - predicate: O, + predicate: impl ToPredicate<'tcx, O>, ) -> Obligation<'tcx, O> { + let predicate = predicate.to_predicate(tcx); Obligation { cause, param_env, recursion_depth, predicate } } pub fn misc( + tcx: TyCtxt<'tcx>, span: Span, body_id: hir::HirId, param_env: ty::ParamEnv<'tcx>, - trait_ref: O, + trait_ref: impl ToPredicate<'tcx, O>, ) -> Obligation<'tcx, O> { - Obligation::new(ObligationCause::misc(span, body_id), param_env, trait_ref) + Obligation::new(tcx, ObligationCause::misc(span, body_id), param_env, trait_ref) } - pub fn with<P>(&self, value: P) -> Obligation<'tcx, P> { - Obligation { - cause: self.cause.clone(), - param_env: self.param_env, - recursion_depth: self.recursion_depth, - predicate: value, - } + pub fn with<P>( + &self, + tcx: TyCtxt<'tcx>, + value: impl ToPredicate<'tcx, P>, + ) -> Obligation<'tcx, P> { + Obligation::with_depth(tcx, self.cause.clone(), self.recursion_depth, self.param_env, value) } } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index e12c069dcc1..b2a31ac7e6f 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -285,6 +285,7 @@ impl<'tcx> Elaborator<'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { // Nothing to elaborate } + ty::PredicateKind::Ambiguous => {} } } } diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 2e526733df9..e67dec31dce 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -53,4 +53,4 @@ rustc_target = { path = "../rustc_target" } [features] llvm = ['rustc_codegen_llvm'] -rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler'] +rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler'] diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index c2d0a662ddb..ada3c3b67fb 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1659,6 +1659,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { Coerce(..) | ConstEvaluatable(..) | ConstEquate(..) | + Ambiguous | TypeWellFormedFromEnv(..) => continue, }; if predicate.is_global() { @@ -2030,10 +2031,10 @@ impl KeywordIdents { impl EarlyLintPass for KeywordIdents { fn check_mac_def(&mut self, cx: &EarlyContext<'_>, mac_def: &ast::MacroDef) { - self.check_tokens(cx, mac_def.body.inner_tokens()); + self.check_tokens(cx, mac_def.body.tokens.clone()); } fn check_mac(&mut self, cx: &EarlyContext<'_>, mac: &ast::MacCall) { - self.check_tokens(cx, mac.args.inner_tokens()); + self.check_tokens(cx, mac.args.tokens.clone()); } fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) { self.check_ident_token(cx, UnderMacro(false), ident); diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 28f6ac61c5b..589b4d6a10f 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -1159,7 +1159,7 @@ impl<'tcx> LateContext<'tcx> { fn print_dyn_existential( self, - _predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + _predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { Ok(()) } diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index aee870dd29d..a7a4d0ca527 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -159,8 +159,8 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> } fn visit_variant_data(&mut self, s: &'a ast::VariantData) { - if let Some(ctor_hir_id) = s.ctor_id() { - self.check_id(ctor_hir_id); + if let Some(ctor_node_id) = s.ctor_node_id() { + self.check_id(ctor_node_id); } ast_visit::walk_struct_def(self, s); } @@ -212,7 +212,10 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T> // Explicitly check for lints associated with 'closure_id', since // it does not have a corresponding AST node match e.kind { - ast::ExprKind::Closure(_, _, ast::Async::Yes { closure_id, .. }, ..) + ast::ExprKind::Closure(box ast::Closure { + asyncness: ast::Async::Yes { closure_id, .. }, + .. + }) | ast::ExprKind::Async(_, closure_id, ..) => self.check_id(closure_id), _ => {} } diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 6ad2e0294b9..c1820ac4d1e 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -5,7 +5,6 @@ use rustc_hir as hir; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; -use rustc_middle::ty::subst::InternalSubsts; use rustc_parse_format::{ParseMode, Parser, Piece}; use rustc_session::lint::FutureIncompatibilityReason; use rustc_span::edition::Edition; @@ -148,22 +147,22 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc ty::Ref(_, r, _) if *r.kind() == ty::Str, ) || matches!( ty.ty_adt_def(), - Some(ty_def) if cx.tcx.is_diagnostic_item(sym::String, ty_def.did()), + Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(), ); let infcx = cx.tcx.infer_ctxt().build(); let suggest_display = is_str - || cx.tcx.get_diagnostic_item(sym::Display).map(|t| { - infcx - .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) - .may_apply() - }) == Some(true); + || cx + .tcx + .get_diagnostic_item(sym::Display) + .map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()) + == Some(true); let suggest_debug = !suggest_display - && cx.tcx.get_diagnostic_item(sym::Debug).map(|t| { - infcx - .type_implements_trait(t, ty, InternalSubsts::empty(), cx.param_env) - .may_apply() - }) == Some(true); + && cx + .tcx + .get_diagnostic_item(sym::Debug) + .map(|t| infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()) + == Some(true); let suggest_panic_any = !is_str && panic == sym::std_panic_macro; diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs index 619582c0539..7e0a8a0df16 100644 --- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs +++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs @@ -108,6 +108,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound { // then we must've taken advantage of the hack in `project_and_unify_types` where // we replace opaques with inference vars. Emit a warning! if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new( + cx.tcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred, diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index ff0fb9bae92..0471890230a 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -13,6 +13,7 @@ use rustc_middle::ty::{self, DefIdTree, Ty}; use rustc_span::symbol::Symbol; use rustc_span::symbol::{kw, sym}; use rustc_span::{BytePos, Span}; +use std::iter; declare_lint! { /// The `unused_must_use` lint detects unused result of a type flagged as @@ -113,30 +114,19 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { } let ty = cx.typeck_results().expr_ty(&expr); - let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, expr.span, "", "", 1); - let mut fn_warned = false; - let mut op_warned = false; - let maybe_def_id = match expr.kind { - hir::ExprKind::Call(ref callee, _) => { - match callee.kind { - hir::ExprKind::Path(ref qpath) => { - match cx.qpath_res(qpath, callee.hir_id) { - Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => Some(def_id), - // `Res::Local` if it was a closure, for which we - // do not currently support must-use linting - _ => None, - } - } - _ => None, - } + let must_use_result = is_ty_must_use(cx, ty, &expr, expr.span); + let type_lint_emitted_or_suppressed = match must_use_result { + Some(path) => { + emit_must_use_untranslated(cx, &path, "", "", 1); + true } - hir::ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(expr.hir_id), - _ => None, + None => false, }; - if let Some(def_id) = maybe_def_id { - fn_warned = check_must_use_def(cx, def_id, expr.span, "return value of ", ""); - } else if type_permits_lack_of_use { + + let fn_warned = check_fn_must_use(cx, expr); + + if !fn_warned && type_lint_emitted_or_suppressed { // We don't warn about unused unit or uninhabited types. // (See https://github.com/rust-lang/rust/issues/43806 for details.) return; @@ -170,6 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { _ => None, }; + let mut op_warned = false; + if let Some(must_use_op) = must_use_op { cx.struct_span_lint(UNUSED_MUST_USE, expr.span, fluent::lint_unused_op, |lint| { lint.set_arg("op", must_use_op) @@ -184,110 +176,229 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { op_warned = true; } - if !(type_permits_lack_of_use || fn_warned || op_warned) { + if !(type_lint_emitted_or_suppressed || fn_warned || op_warned) { cx.struct_span_lint(UNUSED_RESULTS, s.span, fluent::lint_unused_result, |lint| { lint.set_arg("ty", ty) }); } - // Returns whether an error has been emitted (and thus another does not need to be later). - fn check_must_use_ty<'tcx>( + fn check_fn_must_use(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { + let maybe_def_id = match expr.kind { + hir::ExprKind::Call(ref callee, _) => { + match callee.kind { + hir::ExprKind::Path(ref qpath) => { + match cx.qpath_res(qpath, callee.hir_id) { + Res::Def(DefKind::Fn | DefKind::AssocFn, def_id) => Some(def_id), + // `Res::Local` if it was a closure, for which we + // do not currently support must-use linting + _ => None, + } + } + _ => None, + } + } + hir::ExprKind::MethodCall(..) => { + cx.typeck_results().type_dependent_def_id(expr.hir_id) + } + _ => None, + }; + if let Some(def_id) = maybe_def_id { + check_must_use_def(cx, def_id, expr.span, "return value of ", "") + } else { + false + } + } + + /// A path through a type to a must_use source. Contains useful info for the lint. + #[derive(Debug)] + enum MustUsePath { + /// Suppress must_use checking. + Suppressed, + /// The root of the normal must_use lint with an optional message. + Def(Span, DefId, Option<Symbol>), + Boxed(Box<Self>), + Opaque(Box<Self>), + TraitObject(Box<Self>), + TupleElement(Vec<(usize, Self)>), + Array(Box<Self>, u64), + /// The root of the unused_closures lint. + Closure(Span), + /// The root of the unused_generators lint. + Generator(Span), + } + + #[instrument(skip(cx, expr), level = "debug", ret)] + fn is_ty_must_use<'tcx>( cx: &LateContext<'tcx>, ty: Ty<'tcx>, expr: &hir::Expr<'_>, span: Span, - descr_pre: &str, - descr_post: &str, - plural_len: usize, - ) -> bool { + ) -> Option<MustUsePath> { if ty.is_unit() - || cx.tcx.is_ty_uninhabited_from( + || !ty.is_inhabited_from( + cx.tcx, cx.tcx.parent_module(expr.hir_id).to_def_id(), - ty, cx.param_env, ) { - return true; + return Some(MustUsePath::Suppressed); } - let plural_suffix = pluralize!(plural_len); - match *ty.kind() { ty::Adt(..) if ty.is_box() => { let boxed_ty = ty.boxed_ty(); - let descr_pre = &format!("{}boxed ", descr_pre); - check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len) + is_ty_must_use(cx, boxed_ty, expr, span) + .map(|inner| MustUsePath::Boxed(Box::new(inner))) } - ty::Adt(def, _) => check_must_use_def(cx, def.did(), span, descr_pre, descr_post), + ty::Adt(def, _) => is_def_must_use(cx, def.did(), span), ty::Opaque(def, _) => { - let mut has_emitted = false; - for obligation in elaborate_predicates_with_span( + elaborate_predicates_with_span( cx.tcx, cx.tcx.explicit_item_bounds(def).iter().cloned(), - ) { + ) + .filter_map(|obligation| { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Trait(ref poly_trait_predicate) = obligation.predicate.kind().skip_binder() { let def_id = poly_trait_predicate.trait_ref.def_id; - let descr_pre = - &format!("{}implementer{} of ", descr_pre, plural_suffix,); - if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { - has_emitted = true; - break; - } + + is_def_must_use(cx, def_id, span) + } else { + None } - } - has_emitted + }) + .map(|inner| MustUsePath::Opaque(Box::new(inner))) + .next() } - ty::Dynamic(binder, _, _) => { - let mut has_emitted = false; - for predicate in binder.iter() { + ty::Dynamic(binders, _, _) => binders + .iter() + .filter_map(|predicate| { if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() { let def_id = trait_ref.def_id; - let descr_post = - &format!(" trait object{}{}", plural_suffix, descr_post,); - if check_must_use_def(cx, def_id, span, descr_pre, descr_post) { - has_emitted = true; - break; - } + is_def_must_use(cx, def_id, span) + } else { + None } - } - has_emitted - } - ty::Tuple(ref tys) => { - let mut has_emitted = false; - let comps = if let hir::ExprKind::Tup(comps) = expr.kind { - debug_assert_eq!(comps.len(), tys.len()); - comps + .map(|inner| MustUsePath::TraitObject(Box::new(inner))) + }) + .next(), + ty::Tuple(tys) => { + let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind { + debug_assert_eq!(elem_exprs.len(), tys.len()); + elem_exprs } else { &[] }; - for (i, ty) in tys.iter().enumerate() { - let descr_post = &format!(" in tuple element {}", i); - let e = comps.get(i).unwrap_or(expr); - let span = e.span; - if check_must_use_ty(cx, ty, e, span, descr_pre, descr_post, plural_len) { - has_emitted = true; - } + + // Default to `expr`. + let elem_exprs = elem_exprs.iter().chain(iter::repeat(expr)); + + let nested_must_use = tys + .iter() + .zip(elem_exprs) + .enumerate() + .filter_map(|(i, (ty, expr))| { + is_ty_must_use(cx, ty, expr, expr.span).map(|path| (i, path)) + }) + .collect::<Vec<_>>(); + + if !nested_must_use.is_empty() { + Some(MustUsePath::TupleElement(nested_must_use)) + } else { + None } - has_emitted } ty::Array(ty, len) => match len.try_eval_usize(cx.tcx, cx.param_env) { // If the array is empty we don't lint, to avoid false positives - Some(0) | None => false, + Some(0) | None => None, // If the array is definitely non-empty, we can do `#[must_use]` checking. - Some(n) => { - let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix,); - check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1) - } + Some(len) => is_ty_must_use(cx, ty, expr, span) + .map(|inner| MustUsePath::Array(Box::new(inner), len)), }, - ty::Closure(..) => { + ty::Closure(..) => Some(MustUsePath::Closure(span)), + ty::Generator(..) => Some(MustUsePath::Generator(span)), + _ => None, + } + } + + fn is_def_must_use(cx: &LateContext<'_>, def_id: DefId, span: Span) -> Option<MustUsePath> { + if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) { + // check for #[must_use = "..."] + let reason = attr.value_str(); + Some(MustUsePath::Def(span, def_id, reason)) + } else { + None + } + } + + // Returns whether further errors should be suppressed because either a lint has been emitted or the type should be ignored. + fn check_must_use_def( + cx: &LateContext<'_>, + def_id: DefId, + span: Span, + descr_pre_path: &str, + descr_post_path: &str, + ) -> bool { + is_def_must_use(cx, def_id, span) + .map(|must_use_path| { + emit_must_use_untranslated( + cx, + &must_use_path, + descr_pre_path, + descr_post_path, + 1, + ) + }) + .is_some() + } + + #[instrument(skip(cx), level = "debug")] + fn emit_must_use_untranslated( + cx: &LateContext<'_>, + path: &MustUsePath, + descr_pre: &str, + descr_post: &str, + plural_len: usize, + ) { + let plural_suffix = pluralize!(plural_len); + + match path { + MustUsePath::Suppressed => {} + MustUsePath::Boxed(path) => { + let descr_pre = &format!("{}boxed ", descr_pre); + emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len); + } + MustUsePath::Opaque(path) => { + let descr_pre = &format!("{}implementer{} of ", descr_pre, plural_suffix); + emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len); + } + MustUsePath::TraitObject(path) => { + let descr_post = &format!(" trait object{}{}", plural_suffix, descr_post); + emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len); + } + MustUsePath::TupleElement(elems) => { + for (index, path) in elems { + let descr_post = &format!(" in tuple element {}", index); + emit_must_use_untranslated(cx, path, descr_pre, descr_post, plural_len); + } + } + MustUsePath::Array(path, len) => { + let descr_pre = &format!("{}array{} of ", descr_pre, plural_suffix); + emit_must_use_untranslated( + cx, + path, + descr_pre, + descr_post, + plural_len.saturating_add(usize::try_from(*len).unwrap_or(usize::MAX)), + ); + } + MustUsePath::Closure(span) => { cx.struct_span_lint( UNUSED_MUST_USE, - span, + *span, fluent::lint_unused_closure, |lint| { // FIXME(davidtwco): this isn't properly translatable because of the @@ -298,12 +409,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { .note(fluent::note) }, ); - true } - ty::Generator(..) => { + MustUsePath::Generator(span) => { cx.struct_span_lint( UNUSED_MUST_USE, - span, + *span, fluent::lint_unused_generator, |lint| { // FIXME(davidtwco): this isn't properly translatable because of the @@ -314,40 +424,20 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { .note(fluent::note) }, ); - true } - _ => false, - } - } - - // Returns whether an error has been emitted (and thus another does not need to be later). - // FIXME: Args desc_{pre,post}_path could be made lazy by taking Fn() -> &str, but this - // would make calling it a big awkward. Could also take String (so args are moved), but - // this would still require a copy into the format string, which would only be executed - // when needed. - fn check_must_use_def( - cx: &LateContext<'_>, - def_id: DefId, - span: Span, - descr_pre_path: &str, - descr_post_path: &str, - ) -> bool { - if let Some(attr) = cx.tcx.get_attr(def_id, sym::must_use) { - cx.struct_span_lint(UNUSED_MUST_USE, span, fluent::lint_unused_def, |lint| { - // FIXME(davidtwco): this isn't properly translatable because of the pre/post - // strings - lint.set_arg("pre", descr_pre_path); - lint.set_arg("post", descr_post_path); - lint.set_arg("def", cx.tcx.def_path_str(def_id)); - // check for #[must_use = "..."] - if let Some(note) = attr.value_str() { - lint.note(note.as_str()); - } - lint - }); - true - } else { - false + MustUsePath::Def(span, def_id, reason) => { + cx.struct_span_lint(UNUSED_MUST_USE, *span, fluent::lint_unused_def, |lint| { + // FIXME(davidtwco): this isn't properly translatable because of the pre/post + // strings + lint.set_arg("pre", descr_pre); + lint.set_arg("post", descr_post); + lint.set_arg("def", cx.tcx.def_path_str(*def_id)); + if let Some(note) = reason { + lint.note(note.as_str()); + } + lint + }); + } } } } @@ -533,16 +623,14 @@ trait UnusedDelimLint { right_pos: Option<BytePos>, ) { let spans = match value.kind { - ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => { - let start = block.stmts[0].span; - let end = block.stmts[block.stmts.len() - 1].span; - if let Some(start) = start.find_ancestor_inside(value.span) - && let Some(end) = end.find_ancestor_inside(value.span) + ast::ExprKind::Block(ref block, None) if block.stmts.len() == 1 => { + if let StmtKind::Expr(expr) = &block.stmts[0].kind + && let ExprKind::Err = expr.kind { - Some(( - value.span.with_hi(start.lo()), - value.span.with_lo(end.hi()), - )) + return + } + if let Some(span) = block.stmts[0].span.find_ancestor_inside(value.span) { + Some((value.span.with_hi(span.lo()), value.span.with_lo(span.hi()))) } else { None } @@ -584,7 +672,7 @@ trait UnusedDelimLint { let sm = cx.sess().source_map(); let lo_replace = if keep_space.0 && - let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(" ") { + let Ok(snip) = sm.span_to_prev_source(lo) && !snip.ends_with(' ') { " ".to_string() } else { "".to_string() @@ -592,7 +680,7 @@ trait UnusedDelimLint { let hi_replace = if keep_space.1 && - let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(" ") { + let Ok(snip) = sm.span_to_next_source(hi) && !snip.starts_with(' ') { " ".to_string() } else { "".to_string() @@ -653,7 +741,7 @@ trait UnusedDelimLint { ref call_or_other => { let (args_to_check, ctx) = match *call_or_other { Call(_, ref args) => (&args[..], UnusedDelimsCtx::FunctionArg), - MethodCall(_, _, ref args, _) => (&args[..], UnusedDelimsCtx::MethodArg), + MethodCall(ref call) => (&call.args[..], UnusedDelimsCtx::MethodArg), // actual catch-all arm _ => { return; diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index 6f8bb676104..216c35d6da0 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1036,8 +1036,9 @@ extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd( extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerator( LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen, - int64_t Value, bool IsUnsigned) { - return wrap(Builder->createEnumerator(StringRef(Name, NameLen), Value, IsUnsigned)); + const uint64_t Value[2], unsigned SizeInBits, bool IsUnsigned) { + return wrap(Builder->createEnumerator(StringRef(Name, NameLen), + APSInt(APInt(SizeInBits, makeArrayRef(Value, 2)), IsUnsigned))); } extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType( diff --git a/compiler/rustc_log/Cargo.toml b/compiler/rustc_log/Cargo.toml index 1b2cde60555..3c50827c1ab 100644 --- a/compiler/rustc_log/Cargo.toml +++ b/compiler/rustc_log/Cargo.toml @@ -4,7 +4,6 @@ version = "0.0.0" edition = "2021" [dependencies] -atty = "0.2" tracing = "0.1.28" tracing-subscriber = { version = "0.3.3", default-features = false, features = ["fmt", "env-filter", "smallvec", "parking_lot", "ansi"] } tracing-tree = "0.2.0" diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs index 458f5e87bae..ddf29c488c9 100644 --- a/compiler/rustc_log/src/lib.rs +++ b/compiler/rustc_log/src/lib.rs @@ -40,10 +40,11 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] +#![feature(is_terminal)] use std::env::{self, VarError}; use std::fmt::{self, Display}; -use std::io; +use std::io::{self, IsTerminal}; use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter}; use tracing_subscriber::layer::SubscriberExt; @@ -93,11 +94,11 @@ pub fn init_env_logger(env: &str) -> Result<(), Error> { } pub fn stdout_isatty() -> bool { - atty::is(atty::Stream::Stdout) + io::stdout().is_terminal() } pub fn stderr_isatty() -> bool { - atty::is(atty::Stream::Stderr) + io::stderr().is_terminal() } #[derive(Debug)] diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index ab38a9ccc8f..be9821c00f5 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -5,6 +5,7 @@ use crate::diagnostics::error::{span_err, DiagnosticDeriveError}; use crate::diagnostics::utils::SetOnce; use proc_macro2::TokenStream; use quote::quote; +use syn::spanned::Spanned; use synstructure::Structure; /// The central struct for constructing the `into_diagnostic` method from an annotated struct. @@ -45,6 +46,17 @@ impl<'a> DiagnosticDerive<'a> { .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } + Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(&format!( + "slug is `{slug_name}` but the crate name is `{crate_name}`" + )) + .help(&format!( + "expected a slug starting with `{slug_prefix}_...`" + )) + .emit(); + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + } Some(slug) => { quote! { let mut #diag = #handler.struct_diagnostic(rustc_errors::fluent::#slug); @@ -128,7 +140,22 @@ impl<'a> LintDiagnosticDerive<'a> { .emit(); return DiagnosticDeriveError::ErrorHandled.to_compile_error(); } - Some(slug) => quote! { rustc_errors::fluent::#slug.into() }, + Some(slug) if let Some( Mismatch { slug_name, crate_name, slug_prefix }) = Mismatch::check(slug) => { + span_err(slug.span().unwrap(), "diagnostic slug and crate name do not match") + .note(&format!( + "slug is `{slug_name}` but the crate name is `{crate_name}`" + )) + .help(&format!( + "expected a slug starting with `{slug_prefix}_...`" + )) + .emit(); + return DiagnosticDeriveError::ErrorHandled.to_compile_error(); + } + Some(slug) => { + quote! { + rustc_errors::fluent::#slug.into() + } + } } }); @@ -151,3 +178,27 @@ impl<'a> LintDiagnosticDerive<'a> { }) } } + +struct Mismatch { + slug_name: String, + crate_name: String, + slug_prefix: String, +} + +impl Mismatch { + /// Checks whether the slug starts with the crate name it's in. + fn check(slug: &syn::Path) -> Option<Mismatch> { + // If this is missing we're probably in a test, so bail. + let crate_name = std::env::var("CARGO_CRATE_NAME").ok()?; + + // If we're not in a "rustc_" crate, bail. + let Some(("rustc", slug_prefix)) = crate_name.split_once("_") else { return None }; + + let slug_name = slug.segments.first()?.ident.to_string(); + if !slug_name.starts_with(slug_prefix) { + Some(Mismatch { slug_name, slug_prefix: slug_prefix.to_string(), crate_name }) + } else { + None + } + } +} diff --git a/compiler/rustc_macros/src/diagnostics/utils.rs b/compiler/rustc_macros/src/diagnostics/utils.rs index ba06f61299f..dff088b9bdf 100644 --- a/compiler/rustc_macros/src/diagnostics/utils.rs +++ b/compiler/rustc_macros/src/diagnostics/utils.rs @@ -830,5 +830,5 @@ pub(super) fn should_generate_set_arg(field: &Field) -> bool { } pub(super) fn is_doc_comment(attr: &Attribute) -> bool { - attr.path.segments.last().unwrap().ident.to_string() == "doc" + attr.path.segments.last().unwrap().ident == "doc" } diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs index 36bda3e0f6b..a2a01b66690 100644 --- a/compiler/rustc_macros/src/lib.rs +++ b/compiler/rustc_macros/src/lib.rs @@ -1,4 +1,5 @@ #![feature(allow_internal_unstable)] +#![feature(if_let_guard)] #![feature(never_type)] #![feature(proc_macro_diagnostic)] #![feature(proc_macro_span)] diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index e5b91d566e5..6f7e6e09ca5 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -692,6 +692,7 @@ pub struct CrateLocationUnknownType<'a> { #[primary_span] pub span: Span, pub path: &'a Path, + pub crate_name: Symbol, } #[derive(Diagnostic)] diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs index 35f9ef92a1c..15546092e41 100644 --- a/compiler/rustc_metadata/src/locator.rs +++ b/compiler/rustc_metadata/src/locator.rs @@ -707,6 +707,12 @@ impl<'a> CrateLocator<'a> { loc.original().clone(), )); } + if !loc.original().is_file() { + return Err(CrateError::ExternLocationNotFile( + self.crate_name, + loc.original().clone(), + )); + } let Some(file) = loc.original().file_name().and_then(|s| s.to_str()) else { return Err(CrateError::ExternLocationNotFile( self.crate_name, @@ -1020,11 +1026,10 @@ impl CrateError { None => String::new(), Some(r) => format!(" which `{}` depends on", r.name), }; - // FIXME: There are no tests for CrateLocationUnknownType or LibFilenameForm if !locator.crate_rejections.via_filename.is_empty() { let mismatches = locator.crate_rejections.via_filename.iter(); for CrateMismatch { path, .. } in mismatches { - sess.emit_err(CrateLocationUnknownType { span, path: &path }); + sess.emit_err(CrateLocationUnknownType { span, path: &path, crate_name }); sess.emit_err(LibFilenameForm { span, dll_prefix: &locator.dll_prefix, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 8e80d794a13..ac4b5126190 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -11,7 +11,7 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro}; -use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; +use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; use rustc_hir::diagnostic_items::DiagnosticItems; @@ -31,7 +31,7 @@ use rustc_session::cstore::{ use rustc_session::Session; use rustc_span::hygiene::{ExpnIndex, MacroKind}; use rustc_span::source_map::{respan, Spanned}; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_span::{self, BytePos, ExpnId, Pos, Span, SyntaxContext, DUMMY_SP}; use proc_macro::bridge::client::ProcMacro; @@ -866,12 +866,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let variant_did = if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None }; - let ctor_did = data.ctor.map(|index| self.local_def_id(index)); + let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index))); ty::VariantDef::new( self.item_name(index), variant_did, - ctor_did, + ctor, data.discr, self.root .tables @@ -885,7 +885,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { vis: self.get_visibility(index), }) .collect(), - data.ctor_kind, adt_kind, parent_did, false, @@ -1041,29 +1040,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }; callback(ModChild { ident, res, vis, span, macro_rules }); - - // For non-reexport variants add their fictive constructors to children. - // Braced variants, unlike structs, generate unusable names in value namespace, - // they are reserved for possible future use. It's ok to use the variant's id as - // a ctor id since an error will be reported on any use of such resolution anyway. - // Reexport lists automatically contain such constructors when necessary. - if kind == DefKind::Variant && self.get_ctor_def_id_and_kind(child_index).is_none() - { - let ctor_res = - Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fictive), def_id); - let mut vis = vis; - if vis.is_public() { - // For non-exhaustive variants lower the constructor visibility to - // within the crate. We only need this for fictive constructors, - // for other constructors correct visibilities - // were already encoded in metadata. - let mut attrs = self.get_item_attrs(def_id.index, sess); - if attrs.any(|item| item.has_name(sym::non_exhaustive)) { - vis = ty::Visibility::Restricted(self.local_def_id(CRATE_DEF_INDEX)); - } - } - callback(ModChild { ident, res: ctor_res, vis, span, macro_rules: false }); - } } } @@ -1136,11 +1112,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> { + fn get_ctor(self, node_id: DefIndex) -> Option<(CtorKind, DefId)> { match self.def_kind(node_id) { DefKind::Struct | DefKind::Variant => { let vdata = self.root.tables.variant_data.get(self, node_id).unwrap().decode(self); - vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind)) + vdata.ctor.map(|(kind, index)| (kind, self.local_def_id(index))) } _ => None, } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index f475b0b3981..d96252ba569 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -495,8 +495,8 @@ impl CStore { self.get_crate_data(def.krate).get_struct_field_visibilities(def.index) } - pub fn ctor_def_id_and_kind_untracked(&self, def: DefId) -> Option<(DefId, CtorKind)> { - self.get_crate_data(def.krate).get_ctor_def_id_and_kind(def.index) + pub fn ctor_untracked(&self, def: DefId) -> Option<(CtorKind, DefId)> { + self.get_crate_data(def.krate).get_ctor(def.index) } pub fn visibility_untracked(&self, def: DefId) -> Visibility<DefId> { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index e09ac968b60..af4be12fe3a 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -928,6 +928,8 @@ fn should_encode_variances(def_kind: DefKind) -> bool { | DefKind::Union | DefKind::Enum | DefKind::Variant + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder | DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn => true, @@ -941,8 +943,6 @@ fn should_encode_variances(def_kind: DefKind) -> bool { | DefKind::Const | DefKind::ForeignMod | DefKind::TyAlias - | DefKind::OpaqueTy - | DefKind::ImplTraitPlaceholder | DefKind::Impl | DefKind::Trait | DefKind::TraitAlias @@ -1221,9 +1221,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_enum_variant_info({:?})", def_id); let data = VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: variant.ctor_def_id.map(|did| did.index), + ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; @@ -1233,32 +1232,28 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { assert!(f.did.is_local()); f.did.index })); - if variant.ctor_kind == CtorKind::Fn { + if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor { // FIXME(eddyb) encode signature only in `encode_enum_variant_ctor`. - if let Some(ctor_def_id) = variant.ctor_def_id { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); - } + record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(ctor_def_id)); } } fn encode_enum_variant_ctor(&mut self, def: ty::AdtDef<'tcx>, index: VariantIdx) { - let tcx = self.tcx; let variant = &def.variant(index); - let def_id = variant.ctor_def_id.unwrap(); + let Some((ctor_kind, def_id)) = variant.ctor else { return }; debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id); // FIXME(eddyb) encode only the `CtorKind` for constructors. let data = VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: Some(def_id.index), + ctor: Some((ctor_kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; record!(self.tables.variant_data[def_id] <- data); self.tables.constness.set(def_id.index, hir::Constness::Const); - if variant.ctor_kind == CtorKind::Fn { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + if ctor_kind == CtorKind::Fn { + record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id)); } } @@ -1313,23 +1308,22 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } - fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>, def_id: DefId) { - debug!("EncodeContext::encode_struct_ctor({:?})", def_id); - let tcx = self.tcx; + fn encode_struct_ctor(&mut self, adt_def: ty::AdtDef<'tcx>) { let variant = adt_def.non_enum_variant(); + let Some((ctor_kind, def_id)) = variant.ctor else { return }; + debug!("EncodeContext::encode_struct_ctor({:?})", def_id); let data = VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: Some(def_id.index), + ctor: Some((ctor_kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; record!(self.tables.repr_options[def_id] <- adt_def.repr()); record!(self.tables.variant_data[def_id] <- data); self.tables.constness.set(def_id.index, hir::Constness::Const); - if variant.ctor_kind == CtorKind::Fn { - record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); + if ctor_kind == CtorKind::Fn { + record!(self.tables.fn_sig[def_id] <- self.tcx.fn_sig(def_id)); } } @@ -1550,21 +1544,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let adt_def = self.tcx.adt_def(def_id); record!(self.tables.repr_options[def_id] <- adt_def.repr()); } - hir::ItemKind::Struct(ref struct_def, _) => { + hir::ItemKind::Struct(..) => { let adt_def = self.tcx.adt_def(def_id); record!(self.tables.repr_options[def_id] <- adt_def.repr()); self.tables.constness.set(def_id.index, hir::Constness::Const); - // Encode def_ids for each field and method - // for methods, write all the stuff get_trait_method - // needs to know - let ctor = struct_def.ctor_def_id().map(|ctor_def_id| ctor_def_id.local_def_index); - let variant = adt_def.non_enum_variant(); record!(self.tables.variant_data[def_id] <- VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor, + ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }); } @@ -1574,9 +1562,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let variant = adt_def.non_enum_variant(); record!(self.tables.variant_data[def_id] <- VariantData { - ctor_kind: variant.ctor_kind, discr: variant.discr, - ctor: None, + ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)), is_non_exhaustive: variant.is_field_list_non_exhaustive(), }); } @@ -1629,7 +1616,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for variant in tcx.adt_def(def_id).variants() { yield variant.def_id.index; // Encode constructors which take a separate slot in value namespace. - if let Some(ctor_def_id) = variant.ctor_def_id { + if let Some(ctor_def_id) = variant.ctor_def_id() { yield ctor_def_id.index; } } @@ -1672,20 +1659,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { match item.kind { hir::ItemKind::Enum(..) => { let def = self.tcx.adt_def(item.owner_id.to_def_id()); - for (i, variant) in def.variants().iter_enumerated() { + for (i, _) in def.variants().iter_enumerated() { self.encode_enum_variant_info(def, i); - - if let Some(_ctor_def_id) = variant.ctor_def_id { - self.encode_enum_variant_ctor(def, i); - } + self.encode_enum_variant_ctor(def, i); } } - hir::ItemKind::Struct(ref struct_def, _) => { + hir::ItemKind::Struct(..) => { let def = self.tcx.adt_def(item.owner_id.to_def_id()); - // If the struct has a constructor, encode it. - if let Some(ctor_def_id) = struct_def.ctor_def_id() { - self.encode_struct_ctor(def, ctor_def_id.to_def_id()); - } + self.encode_struct_ctor(def); } hir::ItemKind::Impl { .. } => { for &trait_item_def_id in diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index aa6d378a43a..3e0b5fa6dd9 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -400,7 +400,7 @@ define_tables! { assoc_container: Table<DefIndex, ty::AssocItemContainer>, // Slot is full when macro is macro_rules. macro_rules: Table<DefIndex, ()>, - macro_definition: Table<DefIndex, LazyValue<ast::MacArgs>>, + macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>, proc_macro: Table<DefIndex, MacroKind>, module_reexports: Table<DefIndex, LazyArray<ModChild>>, deduced_param_attrs: Table<DefIndex, LazyArray<DeducedParamAttrs>>, @@ -410,10 +410,9 @@ define_tables! { #[derive(TyEncodable, TyDecodable)] struct VariantData { - ctor_kind: CtorKind, discr: ty::VariantDiscr, /// If this is unit or tuple-variant/struct, then this is the index of the ctor id. - ctor: Option<DefIndex>, + ctor: Option<(CtorKind, DefIndex)>, is_non_exhaustive: bool, } diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index e7c1abd126e..29fe6110797 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -101,10 +101,8 @@ fixed_size_enum! { ( Static(ast::Mutability::Mut) ) ( Ctor(CtorOf::Struct, CtorKind::Fn) ) ( Ctor(CtorOf::Struct, CtorKind::Const) ) - ( Ctor(CtorOf::Struct, CtorKind::Fictive) ) ( Ctor(CtorOf::Variant, CtorKind::Fn) ) ( Ctor(CtorOf::Variant, CtorKind::Const) ) - ( Ctor(CtorOf::Variant, CtorKind::Fictive) ) ( Macro(MacroKind::Bang) ) ( Macro(MacroKind::Attr) ) ( Macro(MacroKind::Derive) ) diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 5f6e498dbea..fc1167c105a 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -4,7 +4,6 @@ version = "0.0.0" edition = "2021" [lib] -doctest = false [dependencies] bitflags = "1.2.1" diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 43903e6739f..5e94da8cb4d 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -64,3 +64,11 @@ pub(crate) struct StrictCoherenceNeedsNegativeCoherence { #[label] pub attr_span: Option<Span>, } + +#[derive(Diagnostic)] +#[diag(middle_const_not_used_in_type_alias)] +pub(super) struct ConstNotUsedTraitAlias { + pub ct: String, + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e14ea7be9cf..d4456adf201 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -245,15 +245,15 @@ impl<'hir> Map<'hir> { }, Node::Variant(_) => DefKind::Variant, Node::Ctor(variant_data) => { - // FIXME(eddyb) is this even possible, if we have a `Node::Ctor`? - assert_ne!(variant_data.ctor_hir_id(), None); - let ctor_of = match self.find(self.get_parent_node(hir_id)) { Some(Node::Item(..)) => def::CtorOf::Struct, Some(Node::Variant(..)) => def::CtorOf::Variant, _ => unreachable!(), }; - DefKind::Ctor(ctor_of, def::CtorKind::from_hir(variant_data)) + match variant_data.ctor_kind() { + Some(kind) => DefKind::Ctor(ctor_of, kind), + None => bug!("constructor node without a constructor"), + } } Node::AnonConst(_) => { let inline = match self.find(self.get_parent_node(hir_id)) { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 68024070346..f8a69f3c7d5 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -11,6 +11,8 @@ use std::hash; use std::ops::Range; use std::ptr; +use either::{Left, Right}; + use rustc_ast::Mutability; use rustc_data_structures::intern::Interned; use rustc_span::DUMMY_SP; @@ -503,11 +505,11 @@ impl<Prov: Provenance, Extra> Allocation<Prov, Extra> { // `to_bits_or_ptr_internal` is the right method because we just want to store this data // as-is into memory. let (bytes, provenance) = match val.to_bits_or_ptr_internal(range.size)? { - Err(val) => { - let (provenance, offset) = val.into_parts(); + Right(ptr) => { + let (provenance, offset) = ptr.into_parts(); (u128::from(offset.bytes()), Some(provenance)) } - Ok(data) => (data, None), + Left(data) => (data, None), }; let endian = cx.data_layout().endian; diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index ae0dbad8b08..bd9cd53e115 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -144,7 +144,7 @@ impl fmt::Display for InvalidProgramInfo<'_> { AlreadyReported(ErrorGuaranteed { .. }) => { write!( f, - "an error has already been reported elsewhere (this sould not usually be printed)" + "an error has already been reported elsewhere (this should not usually be printed)" ) } Layout(ref err) => write!(f, "{err}"), diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs index ac5fddb7ad1..770c3ed05e8 100644 --- a/compiler/rustc_middle/src/mir/interpret/value.rs +++ b/compiler/rustc_middle/src/mir/interpret/value.rs @@ -1,6 +1,8 @@ use std::convert::{TryFrom, TryInto}; use std::fmt; +use either::{Either, Left, Right}; + use rustc_apfloat::{ ieee::{Double, Single}, Float, @@ -293,10 +295,10 @@ impl<Prov> Scalar<Prov> { pub fn to_bits_or_ptr_internal( self, target_size: Size, - ) -> Result<Result<u128, Pointer<Prov>>, ScalarSizeMismatch> { + ) -> Result<Either<u128, Pointer<Prov>>, ScalarSizeMismatch> { assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST"); Ok(match self { - Scalar::Int(int) => Ok(int.to_bits(target_size).map_err(|size| { + Scalar::Int(int) => Left(int.to_bits(target_size).map_err(|size| { ScalarSizeMismatch { target_size: target_size.bytes(), data_size: size.bytes() } })?), Scalar::Ptr(ptr, sz) => { @@ -306,7 +308,7 @@ impl<Prov> Scalar<Prov> { data_size: sz.into(), }); } - Err(ptr) + Right(ptr) } }) } @@ -318,8 +320,8 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> { .to_bits_or_ptr_internal(cx.pointer_size()) .map_err(|s| err_ub!(ScalarSizeMismatch(s)))? { - Err(ptr) => Ok(ptr.into()), - Ok(bits) => { + Right(ptr) => Ok(ptr.into()), + Left(bits) => { let addr = u64::try_from(bits).unwrap(); Ok(Pointer::from_addr(addr)) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index e0a786e201a..364c1b375ae 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1884,7 +1884,7 @@ impl<'tcx> Operand<'tcx> { substs: SubstsRef<'tcx>, span: Span, ) -> Self { - let ty = tcx.bound_type_of(def_id).subst(tcx, substs); + let ty = tcx.mk_fn_def(def_id, substs); Operand::Constant(Box::new(Constant { span, user_ty: None, @@ -2115,10 +2115,10 @@ impl<'tcx> Debug for Rvalue<'tcx> { .print_def_path(variant_def.def_id, substs)? .into_buffer(); - match variant_def.ctor_kind { - CtorKind::Const => fmt.write_str(&name), - CtorKind::Fn => fmt_tuple(fmt, &name), - CtorKind::Fictive => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => fmt.write_str(&name), + Some(CtorKind::Fn) => fmt_tuple(fmt, &name), + None => { let mut struct_fmt = fmt.debug_struct(&name); for (field, place) in iter::zip(&variant_def.fields, places) { struct_fmt.field(field.name.as_str(), place); @@ -2955,14 +2955,14 @@ fn pretty_print_const_value<'tcx>( let cx = cx.print_value_path(variant_def.def_id, substs)?; fmt.write_str(&cx.into_buffer())?; - match variant_def.ctor_kind { - CtorKind::Const => {} - CtorKind::Fn => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => {} + Some(CtorKind::Fn) => { fmt.write_str("(")?; comma_sep(fmt, fields)?; fmt.write_str(")")?; } - CtorKind::Fictive => { + None => { fmt.write_str(" {{ ")?; let mut first = true; for (field_def, field) in iter::zip(&variant_def.fields, fields) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1564cf414bd..21097b1fec6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1648,6 +1648,8 @@ rustc_queries! { /// a generic type parameter will panic if you call this method on it: /// /// ``` + /// use std::fmt::Debug; + /// /// pub trait Foo<T: Debug> {} /// ``` /// @@ -2076,17 +2078,6 @@ rustc_queries! { desc { "normalizing opaque types in `{:?}`", key } } - /// Checks whether a type is definitely uninhabited. This is - /// conservative: for some types that are uninhabited we return `false`, - /// but we only return `true` for types that are definitely uninhabited. - /// `ty.conservative_is_privately_uninhabited` implies that any value of type `ty` - /// will be `Abi::Uninhabited`. (Note that uninhabited types may have nonzero - /// size, to account for partial initialisation. See #49298 for details.) - query conservative_is_privately_uninhabited(key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> bool { - desc { "conservatively checking if `{}` is privately uninhabited", key.value } - remap_env_constness - } - query limits(key: ()) -> Limits { desc { "looking up limits" } } diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index ea7a507d7a4..8bef9dfe099 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -10,7 +10,6 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir as hir; -use rustc_hir::def::CtorKind; use rustc_hir::def_id::DefId; use rustc_hir::RangeEnd; use rustc_index::newtype_index; @@ -751,7 +750,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { // Only for Adt we can have `S {...}`, // which we handle separately here. - if variant.ctor_kind == CtorKind::Fictive { + if variant.ctor.is_none() { write!(f, " {{ ")?; let mut printed = 0; diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 05382bd887c..1890c0e24bb 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -924,10 +924,13 @@ impl ObjectSafetyViolation { } ObjectSafetyViolation::Method( name, - MethodViolationCode::ReferencesImplTraitInTrait, + MethodViolationCode::ReferencesImplTraitInTrait(_), _, ) => format!("method `{}` references an `impl Trait` type in its return type", name) .into(), + ObjectSafetyViolation::Method(name, MethodViolationCode::AsyncFn, _) => { + format!("method `{}` is `async`", name).into() + } ObjectSafetyViolation::Method( name, MethodViolationCode::WhereClauseReferencesSelf, @@ -1035,7 +1038,10 @@ pub enum MethodViolationCode { ReferencesSelfOutput, /// e.g., `fn foo(&self) -> impl Sized` - ReferencesImplTraitInTrait, + ReferencesImplTraitInTrait(Span), + + /// e.g., `async fn foo(&self)` + AsyncFn, /// e.g., `fn foo(&self) where Self: Clone` WhereClauseReferencesSelf, diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs index e6aab30a150..cd147d7e558 100644 --- a/compiler/rustc_middle/src/ty/_match.rs +++ b/compiler/rustc_middle/src/ty/_match.rs @@ -36,6 +36,11 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } + + fn intercrate(&self) -> bool { + false + } + fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env } @@ -43,6 +48,10 @@ impl<'tcx> TypeRelation<'tcx> for Match<'tcx> { true } // irrelevant + fn mark_ambiguous(&mut self) { + bug!() + } + fn relate_with_variance<T: Relate<'tcx>>( &mut self, _: ty::Variance, diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 4682ac96b52..b8e6f0258d0 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -1,7 +1,5 @@ -use crate::ty::subst::SubstsRef; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_macros::HashStable; use rustc_span::Span; @@ -121,7 +119,8 @@ pub struct OverloadedDeref<'tcx> { } impl<'tcx> OverloadedDeref<'tcx> { - pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> (DefId, SubstsRef<'tcx>) { + /// Get the zst function item type for this method call. + pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> { let trait_def_id = match self.mutbl { hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None), hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None), @@ -132,7 +131,7 @@ impl<'tcx> OverloadedDeref<'tcx> { .find(|m| m.kind == ty::AssocKind::Fn) .unwrap() .def_id; - (method_def_id, tcx.mk_substs_trait(source, &[])) + tcx.mk_fn_def(method_def_id, tcx.mk_substs_trait(source, [])) } } diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 137b59cf6c2..6b6aa40a160 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -230,7 +230,7 @@ impl AdtDefData { AdtKind::Struct => AdtFlags::IS_STRUCT, }; - if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor_def_id.is_some() { + if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor.is_some() { flags |= AdtFlags::HAS_CTOR; } @@ -386,11 +386,9 @@ impl<'tcx> AdtDef<'tcx> { // Baz = 3, // } // ``` - if self - .variants() - .iter() - .any(|v| matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind != CtorKind::Const) - { + if self.variants().iter().any(|v| { + matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind() != Some(CtorKind::Const) + }) { return false; } self.variants().iter().all(|v| v.fields.is_empty()) @@ -405,7 +403,7 @@ impl<'tcx> AdtDef<'tcx> { pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef { self.variants() .iter() - .find(|v| v.ctor_def_id == Some(cid)) + .find(|v| v.ctor_def_id() == Some(cid)) .expect("variant_with_ctor_id: unknown variant") } @@ -422,7 +420,7 @@ impl<'tcx> AdtDef<'tcx> { pub fn variant_index_with_ctor_id(self, cid: DefId) -> VariantIdx { self.variants() .iter_enumerated() - .find(|(_, v)| v.ctor_def_id == Some(cid)) + .find(|(_, v)| v.ctor_def_id() == Some(cid)) .expect("variant_index_with_ctor_id: unknown variant") .0 } diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index 0d6c26a5822..273a61c966c 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -5,6 +5,7 @@ use crate::{mir, ty}; use std::fmt::Write; +use hir::LangItem; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; @@ -130,11 +131,14 @@ impl<'tcx> ClosureKind { } pub fn to_def_id(&self, tcx: TyCtxt<'_>) -> DefId { - match self { - ClosureKind::Fn => tcx.lang_items().fn_once_trait().unwrap(), - ClosureKind::FnMut => tcx.lang_items().fn_mut_trait().unwrap(), - ClosureKind::FnOnce => tcx.lang_items().fn_trait().unwrap(), - } + tcx.require_lang_item( + match self { + ClosureKind::Fn => LangItem::Fn, + ClosureKind::FnMut => LangItem::FnMut, + ClosureKind::FnOnce => LangItem::FnOnce, + }, + None, + ) } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 7263e8306cf..b469eebfad9 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -298,7 +298,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Ty } impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> - for ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> + for ty::List<ty::PolyExistentialPredicate<'tcx>> { fn decode(decoder: &mut D) -> &'tcx Self { let len = decoder.read_usize(); @@ -379,7 +379,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List<Ty<'tcx>>, - &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, &'tcx traits::ImplSource<'tcx, ()>, &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 37153a63944..9a58a196ed7 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -1,5 +1,4 @@ use crate::mir::interpret::LitToConstInput; -use crate::mir::ConstantKind; use crate::ty::{self, DefIdTree, InternalSubsts, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; use rustc_hir as hir; @@ -231,20 +230,6 @@ impl<'tcx> Const<'tcx> { } #[inline] - /// Tries to evaluate the constant if it is `Unevaluated` and creates a ConstValue if the - /// evaluation succeeds. If it doesn't succeed, returns the unevaluated constant. - pub fn eval_for_mir(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> ConstantKind<'tcx> { - if let Some(val) = self.kind().try_eval_for_mir(tcx, param_env) { - match val { - Ok(const_val) => ConstantKind::from_value(const_val, self.ty()), - Err(guar) => ConstantKind::Ty(tcx.const_error_with_guaranteed(self.ty(), guar)), - } - } else { - ConstantKind::Ty(self) - } - } - - #[inline] /// Panics if the value cannot be evaluated or doesn't contain a valid integer of the given type. pub fn eval_bits(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> u128 { self.try_eval_bits(tcx, param_env, ty) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1c714f59425..26d30308ed3 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -17,11 +17,11 @@ use crate::traits; use crate::ty::query::{self, TyCtxtAt}; use crate::ty::{ self, AdtDef, AdtDefData, AdtKind, Binder, BindingMode, BoundVar, CanonicalPolyFnSig, - ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, ExistentialPredicate, FloatTy, - FloatVar, FloatVid, GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, - ParamConst, ParamTy, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, Region, - RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, UintTy, - Visibility, + ClosureSizeProfileData, Const, ConstS, ConstVid, DefIdTree, FloatTy, FloatVar, FloatVid, + GenericParamDefKind, InferConst, InferTy, IntTy, IntVar, IntVid, List, ParamConst, ParamTy, + PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind, PredicateS, ProjectionTy, + Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyS, TyVar, TyVid, TypeAndMut, + UintTy, Visibility, }; use crate::ty::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef, UserSubsts}; use rustc_ast as ast; @@ -109,7 +109,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> { type Mutability = hir::Mutability; type Movability = hir::Movability; type PolyFnSig = PolyFnSig<'tcx>; - type ListBinderExistentialPredicate = &'tcx List<Binder<'tcx, ExistentialPredicate<'tcx>>>; + type ListBinderExistentialPredicate = &'tcx List<PolyExistentialPredicate<'tcx>>; type BinderListTy = Binder<'tcx, &'tcx List<Ty<'tcx>>>; type ListTy = &'tcx List<Ty<'tcx>>; type ProjectionTy = ty::ProjectionTy<'tcx>; @@ -140,8 +140,7 @@ pub struct CtxtInterners<'tcx> { substs: InternedSet<'tcx, InternalSubsts<'tcx>>, canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>, region: InternedSet<'tcx, RegionKind<'tcx>>, - poly_existential_predicates: - InternedSet<'tcx, List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>>, + poly_existential_predicates: InternedSet<'tcx, List<PolyExistentialPredicate<'tcx>>>, predicate: InternedSet<'tcx, PredicateS<'tcx>>, predicates: InternedSet<'tcx, List<Predicate<'tcx>>>, projs: InternedSet<'tcx, List<ProjectionKind>>, @@ -1810,7 +1809,7 @@ nop_lift! {const_; Const<'a> => Const<'tcx>} nop_lift! {const_allocation; ConstAllocation<'a> => ConstAllocation<'tcx>} nop_lift! {predicate; Predicate<'a> => Predicate<'tcx>} -nop_list_lift! {poly_existential_predicates; ty::Binder<'a, ExistentialPredicate<'a>> => ty::Binder<'tcx, ExistentialPredicate<'tcx>>} +nop_list_lift! {poly_existential_predicates; PolyExistentialPredicate<'a> => PolyExistentialPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} @@ -2265,7 +2264,7 @@ slice_interners!( substs: _intern_substs(GenericArg<'tcx>), canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), poly_existential_predicates: - _intern_poly_existential_predicates(ty::Binder<'tcx, ExistentialPredicate<'tcx>>), + _intern_poly_existential_predicates(PolyExistentialPredicate<'tcx>), predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), place_elems: _intern_place_elems(PlaceElem<'tcx>), @@ -2294,7 +2293,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Given a `ty`, return whether it's an `impl Future<...>`. pub fn ty_is_opaque_future(self, ty: Ty<'_>) -> bool { let ty::Opaque(def_id, _) = ty.kind() else { return false }; - let future_trait = self.lang_items().future_trait().unwrap(); + let future_trait = self.require_lang_item(LangItem::Future, None); self.explicit_item_bounds(def_id).iter().any(|(predicate, _)| { let ty::PredicateKind::Trait(trait_predicate) = predicate.kind().skip_binder() else { @@ -2517,7 +2516,7 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Tuple(self.intern_type_list(&ts))) } - pub fn mk_tup<I: InternAs<[Ty<'tcx>], Ty<'tcx>>>(self, iter: I) -> I::Output { + pub fn mk_tup<I: InternAs<Ty<'tcx>, Ty<'tcx>>>(self, iter: I) -> I::Output { iter.intern_with(|ts| self.mk_ty(Tuple(self.intern_type_list(&ts)))) } @@ -2533,6 +2532,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_fn_def(self, def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { + debug_assert_eq!( + self.generics_of(def_id).count(), + substs.len(), + "wrong number of generic parameters for {def_id:?}: {substs:?}", + ); self.mk_ty(FnDef(def_id, substs)) } @@ -2544,7 +2548,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_dynamic( self, - obj: &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>, + obj: &'tcx List<PolyExistentialPredicate<'tcx>>, reg: ty::Region<'tcx>, repr: DynKind, ) -> Ty<'tcx> { @@ -2553,6 +2557,11 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_projection(self, item_def_id: DefId, substs: SubstsRef<'tcx>) -> Ty<'tcx> { + debug_assert_eq!( + self.generics_of(item_def_id).count(), + substs.len(), + "wrong number of generic parameters for {item_def_id:?}: {substs:?}", + ); self.mk_ty(Projection(ProjectionTy { item_def_id, substs })) } @@ -2682,8 +2691,8 @@ impl<'tcx> TyCtxt<'tcx> { pub fn intern_poly_existential_predicates( self, - eps: &[ty::Binder<'tcx, ExistentialPredicate<'tcx>>], - ) -> &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> { + eps: &[PolyExistentialPredicate<'tcx>], + ) -> &'tcx List<PolyExistentialPredicate<'tcx>> { assert!(!eps.is_empty()); assert!( eps.array_windows() @@ -2767,10 +2776,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn mk_poly_existential_predicates< - I: InternAs< - [ty::Binder<'tcx, ExistentialPredicate<'tcx>>], - &'tcx List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>>, - >, + I: InternAs<PolyExistentialPredicate<'tcx>, &'tcx List<PolyExistentialPredicate<'tcx>>>, >( self, iter: I, @@ -2778,37 +2784,58 @@ impl<'tcx> TyCtxt<'tcx> { iter.intern_with(|xs| self.intern_poly_existential_predicates(xs)) } - pub fn mk_predicates<I: InternAs<[Predicate<'tcx>], &'tcx List<Predicate<'tcx>>>>( + pub fn mk_predicates<I: InternAs<Predicate<'tcx>, &'tcx List<Predicate<'tcx>>>>( self, iter: I, ) -> I::Output { iter.intern_with(|xs| self.intern_predicates(xs)) } - pub fn mk_type_list<I: InternAs<[Ty<'tcx>], &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output { + pub fn mk_type_list<I: InternAs<Ty<'tcx>, &'tcx List<Ty<'tcx>>>>(self, iter: I) -> I::Output { iter.intern_with(|xs| self.intern_type_list(xs)) } - pub fn mk_substs<I: InternAs<[GenericArg<'tcx>], &'tcx List<GenericArg<'tcx>>>>( + pub fn mk_substs<I: InternAs<GenericArg<'tcx>, &'tcx List<GenericArg<'tcx>>>>( self, iter: I, ) -> I::Output { iter.intern_with(|xs| self.intern_substs(xs)) } - pub fn mk_place_elems<I: InternAs<[PlaceElem<'tcx>], &'tcx List<PlaceElem<'tcx>>>>( + pub fn mk_place_elems<I: InternAs<PlaceElem<'tcx>, &'tcx List<PlaceElem<'tcx>>>>( self, iter: I, ) -> I::Output { iter.intern_with(|xs| self.intern_place_elems(xs)) } - pub fn mk_substs_trait(self, self_ty: Ty<'tcx>, rest: &[GenericArg<'tcx>]) -> SubstsRef<'tcx> { - self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned())) + pub fn mk_substs_trait( + self, + self_ty: Ty<'tcx>, + rest: impl IntoIterator<Item = GenericArg<'tcx>>, + ) -> SubstsRef<'tcx> { + self.mk_substs(iter::once(self_ty.into()).chain(rest)) + } + + pub fn mk_trait_ref( + self, + trait_def_id: DefId, + substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + ) -> ty::TraitRef<'tcx> { + let substs = substs.into_iter().map(Into::into); + let n = self.generics_of(trait_def_id).count(); + debug_assert_eq!( + (n, Some(n)), + substs.size_hint(), + "wrong number of generic parameters for {trait_def_id:?}: {:?} \nDid you accidentally include the self-type in the params list?", + substs.collect::<Vec<_>>(), + ); + let substs = self.mk_substs(substs); + ty::TraitRef::new(trait_def_id, substs) } pub fn mk_bound_variable_kinds< - I: InternAs<[ty::BoundVariableKind], &'tcx List<ty::BoundVariableKind>>, + I: InternAs<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>, >( self, iter: I, @@ -2963,6 +2990,15 @@ impl<'tcx> TyCtxtAt<'tcx> { pub fn ty_error_with_message(self, msg: &str) -> Ty<'tcx> { self.tcx.ty_error_with_message(self.span, msg) } + + pub fn mk_trait_ref( + self, + trait_lang_item: LangItem, + substs: impl IntoIterator<Item = impl Into<ty::GenericArg<'tcx>>>, + ) -> ty::TraitRef<'tcx> { + let trait_def_id = self.require_lang_item(trait_lang_item, Some(self.span)); + self.tcx.mk_trait_ref(trait_def_id, substs) + } } /// Parameter attributes that can only be determined by examining the body of a function instead diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 029ee15d68d..69f50df6235 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -508,11 +508,3 @@ impl<'tcx> TypeVisitor<'tcx> for IsSuggestableVisitor<'tcx> { c.super_visit_with(self) } } - -#[derive(Diagnostic)] -#[diag(borrowck_const_not_used_in_type_alias)] -pub(super) struct ConstNotUsedTraitAlias { - pub ct: String, - #[primary_span] - pub span: Span, -} diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index dc13374f992..a61f41b9c58 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -12,7 +12,12 @@ use rustc_span::{BytePos, Span}; use rustc_target::spec::abi; use std::borrow::Cow; +use std::collections::hash_map::DefaultHasher; use std::fmt; +use std::hash::{Hash, Hasher}; +use std::path::PathBuf; + +use super::print::PrettyPrinter; #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeFoldable, TypeVisitable, Lift)] pub struct ExpectedFound<T> { @@ -64,9 +69,7 @@ pub enum TypeError<'tcx> { CyclicTy(Ty<'tcx>), CyclicConst(ty::Const<'tcx>), ProjectionMismatched(ExpectedFound<DefId>), - ExistentialMismatch( - ExpectedFound<&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>>, - ), + ExistentialMismatch(ExpectedFound<&'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>>), ObjectUnsafeCoercion(DefId), ConstMismatch(ExpectedFound<ty::Const<'tcx>>), @@ -985,6 +988,38 @@ fn foo(&self) -> Self::T { String::new() } false } + pub fn short_ty_string(self, ty: Ty<'tcx>) -> (String, Option<PathBuf>) { + let length_limit = 50; + let type_limit = 4; + let regular = FmtPrinter::new(self, hir::def::Namespace::TypeNS) + .pretty_print_type(ty) + .expect("could not write to `String`") + .into_buffer(); + if regular.len() <= length_limit { + return (regular, None); + } + let short = FmtPrinter::new_with_limit( + self, + hir::def::Namespace::TypeNS, + rustc_session::Limit(type_limit), + ) + .pretty_print_type(ty) + .expect("could not write to `String`") + .into_buffer(); + if regular == short { + return (regular, None); + } + // Multiple types might be shortened in a single error, ensure we create a file for each. + let mut s = DefaultHasher::new(); + ty.hash(&mut s); + let hash = s.finish(); + let path = self.output_filenames(()).temp_path_ext(&format!("long-type-{hash}.txt"), None); + match std::fs::write(&path, ®ular) { + Ok(_) => (short, Some(path)), + Err(_) => (regular, None), + } + } + fn format_generic_args(self, args: &[ty::GenericArg<'tcx>]) -> String { FmtPrinter::new(self, hir::def::Namespace::TypeNS) .path_generic_args(Ok, args) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 3be0bc4defc..1ee4985cf8d 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -42,7 +42,6 @@ where ClosureSimplifiedType(D), GeneratorSimplifiedType(D), GeneratorWitnessSimplifiedType(usize), - OpaqueSimplifiedType(D), FunctionSimplifiedType(usize), PlaceholderSimplifiedType, } @@ -127,7 +126,7 @@ pub fn simplify_type<'tcx>( TreatParams::AsPlaceholder => Some(PlaceholderSimplifiedType), TreatParams::AsInfer => None, }, - ty::Projection(_) => match treat_params { + ty::Opaque(..) | ty::Projection(_) => match treat_params { // When treating `ty::Param` as a placeholder, projections also // don't unify with anything else as long as they are fully normalized. // @@ -138,7 +137,6 @@ pub fn simplify_type<'tcx>( } TreatParams::AsPlaceholder | TreatParams::AsInfer => None, }, - ty::Opaque(def_id, _) => Some(OpaqueSimplifiedType(def_id)), ty::Foreign(def_id) => Some(ForeignSimplifiedType(def_id)), ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None, } @@ -151,8 +149,7 @@ impl<D: Copy + Debug + Eq> SimplifiedTypeGen<D> { | ForeignSimplifiedType(d) | TraitSimplifiedType(d) | ClosureSimplifiedType(d) - | GeneratorSimplifiedType(d) - | OpaqueSimplifiedType(d) => Some(d), + | GeneratorSimplifiedType(d) => Some(d), _ => None, } } @@ -182,7 +179,6 @@ impl<D: Copy + Debug + Eq> SimplifiedTypeGen<D> { ClosureSimplifiedType(d) => ClosureSimplifiedType(map(d)), GeneratorSimplifiedType(d) => GeneratorSimplifiedType(map(d)), GeneratorWitnessSimplifiedType(n) => GeneratorWitnessSimplifiedType(n), - OpaqueSimplifiedType(d) => OpaqueSimplifiedType(map(d)), FunctionSimplifiedType(n) => FunctionSimplifiedType(n), PlaceholderSimplifiedType => PlaceholderSimplifiedType, } @@ -229,7 +225,7 @@ impl DeepRejectCtxt { match impl_ty.kind() { // Start by checking whether the type in the impl may unify with // pretty much everything. Just return `true` in that case. - ty::Param(_) | ty::Projection(_) | ty::Error(_) => return true, + ty::Param(_) | ty::Projection(_) | ty::Error(_) | ty::Opaque(..) => return true, // These types only unify with inference variables or their own // variant. ty::Bool @@ -247,8 +243,7 @@ impl DeepRejectCtxt { | ty::Never | ty::Tuple(..) | ty::FnPtr(..) - | ty::Foreign(..) - | ty::Opaque(..) => {} + | ty::Foreign(..) => {} ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) @@ -328,10 +323,7 @@ impl DeepRejectCtxt { _ => false, }, - // Opaque types in impls should be forbidden, but that doesn't - // stop compilation. So this match arm should never return true - // if compilation succeeds. - ty::Opaque(..) => matches!(k, ty::Opaque(..)), + ty::Opaque(..) => true, // Impls cannot contain these types as these cannot be named directly. ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false, diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 7201737be65..ee4b8f91c54 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -259,6 +259,7 @@ impl FlagComputation { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { self.add_ty(ty); } + ty::PredicateKind::Ambiguous => {} } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs index b7aa455727d..33f72729798 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs @@ -41,6 +41,13 @@ impl<'tcx> InhabitedPredicate<'tcx> { self.apply_inner(tcx, param_env, &|_| Err(())).ok() } + /// Same as `apply`, but `NotInModule(_)` predicates yield `false`. That is, + /// privately uninhabited types are considered always uninhabited. + pub fn apply_ignore_module(self, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> bool { + let Ok(result) = self.apply_inner::<!>(tcx, param_env, &|_| Ok(true)); + result + } + fn apply_inner<E>( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 279a728ea39..ace81bc4f83 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -5,7 +5,7 @@ //! //! # Example //! ```rust -//! enum Void {} +//! #![feature(never_type)] //! mod a { //! pub mod b { //! pub struct SecretlyUninhabited { @@ -15,6 +15,7 @@ //! } //! //! mod c { +//! enum Void {} //! pub struct AlsoSecretlyUninhabited { //! _priv: Void, //! } @@ -28,14 +29,14 @@ //! } //! ``` //! In this code, the type `Foo` will only be visibly uninhabited inside the -//! modules `b`, `c` and `d`. Calling `uninhabited_predicate` on `Foo` will +//! modules `b`, `c` and `d`. Calling `inhabited_predicate` on `Foo` will //! return `NotInModule(b) AND NotInModule(c)`. //! //! We need this information for pattern-matching on `Foo` or types that contain //! `Foo`. //! //! # Example -//! ```rust +//! ```ignore(illustrative) //! let foo_result: Result<T, Foo> = ... ; //! let Ok(t) = foo_result; //! ``` @@ -56,57 +57,6 @@ pub(crate) fn provide(providers: &mut ty::query::Providers) { ty::query::Providers { inhabited_predicate_adt, inhabited_predicate_type, ..*providers }; } -impl<'tcx> TyCtxt<'tcx> { - /// Checks whether a type is visibly uninhabited from a particular module. - /// - /// # Example - /// ``` - /// #![feature(never_type)] - /// # fn main() {} - /// enum Void {} - /// mod a { - /// pub mod b { - /// pub struct SecretlyUninhabited { - /// _priv: !, - /// } - /// } - /// } - /// - /// mod c { - /// use super::Void; - /// pub struct AlsoSecretlyUninhabited { - /// _priv: Void, - /// } - /// mod d { - /// } - /// } - /// - /// struct Foo { - /// x: a::b::SecretlyUninhabited, - /// y: c::AlsoSecretlyUninhabited, - /// } - /// ``` - /// In this code, the type `Foo` will only be visibly uninhabited inside the - /// modules b, c and d. This effects pattern-matching on `Foo` or types that - /// contain `Foo`. - /// - /// # Example - /// ```ignore (illustrative) - /// let foo_result: Result<T, Foo> = ... ; - /// let Ok(t) = foo_result; - /// ``` - /// This code should only compile in modules where the uninhabitedness of Foo is - /// visible. - pub fn is_ty_uninhabited_from( - self, - module: DefId, - ty: Ty<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> bool { - !ty.inhabited_predicate(self).apply(self, param_env, module) - } -} - /// Returns an `InhabitedPredicate` that is generic over type parameters and /// requires calling [`InhabitedPredicate::subst`] fn inhabited_predicate_adt(tcx: TyCtxt<'_>, def_id: DefId) -> InhabitedPredicate<'_> { @@ -170,6 +120,64 @@ impl<'tcx> Ty<'tcx> { _ => InhabitedPredicate::True, } } + + /// Checks whether a type is visibly uninhabited from a particular module. + /// + /// # Example + /// ``` + /// #![feature(never_type)] + /// # fn main() {} + /// enum Void {} + /// mod a { + /// pub mod b { + /// pub struct SecretlyUninhabited { + /// _priv: !, + /// } + /// } + /// } + /// + /// mod c { + /// use super::Void; + /// pub struct AlsoSecretlyUninhabited { + /// _priv: Void, + /// } + /// mod d { + /// } + /// } + /// + /// struct Foo { + /// x: a::b::SecretlyUninhabited, + /// y: c::AlsoSecretlyUninhabited, + /// } + /// ``` + /// In this code, the type `Foo` will only be visibly uninhabited inside the + /// modules b, c and d. This effects pattern-matching on `Foo` or types that + /// contain `Foo`. + /// + /// # Example + /// ```ignore (illustrative) + /// let foo_result: Result<T, Foo> = ... ; + /// let Ok(t) = foo_result; + /// ``` + /// This code should only compile in modules where the uninhabitedness of Foo is + /// visible. + pub fn is_inhabited_from( + self, + tcx: TyCtxt<'tcx>, + module: DefId, + param_env: ty::ParamEnv<'tcx>, + ) -> bool { + self.inhabited_predicate(tcx).apply(tcx, param_env, module) + } + + /// Returns true if the type is uninhabited without regard to visibility + pub fn is_privately_uninhabited( + self, + tcx: TyCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> bool { + !self.inhabited_predicate(tcx).apply_ignore_module(tcx, param_env) + } } /// N.B. this query should only be called through `Ty::inhabited_predicate` diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index ae0f158ede9..586460986dd 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -276,28 +276,45 @@ impl<'tcx> InstanceDef<'tcx> { } } -impl<'tcx> fmt::Display for Instance<'tcx> { +fn fmt_instance( + f: &mut fmt::Formatter<'_>, + instance: &Instance<'_>, + type_length: rustc_session::Limit, +) -> fmt::Result { + ty::tls::with(|tcx| { + let substs = tcx.lift(instance.substs).expect("could not lift for printing"); + + let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length) + .print_def_path(instance.def_id(), substs)? + .into_buffer(); + f.write_str(&s) + })?; + + match instance.def { + InstanceDef::Item(_) => Ok(()), + InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"), + InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), + InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), + InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num), + InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty), + InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"), + InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"), + InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty), + InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty), + } +} + +pub struct ShortInstance<'a, 'tcx>(pub &'a Instance<'tcx>, pub usize); + +impl<'a, 'tcx> fmt::Display for ShortInstance<'a, 'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - ty::tls::with(|tcx| { - let substs = tcx.lift(self.substs).expect("could not lift for printing"); - let s = FmtPrinter::new(tcx, Namespace::ValueNS) - .print_def_path(self.def_id(), substs)? - .into_buffer(); - f.write_str(&s) - })?; + fmt_instance(f, self.0, rustc_session::Limit(self.1)) + } +} - match self.def { - InstanceDef::Item(_) => Ok(()), - InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"), - InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), - InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), - InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num), - InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty), - InstanceDef::ClosureOnceShim { .. } => write!(f, " - shim"), - InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"), - InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty), - InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty), - } +impl<'tcx> fmt::Display for Instance<'tcx> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + ty::tls::with(|tcx| fmt_instance(f, self, tcx.type_length_limit())) } } @@ -534,7 +551,7 @@ impl<'tcx> Instance<'tcx> { let sig = tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?; assert_eq!(sig.inputs().len(), 1); - let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]); + let substs = tcx.mk_substs_trait(self_ty, [sig.inputs()[0].into()]); debug!(?self_ty, ?sig); Some(Instance { def, substs }) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 18eb06b83c9..0458c4abd3d 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -84,7 +84,7 @@ pub use self::context::{ GeneratorInteriorTypeCause, GlobalCtxt, Lift, OnDiskCache, TyCtxt, TypeckResults, UserType, UserTypeAnnotationIndex, }; -pub use self::instance::{Instance, InstanceDef}; +pub use self::instance::{Instance, InstanceDef, ShortInstance}; pub use self::list::List; pub use self::parameterized::ParameterizedOverTcx; pub use self::rvalue_scopes::RvalueScopes; @@ -94,9 +94,10 @@ pub use self::sty::{ BoundVariableKind, CanonicalPolyFnSig, ClosureSubsts, ClosureSubstsParts, ConstVid, EarlyBoundRegion, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FnSig, FreeRegion, GenSig, GeneratorSubsts, GeneratorSubstsParts, InlineConstSubsts, - InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialProjection, - PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, ProjectionTy, Region, RegionKind, - RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, VarianceDiagInfo, + InlineConstSubstsParts, ParamConst, ParamTy, PolyExistentialPredicate, + PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef, + ProjectionTy, Region, RegionKind, RegionVid, TraitRef, TyKind, TypeAndMut, UpvarSubsts, + VarianceDiagInfo, }; pub use self::trait_def::TraitDef; @@ -619,6 +620,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Coerce(_) | PredicateKind::ConstEvaluatable(_) | PredicateKind::ConstEquate(_, _) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(_) => true, } } @@ -701,6 +703,10 @@ pub enum PredicateKind<'tcx> { /// /// Only used for Chalk. TypeWellFormedFromEnv(Ty<'tcx>), + + /// A marker predicate that is always ambiguous. + /// Used for coherence to mark opaque types as possibly equal to each other but ambiguous. + Ambiguous, } /// The crate outlives map is computed during typeck and contains the @@ -851,6 +857,10 @@ impl<'tcx> TraitPredicate<'tcx> { } } + pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + Self { trait_ref: self.trait_ref.with_self_type(tcx, self_ty), ..self } + } + pub fn def_id(self) -> DefId { self.trait_ref.def_id } @@ -1125,42 +1135,42 @@ impl<'tcx> ToPolyTraitRef<'tcx> for PolyTraitPredicate<'tcx> { } } -pub trait ToPredicate<'tcx> { - fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx>; +pub trait ToPredicate<'tcx, Predicate> { + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate; } -impl<'tcx> ToPredicate<'tcx> for Predicate<'tcx> { - fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { +impl<'tcx, T> ToPredicate<'tcx, T> for T { + fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> T { self } } -impl<'tcx> ToPredicate<'tcx> for Binder<'tcx, PredicateKind<'tcx>> { +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tcx>> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { tcx.mk_predicate(self) } } -impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> { +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTraitPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(PredicateKind::Trait).to_predicate(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> { +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyRegionOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(PredicateKind::RegionOutlives).to_predicate(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> { +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyTypeOutlivesPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(PredicateKind::TypeOutlives).to_predicate(tcx) } } -impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for PolyProjectionPredicate<'tcx> { fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { self.map_bound(PredicateKind::Projection).to_predicate(tcx) } @@ -1181,6 +1191,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::TypeOutlives(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1199,6 +1210,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::TypeOutlives(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1217,6 +1229,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ClosureKind(..) | PredicateKind::ConstEvaluatable(..) | PredicateKind::ConstEquate(..) + | PredicateKind::Ambiguous | PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -1257,7 +1270,7 @@ impl<'tcx> InstantiatedPredicates<'tcx> { } } -#[derive(Copy, Clone, Debug, PartialEq, Eq, HashStable, TyEncodable, TyDecodable, Lift)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)] #[derive(TypeFoldable, TypeVisitable)] pub struct OpaqueTypeKey<'tcx> { pub def_id: LocalDefId, @@ -1332,6 +1345,9 @@ impl<'tcx> OpaqueHiddenType<'tcx> { let id_substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id()); debug!(?id_substs); + // This zip may have several times the same lifetime in `substs` paired with a different + // lifetime from `id_substs`. Simply `collect`ing the iterator is the correct behaviour: + // it will pick the last one, which is the one we introduced in the impl-trait desugaring. let map = substs.iter().zip(id_substs); let map: FxHashMap<GenericArg<'tcx>, GenericArg<'tcx>> = match origin { @@ -1345,61 +1361,13 @@ impl<'tcx> OpaqueHiddenType<'tcx> { // type Foo<'a, 'b, 'c> = impl Trait<'a> + 'b; // ``` // we may not use `'c` in the hidden type. - struct OpaqueTypeLifetimeCollector<'tcx> { - lifetimes: FxHashSet<ty::Region<'tcx>>, - } - - impl<'tcx> ty::TypeVisitor<'tcx> for OpaqueTypeLifetimeCollector<'tcx> { - fn visit_region(&mut self, r: ty::Region<'tcx>) -> ControlFlow<Self::BreakTy> { - self.lifetimes.insert(r); - r.super_visit_with(self) - } - } + let variances = tcx.variances_of(def_id); + debug!(?variances); - let mut collector = OpaqueTypeLifetimeCollector { lifetimes: Default::default() }; - - for pred in tcx.bound_explicit_item_bounds(def_id.to_def_id()).transpose_iter() { - let pred = pred.map_bound(|(pred, _)| *pred).subst(tcx, id_substs); - - trace!(pred=?pred.kind()); - - // We only ignore opaque type substs if the opaque type is the outermost type. - // The opaque type may be nested within itself via recursion in e.g. - // type Foo<'a> = impl PartialEq<Foo<'a>>; - // which thus mentions `'a` and should thus accept hidden types that borrow 'a - // instead of requiring an additional `+ 'a`. - match pred.kind().skip_binder() { - ty::PredicateKind::Trait(TraitPredicate { - trait_ref: ty::TraitRef { def_id: _, substs }, - constness: _, - polarity: _, - }) => { - trace!(?substs); - for subst in &substs[1..] { - subst.visit_with(&mut collector); - } - } - ty::PredicateKind::Projection(ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy { substs, item_def_id: _ }, - term, - }) => { - for subst in &substs[1..] { - subst.visit_with(&mut collector); - } - term.visit_with(&mut collector); - } - _ => { - pred.visit_with(&mut collector); - } - } - } - let lifetimes = collector.lifetimes; - trace!(?lifetimes); map.filter(|(_, v)| { - let ty::GenericArgKind::Lifetime(lt) = v.unpack() else { - return true; - }; - lifetimes.contains(<) + let ty::GenericArgKind::Lifetime(lt) = v.unpack() else { return true }; + let ty::ReEarlyBound(ebr) = lt.kind() else { bug!() }; + variances[ebr.index as usize] == ty::Variance::Invariant }) .collect() } @@ -1852,15 +1820,13 @@ pub struct VariantDef { pub def_id: DefId, /// `DefId` that identifies the variant's constructor. /// If this variant is a struct variant, then this is `None`. - pub ctor_def_id: Option<DefId>, + pub ctor: Option<(CtorKind, DefId)>, /// Variant or struct name. pub name: Symbol, /// Discriminant of this variant. pub discr: VariantDiscr, /// Fields of this variant. pub fields: Vec<FieldDef>, - /// Type of constructor of variant. - pub ctor_kind: CtorKind, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, } @@ -1885,19 +1851,18 @@ impl VariantDef { pub fn new( name: Symbol, variant_did: Option<DefId>, - ctor_def_id: Option<DefId>, + ctor: Option<(CtorKind, DefId)>, discr: VariantDiscr, fields: Vec<FieldDef>, - ctor_kind: CtorKind, adt_kind: AdtKind, parent_did: DefId, recovered: bool, is_field_list_non_exhaustive: bool, ) -> Self { debug!( - "VariantDef::new(name = {:?}, variant_did = {:?}, ctor_def_id = {:?}, discr = {:?}, - fields = {:?}, ctor_kind = {:?}, adt_kind = {:?}, parent_did = {:?})", - name, variant_did, ctor_def_id, discr, fields, ctor_kind, adt_kind, parent_did, + "VariantDef::new(name = {:?}, variant_did = {:?}, ctor = {:?}, discr = {:?}, + fields = {:?}, adt_kind = {:?}, parent_did = {:?})", + name, variant_did, ctor, discr, fields, adt_kind, parent_did, ); let mut flags = VariantFlags::NO_VARIANT_FLAGS; @@ -1909,15 +1874,7 @@ impl VariantDef { flags |= VariantFlags::IS_RECOVERED; } - VariantDef { - def_id: variant_did.unwrap_or(parent_did), - ctor_def_id, - name, - discr, - fields, - ctor_kind, - flags, - } + VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags } } /// Is this field list non-exhaustive? @@ -1936,6 +1893,16 @@ impl VariantDef { pub fn ident(&self, tcx: TyCtxt<'_>) -> Ident { Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) } + + #[inline] + pub fn ctor_kind(&self) -> Option<CtorKind> { + self.ctor.map(|(kind, _)| kind) + } + + #[inline] + pub fn ctor_def_id(&self) -> Option<DefId> { + self.ctor.map(|(_, def_id)| def_id) + } } impl PartialEq for VariantDef { @@ -1948,26 +1915,8 @@ impl PartialEq for VariantDef { // definition of `VariantDef` changes, a compile-error will be produced, // reminding us to revisit this assumption. - let Self { - def_id: lhs_def_id, - ctor_def_id: _, - name: _, - discr: _, - fields: _, - ctor_kind: _, - flags: _, - } = &self; - - let Self { - def_id: rhs_def_id, - ctor_def_id: _, - name: _, - discr: _, - fields: _, - ctor_kind: _, - flags: _, - } = other; - + let Self { def_id: lhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; + let Self { def_id: rhs_def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = other; lhs_def_id == rhs_def_id } } @@ -1984,9 +1933,7 @@ impl Hash for VariantDef { // of `VariantDef` changes, a compile-error will be produced, reminding // us to revisit this assumption. - let Self { def_id, ctor_def_id: _, name: _, discr: _, fields: _, ctor_kind: _, flags: _ } = - &self; - + let Self { def_id, ctor: _, name: _, discr: _, fields: _, flags: _ } = &self; def_id.hash(s) } } diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs index b05c6310929..98cd92007c2 100644 --- a/compiler/rustc_middle/src/ty/opaque_types.rs +++ b/compiler/rustc_middle/src/ty/opaque_types.rs @@ -1,7 +1,8 @@ +use crate::error::ConstNotUsedTraitAlias; +use crate::ty::fold::{TypeFolder, TypeSuperFoldable}; +use crate::ty::subst::{GenericArg, GenericArgKind}; +use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::FxHashMap; -use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc_span::Span; /// Converts generic params of a TypeFoldable from one @@ -201,7 +202,7 @@ impl<'tcx> TypeFolder<'tcx> for ReverseMapper<'tcx> { Some(u) => panic!("const mapped to unexpected kind: {:?}", u), None => { if !self.ignore_errors { - self.tcx.sess.emit_err(ty::ConstNotUsedTraitAlias { + self.tcx.sess.emit_err(ConstNotUsedTraitAlias { ct: ct.to_string(), span: self.span, }); diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index e1e705a922f..d6025248081 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -70,7 +70,7 @@ trivially_parameterized_over_tcx! { ty::adjustment::CoerceUnsizedInfo, ty::fast_reject::SimplifiedTypeGen<DefId>, rustc_ast::Attribute, - rustc_ast::MacArgs, + rustc_ast::DelimArgs, rustc_attr::ConstStability, rustc_attr::DefaultBodyStability, rustc_attr::Deprecation, diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 44b9548db89..667298b9b5b 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -63,7 +63,7 @@ pub trait Printer<'tcx>: Sized { fn print_dyn_existential( self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error>; fn print_const(self, ct: ty::Const<'tcx>) -> Result<Self::Const, Self::Error>; @@ -308,9 +308,7 @@ impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for Ty<'tcx> { } } -impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> - for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> -{ +impl<'tcx, P: Printer<'tcx>> Print<'tcx, P> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { type Output = P::DynExistential; type Error = P::Error; fn print(&self, cx: P) -> Result<Self::Output, Self::Error> { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 48e803597b0..bddcdd0b693 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -11,8 +11,10 @@ use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; +use rustc_hir::LangItem; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; +use rustc_session::Limit; use rustc_span::symbol::{kw, Ident, Symbol}; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; @@ -888,7 +890,7 @@ pub trait PrettyPrinter<'tcx>: // Group the return ty with its def id, if we had one. entry .return_ty - .map(|ty| (tcx.lang_items().fn_once_output().unwrap(), ty)), + .map(|ty| (tcx.require_lang_item(LangItem::FnOnce, None), ty)), ); } if let Some(trait_ref) = entry.fn_mut_trait_ref { @@ -1059,7 +1061,7 @@ pub trait PrettyPrinter<'tcx>: fn pretty_print_dyn_existential( mut self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { // Generate the main trait ref, including associated types. let mut first = true; @@ -1486,12 +1488,12 @@ pub trait PrettyPrinter<'tcx>: contents.variant.expect("destructed const of adt without variant idx"); let variant_def = &def.variant(variant_idx); p!(print_value_path(variant_def.def_id, substs)); - match variant_def.ctor_kind { - CtorKind::Const => {} - CtorKind::Fn => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => {} + Some(CtorKind::Fn) => { p!("(", comma_sep(fields), ")"); } - CtorKind::Fictive => { + None => { p!(" {{ "); let mut first = true; for (field_def, field) in iter::zip(&variant_def.fields, fields) { @@ -1583,6 +1585,8 @@ pub struct FmtPrinterData<'a, 'tcx> { region_index: usize, binder_depth: usize, printed_type_count: usize, + type_length_limit: Limit, + truncated: bool, pub region_highlight_mode: RegionHighlightMode<'tcx>, @@ -1605,6 +1609,10 @@ impl DerefMut for FmtPrinter<'_, '_> { impl<'a, 'tcx> FmtPrinter<'a, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, ns: Namespace) -> Self { + Self::new_with_limit(tcx, ns, tcx.type_length_limit()) + } + + pub fn new_with_limit(tcx: TyCtxt<'tcx>, ns: Namespace, type_length_limit: Limit) -> Self { FmtPrinter(Box::new(FmtPrinterData { tcx, // Estimated reasonable capacity to allocate upfront based on a few @@ -1617,6 +1625,8 @@ impl<'a, 'tcx> FmtPrinter<'a, 'tcx> { region_index: 0, binder_depth: 0, printed_type_count: 0, + type_length_limit, + truncated: false, region_highlight_mode: RegionHighlightMode::new(tcx), ty_infer_name_resolver: None, const_infer_name_resolver: None, @@ -1751,11 +1761,11 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { } fn print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> { - let type_length_limit = self.tcx.type_length_limit(); - if type_length_limit.value_within_limit(self.printed_type_count) { + if self.type_length_limit.value_within_limit(self.printed_type_count) { self.printed_type_count += 1; self.pretty_print_type(ty) } else { + self.truncated = true; write!(self, "...")?; Ok(self) } @@ -1763,7 +1773,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { fn print_dyn_existential( self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { self.pretty_print_dyn_existential(predicates) } @@ -2194,11 +2204,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { define_scoped_cx!(self); - let possible_names = - ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}"))).collect::<Vec<_>>(); + let possible_names = ('a'..='z').rev().map(|s| Symbol::intern(&format!("'{s}"))); let mut available_names = possible_names - .into_iter() .filter(|name| !self.used_region_names.contains(&name)) .collect::<Vec<_>>(); debug!(?available_names); @@ -2523,12 +2531,12 @@ pub struct PrintClosureAsImpl<'tcx> { forward_display_to_print! { ty::Region<'tcx>, Ty<'tcx>, - &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ty::Const<'tcx>, // HACK(eddyb) these are exhaustive instead of generic, // because `for<'tcx>` isn't possible yet. - ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>, + ty::PolyExistentialPredicate<'tcx>, ty::Binder<'tcx, ty::TraitRef<'tcx>>, ty::Binder<'tcx, ty::ExistentialTraitRef<'tcx>>, ty::Binder<'tcx, TraitRefPrintOnlyTraitPath<'tcx>>, @@ -2696,6 +2704,7 @@ define_print_and_forward_display! { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { p!("the type `", print(ty), "` is found in the environment") } + ty::PredicateKind::Ambiguous => p!("ambiguous"), } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index c083a405e3c..3d47b71b7ce 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -23,6 +23,8 @@ pub enum Cause { pub trait TypeRelation<'tcx>: Sized { fn tcx(&self) -> TyCtxt<'tcx>; + fn intercrate(&self) -> bool; + fn param_env(&self) -> ty::ParamEnv<'tcx>; /// Returns a static string we can use for printouts. @@ -32,6 +34,9 @@ pub trait TypeRelation<'tcx>: Sized { /// relation. Just affects error messages. fn a_is_expected(&self) -> bool; + /// Used during coherence. If called, must emit an always-ambiguous obligation. + fn mark_ambiguous(&mut self); + fn with_cause<F, R>(&mut self, _cause: Cause, f: F) -> R where F: FnOnce(&mut Self) -> R, @@ -60,7 +65,7 @@ pub trait TypeRelation<'tcx>: Sized { let tcx = self.tcx(); let opt_variances = tcx.variances_of(item_def_id); - relate_substs_with_variances(self, item_def_id, opt_variances, a_subst, b_subst) + relate_substs_with_variances(self, item_def_id, opt_variances, a_subst, b_subst, true) } /// Switch variance for the purpose of relating `a` and `b`. @@ -151,13 +156,14 @@ pub fn relate_substs_with_variances<'tcx, R: TypeRelation<'tcx>>( variances: &[ty::Variance], a_subst: SubstsRef<'tcx>, b_subst: SubstsRef<'tcx>, + fetch_ty_for_diag: bool, ) -> RelateResult<'tcx, SubstsRef<'tcx>> { let tcx = relation.tcx(); let mut cached_ty = None; let params = iter::zip(a_subst, b_subst).enumerate().map(|(i, (a, b))| { let variance = variances[i]; - let variance_info = if variance == ty::Invariant { + let variance_info = if variance == ty::Invariant && fetch_ty_for_diag { let ty = *cached_ty.get_or_insert_with(|| tcx.bound_type_of(ty_def_id).subst(tcx, a_subst)); ty::VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() } @@ -561,8 +567,23 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( (&ty::Opaque(a_def_id, a_substs), &ty::Opaque(b_def_id, b_substs)) if a_def_id == b_def_id => { - let substs = relate_substs(relation, a_substs, b_substs)?; - Ok(tcx.mk_opaque(a_def_id, substs)) + if relation.intercrate() { + // During coherence, opaque types should be treated as equal to each other, even if their generic params + // differ, as they could resolve to the same hidden type, even for different generic params. + relation.mark_ambiguous(); + Ok(a) + } else { + let opt_variances = tcx.variances_of(a_def_id); + let substs = relate_substs_with_variances( + relation, + a_def_id, + opt_variances, + a_substs, + b_substs, + false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle + )?; + Ok(tcx.mk_opaque(a_def_id, substs)) + } } _ => Err(TypeError::Sorts(expected_found(relation, a, b))), @@ -649,7 +670,7 @@ pub fn super_relate_consts<'tcx, R: TypeRelation<'tcx>>( if is_match { Ok(a) } else { Err(TypeError::ConstMismatch(expected_found(relation, a, b))) } } -impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> { +impl<'tcx> Relate<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { fn relate<R: TypeRelation<'tcx>>( relation: &mut R, a: Self, diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 9f0598d0ba8..64b4fd11762 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -173,6 +173,7 @@ impl<'tcx> fmt::Debug for ty::PredicateKind<'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(ty) => { write!(f, "TypeWellFormedFromEnv({:?})", ty) } + ty::PredicateKind::Ambiguous => write!(f, "Ambiguous"), } } } @@ -586,7 +587,7 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeSuperVisitable<'tcx> for ty::Binder<'tcx, } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> { +impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { ty::util::fold_list(self, folder, |tcx, v| tcx.intern_poly_existential_predicates(v)) } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 49d82b503a4..e7a751fa0af 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -17,6 +17,7 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::intern::Interned; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::LangItem; use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; @@ -703,7 +704,9 @@ impl<'tcx> ExistentialPredicate<'tcx> { } } -impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { +pub type PolyExistentialPredicate<'tcx> = Binder<'tcx, ExistentialPredicate<'tcx>>; + +impl<'tcx> PolyExistentialPredicate<'tcx> { /// Given an existential predicate like `?Self: PartialEq<u32>` (e.g., derived from `dyn PartialEq<u32>`), /// and a concrete type `self_ty`, returns a full predicate where the existentially quantified variable `?Self` /// has been replaced with `self_ty` (e.g., `self_ty: PartialEq<u32>`, in our example). @@ -717,17 +720,14 @@ impl<'tcx> Binder<'tcx, ExistentialPredicate<'tcx>> { self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx) } ExistentialPredicate::AutoTrait(did) => { - let trait_ref = self.rebind(ty::TraitRef { - def_id: did, - substs: tcx.mk_substs_trait(self_ty, &[]), - }); + let trait_ref = self.rebind(tcx.mk_trait_ref(did, [self_ty])); trait_ref.without_const().to_predicate(tcx) } } } } -impl<'tcx> List<ty::Binder<'tcx, ExistentialPredicate<'tcx>>> { +impl<'tcx> List<ty::PolyExistentialPredicate<'tcx>> { /// Returns the "principal `DefId`" of this set of existential predicates. /// /// A Rust trait object type consists (in addition to a lifetime bound) @@ -812,6 +812,13 @@ impl<'tcx> TraitRef<'tcx> { TraitRef { def_id, substs } } + pub fn with_self_type(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self { + tcx.mk_trait_ref( + self.def_id, + [self_ty.into()].into_iter().chain(self.substs.iter().skip(1)), + ) + } + /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi` /// are the parameters defined on trait. pub fn identity(tcx: TyCtxt<'tcx>, def_id: DefId) -> Binder<'tcx, TraitRef<'tcx>> { @@ -907,7 +914,7 @@ impl<'tcx> ExistentialTraitRef<'tcx> { // otherwise the escaping vars would be captured by the binder // debug_assert!(!self_ty.has_escaping_bound_vars()); - ty::TraitRef { def_id: self.def_id, substs: tcx.mk_substs_trait(self_ty, self.substs) } + tcx.mk_trait_ref(self.def_id, [self_ty.into()].into_iter().chain(self.substs.iter())) } } @@ -2102,7 +2109,7 @@ impl<'tcx> Ty<'tcx> { ty::Str | ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { - let dyn_metadata = tcx.lang_items().dyn_metadata().unwrap(); + let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) }, diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index c726fa3a33f..2baa3bfcb64 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] rustc_arena = { path = "../rustc_arena" } tracing = "0.1" +either = "1" rustc_middle = { path = "../rustc_middle" } rustc_apfloat = { path = "../rustc_apfloat" } rustc_attr = { path = "../rustc_attr" } diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index db05592ed0e..49d7136a2f1 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -1,4 +1,3 @@ -use crate::build::matches::ArmHasGuard; use crate::build::ForGuard::OutsideGuard; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder}; use rustc_middle::middle::region::Scope; @@ -231,7 +230,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visibility_scope, remainder_span, pattern, - ArmHasGuard(false), + None, Some((None, initializer_span)), ); this.visit_primary_bindings( @@ -308,7 +307,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visibility_scope, remainder_span, pattern, - ArmHasGuard(false), + None, Some((None, initializer_span)), ); this.expr_into_pattern(block, &pattern, init) @@ -324,7 +323,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { visibility_scope, remainder_span, pattern, - ArmHasGuard(false), + None, None, ); block.unit() diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 1fb0f36021e..218a26e6279 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -108,7 +108,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Let { expr, ref pat } => { let scope = this.local_scope(); let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| { - this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span) + this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span, true) }); this.cfg.push_assign_constant( @@ -271,15 +271,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // MIR checks and ultimately whether code is accepted or not. We can only // omit the return edge if a return type is visibly uninhabited to a module // that makes the call. - target: if this.tcx.is_ty_uninhabited_from( - this.parent_module, - expr.ty, - this.param_env, - ) { - None - } else { - Some(success) - }, + target: expr + .ty + .is_inhabited_from(this.tcx, this.parent_module, this.param_env) + .then_some(success), from_hir_call, fn_span, }, diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index d5b1a56076a..691cbee2c73 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -84,6 +84,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { break_scope, Some(variable_source_info.scope), variable_source_info.span, + true, ), _ => { let temp_scope = temp_scope_override.unwrap_or_else(|| this.local_scope()); @@ -351,7 +352,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { None, arm.span, &arm.pattern, - ArmHasGuard(arm.guard.is_some()), + arm.guard.as_ref(), opt_scrutinee_place, ); @@ -637,7 +638,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mut visibility_scope: Option<SourceScope>, scope_span: Span, pattern: &Pat<'tcx>, - has_guard: ArmHasGuard, + guard: Option<&Guard<'tcx>>, opt_match_place: Option<(Option<&Place<'tcx>>, Span)>, ) -> Option<SourceScope> { self.visit_primary_bindings( @@ -659,12 +660,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { var, ty, user_ty, - has_guard, + ArmHasGuard(guard.is_some()), opt_match_place.map(|(x, y)| (x.cloned(), y)), pattern.span, ); }, ); + if let Some(Guard::IfLet(guard_pat, _)) = guard { + // FIXME: pass a proper `opt_match_place` + self.declare_bindings(visibility_scope, scope_span, guard_pat, None, None); + } visibility_scope } @@ -1756,6 +1761,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Pat binding - used for `let` and function parameters as well. impl<'a, 'tcx> Builder<'a, 'tcx> { + /// If the bindings have already been declared, set `declare_bindings` to + /// `false` to avoid duplicated bindings declaration. Used for if-let guards. pub(crate) fn lower_let_expr( &mut self, mut block: BasicBlock, @@ -1764,6 +1771,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { else_target: region::Scope, source_scope: Option<SourceScope>, span: Span, + declare_bindings: bool, ) -> BlockAnd<()> { let expr_span = expr.span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span)); @@ -1783,13 +1791,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap(); self.break_for_else(otherwise_post_guard_block, else_target, self.source_info(expr_span)); - self.declare_bindings( - source_scope, - pat.span.to(span), - pat, - ArmHasGuard(false), - opt_expr_place, - ); + if declare_bindings { + self.declare_bindings(source_scope, pat.span.to(span), pat, None, opt_expr_place); + } let post_guard_block = self.bind_pattern( self.source_info(pat.span), @@ -1970,7 +1974,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Guard::IfLet(ref pat, scrutinee) => { let s = &this.thir[scrutinee]; guard_span = s.span; - this.lower_let_expr(block, s, pat, match_scope, None, arm.span) + this.lower_let_expr(block, s, pat, match_scope, None, arm.span, false) } }); diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 3e8d6cd71a1..f6b1955fdec 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -263,10 +263,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index || { self.tcx.features().exhaustive_patterns - && v.inhabited_predicate(self.tcx, adt_def) + && !v + .inhabited_predicate(self.tcx, adt_def) .subst(self.tcx, substs) - .apply_any_module(self.tcx, self.param_env) - != Some(true) + .apply_ignore_module(self.tcx, self.param_env) } }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 0db29c3f983..58513bde2aa 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -240,6 +240,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } TestKind::Eq { value, ty } => { + let tcx = self.tcx; + if let ty::Adt(def, _) = ty.kind() && Some(def.did()) == tcx.lang_items().string() { + if !tcx.features().string_deref_patterns { + bug!("matching on `String` went through without enabling string_deref_patterns"); + } + let re_erased = tcx.lifetimes.re_erased; + let ref_string = self.temp(tcx.mk_imm_ref(re_erased, ty), test.span); + let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_); + let ref_str = self.temp(ref_str_ty, test.span); + let deref = tcx.require_lang_item(LangItem::Deref, None); + let method = trait_method(tcx, deref, sym::deref, [ty]); + let eq_block = self.cfg.start_new_block(); + self.cfg.push_assign(block, source_info, ref_string, Rvalue::Ref(re_erased, BorrowKind::Shared, place)); + self.cfg.terminate( + block, + source_info, + TerminatorKind::Call { + func: Operand::Constant(Box::new(Constant { + span: test.span, + user_ty: None, + literal: method, + })), + args: vec![Operand::Move(ref_string)], + destination: ref_str, + target: Some(eq_block), + cleanup: None, + from_hir_call: false, + fn_span: source_info.span + } + ); + self.non_scalar_compare(eq_block, make_target_blocks, source_info, value, ref_str, ref_str_ty); + return; + } if !ty.is_scalar() { // Use `PartialEq::eq` instead of `BinOp::Eq` // (the binop can only handle primitives) @@ -411,8 +444,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { bug!("non_scalar_compare called on non-reference type: {}", ty); }; - let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, None); - let method = trait_method(self.tcx, eq_def_id, sym::eq, deref_ty, &[deref_ty.into()]); + let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [deref_ty, deref_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); @@ -805,10 +838,9 @@ fn trait_method<'tcx>( tcx: TyCtxt<'tcx>, trait_def_id: DefId, method_name: Symbol, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>], + substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, ) -> ConstantKind<'tcx> { - let substs = tcx.mk_substs_trait(self_ty, params); + let substs = tcx.mk_substs(substs.into_iter().map(Into::into)); // The unhygienic comparison here is acceptable because this is only // used on known traits. @@ -818,8 +850,7 @@ fn trait_method<'tcx>( .find(|item| item.kind == ty::AssocKind::Fn) .expect("trait method not found"); - let method_ty = tcx.bound_type_of(item.def_id); - let method_ty = method_ty.subst(tcx, substs); + let method_ty = tcx.mk_fn_def(item.def_id, substs); ConstantKind::zero_sized(method_ty) } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 437ac8d82a1..0b76122913e 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -924,7 +924,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { scope, expr.span, &pat, - matches::ArmHasGuard(false), + None, Some((Some(&place), span)), ); let place_builder = PlaceBuilder::from(local); diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index b53bd3d0710..87975294595 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -3,6 +3,7 @@ //! This crate also contains the match exhaustiveness and usefulness checking. #![allow(rustc::potential_query_instability)] #![feature(assert_matches)] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(if_let_guard)] diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 57382f5e1bd..60e64b45963 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -14,11 +14,10 @@ use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, }; -use rustc_middle::ty::subst::{InternalSubsts, SubstsRef}; +use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; -use rustc_span::def_id::DefId; use rustc_span::Span; use rustc_target::abi::VariantIdx; @@ -806,12 +805,12 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &hir::Expr<'_>, span: Span, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option<Ty<'tcx>>, ) -> Expr<'tcx> { let temp_lifetime = self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id); - let (def_id, substs, user_ty) = match overloaded_callee { - Some((def_id, substs)) => (def_id, substs, None), + let (ty, user_ty) = match overloaded_callee { + Some(fn_def) => (fn_def, None), None => { let (kind, def_id) = self.typeck_results().type_dependent_def(expr.hir_id).unwrap_or_else(|| { @@ -819,10 +818,12 @@ impl<'tcx> Cx<'tcx> { }); let user_ty = self.user_substs_applied_to_res(expr.hir_id, Res::Def(kind, def_id)); debug!("method_callee: user_ty={:?}", user_ty); - (def_id, self.typeck_results().node_substs(expr.hir_id), user_ty) + ( + self.tcx().mk_fn_def(def_id, self.typeck_results().node_substs(expr.hir_id)), + user_ty, + ) } }; - let ty = self.tcx().mk_fn_def(def_id, substs); Expr { temp_lifetime, ty, span, kind: ExprKind::ZstLiteral { user_ty } } } @@ -957,7 +958,7 @@ impl<'tcx> Cx<'tcx> { &mut self, expr: &'tcx hir::Expr<'tcx>, place_ty: Ty<'tcx>, - overloaded_callee: Option<(DefId, SubstsRef<'tcx>)>, + overloaded_callee: Option<Ty<'tcx>>, args: Box<[ExprId]>, span: Span, ) -> ExprKind<'tcx> { diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 93a3dd8962a..ba04cb6eef8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -564,7 +564,7 @@ fn check_for_bindings_named_same_as_variants( && let ty::Adt(edef, _) = pat_ty.kind() && edef.is_enum() && edef.variants().iter().any(|variant| { - variant.ident(cx.tcx) == ident && variant.ctor_kind == CtorKind::Const + variant.ident(cx.tcx) == ident && variant.ctor_kind() == Some(CtorKind::Const) }) { let variant_count = edef.variants().len(); @@ -818,7 +818,7 @@ fn non_exhaustive_match<'p, 'tcx>( } } if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() { - if cx.tcx.is_ty_uninhabited_from(cx.module, *sub_ty, cx.param_env) { + if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.param_env) { err.note("references are always considered inhabited"); } } diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ad12e011621..a21f6cd39f0 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -232,8 +232,7 @@ impl<'tcx> ConstToPat<'tcx> { ObligationCause::misc(self.span, self.id), partial_eq_trait_id, 0, - ty, - &[], + [ty, ty], ); // FIXME: should this call a `predicate_must_hold` variant instead? diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 595abc8f668..d60e8722cb6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -42,16 +42,17 @@ //! wildcards, see [`SplitWildcard`]; for integer ranges, see [`SplitIntRange`]; for slices, see //! [`SplitVarLenSlice`]. -use self::Constructor::*; -use self::SliceKind::*; +use std::cell::Cell; +use std::cmp::{self, max, min, Ordering}; +use std::fmt; +use std::iter::{once, IntoIterator}; +use std::ops::RangeInclusive; -use super::compare_const_vals; -use super::usefulness::{MatchCheckCtxt, PatCtxt}; +use smallvec::{smallvec, SmallVec}; use rustc_data_structures::captures::Captures; -use rustc_index::vec::Idx; - use rustc_hir::{HirId, RangeEnd}; +use rustc_index::vec::Idx; use rustc_middle::mir::{self, Field}; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; @@ -61,12 +62,11 @@ use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; use rustc_target::abi::{Integer, Size, VariantIdx}; -use smallvec::{smallvec, SmallVec}; -use std::cell::Cell; -use std::cmp::{self, max, min, Ordering}; -use std::fmt; -use std::iter::{once, IntoIterator}; -use std::ops::RangeInclusive; +use self::Constructor::*; +use self::SliceKind::*; + +use super::compare_const_vals; +use super::usefulness::{MatchCheckCtxt, PatCtxt}; /// Recursively expand this pattern into its subpatterns. Only useful for or-patterns. fn expand_or_pat<'p, 'tcx>(pat: &'p Pat<'tcx>) -> Vec<&'p Pat<'tcx>> { @@ -147,11 +147,7 @@ impl IntRange { // straight to the result, after doing a bit of checking. (We // could remove this branch and just fall through, which // is more general but much slower.) - if let Ok(Ok(bits)) = scalar.to_bits_or_ptr_internal(target_size) { - return Some(bits); - } else { - return None; - } + return scalar.to_bits_or_ptr_internal(target_size).unwrap().left(); } mir::ConstantKind::Ty(c) => match c.kind() { ty::ConstKind::Value(_) => bug!( diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index 8dc9976eaea..3e370a05376 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -324,7 +324,7 @@ pub(crate) struct MatchCheckCtxt<'p, 'tcx> { impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> { pub(super) fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool { if self.tcx.features().exhaustive_patterns { - self.tcx.is_ty_uninhabited_from(self.module, ty, self.param_env) + !ty.is_inhabited_from(self.tcx, self.module, self.param_env) } else { false } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 14d265a402e..ce87a1916b4 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -615,7 +615,7 @@ where let drop_trait = tcx.require_lang_item(LangItem::Drop, None); let drop_fn = tcx.associated_item_def_ids(drop_trait)[0]; let ty = self.place_ty(self.place); - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, []); let ref_ty = tcx.mk_ref(tcx.lifetimes.re_erased, ty::TypeAndMut { ty, mutbl: hir::Mutability::Mut }); diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index db4b0a3deda..cc69a1bb02d 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -899,7 +899,7 @@ fn debug_with_context_rec<V: Debug + Eq>( let info_elem = map.places[child].proj_elem.unwrap(); let child_place_str = match info_elem { TrackElem::Field(field) => { - if place_str.starts_with("*") { + if place_str.starts_with('*') { format!("({}).{}", place_str, field.index()) } else { format!("{}.{}", place_str, field.index()) diff --git a/compiler/rustc_mir_transform/Cargo.toml b/compiler/rustc_mir_transform/Cargo.toml index 53545cff0cb..962536669e0 100644 --- a/compiler/rustc_mir_transform/Cargo.toml +++ b/compiler/rustc_mir_transform/Cargo.toml @@ -9,6 +9,7 @@ edition = "2021" itertools = "0.10.1" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } tracing = "0.1" +either = "1" rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 3f5890040c3..b0514e03356 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -3,6 +3,8 @@ use std::cell::Cell; +use either::Right; + use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; @@ -429,7 +431,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Try to read the local as an immediate so that if it is representable as a scalar, we can // handle it as such, but otherwise, just return the value as is. Some(match self.ecx.read_immediate_raw(&op) { - Ok(Ok(imm)) => imm.into(), + Ok(Right(imm)) => imm.into(), _ => op, }) } @@ -743,7 +745,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // FIXME> figure out what to do when read_immediate_raw fails let imm = self.use_ecx(|this| this.ecx.read_immediate_raw(value)); - if let Some(Ok(imm)) = imm { + if let Some(Right(imm)) = imm { match *imm { interpret::Immediate::Scalar(scalar) => { *rval = Rvalue::Use(self.operand_from_scalar( diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 786063d538c..0ab67228f3f 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -1,10 +1,10 @@ //! Propagates constants for early reporting of statically known //! assertion failures -use crate::const_prop::CanConstProp; -use crate::const_prop::ConstPropMachine; -use crate::const_prop::ConstPropMode; -use crate::MirLint; +use std::cell::Cell; + +use either::{Left, Right}; + use rustc_const_eval::interpret::Immediate; use rustc_const_eval::interpret::{ self, InterpCx, InterpResult, LocalState, LocalValue, MemoryKind, OpTy, Scalar, StackPopCleanup, @@ -26,12 +26,17 @@ use rustc_session::lint; use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size, TargetDataLayout}; use rustc_trait_selection::traits; -use std::cell::Cell; + +use crate::const_prop::CanConstProp; +use crate::const_prop::ConstPropMachine; +use crate::const_prop::ConstPropMode; +use crate::MirLint; /// The maximum number of bytes that we'll allocate space for a local or the return value. /// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just /// Severely regress performance. const MAX_ALLOC_LIMIT: u64 = 1024; + pub struct ConstProp; impl<'tcx> MirLint<'tcx> for ConstProp { @@ -243,7 +248,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // Try to read the local as an immediate so that if it is representable as a scalar, we can // handle it as such, but otherwise, just return the value as is. Some(match self.ecx.read_immediate_raw(&op) { - Ok(Ok(imm)) => imm.into(), + Ok(Left(imm)) => imm.into(), _ => op, }) } @@ -266,7 +271,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { F: FnOnce(&mut Self) -> InterpResult<'tcx, T>, { // Overwrite the PC -- whatever the interpreter does to it does not make any sense anyway. - self.ecx.frame_mut().loc = Err(source_info.span); + self.ecx.frame_mut().loc = Right(source_info.span); match f(self) { Ok(val) => Some(val), Err(error) => { diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index c833de3a8a7..fcd63b6cfa1 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -1015,7 +1015,7 @@ fn insert_panic_block<'tcx>( fn can_return<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool { // Returning from a function with an uninhabited return type is undefined behavior. - if tcx.conservative_is_privately_uninhabited(param_env.and(body.return_ty())) { + if body.return_ty().is_privately_uninhabited(tcx, param_env) { return false; } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 780b91d9215..d7dd5fc8528 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -1,7 +1,6 @@ //! Inlining pass for MIR functions use crate::deref_separator::deref_finder; use rustc_attr::InlineAttr; -use rustc_const_eval::transform::validate::equal_up_to_regions; use rustc_index::bit_set::BitSet; use rustc_index::vec::Idx; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; @@ -14,7 +13,8 @@ use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; use rustc_target::abi::VariantIdx; use rustc_target::spec::abi::Abi; -use super::simplify::{remove_dead_blocks, CfgSimplifier}; +use crate::simplify::{remove_dead_blocks, CfgSimplifier}; +use crate::util; use crate::MirPass; use std::iter; use std::ops::{Range, RangeFrom}; @@ -180,7 +180,7 @@ impl<'tcx> Inliner<'tcx> { let TerminatorKind::Call { args, destination, .. } = &terminator.kind else { bug!() }; let destination_ty = destination.ty(&caller_body.local_decls, self.tcx).ty; let output_type = callee_body.return_ty(); - if !equal_up_to_regions(self.tcx, self.param_env, output_type, destination_ty) { + if !util::is_subtype(self.tcx, self.param_env, output_type, destination_ty) { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -200,7 +200,7 @@ impl<'tcx> Inliner<'tcx> { arg_tuple_tys.iter().zip(callee_body.args_iter().skip(skipped_args)) { let input_type = callee_body.local_decls[input].ty; - if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) { + if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -209,7 +209,7 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.ty(&caller_body.local_decls, self.tcx); - if !equal_up_to_regions(self.tcx, self.param_env, arg_ty, input_type) { + if !util::is_subtype(self.tcx, self.param_env, input_type, arg_ty) { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } @@ -847,7 +847,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) }; let parent_ty = parent.ty(&self.callee_body.local_decls, self.tcx); let check_equal = |this: &mut Self, f_ty| { - if !equal_up_to_regions(this.tcx, this.param_env, ty, f_ty) { + if !util::is_equal_up_to_subtyping(this.tcx, this.param_env, ty, f_ty) { trace!(?ty, ?f_ty); this.validation = Err("failed to normalize projection type"); return; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index a0ff7550fae..68703eb0a23 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -346,7 +346,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // we must subst the self_ty because it's // otherwise going to be TySelf and we can't index // or access fields of a Place of type TySelf. - let substs = tcx.mk_substs_trait(self_ty, &[]); + let substs = tcx.mk_substs_trait(self_ty, []); let sig = tcx.bound_fn_sig(def_id).subst(tcx, substs); let sig = tcx.erase_late_bound_regions(sig); let span = tcx.def_span(def_id); @@ -427,7 +427,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { ) { let tcx = self.tcx; - let substs = tcx.mk_substs_trait(ty, &[]); + let substs = tcx.mk_substs_trait(ty, []); // `func == Clone::clone(&ty) -> ty` let func_ty = tcx.mk_fn_def(self.def_id, substs); @@ -586,7 +586,7 @@ fn build_call_shim<'tcx>( // Create substitutions for the `Self` and `Args` generic parameters of the shim body. let arg_tup = tcx.mk_tup(untuple_args.iter()); - let sig_substs = tcx.mk_substs_trait(ty, &[ty::subst::GenericArg::from(arg_tup)]); + let sig_substs = tcx.mk_substs_trait(ty, [ty::subst::GenericArg::from(arg_tup)]); (Some(sig_substs), Some(untuple_args)) } else { diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index cdf8011d4f5..559ce227454 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -187,6 +187,7 @@ use rustc_middle::mir::visit::Visitor as MirVisitor; use rustc_middle::mir::{self, Local, Location}; use rustc_middle::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitable, VtblEntry, @@ -197,7 +198,6 @@ use rustc_session::lint::builtin::LARGE_ASSIGNMENTS; use rustc_session::Limit; use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP}; use rustc_target::abi::Size; -use std::iter; use std::ops::Range; use std::path::PathBuf; @@ -541,29 +541,23 @@ fn collect_items_rec<'tcx>( } /// Format instance name that is already known to be too long for rustc. -/// Show only the first and last 32 characters to avoid blasting +/// Show only the first 2 types if it is longer than 32 characters to avoid blasting /// the user's terminal with thousands of lines of type-name. /// /// If the type name is longer than before+after, it will be written to a file. fn shrunk_instance_name<'tcx>( tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>, - before: usize, - after: usize, ) -> (String, Option<PathBuf>) { let s = instance.to_string(); // Only use the shrunk version if it's really shorter. // This also avoids the case where before and after slices overlap. - if s.chars().nth(before + after + 1).is_some() { - // An iterator of all byte positions including the end of the string. - let positions = || s.char_indices().map(|(i, _)| i).chain(iter::once(s.len())); - - let shrunk = format!( - "{before}...{after}", - before = &s[..positions().nth(before).unwrap_or(s.len())], - after = &s[positions().rev().nth(after).unwrap_or(0)..], - ); + if s.chars().nth(33).is_some() { + let shrunk = format!("{}", ty::ShortInstance(instance, 4)); + if shrunk == s { + return (s, None); + } let path = tcx.output_filenames(()).temp_path_ext("long-type.txt", None); let written_to_path = std::fs::write(&path, s).ok().map(|_| path); @@ -599,7 +593,7 @@ fn check_recursion_limit<'tcx>( if !recursion_limit.value_within_limit(adjusted_recursion_depth) { let def_span = tcx.def_span(def_id); let def_path_str = tcx.def_path_str(def_id); - let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32); + let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let mut path = PathBuf::new(); let was_written = if written_to_path.is_some() { path = written_to_path.unwrap(); @@ -641,7 +635,7 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { // // Bail out in these cases to avoid that bad user experience. if !tcx.type_length_limit().value_within_limit(type_length) { - let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance, 32, 32); + let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let span = tcx.def_span(instance.def_id()); let mut path = PathBuf::new(); let was_written = if written_to_path.is_some() { @@ -695,7 +689,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { let source_ty = operand.ty(self.body, self.tcx); let source_ty = self.monomorphize(source_ty); let (source_ty, target_ty) = - find_vtable_types_for_unsizing(self.tcx, source_ty, target_ty); + find_vtable_types_for_unsizing(self.tcx.at(span), source_ty, target_ty); // This could also be a different Unsize instruction, like // from a fixed sized array to a slice. But we are only // interested in things that produce a vtable. @@ -1060,14 +1054,14 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) -> /// Finally, there is also the case of custom unsizing coercions, e.g., for /// smart pointers such as `Rc` and `Arc`. fn find_vtable_types_for_unsizing<'tcx>( - tcx: TyCtxt<'tcx>, + tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> (Ty<'tcx>, Ty<'tcx>) { let ptr_vtable = |inner_source: Ty<'tcx>, inner_target: Ty<'tcx>| { let param_env = ty::ParamEnv::reveal_all(); let type_has_metadata = |ty: Ty<'tcx>| -> bool { - if ty.is_sized(tcx, param_env) { + if ty.is_sized(tcx.tcx, param_env) { return false; } let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env); @@ -1111,8 +1105,8 @@ fn find_vtable_types_for_unsizing<'tcx>( find_vtable_types_for_unsizing( tcx, - source_fields[coerce_index].ty(tcx, source_substs), - target_fields[coerce_index].ty(tcx, target_substs), + source_fields[coerce_index].ty(*tcx, source_substs), + target_fields[coerce_index].ty(*tcx, target_substs), ) } _ => bug!( diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs index 42781bd25f0..b616ed35d99 100644 --- a/compiler/rustc_monomorphize/src/lib.rs +++ b/compiler/rustc_monomorphize/src/lib.rs @@ -13,8 +13,8 @@ extern crate rustc_middle; use rustc_hir::lang_items::LangItem; use rustc_middle::traits; use rustc_middle::ty::adjustment::CustomCoerceUnsized; -use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::query::{Providers, TyCtxtAt}; +use rustc_middle::ty::{self, Ty}; mod collector; mod errors; @@ -23,16 +23,12 @@ mod polymorphize; mod util; fn custom_coerce_unsize_info<'tcx>( - tcx: TyCtxt<'tcx>, + tcx: TyCtxtAt<'tcx>, source_ty: Ty<'tcx>, target_ty: Ty<'tcx>, ) -> CustomCoerceUnsized { - let def_id = tcx.require_lang_item(LangItem::CoerceUnsized, None); - - let trait_ref = ty::Binder::dummy(ty::TraitRef { - def_id, - substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()]), - }); + let trait_ref = + ty::Binder::dummy(tcx.mk_trait_ref(LangItem::CoerceUnsized, [source_ty, target_ty])); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), trait_ref)) { Ok(traits::ImplSource::UserDefined(traits::ImplSourceUserDefinedData { diff --git a/compiler/rustc_parse/Cargo.toml b/compiler/rustc_parse/Cargo.toml index a5c94e16403..dbcfb390333 100644 --- a/compiler/rustc_parse/Cargo.toml +++ b/compiler/rustc_parse/Cargo.toml @@ -7,15 +7,16 @@ edition = "2021" [dependencies] bitflags = "1.0" -tracing = "0.1" +rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_data_structures = { path = "../rustc_data_structures" } +rustc_errors = { path = "../rustc_errors" } rustc_feature = { path = "../rustc_feature" } rustc_lexer = { path = "../rustc_lexer" } rustc_macros = { path = "../rustc_macros" } -rustc_errors = { path = "../rustc_errors" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_ast = { path = "../rustc_ast" } +thin-vec = "0.2.8" +tracing = "0.1" unicode-normalization = "0.1.11" unicode-width = "0.1.4" diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 724d92254a4..9875cde4a05 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -9,7 +9,7 @@ use rustc_span::{Span, Symbol}; use crate::parser::TokenDescription; #[derive(Diagnostic)] -#[diag(parser_maybe_report_ambiguous_plus)] +#[diag(parse_maybe_report_ambiguous_plus)] pub(crate) struct AmbiguousPlus { pub sum_ty: String, #[primary_span] @@ -18,7 +18,7 @@ pub(crate) struct AmbiguousPlus { } #[derive(Diagnostic)] -#[diag(parser_maybe_recover_from_bad_type_plus, code = "E0178")] +#[diag(parse_maybe_recover_from_bad_type_plus, code = "E0178")] pub(crate) struct BadTypePlus { pub ty: String, #[primary_span] @@ -30,7 +30,7 @@ pub(crate) struct BadTypePlus { #[derive(Subdiagnostic)] pub(crate) enum BadTypePlusSub { #[suggestion( - parser_add_paren, + parse_add_paren, code = "{sum_with_parens}", applicability = "machine-applicable" )] @@ -39,12 +39,12 @@ pub(crate) enum BadTypePlusSub { #[primary_span] span: Span, }, - #[label(parser_forgot_paren)] + #[label(parse_forgot_paren)] ForgotParen { #[primary_span] span: Span, }, - #[label(parser_expect_path)] + #[label(parse_expect_path)] ExpectPath { #[primary_span] span: Span, @@ -52,7 +52,7 @@ pub(crate) enum BadTypePlusSub { } #[derive(Diagnostic)] -#[diag(parser_maybe_recover_from_bad_qpath_stage_2)] +#[diag(parse_maybe_recover_from_bad_qpath_stage_2)] pub(crate) struct BadQPathStage2 { #[primary_span] #[suggestion(code = "", applicability = "maybe-incorrect")] @@ -61,7 +61,7 @@ pub(crate) struct BadQPathStage2 { } #[derive(Diagnostic)] -#[diag(parser_incorrect_semicolon)] +#[diag(parse_incorrect_semicolon)] pub(crate) struct IncorrectSemicolon<'a> { #[primary_span] #[suggestion(style = "short", code = "", applicability = "machine-applicable")] @@ -72,7 +72,7 @@ pub(crate) struct IncorrectSemicolon<'a> { } #[derive(Diagnostic)] -#[diag(parser_incorrect_use_of_await)] +#[diag(parse_incorrect_use_of_await)] pub(crate) struct IncorrectUseOfAwait { #[primary_span] #[suggestion(parentheses_suggestion, code = "", applicability = "machine-applicable")] @@ -80,7 +80,7 @@ pub(crate) struct IncorrectUseOfAwait { } #[derive(Diagnostic)] -#[diag(parser_incorrect_use_of_await)] +#[diag(parse_incorrect_use_of_await)] pub(crate) struct IncorrectAwait { #[primary_span] pub span: Span, @@ -91,7 +91,7 @@ pub(crate) struct IncorrectAwait { } #[derive(Diagnostic)] -#[diag(parser_in_in_typo)] +#[diag(parse_in_in_typo)] pub(crate) struct InInTypo { #[primary_span] pub span: Span, @@ -100,7 +100,7 @@ pub(crate) struct InInTypo { } #[derive(Diagnostic)] -#[diag(parser_invalid_variable_declaration)] +#[diag(parse_invalid_variable_declaration)] pub(crate) struct InvalidVariableDeclaration { #[primary_span] pub span: Span, @@ -110,22 +110,22 @@ pub(crate) struct InvalidVariableDeclaration { #[derive(Subdiagnostic)] pub(crate) enum InvalidVariableDeclarationSub { - #[suggestion(parser_switch_mut_let_order, applicability = "maybe-incorrect", code = "let mut")] + #[suggestion(parse_switch_mut_let_order, applicability = "maybe-incorrect", code = "let mut")] SwitchMutLetOrder(#[primary_span] Span), #[suggestion( - parser_missing_let_before_mut, + parse_missing_let_before_mut, applicability = "machine-applicable", code = "let mut" )] MissingLet(#[primary_span] Span), - #[suggestion(parser_use_let_not_auto, applicability = "machine-applicable", code = "let")] + #[suggestion(parse_use_let_not_auto, applicability = "machine-applicable", code = "let")] UseLetNotAuto(#[primary_span] Span), - #[suggestion(parser_use_let_not_var, applicability = "machine-applicable", code = "let")] + #[suggestion(parse_use_let_not_var, applicability = "machine-applicable", code = "let")] UseLetNotVar(#[primary_span] Span), } #[derive(Diagnostic)] -#[diag(parser_invalid_comparison_operator)] +#[diag(parse_invalid_comparison_operator)] pub(crate) struct InvalidComparisonOperator { #[primary_span] pub span: Span, @@ -153,7 +153,7 @@ pub(crate) enum InvalidComparisonOperatorSub { } #[derive(Diagnostic)] -#[diag(parser_invalid_logical_operator)] +#[diag(parse_invalid_logical_operator)] #[note] pub(crate) struct InvalidLogicalOperator { #[primary_span] @@ -182,7 +182,7 @@ pub(crate) enum InvalidLogicalOperatorSub { } #[derive(Diagnostic)] -#[diag(parser_tilde_is_not_unary_operator)] +#[diag(parse_tilde_is_not_unary_operator)] pub(crate) struct TildeAsUnaryOperator( #[primary_span] #[suggestion(style = "short", applicability = "machine-applicable", code = "!")] @@ -190,7 +190,7 @@ pub(crate) struct TildeAsUnaryOperator( ); #[derive(Diagnostic)] -#[diag(parser_unexpected_token_after_not)] +#[diag(parse_unexpected_token_after_not)] pub(crate) struct NotAsNegationOperator { #[primary_span] pub negated: Span, @@ -202,7 +202,7 @@ pub(crate) struct NotAsNegationOperator { #[derive(Subdiagnostic)] pub enum NotAsNegationOperatorSub { #[suggestion( - parser_unexpected_token_after_not_default, + parse_unexpected_token_after_not_default, style = "short", applicability = "machine-applicable", code = "!" @@ -210,7 +210,7 @@ pub enum NotAsNegationOperatorSub { SuggestNotDefault(#[primary_span] Span), #[suggestion( - parser_unexpected_token_after_not_bitwise, + parse_unexpected_token_after_not_bitwise, style = "short", applicability = "machine-applicable", code = "!" @@ -218,7 +218,7 @@ pub enum NotAsNegationOperatorSub { SuggestNotBitwise(#[primary_span] Span), #[suggestion( - parser_unexpected_token_after_not_logical, + parse_unexpected_token_after_not_logical, style = "short", applicability = "machine-applicable", code = "!" @@ -227,7 +227,7 @@ pub enum NotAsNegationOperatorSub { } #[derive(Diagnostic)] -#[diag(parser_malformed_loop_label)] +#[diag(parse_malformed_loop_label)] pub(crate) struct MalformedLoopLabel { #[primary_span] #[suggestion(applicability = "machine-applicable", code = "{correct_label}")] @@ -236,7 +236,7 @@ pub(crate) struct MalformedLoopLabel { } #[derive(Diagnostic)] -#[diag(parser_lifetime_in_borrow_expression)] +#[diag(parse_lifetime_in_borrow_expression)] pub(crate) struct LifetimeInBorrowExpression { #[primary_span] pub span: Span, @@ -246,18 +246,18 @@ pub(crate) struct LifetimeInBorrowExpression { } #[derive(Diagnostic)] -#[diag(parser_field_expression_with_generic)] +#[diag(parse_field_expression_with_generic)] pub(crate) struct FieldExpressionWithGeneric(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parser_macro_invocation_with_qualified_path)] +#[diag(parse_macro_invocation_with_qualified_path)] pub(crate) struct MacroInvocationWithQualifiedPath(#[primary_span] pub Span); #[derive(Diagnostic)] -#[diag(parser_unexpected_token_after_label)] +#[diag(parse_unexpected_token_after_label)] pub(crate) struct UnexpectedTokenAfterLabel { #[primary_span] - #[label(parser_unexpected_token_after_label)] + #[label(parse_unexpected_token_after_label)] pub span: Span, #[suggestion(suggestion_remove_label, style = "verbose", code = "")] pub remove_label: Option<Span>, @@ -275,7 +275,7 @@ pub(crate) struct UnexpectedTokenAfterLabelSugg { } #[derive(Diagnostic)] -#[diag(parser_require_colon_after_labeled_expression)] +#[diag(parse_require_colon_after_labeled_expression)] #[note] pub(crate) struct RequireColonAfterLabeledExpression { #[primary_span] @@ -287,7 +287,7 @@ pub(crate) struct RequireColonAfterLabeledExpression { } #[derive(Diagnostic)] -#[diag(parser_do_catch_syntax_removed)] +#[diag(parse_do_catch_syntax_removed)] #[note] pub(crate) struct DoCatchSyntaxRemoved { #[primary_span] @@ -296,7 +296,7 @@ pub(crate) struct DoCatchSyntaxRemoved { } #[derive(Diagnostic)] -#[diag(parser_float_literal_requires_integer_part)] +#[diag(parse_float_literal_requires_integer_part)] pub(crate) struct FloatLiteralRequiresIntegerPart { #[primary_span] #[suggestion(applicability = "machine-applicable", code = "{correct}")] @@ -305,7 +305,7 @@ pub(crate) struct FloatLiteralRequiresIntegerPart { } #[derive(Diagnostic)] -#[diag(parser_missing_semicolon_before_array)] +#[diag(parse_missing_semicolon_before_array)] pub(crate) struct MissingSemicolonBeforeArray { #[primary_span] pub open_delim: Span, @@ -314,7 +314,7 @@ pub(crate) struct MissingSemicolonBeforeArray { } #[derive(Diagnostic)] -#[diag(parser_expect_dotdot_not_dotdotdot)] +#[diag(parse_expect_dotdot_not_dotdotdot)] pub(crate) struct MissingDotDot { #[primary_span] pub token_span: Span, @@ -323,7 +323,7 @@ pub(crate) struct MissingDotDot { } #[derive(Diagnostic)] -#[diag(parser_invalid_block_macro_segment)] +#[diag(parse_invalid_block_macro_segment)] pub(crate) struct InvalidBlockMacroSegment { #[primary_span] pub span: Span, @@ -332,7 +332,7 @@ pub(crate) struct InvalidBlockMacroSegment { } #[derive(Diagnostic)] -#[diag(parser_if_expression_missing_then_block)] +#[diag(parse_if_expression_missing_then_block)] pub(crate) struct IfExpressionMissingThenBlock { #[primary_span] pub if_span: Span, @@ -349,7 +349,7 @@ pub(crate) enum IfExpressionMissingThenBlockSub { } #[derive(Diagnostic)] -#[diag(parser_if_expression_missing_condition)] +#[diag(parse_if_expression_missing_condition)] pub(crate) struct IfExpressionMissingCondition { #[primary_span] #[label(condition_label)] @@ -359,14 +359,14 @@ pub(crate) struct IfExpressionMissingCondition { } #[derive(Diagnostic)] -#[diag(parser_expected_expression_found_let)] +#[diag(parse_expected_expression_found_let)] pub(crate) struct ExpectedExpressionFoundLet { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_expect_eq_instead_of_eqeq)] +#[diag(parse_expect_eq_instead_of_eqeq)] pub(crate) struct ExpectedEqForLetExpr { #[primary_span] pub span: Span, @@ -375,7 +375,7 @@ pub(crate) struct ExpectedEqForLetExpr { } #[derive(Diagnostic)] -#[diag(parser_expected_else_block)] +#[diag(parse_expected_else_block)] pub(crate) struct ExpectedElseBlock { #[primary_span] pub first_tok_span: Span, @@ -387,7 +387,7 @@ pub(crate) struct ExpectedElseBlock { } #[derive(Diagnostic)] -#[diag(parser_outer_attribute_not_allowed_on_if_else)] +#[diag(parse_outer_attribute_not_allowed_on_if_else)] pub(crate) struct OuterAttributeNotAllowedOnIfElse { #[primary_span] pub last: Span, @@ -404,7 +404,7 @@ pub(crate) struct OuterAttributeNotAllowedOnIfElse { } #[derive(Diagnostic)] -#[diag(parser_missing_in_in_for_loop)] +#[diag(parse_missing_in_in_for_loop)] pub(crate) struct MissingInInForLoop { #[primary_span] pub span: Span, @@ -422,7 +422,7 @@ pub(crate) enum MissingInInForLoopSub { } #[derive(Diagnostic)] -#[diag(parser_missing_comma_after_match_arm)] +#[diag(parse_missing_comma_after_match_arm)] pub(crate) struct MissingCommaAfterMatchArm { #[primary_span] #[suggestion(applicability = "machine-applicable", code = ",")] @@ -430,7 +430,7 @@ pub(crate) struct MissingCommaAfterMatchArm { } #[derive(Diagnostic)] -#[diag(parser_catch_after_try)] +#[diag(parse_catch_after_try)] #[help] pub(crate) struct CatchAfterTry { #[primary_span] @@ -438,7 +438,7 @@ pub(crate) struct CatchAfterTry { } #[derive(Diagnostic)] -#[diag(parser_comma_after_base_struct)] +#[diag(parse_comma_after_base_struct)] #[note] pub(crate) struct CommaAfterBaseStruct { #[primary_span] @@ -448,7 +448,7 @@ pub(crate) struct CommaAfterBaseStruct { } #[derive(Diagnostic)] -#[diag(parser_eq_field_init)] +#[diag(parse_eq_field_init)] pub(crate) struct EqFieldInit { #[primary_span] pub span: Span, @@ -457,7 +457,7 @@ pub(crate) struct EqFieldInit { } #[derive(Diagnostic)] -#[diag(parser_dotdotdot)] +#[diag(parse_dotdotdot)] pub(crate) struct DotDotDot { #[primary_span] #[suggestion(suggest_exclusive_range, applicability = "maybe-incorrect", code = "..")] @@ -466,7 +466,7 @@ pub(crate) struct DotDotDot { } #[derive(Diagnostic)] -#[diag(parser_left_arrow_operator)] +#[diag(parse_left_arrow_operator)] pub(crate) struct LeftArrowOperator { #[primary_span] #[suggestion(applicability = "maybe-incorrect", code = "< -")] @@ -474,7 +474,7 @@ pub(crate) struct LeftArrowOperator { } #[derive(Diagnostic)] -#[diag(parser_remove_let)] +#[diag(parse_remove_let)] pub(crate) struct RemoveLet { #[primary_span] #[suggestion(applicability = "machine-applicable", code = "")] @@ -482,7 +482,7 @@ pub(crate) struct RemoveLet { } #[derive(Diagnostic)] -#[diag(parser_use_eq_instead)] +#[diag(parse_use_eq_instead)] pub(crate) struct UseEqInstead { #[primary_span] #[suggestion(style = "short", applicability = "machine-applicable", code = "=")] @@ -490,7 +490,7 @@ pub(crate) struct UseEqInstead { } #[derive(Diagnostic)] -#[diag(parser_use_empty_block_not_semi)] +#[diag(parse_use_empty_block_not_semi)] pub(crate) struct UseEmptyBlockNotSemi { #[primary_span] #[suggestion(style = "hidden", applicability = "machine-applicable", code = "{{}}")] @@ -498,7 +498,7 @@ pub(crate) struct UseEmptyBlockNotSemi { } #[derive(Diagnostic)] -#[diag(parser_comparison_interpreted_as_generic)] +#[diag(parse_comparison_interpreted_as_generic)] pub(crate) struct ComparisonInterpretedAsGeneric { #[primary_span] #[label(label_comparison)] @@ -511,7 +511,7 @@ pub(crate) struct ComparisonInterpretedAsGeneric { } #[derive(Diagnostic)] -#[diag(parser_shift_interpreted_as_generic)] +#[diag(parse_shift_interpreted_as_generic)] pub(crate) struct ShiftInterpretedAsGeneric { #[primary_span] #[label(label_comparison)] @@ -533,7 +533,7 @@ pub(crate) struct ComparisonOrShiftInterpretedAsGenericSugg { } #[derive(Diagnostic)] -#[diag(parser_found_expr_would_be_stmt)] +#[diag(parse_found_expr_would_be_stmt)] pub(crate) struct FoundExprWouldBeStmt { #[primary_span] #[label] @@ -544,7 +544,7 @@ pub(crate) struct FoundExprWouldBeStmt { } #[derive(Diagnostic)] -#[diag(parser_leading_plus_not_supported)] +#[diag(parse_leading_plus_not_supported)] pub(crate) struct LeadingPlusNotSupported { #[primary_span] #[label] @@ -561,7 +561,7 @@ pub(crate) struct LeadingPlusNotSupported { } #[derive(Diagnostic)] -#[diag(parser_parentheses_with_struct_fields)] +#[diag(parse_parentheses_with_struct_fields)] pub(crate) struct ParenthesesWithStructFields { #[primary_span] pub span: Span, @@ -589,7 +589,7 @@ pub(crate) struct NoFieldsForFnCall { } #[derive(Diagnostic)] -#[diag(parser_labeled_loop_in_break)] +#[diag(parse_labeled_loop_in_break)] pub(crate) struct LabeledLoopInBreak { #[primary_span] pub span: Span, @@ -599,7 +599,7 @@ pub(crate) struct LabeledLoopInBreak { #[derive(Subdiagnostic)] #[multipart_suggestion( - parser_sugg_wrap_expression_in_parentheses, + parse_sugg_wrap_expression_in_parentheses, applicability = "machine-applicable" )] pub(crate) struct WrapExpressionInParentheses { @@ -610,7 +610,7 @@ pub(crate) struct WrapExpressionInParentheses { } #[derive(Diagnostic)] -#[diag(parser_array_brackets_instead_of_braces)] +#[diag(parse_array_brackets_instead_of_braces)] pub(crate) struct ArrayBracketsInsteadOfSpaces { #[primary_span] pub span: Span, @@ -628,7 +628,7 @@ pub(crate) struct ArrayBracketsInsteadOfSpacesSugg { } #[derive(Diagnostic)] -#[diag(parser_match_arm_body_without_braces)] +#[diag(parse_match_arm_body_without_braces)] pub(crate) struct MatchArmBodyWithoutBraces { #[primary_span] #[label(label_statements)] @@ -661,7 +661,7 @@ pub(crate) enum MatchArmBodyWithoutBracesSugg { } #[derive(Diagnostic)] -#[diag(parser_struct_literal_not_allowed_here)] +#[diag(parse_struct_literal_not_allowed_here)] pub(crate) struct StructLiteralNotAllowedHere { #[primary_span] pub span: Span, @@ -679,14 +679,14 @@ pub(crate) struct StructLiteralNotAllowedHereSugg { } #[derive(Diagnostic)] -#[diag(parser_invalid_interpolated_expression)] +#[diag(parse_invalid_interpolated_expression)] pub(crate) struct InvalidInterpolatedExpression { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_invalid_literal_suffix_on_tuple_index)] +#[diag(parse_invalid_literal_suffix_on_tuple_index)] pub(crate) struct InvalidLiteralSuffixOnTupleIndex { #[primary_span] #[label] @@ -699,7 +699,7 @@ pub(crate) struct InvalidLiteralSuffixOnTupleIndex { } #[derive(Diagnostic)] -#[diag(parser_non_string_abi_literal)] +#[diag(parse_non_string_abi_literal)] pub(crate) struct NonStringAbiLiteral { #[primary_span] #[suggestion(code = "\"C\"", applicability = "maybe-incorrect")] @@ -707,7 +707,7 @@ pub(crate) struct NonStringAbiLiteral { } #[derive(Diagnostic)] -#[diag(parser_mismatched_closing_delimiter)] +#[diag(parse_mismatched_closing_delimiter)] pub(crate) struct MismatchedClosingDelimiter { #[primary_span] pub spans: Vec<Span>, @@ -721,7 +721,7 @@ pub(crate) struct MismatchedClosingDelimiter { } #[derive(Diagnostic)] -#[diag(parser_incorrect_visibility_restriction, code = "E0704")] +#[diag(parse_incorrect_visibility_restriction, code = "E0704")] #[help] pub(crate) struct IncorrectVisibilityRestriction { #[primary_span] @@ -731,21 +731,21 @@ pub(crate) struct IncorrectVisibilityRestriction { } #[derive(Diagnostic)] -#[diag(parser_assignment_else_not_allowed)] +#[diag(parse_assignment_else_not_allowed)] pub(crate) struct AssignmentElseNotAllowed { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_expected_statement_after_outer_attr)] +#[diag(parse_expected_statement_after_outer_attr)] pub(crate) struct ExpectedStatementAfterOuterAttr { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_doc_comment_does_not_document_anything, code = "E0585")] +#[diag(parse_doc_comment_does_not_document_anything, code = "E0585")] #[help] pub(crate) struct DocCommentDoesNotDocumentAnything { #[primary_span] @@ -755,7 +755,7 @@ pub(crate) struct DocCommentDoesNotDocumentAnything { } #[derive(Diagnostic)] -#[diag(parser_const_let_mutually_exclusive)] +#[diag(parse_const_let_mutually_exclusive)] pub(crate) struct ConstLetMutuallyExclusive { #[primary_span] #[suggestion(code = "const", applicability = "maybe-incorrect")] @@ -763,7 +763,7 @@ pub(crate) struct ConstLetMutuallyExclusive { } #[derive(Diagnostic)] -#[diag(parser_invalid_expression_in_let_else)] +#[diag(parse_invalid_expression_in_let_else)] pub(crate) struct InvalidExpressionInLetElse { #[primary_span] pub span: Span, @@ -773,7 +773,7 @@ pub(crate) struct InvalidExpressionInLetElse { } #[derive(Diagnostic)] -#[diag(parser_invalid_curly_in_let_else)] +#[diag(parse_invalid_curly_in_let_else)] pub(crate) struct InvalidCurlyInLetElse { #[primary_span] pub span: Span, @@ -782,7 +782,7 @@ pub(crate) struct InvalidCurlyInLetElse { } #[derive(Diagnostic)] -#[diag(parser_compound_assignment_expression_in_let)] +#[diag(parse_compound_assignment_expression_in_let)] #[help] pub(crate) struct CompoundAssignmentExpressionInLet { #[primary_span] @@ -791,7 +791,7 @@ pub(crate) struct CompoundAssignmentExpressionInLet { } #[derive(Diagnostic)] -#[diag(parser_suffixed_literal_in_attribute)] +#[diag(parse_suffixed_literal_in_attribute)] #[help] pub(crate) struct SuffixedLiteralInAttribute { #[primary_span] @@ -799,7 +799,7 @@ pub(crate) struct SuffixedLiteralInAttribute { } #[derive(Diagnostic)] -#[diag(parser_invalid_meta_item)] +#[diag(parse_invalid_meta_item)] pub(crate) struct InvalidMetaItem { #[primary_span] pub span: Span, @@ -808,7 +808,7 @@ pub(crate) struct InvalidMetaItem { #[derive(Subdiagnostic)] #[suggestion( - parser_sugg_escape_to_use_as_identifier, + parse_sugg_escape_to_use_as_identifier, style = "verbose", applicability = "maybe-incorrect", code = "r#" @@ -820,7 +820,7 @@ pub(crate) struct SuggEscapeToUseAsIdentifier { } #[derive(Subdiagnostic)] -#[suggestion(parser_sugg_remove_comma, applicability = "machine-applicable", code = "")] +#[suggestion(parse_sugg_remove_comma, applicability = "machine-applicable", code = "")] pub(crate) struct SuggRemoveComma { #[primary_span] pub span: Span, @@ -828,15 +828,15 @@ pub(crate) struct SuggRemoveComma { #[derive(Subdiagnostic)] pub(crate) enum ExpectedIdentifierFound { - #[label(parser_expected_identifier_found_reserved_identifier)] + #[label(parse_expected_identifier_found_reserved_identifier)] ReservedIdentifier(#[primary_span] Span), - #[label(parser_expected_identifier_found_keyword)] + #[label(parse_expected_identifier_found_keyword)] Keyword(#[primary_span] Span), - #[label(parser_expected_identifier_found_reserved_keyword)] + #[label(parse_expected_identifier_found_reserved_keyword)] ReservedKeyword(#[primary_span] Span), - #[label(parser_expected_identifier_found_doc_comment)] + #[label(parse_expected_identifier_found_doc_comment)] DocComment(#[primary_span] Span), - #[label(parser_expected_identifier)] + #[label(parse_expected_identifier)] Other(#[primary_span] Span), } @@ -871,16 +871,16 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier { let mut diag = handler.struct_diagnostic(match token_descr { Some(TokenDescription::ReservedIdentifier) => { - fluent::parser_expected_identifier_found_reserved_identifier_str + fluent::parse_expected_identifier_found_reserved_identifier_str } - Some(TokenDescription::Keyword) => fluent::parser_expected_identifier_found_keyword_str, + Some(TokenDescription::Keyword) => fluent::parse_expected_identifier_found_keyword_str, Some(TokenDescription::ReservedKeyword) => { - fluent::parser_expected_identifier_found_reserved_keyword_str + fluent::parse_expected_identifier_found_reserved_keyword_str } Some(TokenDescription::DocComment) => { - fluent::parser_expected_identifier_found_doc_comment_str + fluent::parse_expected_identifier_found_doc_comment_str } - None => fluent::parser_expected_identifier_found_str, + None => fluent::parse_expected_identifier_found_str, }); diag.set_span(self.span); diag.set_arg("token", self.token); @@ -917,22 +917,20 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { let mut diag = handler.struct_diagnostic(match token_descr { Some(TokenDescription::ReservedIdentifier) => { - fluent::parser_expected_semi_found_reserved_identifier_str + fluent::parse_expected_semi_found_reserved_identifier_str } - Some(TokenDescription::Keyword) => fluent::parser_expected_semi_found_keyword_str, + Some(TokenDescription::Keyword) => fluent::parse_expected_semi_found_keyword_str, Some(TokenDescription::ReservedKeyword) => { - fluent::parser_expected_semi_found_reserved_keyword_str + fluent::parse_expected_semi_found_reserved_keyword_str } - Some(TokenDescription::DocComment) => { - fluent::parser_expected_semi_found_doc_comment_str - } - None => fluent::parser_expected_semi_found_str, + Some(TokenDescription::DocComment) => fluent::parse_expected_semi_found_doc_comment_str, + None => fluent::parse_expected_semi_found_str, }); diag.set_span(self.span); diag.set_arg("token", self.token); if let Some(unexpected_token_label) = self.unexpected_token_label { - diag.span_label(unexpected_token_label, fluent::parser_label_unexpected_token); + diag.span_label(unexpected_token_label, fluent::parse_label_unexpected_token); } self.sugg.add_to_diagnostic(&mut diag); @@ -943,14 +941,10 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi { #[derive(Subdiagnostic)] pub(crate) enum ExpectedSemiSugg { - #[suggestion( - parser_sugg_change_this_to_semi, - code = ";", - applicability = "machine-applicable" - )] + #[suggestion(parse_sugg_change_this_to_semi, code = ";", applicability = "machine-applicable")] ChangeToSemi(#[primary_span] Span), #[suggestion( - parser_sugg_add_semi, + parse_sugg_add_semi, style = "short", code = ";", applicability = "machine-applicable" @@ -959,7 +953,7 @@ pub(crate) enum ExpectedSemiSugg { } #[derive(Diagnostic)] -#[diag(parser_struct_literal_body_without_path)] +#[diag(parse_struct_literal_body_without_path)] pub(crate) struct StructLiteralBodyWithoutPath { #[primary_span] pub span: Span, @@ -977,7 +971,7 @@ pub(crate) struct StructLiteralBodyWithoutPathSugg { } #[derive(Diagnostic)] -#[diag(parser_unmatched_angle_brackets)] +#[diag(parse_unmatched_angle_brackets)] pub(crate) struct UnmatchedAngleBrackets { #[primary_span] #[suggestion(code = "", applicability = "machine-applicable")] @@ -986,7 +980,7 @@ pub(crate) struct UnmatchedAngleBrackets { } #[derive(Diagnostic)] -#[diag(parser_generic_parameters_without_angle_brackets)] +#[diag(parse_generic_parameters_without_angle_brackets)] pub(crate) struct GenericParamsWithoutAngleBrackets { #[primary_span] pub span: Span, @@ -1004,18 +998,18 @@ pub(crate) struct GenericParamsWithoutAngleBracketsSugg { } #[derive(Diagnostic)] -#[diag(parser_comparison_operators_cannot_be_chained)] +#[diag(parse_comparison_operators_cannot_be_chained)] pub(crate) struct ComparisonOperatorsCannotBeChained { #[primary_span] pub span: Vec<Span>, #[suggestion( - parser_sugg_turbofish_syntax, + parse_sugg_turbofish_syntax, style = "verbose", code = "::", applicability = "maybe-incorrect" )] pub suggest_turbofish: Option<Span>, - #[help(parser_sugg_turbofish_syntax)] + #[help(parse_sugg_turbofish_syntax)] #[help(sugg_parentheses_for_function_args)] pub help_turbofish: Option<()>, #[subdiagnostic] @@ -1045,7 +1039,7 @@ pub(crate) enum ComparisonOperatorsCannotBeChainedSugg { } #[derive(Diagnostic)] -#[diag(parser_question_mark_in_type)] +#[diag(parse_question_mark_in_type)] pub(crate) struct QuestionMarkInType { #[primary_span] #[label] @@ -1064,7 +1058,7 @@ pub(crate) struct QuestionMarkInTypeSugg { } #[derive(Diagnostic)] -#[diag(parser_unexpected_parentheses_in_for_head)] +#[diag(parse_unexpected_parentheses_in_for_head)] pub(crate) struct ParenthesesInForHead { #[primary_span] pub span: Vec<Span>, @@ -1084,7 +1078,7 @@ pub(crate) struct ParenthesesInForHeadSugg { } #[derive(Diagnostic)] -#[diag(parser_doc_comment_on_param_type)] +#[diag(parse_doc_comment_on_param_type)] pub(crate) struct DocCommentOnParamType { #[primary_span] #[label] @@ -1092,7 +1086,7 @@ pub(crate) struct DocCommentOnParamType { } #[derive(Diagnostic)] -#[diag(parser_attribute_on_param_type)] +#[diag(parse_attribute_on_param_type)] pub(crate) struct AttributeOnParamType { #[primary_span] #[label] @@ -1100,7 +1094,7 @@ pub(crate) struct AttributeOnParamType { } #[derive(Diagnostic)] -#[diag(parser_pattern_method_param_without_body, code = "E0642")] +#[diag(parse_pattern_method_param_without_body, code = "E0642")] pub(crate) struct PatternMethodParamWithoutBody { #[primary_span] #[suggestion(code = "_", applicability = "machine-applicable")] @@ -1108,7 +1102,7 @@ pub(crate) struct PatternMethodParamWithoutBody { } #[derive(Diagnostic)] -#[diag(parser_self_param_not_first)] +#[diag(parse_self_param_not_first)] pub(crate) struct SelfParamNotFirst { #[primary_span] #[label] @@ -1116,7 +1110,7 @@ pub(crate) struct SelfParamNotFirst { } #[derive(Diagnostic)] -#[diag(parser_invalid_identifier_with_leading_number)] +#[diag(parse_invalid_identifier_with_leading_number)] pub(crate) struct InvalidIdentiferStartsWithNumber { #[primary_span] #[label] @@ -1124,7 +1118,7 @@ pub(crate) struct InvalidIdentiferStartsWithNumber { } #[derive(Diagnostic)] -#[diag(parser_const_generic_without_braces)] +#[diag(parse_const_generic_without_braces)] pub(crate) struct ConstGenericWithoutBraces { #[primary_span] pub span: Span, @@ -1142,7 +1136,7 @@ pub(crate) struct ConstGenericWithoutBracesSugg { } #[derive(Diagnostic)] -#[diag(parser_unexpected_const_param_declaration)] +#[diag(parse_unexpected_const_param_declaration)] pub(crate) struct UnexpectedConstParamDeclaration { #[primary_span] #[label] @@ -1174,7 +1168,7 @@ pub(crate) enum UnexpectedConstParamDeclarationSugg { } #[derive(Diagnostic)] -#[diag(parser_unexpected_const_in_generic_param)] +#[diag(parse_unexpected_const_in_generic_param)] pub(crate) struct UnexpectedConstInGenericParam { #[primary_span] pub span: Span, @@ -1183,7 +1177,7 @@ pub(crate) struct UnexpectedConstInGenericParam { } #[derive(Diagnostic)] -#[diag(parser_async_move_order_incorrect)] +#[diag(parse_async_move_order_incorrect)] pub(crate) struct AsyncMoveOrderIncorrect { #[primary_span] #[suggestion(style = "verbose", code = "async move", applicability = "maybe-incorrect")] @@ -1191,7 +1185,7 @@ pub(crate) struct AsyncMoveOrderIncorrect { } #[derive(Diagnostic)] -#[diag(parser_double_colon_in_bound)] +#[diag(parse_double_colon_in_bound)] pub(crate) struct DoubleColonInBound { #[primary_span] pub span: Span, @@ -1200,7 +1194,7 @@ pub(crate) struct DoubleColonInBound { } #[derive(Diagnostic)] -#[diag(parser_fn_ptr_with_generics)] +#[diag(parse_fn_ptr_with_generics)] pub(crate) struct FnPtrWithGenerics { #[primary_span] pub span: Span, @@ -1219,3 +1213,11 @@ pub(crate) struct FnPtrWithGenericsSugg { pub arity: usize, pub for_param_list_exists: bool, } + +#[derive(Diagnostic)] +#[diag(parse_unexpected_if_with_if)] +pub(crate) struct UnexpectedIfWithIf( + #[primary_span] + #[suggestion(applicability = "machine-applicable", code = " ", style = "verbose")] + pub Span, +); diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index c78479b098b..b49a01d75ed 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -15,8 +15,7 @@ extern crate tracing; use rustc_ast as ast; use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_ast::Attribute; -use rustc_ast::{AttrItem, MetaItem}; +use rustc_ast::{AttrItem, Attribute, MetaItem}; use rustc_ast_pretty::pprust; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, Diagnostic, FatalError, Level, PResult}; @@ -257,10 +256,12 @@ pub fn parse_cfg_attr( parse_sess: &ParseSess, ) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> { match attr.get_normal_item().args { - ast::MacArgs::Delimited(dspan, delim, ref tts) if !tts.is_empty() => { + ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens }) + if !tokens.is_empty() => + { let msg = "wrong `cfg_attr` delimiters"; crate::validate_attr::check_meta_bad_delim(parse_sess, dspan, delim, msg); - match parse_in(parse_sess, tts.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { + match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { Ok(r) => return Some(r), Err(mut e) => { e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 612accf3e3b..fb2cee9e346 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -55,7 +55,7 @@ impl<'a> Parser<'a> { let span = self.token.span; let mut err = self.sess.span_diagnostic.struct_span_err_with_code( span, - fluent::parser_inner_doc_comment_not_permitted, + fluent::parse_inner_doc_comment_not_permitted, error_code!(E0753), ); if let Some(replacement_span) = self.annotate_following_item_if_applicable( @@ -200,7 +200,7 @@ impl<'a> Parser<'a> { Some(InnerAttrForbiddenReason::AfterOuterDocComment { prev_doc_comment_span }) => { let mut diag = self.struct_span_err( attr_sp, - fluent::parser_inner_attr_not_permitted_after_outer_doc_comment, + fluent::parse_inner_attr_not_permitted_after_outer_doc_comment, ); diag.span_label(attr_sp, fluent::label_attr) .span_label(prev_doc_comment_span, fluent::label_prev_doc_comment); @@ -209,18 +209,18 @@ impl<'a> Parser<'a> { Some(InnerAttrForbiddenReason::AfterOuterAttribute { prev_outer_attr_sp }) => { let mut diag = self.struct_span_err( attr_sp, - fluent::parser_inner_attr_not_permitted_after_outer_attr, + fluent::parse_inner_attr_not_permitted_after_outer_attr, ); diag.span_label(attr_sp, fluent::label_attr) .span_label(prev_outer_attr_sp, fluent::label_prev_attr); diag } Some(InnerAttrForbiddenReason::InCodeBlock) | None => { - self.struct_span_err(attr_sp, fluent::parser_inner_attr_not_permitted) + self.struct_span_err(attr_sp, fluent::parse_inner_attr_not_permitted) } }; - diag.note(fluent::parser_inner_attr_explanation); + diag.note(fluent::parse_inner_attr_explanation); if self .annotate_following_item_if_applicable( &mut diag, @@ -229,7 +229,7 @@ impl<'a> Parser<'a> { ) .is_some() { - diag.note(fluent::parser_outer_attr_explanation); + diag.note(fluent::parse_outer_attr_explanation); }; diag.emit(); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 0bbe073fe2a..4c626539238 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -18,6 +18,7 @@ use crate::errors::{ }; use crate::lexer::UnmatchedBrace; +use crate::parser; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Lit, LitKind, TokenKind}; @@ -37,11 +38,10 @@ use rustc_session::errors::ExprParenthesesNeeded; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{Span, SpanSnippetError, DUMMY_SP}; -use std::ops::{Deref, DerefMut}; - use std::mem::take; - -use crate::parser; +use std::ops::{Deref, DerefMut}; +use thin_vec::{thin_vec, ThinVec}; +use tracing::{debug, trace}; /// Creates a placeholder argument. pub(super) fn dummy_arg(ident: Ident) -> Param { @@ -65,7 +65,7 @@ pub(super) fn dummy_arg(ident: Ident) -> Param { pub(super) trait RecoverQPath: Sized + 'static { const PATH_STYLE: PathStyle = PathStyle::Expr; fn to_ty(&self) -> Option<P<Ty>>; - fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self; + fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self; } impl RecoverQPath for Ty { @@ -73,7 +73,7 @@ impl RecoverQPath for Ty { fn to_ty(&self) -> Option<P<Ty>> { Some(P(self.clone())) } - fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self { + fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self { Self { span: path.span, kind: TyKind::Path(qself, path), @@ -87,7 +87,7 @@ impl RecoverQPath for Pat { fn to_ty(&self) -> Option<P<Ty>> { self.to_ty() } - fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self { + fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self { Self { span: path.span, kind: PatKind::Path(qself, path), @@ -101,7 +101,7 @@ impl RecoverQPath for Expr { fn to_ty(&self) -> Option<P<Ty>> { self.to_ty() } - fn recovered(qself: Option<QSelf>, path: ast::Path) -> Self { + fn recovered(qself: Option<P<QSelf>>, path: ast::Path) -> Self { Self { span: path.span, kind: ExprKind::Path(qself, path), @@ -638,8 +638,11 @@ impl<'a> Parser<'a> { // field: value, // } let mut snapshot = self.create_snapshot_for_diagnostic(); - let path = - Path { segments: vec![], span: self.prev_token.span.shrink_to_lo(), tokens: None }; + let path = Path { + segments: ThinVec::new(), + span: self.prev_token.span.shrink_to_lo(), + tokens: None, + }; let struct_expr = snapshot.parse_struct_expr(None, path, false); let block_tail = self.parse_block_tail(lo, s, AttemptLocalParseRecovery::No); return Some(match (struct_expr, block_tail) { @@ -934,7 +937,7 @@ impl<'a> Parser<'a> { if self.eat(&token::Gt) { e.span_suggestion_verbose( binop.span.shrink_to_lo(), - fluent::parser_sugg_turbofish_syntax, + fluent::parse_sugg_turbofish_syntax, "::", Applicability::MaybeIncorrect, ) @@ -1426,7 +1429,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P<T>> { self.expect(&token::ModSep)?; - let mut path = ast::Path { segments: Vec::new(), span: DUMMY_SP, tokens: None }; + let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None }; self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?; path.span = ty_span.to(self.prev_token.span); @@ -1437,7 +1440,7 @@ impl<'a> Parser<'a> { }); let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`. - Ok(P(T::recovered(Some(QSelf { ty, path_span, position: 0 }), path))) + Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path))) } pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool { @@ -1657,14 +1660,14 @@ impl<'a> Parser<'a> { let left = begin_par_sp; let right = self.prev_token.span; let left_snippet = if let Ok(snip) = sm.span_to_prev_source(left) && - !snip.ends_with(" ") { + !snip.ends_with(' ') { " ".to_string() } else { "".to_string() }; let right_snippet = if let Ok(snip) = sm.span_to_next_source(right) && - !snip.starts_with(" ") { + !snip.starts_with(' ') { " ".to_string() } else { "".to_string() @@ -2434,7 +2437,7 @@ impl<'a> Parser<'a> { None, Path { span: new_span, - segments: vec![ + segments: thin_vec![ PathSegment::from_ident(*old_ident), PathSegment::from_ident(*ident), ], diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index c9629ea49e0..ba73fbd3e12 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -21,8 +21,8 @@ use crate::errors::{ NoFieldsForFnCall, NotAsNegationOperator, NotAsNegationOperatorSub, OuterAttributeNotAllowedOnIfElse, ParenthesesWithStructFields, RequireColonAfterLabeledExpression, ShiftInterpretedAsGeneric, StructLiteralNotAllowedHere, - StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedTokenAfterLabel, - UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses, + StructLiteralNotAllowedHereSugg, TildeAsUnaryOperator, UnexpectedIfWithIf, + UnexpectedTokenAfterLabel, UnexpectedTokenAfterLabelSugg, WrapExpressionInParentheses, }; use crate::maybe_recover_from_interpolated_ty_qpath; use core::mem; @@ -840,7 +840,7 @@ impl<'a> Parser<'a> { ExprKind::Index(_, _) => "indexing", ExprKind::Try(_) => "`?`", ExprKind::Field(_, _) => "a field access", - ExprKind::MethodCall(_, _, _, _) => "a method call", + ExprKind::MethodCall(_) => "a method call", ExprKind::Call(_, _) => "a function call", ExprKind::Await(_) => "`.await`", ExprKind::Err => return Ok(with_postfix), @@ -1262,24 +1262,32 @@ impl<'a> Parser<'a> { } let fn_span_lo = self.token.span; - let mut segment = self.parse_path_segment(PathStyle::Expr, None)?; - self.check_trailing_angle_brackets(&segment, &[&token::OpenDelim(Delimiter::Parenthesis)]); - self.check_turbofish_missing_angle_brackets(&mut segment); + let mut seg = self.parse_path_segment(PathStyle::Expr, None)?; + self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]); + self.check_turbofish_missing_angle_brackets(&mut seg); if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { // Method call `expr.f()` let args = self.parse_paren_expr_seq()?; let fn_span = fn_span_lo.to(self.prev_token.span); let span = lo.to(self.prev_token.span); - Ok(self.mk_expr(span, ExprKind::MethodCall(segment, self_arg, args, fn_span))) + Ok(self.mk_expr( + span, + ExprKind::MethodCall(Box::new(ast::MethodCall { + seg, + receiver: self_arg, + args, + span: fn_span, + })), + )) } else { // Field access `expr.f` - if let Some(args) = segment.args { + if let Some(args) = seg.args { self.sess.emit_err(FieldExpressionWithGeneric(args.span())); } let span = lo.to(self.prev_token.span); - Ok(self.mk_expr(span, ExprKind::Field(self_arg, segment.ident))) + Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident))) } } @@ -1493,12 +1501,12 @@ impl<'a> Parser<'a> { let lo = path.span; let mac = P(MacCall { path, - args: self.parse_mac_args()?, + args: self.parse_delim_args()?, prior_type_ascription: self.last_type_ascription, }); (lo.to(self.prev_token.span), ExprKind::MacCall(mac)) } else if self.check(&token::OpenDelim(Delimiter::Brace)) && - let Some(expr) = self.maybe_parse_struct_expr(qself.as_ref(), &path) { + let Some(expr) = self.maybe_parse_struct_expr(&qself, &path) { if qself.is_some() { self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); } @@ -2049,9 +2057,9 @@ impl<'a> Parser<'a> { }; let capture_clause = self.parse_capture_clause()?; - let decl = self.parse_fn_block_decl()?; + let fn_decl = self.parse_fn_block_decl()?; let decl_hi = self.prev_token.span; - let mut body = match decl.output { + let mut body = match fn_decl.output { FnRetTy::Default(_) => { let restrictions = self.restrictions - Restrictions::STMT_EXPR; self.parse_expr_res(restrictions, None)? @@ -2070,12 +2078,7 @@ impl<'a> Parser<'a> { if self.token.kind == TokenKind::Semi && matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _))) - // HACK: This is needed so we can detect whether we're inside a macro, - // where regular assumptions about what tokens can follow other tokens - // don't necessarily apply. && self.may_recover() - // FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery - && self.subparser_name.is_none() { // It is likely that the closure body is a block but where the // braces have been removed. We will recover and eat the next @@ -2087,15 +2090,15 @@ impl<'a> Parser<'a> { let closure = self.mk_expr( lo.to(body.span), - ExprKind::Closure( + ExprKind::Closure(Box::new(ast::Closure { binder, capture_clause, asyncness, movability, - decl, + fn_decl, body, - lo.to(decl_hi), - ), + fn_decl_span: lo.to(decl_hi), + })), ); // Disable recovery for closure body @@ -2231,6 +2234,7 @@ impl<'a> Parser<'a> { if let Some(block) = recover_block_from_condition(self) { block } else { + self.error_on_extra_if(&cond)?; // Parse block, which will always fail, but we can add a nice note to the error self.parse_block().map_err(|mut err| { err.span_note( @@ -2367,6 +2371,16 @@ impl<'a> Parser<'a> { }); } + fn error_on_extra_if(&mut self, cond: &P<Expr>) -> PResult<'a, ()> { + if let ExprKind::Binary(Spanned { span: binop_span, node: binop}, _, right) = &cond.kind && + let BinOpKind::And = binop && + let ExprKind::If(cond, ..) = &right.kind { + Err(self.sess.create_err(UnexpectedIfWithIf(binop_span.shrink_to_hi().to(cond.span.shrink_to_lo())))) + } else { + Ok(()) + } + } + /// Parses `for <src_pat> in <src_expr> <src_loop_block>` (`for` token already eaten). fn parse_for_expr(&mut self, opt_label: Option<Label>, lo: Span) -> PResult<'a, P<Expr>> { // Record whether we are about to parse `for (`. @@ -2800,7 +2814,7 @@ impl<'a> Parser<'a> { fn maybe_parse_struct_expr( &mut self, - qself: Option<&ast::QSelf>, + qself: &Option<P<ast::QSelf>>, path: &ast::Path, ) -> Option<PResult<'a, P<Expr>>> { let struct_allowed = !self.restrictions.contains(Restrictions::NO_STRUCT_LITERAL); @@ -2808,7 +2822,7 @@ impl<'a> Parser<'a> { if let Err(err) = self.expect(&token::OpenDelim(Delimiter::Brace)) { return Some(Err(err)); } - let expr = self.parse_struct_expr(qself.cloned(), path.clone(), true); + let expr = self.parse_struct_expr(qself.clone(), path.clone(), true); if let (Ok(expr), false) = (&expr, struct_allowed) { // This is a struct literal, but we don't can't accept them here. self.sess.emit_err(StructLiteralNotAllowedHere { @@ -2939,7 +2953,7 @@ impl<'a> Parser<'a> { /// Precondition: already parsed the '{'. pub(super) fn parse_struct_expr( &mut self, - qself: Option<ast::QSelf>, + qself: Option<P<ast::QSelf>>, pth: ast::Path, recover: bool, ) -> PResult<'a, P<Expr>> { diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 494f0cf56a8..20b01f554f2 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -3,7 +3,6 @@ use crate::errors::{DocCommentDoesNotDocumentAnything, UseEmptyBlockNotSemi}; use super::diagnostics::{dummy_arg, ConsumeClosingDelim}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken}; - use rustc_ast::ast::*; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, TokenKind}; @@ -14,7 +13,7 @@ use rustc_ast::{Async, Const, Defaultness, IsAuto, Mutability, Unsafe, UseTree, use rustc_ast::{BindingAnnotation, Block, FnDecl, FnSig, Param, SelfKind}; use rustc_ast::{EnumDef, FieldDef, Generics, TraitRef, Ty, TyKind, Variant, VariantData}; use rustc_ast::{FnHeader, ForeignItem, Path, PathSegment, Visibility, VisibilityKind}; -use rustc_ast::{MacArgs, MacCall, MacDelimiter}; +use rustc_ast::{MacCall, MacDelimiter}; use rustc_ast_pretty::pprust; use rustc_errors::{struct_span_err, Applicability, IntoDiagnostic, PResult, StashKey}; use rustc_span::edition::Edition; @@ -22,9 +21,10 @@ use rustc_span::lev_distance::lev_distance; use rustc_span::source_map::{self, Span}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::DUMMY_SP; - use std::convert::TryFrom; use std::mem; +use thin_vec::ThinVec; +use tracing::debug; impl<'a> Parser<'a> { /// Parses a source module as a crate. This is the main entry point for the parser. @@ -471,7 +471,7 @@ impl<'a> Parser<'a> { fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> { let path = self.parse_path(PathStyle::Mod)?; // `foo::bar` self.expect(&token::Not)?; // `!` - match self.parse_mac_args() { + match self.parse_delim_args() { // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`. Ok(args) => { self.eat_semi_for_macro_if_needed(&args); @@ -972,7 +972,8 @@ impl<'a> Parser<'a> { fn parse_use_tree(&mut self) -> PResult<'a, UseTree> { let lo = self.token.span; - let mut prefix = ast::Path { segments: Vec::new(), span: lo.shrink_to_lo(), tokens: None }; + let mut prefix = + ast::Path { segments: ThinVec::new(), span: lo.shrink_to_lo(), tokens: None }; let kind = if self.check(&token::OpenDelim(Delimiter::Brace)) || self.check(&token::BinOp(token::Star)) || self.is_import_coupler() @@ -1866,7 +1867,7 @@ impl<'a> Parser<'a> { fn parse_item_decl_macro(&mut self, lo: Span) -> PResult<'a, ItemInfo> { let ident = self.parse_ident()?; let body = if self.check(&token::OpenDelim(Delimiter::Brace)) { - self.parse_mac_args()? // `MacBody` + self.parse_delim_args()? // `MacBody` } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) { let params = self.parse_token_tree(); // `MacParams` let pspan = params.span(); @@ -1879,7 +1880,7 @@ impl<'a> Parser<'a> { let arrow = TokenTree::token_alone(token::FatArrow, pspan.between(bspan)); // `=>` let tokens = TokenStream::new(vec![params, arrow, body]); let dspan = DelimSpan::from_pair(pspan.shrink_to_lo(), bspan.shrink_to_hi()); - P(MacArgs::Delimited(dspan, MacDelimiter::Brace, tokens)) + P(DelimArgs { dspan, delim: MacDelimiter::Brace, tokens }) } else { return self.unexpected(); }; @@ -1934,7 +1935,7 @@ impl<'a> Parser<'a> { .emit(); } - let body = self.parse_mac_args()?; + let body = self.parse_delim_args()?; self.eat_semi_for_macro_if_needed(&body); self.complain_if_pub_macro(vis, true); @@ -1973,14 +1974,14 @@ impl<'a> Parser<'a> { } } - fn eat_semi_for_macro_if_needed(&mut self, args: &MacArgs) { + fn eat_semi_for_macro_if_needed(&mut self, args: &DelimArgs) { if args.need_semicolon() && !self.eat(&token::Semi) { self.report_invalid_macro_expansion_item(args); } } - fn report_invalid_macro_expansion_item(&self, args: &MacArgs) { - let span = args.span().expect("undelimited macro call"); + fn report_invalid_macro_expansion_item(&self, args: &DelimArgs) { + let span = args.dspan.entire(); let mut err = self.struct_span_err( span, "macros that expand to items must be delimited with braces or followed by a semicolon", @@ -1989,10 +1990,7 @@ impl<'a> Parser<'a> { // macros within the same crate (that we can fix), which is sad. if !span.from_expansion() { if self.unclosed_delims.is_empty() { - let DelimSpan { open, close } = match args { - MacArgs::Empty | MacArgs::Eq(..) => unreachable!(), - MacArgs::Delimited(dspan, ..) => *dspan, - }; + let DelimSpan { open, close } = args.dspan; err.multipart_suggestion( "change the delimiters to curly braces", vec![(open, "{".to_string()), (close, '}'.to_string())], diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 13a38a17735..8878c404c58 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -25,8 +25,8 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::case::Case; use rustc_ast::AttrId; use rustc_ast::DUMMY_NODE_ID; -use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, Extern}; -use rustc_ast::{Async, Expr, ExprKind, MacArgs, MacArgsEq, MacDelimiter, Mutability, StrLit}; +use rustc_ast::{self as ast, AnonConst, AttrStyle, AttrVec, Const, DelimArgs, Extern}; +use rustc_ast::{Async, AttrArgs, AttrArgsEq, Expr, ExprKind, MacDelimiter, Mutability, StrLit}; use rustc_ast::{HasAttrs, HasTokens, Unsafe, Visibility, VisibilityKind}; use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashMap; @@ -1249,39 +1249,40 @@ impl<'a> Parser<'a> { } } - fn parse_mac_args(&mut self) -> PResult<'a, P<MacArgs>> { - self.parse_mac_args_common(true).map(P) + fn parse_delim_args(&mut self) -> PResult<'a, P<DelimArgs>> { + if let Some(args) = self.parse_delim_args_inner() { Ok(P(args)) } else { self.unexpected() } } - fn parse_attr_args(&mut self) -> PResult<'a, MacArgs> { - self.parse_mac_args_common(false) + fn parse_attr_args(&mut self) -> PResult<'a, AttrArgs> { + Ok(if let Some(args) = self.parse_delim_args_inner() { + AttrArgs::Delimited(args) + } else { + if self.eat(&token::Eq) { + let eq_span = self.prev_token.span; + AttrArgs::Eq(eq_span, AttrArgsEq::Ast(self.parse_expr_force_collect()?)) + } else { + AttrArgs::Empty + } + }) } - fn parse_mac_args_common(&mut self, delimited_only: bool) -> PResult<'a, MacArgs> { - Ok( - if self.check(&token::OpenDelim(Delimiter::Parenthesis)) - || self.check(&token::OpenDelim(Delimiter::Bracket)) - || self.check(&token::OpenDelim(Delimiter::Brace)) - { - match self.parse_token_tree() { - TokenTree::Delimited(dspan, delim, tokens) => - // We've confirmed above that there is a delimiter so unwrapping is OK. - { - MacArgs::Delimited(dspan, MacDelimiter::from_token(delim).unwrap(), tokens) - } - _ => unreachable!(), - } - } else if !delimited_only { - if self.eat(&token::Eq) { - let eq_span = self.prev_token.span; - MacArgs::Eq(eq_span, MacArgsEq::Ast(self.parse_expr_force_collect()?)) - } else { - MacArgs::Empty - } - } else { - return self.unexpected(); - }, - ) + fn parse_delim_args_inner(&mut self) -> Option<DelimArgs> { + if self.check(&token::OpenDelim(Delimiter::Parenthesis)) + || self.check(&token::OpenDelim(Delimiter::Bracket)) + || self.check(&token::OpenDelim(Delimiter::Brace)) + { + match self.parse_token_tree() { + // We've confirmed above that there is a delimiter so unwrapping is OK. + TokenTree::Delimited(dspan, delim, tokens) => Some(DelimArgs { + dspan, + delim: MacDelimiter::from_token(delim).unwrap(), + tokens, + }), + _ => unreachable!(), + } + } else { + None + } } fn parse_or_use_outer_attributes( diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index b3af37a5f70..bf52febb107 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -693,7 +693,7 @@ impl<'a> Parser<'a> { /// Parse macro invocation fn parse_pat_mac_invoc(&mut self, path: Path) -> PResult<'a, PatKind> { self.bump(); - let args = self.parse_mac_args()?; + let args = self.parse_delim_args()?; let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); Ok(PatKind::MacCall(mac)) } @@ -889,7 +889,7 @@ impl<'a> Parser<'a> { } /// Parse a struct ("record") pattern (e.g. `Foo { ... }` or `Foo::Bar { ... }`). - fn parse_pat_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> { + fn parse_pat_struct(&mut self, qself: Option<P<QSelf>>, path: Path) -> PResult<'a, PatKind> { if qself.is_some() { // Feature gate the use of qualified paths in patterns self.sess.gated_spans.gate(sym::more_qualified_paths, path.span); @@ -906,7 +906,11 @@ impl<'a> Parser<'a> { } /// Parse tuple struct or tuple variant pattern (e.g. `Foo(...)` or `Foo::Bar(...)`). - fn parse_pat_tuple_struct(&mut self, qself: Option<QSelf>, path: Path) -> PResult<'a, PatKind> { + fn parse_pat_tuple_struct( + &mut self, + qself: Option<P<QSelf>>, + path: Path, + ) -> PResult<'a, PatKind> { let (fields, _) = self.parse_paren_comma_seq(|p| { p.parse_pat_allow_top_alt( None, diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index d46565dea89..2d432e3f5bd 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -11,8 +11,9 @@ use rustc_ast::{ use rustc_errors::{pluralize, Applicability, PResult}; use rustc_span::source_map::{BytePos, Span}; use rustc_span::symbol::{kw, sym, Ident}; - use std::mem; +use thin_vec::ThinVec; +use tracing::debug; /// Specifies how to parse a path. #[derive(Copy, Clone, PartialEq)] @@ -48,7 +49,7 @@ impl<'a> Parser<'a> { /// `<T as U>::a` /// `<T as U>::F::a<S>` (without disambiguator) /// `<T as U>::F::a::<S>` (with disambiguator) - pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (QSelf, Path)> { + pub(super) fn parse_qpath(&mut self, style: PathStyle) -> PResult<'a, (P<QSelf>, Path)> { let lo = self.prev_token.span; let ty = self.parse_ty()?; @@ -63,7 +64,7 @@ impl<'a> Parser<'a> { path_span = path_lo.to(self.prev_token.span); } else { path_span = self.token.span.to(self.token.span); - path = ast::Path { segments: Vec::new(), span: path_span, tokens: None }; + path = ast::Path { segments: ThinVec::new(), span: path_span, tokens: None }; } // See doc comment for `unmatched_angle_bracket_count`. @@ -77,7 +78,7 @@ impl<'a> Parser<'a> { self.expect(&token::ModSep)?; } - let qself = QSelf { ty, path_span, position: path.segments.len() }; + let qself = P(QSelf { ty, path_span, position: path.segments.len() }); self.parse_path_segments(&mut path.segments, style, None)?; Ok(( @@ -179,7 +180,7 @@ impl<'a> Parser<'a> { } let lo = self.token.span; - let mut segments = Vec::new(); + let mut segments = ThinVec::new(); let mod_sep_ctxt = self.token.span.ctxt(); if self.eat(&token::ModSep) { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); @@ -191,7 +192,7 @@ impl<'a> Parser<'a> { pub(super) fn parse_path_segments( &mut self, - segments: &mut Vec<PathSegment>, + segments: &mut ThinVec<PathSegment>, style: PathStyle, ty_generics: Option<&Generics>, ) -> PResult<'a, ()> { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 7820bbc1789..73de86820d8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -167,14 +167,13 @@ impl<'a> Parser<'a> { /// Parses a statement macro `mac!(args)` provided a `path` representing `mac`. /// At this point, the `!` token after the path has already been eaten. fn parse_stmt_mac(&mut self, lo: Span, attrs: AttrVec, path: ast::Path) -> PResult<'a, Stmt> { - let args = self.parse_mac_args()?; - let delim = args.delim(); + let args = self.parse_delim_args()?; + let delim = args.delim.to_token(); let hi = self.prev_token.span; let style = match delim { - Some(Delimiter::Brace) => MacStmtStyle::Braces, - Some(_) => MacStmtStyle::NoBraces, - None => unreachable!(), + Delimiter::Brace => MacStmtStyle::Braces, + _ => MacStmtStyle::NoBraces, }; let mac = P(MacCall { path, args, prior_type_ascription: self.last_type_ascription }); diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index d6854f07025..fecf67cb596 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -665,7 +665,7 @@ impl<'a> Parser<'a> { // Macro invocation in type position Ok(TyKind::MacCall(P(MacCall { path, - args: self.parse_mac_args()?, + args: self.parse_delim_args()?, prior_type_ascription: self.last_type_ascription, }))) } else if allow_plus == AllowPlus::Yes && self.check_plus() { diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 8e7f8bfe0f5..e2f95d74a3d 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -3,7 +3,8 @@ use crate::parse_in; use rustc_ast::tokenstream::DelimSpan; -use rustc_ast::{self as ast, Attribute, MacArgs, MacArgsEq, MacDelimiter, MetaItem, MetaItemKind}; +use rustc_ast::MetaItemKind; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MacDelimiter, MetaItem}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, FatalError, PResult}; use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; @@ -24,7 +25,7 @@ pub fn check_meta(sess: &ParseSess, attr: &Attribute) { Some(BuiltinAttribute { name, template, .. }) if *name != sym::rustc_dummy => { check_builtin_attribute(sess, attr, *name, *template) } - _ if let MacArgs::Eq(..) = attr.get_normal_item().args => { + _ if let AttrArgs::Eq(..) = attr.get_normal_item().args => { // All key-value attributes are restricted to meta-item syntax. parse_meta(sess, attr) .map_err(|mut err| { @@ -42,13 +43,13 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta span: attr.span, path: item.path.clone(), kind: match &item.args { - MacArgs::Empty => MetaItemKind::Word, - MacArgs::Delimited(dspan, delim, t) => { + AttrArgs::Empty => MetaItemKind::Word, + AttrArgs::Delimited(DelimArgs { dspan, delim, tokens }) => { check_meta_bad_delim(sess, *dspan, *delim, "wrong meta list delimiters"); - let nmis = parse_in(sess, t.clone(), "meta list", |p| p.parse_meta_seq_top())?; + let nmis = parse_in(sess, tokens.clone(), "meta list", |p| p.parse_meta_seq_top())?; MetaItemKind::List(nmis) } - MacArgs::Eq(_, MacArgsEq::Ast(expr)) => { + AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => { if let ast::ExprKind::Lit(token_lit) = expr.kind && let Ok(lit) = ast::Lit::from_token_lit(token_lit, expr.span) { @@ -78,7 +79,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta return Err(err); } } - MacArgs::Eq(_, MacArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), + AttrArgs::Eq(_, AttrArgsEq::Hir(lit)) => MetaItemKind::NameValue(lit.clone()), }, }) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 6b8cd071373..acb9bd8e78a 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -353,7 +353,7 @@ impl CheckAttrVisitor<'_> { attr.span, OnlyHasEffectOn { attr_name: attr.name_or_empty(), - target_name: allowed_target.name().replace(" ", "_"), + target_name: allowed_target.name().replace(' ', "_"), }, ); } diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index d4722234a8f..5d0224c35f3 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -772,7 +772,7 @@ impl<'tcx> DeadVisitor<'tcx> { self.tcx.emit_spanned_lint( lint, tcx.hir().local_def_id_to_hir_id(first_id), - MultiSpan::from_spans(spans.clone()), + MultiSpan::from_spans(spans), diag, ); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 0100860afb9..58e1fe937a6 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -1284,20 +1284,19 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { fn check_is_ty_uninhabited(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode { let ty = self.typeck_results.expr_ty(expr); let m = self.ir.tcx.parent_module(expr.hir_id).to_def_id(); - if self.ir.tcx.is_ty_uninhabited_from(m, ty, self.param_env) { - match self.ir.lnks[succ] { - LiveNodeKind::ExprNode(succ_span, succ_id) => { - self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression"); - } - LiveNodeKind::VarDefNode(succ_span, succ_id) => { - self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition"); - } - _ => {} - }; - self.exit_ln - } else { - succ + if ty.is_inhabited_from(self.ir.tcx, m, self.param_env) { + return succ; } + match self.ir.lnks[succ] { + LiveNodeKind::ExprNode(succ_span, succ_id) => { + self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "expression"); + } + LiveNodeKind::VarDefNode(succ_span, succ_id) => { + self.warn_about_unreachable(expr.span, ty, succ_span, succ_id, "definition"); + } + _ => {} + }; + self.exit_ln } fn warn_about_unreachable( diff --git a/compiler/rustc_resolve/Cargo.toml b/compiler/rustc_resolve/Cargo.toml index d66db1d7a0d..7c3a0f8f277 100644 --- a/compiler/rustc_resolve/Cargo.toml +++ b/compiler/rustc_resolve/Cargo.toml @@ -7,10 +7,8 @@ edition = "2021" [dependencies] bitflags = "1.2.1" -tracing = "0.1" -rustc_ast = { path = "../rustc_ast" } rustc_arena = { path = "../rustc_arena" } -rustc_middle = { path = "../rustc_middle" } +rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_attr = { path = "../rustc_attr" } rustc_data_structures = { path = "../rustc_data_structures" } @@ -19,8 +17,12 @@ rustc_expand = { path = "../rustc_expand" } rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } +rustc_macros = { path = "../rustc_macros" } rustc_metadata = { path = "../rustc_metadata" } +rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } +thin-vec = "0.2.8" +tracing = "0.1" diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e7e419c9b42..7ac4fcfa64c 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -747,7 +747,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // If this is a tuple or unit struct, define a name // in the value namespace as well. - if let Some(ctor_node_id) = vdata.ctor_id() { + if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(vdata) { // If the structure is marked as non_exhaustive then lower the visibility // to within the crate. let mut ctor_vis = if vis.is_public() @@ -773,10 +773,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { ret_fields.push(field_vis.to_def_id()); } let ctor_def_id = self.r.local_def_id(ctor_node_id); - let ctor_res = Res::Def( - DefKind::Ctor(CtorOf::Struct, CtorKind::from_ast(vdata)), - ctor_def_id.to_def_id(), - ); + let ctor_res = + Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.visibilities.insert(ctor_def_id, ctor_vis); @@ -999,8 +997,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { Res::Def(DefKind::Struct, def_id) => { let field_names = cstore.struct_field_names_untracked(def_id, self.r.session).collect(); - let ctor = cstore.ctor_def_id_and_kind_untracked(def_id); - if let Some((ctor_def_id, ctor_kind)) = ctor { + if let Some((ctor_kind, ctor_def_id)) = cstore.ctor_untracked(def_id) { let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id); let ctor_vis = cstore.visibility_untracked(ctor_def_id); let field_visibilities = @@ -1517,20 +1514,20 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { }; // Define a constructor name in the value namespace. - // Braced variants, unlike structs, generate unusable names in - // value namespace, they are reserved for possible future use. - // It's ok to use the variant's id as a ctor id since an - // error will be reported on any use of such resolution anyway. - let ctor_node_id = variant.data.ctor_id().unwrap_or(variant.id); - let ctor_def_id = self.r.local_def_id(ctor_node_id); - let ctor_kind = CtorKind::from_ast(&variant.data); - let ctor_res = Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id()); - self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); - if ctor_def_id != def_id { + let fields_id = if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(&variant.data) { + let ctor_def_id = self.r.local_def_id(ctor_node_id); + let ctor_res = + Res::Def(DefKind::Ctor(CtorOf::Variant, ctor_kind), ctor_def_id.to_def_id()); + self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); self.r.visibilities.insert(ctor_def_id, ctor_vis); - } + ctor_def_id + } else { + def_id + }; + // Record field names for error reporting. - self.insert_field_names_local(ctor_def_id.to_def_id(), &variant.data); + // FIXME: Always use non-ctor id as the key. + self.insert_field_names_local(fields_id.to_def_id(), &variant.data); visit::walk_variant(self, variant); } diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index d36e0f61d91..bf2428e1731 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -118,8 +118,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { match i.kind { ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => { // If this is a unit or tuple-like struct, register the constructor. - if let Some(ctor_hir_id) = struct_def.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, i.span); + if let Some(ctor_node_id) = struct_def.ctor_node_id() { + this.create_def(ctor_node_id, DefPathData::Ctor, i.span); } } _ => {} @@ -131,12 +131,9 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_fn(&mut self, fn_kind: FnKind<'a>, span: Span, _: NodeId) { if let FnKind::Fn(_, _, sig, _, generics, body) = fn_kind { - if let Async::Yes { closure_id, return_impl_trait_id, .. } = sig.header.asyncness { + if let Async::Yes { closure_id, .. } = sig.header.asyncness { self.visit_generics(generics); - let return_impl_trait_id = - self.create_def(return_impl_trait_id, DefPathData::ImplTrait, span); - // For async functions, we need to create their inner defs inside of a // closure to match their desugared representation. Besides that, // we must mirror everything that `visit::walk_fn` below does. @@ -144,9 +141,7 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { for param in &sig.decl.inputs { self.visit_param(param); } - self.with_parent(return_impl_trait_id, |this| { - this.visit_fn_ret_ty(&sig.decl.output) - }); + self.visit_fn_ret_ty(&sig.decl.output); // If this async fn has no body (i.e. it's an async fn signature in a trait) // then the closure_def will never be used, and we should avoid generating a // def-id for it. @@ -196,8 +191,8 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { } let def = self.create_def(v.id, DefPathData::TypeNs(v.ident.name), v.span); self.with_parent(def, |this| { - if let Some(ctor_hir_id) = v.data.ctor_id() { - this.create_def(ctor_hir_id, DefPathData::Ctor, v.span); + if let Some(ctor_node_id) = v.data.ctor_node_id() { + this.create_def(ctor_node_id, DefPathData::Ctor, v.span); } visit::walk_variant(this, v) }); @@ -262,11 +257,11 @@ impl<'a, 'b> visit::Visitor<'a> for DefCollector<'a, 'b> { fn visit_expr(&mut self, expr: &'a Expr) { let parent_def = match expr.kind { ExprKind::MacCall(..) => return self.visit_macro_invoc(expr.id), - ExprKind::Closure(_, _, asyncness, ..) => { + ExprKind::Closure(ref closure) => { // Async closures desugar to closures inside of closures, so // we must create two defs. let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span); - match asyncness { + match closure.asyncness { Async::Yes { closure_id, .. } => { self.create_def(closure_id, DefPathData::ClosureExpr, expr.span) } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index a12918b2979..bc3a710e84b 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -25,7 +25,9 @@ use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Span, SyntaxContext}; +use thin_vec::ThinVec; +use crate::errors as errs; use crate::imports::{Import, ImportKind, ImportResolver}; use crate::late::{PatternSource, Rib}; use crate::path_names_to_string; @@ -597,78 +599,41 @@ impl<'a> Resolver<'a> { err } - ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => { - let mut err = struct_span_err!( - self.session, - span, - E0403, - "the name `{}` is already used for a generic \ - parameter in this item's generic parameters", - name, - ); - err.span_label(span, "already used"); - err.span_label(first_use_span, format!("first use of `{}`", name)); - err - } + ResolutionError::NameAlreadyUsedInParameterList(name, first_use_span) => self + .session + .create_err(errs::NameAlreadyUsedInParameterList { span, first_use_span, name }), ResolutionError::MethodNotMemberOfTrait(method, trait_, candidate) => { - let mut err = struct_span_err!( - self.session, + self.session.create_err(errs::MethodNotMemberOfTrait { span, - E0407, - "method `{}` is not a member of trait `{}`", method, - trait_ - ); - err.span_label(span, format!("not a member of trait `{}`", trait_)); - if let Some(candidate) = candidate { - err.span_suggestion( - method.span, - "there is an associated function with a similar name", - candidate.to_ident_string(), - Applicability::MaybeIncorrect, - ); - } - err + trait_, + sub: candidate.map(|c| errs::AssociatedFnWithSimilarNameExists { + span: method.span, + candidate: c, + }), + }) } ResolutionError::TypeNotMemberOfTrait(type_, trait_, candidate) => { - let mut err = struct_span_err!( - self.session, + self.session.create_err(errs::TypeNotMemberOfTrait { span, - E0437, - "type `{}` is not a member of trait `{}`", type_, - trait_ - ); - err.span_label(span, format!("not a member of trait `{}`", trait_)); - if let Some(candidate) = candidate { - err.span_suggestion( - type_.span, - "there is an associated type with a similar name", - candidate.to_ident_string(), - Applicability::MaybeIncorrect, - ); - } - err + trait_, + sub: candidate.map(|c| errs::AssociatedTypeWithSimilarNameExists { + span: type_.span, + candidate: c, + }), + }) } ResolutionError::ConstNotMemberOfTrait(const_, trait_, candidate) => { - let mut err = struct_span_err!( - self.session, + self.session.create_err(errs::ConstNotMemberOfTrait { span, - E0438, - "const `{}` is not a member of trait `{}`", const_, - trait_ - ); - err.span_label(span, format!("not a member of trait `{}`", trait_)); - if let Some(candidate) = candidate { - err.span_suggestion( - const_.span, - "there is an associated constant with a similar name", - candidate.to_ident_string(), - Applicability::MaybeIncorrect, - ); - } - err + trait_, + sub: candidate.map(|c| errs::AssociatedConstWithSimilarNameExists { + span: const_.span, + candidate: c, + }), + }) } ResolutionError::VariableNotBoundInPattern(binding_error, parent_scope) => { let BindingError { name, target, origin, could_be_path } = binding_error; @@ -730,128 +695,78 @@ impl<'a> Resolver<'a> { err } ResolutionError::VariableBoundWithDifferentMode(variable_name, first_binding_span) => { - let mut err = struct_span_err!( - self.session, - span, - E0409, - "variable `{}` is bound inconsistently across alternatives separated by `|`", - variable_name - ); - err.span_label(span, "bound in different ways"); - err.span_label(first_binding_span, "first binding"); - err - } - ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => { - let mut err = struct_span_err!( - self.session, - span, - E0415, - "identifier `{}` is bound more than once in this parameter list", - identifier - ); - err.span_label(span, "used as parameter more than once"); - err - } - ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => { - let mut err = struct_span_err!( - self.session, + self.session.create_err(errs::VariableBoundWithDifferentMode { span, - E0416, - "identifier `{}` is bound more than once in the same pattern", - identifier - ); - err.span_label(span, "used in a pattern more than once"); - err - } + first_binding_span, + variable_name, + }) + } + ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => self + .session + .create_err(errs::IdentifierBoundMoreThanOnceInParameterList { span, identifier }), + ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => self + .session + .create_err(errs::IdentifierBoundMoreThanOnceInSamePattern { span, identifier }), ResolutionError::UndeclaredLabel { name, suggestion } => { - let mut err = struct_span_err!( - self.session, - span, - E0426, - "use of undeclared label `{}`", - name - ); - - err.span_label(span, format!("undeclared label `{}`", name)); - - match suggestion { + let ((sub_reachable, sub_reachable_suggestion), sub_unreachable) = match suggestion + { // A reachable label with a similar name exists. - Some((ident, true)) => { - err.span_label(ident.span, "a label with a similar name is reachable"); - err.span_suggestion( - span, - "try using similarly named label", - ident.name, - Applicability::MaybeIncorrect, - ); - } + Some((ident, true)) => ( + ( + Some(errs::LabelWithSimilarNameReachable(ident.span)), + Some(errs::TryUsingSimilarlyNamedLabel { + span, + ident_name: ident.name, + }), + ), + None, + ), // An unreachable label with a similar name exists. - Some((ident, false)) => { - err.span_label( - ident.span, - "a label with a similar name exists but is unreachable", - ); - } + Some((ident, false)) => ( + (None, None), + Some(errs::UnreachableLabelWithSimilarNameExists { + ident_span: ident.span, + }), + ), // No similarly-named labels exist. - None => (), - } - - err + None => ((None, None), None), + }; + self.session.create_err(errs::UndeclaredLabel { + span, + name, + sub_reachable, + sub_reachable_suggestion, + sub_unreachable, + }) } ResolutionError::SelfImportsOnlyAllowedWithin { root, span_with_rename } => { - let mut err = struct_span_err!( - self.session, - span, - E0429, - "{}", - "`self` imports are only allowed within a { } list" - ); - // None of the suggestions below would help with a case like `use self`. - if !root { + let (suggestion, mpart_suggestion) = if root { + (None, None) + } else { // use foo::bar::self -> foo::bar // use foo::bar::self as abc -> foo::bar as abc - err.span_suggestion( - span, - "consider importing the module directly", - "", - Applicability::MachineApplicable, - ); + let suggestion = errs::SelfImportsOnlyAllowedWithinSuggestion { span }; // use foo::bar::self -> foo::bar::{self} // use foo::bar::self as abc -> foo::bar::{self as abc} - let braces = vec![ - (span_with_rename.shrink_to_lo(), "{".to_string()), - (span_with_rename.shrink_to_hi(), "}".to_string()), - ]; - err.multipart_suggestion( - "alternatively, use the multi-path `use` syntax to import `self`", - braces, - Applicability::MachineApplicable, - ); - } - err + let mpart_suggestion = errs::SelfImportsOnlyAllowedWithinMultipartSuggestion { + multipart_start: span_with_rename.shrink_to_lo(), + multipart_end: span_with_rename.shrink_to_hi(), + }; + (Some(suggestion), Some(mpart_suggestion)) + }; + self.session.create_err(errs::SelfImportsOnlyAllowedWithin { + span, + suggestion, + mpart_suggestion, + }) } ResolutionError::SelfImportCanOnlyAppearOnceInTheList => { - let mut err = struct_span_err!( - self.session, - span, - E0430, - "`self` import can only appear once in an import list" - ); - err.span_label(span, "can only appear once in an import list"); - err + self.session.create_err(errs::SelfImportCanOnlyAppearOnceInTheList { span }) } ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => { - let mut err = struct_span_err!( - self.session, - span, - E0431, - "`self` import can only appear in an import list with \ - a non-empty prefix" - ); - err.span_label(span, "can only appear in an import list with a non-empty prefix"); - err + self.session.create_err(errs::SelfImportOnlyInImportListWithNonEmptyPrefix { span }) } ResolutionError::FailedToResolve { label, suggestion } => { let mut err = @@ -869,23 +784,9 @@ impl<'a> Resolver<'a> { err } ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => { - let mut err = struct_span_err!( - self.session, - span, - E0434, - "{}", - "can't capture dynamic environment in a fn item" - ); - err.help("use the `|| { ... }` closure form instead"); - err + self.session.create_err(errs::CannotCaptureDynamicEnvironmentInFnItem { span }) } - ResolutionError::AttemptToUseNonConstantValueInConstant(ident, sugg, current) => { - let mut err = struct_span_err!( - self.session, - span, - E0435, - "attempt to use a non-constant value in a constant" - ); + ResolutionError::AttemptToUseNonConstantValueInConstant(ident, suggestion, current) => { // let foo =... // ^^^ given this Span // ------- get this Span to have an applicable suggestion @@ -899,23 +800,34 @@ impl<'a> Resolver<'a> { .source_map() .span_extend_to_prev_str(ident.span, current, true, false); - match sp { + let ((with, with_label), without) = match sp { Some(sp) if !self.session.source_map().is_multiline(sp) => { let sp = sp.with_lo(BytePos(sp.lo().0 - (current.len() as u32))); - err.span_suggestion( - sp, - &format!("consider using `{}` instead of `{}`", sugg, current), - format!("{} {}", sugg, ident), - Applicability::MaybeIncorrect, - ); - err.span_label(span, "non-constant value"); - } - _ => { - err.span_label(ident.span, &format!("this would need to be a `{}`", sugg)); + ( + (Some(errs::AttemptToUseNonConstantValueInConstantWithSuggestion { + span: sp, + ident, + suggestion, + current, + }), Some(errs::AttemptToUseNonConstantValueInConstantLabelWithSuggestion {span})), + None, + ) } - } + _ => ( + (None, None), + Some(errs::AttemptToUseNonConstantValueInConstantWithoutSuggestion { + ident_span: ident.span, + suggestion, + }), + ), + }; - err + self.session.create_err(errs::AttemptToUseNonConstantValueInConstant { + span, + with, + with_label, + without, + }) } ResolutionError::BindingShadowsSomethingUnacceptable { shadowing_binding, @@ -924,135 +836,80 @@ impl<'a> Resolver<'a> { article, shadowed_binding, shadowed_binding_span, - } => { - let shadowed_binding_descr = shadowed_binding.descr(); - let mut err = struct_span_err!( - self.session, - span, - E0530, - "{}s cannot shadow {}s", - shadowing_binding.descr(), - shadowed_binding_descr, - ); - err.span_label( - span, - format!("cannot be named the same as {} {}", article, shadowed_binding_descr), - ); - match (shadowing_binding, shadowed_binding) { + } => self.session.create_err(errs::BindingShadowsSomethingUnacceptable { + span, + shadowing_binding, + shadowed_binding, + article, + sub_suggestion: match (shadowing_binding, shadowed_binding) { ( PatternSource::Match, Res::Def(DefKind::Ctor(CtorOf::Variant | CtorOf::Struct, CtorKind::Fn), _), - ) => { - err.span_suggestion( - span, - "try specify the pattern arguments", - format!("{}(..)", name), - Applicability::Unspecified, - ); - } - _ => (), - } - let msg = - format!("the {} `{}` is {} here", shadowed_binding_descr, name, participle); - err.span_label(shadowed_binding_span, msg); - err - } + ) => Some(errs::BindingShadowsSomethingUnacceptableSuggestion { span, name }), + _ => None, + }, + shadowed_binding_span, + participle, + name, + }), ResolutionError::ForwardDeclaredGenericParam => { - let mut err = struct_span_err!( - self.session, - span, - E0128, - "generic parameters with a default cannot use \ - forward declared identifiers" - ); - err.span_label(span, "defaulted generic parameters cannot be forward declared"); - err + self.session.create_err(errs::ForwardDeclaredGenericParam { span }) } ResolutionError::ParamInTyOfConstParam(name) => { - let mut err = struct_span_err!( - self.session, - span, - E0770, - "the type of const parameters must not depend on other generic parameters" - ); - err.span_label( - span, - format!("the type must not depend on the parameter `{}`", name), - ); - err + self.session.create_err(errs::ParamInTyOfConstParam { span, name }) } ResolutionError::ParamInNonTrivialAnonConst { name, is_type } => { - let mut err = self.session.struct_span_err( + self.session.create_err(errs::ParamInNonTrivialAnonConst { span, - "generic parameters may not be used in const operations", - ); - err.span_label(span, &format!("cannot perform const operation using `{}`", name)); - - if is_type { - err.note("type parameters may not be used in const expressions"); - } else { - err.help(&format!( - "const parameters may only be used as standalone arguments, i.e. `{}`", - name - )); - } - - if self.session.is_nightly_build() { - err.help( - "use `#![feature(generic_const_exprs)]` to allow generic const expressions", - ); - } - - err + name, + sub_is_type: if is_type { + errs::ParamInNonTrivialAnonConstIsType::AType + } else { + errs::ParamInNonTrivialAnonConstIsType::NotAType { name } + }, + help: self + .session + .is_nightly_build() + .then_some(errs::ParamInNonTrivialAnonConstHelp), + }) } ResolutionError::SelfInGenericParamDefault => { - let mut err = struct_span_err!( - self.session, - span, - E0735, - "generic parameters cannot use `Self` in their defaults" - ); - err.span_label(span, "`Self` in generic parameter default"); - err + self.session.create_err(errs::SelfInGenericParamDefault { span }) } ResolutionError::UnreachableLabel { name, definition_span, suggestion } => { - let mut err = struct_span_err!( - self.session, + let ((sub_suggestion_label, sub_suggestion), sub_unreachable_label) = + match suggestion { + // A reachable label with a similar name exists. + Some((ident, true)) => ( + ( + Some(errs::UnreachableLabelSubLabel { ident_span: ident.span }), + Some(errs::UnreachableLabelSubSuggestion { + span, + // intentionally taking 'ident.name' instead of 'ident' itself, as this + // could be used in suggestion context + ident_name: ident.name, + }), + ), + None, + ), + // An unreachable label with a similar name exists. + Some((ident, false)) => ( + (None, None), + Some(errs::UnreachableLabelSubLabelUnreachable { + ident_span: ident.span, + }), + ), + // No similarly-named labels exist. + None => ((None, None), None), + }; + self.session.create_err(errs::UnreachableLabel { span, - E0767, - "use of unreachable label `{}`", name, - ); - - err.span_label(definition_span, "unreachable label defined here"); - err.span_label(span, format!("unreachable label `{}`", name)); - err.note( - "labels are unreachable through functions, closures, async blocks and modules", - ); - - match suggestion { - // A reachable label with a similar name exists. - Some((ident, true)) => { - err.span_label(ident.span, "a label with a similar name is reachable"); - err.span_suggestion( - span, - "try using similarly named label", - ident.name, - Applicability::MaybeIncorrect, - ); - } - // An unreachable label with a similar name exists. - Some((ident, false)) => { - err.span_label( - ident.span, - "a label with a similar name exists but is also unreachable", - ); - } - // No similarly-named labels exist. - None => (), - } - - err + definition_span, + sub_suggestion, + sub_suggestion_label, + sub_unreachable_label, + }) } ResolutionError::TraitImplMismatch { name, @@ -1073,25 +930,10 @@ impl<'a> Resolver<'a> { err.span_label(trait_item_span, "item in trait"); err } - ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => { - let mut err = struct_span_err!( - self.session, - span, - E0201, - "duplicate definitions with name `{}`:", - name, - ); - err.span_label(old_span, "previous definition here"); - err.span_label(trait_item_span, "item in trait"); - err.span_label(span, "duplicate definition"); - err - } - ResolutionError::InvalidAsmSym => { - let mut err = self.session.struct_span_err(span, "invalid `sym` operand"); - err.span_label(span, "is a local variable"); - err.help("`sym` operands must refer to either a function or a static"); - err - } + ResolutionError::TraitImplDuplicate { name, trait_item_span, old_span } => self + .session + .create_err(errs::TraitImplDuplicate { span, name, trait_item_span, old_span }), + ResolutionError::InvalidAsmSym => self.session.create_err(errs::InvalidAsmSym { span }), } } @@ -1101,48 +943,27 @@ impl<'a> Resolver<'a> { ) -> ErrorGuaranteed { match vis_resolution_error { VisResolutionError::Relative2018(span, path) => { - let mut err = self.session.struct_span_err( + self.session.create_err(errs::Relative2018 { span, - "relative paths are not supported in visibilities in 2018 edition or later", - ); - err.span_suggestion( - path.span, - "try", - format!("crate::{}", pprust::path_to_string(&path)), - Applicability::MaybeIncorrect, - ); - err + path_span: path.span, + // intentionally converting to String, as the text would also be used as + // in suggestion context + path_str: pprust::path_to_string(&path), + }) + } + VisResolutionError::AncestorOnly(span) => { + self.session.create_err(errs::AncestorOnly(span)) } - VisResolutionError::AncestorOnly(span) => struct_span_err!( - self.session, - span, - E0742, - "visibilities can only be restricted to ancestor modules" - ), VisResolutionError::FailedToResolve(span, label, suggestion) => { self.into_struct_error(span, ResolutionError::FailedToResolve { label, suggestion }) } VisResolutionError::ExpectedFound(span, path_str, res) => { - let mut err = struct_span_err!( - self.session, - span, - E0577, - "expected module, found {} `{}`", - res.descr(), - path_str - ); - err.span_label(span, "not a module"); - err + self.session.create_err(errs::ExpectedFound { span, res, path_str }) } - VisResolutionError::Indeterminate(span) => struct_span_err!( - self.session, - span, - E0578, - "cannot determine resolution for the visibility" - ), - VisResolutionError::ModuleOnly(span) => { - self.session.struct_span_err(span, "visibility must resolve to a module") + VisResolutionError::Indeterminate(span) => { + self.session.create_err(errs::Indeterminate(span)) } + VisResolutionError::ModuleOnly(span) => self.session.create_err(errs::ModuleOnly(span)), } .emit() } @@ -1295,7 +1116,7 @@ impl<'a> Resolver<'a> { { let mut candidates = Vec::new(); let mut seen_modules = FxHashSet::default(); - let mut worklist = vec![(start_module, Vec::<ast::PathSegment>::new(), true)]; + let mut worklist = vec![(start_module, ThinVec::<ast::PathSegment>::new(), true)]; let mut worklist_via_import = vec![]; while let Some((in_module, path_segments, accessible)) = match worklist.pop() { diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs new file mode 100644 index 00000000000..2c442774667 --- /dev/null +++ b/compiler/rustc_resolve/src/errors.rs @@ -0,0 +1,474 @@ +use rustc_macros::{Diagnostic, Subdiagnostic}; +use rustc_span::{ + symbol::{Ident, Symbol}, + Span, +}; + +use crate::{late::PatternSource, Res}; + +#[derive(Diagnostic)] +#[diag(resolve_parent_module_reset_for_binding, code = "E0637")] +pub(crate) struct ParentModuleResetForBinding; + +#[derive(Diagnostic)] +#[diag(resolve_ampersand_used_without_explicit_lifetime_name, code = "E0637")] +#[note] +pub(crate) struct AmpersandUsedWithoutExplicitLifetimeName(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_underscore_lifetime_name_cannot_be_used_here, code = "E0637")] +#[note] +pub(crate) struct UnderscoreLifetimeNameCannotBeUsedHere(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_crate_may_not_be_imported)] +pub(crate) struct CrateMayNotBeImprted(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_crate_root_imports_must_be_named_explicitly)] +pub(crate) struct CrateRootNamesMustBeNamedExplicitly(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_crate_root_imports_must_be_named_explicitly)] +pub(crate) struct ResolutionError(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_name_is_already_used_as_generic_parameter, code = "E0403")] +pub(crate) struct NameAlreadyUsedInParameterList { + #[primary_span] + #[label] + pub(crate) span: Span, + #[label(first_use_of_name)] + pub(crate) first_use_span: Span, + pub(crate) name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_method_not_member_of_trait, code = "E0407")] +pub(crate) struct MethodNotMemberOfTrait { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) method: Ident, + pub(crate) trait_: String, + #[subdiagnostic] + pub(crate) sub: Option<AssociatedFnWithSimilarNameExists>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_associated_fn_with_similar_name_exists, + code = "{candidate}", + applicability = "maybe-incorrect" +)] +pub(crate) struct AssociatedFnWithSimilarNameExists { + #[primary_span] + pub(crate) span: Span, + pub(crate) candidate: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_type_not_member_of_trait, code = "E0437")] +pub(crate) struct TypeNotMemberOfTrait { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) type_: Ident, + pub(crate) trait_: String, + #[subdiagnostic] + pub(crate) sub: Option<AssociatedTypeWithSimilarNameExists>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_associated_type_with_similar_name_exists, + code = "{candidate}", + applicability = "maybe-incorrect" +)] +pub(crate) struct AssociatedTypeWithSimilarNameExists { + #[primary_span] + pub(crate) span: Span, + pub(crate) candidate: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_const_not_member_of_trait, code = "E0438")] +pub(crate) struct ConstNotMemberOfTrait { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) const_: Ident, + pub(crate) trait_: String, + #[subdiagnostic] + pub(crate) sub: Option<AssociatedConstWithSimilarNameExists>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_associated_const_with_similar_name_exists, + code = "{candidate}", + applicability = "maybe-incorrect" +)] +pub(crate) struct AssociatedConstWithSimilarNameExists { + #[primary_span] + pub(crate) span: Span, + pub(crate) candidate: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_variable_bound_with_different_mode, code = "E0409")] +pub(crate) struct VariableBoundWithDifferentMode { + #[primary_span] + #[label] + pub(crate) span: Span, + #[label(first_binding_span)] + pub(crate) first_binding_span: Span, + pub(crate) variable_name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_ident_bound_more_than_once_in_parameter_list, code = "E0415")] +pub(crate) struct IdentifierBoundMoreThanOnceInParameterList { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) identifier: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_ident_bound_more_than_once_in_same_pattern, code = "E0416")] +pub(crate) struct IdentifierBoundMoreThanOnceInSamePattern { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) identifier: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_undeclared_label, code = "E0426")] +pub(crate) struct UndeclaredLabel { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + #[subdiagnostic] + pub(crate) sub_reachable: Option<LabelWithSimilarNameReachable>, + #[subdiagnostic] + pub(crate) sub_reachable_suggestion: Option<TryUsingSimilarlyNamedLabel>, + #[subdiagnostic] + pub(crate) sub_unreachable: Option<UnreachableLabelWithSimilarNameExists>, +} + +#[derive(Subdiagnostic)] +#[label(resolve_label_with_similar_name_reachable)] +pub(crate) struct LabelWithSimilarNameReachable(#[primary_span] pub(crate) Span); + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_try_using_similarly_named_label, + code = "{ident_name}", + applicability = "maybe-incorrect" +)] +pub(crate) struct TryUsingSimilarlyNamedLabel { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident_name: Symbol, +} + +#[derive(Subdiagnostic)] +#[label(resolve_unreachable_label_with_similar_name_exists)] +pub(crate) struct UnreachableLabelWithSimilarNameExists { + #[primary_span] + pub(crate) ident_span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_import_can_only_appear_once_in_the_list, code = "E0430")] +pub(crate) struct SelfImportCanOnlyAppearOnceInTheList { + #[primary_span] + #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_import_only_in_import_list_with_non_empty_prefix, code = "E0431")] +pub(crate) struct SelfImportOnlyInImportListWithNonEmptyPrefix { + #[primary_span] + #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_cannot_capture_dynamic_environment_in_fn_item, code = "E0434")] +#[help] +pub(crate) struct CannotCaptureDynamicEnvironmentInFnItem { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_attempt_to_use_non_constant_value_in_constant, code = "E0435")] +pub(crate) struct AttemptToUseNonConstantValueInConstant<'a> { + #[primary_span] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) with: Option<AttemptToUseNonConstantValueInConstantWithSuggestion<'a>>, + #[subdiagnostic] + pub(crate) with_label: Option<AttemptToUseNonConstantValueInConstantLabelWithSuggestion>, + #[subdiagnostic] + pub(crate) without: Option<AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a>>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_attempt_to_use_non_constant_value_in_constant_with_suggestion, + code = "{suggestion} {ident}", + applicability = "maybe-incorrect" +)] +pub(crate) struct AttemptToUseNonConstantValueInConstantWithSuggestion<'a> { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident: Ident, + pub(crate) suggestion: &'a str, + pub(crate) current: &'a str, +} + +#[derive(Subdiagnostic)] +#[label(resolve_attempt_to_use_non_constant_value_in_constant_label_with_suggestion)] +pub(crate) struct AttemptToUseNonConstantValueInConstantLabelWithSuggestion { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[label(resolve_attempt_to_use_non_constant_value_in_constant_without_suggestion)] +pub(crate) struct AttemptToUseNonConstantValueInConstantWithoutSuggestion<'a> { + #[primary_span] + pub(crate) ident_span: Span, + pub(crate) suggestion: &'a str, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_imports_only_allowed_within, code = "E0429")] +pub(crate) struct SelfImportsOnlyAllowedWithin { + #[primary_span] + pub(crate) span: Span, + #[subdiagnostic] + pub(crate) suggestion: Option<SelfImportsOnlyAllowedWithinSuggestion>, + #[subdiagnostic] + pub(crate) mpart_suggestion: Option<SelfImportsOnlyAllowedWithinMultipartSuggestion>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_self_imports_only_allowed_within_suggestion, + code = "", + applicability = "machine-applicable" +)] +pub(crate) struct SelfImportsOnlyAllowedWithinSuggestion { + #[primary_span] + pub(crate) span: Span, +} + +#[derive(Subdiagnostic)] +#[multipart_suggestion( + resolve_self_imports_only_allowed_within_multipart_suggestion, + applicability = "machine-applicable" +)] +pub(crate) struct SelfImportsOnlyAllowedWithinMultipartSuggestion { + #[suggestion_part(code = "{{")] + pub(crate) multipart_start: Span, + #[suggestion_part(code = "}}")] + pub(crate) multipart_end: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_binding_shadows_something_unacceptable, code = "E0530")] +pub(crate) struct BindingShadowsSomethingUnacceptable<'a> { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) shadowing_binding: PatternSource, + pub(crate) shadowed_binding: Res, + pub(crate) article: &'a str, + #[subdiagnostic] + pub(crate) sub_suggestion: Option<BindingShadowsSomethingUnacceptableSuggestion>, + #[label(label_shadowed_binding)] + pub(crate) shadowed_binding_span: Span, + pub(crate) participle: &'a str, + pub(crate) name: Symbol, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_binding_shadows_something_unacceptable_suggestion, + code = "{name}(..)", + applicability = "unspecified" +)] +pub(crate) struct BindingShadowsSomethingUnacceptableSuggestion { + #[primary_span] + pub(crate) span: Span, + pub(crate) name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_forward_declared_generic_param, code = "E0128")] +pub(crate) struct ForwardDeclaredGenericParam { + #[primary_span] + #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_param_in_ty_of_const_param, code = "E0770")] +pub(crate) struct ParamInTyOfConstParam { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_self_in_generic_param_default, code = "E0735")] +pub(crate) struct SelfInGenericParamDefault { + #[primary_span] + #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_param_in_non_trivial_anon_const)] +pub(crate) struct ParamInNonTrivialAnonConst { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + #[subdiagnostic] + pub(crate) sub_is_type: ParamInNonTrivialAnonConstIsType, + #[subdiagnostic] + pub(crate) help: Option<ParamInNonTrivialAnonConstHelp>, +} + +#[derive(Subdiagnostic)] +#[help(resolve_param_in_non_trivial_anon_const_help)] +pub(crate) struct ParamInNonTrivialAnonConstHelp; + +#[derive(Subdiagnostic)] +pub(crate) enum ParamInNonTrivialAnonConstIsType { + #[note(resolve_param_in_non_trivial_anon_const_sub_type)] + AType, + #[help(resolve_param_in_non_trivial_anon_const_sub_non_type)] + NotAType { name: Symbol }, +} + +#[derive(Diagnostic)] +#[diag(resolve_unreachable_label, code = "E0767")] +#[note] +pub(crate) struct UnreachableLabel { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + #[label(label_definition_span)] + pub(crate) definition_span: Span, + #[subdiagnostic] + pub(crate) sub_suggestion: Option<UnreachableLabelSubSuggestion>, + #[subdiagnostic] + pub(crate) sub_suggestion_label: Option<UnreachableLabelSubLabel>, + #[subdiagnostic] + pub(crate) sub_unreachable_label: Option<UnreachableLabelSubLabelUnreachable>, +} + +#[derive(Subdiagnostic)] +#[suggestion( + resolve_unreachable_label_suggestion_use_similarly_named, + code = "{ident_name}", + applicability = "maybe-incorrect" +)] +pub(crate) struct UnreachableLabelSubSuggestion { + #[primary_span] + pub(crate) span: Span, + pub(crate) ident_name: Symbol, +} + +#[derive(Subdiagnostic)] +#[label(resolve_unreachable_label_similar_name_reachable)] +pub(crate) struct UnreachableLabelSubLabel { + #[primary_span] + pub(crate) ident_span: Span, +} + +#[derive(Subdiagnostic)] +#[label(resolve_unreachable_label_similar_name_unreachable)] +pub(crate) struct UnreachableLabelSubLabelUnreachable { + #[primary_span] + pub(crate) ident_span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_trait_impl_mismatch, code = "{code}")] +pub(crate) struct TraitImplMismatch { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) name: Symbol, + pub(crate) kind: String, + #[label(label_trait_item)] + pub(crate) trait_item_span: Span, + pub(crate) trait_path: String, + pub(crate) code: String, +} + +#[derive(Diagnostic)] +#[diag(resolve_invalid_asm_sym)] +#[help] +pub(crate) struct InvalidAsmSym { + #[primary_span] + #[label] + pub(crate) span: Span, +} + +#[derive(Diagnostic)] +#[diag(resolve_trait_impl_duplicate, code = "E0201")] +pub(crate) struct TraitImplDuplicate { + #[primary_span] + #[label] + pub(crate) span: Span, + #[label(old_span_label)] + pub(crate) old_span: Span, + #[label(trait_item_span)] + pub(crate) trait_item_span: Span, + pub(crate) name: Symbol, +} + +#[derive(Diagnostic)] +#[diag(resolve_relative_2018)] +pub(crate) struct Relative2018 { + #[primary_span] + pub(crate) span: Span, + #[suggestion(code = "crate::{path_str}", applicability = "maybe-incorrect")] + pub(crate) path_span: Span, + pub(crate) path_str: String, +} + +#[derive(Diagnostic)] +#[diag(resolve_ancestor_only, code = "E0742")] +pub(crate) struct AncestorOnly(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_expected_found, code = "E0577")] +pub(crate) struct ExpectedFound { + #[primary_span] + #[label] + pub(crate) span: Span, + pub(crate) res: Res, + pub(crate) path_str: String, +} + +#[derive(Diagnostic)] +#[diag(resolve_indeterminate, code = "E0578")] +pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span); + +#[derive(Diagnostic)] +#[diag(resolve_module_only)] +pub(crate) struct ModuleOnly(#[primary_span] pub(crate) Span); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ede67813883..5072d2aad16 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -16,7 +16,7 @@ use rustc_ast::ptr::P; use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor}; use rustc_ast::*; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; -use rustc_errors::DiagnosticId; +use rustc_errors::{DiagnosticArgValue, DiagnosticId, IntoDiagnosticArg}; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, PartialRes, PerNS}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE}; @@ -31,6 +31,7 @@ use smallvec::{smallvec, SmallVec}; use rustc_span::source_map::{respan, Spanned}; use std::assert_matches::debug_assert_matches; +use std::borrow::Cow; use std::collections::{hash_map::Entry, BTreeSet}; use std::mem::{replace, swap, take}; @@ -78,6 +79,12 @@ impl PatternSource { } } +impl IntoDiagnosticArg for PatternSource { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Borrowed(self.descr())) + } +} + /// Denotes whether the context for the set of already bound bindings is a `Product` /// or `Or` context. This is used in e.g., `fresh_binding` and `resolve_pattern_inner`. /// See those functions for more information. @@ -648,7 +655,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { } TyKind::Path(ref qself, ref path) => { self.diagnostic_metadata.current_type_path = Some(ty); - self.smart_resolve_path(ty.id, qself.as_ref(), path, PathSource::Type); + self.smart_resolve_path(ty.id, &qself, path, PathSource::Type); // Check whether we should interpret this as a bare trait object. if qself.is_none() @@ -749,7 +756,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { this.visit_generic_params(&tref.bound_generic_params, false); this.smart_resolve_path( tref.trait_ref.ref_id, - None, + &None, &tref.trait_ref.path, PathSource::Trait(AliasPossibility::Maybe), ); @@ -978,7 +985,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { |this| { this.smart_resolve_path( ty.id, - qself.as_ref(), + qself, path, PathSource::Expr(None), ); @@ -1138,12 +1145,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { self.with_rib(ValueNS, InlineAsmSymRibKind, |this| { this.with_rib(TypeNS, InlineAsmSymRibKind, |this| { this.with_label_rib(InlineAsmSymRibKind, |this| { - this.smart_resolve_path( - sym.id, - sym.qself.as_ref(), - &sym.path, - PathSource::Expr(None), - ); + this.smart_resolve_path(sym.id, &sym.qself, &sym.path, PathSource::Expr(None)); visit::walk_inline_asm_sym(this, sym); }); }) @@ -2571,7 +2573,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.diagnostic_metadata.currently_processing_impl_trait = Some((trait_ref.clone(), self_type.clone())); let res = self.smart_resolve_path_fragment( - None, + &None, &path, PathSource::Trait(AliasPossibility::No), Finalize::new(trait_ref.ref_id, trait_ref.path.span), @@ -3094,7 +3096,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { PatKind::TupleStruct(ref qself, ref path, ref sub_patterns) => { self.smart_resolve_path( pat.id, - qself.as_ref(), + qself, path, PathSource::TupleStruct( pat.span, @@ -3103,10 +3105,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ); } PatKind::Path(ref qself, ref path) => { - self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Pat); + self.smart_resolve_path(pat.id, qself, path, PathSource::Pat); } PatKind::Struct(ref qself, ref path, ..) => { - self.smart_resolve_path(pat.id, qself.as_ref(), path, PathSource::Struct); + self.smart_resolve_path(pat.id, qself, path, PathSource::Struct); } PatKind::Or(ref ps) => { // Add a new set of bindings to the stack. `Or` here records that when a @@ -3299,7 +3301,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { fn smart_resolve_path( &mut self, id: NodeId, - qself: Option<&QSelf>, + qself: &Option<P<QSelf>>, path: &Path, source: PathSource<'ast>, ) { @@ -3313,7 +3315,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { fn smart_resolve_path_fragment( &mut self, - qself: Option<&QSelf>, + qself: &Option<P<QSelf>>, path: &[Segment], source: PathSource<'ast>, finalize: Finalize, @@ -3534,7 +3536,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Resolve in alternative namespaces if resolution in the primary namespace fails. fn resolve_qpath_anywhere( &mut self, - qself: Option<&QSelf>, + qself: &Option<P<QSelf>>, path: &[Segment], primary_ns: Namespace, span: Span, @@ -3578,7 +3580,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { /// Handles paths that may refer to associated items. fn resolve_qpath( &mut self, - qself: Option<&QSelf>, + qself: &Option<P<QSelf>>, path: &[Segment], ns: Namespace, finalize: Finalize, @@ -3608,7 +3610,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // but with `qself` set to `None`. let ns = if qself.position + 1 == path.len() { ns } else { TypeNS }; let partial_res = self.smart_resolve_path_fragment( - None, + &None, &path[..=qself.position], PathSource::TraitItem(ns), Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span), @@ -3791,12 +3793,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Next, resolve the node. match expr.kind { ExprKind::Path(ref qself, ref path) => { - self.smart_resolve_path(expr.id, qself.as_ref(), path, PathSource::Expr(parent)); + self.smart_resolve_path(expr.id, qself, path, PathSource::Expr(parent)); visit::walk_expr(self, expr); } ExprKind::Struct(ref se) => { - self.smart_resolve_path(expr.id, se.qself.as_ref(), &se.path, PathSource::Struct); + self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct); visit::walk_expr(self, expr); } @@ -3866,12 +3868,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ExprKind::Field(ref subexpression, _) => { self.resolve_expr(subexpression, Some(expr)); } - ExprKind::MethodCall(ref segment, ref receiver, ref arguments, _) => { + ExprKind::MethodCall(box MethodCall { ref seg, ref receiver, ref args, .. }) => { self.resolve_expr(receiver, Some(expr)); - for argument in arguments { - self.resolve_expr(argument, None); + for arg in args { + self.resolve_expr(arg, None); } - self.visit_path_segment(segment); + self.visit_path_segment(seg); } ExprKind::Call(ref callee, ref arguments) => { @@ -3913,7 +3915,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // `async |x| ...` gets desugared to `|x| future_from_generator(|| ...)`, so we need to // resolve the arguments within the proper scopes so that usages of them inside the // closure are detected as upvars rather than normal closure arg usages. - ExprKind::Closure(_, _, Async::Yes { .. }, _, ref fn_decl, ref body, _span) => { + ExprKind::Closure(box ast::Closure { + asyncness: Async::Yes { .. }, + ref fn_decl, + ref body, + .. + }) => { self.with_rib(ValueNS, NormalRibKind, |this| { this.with_label_rib(ClosureOrAsyncRibKind, |this| { // Resolve arguments: @@ -3933,7 +3940,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { }); } // For closures, ClosureOrAsyncRibKind is added in visit_fn - ExprKind::Closure(ClosureBinder::For { ref generic_params, span }, ..) => { + ExprKind::Closure(box ast::Closure { + binder: ClosureBinder::For { ref generic_params, span }, + .. + }) => { self.with_generic_param_rib( &generic_params, NormalRibKind, @@ -3990,9 +4000,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let traits = self.traits_in_scope(ident, ValueNS); self.r.trait_map.insert(expr.id, traits); } - ExprKind::MethodCall(ref segment, ..) => { + ExprKind::MethodCall(ref call) => { debug!("(recording candidate traits for expr) recording traits for {}", expr.id); - let traits = self.traits_in_scope(segment.ident, ValueNS); + let traits = self.traits_in_scope(call.seg.ident, ValueNS); self.r.trait_map.insert(expr.id, traits); } _ => { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 95eff92ef5e..b340bee28c3 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -8,7 +8,7 @@ use crate::{PathResult, PathSource, Segment}; use rustc_ast::visit::{FnCtxt, FnKind, LifetimeCtxt}; use rustc_ast::{ self as ast, AssocItemKind, Expr, ExprKind, GenericParam, GenericParamKind, Item, ItemKind, - NodeId, Path, Ty, TyKind, DUMMY_NODE_ID, + MethodCall, NodeId, Path, Ty, TyKind, DUMMY_NODE_ID, }; use rustc_ast_pretty::pprust::path_segment_to_string; use rustc_data_structures::fx::FxHashSet; @@ -33,6 +33,8 @@ use rustc_span::{BytePos, Span}; use std::iter; use std::ops::Deref; +use thin_vec::ThinVec; + type Res = def::Res<ast::NodeId>; /// A field or associated item from self type suggested in case of resolution failure. @@ -78,7 +80,7 @@ fn import_candidate_to_enum_paths(suggestion: &ImportSuggestion) -> (String, Str let path_len = suggestion.path.segments.len(); let enum_path = ast::Path { span: suggestion.path.span, - segments: suggestion.path.segments[0..path_len - 1].to_vec(), + segments: suggestion.path.segments[0..path_len - 1].iter().cloned().collect(), tokens: None, }; let enum_path_string = path_names_to_string(&enum_path); @@ -1022,11 +1024,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { }; // Confirm that the target is an associated type. - let (ty, position, path) = if let ast::TyKind::Path( - Some(ast::QSelf { ty, position, .. }), - path, - ) = &bounded_ty.kind - { + let (ty, position, path) = if let ast::TyKind::Path(Some(qself), path) = &bounded_ty.kind { // use this to verify that ident is a type param. let Some(partial_res) = self.r.partial_res_map.get(&bounded_ty.id) else { return false; @@ -1037,7 +1035,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { ) { return false; } - (ty, position, path) + (&qself.ty, qself.position, path) } else { return false; }; @@ -1073,12 +1071,12 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .source_map() .span_to_snippet(ty.span) // Account for `<&'a T as Foo>::Bar`. .unwrap_or_else(|_| constrain_ident.to_string()), - path.segments[..*position] + path.segments[..position] .iter() .map(|segment| path_segment_to_string(segment)) .collect::<Vec<_>>() .join("::"), - path.segments[*position..] + path.segments[position..] .iter() .map(|segment| path_segment_to_string(segment)) .collect::<Vec<_>>() @@ -1170,7 +1168,9 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let (lhs_span, rhs_span) = match &expr.kind { ExprKind::Field(base, ident) => (base.span, ident.span), - ExprKind::MethodCall(_, receiver, _, span) => (receiver.span, *span), + ExprKind::MethodCall(box MethodCall { receiver, span, .. }) => { + (receiver.span, *span) + } _ => return false, }; @@ -1442,13 +1442,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_label(span, "constructor is not visible here due to private fields"); } - ( - Res::Def( - DefKind::Union | DefKind::Variant | DefKind::Ctor(_, CtorKind::Fictive), - def_id, - ), - _, - ) if ns == ValueNS => { + (Res::Def(DefKind::Union | DefKind::Variant, def_id), _) if ns == ValueNS => { bad_struct_syntax_suggestion(def_id); } (Res::Def(DefKind::Ctor(_, CtorKind::Const), def_id), _) if ns == ValueNS => { @@ -1833,7 +1827,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { fn find_module(&mut self, def_id: DefId) -> Option<(Module<'a>, ImportSuggestion)> { let mut result = None; let mut seen_modules = FxHashSet::default(); - let mut worklist = vec![(self.r.graph_root, Vec::new())]; + let mut worklist = vec![(self.r.graph_root, ThinVec::new())]; while let Some((in_module, path_segments)) = worklist.pop() { // abort if the module is already found @@ -1963,7 +1957,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let has_no_fields = self.r.field_names.get(&def_id).map_or(false, |f| f.is_empty()); match kind { CtorKind::Const => false, - CtorKind::Fn | CtorKind::Fictive if has_no_fields => false, + CtorKind::Fn if has_no_fields => false, _ => true, } }; @@ -1975,7 +1969,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map(|(variant, kind)| match kind { CtorKind::Const => variant, CtorKind::Fn => format!("({}())", variant), - CtorKind::Fictive => format!("({} {{}})", variant), }) .collect::<Vec<_>>(); let no_suggestable_variant = suggestable_variants.is_empty(); @@ -2001,7 +1994,6 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map(|(variant, _, kind)| (path_names_to_string(variant), kind)) .filter_map(|(variant, kind)| match kind { CtorKind::Fn => Some(format!("({}(/* fields */))", variant)), - CtorKind::Fictive => Some(format!("({} {{ /* fields */ }})", variant)), _ => None, }) .collect::<Vec<_>>(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 9ca3588fff4..f9ae3b58172 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -73,6 +73,7 @@ mod check_unused; mod def_collector; mod diagnostics; mod effective_visibilities; +mod errors; mod ident; mod imports; mod late; diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index 4bfa583fc72..2f7055e3cc5 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -196,7 +196,7 @@ pub enum UnleashedFeatureHelp { } #[derive(Diagnostic)] -#[diag(parser_invalid_literal_suffix)] +#[diag(session_invalid_literal_suffix)] pub(crate) struct InvalidLiteralSuffix { #[primary_span] #[label] @@ -207,7 +207,7 @@ pub(crate) struct InvalidLiteralSuffix { } #[derive(Diagnostic)] -#[diag(parser_invalid_int_literal_width)] +#[diag(session_invalid_int_literal_width)] #[help] pub(crate) struct InvalidIntLiteralWidth { #[primary_span] @@ -216,7 +216,7 @@ pub(crate) struct InvalidIntLiteralWidth { } #[derive(Diagnostic)] -#[diag(parser_invalid_num_literal_base_prefix)] +#[diag(session_invalid_num_literal_base_prefix)] #[note] pub(crate) struct InvalidNumLiteralBasePrefix { #[primary_span] @@ -226,7 +226,7 @@ pub(crate) struct InvalidNumLiteralBasePrefix { } #[derive(Diagnostic)] -#[diag(parser_invalid_num_literal_suffix)] +#[diag(session_invalid_num_literal_suffix)] #[help] pub(crate) struct InvalidNumLiteralSuffix { #[primary_span] @@ -236,7 +236,7 @@ pub(crate) struct InvalidNumLiteralSuffix { } #[derive(Diagnostic)] -#[diag(parser_invalid_float_literal_width)] +#[diag(session_invalid_float_literal_width)] #[help] pub(crate) struct InvalidFloatLiteralWidth { #[primary_span] @@ -245,7 +245,7 @@ pub(crate) struct InvalidFloatLiteralWidth { } #[derive(Diagnostic)] -#[diag(parser_invalid_float_literal_suffix)] +#[diag(session_invalid_float_literal_suffix)] #[help] pub(crate) struct InvalidFloatLiteralSuffix { #[primary_span] @@ -255,33 +255,33 @@ pub(crate) struct InvalidFloatLiteralSuffix { } #[derive(Diagnostic)] -#[diag(parser_int_literal_too_large)] +#[diag(session_int_literal_too_large)] pub(crate) struct IntLiteralTooLarge { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_hexadecimal_float_literal_not_supported)] +#[diag(session_hexadecimal_float_literal_not_supported)] pub(crate) struct HexadecimalFloatLiteralNotSupported { #[primary_span] - #[label(parser_not_supported)] + #[label(session_not_supported)] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_octal_float_literal_not_supported)] +#[diag(session_octal_float_literal_not_supported)] pub(crate) struct OctalFloatLiteralNotSupported { #[primary_span] - #[label(parser_not_supported)] + #[label(session_not_supported)] pub span: Span, } #[derive(Diagnostic)] -#[diag(parser_binary_float_literal_not_supported)] +#[diag(session_binary_float_literal_not_supported)] pub(crate) struct BinaryFloatLiteralNotSupported { #[primary_span] - #[label(parser_not_supported)] + #[label(session_not_supported)] pub span: Span, } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 10352198357..d602acec53e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -562,7 +562,10 @@ impl Session { if self.err_count() == old_count { Ok(result) } else { - Err(ErrorGuaranteed::unchecked_claim_error_was_emitted()) + Err(self.delay_span_bug( + rustc_span::DUMMY_SP, + "`self.err_count()` changed but an error was not emitted", + )) } } #[allow(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs index 7ea028b12ef..e8d129d733c 100644 --- a/compiler/rustc_span/src/source_map.rs +++ b/compiler/rustc_span/src/source_map.rs @@ -753,10 +753,11 @@ impl SourceMap { } } - /// Given a 'Span', tries to tell if the next character is '>' - /// and the previous charactoer is '<' after skipping white space - /// return true if wrapped by '<>' - pub fn span_wrapped_by_angle_bracket(&self, span: Span) -> bool { + /// Given a 'Span', tries to tell if it's wrapped by "<>" or "()" + /// the algorithm searches if the next character is '>' or ')' after skipping white space + /// then searches the previous charactoer to match '<' or '(' after skipping white space + /// return true if wrapped by '<>' or '()' + pub fn span_wrapped_by_angle_or_parentheses(&self, span: Span) -> bool { self.span_to_source(span, |src, start_index, end_index| { if src.get(start_index..end_index).is_none() { return Ok(false); @@ -764,11 +765,17 @@ impl SourceMap { // test the right side to match '>' after skipping white space let end_src = &src[end_index..]; let mut i = 0; + let mut found_right_parentheses = false; + let mut found_right_angle = false; while let Some(cc) = end_src.chars().nth(i) { if cc == ' ' { i = i + 1; } else if cc == '>' { // found > in the right; + found_right_angle = true; + break; + } else if cc == ')' { + found_right_parentheses = true; break; } else { // failed to find '>' return false immediately @@ -786,6 +793,16 @@ impl SourceMap { i = i - 1; } else if cc == '<' { // found < in the left + if !found_right_angle { + // skip something like "(< )>" + return Ok(false); + } + break; + } else if cc == '(' { + if !found_right_parentheses { + // skip something like "<(>)" + return Ok(false); + } break; } else { // failed to find '<' return false immediately diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index a56450a3573..29312a21b4d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -787,6 +787,7 @@ symbols! { impl_lint_pass, impl_trait_in_bindings, impl_trait_in_fn_trait_return, + impl_trait_projections, implied_by, import, import_name_type, @@ -893,6 +894,7 @@ symbols! { masked, match_beginning_vert, match_default_bindings, + matches_macro, maxnumf32, maxnumf64, may_dangle, @@ -1066,6 +1068,7 @@ symbols! { plugins, pointee_trait, pointer, + pointer_sized, poll, position, post_dash_lto: "post-lto", @@ -1405,6 +1408,7 @@ symbols! { str_trim_end, str_trim_start, strict_provenance, + string_deref_patterns, stringify, struct_field_attributes, struct_inherit, diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 46c5fe78ffb..c60a2f4671d 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -244,7 +244,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolPrinter<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { let mut first = true; for p in predicates { diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 6aa031c8378..87128e0f893 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -12,8 +12,8 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir as hir; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{ - self, Binder, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind, - TermKind, Ty, TyCtxt, UintTy, + self, Const, ExistentialPredicate, FloatTy, FnSig, IntTy, List, Region, RegionKind, TermKind, + Ty, TyCtxt, UintTy, }; use rustc_span::def_id::DefId; use rustc_span::symbol::sym; @@ -226,7 +226,7 @@ fn encode_fnsig<'tcx>( /// Rust types that are not used at the FFI boundary. fn encode_predicate<'tcx>( tcx: TyCtxt<'tcx>, - predicate: Binder<'tcx, ExistentialPredicate<'tcx>>, + predicate: ty::PolyExistentialPredicate<'tcx>, dict: &mut FxHashMap<DictKey<'tcx>, usize>, options: EncodeTyOptions, ) -> String { @@ -261,13 +261,13 @@ fn encode_predicate<'tcx>( /// Rust types that are not used at the FFI boundary. fn encode_predicates<'tcx>( tcx: TyCtxt<'tcx>, - predicates: &List<Binder<'tcx, ExistentialPredicate<'tcx>>>, + predicates: &List<ty::PolyExistentialPredicate<'tcx>>, dict: &mut FxHashMap<DictKey<'tcx>, usize>, options: EncodeTyOptions, ) -> String { // <predicate1[..predicateN]>E as part of vendor extended type let mut s = String::new(); - let predicates: Vec<Binder<'tcx, ExistentialPredicate<'tcx>>> = + let predicates: Vec<ty::PolyExistentialPredicate<'tcx>> = predicates.iter().map(|predicate| predicate).collect(); for predicate in predicates { s.push_str(&encode_predicate(tcx, predicate, dict, options)); diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index e540e2f2a21..d1a2aee207d 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -502,7 +502,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { fn print_dyn_existential( mut self, - predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Result<Self::DynExistential, Self::Error> { // Okay, so this is a bit tricky. Imagine we have a trait object like // `dyn for<'a> Foo<'a, Bar = &'a ()>`. When we mangle this, the @@ -689,15 +689,15 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { self.push("V"); self = self.print_def_path(variant_def.def_id, substs)?; - match variant_def.ctor_kind { - CtorKind::Const => { + match variant_def.ctor_kind() { + Some(CtorKind::Const) => { self.push("U"); } - CtorKind::Fn => { + Some(CtorKind::Fn) => { self.push("T"); self = print_field_list(self)?; } - CtorKind::Fictive => { + None => { self.push("S"); for (field_def, field) in iter::zip(&variant_def.fields, fields) { // HACK(eddyb) this mimics `path_append`, diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index c5a6f9893b6..0c559ec04a4 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -3,6 +3,7 @@ use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::{self, HasTargetSpec}; use rustc_span::Symbol; use std::fmt; +use std::str::FromStr; mod aarch64; mod amdgpu; @@ -737,6 +738,33 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } +impl FromStr for Conv { + type Err = String; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "C" => Ok(Conv::C), + "Rust" => Ok(Conv::Rust), + "RustCold" => Ok(Conv::Rust), + "ArmAapcs" => Ok(Conv::ArmAapcs), + "CCmseNonSecureCall" => Ok(Conv::CCmseNonSecureCall), + "Msp430Intr" => Ok(Conv::Msp430Intr), + "PtxKernel" => Ok(Conv::PtxKernel), + "X86Fastcall" => Ok(Conv::X86Fastcall), + "X86Intr" => Ok(Conv::X86Intr), + "X86Stdcall" => Ok(Conv::X86Stdcall), + "X86ThisCall" => Ok(Conv::X86ThisCall), + "X86VectorCall" => Ok(Conv::X86VectorCall), + "X86_64SysV" => Ok(Conv::X86_64SysV), + "X86_64Win64" => Ok(Conv::X86_64Win64), + "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), + "AvrInterrupt" => Ok(Conv::AvrInterrupt), + "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), + _ => Err(format!("'{}' is not a valid value for entry function call convetion.", s)), + } + } +} + // Some types are used a lot. Make sure they don't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { diff --git a/compiler/rustc_target/src/json.rs b/compiler/rustc_target/src/json.rs index b5d92635212..75bb76a9de0 100644 --- a/compiler/rustc_target/src/json.rs +++ b/compiler/rustc_target/src/json.rs @@ -89,3 +89,28 @@ impl<A: ToJson> ToJson for Option<A> { } } } + +impl ToJson for crate::abi::call::Conv { + fn to_json(&self) -> Json { + let s = match self { + Self::C => "C", + Self::Rust => "Rust", + Self::RustCold => "RustCold", + Self::ArmAapcs => "ArmAapcs", + Self::CCmseNonSecureCall => "CCmseNonSecureCall", + Self::Msp430Intr => "Msp430Intr", + Self::PtxKernel => "PtxKernel", + Self::X86Fastcall => "X86Fastcall", + Self::X86Intr => "X86Intr", + Self::X86Stdcall => "X86Stdcall", + Self::X86ThisCall => "X86ThisCall", + Self::X86VectorCall => "X86VectorCall", + Self::X86_64SysV => "X86_64SysV", + Self::X86_64Win64 => "X86_64Win64", + Self::AmdGpuKernel => "AmdGpuKernel", + Self::AvrInterrupt => "AvrInterrupt", + Self::AvrNonBlockingInterrupt => "AvrNonBlockingInterrupt", + }; + Json::String(s.to_owned()) + } +} diff --git a/compiler/rustc_target/src/spec/aix_base.rs b/compiler/rustc_target/src/spec/aix_base.rs new file mode 100644 index 00000000000..c71c4ba2cc9 --- /dev/null +++ b/compiler/rustc_target/src/spec/aix_base.rs @@ -0,0 +1,32 @@ +use crate::abi::Endian; +use crate::spec::{crt_objects, cvs, Cc, CodeModel, LinkOutputKind, LinkerFlavor, TargetOptions}; + +pub fn opts() -> TargetOptions { + TargetOptions { + abi: "vec-extabi".into(), + code_model: Some(CodeModel::Small), + cpu: "pwr7".into(), + os: "aix".into(), + vendor: "ibm".into(), + dynamic_linking: true, + endian: Endian::Big, + executables: true, + archive_format: "aix_big".into(), + families: cvs!["unix"], + has_rpath: false, + has_thread_local: true, + crt_static_respected: true, + linker_flavor: LinkerFlavor::Unix(Cc::No), + linker: Some("ld".into()), + eh_frame_header: false, + is_like_aix: true, + default_dwarf_version: 3, + function_sections: true, + pre_link_objects: crt_objects::new(&[ + (LinkOutputKind::DynamicNoPicExe, &["/usr/lib/crt0_64.o", "/usr/lib/crti_64.o"]), + (LinkOutputKind::DynamicPicExe, &["/usr/lib/crt0_64.o", "/usr/lib/crti_64.o"]), + ]), + dll_suffix: ".a".into(), + ..Default::default() + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 664592b02a1..c633ef1e761 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -34,6 +34,7 @@ //! the target's settings, though `target-feature` and `link-args` will *add* //! to the list specified by the target, rather than replace. +use crate::abi::call::Conv; use crate::abi::Endian; use crate::json::{Json, ToJson}; use crate::spec::abi::{lookup as lookup_abi, Abi}; @@ -57,6 +58,7 @@ use rustc_macros::HashStable_Generic; pub mod abi; pub mod crt_objects; +mod aix_base; mod android_base; mod apple_base; mod avr_gnu_base; @@ -1026,6 +1028,7 @@ supported_targets! { ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), ("powerpc-unknown-linux-musl", powerpc_unknown_linux_musl), + ("powerpc64-ibm-aix", powerpc64_ibm_aix), ("powerpc64-unknown-linux-gnu", powerpc64_unknown_linux_gnu), ("powerpc64-unknown-linux-musl", powerpc64_unknown_linux_musl), ("powerpc64le-unknown-linux-gnu", powerpc64le_unknown_linux_gnu), @@ -1453,6 +1456,9 @@ pub struct TargetOptions { pub families: StaticCow<[StaticCow<str>]>, /// Whether the target toolchain's ABI supports returning small structs as an integer. pub abi_return_struct_as_int: bool, + /// Whether the target toolchain is like AIX's. Linker options on AIX are special and it uses + /// XCOFF as binary format. Defaults to false. + pub is_like_aix: bool, /// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS, /// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false. /// Also indiates whether to use Apple-specific ABI changes, such as extending function @@ -1668,6 +1674,14 @@ pub struct TargetOptions { /// Whether the target supports stack canary checks. `true` by default, /// since this is most common among tier 1 and tier 2 targets. pub supports_stack_protector: bool, + + // The name of entry function. + // Default value is "main" + pub entry_name: StaticCow<str>, + + // The ABI of entry function. + // Default value is `Conv::C`, i.e. C call convention + pub entry_abi: Conv, } /// Add arguments for the given flavor and also for its "twin" flavors @@ -1808,6 +1822,7 @@ impl Default for TargetOptions { staticlib_suffix: ".a".into(), families: cvs![], abi_return_struct_as_int: false, + is_like_aix: false, is_like_osx: false, is_like_solaris: false, is_like_windows: false, @@ -1884,6 +1899,8 @@ impl Default for TargetOptions { c_enum_min_bits: 32, generate_arange_section: true, supports_stack_protector: true, + entry_name: "main".into(), + entry_abi: Conv::C, } } } @@ -2404,6 +2421,18 @@ impl Target { } } } ); + ($key_name:ident, Conv) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + match Conv::from_str(s) { + Ok(c) => { + base.$key_name = c; + Some(Ok(())) + } + Err(e) => Some(Err(e)) + } + })).unwrap_or(Ok(())) + } ); } if let Some(j) = obj.remove("target-endian") { @@ -2465,6 +2494,7 @@ impl Target { key!(staticlib_suffix); key!(families, TargetFamilies); key!(abi_return_struct_as_int, bool); + key!(is_like_aix, bool); key!(is_like_osx, bool); key!(is_like_solaris, bool); key!(is_like_windows, bool); @@ -2523,6 +2553,8 @@ impl Target { key!(c_enum_min_bits, u64); key!(generate_arange_section, bool); key!(supports_stack_protector, bool); + key!(entry_name); + key!(entry_abi, Conv)?; if base.is_builtin { // This can cause unfortunate ICEs later down the line. @@ -2716,6 +2748,7 @@ impl ToJson for Target { target_option_val!(staticlib_suffix); target_option_val!(families, "target-family"); target_option_val!(abi_return_struct_as_int); + target_option_val!(is_like_aix); target_option_val!(is_like_osx); target_option_val!(is_like_solaris); target_option_val!(is_like_windows); @@ -2773,6 +2806,8 @@ impl ToJson for Target { target_option_val!(c_enum_min_bits); target_option_val!(generate_arange_section); target_option_val!(supports_stack_protector); + target_option_val!(entry_name); + target_option_val!(entry_abi); if let Some(abi) = self.default_adjusted_cabi { d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json()); diff --git a/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs new file mode 100644 index 00000000000..e3eb9bccd5e --- /dev/null +++ b/compiler/rustc_target/src/spec/powerpc64_ibm_aix.rs @@ -0,0 +1,23 @@ +use crate::spec::{Cc, LinkerFlavor, Target}; + +pub fn target() -> Target { + let mut base = super::aix_base::opts(); + base.max_atomic_width = Some(64); + base.add_pre_link_args( + LinkerFlavor::Unix(Cc::No), + &[ + "-b64".into(), + "-bpT:0x100000000".into(), + "-bpD:0x110000000".into(), + "-bcdtors:all:0:s".into(), + ], + ); + + Target { + llvm_target: "powerpc64-ibm-aix".into(), + pointer_width: 64, + data_layout: "E-m:a-i64:64-n32:64-S128-v256:256:256-v512:512:512".into(), + arch: "powerpc64".into(), + options: base, + } +} diff --git a/compiler/rustc_trait_selection/src/autoderef.rs b/compiler/rustc_trait_selection/src/autoderef.rs index 54c738d8389..9b39a940114 100644 --- a/compiler/rustc_trait_selection/src/autoderef.rs +++ b/compiler/rustc_trait_selection/src/autoderef.rs @@ -3,8 +3,8 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, TraitEngine, TraitEngineExt}; use rustc_hir as hir; use rustc_infer::infer::InferCtxt; -use rustc_middle::ty::{self, TraitRef, Ty, TyCtxt}; -use rustc_middle::ty::{ToPredicate, TypeVisitable}; +use rustc_middle::ty::TypeVisitable; +use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::Limit; use rustc_span::def_id::LOCAL_CRATE; use rustc_span::Span; @@ -122,17 +122,15 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> { let tcx = self.infcx.tcx; // <ty as Deref> - let trait_ref = TraitRef { - def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]); let cause = traits::ObligationCause::misc(self.span, self.body_id); let obligation = traits::Obligation::new( + tcx, cause.clone(), self.param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + ty::Binder::dummy(trait_ref).without_const(), ); if !self.infcx.predicate_may_hold(&obligation) { debug!("overloaded_deref_ty: cannot match obligation"); diff --git a/compiler/rustc_trait_selection/src/infer.rs b/compiler/rustc_trait_selection/src/infer.rs index 0f2e22604dc..25a9c29caa7 100644 --- a/compiler/rustc_trait_selection/src/infer.rs +++ b/compiler/rustc_trait_selection/src/infer.rs @@ -7,9 +7,8 @@ use rustc_infer::traits::ObligationCause; use rustc_middle::arena::ArenaAllocatable; use rustc_middle::infer::canonical::{Canonical, CanonicalizedQueryResponse, QueryResponse}; use rustc_middle::traits::query::Fallible; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitable}; +use rustc_middle::ty::{GenericArg, ToPredicate}; use rustc_span::{Span, DUMMY_SP}; use std::fmt::Debug; @@ -44,8 +43,7 @@ pub trait InferCtxtExt<'tcx> { /// The inputs are: /// /// - the def-id of the trait - /// - the self type - /// - the *other* type parameters of the trait, excluding the self-type + /// - the type parameters of the trait, including the self-type /// - the parameter environment /// /// Invokes `evaluate_obligation`, so in the event that evaluating @@ -54,8 +52,7 @@ pub trait InferCtxtExt<'tcx> { fn type_implements_trait( &self, trait_def_id: DefId, - ty: Ty<'tcx>, - params: SubstsRef<'tcx>, + params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult; } @@ -109,16 +106,14 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { InferOk { value, obligations } } - #[instrument(level = "debug", skip(self), ret)] + #[instrument(level = "debug", skip(self, params), ret)] fn type_implements_trait( &self, trait_def_id: DefId, - ty: Ty<'tcx>, - params: SubstsRef<'tcx>, + params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, param_env: ty::ParamEnv<'tcx>, ) -> traits::EvaluationResult { - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: self.tcx.mk_substs_trait(ty, params) }; + let trait_ref = self.tcx.mk_trait_ref(trait_def_id, params); let obligation = traits::Obligation { cause: traits::ObligationCause::dummy(), diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs index 2dce18e2d3c..975ff31a607 100644 --- a/compiler/rustc_trait_selection/src/lib.rs +++ b/compiler/rustc_trait_selection/src/lib.rs @@ -11,6 +11,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] +#![feature(associated_type_bounds)] #![feature(box_patterns)] #![feature(control_flow_enum)] #![feature(drain_filter)] diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 188f8bb7e2a..78af187cd8f 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -86,7 +86,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { ) -> AutoTraitResult<A> { let tcx = self.tcx; - let trait_ref = ty::TraitRef { def_id: trait_did, substs: tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = tcx.mk_trait_ref(trait_did, [ty]); let trait_pred = ty::Binder::dummy(trait_ref); @@ -96,8 +96,12 @@ impl<'tcx> AutoTraitFinder<'tcx> { PolyTraitRef::to_poly_trait_predicate, PolyTraitRef::to_poly_trait_predicate_negative_polarity, ] { - let result = - selcx.select(&Obligation::new(ObligationCause::dummy(), orig_env, f(&trait_pred))); + let result = selcx.select(&Obligation::new( + tcx, + ObligationCause::dummy(), + orig_env, + f(&trait_pred), + )); if let Ok(Some(ImplSource::UserDefined(_))) = result { debug!( "find_auto_trait_generics({:?}): \ @@ -256,10 +260,8 @@ impl<'tcx> AutoTraitFinder<'tcx> { let mut already_visited = FxHashSet::default(); let mut predicates = VecDeque::new(); predicates.push_back(ty::Binder::dummy(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: trait_did, - substs: infcx.tcx.mk_substs_trait(ty, &[]), - }, + trait_ref: infcx.tcx.mk_trait_ref(trait_did, [ty]), + constness: ty::BoundConstness::NotConst, // Auto traits are positive polarity: ty::ImplPolarity::Positive, @@ -280,8 +282,12 @@ impl<'tcx> AutoTraitFinder<'tcx> { // Call `infcx.resolve_vars_if_possible` to see if we can // get rid of any inference variables. - let obligation = - infcx.resolve_vars_if_possible(Obligation::new(dummy_cause.clone(), new_env, pred)); + let obligation = infcx.resolve_vars_if_possible(Obligation::new( + tcx, + dummy_cause.clone(), + new_env, + pred, + )); let result = select.select(&obligation); match result { @@ -706,7 +712,10 @@ impl<'tcx> AutoTraitFinder<'tcx> { // and turn them into an explicit negative impl for our type. debug!("Projecting and unifying projection predicate {:?}", predicate); - match project::poly_project_and_unify_type(select, &obligation.with(p)) { + match project::poly_project_and_unify_type( + select, + &obligation.with(self.tcx, p), + ) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { debug!( "evaluate_nested_obligations: Unable to unify predicate \ @@ -832,6 +841,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => {} + ty::PredicateKind::Ambiguous => return false, }; } true diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 8a62bf01567..ca4299f7db3 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -40,7 +40,7 @@ pub fn codegen_select_candidate<'tcx>( let obligation_cause = ObligationCause::dummy(); let obligation = - Obligation::new(obligation_cause, param_env, trait_ref.to_poly_trait_predicate()); + Obligation::new(tcx, obligation_cause, param_env, trait_ref.to_poly_trait_predicate()); let selection = match selcx.select(&obligation) { Ok(Some(selection)) => selection, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 3cf2959a9ff..741bf206d03 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -18,7 +18,7 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::CRATE_HIR_ID; -use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; +use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::util; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; @@ -94,8 +94,9 @@ pub fn overlapping_impls<'tcx>( return None; } - let infcx = tcx.infer_ctxt().build(); - let selcx = &mut SelectionContext::intercrate(&infcx); + let infcx = + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let selcx = &mut SelectionContext::new(&infcx); let overlaps = overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some(); if !overlaps { @@ -105,8 +106,9 @@ pub fn overlapping_impls<'tcx>( // In the case where we detect an error, run the check again, but // this time tracking intercrate ambiguity causes for better // diagnostics. (These take time and can lead to false errors.) - let infcx = tcx.infer_ctxt().build(); - let selcx = &mut SelectionContext::intercrate(&infcx); + let infcx = + tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).intercrate().build(); + let selcx = &mut SelectionContext::new(&infcx); selcx.enable_tracking_intercrate_ambiguity_causes(); Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap()) } @@ -162,8 +164,8 @@ fn overlap_within_probe<'cx, 'tcx>( let infcx = selcx.infcx(); if overlap_mode.use_negative_impl() { - if negative_impl(selcx, impl1_def_id, impl2_def_id) - || negative_impl(selcx, impl2_def_id, impl1_def_id) + if negative_impl(infcx.tcx, impl1_def_id, impl2_def_id) + || negative_impl(infcx.tcx, impl2_def_id, impl1_def_id) { return None; } @@ -279,13 +281,8 @@ fn implicit_negative<'cx, 'tcx>( /// Given impl1 and impl2 check if both impls are never satisfied by a common type (including /// where-clauses) If so, return true, they are disjoint and false otherwise. -fn negative_impl<'cx, 'tcx>( - selcx: &mut SelectionContext<'cx, 'tcx>, - impl1_def_id: DefId, - impl2_def_id: DefId, -) -> bool { +fn negative_impl<'tcx>(tcx: TyCtxt<'tcx>, impl1_def_id: DefId, impl2_def_id: DefId) -> bool { debug!("negative_impl(impl1_def_id={:?}, impl2_def_id={:?})", impl1_def_id, impl2_def_id); - let tcx = selcx.infcx().tcx; // Create an infcx, taking the predicates of impl1 as assumptions: let infcx = tcx.infer_ctxt().build(); @@ -332,11 +329,10 @@ fn equate<'tcx>( return true; }; - let selcx = &mut SelectionContext::new(&infcx); let opt_failing_obligation = obligations .into_iter() .chain(more_obligations) - .find(|o| negative_impl_exists(selcx, o, body_def_id)); + .find(|o| negative_impl_exists(infcx, o, body_def_id)); if let Some(failing_obligation) = opt_failing_obligation { debug!("overlap: obligation unsatisfiable {:?}", failing_obligation); @@ -347,19 +343,19 @@ fn equate<'tcx>( } /// Try to prove that a negative impl exist for the given obligation and its super predicates. -#[instrument(level = "debug", skip(selcx))] -fn negative_impl_exists<'cx, 'tcx>( - selcx: &SelectionContext<'cx, 'tcx>, +#[instrument(level = "debug", skip(infcx))] +fn negative_impl_exists<'tcx>( + infcx: &InferCtxt<'tcx>, o: &PredicateObligation<'tcx>, body_def_id: DefId, ) -> bool { - if resolve_negative_obligation(selcx.infcx().fork(), o, body_def_id) { + if resolve_negative_obligation(infcx.fork(), o, body_def_id) { return true; } // Try to prove a negative obligation exists for super predicates - for o in util::elaborate_predicates(selcx.tcx(), iter::once(o.predicate)) { - if resolve_negative_obligation(selcx.infcx().fork(), &o, body_def_id) { + for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { + if resolve_negative_obligation(infcx.fork(), &o, body_def_id) { return true; } } diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index ae29c9f5617..3a05708aebc 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -93,7 +93,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { def_id: DefId, ) { let tcx = self.infcx.tcx; - let trait_ref = ty::TraitRef { def_id, substs: tcx.mk_substs_trait(ty, &[]) }; + let trait_ref = tcx.mk_trait_ref(def_id, [ty]); self.register_obligation(Obligation { cause, recursion_depth: 0, @@ -125,6 +125,21 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } + /// Checks whether `expected` is a subtype of `actual`: `expected <: actual`. + pub fn sub<T: ToTrace<'tcx>>( + &self, + cause: &ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + expected: T, + actual: T, + ) -> Result<(), TypeError<'tcx>> { + self.infcx + .at(cause, param_env) + .sup(expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) + } + + /// Checks whether `expected` is a supertype of `actual`: `expected :> actual`. pub fn sup<T: ToTrace<'tcx>>( &self, cause: &ObligationCause<'tcx>, @@ -132,13 +147,10 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> { expected: T, actual: T, ) -> Result<(), TypeError<'tcx>> { - match self.infcx.at(cause, param_env).sup(expected, actual) { - Ok(InferOk { obligations, value: () }) => { - self.register_obligations(obligations); - Ok(()) - } - Err(e) => Err(e), - } + self.infcx + .at(cause, param_env) + .sup(expected, actual) + .map(|infer_ok| self.register_infer_ok_obligations(infer_ok)) } pub fn select_where_possible(&self) -> Vec<FulfillmentError<'tcx>> { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index 58da54afb75..6a5744f5f76 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -32,7 +32,7 @@ pub fn recompute_applicable_impls<'tcx>( impl_predicates .predicates .iter() - .map(|&predicate| Obligation::new(dummy_cause.clone(), param_env, predicate)), + .map(|&predicate| Obligation::new(tcx, dummy_cause.clone(), param_env, predicate)), ); ocx.select_where_possible().is_empty() diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 786cadaa6ce..ef3d300020a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -22,6 +22,7 @@ use rustc_errors::{ MultiSpan, Style, }; use rustc_hir as hir; +use rustc_hir::def::Namespace; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::GenericParam; @@ -34,6 +35,7 @@ use rustc_middle::traits::select::OverflowError; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::ExpectedFound; use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::{ self, SubtypePredicate, ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeFoldable, TypeVisitable, @@ -109,7 +111,10 @@ pub trait TypeErrCtxtExt<'tcx> { suggest_increasing_limit: bool, ) -> ! where - T: fmt::Display + TypeFoldable<'tcx>; + T: fmt::Display + + TypeFoldable<'tcx> + + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, + <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug; fn suggest_new_overflow_limit(&self, err: &mut Diagnostic); @@ -342,16 +347,12 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { span: DUMMY_SP, kind: TypeVariableOriginKind::MiscVariable, }); - let substs = self.tcx.mk_substs_trait(ty.skip_binder(), &[var.into()]); + let trait_ref = self.tcx.mk_trait_ref(trait_def_id, [ty.skip_binder(), var]); let obligation = Obligation::new( + self.tcx, ObligationCause::dummy(), param_env, - ty.rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef::new(trait_def_id, substs), - constness, - polarity, - }) - .to_predicate(self.tcx), + ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }), ); let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new_in_snapshot(self.tcx); fulfill_cx.register_predicate_obligation(self, obligation); @@ -468,15 +469,31 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { suggest_increasing_limit: bool, ) -> ! where - T: fmt::Display + TypeFoldable<'tcx>, + T: fmt::Display + + TypeFoldable<'tcx> + + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, + <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug, { let predicate = self.resolve_vars_if_possible(obligation.predicate.clone()); + let mut pred_str = predicate.to_string(); + if pred_str.len() > 50 { + // We don't need to save the type to a file, we will be talking about this type already + // in a separate note when we explain the obligation, so it will be available that way. + pred_str = predicate + .print(FmtPrinter::new_with_limit( + self.tcx, + Namespace::TypeNS, + rustc_session::Limit(6), + )) + .unwrap() + .into_buffer(); + } let mut err = struct_span_err!( self.tcx.sess, obligation.cause.span, E0275, "overflow evaluating the requirement `{}`", - predicate + pred_str, ); if suggest_increasing_limit { @@ -532,9 +549,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { root_obligation: &PredicateObligation<'tcx>, error: &SelectionError<'tcx>, ) { - self.set_tainted_by_errors(); let tcx = self.tcx; let mut span = obligation.cause.span; + // FIXME: statically guarantee this by tainting after the diagnostic is emitted + self.set_tainted_by_errors( + tcx.sess.delay_span_bug(span, "`report_selection_error` did not emit an error"), + ); let mut err = match *error { SelectionError::Unimplemented => { @@ -977,14 +997,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if trait_predicate.skip_binder().self_ty().is_never() && self.fallback_has_occurred { - let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( - self.tcx.mk_unit(), - &trait_pred.trait_ref.substs[1..], - ); - trait_pred + let predicate = trait_predicate.map_bound(|trait_pred| { + trait_pred.with_self_type(self.tcx, self.tcx.mk_unit()) }); - let unit_obligation = obligation.with(predicate.to_predicate(tcx)); + let unit_obligation = obligation.with(tcx, predicate); if self.predicate_may_hold(&unit_obligation) { err.note( "this error might have been caused by changes to \ @@ -1152,6 +1168,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) } + ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"), + ty::PredicateKind::TypeWellFormedFromEnv(..) => span_bug!( span, "TypeWellFormedFromEnv predicate should only exist in the environment" @@ -1705,7 +1723,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::Bool => Some(0), ty::Char => Some(1), ty::Str => Some(2), - ty::Adt(def, _) if tcx.is_diagnostic_item(sym::String, def.did()) => Some(2), + ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2), ty::Int(..) | ty::Uint(..) | ty::Float(..) @@ -2004,15 +2022,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { param_env: ty::ParamEnv<'tcx>, trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>, ) -> PredicateObligation<'tcx> { - let trait_pred = trait_ref_and_ty.map_bound_ref(|(tr, new_self_ty)| ty::TraitPredicate { - trait_ref: ty::TraitRef { - substs: self.tcx.mk_substs_trait(*new_self_ty, &tr.trait_ref.substs[1..]), - ..tr.trait_ref - }, - ..*tr - }); + let trait_pred = trait_ref_and_ty + .map_bound(|(tr, new_self_ty)| tr.with_self_type(self.tcx, new_self_ty)); - Obligation::new(ObligationCause::dummy(), param_env, trait_pred.to_predicate(self.tcx)) + Obligation::new(self.tcx, ObligationCause::dummy(), param_env, trait_pred) } #[instrument(skip(self), level = "debug")] @@ -2060,7 +2073,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // check upstream for type errors and don't add the obligations to // begin with in those cases. if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) { - if !self.is_tainted_by_errors() { + if let None = self.tainted_by_errors() { self.emit_inference_failure_err( body_id, span, @@ -2100,11 +2113,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) }; - let obligation = Obligation::new( - obligation.cause.clone(), - obligation.param_env, - trait_ref.to_poly_trait_predicate(), - ); + let obligation = obligation.with(self.tcx, trait_ref.to_poly_trait_predicate()); let mut selcx = SelectionContext::with_query_mode( &self, crate::traits::TraitQueryMode::Standard, @@ -2119,16 +2128,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if impls.len() > 1 && impls.len() < 5 && has_non_region_infer { self.annotate_source_of_ambiguity(&mut err, &impls, predicate); } else { - if self.is_tainted_by_errors() { - err.delay_as_bug(); + if self.tainted_by_errors().is_some() { + err.cancel(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); } } _ => { - if self.is_tainted_by_errors() { - err.delay_as_bug(); + if self.tainted_by_errors().is_some() { + err.cancel(); return; } err.note(&format!("cannot satisfy `{}`", predicate)); @@ -2230,7 +2239,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ] = path.segments && data.trait_ref.def_id == *trait_id && self.tcx.trait_of_item(*item_id) == Some(*trait_id) - && !self.is_tainted_by_errors() + && let None = self.tainted_by_errors() { let (verb, noun) = match self.tcx.associated_item(item_id).kind { ty::AssocKind::Const => ("refer to the", "constant"), @@ -2299,7 +2308,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // with error messages. if arg.references_error() || self.tcx.sess.has_errors().is_some() - || self.is_tainted_by_errors() + || self.tainted_by_errors().is_some() { return; } @@ -2310,7 +2319,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Subtype(data) => { if data.references_error() || self.tcx.sess.has_errors().is_some() - || self.is_tainted_by_errors() + || self.tainted_by_errors().is_some() { // no need to overload user in such cases return; @@ -2321,7 +2330,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true) } ty::PredicateKind::Projection(data) => { - if predicate.references_error() || self.is_tainted_by_errors() { + if predicate.references_error() || self.tainted_by_errors().is_some() { return; } let subst = data @@ -2355,7 +2364,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ty::PredicateKind::ConstEvaluatable(data) => { - if predicate.references_error() || self.is_tainted_by_errors() { + if predicate.references_error() || self.tainted_by_errors().is_some() { return; } let subst = data.walk().find(|g| g.is_non_region_infer()); @@ -2382,7 +2391,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } } _ => { - if self.tcx.sess.has_errors().is_some() || self.is_tainted_by_errors() { + if self.tcx.sess.has_errors().is_some() || self.tainted_by_errors().is_some() { return; } let mut err = struct_span_err!( @@ -2426,7 +2435,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { post.sort(); post.dedup(); - if self.is_tainted_by_errors() + if self.tainted_by_errors().is_some() && (crate_names.len() == 1 && spans.len() == 0 && ["`core`", "`alloc`", "`std`"].contains(&crate_names[0].as_str()) @@ -2534,11 +2543,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ) .value; - let obligation = Obligation::new( - ObligationCause::dummy(), - param_env, - cleaned_pred.to_predicate(selcx.tcx()), - ); + let obligation = + Obligation::new(self.tcx, ObligationCause::dummy(), param_env, cleaned_pred); self.predicate_may_hold(&obligation) }) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 84daaf97ecf..186109e7075 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -301,7 +301,7 @@ pub trait TypeErrCtxtExt<'tcx> { obligated_types: &mut Vec<Ty<'tcx>>, seen_requirements: &mut FxHashSet<DefId>, ) where - T: fmt::Display; + T: fmt::Display + ToPredicate<'tcx, T>; /// Suggest to await before try: future? => future.await? fn suggest_await_before_try( @@ -334,7 +334,7 @@ pub trait TypeErrCtxtExt<'tcx> { ); } -fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) { +fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) { ( generics.tail_span_for_predicate_suggestion(), format!("{} {}", generics.add_where_or_trailing_comma(), pred), @@ -416,7 +416,7 @@ fn suggest_restriction<'tcx>( }, // `fn foo(t: impl Trait)` // ^ suggest `where <T as Trait>::A: Bound` - predicate_constraint(hir_generics, trait_pred.to_predicate(tcx).to_string()), + predicate_constraint(hir_generics, trait_pred.to_predicate(tcx)), ]; sugg.extend(ty_spans.into_iter().map(|s| (s, type_param_name.to_string()))); @@ -440,9 +440,7 @@ fn suggest_restriction<'tcx>( .find(|p| !matches!(p.kind, hir::GenericParamKind::Type { synthetic: true, .. })), super_traits, ) { - (_, None) => { - predicate_constraint(hir_generics, trait_pred.to_predicate(tcx).to_string()) - } + (_, None) => predicate_constraint(hir_generics, trait_pred.to_predicate(tcx)), (None, Some((ident, []))) => ( ident.span.shrink_to_hi(), format!(": {}", trait_pred.print_modifiers_and_trait_path()), @@ -1162,7 +1160,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { for predicate in predicates.iter() { if !self.predicate_must_hold_modulo_regions( - &obligation.with(predicate.with_self_ty(self.tcx, self_ref_ty)), + &obligation.with(self.tcx, predicate.with_self_ty(self.tcx, self_ref_ty)), ) { return; } @@ -1523,7 +1521,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let self_ty_satisfies_dyn_predicates = |self_ty| { predicates.iter().all(|predicate| { let pred = predicate.with_self_ty(self.tcx, self_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); + let obl = Obligation::new(self.tcx, cause.clone(), param_env, pred); self.predicate_may_hold(&obl) }) }; @@ -2627,7 +2625,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } }; - let from_generator = tcx.lang_items().from_generator_fn().unwrap(); + let from_generator = tcx.require_lang_item(LangItem::FromGenerator, None); // Don't print the tuple of capture types 'print: { @@ -2704,7 +2702,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { obligated_types.push(ty); - let parent_predicate = parent_trait_ref.to_predicate(tcx); + let parent_predicate = parent_trait_ref; if !self.is_recursive_obligation(obligated_types, &data.parent_code) { // #74711: avoid a stack overflow ensure_sufficient_stack(|| { @@ -2735,9 +2733,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.resolve_vars_if_possible(data.derived.parent_trait_pred); parent_trait_pred.remap_constness_diag(param_env); let parent_def_id = parent_trait_pred.def_id(); + let (self_ty, file) = + self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); let msg = format!( - "required for `{}` to implement `{}`", - parent_trait_pred.skip_binder().self_ty(), + "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() ); let mut is_auto_trait = false; @@ -2766,7 +2765,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { _ => err.note(&msg), }; - let mut parent_predicate = parent_trait_pred.to_predicate(tcx); + if let Some(file) = file { + err.note(&format!( + "the full type name has been written to '{}'", + file.display(), + )); + } + let mut parent_predicate = parent_trait_pred; let mut data = &data.derived; let mut count = 0; seen_requirements.insert(parent_def_id); @@ -2806,11 +2811,18 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { count, pluralize!(count) )); + let (self_ty, file) = + self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty()); err.note(&format!( - "required for `{}` to implement `{}`", - parent_trait_pred.skip_binder().self_ty(), + "required for `{self_ty}` to implement `{}`", parent_trait_pred.print_modifiers_and_trait_path() )); + if let Some(file) = file { + err.note(&format!( + "the full type name has been written to '{}'", + file.display(), + )); + } } // #74711: avoid a stack overflow ensure_sufficient_stack(|| { @@ -2826,7 +2838,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } ObligationCauseCode::DerivedObligation(ref data) => { let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred); - let parent_predicate = parent_trait_ref.to_predicate(tcx); + let parent_predicate = parent_trait_ref; // #74711: avoid a stack overflow ensure_sufficient_stack(|| { self.note_obligation_cause_code( @@ -2959,8 +2971,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let impls_future = self.type_implements_trait( future_trait, - self.tcx.erase_late_bound_regions(self_ty), - ty::List::empty(), + [self.tcx.erase_late_bound_regions(self_ty)], obligation.param_env, ); if !impls_future.must_apply_modulo_regions() { @@ -2973,7 +2984,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { self.tcx.mk_projection( item_def_id, // Future::Output has no substs - self.tcx.mk_substs_trait(trait_pred.self_ty(), &[]), + self.tcx.mk_substs_trait(trait_pred.self_ty(), []), ) }); let projection_ty = normalize_to( @@ -3058,21 +3069,22 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { let field_ty = field.ty(self.tcx, substs); let trait_substs = match diagnostic_name { sym::PartialEq | sym::PartialOrd => { - self.tcx.mk_substs_trait(field_ty, &[field_ty.into()]) + Some(field_ty) } - _ => self.tcx.mk_substs_trait(field_ty, &[]), + _ => None, }; let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate { - trait_ref: ty::TraitRef { - substs: trait_substs, - ..trait_pred.skip_binder().trait_ref - }, + trait_ref: self.tcx.mk_trait_ref( + trait_pred.def_id(), + [field_ty].into_iter().chain(trait_substs), + ), ..*tr }); let field_obl = Obligation::new( + self.tcx, obligation.cause.clone(), obligation.param_env, - trait_pred.to_predicate(self.tcx), + trait_pred, ); self.predicate_must_hold_modulo_regions(&field_obl) }) diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 4905bb69cc5..d238e7556ae 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -9,7 +9,6 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::error::{ExpectedFound, TypeError}; use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::ToPredicate; use rustc_middle::ty::{self, Binder, Const, Ty, TypeVisitable}; use std::marker::PhantomData; @@ -296,7 +295,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { &mut obligations, ); if predicate != obligation.predicate { - obligations.push(obligation.with(predicate)); + obligations.push(obligation.with(infcx.tcx, predicate)); return ProcessResult::Changed(mk_pending(obligations)); } } @@ -307,7 +306,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { // This means we need to pass it the bound version of our // predicate. ty::PredicateKind::Trait(trait_ref) => { - let trait_obligation = obligation.with(binder.rebind(trait_ref)); + let trait_obligation = obligation.with(infcx.tcx, binder.rebind(trait_ref)); self.process_trait_obligation( obligation, @@ -316,7 +315,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ) } ty::PredicateKind::Projection(data) => { - let project_obligation = obligation.with(binder.rebind(data)); + let project_obligation = obligation.with(infcx.tcx, binder.rebind(data)); self.process_projection_obligation( obligation, @@ -335,17 +334,16 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { | ty::PredicateKind::ConstEquate(..) => { let pred = ty::Binder::dummy(infcx.replace_bound_vars_with_placeholders(binder)); - ProcessResult::Changed(mk_pending(vec![ - obligation.with(pred.to_predicate(self.selcx.tcx())), - ])) + ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) } + ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } }, Some(pred) => match pred { ty::PredicateKind::Trait(data) => { - let trait_obligation = obligation.with(Binder::dummy(data)); + let trait_obligation = obligation.with(infcx.tcx, Binder::dummy(data)); self.process_trait_obligation( obligation, @@ -370,7 +368,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } ty::PredicateKind::Projection(ref data) => { - let project_obligation = obligation.with(Binder::dummy(*data)); + let project_obligation = obligation.with(infcx.tcx, Binder::dummy(*data)); self.process_projection_obligation( obligation, @@ -572,6 +570,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } } + ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } @@ -697,7 +696,7 @@ impl<'a, 'tcx> FulfillProcessor<'a, 'tcx> { } // Let the caller handle the recursion ProjectAndUnifyResult::Recursive => ProcessResult::Changed(mk_pending(vec![ - project_obligation.with(project_obligation.predicate.to_predicate(tcx)), + project_obligation.with(tcx, project_obligation.predicate), ])), ProjectAndUnifyResult::MismatchedProjectionTypes(e) => { ProcessResult::Error(CodeProjectionError(e)) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 10e48610e3a..ff18aa1f9e9 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -136,7 +136,6 @@ pub fn predicates_for_generics<'tcx>( /// `bound` or is not known to meet bound (note that this is /// conservative towards *no impl*, which is the opposite of the /// `evaluate` methods). -#[instrument(level = "debug", skip(infcx, param_env, span), ret)] pub fn type_known_to_meet_bound_modulo_regions<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, @@ -144,33 +143,42 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>( def_id: DefId, span: Span, ) -> bool { - let trait_ref = - ty::Binder::dummy(ty::TraitRef { def_id, substs: infcx.tcx.mk_substs_trait(ty, &[]) }); + let trait_ref = ty::Binder::dummy(infcx.tcx.mk_trait_ref(def_id, [ty])); + pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const(), span) +} + +#[instrument(level = "debug", skip(infcx, param_env, span, pred), ret)] +fn pred_known_to_hold_modulo_regions<'tcx>( + infcx: &InferCtxt<'tcx>, + param_env: ty::ParamEnv<'tcx>, + pred: impl ToPredicate<'tcx, ty::Predicate<'tcx>> + TypeVisitable<'tcx>, + span: Span, +) -> bool { + let has_non_region_infer = pred.has_non_region_infer(); let obligation = Obligation { param_env, + // We can use a dummy node-id here because we won't pay any mind + // to region obligations that arise (there shouldn't really be any + // anyhow). cause: ObligationCause::misc(span, hir::CRATE_HIR_ID), recursion_depth: 0, - predicate: trait_ref.without_const().to_predicate(infcx.tcx), + predicate: pred.to_predicate(infcx.tcx), }; let result = infcx.predicate_must_hold_modulo_regions(&obligation); debug!(?result); - if result && ty.has_non_region_infer() { + if result && has_non_region_infer { // Because of inference "guessing", selection can sometimes claim // to succeed while the success requires a guess. To ensure // this function's result remains infallible, we must confirm // that guess. While imperfect, I believe this is sound. - // We can use a dummy node-id here because we won't pay any mind - // to region obligations that arise (there shouldn't really be any - // anyhow). - let cause = ObligationCause::misc(span, hir::CRATE_HIR_ID); - + // FIXME(@lcnr): this function doesn't seem right. // The handling of regions in this area of the code is terrible, // see issue #29149. We should be able to improve on this with // NLL. - let errors = fully_solve_bound(infcx, cause, param_env, ty, def_id); + let errors = fully_solve_obligation(infcx, obligation); // Note: we only assume something is `Copy` if we can // *definitively* show that it implements `Copy`. Otherwise, @@ -440,7 +448,7 @@ pub fn impossible_predicates<'tcx>( let ocx = ObligationCtxt::new(&infcx); let predicates = ocx.normalize(ObligationCause::dummy(), param_env, predicates); for predicate in predicates { - let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate); + let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate); ocx.register_obligation(obligation); } let errors = ocx.select_all_or_error(); @@ -530,6 +538,7 @@ fn is_impossible_method<'tcx>( let predicates_for_trait = predicates.predicates.iter().filter_map(|(pred, span)| { if pred.visit_with(&mut visitor).is_continue() { Some(Obligation::new( + tcx, ObligationCause::dummy_with_span(*span), param_env, ty::EarlyBinder(*pred).subst(tcx, impl_trait_ref.substs), @@ -894,10 +903,7 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>( // this has been typecked-before, so diagnostics is not really needed. let unsize_trait_did = tcx.require_lang_item(LangItem::Unsize, None); - let trait_ref = ty::TraitRef { - def_id: unsize_trait_did, - substs: tcx.mk_substs_trait(source, &[target.into()]), - }; + let trait_ref = tcx.mk_trait_ref(unsize_trait_did, [source, target]); match tcx.codegen_select_candidate((ty::ParamEnv::reveal_all(), ty::Binder::dummy(trait_ref))) { Ok(ImplSource::TraitUpcasting(implsrc_traitcasting)) => { diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 0bb25a74dc8..7c4c58ba361 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -319,6 +319,7 @@ fn predicate_references_self<'tcx>( | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, } } @@ -350,6 +351,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::PredicateKind::TypeOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, } }) @@ -375,6 +377,7 @@ fn object_safety_violation_for_method( let span = match (&v, node) { (MethodViolationCode::ReferencesSelfInput(Some(span)), _) => *span, (MethodViolationCode::UndispatchableReceiver(Some(span)), _) => *span, + (MethodViolationCode::ReferencesImplTraitInTrait(span), _) => *span, (MethodViolationCode::ReferencesSelfOutput, Some(node)) => { node.fn_decl().map_or(method.ident(tcx).span, |decl| decl.output.span()) } @@ -437,8 +440,8 @@ fn virtual_call_violation_for_method<'tcx>( if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) { return Some(MethodViolationCode::ReferencesSelfOutput); } - if contains_illegal_impl_trait_in_trait(tcx, sig.output()) { - return Some(MethodViolationCode::ReferencesImplTraitInTrait); + if let Some(code) = contains_illegal_impl_trait_in_trait(tcx, method.def_id, sig.output()) { + return Some(code); } // We can't monomorphize things like `fn foo<A>(...)`. @@ -684,10 +687,9 @@ fn receiver_is_dispatchable<'tcx>( let param_env = tcx.param_env(method.def_id); // Self: Unsize<U> - let unsize_predicate = ty::Binder::dummy(ty::TraitRef { - def_id: unsize_did, - substs: tcx.mk_substs_trait(tcx.types.self_param, &[unsized_self_ty.into()]), - }) + let unsize_predicate = ty::Binder::dummy( + tcx.mk_trait_ref(unsize_did, [tcx.types.self_param, unsized_self_ty]), + ) .without_const() .to_predicate(tcx); @@ -719,14 +721,12 @@ fn receiver_is_dispatchable<'tcx>( // Receiver: DispatchFromDyn<Receiver[Self => U]> let obligation = { - let predicate = ty::Binder::dummy(ty::TraitRef { - def_id: dispatch_from_dyn_did, - substs: tcx.mk_substs_trait(receiver_ty, &[unsized_receiver_ty.into()]), - }) - .without_const() - .to_predicate(tcx); + let predicate = ty::Binder::dummy( + tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]), + ) + .without_const(); - Obligation::new(ObligationCause::dummy(), param_env, predicate) + Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate) }; let infcx = tcx.infer_ctxt().build(); @@ -865,16 +865,24 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>( pub fn contains_illegal_impl_trait_in_trait<'tcx>( tcx: TyCtxt<'tcx>, + fn_def_id: DefId, ty: ty::Binder<'tcx, Ty<'tcx>>, -) -> bool { +) -> Option<MethodViolationCode> { + // This would be caught below, but rendering the error as a separate + // `async-specific` message is better. + if tcx.asyncness(fn_def_id).is_async() { + return Some(MethodViolationCode::AsyncFn); + } + // FIXME(RPITIT): Perhaps we should use a visitor here? - ty.skip_binder().walk().any(|arg| { + ty.skip_binder().walk().find_map(|arg| { if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Projection(proj) = ty.kind() + && tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder { - tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder + Some(MethodViolationCode::ReferencesImplTraitInTrait(tcx.def_span(proj.item_def_id))) } else { - false + None } }) } diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 572f82117cc..9f19b0092c0 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -200,7 +200,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>( infcx.replace_bound_vars_with_placeholders(obligation.predicate); let new_universe = infcx.universe(); - let placeholder_obligation = obligation.with(placeholder_predicate); + let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate); match project_and_unify_type(selcx, &placeholder_obligation) { ProjectAndUnifyResult::MismatchedProjectionTypes(e) => Err(e), ProjectAndUnifyResult::Holds(obligations) @@ -508,7 +508,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // This is really important. While we *can* handle this, this has // severe performance implications for large opaque types with // late-bound regions. See `issue-88862` benchmark. - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty.super_fold_with(self), @@ -517,6 +517,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { let obligation = Obligation::with_depth( + self.tcx(), self.cause.clone(), recursion_limit.0, self.param_env, @@ -573,6 +574,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { && !self.tcx().sess.opts.actually_rustdoc { let obligation = Obligation::with_depth( + self.selcx.tcx(), self.cause.clone(), recursion_limit.0, self.param_env, @@ -1110,7 +1112,8 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>( } } - let obligation = Obligation::with_depth(cause.clone(), depth, param_env, projection_ty); + let obligation = + Obligation::with_depth(selcx.tcx(), cause.clone(), depth, param_env, projection_ty); match project(selcx, &obligation) { Ok(Projected::Progress(Progress { @@ -1343,8 +1346,8 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs }) .to_poly_trait_predicate(); - let _ = - selcx.infcx().commit_if_ok(|_| match selcx.select(&obligation.with(trait_predicate)) { + let _ = selcx.infcx().commit_if_ok(|_| { + match selcx.select(&obligation.with(tcx, trait_predicate)) { Ok(Some(super::ImplSource::UserDefined(data))) => { candidate_set.push_candidate(ProjectionCandidate::ImplTraitInTrait( ImplTraitInTraitCandidate::Impl(data), @@ -1364,7 +1367,8 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>( candidate_set.mark_error(e); return Err(()); } - }); + } + }); } } @@ -1538,7 +1542,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // If we are resolving `<T as TraitRef<...>>::Item == Type`, // start out by selecting the predicate `T as TraitRef<...>`: let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx())); - let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate()); + let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref.to_poly_trait_predicate()); let _ = selcx.infcx().commit_if_ok(|_| { let impl_source = match selcx.select(&trait_obligation) { Ok(Some(impl_source)) => impl_source, @@ -1705,12 +1709,12 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( ty::Param(_) | ty::Projection(..) | ty::Opaque(..) if selcx.infcx().predicate_must_hold_modulo_regions( &obligation.with( - ty::Binder::dummy(ty::TraitRef::new( - selcx.tcx().require_lang_item(LangItem::Sized, None), - selcx.tcx().mk_substs_trait(self_ty, &[]), + selcx.tcx(), + ty::Binder::dummy(selcx.tcx().at(obligation.cause.span).mk_trait_ref( + LangItem::Sized, + [self_ty], )) - .without_const() - .to_predicate(selcx.tcx()), + .without_const(), ), ) => { @@ -1962,21 +1966,15 @@ fn confirm_pointee_candidate<'cx, 'tcx>( ) }); if check_is_sized { - let sized_predicate = ty::Binder::dummy(ty::TraitRef::new( - tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait(self_ty, &[]), - )) - .without_const() - .to_predicate(tcx); - obligations.push(Obligation::new( - obligation.cause.clone(), - obligation.param_env, - sized_predicate, - )); + let sized_predicate = ty::Binder::dummy( + tcx.at(obligation.cause.span).mk_trait_ref(LangItem::Sized, [self_ty]), + ) + .without_const(); + obligations.push(obligation.with(tcx, sized_predicate)); } let substs = tcx.mk_substs([self_ty.into()].iter()); - let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None); + let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, Some(obligation.cause.span)); let predicate = ty::ProjectionPredicate { projection_ty: ty::ProjectionTy { substs, item_def_id: metadata_def_id }, @@ -2289,6 +2287,7 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>( obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map( |(pred, span)| { Obligation::with_depth( + tcx, ObligationCause::new( obligation.cause.span, obligation.cause.body_id, @@ -2342,6 +2341,7 @@ fn assoc_ty_own_obligations<'cx, 'tcx>( nested, ); nested.push(Obligation::with_depth( + tcx, obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a7932b332c9..a875ea1578d 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -198,7 +198,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // This is really important. While we *can* handle this, this has // severe performance implications for large opaque types with // late-bound regions. See `issue-88862` benchmark. - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` outside of type inference, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty.try_super_fold_with(self), @@ -208,6 +208,7 @@ impl<'cx, 'tcx> FallibleTypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let recursion_limit = self.tcx().recursion_limit(); if !recursion_limit.value_within_limit(self.anon_depth) { let obligation = Obligation::with_depth( + self.tcx(), self.cause.clone(), recursion_limit.0, self.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/relationships.rs b/compiler/rustc_trait_selection/src/traits/relationships.rs index 8cf500a466b..f844da50032 100644 --- a/compiler/rustc_trait_selection/src/traits/relationships.rs +++ b/compiler/rustc_trait_selection/src/traits/relationships.rs @@ -1,8 +1,8 @@ use crate::infer::InferCtxt; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{ObligationCause, PredicateObligation}; +use crate::traits::PredicateObligation; use rustc_infer::traits::TraitEngine; -use rustc_middle::ty::{self, ToPredicate}; +use rustc_middle::ty; pub(crate) fn update<'tcx, T>( engine: &mut T, @@ -18,28 +18,16 @@ pub(crate) fn update<'tcx, T>( { let new_self_ty = infcx.tcx.types.unit; - let trait_ref = ty::TraitRef { - substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]), - ..tpred.trait_ref - }; - // Then construct a new obligation with Self = () added // to the ParamEnv, and see if it holds. - let o = rustc_infer::traits::Obligation::new( - ObligationCause::dummy(), - obligation.param_env, + let o = obligation.with(infcx.tcx, obligation .predicate .kind() .rebind( // (*) binder moved here - ty::PredicateKind::Trait(ty::TraitPredicate { - trait_ref, - constness: tpred.constness, - polarity: tpred.polarity, - }) - ) - .to_predicate(infcx.tcx), + ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty)) + ), ); // Don't report overflow errors. Otherwise equivalent to may_hold. if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) && result.may_apply() { diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 3671a0d87df..3b107d9570f 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -8,12 +8,11 @@ use hir::LangItem; use rustc_errors::DelayDm; use rustc_hir as hir; -use rustc_hir::def_id::DefId; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; use rustc_lint_defs::builtin::DEREF_INTO_DYN_SUPERTRAIT; use rustc_middle::ty::print::with_no_trimmed_paths; -use rustc_middle::ty::{self, ToPredicate, Ty, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TypeVisitable}; use rustc_target::spec::abi::Abi; use crate::traits; @@ -304,6 +303,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_candidates_for_transmutability(obligation, &mut candidates); } else if lang_items.tuple_trait() == Some(def_id) { self.assemble_candidate_for_tuple(obligation, &mut candidates); + } else if lang_items.pointer_sized() == Some(def_id) { + self.assemble_candidate_for_ptr_sized(obligation, &mut candidates); } else { if lang_items.clone_trait() == Some(def_id) { // Same builtin conditions as `Copy`, i.e., every type which has builtin support @@ -705,48 +706,44 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty: Ty<'tcx>, param_env: ty::ParamEnv<'tcx>, cause: &ObligationCause<'tcx>, - ) -> Option<(Ty<'tcx>, DefId)> { + ) -> Option<ty::PolyExistentialTraitRef<'tcx>> { let tcx = self.tcx(); if tcx.features().trait_upcasting { return None; } // <ty as Deref> - let trait_ref = ty::TraitRef { - def_id: tcx.lang_items().deref_trait()?, - substs: tcx.mk_substs_trait(ty, &[]), - }; + let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]); let obligation = traits::Obligation::new( + tcx, cause.clone(), param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx), + ty::Binder::dummy(trait_ref).without_const(), ); if !self.infcx.predicate_may_hold(&obligation) { return None; } - let ty = traits::normalize_projection_type( - self, - param_env, - ty::ProjectionTy { - item_def_id: tcx.lang_items().deref_target()?, - substs: trait_ref.substs, - }, - cause.clone(), - 0, - // We're *intentionally* throwing these away, - // since we don't actually use them. - &mut vec![], - ) - .ty() - .unwrap(); - - if let ty::Dynamic(data, ..) = ty.kind() { - Some((ty, data.principal_def_id()?)) - } else { - None - } + self.infcx.probe(|_| { + let ty = traits::normalize_projection_type( + self, + param_env, + ty::ProjectionTy { + item_def_id: tcx.lang_items().deref_target()?, + substs: trait_ref.substs, + }, + cause.clone(), + 0, + // We're *intentionally* throwing these away, + // since we don't actually use them. + &mut vec![], + ) + .ty() + .unwrap(); + + if let ty::Dynamic(data, ..) = ty.kind() { data.principal() } else { None } + }) } /// Searches for unsizing that might apply to `obligation`. @@ -779,7 +776,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match (source.kind(), target.kind()) { // Trait+Kx+'a -> Trait+Ky+'b (upcasts). - (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => { + (&ty::Dynamic(ref data_a, _, dyn_a), &ty::Dynamic(ref data_b, _, dyn_b)) + if dyn_a == dyn_b => + { // Upcast coercions permit several things: // // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo` @@ -806,21 +805,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let principal_a = data_a.principal().unwrap(); let target_trait_did = principal_def_id_b.unwrap(); let source_trait_ref = principal_a.with_self_ty(self.tcx(), source); - if let Some((deref_output_ty, deref_output_trait_did)) = self - .need_migrate_deref_output_trait_object( - source, - obligation.param_env, - &obligation.cause, - ) - { - if deref_output_trait_did == target_trait_did { + if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object( + source, + obligation.param_env, + &obligation.cause, + ) { + if deref_trait_ref.def_id() == target_trait_did { self.tcx().struct_span_lint_hir( DEREF_INTO_DYN_SUPERTRAIT, obligation.cause.body_id, obligation.cause.span, DelayDm(|| format!( "`{}` implements `Deref` with supertrait `{}` as output", - source, deref_output_ty + source, deref_trait_ref )), |lint| lint, ); @@ -840,7 +837,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } // `T` -> `Trait` - (_, &ty::Dynamic(..)) => { + (_, &ty::Dynamic(_, _, ty::Dyn)) => { candidates.vec.push(BuiltinUnsizeCandidate); } @@ -1046,4 +1043,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Placeholder(_) => {} } } + + fn assemble_candidate_for_ptr_sized( + &mut self, + obligation: &TraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + // The regions of a type don't affect the size of the type + let self_ty = self + .tcx() + .erase_regions(self.tcx().erase_late_bound_regions(obligation.predicate.self_ty())); + + // But if there are inference variables, we have to wait until it's resolved. + if self_ty.has_non_region_infer() { + candidates.ambiguous = true; + return; + } + + let usize_layout = + self.tcx().layout_of(ty::ParamEnv::empty().and(self.tcx().types.usize)).unwrap().layout; + if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty)) + && layout.layout.size() == usize_layout.size() + && layout.layout.align().abi == usize_layout.align().abi + { + candidates.vec.push(BuiltinCandidate { has_nested: false }); + } + } } diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index 28b4bae7cbe..2ec5d925b69 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -194,6 +194,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut obligations, ); obligations.push(Obligation::with_depth( + self.tcx(), obligation.cause.clone(), obligation.recursion_depth + 1, obligation.param_env, @@ -482,11 +483,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { super_trait, &mut nested, ); - nested.push(Obligation::new( - obligation.cause.clone(), - obligation.param_env, - normalized_super_trait, - )); + nested.push(obligation.with(tcx, normalized_super_trait)); } let assoc_types: Vec<_> = tcx @@ -581,11 +578,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { subst_bound, &mut nested, ); - nested.push(Obligation::new( - obligation.cause.clone(), - obligation.param_env, - normalized_bound, - )); + nested.push(obligation.with(tcx, normalized_bound)); } } @@ -639,14 +632,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { output_ty, &mut nested, ); - let tr = ty::Binder::dummy(ty::TraitRef::new( - self.tcx().require_lang_item(LangItem::Sized, None), - self.tcx().mk_substs_trait(output_ty, &[]), - )); + let tr = + ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty])); nested.push(Obligation::new( + self.infcx.tcx, cause, obligation.param_env, - tr.to_poly_trait_predicate().to_predicate(self.tcx()), + tr.to_poly_trait_predicate(), )); Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested }) @@ -727,11 +719,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME: Chalk if !self.tcx().sess.opts.unstable_opts.chalk { - nested.push(Obligation::new( - obligation.cause.clone(), - obligation.param_env, - ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)) - .to_predicate(self.tcx()), + nested.push(obligation.with( + self.tcx(), + ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)), )); } @@ -860,10 +850,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( + tcx, cause, obligation.recursion_depth + 1, obligation.param_env, - obligation.predicate.rebind(outlives).to_predicate(tcx), + obligation.predicate.rebind(outlives), )); } _ => bug!(), @@ -919,7 +910,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut nested = vec![]; match (source.kind(), target.kind()) { // Trait+Kx+'a -> Trait+Ky+'b (auto traits and lifetime subtyping). - (&ty::Dynamic(ref data_a, r_a, ty::Dyn), &ty::Dynamic(ref data_b, r_b, ty::Dyn)) => { + (&ty::Dynamic(ref data_a, r_a, dyn_a), &ty::Dynamic(ref data_b, r_b, dyn_b)) + if dyn_a == dyn_b => + { // See `assemble_candidates_for_unsizing` for more info. // We already checked the compatibility of auto traits within `assemble_candidates_for_unsizing`. let iter = data_a @@ -938,7 +931,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map(ty::Binder::dummy), ); let existential_predicates = tcx.mk_poly_existential_predicates(iter); - let source_trait = tcx.mk_dynamic(existential_predicates, r_b, ty::Dyn); + let source_trait = tcx.mk_dynamic(existential_predicates, r_b, dyn_a); // Require that the traits involved in this upcast are **equal**; // only the **lifetime bound** is changed. @@ -957,10 +950,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); let outlives = ty::OutlivesPredicate(r_a, r_b); nested.push(Obligation::with_depth( + tcx, cause, obligation.recursion_depth + 1, obligation.param_env, - obligation.predicate.rebind(outlives).to_predicate(tcx), + obligation.predicate.rebind(outlives), )); } @@ -979,6 +973,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let predicate_to_obligation = |predicate| { Obligation::with_depth( + tcx, cause.clone(), obligation.recursion_depth + 1, obligation.param_env, @@ -999,10 +994,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); // We can only make objects from sized types. - let tr = ty::Binder::dummy(ty::TraitRef::new( - tcx.require_lang_item(LangItem::Sized, None), - tcx.mk_substs_trait(source, &[]), - )); + let tr = + ty::Binder::dummy(tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [source])); nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx))); // If the type is `Foo + 'a`, ensure that the type @@ -1108,8 +1101,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.clone(), obligation.predicate.def_id(), obligation.recursion_depth + 1, - source_tail, - &[target_tail.into()], + [source_tail, target_tail], )); } @@ -1139,13 +1131,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.cause.clone(), obligation.predicate.def_id(), obligation.recursion_depth + 1, - a_last, - &[b_last.into()], + [a_last, b_last], ) })); } - _ => bug!(), + _ => bug!("source: {source}, target: {target}"), }; Ok(ImplSourceBuiltinData { nested }) @@ -1255,20 +1246,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { obligation.param_env, cause.clone(), obligation.recursion_depth + 1, - self_ty - .rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), - }, - constness: ty::BoundConstness::ConstIfConst, - polarity: ty::ImplPolarity::Positive, - }) - .to_predicate(tcx), + self_ty.rebind(ty::TraitPredicate { + trait_ref: self + .tcx() + .at(cause.span) + .mk_trait_ref(LangItem::Destruct, [nested_ty]), + constness: ty::BoundConstness::ConstIfConst, + polarity: ty::ImplPolarity::Positive, + }), &mut nested, ); nested.push(Obligation::with_depth( + tcx, cause.clone(), obligation.recursion_depth + 1, obligation.param_env, @@ -1280,18 +1270,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // since it's either not `const Drop` (and we raise an error during selection), // or it's an ADT (and we need to check for a custom impl during selection) _ => { - let predicate = self_ty - .rebind(ty::TraitPredicate { - trait_ref: ty::TraitRef { - def_id: self.tcx().require_lang_item(LangItem::Destruct, None), - substs: self.tcx().mk_substs_trait(nested_ty, &[]), - }, - constness: ty::BoundConstness::ConstIfConst, - polarity: ty::ImplPolarity::Positive, - }) - .to_predicate(tcx); + let predicate = self_ty.rebind(ty::TraitPredicate { + trait_ref: self + .tcx() + .at(cause.span) + .mk_trait_ref(LangItem::Destruct, [nested_ty]), + constness: ty::BoundConstness::ConstIfConst, + polarity: ty::ImplPolarity::Positive, + }); nested.push(Obligation::with_depth( + tcx, cause.clone(), obligation.recursion_depth + 1, obligation.param_env, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 3a899c03b4c..2803a2d38c8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -33,7 +33,7 @@ use crate::traits::ProjectionCacheKey; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_errors::{Diagnostic, ErrorGuaranteed}; +use rustc_errors::Diagnostic; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_infer::infer::LateBoundRegionConversionTime; @@ -42,6 +42,7 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::ty::print::{FmtPrinter, Print}; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::SubstsRef; use rustc_middle::ty::{self, EarlyBinder, PolyProjectionPredicate, ToPolyTraitRef, ToPredicate}; @@ -109,25 +110,6 @@ pub struct SelectionContext<'cx, 'tcx> { /// require themselves. freshener: TypeFreshener<'cx, 'tcx>, - /// During coherence we have to assume that other crates may add - /// additional impls which we currently don't know about. - /// - /// To deal with this evaluation should be conservative - /// and consider the possibility of impls from outside this crate. - /// This comes up primarily when resolving ambiguity. Imagine - /// there is some trait reference `$0: Bar` where `$0` is an - /// inference variable. If `intercrate` is true, then we can never - /// say for sure that this reference is not implemented, even if - /// there are *no impls at all for `Bar`*, because `$0` could be - /// bound to some type that in a downstream crate that implements - /// `Bar`. - /// - /// Outside of coherence we set this to false because we are only - /// interested in types that the user could actually have written. - /// In other words, we consider `$0: Bar` to be unimplemented if - /// there is no type that the user could *actually name* that - /// would satisfy it. This avoids crippling inference, basically. - intercrate: bool, /// If `intercrate` is set, we remember predicates which were /// considered ambiguous because of impls potentially added in other crates. /// This is used in coherence to give improved diagnostics. @@ -225,16 +207,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, freshener: infcx.freshener_keep_static(), - intercrate: false, intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } } - pub fn intercrate(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> { - SelectionContext { intercrate: true, ..SelectionContext::new(infcx) } - } - pub fn with_query_mode( infcx: &'cx InferCtxt<'tcx>, query_mode: TraitQueryMode, @@ -246,7 +223,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// Enables tracking of intercrate ambiguity causes. See /// the documentation of [`Self::intercrate_ambiguity_causes`] for more. pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) { - assert!(self.intercrate); + assert!(self.is_intercrate()); assert!(self.intercrate_ambiguity_causes.is_none()); self.intercrate_ambiguity_causes = Some(FxIndexSet::default()); debug!("selcx: enable_tracking_intercrate_ambiguity_causes"); @@ -256,7 +233,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// was enabled and disables tracking at the same time. If /// tracking is not enabled, just returns an empty vector. pub fn take_intercrate_ambiguity_causes(&mut self) -> FxIndexSet<IntercrateAmbiguityCause> { - assert!(self.intercrate); + assert!(self.is_intercrate()); self.intercrate_ambiguity_causes.take().unwrap_or_default() } @@ -269,7 +246,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } pub fn is_intercrate(&self) -> bool { - self.intercrate + self.infcx.intercrate } /////////////////////////////////////////////////////////////////////////// @@ -445,7 +422,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::Trait(t) => { let t = bound_predicate.rebind(t); debug_assert!(!t.has_escaping_bound_vars()); - let obligation = obligation.with(t); + let obligation = obligation.with(self.tcx(), t); self.evaluate_trait_predicate_recursively(previous_stack, obligation) } @@ -596,7 +573,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::Projection(data) => { let data = bound_predicate.rebind(data); - let project_obligation = obligation.with(data); + let project_obligation = obligation.with(self.tcx(), data); match project::poly_project_and_unify_type(self, &project_obligation) { ProjectAndUnifyResult::Holds(mut subobligations) => { 'compute_res: { @@ -740,6 +717,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for chalk") } + ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig), } }) } @@ -750,7 +728,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { previous_stack: TraitObligationStackList<'o, 'tcx>, mut obligation: TraitObligation<'tcx>, ) -> Result<EvaluationResult, OverflowError> { - if !self.intercrate + if !self.is_intercrate() && obligation.is_global() && obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst()) { @@ -1013,7 +991,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return None; } @@ -1043,7 +1021,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return; } @@ -1081,18 +1059,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { it.for_each(|o| o.recursion_depth = cmp::max(min_depth, o.recursion_depth) + 1); } - fn check_recursion_depth<T: Display + TypeFoldable<'tcx>>( + fn check_recursion_depth<T>( &self, depth: usize, error_obligation: &Obligation<'tcx, T>, - ) -> Result<(), OverflowError> { + ) -> Result<(), OverflowError> + where + T: fmt::Display + + TypeFoldable<'tcx> + + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, + <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug, + { if !self.infcx.tcx.recursion_limit().value_within_limit(depth) { match self.query_mode { TraitQueryMode::Standard => { - if self.infcx.is_tainted_by_errors() { - return Err(OverflowError::Error( - ErrorGuaranteed::unchecked_claim_error_was_emitted(), - )); + if let Some(e) = self.infcx.tainted_by_errors() { + return Err(OverflowError::Error(e)); } self.infcx.err_ctxt().report_overflow_error(error_obligation, true); } @@ -1109,11 +1091,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// The weird return type of this function allows it to be used with the `try` (`?`) /// operator within certain functions. #[inline(always)] - fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V: Display + TypeFoldable<'tcx>>( + fn check_recursion_limit<T: Display + TypeFoldable<'tcx>, V>( &self, obligation: &Obligation<'tcx, T>, error_obligation: &Obligation<'tcx, V>, - ) -> Result<(), OverflowError> { + ) -> Result<(), OverflowError> + where + V: fmt::Display + + TypeFoldable<'tcx> + + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>, + <V as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug, + { self.check_recursion_depth(obligation.recursion_depth, error_obligation) } @@ -1214,9 +1202,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } fn is_knowable<'o>(&mut self, stack: &TraitObligationStack<'o, 'tcx>) -> Result<(), Conflict> { - debug!("is_knowable(intercrate={:?})", self.intercrate); + debug!("is_knowable(intercrate={:?})", self.is_intercrate()); - if !self.intercrate || stack.obligation.polarity() == ty::ImplPolarity::Negative { + if !self.is_intercrate() || stack.obligation.polarity() == ty::ImplPolarity::Negative { return Ok(()); } @@ -1247,7 +1235,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // the master cache. Since coherence executes pretty quickly, // it's not worth going to more trouble to increase the // hit-rate, I don't think. - if self.intercrate { + if self.is_intercrate() { return false; } @@ -1264,7 +1252,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return None; } let tcx = self.tcx(); @@ -1303,7 +1291,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // mode, so don't do any caching. In particular, we might // re-use the same `InferCtxt` with both an intercrate // and non-intercrate `SelectionContext` - if self.intercrate { + if self.is_intercrate() { return false; } match result { @@ -2089,8 +2077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { cause.clone(), trait_def_id, recursion_depth, - normalized_ty, - &[], + [normalized_ty], ); obligations.push(placeholder_obligation); obligations @@ -2181,7 +2168,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { .map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{e}`"))?; nested_obligations.extend(obligations); - if !self.intercrate + if !self.is_intercrate() && self.tcx().impl_polarity(impl_def_id) == ty::ImplPolarity::Reservation { debug!("reservation impls only apply in intercrate mode"); diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index ed47d2f83df..895b84fd7e9 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -238,11 +238,9 @@ pub fn predicate_for_trait_def<'tcx>( cause: ObligationCause<'tcx>, trait_def_id: DefId, recursion_depth: usize, - self_ty: Ty<'tcx>, - params: &[GenericArg<'tcx>], + params: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, ) -> PredicateObligation<'tcx> { - let trait_ref = - ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(self_ty, params) }; + let trait_ref = tcx.mk_trait_ref(trait_def_id, params); predicate_for_trait_ref(tcx, cause, param_env, trait_ref, recursion_depth) } @@ -305,10 +303,7 @@ pub fn closure_trait_ref_and_return_type<'tcx>( TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()), }; debug_assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]), - }; + let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, arguments_tuple]); sig.map_bound(|sig| (trait_ref, sig.output())) } @@ -319,10 +314,7 @@ pub fn generator_trait_ref_and_outputs<'tcx>( sig: ty::PolyGenSig<'tcx>, ) -> ty::Binder<'tcx, (ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> { debug_assert!(!self_ty.has_escaping_bound_vars()); - let trait_ref = ty::TraitRef { - def_id: fn_trait_def_id, - substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]), - }; + let trait_ref = tcx.mk_trait_ref(fn_trait_def_id, [self_ty, sig.skip_binder().resume_ty]); sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty)) } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index fc0a9f69003..5e506a23f38 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -4,7 +4,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeVisitable}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable}; use rustc_span::Span; use std::iter; @@ -155,6 +155,7 @@ pub fn predicate_obligations<'tcx>( wf.compute(c1.into()); wf.compute(c2.into()); } + ty::PredicateKind::Ambiguous => {} ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("TypeWellFormedFromEnv is only used for Chalk") } @@ -324,7 +325,7 @@ impl<'tcx> WfPredicates<'tcx> { extend_cause_with_original_assoc_item_obligation( tcx, trait_ref, item, &mut cause, predicate, ); - traits::Obligation::with_depth(cause, depth, param_env, predicate) + traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate) }; if let Elaborate::All = elaborate { @@ -356,10 +357,11 @@ impl<'tcx> WfPredicates<'tcx> { } } traits::Obligation::with_depth( + tcx, cause, depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), ) }), ); @@ -407,10 +409,11 @@ impl<'tcx> WfPredicates<'tcx> { .filter(|arg| !arg.has_escaping_bound_vars()) .map(|arg| { traits::Obligation::with_depth( + tcx, cause.clone(), depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)), ) }), ); @@ -419,15 +422,13 @@ impl<'tcx> WfPredicates<'tcx> { fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) { if !subty.has_escaping_bound_vars() { let cause = self.cause(cause); - let trait_ref = ty::TraitRef { - def_id: self.tcx.require_lang_item(LangItem::Sized, None), - substs: self.tcx.mk_substs_trait(subty, &[]), - }; + let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [subty]); self.out.push(traits::Obligation::with_depth( + self.tcx, cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx), + ty::Binder::dummy(trait_ref).without_const(), )); } } @@ -454,10 +455,10 @@ impl<'tcx> WfPredicates<'tcx> { self.out.extend(obligations); let predicate = - ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)) - .to_predicate(self.tcx()); + ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct)); let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( + self.tcx(), cause, self.recursion_depth, self.param_env, @@ -468,11 +469,11 @@ impl<'tcx> WfPredicates<'tcx> { let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( + self.tcx(), cause, self.recursion_depth, self.param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())), )); } ty::ConstKind::Error(_) @@ -556,13 +557,13 @@ impl<'tcx> WfPredicates<'tcx> { if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() { let cause = self.cause(traits::ReferenceOutlivesReferent(ty)); self.out.push(traits::Obligation::with_depth( + self.tcx(), cause, depth, param_env, ty::Binder::dummy(ty::PredicateKind::TypeOutlives( ty::OutlivesPredicate(rty, r), - )) - .to_predicate(self.tcx()), + )), )); } } @@ -656,11 +657,11 @@ impl<'tcx> WfPredicates<'tcx> { let tcx = self.tcx(); self.out.extend(component_traits.map(|did| { traits::Obligation::with_depth( + tcx, cause.clone(), depth, param_env, - ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)) - .to_predicate(tcx), + ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)), ) })); } @@ -681,11 +682,11 @@ impl<'tcx> WfPredicates<'tcx> { ty::Infer(_) => { let cause = self.cause(traits::WellFormed(None)); self.out.push(traits::Obligation::with_depth( + self.tcx(), cause, self.recursion_depth, param_env, - ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())) - .to_predicate(self.tcx()), + ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())), )); } } @@ -724,7 +725,13 @@ impl<'tcx> WfPredicates<'tcx> { if remap_constness { pred = pred.without_const(self.tcx); } - traits::Obligation::with_depth(cause, self.recursion_depth, self.param_env, pred) + traits::Obligation::with_depth( + self.tcx, + cause, + self.recursion_depth, + self.param_env, + pred, + ) }) .filter(|pred| !pred.has_escaping_bound_vars()) .collect() @@ -749,7 +756,7 @@ impl<'tcx> WfPredicates<'tcx> { fn from_object_ty( &mut self, ty: Ty<'tcx>, - data: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, region: ty::Region<'tcx>, ) { // Imagine a type like this: @@ -794,10 +801,11 @@ impl<'tcx> WfPredicates<'tcx> { let outlives = ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound)); self.out.push(traits::Obligation::with_depth( + self.tcx, cause, self.recursion_depth, self.param_env, - outlives.to_predicate(self.tcx), + outlives, )); } } @@ -812,7 +820,7 @@ impl<'tcx> WfPredicates<'tcx> { /// `infer::required_region_bounds`, see that for more information. pub fn object_region_bounds<'tcx>( tcx: TyCtxt<'tcx>, - existential_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, + existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>, ) -> Vec<ty::Region<'tcx>> { // Since we don't actually *know* the self type for an object, // this "open(err)" serves as a kind of dummy standin -- basically @@ -868,6 +876,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => { // Search for a bound of the form `erased_self_ty diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 25cedefa261..ee013515e86 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -121,6 +121,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<' | ty::PredicateKind::Subtype(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::ConstEquate(..) => bug!("unexpected predicate {}", predicate), }; let value = chalk_ir::ProgramClauseImplication { @@ -212,6 +213,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predi ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::ConstEquate(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } @@ -625,6 +627,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<' | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("unexpected predicate {}", &self) } @@ -634,7 +637,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<' } impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<RustInterner<'tcx>>>> - for &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>> + for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> { fn lower_into( self, @@ -689,7 +692,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders<chalk_ir::QuantifiedWhereClauses<Ru trait_id: chalk_ir::TraitId(def_id), substitution: interner .tcx - .mk_substs_trait(self_ty, &[]) + .mk_substs_trait(self_ty, []) .lower_into(interner), }), ), @@ -754,6 +757,7 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_solve::rust_ir::QuantifiedInlineBound<Ru | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => { bug!("unexpected predicate {}", &self) } diff --git a/compiler/rustc_traits/src/evaluate_obligation.rs b/compiler/rustc_traits/src/evaluate_obligation.rs index 493d5de0807..e94c8efe69a 100644 --- a/compiler/rustc_traits/src/evaluate_obligation.rs +++ b/compiler/rustc_traits/src/evaluate_obligation.rs @@ -26,7 +26,7 @@ fn evaluate_obligation<'tcx>( let ParamEnvAnd { param_env, value: predicate } = goal; let mut selcx = SelectionContext::with_query_mode(&infcx, TraitQueryMode::Canonical); - let obligation = Obligation::new(ObligationCause::dummy(), param_env, predicate); + let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate); selcx.evaluate_root_obligation(&obligation) } diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs index 82f6111f6f9..2d1a3869926 100644 --- a/compiler/rustc_traits/src/implied_outlives_bounds.rs +++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs @@ -97,6 +97,7 @@ fn compute_implied_outlives_bounds<'tcx>( | ty::PredicateKind::ObjectSafe(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => None, ty::PredicateKind::WellFormed(arg) => { wf_args.push(arg); diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index 2da64d73d34..5200908527a 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -34,7 +34,9 @@ fn try_normalize_after_erasing_regions<'tcx, T: TypeFoldable<'tcx> + PartialEq + // We don't care about the `obligations`; they are // always only region relations, and we are about to // erase those anyway: - debug_assert_eq!( + // This has been seen to fail in RL, so making it a non-debug assertion to better catch + // those cases. + assert_eq!( normalized_obligations.iter().find(|p| not_outlives_predicate(p.predicate)), None, ); @@ -64,6 +66,7 @@ fn not_outlives_predicate<'tcx>(p: ty::Predicate<'tcx>) -> bool { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::Ambiguous | ty::PredicateKind::TypeWellFormedFromEnv(..) => true, } } diff --git a/compiler/rustc_traits/src/type_op.rs b/compiler/rustc_traits/src/type_op.rs index 98cb3f21555..9eceae8b44f 100644 --- a/compiler/rustc_traits/src/type_op.rs +++ b/compiler/rustc_traits/src/type_op.rs @@ -91,7 +91,12 @@ impl<'me, 'tcx> AscribeUserTypeCx<'me, 'tcx> { } fn prove_predicate(&self, predicate: Predicate<'tcx>, cause: ObligationCause<'tcx>) { - self.ocx.register_obligation(Obligation::new(cause, self.param_env, predicate)); + self.ocx.register_obligation(Obligation::new( + self.ocx.infcx.tcx, + cause, + self.param_env, + predicate, + )); } fn tcx(&self) -> TyCtxt<'tcx> { @@ -256,5 +261,5 @@ pub fn type_op_prove_predicate_with_cause<'tcx>( cause: ObligationCause<'tcx>, ) { let (param_env, ProvePredicate { predicate }) = key.into_parts(); - ocx.register_obligation(Obligation::new(cause, param_env, predicate)); + ocx.register_obligation(Obligation::new(ocx.infcx.tcx, cause, param_env, predicate)); } diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index b59be0a0ea7..07af3dc5164 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -138,8 +138,18 @@ fn univariant_uninterned<'tcx>( if optimize { let end = if let StructKind::MaybeUnsized = kind { fields.len() - 1 } else { fields.len() }; let optimizing = &mut inverse_memory_index[..end]; - let field_align = |f: &TyAndLayout<'_>| { - if let Some(pack) = pack { f.align.abi.min(pack) } else { f.align.abi } + let effective_field_align = |f: &TyAndLayout<'_>| { + if let Some(pack) = pack { + // return the packed alignment in bytes + f.align.abi.min(pack).bytes() + } else { + // returns log2(effective-align). + // This is ok since `pack` applies to all fields equally. + // The calculation assumes that size is an integer multiple of align, except for ZSTs. + // + // group [u8; 4] with align-4 or [u8; 6] with align-2 fields + f.align.abi.bytes().max(f.size.bytes()).trailing_zeros() as u64 + } }; // If `-Z randomize-layout` was enabled for the type definition we can shuffle @@ -160,15 +170,23 @@ fn univariant_uninterned<'tcx>( optimizing.sort_by_key(|&x| { // Place ZSTs first to avoid "interesting offsets", // especially with only one or two non-ZST fields. + // Then place largest alignments first, largest niches within an alignment group last let f = &fields[x as usize]; - (!f.is_zst(), cmp::Reverse(field_align(f))) + let niche_size = f.largest_niche.map_or(0, |n| n.available(cx)); + (!f.is_zst(), cmp::Reverse(effective_field_align(f)), niche_size) }); } StructKind::Prefixed(..) => { // Sort in ascending alignment so that the layout stays optimal - // regardless of the prefix - optimizing.sort_by_key(|&x| field_align(&fields[x as usize])); + // regardless of the prefix. + // And put the largest niche in an alignment group at the end + // so it can be used as discriminant in jagged enums + optimizing.sort_by_key(|&x| { + let f = &fields[x as usize]; + let niche_size = f.largest_niche.map_or(0, |n| n.available(cx)); + (effective_field_align(f), niche_size) + }); } } @@ -442,8 +460,7 @@ fn layout_of_uncached<'tcx>( let element = cx.layout_of(element)?; let size = element.size.checked_mul(count, dl).ok_or(LayoutError::SizeOverflow(ty))?; - let abi = if count != 0 && tcx.conservative_is_privately_uninhabited(param_env.and(ty)) - { + let abi = if count != 0 && ty.is_privately_uninhabited(tcx, param_env) { Abi::Uninhabited } else { Abi::Aggregate { sized: true } diff --git a/compiler/rustc_ty_utils/src/layout_sanity_check.rs b/compiler/rustc_ty_utils/src/layout_sanity_check.rs index 100926ad446..ee5e7bc2359 100644 --- a/compiler/rustc_ty_utils/src/layout_sanity_check.rs +++ b/compiler/rustc_ty_utils/src/layout_sanity_check.rs @@ -12,7 +12,7 @@ pub(super) fn sanity_check_layout<'tcx>( layout: &TyAndLayout<'tcx>, ) { // Type-level uninhabitedness should always imply ABI uninhabitedness. - if cx.tcx.conservative_is_privately_uninhabited(cx.param_env.and(layout.ty)) { + if layout.ty.is_privately_uninhabited(cx.tcx, cx.param_env) { assert!(layout.abi.is_uninhabited()); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 99d3bda6ebf..5fc9bcac1b1 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -49,12 +49,9 @@ fn sized_constraint_for_ty<'tcx>( // it on the impl. let Some(sized_trait) = tcx.lang_items().sized_trait() else { return vec![ty] }; - let sized_predicate = ty::Binder::dummy(ty::TraitRef { - def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]), - }) - .without_const() - .to_predicate(tcx); + let sized_predicate = ty::Binder::dummy(tcx.mk_trait_ref(sized_trait, [ty])) + .without_const() + .to_predicate(tcx); let predicates = tcx.predicates_of(adtdef.did()).predicates; if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } } @@ -108,12 +105,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { /// See `ParamEnv` struct definition for details. fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { - // The param_env of an impl Trait type is its defining function's param_env - if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { - return param_env(tcx, parent.to_def_id()); - } // Compute the bounds on Self and the type parameters. - let ty::InstantiatedPredicates { mut predicates, .. } = tcx.predicates_of(def_id).instantiate_identity(tcx); @@ -416,62 +408,6 @@ fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness) } -/// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead. -pub fn conservative_is_privately_uninhabited_raw<'tcx>( - tcx: TyCtxt<'tcx>, - param_env_and: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> bool { - let (param_env, ty) = param_env_and.into_parts(); - match ty.kind() { - ty::Never => { - debug!("ty::Never =>"); - true - } - ty::Adt(def, _) if def.is_union() => { - debug!("ty::Adt(def, _) if def.is_union() =>"); - // For now, `union`s are never considered uninhabited. - false - } - ty::Adt(def, substs) => { - debug!("ty::Adt(def, _) if def.is_not_union() =>"); - // Any ADT is uninhabited if either: - // (a) It has no variants (i.e. an empty `enum`); - // (b) Each of its variants (a single one in the case of a `struct`) has at least - // one uninhabited field. - def.variants().iter().all(|var| { - var.fields.iter().any(|field| { - let ty = tcx.bound_type_of(field.did).subst(tcx, substs); - tcx.conservative_is_privately_uninhabited(param_env.and(ty)) - }) - }) - } - ty::Tuple(fields) => { - debug!("ty::Tuple(..) =>"); - fields.iter().any(|ty| tcx.conservative_is_privately_uninhabited(param_env.and(ty))) - } - ty::Array(ty, len) => { - debug!("ty::Array(ty, len) =>"); - match len.try_eval_usize(tcx, param_env) { - Some(0) | None => false, - // If the array is definitely non-empty, it's uninhabited if - // the type of its elements is uninhabited. - Some(1..) => tcx.conservative_is_privately_uninhabited(param_env.and(*ty)), - } - } - ty::Ref(..) => { - debug!("ty::Ref(..) =>"); - // References to uninitialised memory is valid for any type, including - // uninhabited types, in unsafe code, so we treat all references as - // inhabited. - false - } - _ => { - debug!("_ =>"); - false - } - } -} - pub fn provide(providers: &mut ty::query::Providers) { *providers = ty::query::Providers { asyncness, @@ -481,7 +417,6 @@ pub fn provide(providers: &mut ty::query::Providers) { instance_def_size_estimate, issue33140_self_ty, impl_defaultness, - conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw, ..*providers }; } diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 7c3eb4efbc9..581993ba7d8 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -60,10 +60,10 @@ pub trait InternAs<T: ?Sized, R> { type Output; fn intern_with<F>(self, f: F) -> Self::Output where - F: FnOnce(&T) -> R; + F: FnOnce(&[T]) -> R; } -impl<I, T, R, E> InternAs<[T], R> for I +impl<I, T, R, E> InternAs<T, R> for I where E: InternIteratorElement<T, R>, I: Iterator<Item = E>, |
