diff --git a/compiler/rustc_attr_parsing/src/attributes/doc.rs b/compiler/rustc_attr_parsing/src/attributes/doc.rs index 5d07478b152ee..60f469990d51a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/doc.rs +++ b/compiler/rustc_attr_parsing/src/attributes/doc.rs @@ -701,6 +701,9 @@ impl DocParser { for i in items.mixed() { match i { MetaItemOrLitParser::MetaItemParser(mip) => { + if self.nb_doc_attrs == 0 { + self.attribute.first_span = cx.attr_span; + } self.nb_doc_attrs += 1; self.parse_single_doc_attr_item(cx, mip); } diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 65e716921f5cb..8c41d7732c7d5 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -292,15 +292,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> { // in where clauses. After that, this function would become useless. let spans = attrs .into_iter() - // FIXME: We shouldn't need to special-case `doc`! - .filter(|attr| { - matches!( - attr, - Attribute::Parsed(AttributeKind::DocComment { .. } | AttributeKind::Doc(_)) - | Attribute::Unparsed(_) - ) + .filter_map(|attr| { + match attr { + Attribute::Parsed(AttributeKind::DocComment { span, .. }) => Some(*span), + // FIXME: We shouldn't need to special-case `doc`! + Attribute::Parsed(AttributeKind::Doc(attr)) => Some(attr.first_span), + // Checked during attribute parsing target checking + Attribute::Parsed(_) => None, + Attribute::Unparsed(attr) => Some(attr.span), + } }) - .map(|attr| attr.span()) .collect::>(); if !spans.is_empty() { self.dcx() diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index cb66dabf507a5..f3e28484bf11d 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -216,7 +216,9 @@ pub(crate) fn create_object_file(sess: &Session) -> Option - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# -)] +#[diag(r#"function pointer calls are not allowed in {$kind}s"#)] pub(crate) struct UnallowedFnPointerCall { #[primary_span] pub span: Span, @@ -224,12 +217,7 @@ pub(crate) struct MutableBorrowEscaping { #[derive(Diagnostic)] #[diag( - r#"cannot call {$non_or_conditionally}-const formatting macro in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, + r#"cannot call {$non_or_conditionally}-const formatting macro in {$kind}s"#, code = E0015, )] pub(crate) struct NonConstFmtMacroCall { @@ -240,12 +228,7 @@ pub(crate) struct NonConstFmtMacroCall { } #[derive(Diagnostic)] -#[diag(r#"cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {$kind}s"#, code = E0015)] pub(crate) struct NonConstFnCall { #[primary_span] pub span: Span, @@ -256,14 +239,7 @@ pub(crate) struct NonConstFnCall { } #[derive(Diagnostic)] -#[diag( - r#"cannot call non-const intrinsic `{$name}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# -)] +#[diag(r#"cannot call non-const intrinsic `{$name}` in {$kind}s"#)] pub(crate) struct NonConstIntrinsic { #[primary_span] pub span: Span, @@ -280,12 +256,7 @@ pub(crate) struct UnallowedOpInConstContext { } #[derive(Diagnostic)] -#[diag(r#"inline assembly is not allowed in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"inline assembly is not allowed in {$kind}s"#, code = E0015)] pub(crate) struct UnallowedInlineAsm { #[primary_span] pub span: Span, @@ -384,14 +355,7 @@ pub(crate) struct RawBytesNote { } #[derive(Diagnostic)] -#[diag( - r#"cannot match on `{$ty}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"# -)] +#[diag(r#"cannot match on `{$ty}` in {$kind}s"#)] #[note("`{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es")] pub(crate) struct NonConstMatchEq<'tcx> { #[primary_span] @@ -402,12 +366,7 @@ pub(crate) struct NonConstMatchEq<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"cannot use `for` loop on `{$ty}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot use `for` loop on `{$ty}` in {$kind}s"#, code = E0015)] pub(crate) struct NonConstForLoopIntoIter<'tcx> { #[primary_span] pub span: Span, @@ -417,12 +376,7 @@ pub(crate) struct NonConstForLoopIntoIter<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"`?` is not allowed on `{$ty}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"`?` is not allowed on `{$ty}` in {$kind}s"#, code = E0015)] pub(crate) struct NonConstQuestionBranch<'tcx> { #[primary_span] pub span: Span, @@ -432,12 +386,7 @@ pub(crate) struct NonConstQuestionBranch<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"`?` is not allowed on `{$ty}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"`?` is not allowed on `{$ty}` in {$kind}s"#, code = E0015)] pub(crate) struct NonConstQuestionFromResidual<'tcx> { #[primary_span] pub span: Span, @@ -447,12 +396,7 @@ pub(crate) struct NonConstQuestionFromResidual<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"`try` block cannot convert `{$ty}` to the result in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"`try` block cannot convert `{$ty}` to the result in {$kind}s"#, code = E0015)] pub(crate) struct NonConstTryBlockFromOutput<'tcx> { #[primary_span] pub span: Span, @@ -462,12 +406,7 @@ pub(crate) struct NonConstTryBlockFromOutput<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"cannot convert `{$ty}` into a future in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot convert `{$ty}` into a future in {$kind}s"#, code = E0015)] pub(crate) struct NonConstAwait<'tcx> { #[primary_span] pub span: Span, @@ -477,12 +416,7 @@ pub(crate) struct NonConstAwait<'tcx> { } #[derive(Diagnostic)] -#[diag(r#"cannot call {$non_or_conditionally}-const closure in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const closure in {$kind}s"#, code = E0015)] pub(crate) struct NonConstClosure { #[primary_span] pub span: Span, @@ -493,12 +427,7 @@ pub(crate) struct NonConstClosure { } #[derive(Diagnostic)] -#[diag(r#"calling const c-variadic functions is unstable in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"calling const c-variadic functions is unstable in {$kind}s"#, code = E0015)] pub(crate) struct NonConstCVariadicCall { #[primary_span] pub span: Span, @@ -512,23 +441,9 @@ pub(crate) enum NonConstClosureNote { #[primary_span] span: Span, }, - #[note( - r#"function pointers need an RFC before allowed to be called in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} - }s"# - )] + #[note(r#"function pointers need an RFC before allowed to be called in {$kind}s"#)] FnPtr { kind: ConstContext }, - #[note( - r#"closures need an RFC before allowed to be called in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} - }s"# - )] + #[note(r#"closures need an RFC before allowed to be called in {$kind}s"#)] Closure { kind: ConstContext }, } @@ -543,12 +458,7 @@ pub(crate) struct ConsiderDereferencing { } #[derive(Diagnostic)] -#[diag(r#"cannot call {$non_or_conditionally}-const operator in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot call {$non_or_conditionally}-const operator in {$kind}s"#, code = E0015)] pub(crate) struct NonConstOperator { #[primary_span] pub span: Span, @@ -559,12 +469,7 @@ pub(crate) struct NonConstOperator { } #[derive(Diagnostic)] -#[diag(r#"cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} -}s"#, code = E0015)] +#[diag(r#"cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {$kind}s"#, code = E0015)] #[note("attempting to deref into `{$target_ty}`")] pub(crate) struct NonConstDerefCoercion<'tcx> { #[primary_span] @@ -581,14 +486,7 @@ pub(crate) struct NonConstDerefCoercion<'tcx> { #[diag("destructor of `{$dropped_ty}` cannot be evaluated at compile-time", code = E0493)] pub(crate) struct LiveDrop<'tcx> { #[primary_span] - #[label( - r#"the destructor for this type cannot be evaluated in {$kind -> - [const] constant - [static] static - [const_fn] constant function - *[other] {""} - }s"# - )] + #[label(r#"the destructor for this type cannot be evaluated in {$kind}s"#)] pub span: Span, pub kind: ConstContext, pub dropped_ty: Ty<'tcx>, diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 6304b830f6ed7..bab86a25e3cbb 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -544,6 +544,8 @@ pub struct CfgHideShow { #[derive(Clone, Debug, Default, HashStable_Generic, Decodable, PrintAttribute)] pub struct DocAttribute { + pub first_span: Span, + pub aliases: FxIndexMap, pub hidden: Option, // Because we need to emit the error if there is more than one `inline` attribute on an item @@ -581,6 +583,7 @@ pub struct DocAttribute { impl rustc_serialize::Encodable for DocAttribute { fn encode(&self, encoder: &mut E) { let DocAttribute { + first_span, aliases, hidden, inline, @@ -603,6 +606,7 @@ impl rustc_serialize::Encodable for DocAttribute test_attrs, no_crate_inject, } = self; + rustc_serialize::Encodable::::encode(first_span, encoder); rustc_serialize::Encodable::::encode(aliases, encoder); rustc_serialize::Encodable::::encode(hidden, encoder); diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index d8e675c6c56b4..f99125d90821d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2389,9 +2389,9 @@ impl fmt::Display for ConstContext { impl IntoDiagArg for ConstContext { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::Borrowed(match self { - ConstContext::ConstFn => "const_fn", + ConstContext::ConstFn => "constant function", ConstContext::Static(_) => "static", - ConstContext::Const { .. } => "const", + ConstContext::Const { .. } => "constant", })) } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ebf0f06f7173d..34c2ec54e8fc9 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1027,6 +1027,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { /// [`check_doc_inline`]: Self::check_doc_inline fn check_doc_attrs(&self, attr: &DocAttribute, hir_id: HirId, target: Target) { let DocAttribute { + first_span: _, aliases, // valid pretty much anywhere, not checked here? // FIXME: should we? diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 28b9ce24178d9..2bbc04b8ac35d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1115,6 +1115,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("CACHE MISS"); self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result); stack.cache().on_completion(stack.dfn); + } else if let Some(_guar) = self.infcx.tainted_by_errors() { + // When an error has occurred, we allow global caching of results even if they + // appear stack-dependent. This prevents exponential re-evaluation of cycles + // in the presence of errors, avoiding compiler hangs like #150907. + // This is safe because compilation will fail anyway. + debug!("CACHE MISS (tainted by errors)"); + self.insert_evaluation_cache(param_env, fresh_trait_pred, dep_node, result); + stack.cache().on_completion(stack.dfn); } else { debug!("PROVISIONAL"); debug!( diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 81e348f96e569..3f604c1b7bb8b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2780,6 +2780,7 @@ fn add_without_unwanted_attributes<'hir>( hir::Attribute::Parsed(AttributeKind::Doc(box d)) => { // Remove attributes from `normal` that should not be inherited by `use` re-export. let DocAttribute { + first_span: _, aliases, hidden, inline, diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 5d1f4778f1c52..44749fd4c0ec6 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -960,6 +960,7 @@ fn maybe_from_hir_attr(attr: &hir::Attribute, item_id: ItemId, tcx: TyCtxt<'_>) } let DocAttribute { + first_span: _, aliases, hidden, inline, diff --git a/tests/ui/attributes/where-doc.rs b/tests/ui/attributes/where-doc.rs new file mode 100644 index 0000000000000..761d83966f659 --- /dev/null +++ b/tests/ui/attributes/where-doc.rs @@ -0,0 +1,34 @@ +#![feature(where_clause_attrs)] +#![allow(invalid_doc_attributes)] + +fn test() +where +#[doc(alias = ":(")] +//~^ ERROR most attributes are not supported in `where` clauses +//~| ERROR `#[doc(alias = "...")]` isn't allowed on where predicate +():, + +#[doc(hidden)] +//~^ ERROR most attributes are not supported in `where` clauses +():, + +#[doc = ""] +//~^ ERROR most attributes are not supported in `where` clauses +():, + +// == That the doc attributes below don't trigger the error is a bug +#[doc()] +():, + +#[doc(5)] +():, + +#[doc] +():, + +#[doc = 5] +():, + +{ } + +fn main() {} diff --git a/tests/ui/attributes/where-doc.stderr b/tests/ui/attributes/where-doc.stderr new file mode 100644 index 0000000000000..c8efaaeedfaac --- /dev/null +++ b/tests/ui/attributes/where-doc.stderr @@ -0,0 +1,32 @@ +error: most attributes are not supported in `where` clauses + --> $DIR/where-doc.rs:6:1 + | +LL | #[doc(alias = ":(")] + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/where-doc.rs:11:1 + | +LL | #[doc(hidden)] + | ^^^^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: most attributes are not supported in `where` clauses + --> $DIR/where-doc.rs:15:1 + | +LL | #[doc = ""] + | ^^^^^^^^^^^ + | + = help: only `#[cfg]` and `#[cfg_attr]` are supported + +error: `#[doc(alias = "...")]` isn't allowed on where predicate + --> $DIR/where-doc.rs:6:15 + | +LL | #[doc(alias = ":(")] + | ^^^^ + +error: aborting due to 4 previous errors + diff --git a/tests/ui/traits/cycle-cache-err-150907.rs b/tests/ui/traits/cycle-cache-err-150907.rs new file mode 100644 index 0000000000000..86bceab442ffc --- /dev/null +++ b/tests/ui/traits/cycle-cache-err-150907.rs @@ -0,0 +1,125 @@ +// Test that we don't hang or take exponential time when evaluating +// auto-traits for cyclic types containing errors, based on the reproducer +// provided in issue #150907. + +use std::sync::Arc; +use std::marker::PhantomData; + +struct Weak(PhantomData); +unsafe impl Send for Weak {} +unsafe impl Sync for Weak {} + +struct BTreeMap(K, V); + +trait DeviceOps: Send {} + +struct SerialDevice { + terminal: Weak, +} + +impl DeviceOps for SerialDevice {} + +struct TtyState { + terminals: Weak, +} + +struct TerminalMutableState { + controller: TerminalController, +} + +struct Terminal { + weak_self: Weak, + state: Arc, + mutable_state: Weak, +} + +struct TerminalController { + session: Weak, +} + +struct Kernel { + weak_self: Weak, + kthreads: KernelThreads, + pids: Weak, +} + +struct KernelThreads { + system_task: SystemTask, + kernel: Weak, +} + +struct SystemTask { + system_thread_group: Weak, +} + +enum ProcessEntry { + ThreadGroup(Weak), +} + +struct PidEntry { + task: Arc, + process: ProcessEntry, +} + +struct PidTable { + table: PidEntry, + process_groups: Arc, +} + +struct ProcessGroupMutableState { + thread_groups: Weak, +} + +struct ProcessGroup { + session: Arc, + mutable_state: Arc, +} + +struct SessionMutableState { + process_groups: BTreeMap<(), Weak>, + controlling_terminal: ControllingTerminal, +} + +struct Session { + mutable_state: Weak, +} + +struct ControllingTerminal { + terminal: Arc, +} + +struct TaskPersistentInfoState { + thread_group_key: ThreadGroupKey, +} + +struct Task { + thread_group_key: ThreadGroupKey, + kernel: Arc, + thread_group: Arc, + persistent_info: Arc, + vfork_event: Arc, //~ ERROR missing generics for struct `Arc` +} + +struct ThreadGroupKey { + thread_group: Arc, +} + +struct ThreadGroupMutableState { + tasks: BTreeMap<(), TaskContainer>, + children: BTreeMap<(), Weak>, + process_group: Arc, +} + +struct ThreadGroup { + kernel: Arc, + mutable_state: Weak, +} + +struct TaskContainer(Arc, Arc); + +fn main() { + // Trigger auto-trait check for one of the cyclic types + is_send::(); +} + +fn is_send() {} diff --git a/tests/ui/traits/cycle-cache-err-150907.stderr b/tests/ui/traits/cycle-cache-err-150907.stderr new file mode 100644 index 0000000000000..a8d680af55377 --- /dev/null +++ b/tests/ui/traits/cycle-cache-err-150907.stderr @@ -0,0 +1,14 @@ +error[E0107]: missing generics for struct `Arc` + --> $DIR/cycle-cache-err-150907.rs:100:18 + | +LL | vfork_event: Arc, + | ^^^ expected at least 1 generic argument + | +help: add missing generic argument + | +LL | vfork_event: Arc, + | +++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-binius_field-regression.rs b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-binius_field-regression.rs new file mode 100644 index 0000000000000..bcf3867b65f7c --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/is-global-norm-binius_field-regression.rs @@ -0,0 +1,51 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver +//@ check-pass + +// One of the minimizations from trait-system-refactor-initiative#257 which ended up +// getting fixed by #153614. It seems somewhat likely that this is somewhat +// accidental by changing the exact shape of the cycle, causing us to avoid the +// underlying issue of trait-system-refactor-initiative#257. + +pub trait Field: Sized + HasUnderlier> {} +pub trait PackScalar: 'static + UnderlierType { + type Packed; +} +trait PackedField { + type Scalar; +} +pub trait UnderlierType {} +pub trait HasUnderlier { + type Underlier; +} +impl HasUnderlier for U { + type Underlier = U; +} +impl UnderlierType for u8 {} +struct MyField; +impl Field for MyField {} +impl HasUnderlier for MyField { + type Underlier = u8; +} +impl PackScalar for u8 +where + F: Field, +{ + type Packed = PackedPrimitiveType; +} +pub struct PackedPrimitiveType(Scalar); +impl PackedField for PackedPrimitiveType +where + Scalar: Field, +{ + type Scalar = Scalar; +} + +pub trait PackedTransformationFactory {} +trait TaggedPackedTransformationFactory: PackedField {} +impl PackedTransformationFactory for PackedPrimitiveType where + Self: TaggedPackedTransformationFactory +{ +} +fn main() {} diff --git a/triagebot.toml b/triagebot.toml index 19b6fa9bc5289..d22723b42d10a 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -945,9 +945,11 @@ message = "`triagebot.toml` has been modified, there may have been changes to th cc = ["@davidtwco", "@wesleywiser"] [mentions."compiler/rustc_codegen_cranelift"] +message = "The Cranelift subtree was changed" cc = ["@bjorn3"] [mentions."compiler/rustc_codegen_gcc"] +message = "The GCC codegen subtree was changed" cc = ["@antoyo", "@GuillaumeGomez"] [mentions."compiler/rustc_const_eval/src/"] @@ -1149,6 +1151,7 @@ cc = [ cc = ["@ehuss"] [mentions."src/tools/clippy"] +message = "The Clippy subtree was changed" cc = ["@rust-lang/clippy"] [mentions."src/tools/compiletest"] @@ -1178,6 +1181,7 @@ this change to [rust-lang/rust-analyzer] instead. cc = ["@rust-lang/rust-analyzer"] [mentions."src/tools/rustfmt"] +message = "The Rustfmt subtree was changed" cc = ["@rust-lang/rustfmt"] [mentions."compiler/rustc_middle/src/mir/syntax.rs"]