From a183989e88f2154770de1afd860bffb387c4b525 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:15:43 +0000 Subject: [PATCH 01/10] Only check locally for reported errors --- compiler/rustc_hir_typeck/src/writeback.rs | 2 +- ...dings-in-pattern-with-ty-err-doesnt-ice.rs | 1 + ...s-in-pattern-with-ty-err-doesnt-ice.stderr | 15 +++++++++-- tests/ui/wf/conflicting-impls.rs | 2 ++ tests/ui/wf/conflicting-impls.stderr | 27 ++++++++++++++++--- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs index b67d29fce92..2714be1f9b4 100644 --- a/compiler/rustc_hir_typeck/src/writeback.rs +++ b/compiler/rustc_hir_typeck/src/writeback.rs @@ -793,7 +793,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> { } fn report_error(&self, p: impl Into>) -> ErrorGuaranteed { - if let Some(guar) = self.fcx.dcx().has_errors() { + if let Some(guar) = self.fcx.tainted_by_errors() { guar } else { self.fcx diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs index 196da30b864..d0bf5078165 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs @@ -4,4 +4,5 @@ fn main() { //~| ERROR cannot find type `T` in this scope //~| ERROR const and type arguments are not allowed on builtin type `str` //~| ERROR expected unit struct, unit variant or constant, found associated function `str< +//~| ERROR type annotations needed } diff --git a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr index 99f8dbd9a6c..fc431eb1412 100644 --- a/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr +++ b/tests/ui/sized/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.stderr @@ -32,7 +32,18 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a unit struct, unit variant or constant -error: aborting due to 4 previous errors +error[E0282]: type annotations needed + --> $DIR/ensure-overriding-bindings-in-pattern-with-ty-err-doesnt-ice.rs:2:31 + | +LL | let str::<{fn str() { let str::T>>::as_bytes; }}, T>::as_bytes; + | ^^^^^^^^^^^^^^^^^^ + | +help: consider giving this pattern a type + | +LL | let str::<{fn str() { let str::T>>::as_bytes: /* Type */; }}, T>::as_bytes; + | ++++++++++++ -Some errors have detailed explanations: E0109, E0412, E0533. +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0109, E0282, E0412, E0533. For more information about an error, try `rustc --explain E0109`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index 8054eb7c594..c387199a8bf 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,6 +5,7 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed loop {} } } @@ -13,6 +14,7 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { + //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index d31ae17aa8f..15222a9b2cc 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` - --> $DIR/conflicting-impls.rs:12:1 + --> $DIR/conflicting-impls.rs:13:1 | LL | impl TryFrom for u8 { | ----------------------- first implementation here @@ -7,6 +7,27 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error: aborting due to 1 previous error +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:7:53 + | +LL | fn try_from(_: Ty) -> Result { + | _____________________________________________________^ +LL | | +LL | | loop {} +LL | | } + | |_____^ cannot infer type for enum `Result` -For more information about this error, try `rustc --explain E0119`. +error[E0282]: type annotations needed + --> $DIR/conflicting-impls.rs:16:53 + | +LL | fn try_from(_: Ty) -> Result { + | _____________________________________________________^ +LL | | +LL | | loop {} +LL | | } + | |_____^ cannot infer type for enum `Result` + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0119, E0282. +For more information about an error, try `rustc --explain E0119`. From c20d909701379ac932a49a946fb478477d907041 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 18 Jun 2024 12:49:43 -0400 Subject: [PATCH 02/10] Make rustc_type_ir nightly again --- compiler/rustc_type_ir/Cargo.toml | 2 +- compiler/rustc_type_ir/src/binder.rs | 6 +++++- compiler/rustc_type_ir/src/data_structures.rs | 19 +++++++++++++++++++ compiler/rustc_type_ir/src/error.rs | 2 +- compiler/rustc_type_ir/src/fold.rs | 3 ++- compiler/rustc_type_ir/src/generic_arg.rs | 1 + compiler/rustc_type_ir/src/inherent.rs | 4 ++-- compiler/rustc_type_ir/src/lib.rs | 10 +--------- compiler/rustc_type_ir/src/opaque_ty.rs | 1 + compiler/rustc_type_ir/src/relate.rs | 9 +++++---- compiler/rustc_type_ir/src/visit.rs | 3 ++- 11 files changed, 40 insertions(+), 20 deletions(-) create mode 100644 compiler/rustc_type_ir/src/data_structures.rs diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 18a09067a2c..02d163531b4 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir" } +rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs index e50d59ba5f0..39ea61f0393 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -5,14 +5,16 @@ use std::ops::{ControlFlow, Deref}; #[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +#[cfg(feature = "nightly")] use rustc_serialize::Decodable; use tracing::debug; +use crate::data_structures::SsoHashSet; use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::inherent::*; use crate::lift::Lift; use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor}; -use crate::{self as ty, Interner, SsoHashSet}; +use crate::{self as ty, Interner}; /// Binder is a binder for higher-ranked lifetimes or types. It is part of the /// compiler's representation for things like `for<'a> Fn(&'a isize)` @@ -55,6 +57,7 @@ where } } +#[cfg(feature = "nightly")] macro_rules! impl_binder_encode_decode { ($($t:ty),+ $(,)?) => { $( @@ -82,6 +85,7 @@ macro_rules! impl_binder_encode_decode { } } +#[cfg(feature = "nightly")] impl_binder_encode_decode! { ty::FnSig, ty::TraitPredicate, diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs new file mode 100644 index 00000000000..86d7b31d216 --- /dev/null +++ b/compiler/rustc_type_ir/src/data_structures.rs @@ -0,0 +1,19 @@ +#[cfg(feature = "nightly")] +mod impl_ { + pub use rustc_data_structures::fx::FxHashMap as HashMap; + pub use rustc_data_structures::fx::FxHashSet as HashSet; + pub use rustc_data_structures::sso::SsoHashMap as SsoHashMap; + pub use rustc_data_structures::sso::SsoHashSet as SsoHashSet; + pub use rustc_data_structures::sync::Lrc; +} + +#[cfg(not(feature = "nightly"))] +mod impl_ { + pub use std::collections::HashMap; + pub use std::collections::HashSet; + pub use std::collections::HashMap as SsoHashMap; + pub use std::collections::HashSet as SsoHashSet; + pub use std::sync::Arc as Lrc; +} + +pub use impl_::*; \ No newline at end of file diff --git a/compiler/rustc_type_ir/src/error.rs b/compiler/rustc_type_ir/src/error.rs index 27623ea9cac..8b59e9a6f48 100644 --- a/compiler/rustc_type_ir/src/error.rs +++ b/compiler/rustc_type_ir/src/error.rs @@ -30,7 +30,7 @@ impl ExpectedFound { Debug(bound = "") )] #[derive(TypeVisitable_Generic)] -#[rustc_pass_by_value] +#[cfg_attr(feature = "nightly", rustc_pass_by_value)] pub enum TypeError { Mismatch, ConstnessMismatch(ExpectedFound), diff --git a/compiler/rustc_type_ir/src/fold.rs b/compiler/rustc_type_ir/src/fold.rs index ee3e5ce66d0..26e365f64fa 100644 --- a/compiler/rustc_type_ir/src/fold.rs +++ b/compiler/rustc_type_ir/src/fold.rs @@ -49,9 +49,10 @@ use rustc_index::{Idx, IndexVec}; use std::mem; use tracing::debug; +use crate::data_structures::Lrc; use crate::inherent::*; use crate::visit::{TypeVisitable, TypeVisitableExt as _}; -use crate::{self as ty, Interner, Lrc}; +use crate::{self as ty, Interner}; #[cfg(feature = "nightly")] type Never = !; diff --git a/compiler/rustc_type_ir/src/generic_arg.rs b/compiler/rustc_type_ir/src/generic_arg.rs index cc8c4444657..b158f0f5eee 100644 --- a/compiler/rustc_type_ir/src/generic_arg.rs +++ b/compiler/rustc_type_ir/src/generic_arg.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use crate::Interner; diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs index 64d3400976a..be6deee011b 100644 --- a/compiler/rustc_type_ir/src/inherent.rs +++ b/compiler/rustc_type_ir/src/inherent.rs @@ -8,8 +8,8 @@ use std::hash::Hash; use std::ops::Deref; use rustc_ast_ir::Mutability; -use rustc_data_structures::fx::FxHashSet; +use crate::data_structures::HashSet; use crate::fold::{TypeFoldable, TypeSuperFoldable}; use crate::relate::Relate; use crate::solve::{CacheData, CanonicalInput, QueryResult, Reveal}; @@ -530,7 +530,7 @@ pub trait EvaluationCache { proof_tree: Option, additional_depth: usize, encountered_overflow: bool, - cycle_participants: FxHashSet>, + cycle_participants: HashSet>, dep_node: I::DepNodeIndex, result: QueryResult, ); diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs index 130ea231bf7..9b8ca5efdda 100644 --- a/compiler/rustc_type_ir/src/lib.rs +++ b/compiler/rustc_type_ir/src/lib.rs @@ -7,27 +7,19 @@ #![cfg_attr(feature = "nightly", allow(internal_features))] // tidy-alphabetical-end -#[cfg(feature = "nightly")] extern crate self as rustc_type_ir; -#[cfg(feature = "nightly")] -use rustc_data_structures::sso::SsoHashSet; -#[cfg(feature = "nightly")] -use rustc_data_structures::sync::Lrc; #[cfg(feature = "nightly")] use rustc_macros::{Decodable, Encodable, HashStable_NoContext}; -#[cfg(not(feature = "nightly"))] -use std::collections::HashSet as SsoHashSet; use std::fmt; use std::hash::Hash; -#[cfg(not(feature = "nightly"))] -use std::sync::Arc as Lrc; // These modules are `pub` since they are not glob-imported. #[macro_use] pub mod visit; #[cfg(feature = "nightly")] pub mod codec; +pub mod data_structures; pub mod error; pub mod fold; pub mod inherent; diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index 60737066597..738350f1b34 100644 --- a/compiler/rustc_type_ir/src/opaque_ty.rs +++ b/compiler/rustc_type_ir/src/opaque_ty.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic}; diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs index 8a6ba87b60e..429bc3197d4 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -1,12 +1,13 @@ use std::iter; use rustc_ast_ir::Mutability; -use rustc_type_ir::error::{ExpectedFound, TypeError}; -use rustc_type_ir::fold::TypeFoldable; -use rustc_type_ir::inherent::*; -use rustc_type_ir::{self as ty, Interner}; use tracing::{debug, instrument}; +use crate::error::{ExpectedFound, TypeError}; +use crate::fold::TypeFoldable; +use crate::inherent::*; +use crate::{self as ty, Interner}; + pub type RelateResult = Result>; /// Extra information about why we ended up with a particular variance. diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs index 6880c7b8cef..473a0aa250f 100644 --- a/compiler/rustc_type_ir/src/visit.rs +++ b/compiler/rustc_type_ir/src/visit.rs @@ -47,8 +47,9 @@ use rustc_index::{Idx, IndexVec}; use std::fmt; use std::ops::ControlFlow; +use crate::data_structures::Lrc; use crate::inherent::*; -use crate::{self as ty, Interner, Lrc, TypeFlags}; +use crate::{self as ty, Interner, TypeFlags}; /// This trait is implemented for every type that can be visited, /// providing the skeleton of the traversal. From 9b0f9ef42eaef33282c05e698668aff0502885db Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 18 Jun 2024 13:21:48 -0400 Subject: [PATCH 03/10] Make rustc_next_trait_solver nightly again --- Cargo.lock | 1 + compiler/rustc_next_trait_solver/Cargo.toml | 2 +- compiler/rustc_next_trait_solver/src/lib.rs | 2 - .../src/solve/assembly/structural_traits.rs | 62 ++++++++++--------- .../src/solve/eval_ctxt/mod.rs | 41 +++++++----- .../src/solve/search_graph.rs | 17 +++-- .../src/solve/trait_goals.rs | 4 +- compiler/rustc_type_ir/Cargo.toml | 1 + compiler/rustc_type_ir/src/data_structures.rs | 18 ++++-- 9 files changed, 88 insertions(+), 60 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 14ee031ad04..2120b1ed50c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4913,6 +4913,7 @@ version = "0.0.0" dependencies = [ "bitflags 2.5.0", "derivative", + "indexmap", "rustc_ast_ir", "rustc_data_structures", "rustc_index", diff --git a/compiler/rustc_next_trait_solver/Cargo.toml b/compiler/rustc_next_trait_solver/Cargo.toml index 3a5f438b432..07cd4ae68d9 100644 --- a/compiler/rustc_next_trait_solver/Cargo.toml +++ b/compiler/rustc_next_trait_solver/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" -rustc_ast_ir = { path = "../rustc_ast_ir" } +rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs index 79c6925221e..ea3e18872fa 100644 --- a/compiler/rustc_next_trait_solver/src/lib.rs +++ b/compiler/rustc_next_trait_solver/src/lib.rs @@ -4,8 +4,6 @@ //! but were uplifted in the process of making the new trait solver generic. //! So if you got to this crate from the old solver, it's totally normal. -#![feature(let_chains)] - pub mod canonicalizer; pub mod infcx; pub mod resolve; diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs index 202af76565a..dbe3dfd4a1b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs @@ -2,7 +2,7 @@ //! traits, `Copy`/`Clone`. use rustc_ast_ir::{Movability, Mutability}; -use rustc_data_structures::fx::FxHashMap; +use rustc_type_ir::data_structures::HashMap; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; @@ -304,9 +304,10 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable, I: Interner> { ecx: &'a EvalCtxt<'a, Infcx>, param_env: I::ParamEnv, - mapping: FxHashMap>>, + mapping: HashMap>>, nested: Vec>, } @@ -725,24 +727,28 @@ impl, I: Interner> TypeFolder } fn fold_ty(&mut self, ty: I::Ty) -> I::Ty { - if let ty::Alias(ty::Projection, alias_ty) = ty.kind() - && let Some(replacement) = self.mapping.get(&alias_ty.def_id) - { - // We may have a case where our object type's projection bound is higher-ranked, - // but the where clauses we instantiated are not. We can solve this by instantiating - // the binder at the usage site. - let proj = self.ecx.instantiate_binder_with_infer(*replacement); - // FIXME: Technically this equate could be fallible... - self.nested.extend( - self.ecx - .eq_and_get_goals( - self.param_env, - alias_ty, - proj.projection_term.expect_ty(self.ecx.interner()), - ) - .expect("expected to be able to unify goal projection with dyn's projection"), - ); - proj.term.expect_ty() + if let ty::Alias(ty::Projection, alias_ty) = ty.kind() { + if let Some(replacement) = self.mapping.get(&alias_ty.def_id) { + // We may have a case where our object type's projection bound is higher-ranked, + // but the where clauses we instantiated are not. We can solve this by instantiating + // the binder at the usage site. + let proj = self.ecx.instantiate_binder_with_infer(*replacement); + // FIXME: Technically this equate could be fallible... + self.nested.extend( + self.ecx + .eq_and_get_goals( + self.param_env, + alias_ty, + proj.projection_term.expect_ty(self.ecx.interner()), + ) + .expect( + "expected to be able to unify goal projection with dyn's projection", + ), + ); + proj.term.expect_ty() + } else { + ty.super_fold_with(self) + } } else { ty.super_fold_with(self) } diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs index 485758b91a2..8548c647b6b 100644 --- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs @@ -1,7 +1,8 @@ use std::ops::ControlFlow; -use rustc_data_structures::stack::ensure_sufficient_stack; +#[cfg(feature = "nightly")] use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable}; +use rustc_type_ir::data_structures::ensure_sufficient_stack; use rustc_type_ir::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_type_ir::inherent::*; use rustc_type_ir::relate::Relate; @@ -88,7 +89,7 @@ where #[derive(derivative::Derivative)] #[derivative(Clone(bound = ""), Debug(bound = ""), Default(bound = ""))] #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)] -#[derive(TyDecodable, TyEncodable, HashStable_NoContext)] +#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))] // FIXME: This can be made crate-private once `EvalCtxt` also lives in this crate. pub struct NestedGoals { /// These normalizes-to goals are treated specially during the evaluation @@ -116,7 +117,8 @@ impl NestedGoals { } } -#[derive(PartialEq, Eq, Debug, Hash, HashStable_NoContext, Clone, Copy)] +#[derive(PartialEq, Eq, Debug, Hash, Clone, Copy)] +#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))] pub enum GenerateProofTree { Yes, No, @@ -689,14 +691,15 @@ where fn visit_ty(&mut self, t: I::Ty) -> Self::Result { match t.kind() { ty::Infer(ty::TyVar(vid)) => { - if let ty::TermKind::Ty(term) = self.term.kind() - && let ty::Infer(ty::TyVar(term_vid)) = term.kind() - && self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) - { - ControlFlow::Break(()) - } else { - self.check_nameable(self.infcx.universe_of_ty(vid).unwrap()) + if let ty::TermKind::Ty(term) = self.term.kind() { + if let ty::Infer(ty::TyVar(term_vid)) = term.kind() { + if self.infcx.root_ty_var(vid) == self.infcx.root_ty_var(term_vid) { + return ControlFlow::Break(()); + } + } } + + self.check_nameable(self.infcx.universe_of_ty(vid).unwrap()) } ty::Placeholder(p) => self.check_nameable(p.universe()), _ => { @@ -712,14 +715,18 @@ where fn visit_const(&mut self, c: I::Const) -> Self::Result { match c.kind() { ty::ConstKind::Infer(ty::InferConst::Var(vid)) => { - if let ty::TermKind::Const(term) = self.term.kind() - && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() - && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid) - { - ControlFlow::Break(()) - } else { - self.check_nameable(self.infcx.universe_of_ct(vid).unwrap()) + if let ty::TermKind::Const(term) = self.term.kind() { + if let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind() + { + if self.infcx.root_const_var(vid) + == self.infcx.root_const_var(term_vid) + { + return ControlFlow::Break(()); + } + } } + + self.check_nameable(self.infcx.universe_of_ct(vid).unwrap()) } ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe()), _ => { diff --git a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs index b923a121d81..fc78a864f81 100644 --- a/compiler/rustc_next_trait_solver/src/solve/search_graph.rs +++ b/compiler/rustc_next_trait_solver/src/solve/search_graph.rs @@ -1,7 +1,7 @@ use std::mem; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_index::{Idx, IndexVec}; +use rustc_type_ir::data_structures::{HashMap, HashSet}; use rustc_type_ir::inherent::*; use rustc_type_ir::Interner; use tracing::debug; @@ -17,6 +17,7 @@ pub struct SolverLimit(usize); rustc_index::newtype_index! { #[orderable] + #[gate_rustc_only] pub struct StackDepth {} } @@ -70,7 +71,7 @@ struct StackEntry { /// C :- D /// D :- C /// ``` - cycle_participants: FxHashSet>, + cycle_participants: HashSet>, /// Starts out as `None` and gets set when rerunning this /// goal in case we encounter a cycle. provisional_result: Option>, @@ -126,7 +127,7 @@ pub(super) struct SearchGraph { /// /// An element is *deeper* in the stack if its index is *lower*. stack: IndexVec>, - provisional_cache: FxHashMap, ProvisionalCacheEntry>, + provisional_cache: HashMap, ProvisionalCacheEntry>, } impl SearchGraph { @@ -227,13 +228,17 @@ impl SearchGraph { } fn clear_dependent_provisional_results( - provisional_cache: &mut FxHashMap, ProvisionalCacheEntry>, + provisional_cache: &mut HashMap, ProvisionalCacheEntry>, head: StackDepth, ) { #[allow(rustc::potential_query_instability)] provisional_cache.retain(|_, entry| { - entry.with_coinductive_stack.take_if(|p| p.head == head); - entry.with_inductive_stack.take_if(|p| p.head == head); + if entry.with_coinductive_stack.as_ref().is_some_and(|p| p.head == head) { + entry.with_coinductive_stack.take(); + } + if entry.with_inductive_stack.as_ref().is_some_and(|p| p.head == head) { + entry.with_inductive_stack.take(); + } !entry.is_empty() }); } diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index d1419bf5db9..c0353f92bf8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1,7 +1,7 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. use rustc_ast_ir::Movability; -use rustc_data_structures::fx::FxIndexSet; +use rustc_type_ir::data_structures::IndexSet; use rustc_type_ir::inherent::*; use rustc_type_ir::lang_items::TraitSolverLangItem; use rustc_type_ir::visit::TypeVisitableExt as _; @@ -821,7 +821,7 @@ where // We may upcast to auto traits that are either explicitly listed in // the object type's bounds, or implied by the principal trait ref's // supertraits. - let a_auto_traits: FxIndexSet = a_data + let a_auto_traits: IndexSet = a_data .auto_traits() .into_iter() .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| { diff --git a/compiler/rustc_type_ir/Cargo.toml b/compiler/rustc_type_ir/Cargo.toml index 02d163531b4..e4bf6069caf 100644 --- a/compiler/rustc_type_ir/Cargo.toml +++ b/compiler/rustc_type_ir/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" # tidy-alphabetical-start bitflags = "2.4.1" derivative = "2.2.0" +indexmap = "2.0.0" rustc_ast_ir = { path = "../rustc_ast_ir", default-features = false } rustc_data_structures = { path = "../rustc_data_structures", optional = true } rustc_index = { path = "../rustc_index", default-features = false } diff --git a/compiler/rustc_type_ir/src/data_structures.rs b/compiler/rustc_type_ir/src/data_structures.rs index 86d7b31d216..6d8ab61b722 100644 --- a/compiler/rustc_type_ir/src/data_structures.rs +++ b/compiler/rustc_type_ir/src/data_structures.rs @@ -2,18 +2,28 @@ mod impl_ { pub use rustc_data_structures::fx::FxHashMap as HashMap; pub use rustc_data_structures::fx::FxHashSet as HashSet; - pub use rustc_data_structures::sso::SsoHashMap as SsoHashMap; - pub use rustc_data_structures::sso::SsoHashSet as SsoHashSet; + pub use rustc_data_structures::fx::FxIndexMap as IndexMap; + pub use rustc_data_structures::fx::FxIndexSet as IndexSet; + pub use rustc_data_structures::sso::SsoHashMap; + pub use rustc_data_structures::sso::SsoHashSet; + pub use rustc_data_structures::stack::ensure_sufficient_stack; pub use rustc_data_structures::sync::Lrc; } #[cfg(not(feature = "nightly"))] mod impl_ { + pub use indexmap::IndexMap; + pub use indexmap::IndexSet; pub use std::collections::HashMap; - pub use std::collections::HashSet; pub use std::collections::HashMap as SsoHashMap; + pub use std::collections::HashSet; pub use std::collections::HashSet as SsoHashSet; pub use std::sync::Arc as Lrc; + + #[inline] + pub fn ensure_sufficient_stack(f: impl FnOnce() -> R) -> R { + f() + } } -pub use impl_::*; \ No newline at end of file +pub use impl_::*; From 3594a19f2ae792cf99a1a78a5454e52cfd7affde Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:34:26 +0000 Subject: [PATCH 04/10] Taint infcx when reporting errors --- .../error_reporting/type_err_ctxt_ext.rs | 23 ++--- tests/crashes/122044.rs | 38 -------- tests/crashes/123255.rs | 13 --- .../incremental/const-generics/issue-64087.rs | 2 + .../const-generics/defaults/doesnt_infer.rs | 1 + .../defaults/doesnt_infer.stderr | 31 ++++++- .../defaults/rp_impl_trait_fail.stderr | 9 +- .../generic_arg_infer/issue-91614.rs | 1 + .../generic_arg_infer/issue-91614.stderr | 28 +++--- .../issue-62504.full.stderr | 33 ++++++- .../issue-62504.min.stderr | 33 ++++++- .../generic_const_exprs/issue-62504.rs | 1 + .../object-safety-ok-infer-err.rs | 1 + .../object-safety-ok-infer-err.stderr | 27 +++++- .../infer/cannot-infer-const-args.stderr | 9 +- tests/ui/const-generics/infer/issue-77092.rs | 5 +- .../const-generics/infer/issue-77092.stderr | 29 +++++- .../const-generics/infer/method-chain.stderr | 9 +- .../infer/one-param-uninferred.stderr | 9 +- .../const-generics/infer/uninferred-consts.rs | 1 + .../infer/uninferred-consts.stderr | 27 +++++- .../const-generics/mistyped_const_in_pat.rs} | 4 +- .../mistyped_const_in_pat.stderr | 12 +++ ...ent_generics_of_encoding_impl_trait.stderr | 4 +- .../unify_with_nested_expr.stderr | 7 +- tests/ui/impl-trait/upvar_captures.rs | 16 ++++ tests/ui/impl-trait/upvar_captures.stderr | 14 +++ tests/ui/inference/issue-83606.stderr | 11 ++- tests/ui/issues/issue-98299.rs | 2 + tests/ui/issues/issue-98299.stderr | 55 ++++++++++- .../const_derives/derive-const-use.stderr | 34 ++++++- .../trait-default-body-stability.stderr | 92 ++++++++++++++++++- tests/ui/wf/conflicting-impls.rs | 2 - tests/ui/wf/conflicting-impls.stderr | 27 +----- .../normalization-of-unknown-type.rs} | 8 +- .../normalization-of-unknown-type.stderr | 9 ++ 36 files changed, 470 insertions(+), 157 deletions(-) delete mode 100644 tests/crashes/122044.rs delete mode 100644 tests/crashes/123255.rs rename tests/{crashes/125799.rs => ui/const-generics/mistyped_const_in_pat.rs} (64%) create mode 100644 tests/ui/const-generics/mistyped_const_in_pat.stderr create mode 100644 tests/ui/impl-trait/upvar_captures.rs create mode 100644 tests/ui/impl-trait/upvar_captures.stderr rename tests/{crashes/123276.rs => ui/where-clauses/normalization-of-unknown-type.rs} (59%) create mode 100644 tests/ui/where-clauses/normalization-of-unknown-type.stderr diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index e38f7951197..b5f2d34852f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -179,6 +179,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { for (error, suppressed) in iter::zip(&errors, &is_suppressed) { if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion { let guar = self.report_fulfillment_error(error); + self.infcx.set_tainted_by_errors(guar); reported = Some(guar); // We want to ignore desugarings here: spans are equivalent even // if one is the result of a desugaring and the other is not. @@ -2686,22 +2687,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - // Given some `ConstArgHasType(?x, usize)`, we should not emit an error such as - // "type annotations needed: cannot satisfy the constant `_` has type `usize`" - // Instead we should emit a normal error suggesting the user to turbofish the - // const parameter that is currently being inferred. Unfortunately we cannot - // nicely emit such an error so we delay an ICE incase nobody else reports it - // for us. - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => { - return self.tcx.sess.dcx().span_delayed_bug( + ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ..)) => self + .emit_inference_failure_err( + obligation.cause.body_id, span, - format!( - "`ambiguous ConstArgHasType({:?}, {:?}) unaccompanied by inference error`", - ct, ty - ), - ); - } - + ct.into(), + ErrorCode::E0284, + true, + ), ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) if term.is_infer() => { diff --git a/tests/crashes/122044.rs b/tests/crashes/122044.rs deleted file mode 100644 index 4c1d0de5719..00000000000 --- a/tests/crashes/122044.rs +++ /dev/null @@ -1,38 +0,0 @@ -//@ known-bug: #122044 -use std::hint::black_box; - -trait Func { - type Ret: Id; -} - -trait Id { - type Assoc; -} -impl Id for u32 {} -impl Id for u32 {} - -impl R, R: Id> Func for F { - type Ret = R; -} - -fn bar() -> impl Copy + Id { - 0u32 -} - -struct Foo { - _func: T, - value: Option<<::Ret as Id>::Assoc>, -} - -fn main() { - let mut fn_def = black_box(Foo { - _func: bar, - value: None, - }); - let fn_ptr = black_box(Foo { - _func: bar as fn() -> _, - value: None, - }); - - fn_def.value = fn_ptr.value; -} diff --git a/tests/crashes/123255.rs b/tests/crashes/123255.rs deleted file mode 100644 index a94a2a0422e..00000000000 --- a/tests/crashes/123255.rs +++ /dev/null @@ -1,13 +0,0 @@ -//@ known-bug: rust-lang/rust#123255 -//@ edition:2021 -#![crate_type = "lib"] - -pub fn a() {} - -mod handlers { - pub struct C(&()); - pub fn c() -> impl Fn() -> C { - let a1 = (); - || C((crate::a(), a1).into()) - } -} diff --git a/tests/incremental/const-generics/issue-64087.rs b/tests/incremental/const-generics/issue-64087.rs index 97f212b3fbb..787f2af8aa3 100644 --- a/tests/incremental/const-generics/issue-64087.rs +++ b/tests/incremental/const-generics/issue-64087.rs @@ -6,4 +6,6 @@ fn combinator() -> [T; S] {} fn main() { combinator().into_iter(); //[cfail1]~^ ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed + //[cfail1]~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.rs b/tests/ui/const-generics/defaults/doesnt_infer.rs index 016685eee9d..f62088210fe 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.rs +++ b/tests/ui/const-generics/defaults/doesnt_infer.rs @@ -12,4 +12,5 @@ fn main() { let foo = Foo::<1>::foo(); let foo = Foo::foo(); //~^ ERROR type annotations needed for `Foo<_>` + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index 1e779f75ce0..e099289827e 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed for `Foo<_>` +error[E0284]: type annotations needed for `Foo<_>` --> $DIR/doesnt_infer.rs:13:9 | LL | let foo = Foo::foo(); - | ^^^ + | ^^^ ---------- type must be known at this point | +note: required by a bound in `Foo::::foo` + --> $DIR/doesnt_infer.rs:5:6 + | +LL | impl Foo { + | ^^^^^^^^^^^^ required by this bound in `Foo::::foo` +LL | fn foo() -> Self { + | --- required by a bound in this associated function help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo = Foo::foo(); | ++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `Foo<_>` + --> $DIR/doesnt_infer.rs:13:9 + | +LL | let foo = Foo::foo(); + | ^^^ --- type must be known at this point + | +note: required by a bound in `Foo` + --> $DIR/doesnt_infer.rs:3:12 + | +LL | struct Foo; + | ^^^^^^^^^^^^^^^^ required by this bound in `Foo` +help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified + | +LL | let foo: Foo = Foo::foo(); + | ++++++++ -For more information about this error, try `rustc --explain E0282`. +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 4ed1c0ded9f..d91e717b3eb 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -31,12 +31,17 @@ LL | 1_u64 | = help: the trait `Traitor<1, 2>` is implemented for `u64` -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/rp_impl_trait_fail.rs:28:5 | LL | uwu(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `uwu` | +note: required by a bound in `uwu` + --> $DIR/rp_impl_trait_fail.rs:16:8 + | +LL | fn uwu() -> impl Traitor { + | ^^^^^^^^^^^ required by this bound in `uwu` help: consider specifying the generic argument | LL | uwu::(); @@ -44,5 +49,5 @@ LL | uwu::(); error: aborting due to 4 previous errors -Some errors have detailed explanations: E0277, E0282. +Some errors have detailed explanations: E0277, E0284. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs index cfbc5faecd9..a386b1e5c2b 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.rs +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.rs @@ -5,4 +5,5 @@ use std::simd::Mask; fn main() { let y = Mask::<_, _>::splat(false); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index 563406ad5ea..b6982e05b88 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -1,23 +1,29 @@ -error[E0283]: type annotations needed for `Mask<_, _>` +error[E0284]: type annotations needed for `Mask<_, _>` --> $DIR/issue-91614.rs:6:9 | LL | let y = Mask::<_, _>::splat(false); | ^ -------------------------- type must be known at this point | - = note: cannot satisfy `_: MaskElement` - = help: the following types implement trait `MaskElement`: - i16 - i32 - i64 - i8 - isize note: required by a bound in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL -help: consider giving `y` an explicit type, where the type for type parameter `T` is specified +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | LL | let y: Mask = Mask::<_, _>::splat(false); | ++++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `Mask<_, _>` + --> $DIR/issue-91614.rs:6:9 + | +LL | let y = Mask::<_, _>::splat(false); + | ^ ------------ type must be known at this point + | +note: required by a bound in `Mask` + --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL +help: consider giving `y` an explicit type, where the value of const parameter `N` is specified + | +LL | let y: Mask = Mask::<_, _>::splat(false); + | ++++++++++++ -For more information about this error, try `rustc --explain E0283`. +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 5cda4681b5c..27411646cb7 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -18,18 +18,41 @@ help: try adding a `where` bound LL | pub const fn new() -> Self where [(); Self::SIZE]: { | +++++++++++++++++++++++ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a bound in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a bound in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index beb159779ff..036b9001c03 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -22,18 +22,41 @@ note: tuple struct defined here LL | struct ArrayHolder([u32; X]); | ^^^^^^^^^^^ -error[E0282]: type annotations needed for `ArrayHolder<_>` +error[E0284]: type annotations needed for `ArrayHolder<_>` --> $DIR/issue-62504.rs:26:9 | LL | let mut array = ArrayHolder::new(); - | ^^^^^^^^^ + | ^^^^^^^^^ ------------------ type must be known at this point | +note: required by a bound in `ArrayHolder::::new` + --> $DIR/issue-62504.rs:16:6 + | +LL | impl ArrayHolder { + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` +LL | pub const fn new() -> Self { + | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); | ++++++++++++++++ -error: aborting due to 3 previous errors +error[E0284]: type annotations needed for `ArrayHolder<_>` + --> $DIR/issue-62504.rs:26:9 + | +LL | let mut array = ArrayHolder::new(); + | ^^^^^^^^^ ----------- type must be known at this point + | +note: required by a bound in `ArrayHolder` + --> $DIR/issue-62504.rs:14:20 + | +LL | struct ArrayHolder([u32; X]); + | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` +help: consider giving `array` an explicit type, where the value of const parameter `X` is specified + | +LL | let mut array: ArrayHolder = ArrayHolder::new(); + | ++++++++++++++++ -Some errors have detailed explanations: E0282, E0308. -For more information about an error, try `rustc --explain E0282`. +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0284, E0308. +For more information about an error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs index b6a6a277843..f021e103614 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.rs @@ -25,4 +25,5 @@ impl ArrayHolder { fn main() { let mut array = ArrayHolder::new(); //~^ ERROR: type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs index 79e9834b54e..298cfb512e4 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.rs @@ -18,4 +18,5 @@ fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { fn main() { use_dyn(&()); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr index e800c5d059f..0c290448fc5 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr @@ -5,15 +5,36 @@ LL | use_dyn(&()); | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn` | note: required by a bound in `use_dyn` - --> $DIR/object-safety-ok-infer-err.rs:14:55 + --> $DIR/object-safety-ok-infer-err.rs:14:12 | LL | fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { - | ^^^^^ required by this bound in `use_dyn` + | ^^^^^^^^^^^^^^ required by this bound in `use_dyn` help: consider specifying the generic argument | LL | use_dyn::(&()); | +++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/object-safety-ok-infer-err.rs:19:5 + | +LL | use_dyn(&()); + | ^^^^^^^ --- type must be known at this point + | | + | cannot infer the value of the const parameter `N` declared on the function `use_dyn` + | +note: required for `()` to implement `Foo<_>` + --> $DIR/object-safety-ok-infer-err.rs:8:22 + | +LL | impl Foo for () { + | -------------- ^^^^^^ ^^ + | | + | unsatisfied trait bound introduced here + = note: required for the cast from `&()` to `&dyn Foo<_>` +help: consider specifying the generic argument + | +LL | use_dyn::(&()); + | +++++ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr index e3caefef10f..2180ba2f809 100644 --- a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr +++ b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/cannot-infer-const-args.rs:6:5 | LL | foo(); | ^^^ cannot infer the value of the const parameter `X` declared on the function `foo` | +note: required by a bound in `foo` + --> $DIR/cannot-infer-const-args.rs:1:8 + | +LL | fn foo() -> usize { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider specifying the generic argument | LL | foo::(); @@ -11,4 +16,4 @@ LL | foo::(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/issue-77092.rs b/tests/ui/const-generics/infer/issue-77092.rs index fcf7d3282b4..47c594e5b11 100644 --- a/tests/ui/const-generics/infer/issue-77092.rs +++ b/tests/ui/const-generics/infer/issue-77092.rs @@ -1,14 +1,15 @@ use std::convert::TryInto; fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { - (&mut data[start .. start + N]).try_into().unwrap() + (&mut data[start..start + N]).try_into().unwrap() } fn main() { let mut arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; - for i in 1 .. 4 { + for i in 1..4 { println!("{:?}", take_array_from_mut(&mut arr, i)); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } } diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 5b411269862..1579d217c2d 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -1,14 +1,37 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/issue-77092.rs:11:26 | LL | println!("{:?}", take_array_from_mut(&mut arr, i)); | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` | +note: required by a bound in `take_array_from_mut` + --> $DIR/issue-77092.rs:3:27 + | +LL | fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { + | ^^^^^^^^^^^^^^ required by this bound in `take_array_from_mut` help: consider specifying the generic arguments | LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); | ++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/issue-77092.rs:11:26 + | +LL | println!("{:?}", take_array_from_mut(&mut arr, i)); + | ---- ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` + | | + | type must be known at this point + | + = note: required for `[i32; _]` to implement `Debug` + = note: 1 redundant requirement hidden + = note: required for `&mut [i32; _]` to implement `Debug` +note: required by a bound in `core::fmt::rt::Argument::<'a>::new_debug` + --> $SRC_DIR/core/src/fmt/rt.rs:LL:COL +help: consider specifying the generic arguments + | +LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); + | ++++++++++ -For more information about this error, try `rustc --explain E0282`. +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index 2def9e85ab7..08c664e82f7 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/method-chain.rs:15:33 | LL | Foo.bar().bar().bar().bar().baz(); | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | +note: required by a bound in `Foo::baz` + --> $DIR/method-chain.rs:8:12 + | +LL | fn baz(self) -> Foo { + | ^^^^^^^^^^^^^^ required by this bound in `Foo::baz` help: consider specifying the generic argument | LL | Foo.bar().bar().bar().bar().baz::(); @@ -11,4 +16,4 @@ LL | Foo.bar().bar().bar().bar().baz::(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/one-param-uninferred.stderr b/tests/ui/const-generics/infer/one-param-uninferred.stderr index 3e33fec9cef..68bec93e826 100644 --- a/tests/ui/const-generics/infer/one-param-uninferred.stderr +++ b/tests/ui/const-generics/infer/one-param-uninferred.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/one-param-uninferred.rs:9:23 | LL | let _: [u8; 17] = foo(); | ^^^ cannot infer the value of the const parameter `M` declared on the function `foo` | +note: required by a bound in `foo` + --> $DIR/one-param-uninferred.rs:2:24 + | +LL | fn foo() -> [u8; N] { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider specifying the generic arguments | LL | let _: [u8; 17] = foo::<17, M>(); @@ -11,4 +16,4 @@ LL | let _: [u8; 17] = foo::<17, M>(); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/const-generics/infer/uninferred-consts.rs b/tests/ui/const-generics/infer/uninferred-consts.rs index 657f4b51304..552e2a15c23 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.rs +++ b/tests/ui/const-generics/infer/uninferred-consts.rs @@ -8,4 +8,5 @@ impl Foo { fn main() { Foo.foo(); //~^ ERROR type annotations needed + //~| ERROR type annotations needed } diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index 0ec6ac9c22e..e8ad336af70 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -1,14 +1,35 @@ -error[E0282]: type annotations needed +error[E0284]: type annotations needed --> $DIR/uninferred-consts.rs:9:9 | LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | +note: required by a bound in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:12 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); | ++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed + --> $DIR/uninferred-consts.rs:9:9 + | +LL | Foo.foo(); + | ^^^ cannot infer the value of the const parameter `B` declared on the method `foo` + | +note: required by a bound in `Foo::foo` + --> $DIR/uninferred-consts.rs:6:28 + | +LL | fn foo(self) {} + | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` +help: consider specifying the generic arguments + | +LL | Foo.foo::(); + | ++++++++ -For more information about this error, try `rustc --explain E0282`. +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/crashes/125799.rs b/tests/ui/const-generics/mistyped_const_in_pat.rs similarity index 64% rename from tests/crashes/125799.rs rename to tests/ui/const-generics/mistyped_const_in_pat.rs index 62d5438b4e4..6f1dd52872f 100644 --- a/tests/crashes/125799.rs +++ b/tests/ui/const-generics/mistyped_const_in_pat.rs @@ -1,4 +1,5 @@ -//@ known-bug: rust-lang/rust#125799 +//! Used to ICE rust-lang/rust#125799 due to `isize` != `()` +//! not being detected early due to the conflicting impls. //@ only-x86_64 trait Trait { @@ -10,6 +11,7 @@ impl Trait for Vec { } impl Trait for Vec {} +//~^ ERROR: conflicting implementations const BAR: as Trait>::Assoc = 3; diff --git a/tests/ui/const-generics/mistyped_const_in_pat.stderr b/tests/ui/const-generics/mistyped_const_in_pat.stderr new file mode 100644 index 00000000000..de7516fa37f --- /dev/null +++ b/tests/ui/const-generics/mistyped_const_in_pat.stderr @@ -0,0 +1,12 @@ +error[E0119]: conflicting implementations of trait `Trait` for type `Vec` + --> $DIR/mistyped_const_in_pat.rs:13:1 + | +LL | impl Trait for Vec { + | --------------------------- first implementation here +... +LL | impl Trait for Vec {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Vec` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr index 5bef6f3c795..cb8f56c6bb0 100644 --- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr +++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr @@ -5,10 +5,10 @@ LL | generics_of_parent_impl_trait::foo([()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo` | note: required by a bound in `foo` - --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:48 + --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:12 | LL | pub fn foo(foo: impl Into<[(); N + 1]>) { - | ^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this bound in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index e050254a3e9..87610db67ae 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -5,13 +5,10 @@ LL | bar(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `bar` | note: required by a bound in `bar` - --> $DIR/unify_with_nested_expr.rs:14:10 + --> $DIR/unify_with_nested_expr.rs:12:8 | LL | fn bar() - | --- required by a bound in this function -LL | where -LL | [(); N + 1]:, - | ^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^^^^ required by this bound in `bar` help: consider specifying the generic argument | LL | bar::(); diff --git a/tests/ui/impl-trait/upvar_captures.rs b/tests/ui/impl-trait/upvar_captures.rs new file mode 100644 index 00000000000..61e3cda66f5 --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.rs @@ -0,0 +1,16 @@ +//! This test used to ICE: rust-lang/rust#123255 +//! Because the errors on `C` were ignored when trying +//! to compute the MIR of the closure, which thus ended +//! up with broken upvars. +//@ edition:2021 +#![crate_type = "lib"] + +pub fn a() {} + +mod handlers { + pub struct C(&()); //~ ERROR missing lifetime specifier + pub fn c() -> impl Fn() -> C { + let a1 = (); + || C((crate::a(), a1).into()) + } +} diff --git a/tests/ui/impl-trait/upvar_captures.stderr b/tests/ui/impl-trait/upvar_captures.stderr new file mode 100644 index 00000000000..b87a16606cc --- /dev/null +++ b/tests/ui/impl-trait/upvar_captures.stderr @@ -0,0 +1,14 @@ +error[E0106]: missing lifetime specifier + --> $DIR/upvar_captures.rs:11:18 + | +LL | pub struct C(&()); + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | pub struct C<'a>(&'a ()); + | ++++ ++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 8e6ff6d568d..2d74024bb28 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -1,9 +1,14 @@ -error[E0282]: type annotations needed for `[usize; _]` +error[E0284]: type annotations needed for `[usize; _]` --> $DIR/issue-83606.rs:8:9 | LL | let _ = foo("foo"); - | ^ + | ^ ---------- type must be known at this point | +note: required by a bound in `foo` + --> $DIR/issue-83606.rs:3:8 + | +LL | fn foo(_: impl std::fmt::Display) -> [usize; N] { + | ^^^^^^^^^^^^^^ required by this bound in `foo` help: consider giving this pattern a type, where the value of const parameter `N` is specified | LL | let _: [usize; N] = foo("foo"); @@ -11,4 +16,4 @@ LL | let _: [usize; N] = foo("foo"); error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0282`. +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/issues/issue-98299.rs b/tests/ui/issues/issue-98299.rs index 63c058f91fc..ba63d963475 100644 --- a/tests/ui/issues/issue-98299.rs +++ b/tests/ui/issues/issue-98299.rs @@ -3,6 +3,8 @@ use std::convert::TryFrom; pub fn test_usage(p: ()) { SmallCString::try_from(p).map(|cstr| cstr); //~^ ERROR: type annotations needed + //~| ERROR: type annotations needed + //~| ERROR: type annotations needed } pub struct SmallCString {} diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index becf16d1db9..f4b40cbbd19 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -1,14 +1,61 @@ -error[E0282]: type annotations needed for `SmallCString<_>` +error[E0284]: type annotations needed for `SmallCString<_>` --> $DIR/issue-98299.rs:4:36 | LL | SmallCString::try_from(p).map(|cstr| cstr); - | ^^^^ + | ------------ ^^^^ + | | + | type must be known at this point | +note: required by a bound in `SmallCString` + --> $DIR/issue-98299.rs:10:25 + | +LL | pub struct SmallCString {} + | ^^^^^^^^^^^^^^ required by this bound in `SmallCString` help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified | LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); | +++++++++++++++++ -error: aborting due to 1 previous error +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------ ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl TryFrom<()> for SmallCString { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); + | +++++++++++++++++ -For more information about this error, try `rustc --explain E0282`. +error[E0284]: type annotations needed for `SmallCString<_>` + --> $DIR/issue-98299.rs:4:36 + | +LL | SmallCString::try_from(p).map(|cstr| cstr); + | ------------------------- ^^^^ + | | + | type must be known at this point + | +note: required for `SmallCString<_>` to implement `TryFrom<()>` + --> $DIR/issue-98299.rs:12:22 + | +LL | impl TryFrom<()> for SmallCString { + | -------------- ^^^^^^^^^^^ ^^^^^^^^^^^^^^^ + | | + | unsatisfied trait bound introduced here +help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified + | +LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); + | +++++++++++++++++ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0284`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr index e45c1a1f46f..86dfc521fea 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const_derives/derive-const-use.stderr @@ -37,6 +37,19 @@ error[E0207]: the const parameter `host` is not constrained by the impl trait, s = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:18:35 + | +LL | const _: () = assert!(S((), A) == S::default()); + | ^^^^^^^^^^^^ cannot infer the value of the constant `_` + | +note: required for `S` to implement `Default` + --> $DIR/derive-const-use.rs:15:16 + | +LL | #[derive_const(Default, PartialEq)] + | ^^^^^^^ unsatisfied trait bound introduced in this `derive` macro + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0308]: mismatched types --> $DIR/derive-const-use.rs:16:14 | @@ -49,7 +62,24 @@ LL | pub struct S((), A); found constant `true` = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 6 previous errors +error[E0284]: type annotations needed + --> $DIR/derive-const-use.rs:16:18 + | +LL | #[derive_const(Default, PartialEq)] + | ------- in this derive macro expansion +LL | pub struct S((), A); + | ^ cannot infer the value of the constant `_` + | +note: required for `A` to implement `Default` + --> $DIR/derive-const-use.rs:7:12 + | +LL | impl const Default for A { + | ----- ^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -Some errors have detailed explanations: E0207, E0308, E0635. +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0207, E0284, E0308, E0635. For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr index 62c4bc3b7ae..b58af6bb9d0 100644 --- a/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/trait-default-body-stability.stderr @@ -34,6 +34,94 @@ LL | impl const FromResidual for T { = note: expressions using a const parameter must map each value to a distinct output value = note: proving the result of expressions other than the parameter are unique is not supported -error: aborting due to 4 previous errors +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:33:6 + | +LL | impl const FromResidual for T { + | ^^^^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here -For more information about this error, try `rustc --explain E0207`. +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `FromResidual` + --> $DIR/trait-default-body-stability.rs:33:12 + | +LL | impl const FromResidual for T { + | ----- ^^^^^^^^^^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0284]: type annotations needed + --> $DIR/trait-default-body-stability.rs:44:9 + | +LL | T? + | ^^ cannot infer the value of the constant `_` + | +note: required for `T` to implement `Try` + --> $DIR/trait-default-body-stability.rs:18:12 + | +LL | impl const Try for T { + | ----- ^^^ ^ + | | + | unsatisfied trait bound introduced here + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 10 previous errors + +Some errors have detailed explanations: E0207, E0284. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/wf/conflicting-impls.rs b/tests/ui/wf/conflicting-impls.rs index c387199a8bf..8054eb7c594 100644 --- a/tests/ui/wf/conflicting-impls.rs +++ b/tests/ui/wf/conflicting-impls.rs @@ -5,7 +5,6 @@ struct Ty; impl TryFrom for u8 { type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } @@ -14,7 +13,6 @@ impl TryFrom for u8 { //~^ ERROR conflicting implementations of trait type Error = Ty; fn try_from(_: Ty) -> Result { - //~^ ERROR type annotations needed loop {} } } diff --git a/tests/ui/wf/conflicting-impls.stderr b/tests/ui/wf/conflicting-impls.stderr index 15222a9b2cc..d31ae17aa8f 100644 --- a/tests/ui/wf/conflicting-impls.stderr +++ b/tests/ui/wf/conflicting-impls.stderr @@ -1,5 +1,5 @@ error[E0119]: conflicting implementations of trait `TryFrom` for type `u8` - --> $DIR/conflicting-impls.rs:13:1 + --> $DIR/conflicting-impls.rs:12:1 | LL | impl TryFrom for u8 { | ----------------------- first implementation here @@ -7,27 +7,6 @@ LL | impl TryFrom for u8 { LL | impl TryFrom for u8 { | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u8` -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:7:53 - | -LL | fn try_from(_: Ty) -> Result { - | _____________________________________________________^ -LL | | -LL | | loop {} -LL | | } - | |_____^ cannot infer type for enum `Result` +error: aborting due to 1 previous error -error[E0282]: type annotations needed - --> $DIR/conflicting-impls.rs:16:53 - | -LL | fn try_from(_: Ty) -> Result { - | _____________________________________________________^ -LL | | -LL | | loop {} -LL | | } - | |_____^ cannot infer type for enum `Result` - -error: aborting due to 3 previous errors - -Some errors have detailed explanations: E0119, E0282. -For more information about an error, try `rustc --explain E0119`. +For more information about this error, try `rustc --explain E0119`. diff --git a/tests/crashes/123276.rs b/tests/ui/where-clauses/normalization-of-unknown-type.rs similarity index 59% rename from tests/crashes/123276.rs rename to tests/ui/where-clauses/normalization-of-unknown-type.rs index d2246f59583..c3ff7ed125a 100644 --- a/tests/crashes/123276.rs +++ b/tests/ui/where-clauses/normalization-of-unknown-type.rs @@ -1,4 +1,6 @@ -//@ known-bug: rust-lang/rust#123276 +//! This test used to ICE: rust-lang/rust#123276 because we did +//! not taint when failing to find the `Foo` type and then tried +//! to normalize it. //@ edition:2021 async fn create_task() { @@ -19,7 +21,9 @@ struct AndThen; impl Filter for AndThen where - Foo: Filter, + Foo: Filter, //~ ERROR: cannot find type `Foo` { type Future = (); } + +fn main() {} diff --git a/tests/ui/where-clauses/normalization-of-unknown-type.stderr b/tests/ui/where-clauses/normalization-of-unknown-type.stderr new file mode 100644 index 00000000000..11b83224352 --- /dev/null +++ b/tests/ui/where-clauses/normalization-of-unknown-type.stderr @@ -0,0 +1,9 @@ +error[E0412]: cannot find type `Foo` in this scope + --> $DIR/normalization-of-unknown-type.rs:24:5 + | +LL | Foo: Filter, + | ^^^ not found in this scope + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0412`. From 1cb75dc4a92ef131b2b88bd9faeaa1d39c3d5f4e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 17 Jun 2024 08:53:45 +0000 Subject: [PATCH 05/10] Remove a hack that isn't needed anymore --- compiler/rustc_hir_analysis/src/check/wfcheck.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index b206d8046ee..a188c1b12ae 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -119,16 +119,7 @@ where let errors = wfcx.select_all_or_error(); if !errors.is_empty() { - let err = infcx.err_ctxt().report_fulfillment_errors(errors); - if tcx.dcx().has_errors().is_some() { - return Err(err); - } else { - // HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs - // causes an delayed bug during normalization, without reporting an error, so we need - // to act as if no error happened, in order to let our callers continue and report an - // error later in check_impl_items_against_trait. - return Ok(()); - } + return Err(infcx.err_ctxt().report_fulfillment_errors(errors)); } debug!(?assumed_wf_types); From e4c9a8cf9b2e2a17c589dadcaffae0b9e6b62cbc Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 19 Jun 2024 08:25:58 +0000 Subject: [PATCH 06/10] Const generic parameters aren't bounds, even if we end up erroring because of the bound that binds the parameter's type --- .../src/traits/error_reporting/suggestions.rs | 188 ++++++++++-------- .../defaults/doesnt_infer.stderr | 8 +- .../defaults/rp_impl_trait_fail.stderr | 4 +- .../generic_arg_infer/issue-91614.stderr | 4 +- .../issue-62504.full.stderr | 8 +- .../issue-62504.min.stderr | 8 +- .../object-safety-ok-infer-err.stderr | 4 +- .../infer/cannot-infer-const-args.stderr | 4 +- .../const-generics/infer/issue-77092.stderr | 4 +- .../const-generics/infer/method-chain.stderr | 4 +- .../infer/one-param-uninferred.stderr | 4 +- .../infer/uninferred-consts.stderr | 8 +- ...ent_generics_of_encoding_impl_trait.stderr | 4 +- tests/ui/const-generics/type_mismatch.stderr | 4 +- .../unify_with_nested_expr.stderr | 4 +- tests/ui/inference/issue-83606.stderr | 4 +- tests/ui/issues/issue-98299.stderr | 4 +- ...oj-ty-as-type-of-const-issue-125757.stderr | 4 +- .../ui/transmutability/issue-101739-1.stderr | 2 +- 19 files changed, 146 insertions(+), 128 deletions(-) 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 f632f1ad4f2..8f8ef4b7acb 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2776,97 +2776,115 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let mut this = "this bound"; let mut note = None; let mut help = None; - if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() - && let ty::ClauseKind::Trait(trait_pred) = clause - { - let def_id = trait_pred.def_id(); - let visible_item = if let Some(local) = def_id.as_local() { - // Check for local traits being reachable. - let vis = &tcx.resolutions(()).effective_visibilities; - // Account for non-`pub` traits in the root of the local crate. - let is_locally_reachable = tcx.parent(def_id).is_crate_root(); - vis.is_reachable(local) || is_locally_reachable - } else { - // Check for foreign traits being reachable. - tcx.visible_parent_map(()).get(&def_id).is_some() - }; - if tcx.is_lang_item(def_id, LangItem::Sized) { - // Check if this is an implicit bound, even in foreign crates. - if tcx - .generics_of(item_def_id) - .own_params - .iter() - .any(|param| tcx.def_span(param.def_id) == span) - { - a = "an implicit `Sized`"; - this = "the implicit `Sized` requirement on this type parameter"; - } - if let Some(hir::Node::TraitItem(hir::TraitItem { - generics, - kind: hir::TraitItemKind::Type(bounds, None), - .. - })) = tcx.hir().get_if_local(item_def_id) - // Do not suggest relaxing if there is an explicit `Sized` obligation. - && !bounds.iter() - .filter_map(|bound| bound.trait_ref()) - .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) - { - let (span, separator) = if let [.., last] = bounds { - (last.span().shrink_to_hi(), " +") + if let ty::PredicateKind::Clause(clause) = predicate.kind().skip_binder() { + match clause { + ty::ClauseKind::Trait(trait_pred) => { + let def_id = trait_pred.def_id(); + let visible_item = if let Some(local) = def_id.as_local() { + // Check for local traits being reachable. + let vis = &tcx.resolutions(()).effective_visibilities; + // Account for non-`pub` traits in the root of the local crate. + let is_locally_reachable = tcx.parent(def_id).is_crate_root(); + vis.is_reachable(local) || is_locally_reachable } else { - (generics.span.shrink_to_hi(), ":") + // Check for foreign traits being reachable. + tcx.visible_parent_map(()).get(&def_id).is_some() }; - err.span_suggestion_verbose( - span, - "consider relaxing the implicit `Sized` restriction", - format!("{separator} ?Sized"), - Applicability::MachineApplicable, - ); + if tcx.is_lang_item(def_id, LangItem::Sized) { + // Check if this is an implicit bound, even in foreign crates. + if tcx + .generics_of(item_def_id) + .own_params + .iter() + .any(|param| tcx.def_span(param.def_id) == span) + { + a = "an implicit `Sized`"; + this = + "the implicit `Sized` requirement on this type parameter"; + } + if let Some(hir::Node::TraitItem(hir::TraitItem { + generics, + kind: hir::TraitItemKind::Type(bounds, None), + .. + })) = tcx.hir().get_if_local(item_def_id) + // Do not suggest relaxing if there is an explicit `Sized` obligation. + && !bounds.iter() + .filter_map(|bound| bound.trait_ref()) + .any(|tr| tr.trait_def_id() == tcx.lang_items().sized_trait()) + { + let (span, separator) = if let [.., last] = bounds { + (last.span().shrink_to_hi(), " +") + } else { + (generics.span.shrink_to_hi(), ":") + }; + err.span_suggestion_verbose( + span, + "consider relaxing the implicit `Sized` restriction", + format!("{separator} ?Sized"), + Applicability::MachineApplicable, + ); + } + } + if let DefKind::Trait = tcx.def_kind(item_def_id) + && !visible_item + { + note = Some(format!( + "`{short_item_name}` is a \"sealed trait\", because to implement it \ + you also need to implement `{}`, which is not accessible; this is \ + usually done to force you to use one of the provided types that \ + already implement it", + with_no_trimmed_paths!(tcx.def_path_str(def_id)), + )); + let impls_of = tcx.trait_impls_of(def_id); + let impls = impls_of + .non_blanket_impls() + .values() + .flatten() + .chain(impls_of.blanket_impls().iter()) + .collect::>(); + if !impls.is_empty() { + let len = impls.len(); + let mut types = impls + .iter() + .map(|t| { + with_no_trimmed_paths!(format!( + " {}", + tcx.type_of(*t).instantiate_identity(), + )) + }) + .collect::>(); + let post = if types.len() > 9 { + types.truncate(8); + format!("\nand {} others", len - 8) + } else { + String::new() + }; + help = Some(format!( + "the following type{} implement{} the trait:\n{}{post}", + pluralize!(len), + if len == 1 { "s" } else { "" }, + types.join("\n"), + )); + } + } } - } - if let DefKind::Trait = tcx.def_kind(item_def_id) - && !visible_item - { - note = Some(format!( - "`{short_item_name}` is a \"sealed trait\", because to implement it \ - you also need to implement `{}`, which is not accessible; this is \ - usually done to force you to use one of the provided types that \ - already implement it", - with_no_trimmed_paths!(tcx.def_path_str(def_id)), - )); - let impls_of = tcx.trait_impls_of(def_id); - let impls = impls_of - .non_blanket_impls() - .values() - .flatten() - .chain(impls_of.blanket_impls().iter()) - .collect::>(); - if !impls.is_empty() { - let len = impls.len(); - let mut types = impls - .iter() - .map(|t| { - with_no_trimmed_paths!(format!( - " {}", - tcx.type_of(*t).instantiate_identity(), - )) - }) - .collect::>(); - let post = if types.len() > 9 { - types.truncate(8); - format!("\nand {} others", len - 8) + ty::ClauseKind::ConstArgHasType(..) => { + let descr = + format!("required by a const generic parameter in `{item_name}`"); + if span.is_visible(sm) { + let msg = format!( + "required by this const generic parameter in `{short_item_name}`" + ); + multispan.push_span_label(span, msg); + err.span_note(multispan, descr); } else { - String::new() - }; - help = Some(format!( - "the following type{} implement{} the trait:\n{}{post}", - pluralize!(len), - if len == 1 { "s" } else { "" }, - types.join("\n"), - )); + err.span_note(tcx.def_span(item_def_id), descr); + } + return; } + _ => (), } - }; + } let descr = format!("required by {a} bound in `{item_name}`"); if span.is_visible(sm) { let msg = format!("required by {this} in `{short_item_name}`"); diff --git a/tests/ui/const-generics/defaults/doesnt_infer.stderr b/tests/ui/const-generics/defaults/doesnt_infer.stderr index e099289827e..c17f57f36bc 100644 --- a/tests/ui/const-generics/defaults/doesnt_infer.stderr +++ b/tests/ui/const-generics/defaults/doesnt_infer.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed for `Foo<_>` LL | let foo = Foo::foo(); | ^^^ ---------- type must be known at this point | -note: required by a bound in `Foo::::foo` +note: required by a const generic parameter in `Foo::::foo` --> $DIR/doesnt_infer.rs:5:6 | LL | impl Foo { - | ^^^^^^^^^^^^ required by this bound in `Foo::::foo` + | ^^^^^^^^^^^^ required by this const generic parameter in `Foo::::foo` LL | fn foo() -> Self { | --- required by a bound in this associated function help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified @@ -22,11 +22,11 @@ error[E0284]: type annotations needed for `Foo<_>` LL | let foo = Foo::foo(); | ^^^ --- type must be known at this point | -note: required by a bound in `Foo` +note: required by a const generic parameter in `Foo` --> $DIR/doesnt_infer.rs:3:12 | LL | struct Foo; - | ^^^^^^^^^^^^^^^^ required by this bound in `Foo` + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` help: consider giving `foo` an explicit type, where the value of const parameter `N` is specified | LL | let foo: Foo = Foo::foo(); diff --git a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr index d91e717b3eb..45be3126e3b 100644 --- a/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/tests/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -37,11 +37,11 @@ error[E0284]: type annotations needed LL | uwu(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `uwu` | -note: required by a bound in `uwu` +note: required by a const generic parameter in `uwu` --> $DIR/rp_impl_trait_fail.rs:16:8 | LL | fn uwu() -> impl Traitor { - | ^^^^^^^^^^^ required by this bound in `uwu` + | ^^^^^^^^^^^ required by this const generic parameter in `uwu` help: consider specifying the generic argument | LL | uwu::(); diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr index b6982e05b88..217f609459e 100644 --- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr +++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr @@ -4,7 +4,7 @@ error[E0284]: type annotations needed for `Mask<_, _>` LL | let y = Mask::<_, _>::splat(false); | ^ -------------------------- type must be known at this point | -note: required by a bound in `Mask::::splat` +note: required by a const generic parameter in `Mask::::splat` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | @@ -17,7 +17,7 @@ error[E0284]: type annotations needed for `Mask<_, _>` LL | let y = Mask::<_, _>::splat(false); | ^ ------------ type must be known at this point | -note: required by a bound in `Mask` +note: required by a const generic parameter in `Mask` --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL help: consider giving `y` an explicit type, where the value of const parameter `N` is specified | diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr index 27411646cb7..3739637c279 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.full.stderr @@ -24,11 +24,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a bound in `ArrayHolder::::new` +note: required by a const generic parameter in `ArrayHolder::::new` --> $DIR/issue-62504.rs:16:6 | LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` LL | pub const fn new() -> Self { | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified @@ -42,11 +42,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a bound in `ArrayHolder` +note: required by a const generic parameter in `ArrayHolder` --> $DIR/issue-62504.rs:14:20 | LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr index 036b9001c03..14c67e2528a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-62504.min.stderr @@ -28,11 +28,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ------------------ type must be known at this point | -note: required by a bound in `ArrayHolder::::new` +note: required by a const generic parameter in `ArrayHolder::::new` --> $DIR/issue-62504.rs:16:6 | LL | impl ArrayHolder { - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder::::new` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder::::new` LL | pub const fn new() -> Self { | --- required by a bound in this associated function help: consider giving `array` an explicit type, where the value of const parameter `X` is specified @@ -46,11 +46,11 @@ error[E0284]: type annotations needed for `ArrayHolder<_>` LL | let mut array = ArrayHolder::new(); | ^^^^^^^^^ ----------- type must be known at this point | -note: required by a bound in `ArrayHolder` +note: required by a const generic parameter in `ArrayHolder` --> $DIR/issue-62504.rs:14:20 | LL | struct ArrayHolder([u32; X]); - | ^^^^^^^^^^^^^^ required by this bound in `ArrayHolder` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `ArrayHolder` help: consider giving `array` an explicit type, where the value of const parameter `X` is specified | LL | let mut array: ArrayHolder = ArrayHolder::new(); diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr index 0c290448fc5..d1e1c976da6 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-ok-infer-err.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | use_dyn(&()); | ^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `use_dyn` | -note: required by a bound in `use_dyn` +note: required by a const generic parameter in `use_dyn` --> $DIR/object-safety-ok-infer-err.rs:14:12 | LL | fn use_dyn(v: &dyn Foo) where [u8; N + 1]: Sized { - | ^^^^^^^^^^^^^^ required by this bound in `use_dyn` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `use_dyn` help: consider specifying the generic argument | LL | use_dyn::(&()); diff --git a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr index 2180ba2f809..c349a50a83f 100644 --- a/tests/ui/const-generics/infer/cannot-infer-const-args.stderr +++ b/tests/ui/const-generics/infer/cannot-infer-const-args.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | foo(); | ^^^ cannot infer the value of the const parameter `X` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/cannot-infer-const-args.rs:1:8 | LL | fn foo() -> usize { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic argument | LL | foo::(); diff --git a/tests/ui/const-generics/infer/issue-77092.stderr b/tests/ui/const-generics/infer/issue-77092.stderr index 1579d217c2d..9a6374a2adc 100644 --- a/tests/ui/const-generics/infer/issue-77092.stderr +++ b/tests/ui/const-generics/infer/issue-77092.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | println!("{:?}", take_array_from_mut(&mut arr, i)); | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the const parameter `N` declared on the function `take_array_from_mut` | -note: required by a bound in `take_array_from_mut` +note: required by a const generic parameter in `take_array_from_mut` --> $DIR/issue-77092.rs:3:27 | LL | fn take_array_from_mut(data: &mut [T], start: usize) -> &mut [T; N] { - | ^^^^^^^^^^^^^^ required by this bound in `take_array_from_mut` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `take_array_from_mut` help: consider specifying the generic arguments | LL | println!("{:?}", take_array_from_mut::(&mut arr, i)); diff --git a/tests/ui/const-generics/infer/method-chain.stderr b/tests/ui/const-generics/infer/method-chain.stderr index 08c664e82f7..95044bb5203 100644 --- a/tests/ui/const-generics/infer/method-chain.stderr +++ b/tests/ui/const-generics/infer/method-chain.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | Foo.bar().bar().bar().bar().baz(); | ^^^ cannot infer the value of the const parameter `N` declared on the method `baz` | -note: required by a bound in `Foo::baz` +note: required by a const generic parameter in `Foo::baz` --> $DIR/method-chain.rs:8:12 | LL | fn baz(self) -> Foo { - | ^^^^^^^^^^^^^^ required by this bound in `Foo::baz` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::baz` help: consider specifying the generic argument | LL | Foo.bar().bar().bar().bar().baz::(); diff --git a/tests/ui/const-generics/infer/one-param-uninferred.stderr b/tests/ui/const-generics/infer/one-param-uninferred.stderr index 68bec93e826..f3aa7973e67 100644 --- a/tests/ui/const-generics/infer/one-param-uninferred.stderr +++ b/tests/ui/const-generics/infer/one-param-uninferred.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | let _: [u8; 17] = foo(); | ^^^ cannot infer the value of the const parameter `M` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/one-param-uninferred.rs:2:24 | LL | fn foo() -> [u8; N] { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider specifying the generic arguments | LL | let _: [u8; 17] = foo::<17, M>(); diff --git a/tests/ui/const-generics/infer/uninferred-consts.stderr b/tests/ui/const-generics/infer/uninferred-consts.stderr index e8ad336af70..839fb25c4e1 100644 --- a/tests/ui/const-generics/infer/uninferred-consts.stderr +++ b/tests/ui/const-generics/infer/uninferred-consts.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `A` declared on the method `foo` | -note: required by a bound in `Foo::foo` +note: required by a const generic parameter in `Foo::foo` --> $DIR/uninferred-consts.rs:6:12 | LL | fn foo(self) {} - | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); @@ -20,11 +20,11 @@ error[E0284]: type annotations needed LL | Foo.foo(); | ^^^ cannot infer the value of the const parameter `B` declared on the method `foo` | -note: required by a bound in `Foo::foo` +note: required by a const generic parameter in `Foo::foo` --> $DIR/uninferred-consts.rs:6:28 | LL | fn foo(self) {} - | ^^^^^^^^^^^^^^ required by this bound in `Foo::foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo::foo` help: consider specifying the generic arguments | LL | Foo.foo::(); diff --git a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr index cb8f56c6bb0..4809f7d37dd 100644 --- a/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr +++ b/tests/ui/const-generics/parent_generics_of_encoding_impl_trait.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | generics_of_parent_impl_trait::foo([()]); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `foo` | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/auxiliary/generics_of_parent_impl_trait.rs:5:12 | LL | pub fn foo(foo: impl Into<[(); N + 1]>) { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index 07476ae76c6..026999827c0 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -4,11 +4,11 @@ error: the constant `N` is not of type `u8` LL | bar::() | ^ expected `u8`, found `usize` | -note: required by a bound in `bar` +note: required by a const generic parameter in `bar` --> $DIR/type_mismatch.rs:6:8 | LL | fn bar() -> [u8; N] {} - | ^^^^^^^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^ required by this const generic parameter in `bar` error[E0308]: mismatched types --> $DIR/type_mismatch.rs:6:26 diff --git a/tests/ui/const-generics/unify_with_nested_expr.stderr b/tests/ui/const-generics/unify_with_nested_expr.stderr index 87610db67ae..b1aecdb3cb5 100644 --- a/tests/ui/const-generics/unify_with_nested_expr.stderr +++ b/tests/ui/const-generics/unify_with_nested_expr.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed LL | bar(); | ^^^ cannot infer the value of the const parameter `N` declared on the function `bar` | -note: required by a bound in `bar` +note: required by a const generic parameter in `bar` --> $DIR/unify_with_nested_expr.rs:12:8 | LL | fn bar() - | ^^^^^^^^^^^^^^ required by this bound in `bar` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `bar` help: consider specifying the generic argument | LL | bar::(); diff --git a/tests/ui/inference/issue-83606.stderr b/tests/ui/inference/issue-83606.stderr index 2d74024bb28..69d1d71ef3c 100644 --- a/tests/ui/inference/issue-83606.stderr +++ b/tests/ui/inference/issue-83606.stderr @@ -4,11 +4,11 @@ error[E0284]: type annotations needed for `[usize; _]` LL | let _ = foo("foo"); | ^ ---------- type must be known at this point | -note: required by a bound in `foo` +note: required by a const generic parameter in `foo` --> $DIR/issue-83606.rs:3:8 | LL | fn foo(_: impl std::fmt::Display) -> [usize; N] { - | ^^^^^^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `foo` help: consider giving this pattern a type, where the value of const parameter `N` is specified | LL | let _: [usize; N] = foo("foo"); diff --git a/tests/ui/issues/issue-98299.stderr b/tests/ui/issues/issue-98299.stderr index f4b40cbbd19..b645267e3b9 100644 --- a/tests/ui/issues/issue-98299.stderr +++ b/tests/ui/issues/issue-98299.stderr @@ -6,11 +6,11 @@ LL | SmallCString::try_from(p).map(|cstr| cstr); | | | type must be known at this point | -note: required by a bound in `SmallCString` +note: required by a const generic parameter in `SmallCString` --> $DIR/issue-98299.rs:10:25 | LL | pub struct SmallCString {} - | ^^^^^^^^^^^^^^ required by this bound in `SmallCString` + | ^^^^^^^^^^^^^^ required by this const generic parameter in `SmallCString` help: consider giving this closure parameter an explicit type, where the value of const parameter `N` is specified | LL | SmallCString::try_from(p).map(|cstr: SmallCString| cstr); diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr index b4c14c2294e..71d4277275f 100644 --- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -14,11 +14,11 @@ LL | impl Wrapper {} | = help: consider constraining the associated type `::Type` to `usize` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -note: required by a bound in `Wrapper` +note: required by a const generic parameter in `Wrapper` --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:12:16 | LL | struct Wrapper::Type> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Wrapper` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `Wrapper` error[E0308]: mismatched types --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:30 diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr index 1df7c3e2f97..6f79bf7b424 100644 --- a/tests/ui/transmutability/issue-101739-1.stderr +++ b/tests/ui/transmutability/issue-101739-1.stderr @@ -10,7 +10,7 @@ error: the constant `ASSUME_ALIGNMENT` is not of type `Assume` LL | Dst: BikeshedIntrinsicFrom, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool` | -note: required by a bound in `BikeshedIntrinsicFrom` +note: required by a const generic parameter in `BikeshedIntrinsicFrom` --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL error[E0308]: mismatched types From 95e214d6e5cbacd4bcc12f449674dbcc3f409a02 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Wed, 19 Jun 2024 20:01:32 +0200 Subject: [PATCH 07/10] reword the hint::blackbox non-guarantees People were tripped up by the "precludes", interpreting it that this function must not ever be used in cryptographic contexts rather than the std lib merely making zero promises about it being fit-for-purpose. What remains unchanged is that if someone does try to use it *despite the warnings* then it is on them to pin their compiler versions and verify the assembly of every single binary build they do. --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 6e2d88c6b83..c3b16c34293 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -263,7 +263,7 @@ pub fn spin_loop() { /// extent to which it can block optimisations may vary depending upon the platform and code-gen /// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the /// identity function. As such, it **must not be relied upon to control critical program behavior.** -/// This _immediately_ precludes any direct use of this function for cryptographic or security +/// This also means that this function does not offer any guarantees for cryptographic or security /// purposes. /// /// [`std::convert::identity`]: crate::convert::identity From 7d9a92ba31122950f2c7f6a71ad6dee49b3e95e4 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 13 Jun 2024 13:40:14 +1000 Subject: [PATCH 08/10] Inline `can_begin_literal_maybe_minus` call into two places. It's clearer this way, because the `Interpolated` cases in `can_begin_const_arg` and `is_pat_range_end_start` are more permissive than the `Interpolated` cases in `can_begin_literal_maybe_minus`. --- compiler/rustc_ast/src/token.rs | 5 +++-- compiler/rustc_parse/src/parser/pat.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 109c401bb6a..4d513797f5f 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -558,9 +558,10 @@ impl Token { /// Returns `true` if the token can appear at the start of a const param. pub fn can_begin_const_arg(&self) -> bool { match self.kind { - OpenDelim(Delimiter::Brace) => true, + OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true, + Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true, Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)), - _ => self.can_begin_literal_maybe_minus(), + _ => false, } } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 03aea0888d9..6f2b7177159 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -939,7 +939,8 @@ impl<'a> Parser<'a> { || self.look_ahead(dist, |t| { t.is_path_start() // e.g. `MY_CONST`; || t.kind == token::Dot // e.g. `.5` for recovery; - || t.can_begin_literal_maybe_minus() // e.g. `42`. + || matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus)) + || t.is_bool_lit() || t.is_whole_expr() || t.is_lifetime() // recover `'a` instead of `'a'` || (self.may_recover() // recover leading `(` From c6f78270b66b2ffc78742006445df76105b7d558 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 13 Jun 2024 13:52:20 +1000 Subject: [PATCH 09/10] Introduce `can_begin_string_literal`. We currently use `can_begin_literal_maybe_minus` in a couple of places where only string literals are allowed. This commit introduces a more specific function, which makes things clearer. It doesn't change behaviour because the two functions affected (`is_unsafe_foreign_mod` and `check_keyword_case`) are always followed by a call to `parse_abi`, which checks again for a string literal. --- compiler/rustc_ast/src/token.rs | 15 +++++++++++++++ compiler/rustc_parse/src/parser/item.rs | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs index 4d513797f5f..4dc41a02cb8 100644 --- a/compiler/rustc_ast/src/token.rs +++ b/compiler/rustc_ast/src/token.rs @@ -621,6 +621,21 @@ impl Token { } } + pub fn can_begin_string_literal(&self) -> bool { + match self.uninterpolate().kind { + Literal(..) => true, + Interpolated(ref nt) => match &**nt { + NtLiteral(_) => true, + NtExpr(e) => match &e.kind { + ast::ExprKind::Lit(_) => true, + _ => false, + }, + _ => false, + }, + _ => false, + } + } + /// A convenience function for matching on identifiers during parsing. /// Turns interpolated identifier (`$i: ident`) or lifetime (`$l: lifetime`) token /// into the regular identifier or lifetime token it refers to, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 2db777a9f70..3e1ea7b129d 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1259,7 +1259,7 @@ impl<'a> Parser<'a> { self.token.is_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Extern]) && self.look_ahead( - 2 + self.look_ahead(2, |t| t.can_begin_literal_maybe_minus() as usize), + 2 + self.look_ahead(2, |t| t.can_begin_string_literal() as usize), |t| t.kind == token::OpenDelim(Delimiter::Brace), ) } @@ -2448,7 +2448,7 @@ impl<'a> Parser<'a> { }) // `extern ABI fn` || self.check_keyword_case(kw::Extern, case) - && self.look_ahead(1, |t| t.can_begin_literal_maybe_minus()) + && self.look_ahead(1, |t| t.can_begin_string_literal()) && (self.look_ahead(2, |t| t.is_keyword_case(kw::Fn, case)) || // this branch is only for better diagnostic in later, `pub` is not allowed here (self.may_recover() From e8a9af9ad972be1b2df26b8e0b4905e6808a912f Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 18 Jun 2024 17:04:40 -0700 Subject: [PATCH 10/10] Clarify that anonymous consts still do introduce a new scope --- compiler/rustc_lint/messages.ftl | 2 +- tests/ui/lint/non-local-defs/cargo-update.stderr | 2 +- tests/ui/lint/non-local-defs/consts.stderr | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 007709e32d8..468673f05c1 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -550,7 +550,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, `impl` blocks sho .with_trait = an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` .bounds = `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type .doctest = make this doc-test a standalone test with its own `fn main() {"{"} ... {"}"}` - .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration + .exception = items in an anonymous const item (`const _: () = {"{"} ... {"}"}`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint .const_anon = use a const-anon item to suppress this lint .macro_to_change = the {$macro_kind} `{$macro_to_change}` defines the non-local `impl`, and may need to be changed diff --git a/tests/ui/lint/non-local-defs/cargo-update.stderr b/tests/ui/lint/non-local-defs/cargo-update.stderr index afd37d03a23..bccf8622bac 100644 --- a/tests/ui/lint/non-local-defs/cargo-update.stderr +++ b/tests/ui/lint/non-local-defs/cargo-update.stderr @@ -12,7 +12,7 @@ LL | non_local_macro::non_local_impl!(LocalStruct); = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro` = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/lint/non-local-defs/consts.stderr b/tests/ui/lint/non-local-defs/consts.stderr index 2756ea40138..9f70119e0f8 100644 --- a/tests/ui/lint/non-local-defs/consts.stderr +++ b/tests/ui/lint/non-local-defs/consts.stderr @@ -15,7 +15,7 @@ LL | impl Uto for &Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue = note: `#[warn(non_local_definitions)]` on by default @@ -32,7 +32,7 @@ LL | impl Uto2 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -48,7 +48,7 @@ LL | impl Uto3 for Test {} | = note: `impl` may be usable in bounds, etc. from outside the expression, which might e.g. make something constructible that previously wasn't, because it's still on a publicly-visible type = note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item @@ -94,7 +94,7 @@ LL | impl Test { | `Test` is not local | = note: methods and associated constants are still usable outside the current expression, only `impl Local` and `impl dyn Local` can ever be private, and only if the type is nested in the same item as the `impl` - = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration + = note: items in an anonymous const item (`const _: () = { ... }`) are treated as in the same scope as the anonymous const's declaration for the purpose of this lint = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item