diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs index 6b7d0e1f204b5..00d75be439964 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/ty.rs @@ -72,13 +72,9 @@ impl Path { ) -> ast::Path { let mut idents = self.path.iter().map(|s| Ident::new(*s, span)).collect(); let lt = mk_lifetimes(cx, span, &self.lifetime); - let tys: Vec> = - self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)).collect(); - let params = lt - .into_iter() - .map(GenericArg::Lifetime) - .chain(tys.into_iter().map(GenericArg::Type)) - .collect(); + let tys = self.params.iter().map(|t| t.to_ty(cx, span, self_ty, self_generics)); + let params = + lt.into_iter().map(GenericArg::Lifetime).chain(tys.map(GenericArg::Type)).collect(); match self.kind { PathKind::Global => cx.path_all(span, true, idents, params), diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 16151e9dca5e0..4467980054f54 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -24,6 +24,7 @@ #![feature(new_uninit)] #![feature(once_cell)] #![feature(maybe_uninit_uninit_array)] +#![feature(min_type_alias_impl_trait)] #![allow(rustc::default_hash_types)] #![deny(unaligned_references)] diff --git a/compiler/rustc_data_structures/src/vec_map.rs b/compiler/rustc_data_structures/src/vec_map.rs index 1786fa340cc8b..e3fa587985df0 100644 --- a/compiler/rustc_data_structures/src/vec_map.rs +++ b/compiler/rustc_data_structures/src/vec_map.rs @@ -1,6 +1,6 @@ use std::borrow::Borrow; use std::iter::FromIterator; -use std::slice::{Iter, IterMut}; +use std::slice::Iter; use std::vec::IntoIter; use crate::stable_hasher::{HashStable, StableHasher}; @@ -67,9 +67,13 @@ where self.into_iter() } - pub fn iter_mut(&mut self) -> IterMut<'_, (K, V)> { + pub fn iter_mut(&mut self) -> impl Iterator { self.into_iter() } + + pub fn retain(&mut self, f: impl Fn(&(K, V)) -> bool) { + self.0.retain(f) + } } impl Default for VecMap { @@ -108,12 +112,12 @@ impl<'a, K, V> IntoIterator for &'a VecMap { } impl<'a, K, V> IntoIterator for &'a mut VecMap { - type Item = &'a mut (K, V); - type IntoIter = IterMut<'a, (K, V)>; + type Item = (&'a K, &'a mut V); + type IntoIter = impl Iterator; #[inline] fn into_iter(self) -> Self::IntoIter { - self.0.iter_mut() + self.0.iter_mut().map(|(k, v)| (&*k, v)) } } diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index df162f8dce026..902c7c4787323 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -418,6 +418,7 @@ E0716: include_str!("./error_codes/E0716.md"), E0718: include_str!("./error_codes/E0718.md"), E0719: include_str!("./error_codes/E0719.md"), E0720: include_str!("./error_codes/E0720.md"), +E0722: include_str!("./error_codes/E0722.md"), E0724: include_str!("./error_codes/E0724.md"), E0725: include_str!("./error_codes/E0725.md"), E0727: include_str!("./error_codes/E0727.md"), @@ -634,7 +635,6 @@ E0783: include_str!("./error_codes/E0783.md"), E0711, // a feature has been declared with conflicting stability attributes E0717, // rustc_promotable without stability attribute // E0721, // `await` keyword - E0722, // Malformed `#[optimize]` attribute // E0723, unstable feature in `const` context E0726, // non-explicit (not `'_`) elided lifetime in unsupported position // E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`. diff --git a/compiler/rustc_error_codes/src/error_codes/E0722.md b/compiler/rustc_error_codes/src/error_codes/E0722.md new file mode 100644 index 0000000000000..570717a92bd79 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0722.md @@ -0,0 +1,31 @@ +The `optimize` attribute was malformed. + +Erroneous code example: + +```compile_fail,E0722 +#![feature(optimize_attribute)] + +#[optimize(something)] // error: invalid argument +pub fn something() {} +``` + +The `#[optimize]` attribute should be used as follows: + +- `#[optimize(size)]` -- instructs the optimization pipeline to generate code + that's smaller rather than faster + +- `#[optimize(speed)]` -- instructs the optimization pipeline to generate code + that's faster rather than smaller + +For example: + +``` +#![feature(optimize_attribute)] + +#[optimize(size)] +pub fn something() {} +``` + +See [RFC 2412] for more details. + +[RFC 2412]: https://rust-lang.github.io/rfcs/2412-optimize-attr.html diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 5c7d10560ca91..6aff2fdbd1f22 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -3060,6 +3060,27 @@ impl<'hir> Node<'hir> { Node::Crate(_) | Node::Visibility(_) => None, } } + + /// Returns `Constness::Const` when this node is a const fn/impl. + pub fn constness(&self) -> Constness { + match self { + Node::Item(Item { + kind: ItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::TraitItem(TraitItem { + kind: TraitItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::ImplItem(ImplItem { + kind: ImplItemKind::Fn(FnSig { header: FnHeader { constness, .. }, .. }, ..), + .. + }) + | Node::Item(Item { kind: ItemKind::Impl(Impl { constness, .. }), .. }) => *constness, + + _ => Constness::NotConst, + } + } } // Some nodes are used a lot. Make sure they don't unintentionally get bigger. diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 670129937be2b..426db95aca16e 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2130,7 +2130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let new_lt = generics .as_ref() .and_then(|(parent_g, g)| { - let possible: Vec<_> = (b'a'..=b'z').map(|c| format!("'{}", c as char)).collect(); + let mut possible = (b'a'..=b'z').map(|c| format!("'{}", c as char)); let mut lts_names = g .params .iter() @@ -2146,7 +2146,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } let lts = lts_names.iter().map(|s| -> &str { &*s }).collect::>(); - possible.into_iter().find(|candidate| !lts.contains(&candidate.as_str())) + possible.find(|candidate| !lts.contains(&candidate.as_str())) }) .unwrap_or("'lt".to_string()); let add_lt_sugg = generics diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index ae53f1ac3bb49..392372fad531e 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -29,7 +29,10 @@ fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> { Node::Item(Item { kind: ItemKind::Fn(sig, _, _), .. }) | Node::TraitItem(TraitItem { kind: TraitItemKind::Fn(sig, _), .. }) | Node::ImplItem(ImplItem { kind: ImplItemKind::Fn(sig, _), .. }) => Some(&sig.decl), - Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) => Some(fn_decl), + Node::Expr(Expr { kind: ExprKind::Closure(_, fn_decl, ..), .. }) + | Node::ForeignItem(ForeignItem { kind: ForeignItemKind::Fn(fn_decl, ..), .. }) => { + Some(fn_decl) + } _ => None, } } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index cb99ae19ee72e..0908b6a1763d5 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1722,7 +1722,7 @@ rustc_queries! { /// span) for an *existing* error. Therefore, it is best-effort, and may never handle /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine, /// because the `ty::Ty`-based wfcheck is always run. - query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, hir::HirId)) -> Option> { + query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option> { eval_always no_hash desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index f951e43fbfa35..a4a2e82463757 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -16,7 +16,7 @@ use crate::ty::{self, AdtKind, Ty, TyCtxt}; use rustc_data_structures::sync::Lrc; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::Constness; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -327,17 +327,39 @@ pub enum ObligationCauseCode<'tcx> { /// If `X` is the concrete type of an opaque type `impl Y`, then `X` must implement `Y` OpaqueType, - /// Well-formed checking. If a `HirId` is provided, - /// it is used to perform HIR-based wf checking if an error - /// occurs, in order to generate a more precise error message. + /// Well-formed checking. If a `WellFormedLoc` is provided, + /// then it will be used to eprform HIR-based wf checking + /// after an error occurs, in order to generate a more precise error span. /// This is purely for diagnostic purposes - it is always - /// correct to use `MiscObligation` instead - WellFormed(Option), + /// correct to use `MiscObligation` instead, or to specify + /// `WellFormed(None)` + WellFormed(Option), /// From `match_impl`. The cause for us having to match an impl, and the DefId we are matching against. MatchImpl(Lrc>, DefId), } +/// The 'location' at which we try to perform HIR-based wf checking. +/// This information is used to obtain an `hir::Ty`, which +/// we can walk in order to obtain precise spans for any +/// 'nested' types (e.g. `Foo` in `Option`). +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +pub enum WellFormedLoc { + /// Use the type of the provided definition. + Ty(LocalDefId), + /// Use the type of the parameter of the provided function. + /// We cannot use `hir::Param`, since the function may + /// not have a body (e.g. a trait method definition) + Param { + /// The function to lookup the parameter in + function: LocalDefId, + /// The index of the parameter to use. + /// Parameters are indexed from 0, with the return type + /// being the last 'parameter' + param_idx: u16, + }, +} + impl ObligationCauseCode<'_> { // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b84058011066f..4ce49032398bc 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1682,7 +1682,7 @@ nop_list_lift! {bound_variable_kinds; ty::BoundVariableKind => ty::BoundVariable // This is the impl for `&'a InternalSubsts<'a>`. nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} -CloneLiftImpls! { for<'tcx> { Constness, } } +CloneLiftImpls! { for<'tcx> { Constness, traits::WellFormedLoc, } } pub mod tls { use super::{ptr_eq, GlobalCtxt, TyCtxt}; diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs index feb7672f650ec..1460c2378d1c9 100644 --- a/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs +++ b/compiler/rustc_mir/src/borrow_check/diagnostics/region_errors.rs @@ -9,7 +9,7 @@ use rustc_middle::mir::{ConstraintCategory, ReturnConstraint}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::{self, RegionVid, Ty}; use rustc_span::symbol::{kw, sym}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; use crate::util::borrowck_errors; @@ -641,12 +641,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } else { "'_".to_string() }; - let suggestion = if snippet.ends_with(';') { + let span = if snippet.ends_with(';') { // `type X = impl Trait;` - format!("{} + {};", &snippet[..snippet.len() - 1], suggestable_fr_name) + span.with_hi(span.hi() - BytePos(1)) } else { - format!("{} + {}", snippet, suggestable_fr_name) + span }; + let suggestion = format!(" + {}", suggestable_fr_name); + let span = span.shrink_to_hi(); diag.span_suggestion( span, &format!( diff --git a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs index aa3ff98f7ff9f..3fb06cd2f5f44 100644 --- a/compiler/rustc_mir/src/borrow_check/type_check/mod.rs +++ b/compiler/rustc_mir/src/borrow_check/type_check/mod.rs @@ -26,7 +26,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::cast::CastTy; use rustc_middle::ty::fold::TypeFoldable; -use rustc_middle::ty::subst::{GenericArgKind, Subst, SubstsRef, UserSubsts}; +use rustc_middle::ty::subst::{GenericArgKind, SubstsRef, UserSubsts}; use rustc_middle::ty::{ self, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, OpaqueTypeKey, RegionVid, ToPredicate, Ty, TyCtxt, UserType, UserTypeAnnotationIndex, WithConstness, @@ -60,7 +60,6 @@ use crate::borrow_check::{ LivenessValues, PlaceholderIndex, PlaceholderIndices, RegionValueElements, }, region_infer::{ClosureRegionRequirementsExt, TypeTest}, - renumber, type_check::free_region_relations::{CreateResult, UniversalRegionRelations}, universal_regions::{DefiningTy, UniversalRegions}, Upvar, @@ -180,7 +179,54 @@ pub(crate) fn type_check<'mir, 'tcx>( liveness::generate(&mut cx, body, elements, flow_inits, move_data, location_table); translate_outlives_facts(&mut cx); - cx.opaque_type_values + let mut opaque_type_values = cx.opaque_type_values; + + for (_, revealed_ty) in &mut opaque_type_values { + *revealed_ty = infcx.resolve_vars_if_possible(*revealed_ty); + if revealed_ty.has_infer_types_or_consts() { + infcx.tcx.sess.delay_span_bug( + body.span, + &format!("could not resolve {:#?}", revealed_ty.kind()), + ); + *revealed_ty = infcx.tcx.ty_error(); + } + } + + opaque_type_values.retain(|(opaque_type_key, resolved_ty)| { + let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() { + *def_id == opaque_type_key.def_id + } else { + false + }; + + if concrete_is_opaque { + // We're using an opaque `impl Trait` type without + // 'revealing' it. For example, code like this: + // + // type Foo = impl Debug; + // fn foo1() -> Foo { ... } + // fn foo2() -> Foo { foo1() } + // + // In `foo2`, we're not revealing the type of `Foo` - we're + // just treating it as the opaque type. + // + // When this occurs, we do *not* want to try to equate + // the concrete type with the underlying defining type + // of the opaque type - this will always fail, since + // the defining type of an opaque type is always + // some other type (e.g. not itself) + // Essentially, none of the normal obligations apply here - + // we're just passing around some unknown opaque type, + // without actually looking at the underlying type it + // gets 'revealed' into + debug!( + "eq_opaque_type_and_type: non-defining use of {:?}", + opaque_type_key.def_id, + ); + } + !concrete_is_opaque + }); + opaque_type_values }, ); @@ -1239,14 +1285,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return Ok(()); } - let infcx = self.infcx; - let tcx = infcx.tcx; let param_env = self.param_env; let body = self.body; let mir_def_id = body.source.def_id().expect_local(); - // the "concrete opaque types" maps - let concrete_opaque_types = &tcx.typeck(mir_def_id).concrete_opaque_types; let mut opaque_type_values = VecMap::new(); debug!("eq_opaque_type_and_type: mir_def_id={:?}", mir_def_id); @@ -1296,88 +1338,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { .eq(output_ty, revealed_ty)?, ); - // For each opaque type `Foo` inferred by this value, we want to equate - // the inference variable `?T` with the revealed type that was computed - // earlier by type check. for &(opaque_type_key, opaque_decl) in &opaque_type_map { - let resolved_ty = infcx.resolve_vars_if_possible(opaque_decl.concrete_ty); - let concrete_is_opaque = if let ty::Opaque(def_id, _) = resolved_ty.kind() { - *def_id == opaque_type_key.def_id - } else { - false - }; - - // The revealed type computed by the earlier phase of type check. - // In our example, this would be `(U, u32)`. Note that this references - // the type parameter `U` from the definition of `Foo`. - let concrete_ty = match concrete_opaque_types - .get_by(|(key, _)| key.def_id == opaque_type_key.def_id) - { - None => { - if !concrete_is_opaque { - tcx.sess.delay_span_bug( - body.span, - &format!( - "Non-defining use of {:?} with revealed type", - opaque_type_key.def_id, - ), - ); - } - continue; - } - Some(concrete_ty) => concrete_ty, - }; - debug!("concrete_ty = {:?}", concrete_ty); - - // Apply the substitution, in this case `[U -> T]`, so that the - // concrete type becomes `Foo<(T, u32)>` - let subst_opaque_defn_ty = concrete_ty.subst(tcx, opaque_type_key.substs); - - // "Renumber" this, meaning that we replace all the regions - // with fresh inference variables. Not relevant to our example. - let renumbered_opaque_defn_ty = - renumber::renumber_regions(infcx, subst_opaque_defn_ty); - - debug!( - "eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}", - concrete_ty, resolved_ty, renumbered_opaque_defn_ty, - ); - - if !concrete_is_opaque { - // Equate the instantiated opaque type `opaque_decl.concrete_ty` (`?T`, - // in our example) with the renumbered version that we took from - // the type check results (`Foo<(T, u32)>`). - obligations.add( - infcx - .at(&ObligationCause::dummy(), param_env) - .eq(opaque_decl.concrete_ty, renumbered_opaque_defn_ty)?, - ); - opaque_type_values.insert(opaque_type_key, renumbered_opaque_defn_ty); - } else { - // We're using an opaque `impl Trait` type without - // 'revealing' it. For example, code like this: - // - // type Foo = impl Debug; - // fn foo1() -> Foo { ... } - // fn foo2() -> Foo { foo1() } - // - // In `foo2`, we're not revealing the type of `Foo` - we're - // just treating it as the opaque type. - // - // When this occurs, we do *not* want to try to equate - // the concrete type with the underlying defining type - // of the opaque type - this will always fail, since - // the defining type of an opaque type is always - // some other type (e.g. not itself) - // Essentially, none of the normal obligations apply here - - // we're just passing around some unknown opaque type, - // without actually looking at the underlying type it - // gets 'revealed' into - debug!( - "eq_opaque_type_and_type: non-defining use of {:?}", - opaque_type_key.def_id, - ); - } + opaque_type_values.insert(opaque_type_key, opaque_decl.concrete_ty); } debug!("eq_opaque_type_and_type: equated"); @@ -1405,7 +1367,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations, ConstraintCategory::OpaqueType, CustomTypeOp::new( - |_cx| { + |infcx| { infcx.constrain_opaque_type( opaque_type_key, &opaque_decl, diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index 646ae8ced7eb4..cfc538ef500a1 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -897,16 +897,19 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> { permitted = true; } } - let mut const_impls = true; - tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| { - if const_impls { - if let hir::Constness::NotConst = tcx.impl_constness(imp) { - const_impls = false; + if !permitted { + // if trait's impls are all const, permit the call. + let mut const_impls = true; + tcx.for_each_relevant_impl(trait_id, substs.type_at(0), |imp| { + if const_impls { + if let hir::Constness::NotConst = tcx.impl_constness(imp) { + const_impls = false; + } } + }); + if const_impls { + permitted = true; } - }); - if const_impls { - permitted = true; } } diff --git a/compiler/rustc_query_impl/src/keys.rs b/compiler/rustc_query_impl/src/keys.rs index 1993e0a602fa5..0ad360c7d89c3 100644 --- a/compiler/rustc_query_impl/src/keys.rs +++ b/compiler/rustc_query_impl/src/keys.rs @@ -1,9 +1,9 @@ //! Defines the set of legal keys that can be used in queries. use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; -use rustc_hir::HirId; use rustc_middle::infer::canonical::Canonical; use rustc_middle::mir; +use rustc_middle::traits; use rustc_middle::ty::fast_reject::SimplifiedType; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -397,7 +397,7 @@ impl<'tcx> Key for (DefId, Ty<'tcx>, SubstsRef<'tcx>, ty::ParamEnv<'tcx>) { } } -impl<'tcx> Key for (ty::Predicate<'tcx>, HirId) { +impl<'tcx> Key for (ty::Predicate<'tcx>, traits::WellFormedLoc) { #[inline(always)] fn query_crate_is_local(&self) -> bool { true diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index f3ce78d2d78f8..86d495c3353b3 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1,7 +1,7 @@ use crate::cgu_reuse_tracker::CguReuseTracker; use crate::code_stats::CodeStats; pub use crate::code_stats::{DataTypeKind, FieldInfo, SizeKind, VariantInfo}; -use crate::config::{self, CrateType, OutputType, PrintRequest, SwitchWithOptPath}; +use crate::config::{self, CrateType, OutputType, SwitchWithOptPath}; use crate::filesearch; use crate::lint::{self, LintId}; use crate::parse::ParseSess; @@ -1440,25 +1440,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) { } } - // PGO does not work reliably with panic=unwind on Windows. Let's make it - // an error to combine the two for now. It always runs into an assertions - // if LLVM is built with assertions, but without assertions it sometimes - // does not crash and will probably generate a corrupted binary. - // We should only display this error if we're actually going to run PGO. - // If we're just supposed to print out some data, don't show the error (#61002). - if sess.opts.cg.profile_generate.enabled() - && sess.target.is_like_msvc - && sess.panic_strategy() == PanicStrategy::Unwind - && sess.opts.prints.iter().all(|&p| p == PrintRequest::NativeStaticLibs) - { - sess.err( - "Profile-guided optimization does not yet work in conjunction \ - with `-Cpanic=unwind` on Windows when targeting MSVC. \ - See issue #61002 \ - for more information.", - ); - } - // Sanitizers can only be used on platforms that we know have working sanitizer codegen. let supported_sanitizers = sess.target.options.supported_sanitizers; let unsupported_sanitizers = sess.opts.debugging_opts.sanitizer - supported_sanitizers; diff --git a/compiler/rustc_trait_selection/src/opaque_types.rs b/compiler/rustc_trait_selection/src/opaque_types.rs index 39013a317fd9c..95c81c5c729be 100644 --- a/compiler/rustc_trait_selection/src/opaque_types.rs +++ b/compiler/rustc_trait_selection/src/opaque_types.rs @@ -83,6 +83,7 @@ pub struct OpaqueTypeDecl<'tcx> { } /// Whether member constraints should be generated for all opaque types +#[derive(Debug)] pub enum GenerateMemberConstraints { /// The default, used by typeck WhenRequired, @@ -354,8 +355,6 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { opaque_types: &OpaqueTypeMap<'tcx>, free_region_relations: &FRR, ) { - debug!("constrain_opaque_types()"); - for &(opaque_type_key, opaque_defn) in opaque_types { self.constrain_opaque_type( opaque_type_key, @@ -367,6 +366,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } /// See `constrain_opaque_types` for documentation. + #[instrument(level = "debug", skip(self, free_region_relations))] fn constrain_opaque_type>( &self, opaque_type_key: OpaqueTypeKey<'tcx>, @@ -376,15 +376,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { ) { let def_id = opaque_type_key.def_id; - debug!("constrain_opaque_type()"); - debug!("constrain_opaque_type: def_id={:?}", def_id); - debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn); - let tcx = self.tcx; let concrete_ty = self.resolve_vars_if_possible(opaque_defn.concrete_ty); - debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); + debug!(?concrete_ty); let first_own_region = match opaque_defn.origin { hir::OpaqueTyOrigin::FnReturn | hir::OpaqueTyOrigin::AsyncFn => { @@ -397,7 +393,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // type foo::<'p0..'pn>::Foo<'q0..'qm> // fn foo() -> foo::<'static..'static>::Foo<'l0..'lm>. // - // For these types we onlt iterate over `'l0..lm` below. + // For these types we only iterate over `'l0..lm` below. tcx.generics_of(def_id).parent_count } // These opaque type inherit all lifetime parameters from their @@ -410,10 +406,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { // If there are required region bounds, we can use them. if opaque_defn.has_required_region_bounds { let bounds = tcx.explicit_item_bounds(def_id); - debug!("constrain_opaque_type: predicates: {:#?}", bounds); + debug!("{:#?}", bounds); let bounds: Vec<_> = bounds.iter().map(|(bound, _)| bound.subst(tcx, opaque_type_key.substs)).collect(); - debug!("constrain_opaque_type: bounds={:#?}", bounds); + debug!("{:#?}", bounds); let opaque_type = tcx.mk_opaque(def_id, opaque_type_key.substs); let required_region_bounds = @@ -452,8 +448,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { }; // Compute the least upper bound of it with the other regions. - debug!("constrain_opaque_types: least_region={:?}", least_region); - debug!("constrain_opaque_types: subst_region={:?}", subst_region); + debug!(?least_region); + debug!(?subst_region); match least_region { None => least_region = Some(subst_region), Some(lr) => { @@ -484,7 +480,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } let least_region = least_region.unwrap_or(tcx.lifetimes.re_static); - debug!("constrain_opaque_types: least_region={:?}", least_region); + debug!(?least_region); if let GenerateMemberConstraints::IfNoStaticBound = mode { if least_region != tcx.lifetimes.re_static { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 5c4aef529e5ac..13a6733fb478a 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -242,11 +242,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { SelectionError::Unimplemented => { // If this obligation was generated as a result of well-formed checking, see if we // can get a better error message by performing HIR-based well formed checking. - if let ObligationCauseCode::WellFormed(Some(wf_hir_id)) = + if let ObligationCauseCode::WellFormed(Some(wf_loc)) = root_obligation.cause.code.peel_derives() { if let Some(cause) = - self.tcx.diagnostic_hir_wf_check((obligation.predicate, *wf_hir_id)) + self.tcx.diagnostic_hir_wf_check((obligation.predicate, wf_loc.clone())) { obligation.cause = cause; span = obligation.cause.span; diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 4ed07ba358de3..865e4ccc0b63f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -40,6 +40,7 @@ use rustc_trait_selection::opaque_types::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _; use rustc_trait_selection::traits::{ self, ObligationCause, ObligationCauseCode, StatementAsExpression, TraitEngine, TraitEngineExt, + WellFormedLoc, }; use std::collections::hash_map::Entry; @@ -419,13 +420,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, span: Span, value: T, - hir_id: hir::HirId, + loc: WellFormedLoc, ) -> T where T: TypeFoldable<'tcx>, { self.inh.normalize_associated_types_in_with_cause( - ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(hir_id))), + ObligationCause::new(span, self.body_id, ObligationCauseCode::WellFormed(Some(loc))), self.param_env, value, ) diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs index 4da4835f7cfbb..13686cfec809a 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/mod.rs @@ -15,7 +15,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, Const, Ty, TyCtxt}; @@ -175,13 +174,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - // FIXME: refactor this into a method - let node = self.tcx.hir().get(self.body_id); - if let Some(fn_like) = FnLikeNode::from_node(node) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.tcx.hir().get(self.body_id).constness() } fn get_type_parameter_bounds( diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index b24d63917c1cf..98980c65bc815 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -22,8 +22,9 @@ use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use rustc_trait_selection::opaque_types::may_define_opaque_type; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; -use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode}; +use rustc_trait_selection::traits::{self, ObligationCause, ObligationCauseCode, WellFormedLoc}; +use std::convert::TryInto; use std::iter; use std::ops::ControlFlow; @@ -386,7 +387,7 @@ fn check_associated_item( span: Span, sig_if_method: Option<&hir::FnSig<'_>>, ) { - let code = ObligationCauseCode::WellFormed(Some(item_id)); + let code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))); for_id(tcx, item_id, span).with_fcx(|fcx| { let item = fcx.tcx.associated_item(fcx.tcx.hir().local_def_id(item_id)); @@ -400,7 +401,11 @@ fn check_associated_item( match item.kind { ty::AssocKind::Const => { let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id); + let ty = fcx.normalize_associated_types_in_wf( + span, + ty, + WellFormedLoc::Ty(item_id.expect_owner()), + ); fcx.register_wf_obligation(ty.into(), span, code.clone()); } ty::AssocKind::Fn => { @@ -422,7 +427,11 @@ fn check_associated_item( } if item.defaultness.has_value() { let ty = fcx.tcx.type_of(item.def_id); - let ty = fcx.normalize_associated_types_in_wf(span, ty, item_id); + let ty = fcx.normalize_associated_types_in_wf( + span, + ty, + WellFormedLoc::Ty(item_id.expect_owner()), + ); fcx.register_wf_obligation(ty.into(), span, code.clone()); } } @@ -621,7 +630,11 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo for_id(tcx, item_id, ty_span).with_fcx(|fcx| { let ty = tcx.type_of(tcx.hir().local_def_id(item_id)); - let item_ty = fcx.normalize_associated_types_in_wf(ty_span, ty, item_id); + let item_ty = fcx.normalize_associated_types_in_wf( + ty_span, + ty, + WellFormedLoc::Ty(item_id.expect_owner()), + ); let mut forbid_unsized = true; if allow_foreign_ty { @@ -634,7 +647,7 @@ fn check_item_type(tcx: TyCtxt<'_>, item_id: hir::HirId, ty_span: Span, allow_fo fcx.register_wf_obligation( item_ty.into(), ty_span, - ObligationCauseCode::WellFormed(Some(item_id)), + ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(item_id.expect_owner()))), ); if forbid_unsized { fcx.register_bound( @@ -684,7 +697,9 @@ fn check_impl<'tcx>( fcx.register_wf_obligation( self_ty.into(), ast_self_ty.span, - ObligationCauseCode::WellFormed(Some(item.hir_id())), + ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty( + item.hir_id().expect_owner(), + ))), ); } } @@ -901,11 +916,48 @@ fn check_fn_or_method<'fcx, 'tcx>( implied_bounds: &mut Vec>, ) { let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig); - let sig = fcx.normalize_associated_types_in(span, sig); - for (&input_ty, ty) in iter::zip(sig.inputs(), hir_decl.inputs) { - fcx.register_wf_obligation(input_ty.into(), ty.span, ObligationCauseCode::WellFormed(None)); + // Normalize the input and output types one at a time, using a different + // `WellFormedLoc` for each. We cannot call `normalize_associated_types` + // on the entire `FnSig`, since this would use the same `WellFormedLoc` + // for each type, preventing the HIR wf check from generating + // a nice error message. + let ty::FnSig { mut inputs_and_output, c_variadic, unsafety, abi } = sig; + inputs_and_output = + fcx.tcx.mk_type_list(inputs_and_output.iter().enumerate().map(|(i, ty)| { + fcx.normalize_associated_types_in_wf( + span, + ty, + WellFormedLoc::Param { + function: def_id.expect_local(), + // Note that the `param_idx` of the output type is + // one greater than the index of the last input type. + param_idx: i.try_into().unwrap(), + }, + ) + })); + // Manually call `normalize_assocaited_types_in` on the other types + // in `FnSig`. This ensures that if the types of these fields + // ever change to include projections, we will start normalizing + // them automatically. + let sig = ty::FnSig { + inputs_and_output, + c_variadic: fcx.normalize_associated_types_in(span, c_variadic), + unsafety: fcx.normalize_associated_types_in(span, unsafety), + abi: fcx.normalize_associated_types_in(span, abi), + }; + + for (i, (&input_ty, ty)) in iter::zip(sig.inputs(), hir_decl.inputs).enumerate() { + fcx.register_wf_obligation( + input_ty.into(), + ty.span, + ObligationCauseCode::WellFormed(Some(WellFormedLoc::Param { + function: def_id.expect_local(), + param_idx: i.try_into().unwrap(), + })), + ); } + implied_bounds.extend(sig.inputs()); fcx.register_wf_obligation( diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 506ca98b96026..1a4c2eb515584 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -35,7 +35,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::weak_lang_items; use rustc_hir::{GenericParamKind, HirId, Node}; -use rustc_middle::hir::map::blocks::FnLikeNode; use rustc_middle::hir::map::Map; use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs}; use rustc_middle::mir::mono::Linkage; @@ -358,11 +357,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { } fn default_constness_for_trait_bounds(&self) -> hir::Constness { - if let Some(fn_like) = FnLikeNode::from_node(self.node()) { - fn_like.constness() - } else { - hir::Constness::NotConst - } + self.node().constness() } fn get_type_parameter_bounds( diff --git a/compiler/rustc_typeck/src/hir_wf_check.rs b/compiler/rustc_typeck/src/hir_wf_check.rs index a8ec7b79e571f..c1af10f5ce451 100644 --- a/compiler/rustc_typeck/src/hir_wf_check.rs +++ b/compiler/rustc_typeck/src/hir_wf_check.rs @@ -3,10 +3,10 @@ use rustc_hir as hir; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::HirId; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::ObligationCause; use rustc_infer::traits::TraitEngine; +use rustc_infer::traits::{ObligationCause, WellFormedLoc}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, ToPredicate, TyCtxt}; +use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder}; use rustc_trait_selection::traits; pub fn provide(providers: &mut Providers) { @@ -17,21 +17,20 @@ pub fn provide(providers: &mut Providers) { // need access to `ItemCtxt` fn diagnostic_hir_wf_check<'tcx>( tcx: TyCtxt<'tcx>, - (predicate, hir_id): (ty::Predicate<'tcx>, HirId), + (predicate, loc): (ty::Predicate<'tcx>, WellFormedLoc), ) -> Option> { let hir = tcx.hir(); - // HIR wfcheck should only ever happen as part of improving an existing error - tcx.sess.delay_span_bug(hir.span(hir_id), "Performed HIR wfcheck without an existing error!"); - // Currently, we only handle WF checking for items (e.g. associated items). - // It would be nice to extend this to handle wf checks inside functions. - let def_id = match tcx.hir().opt_local_def_id(hir_id) { - Some(def_id) => def_id, - None => return None, + let def_id = match loc { + WellFormedLoc::Ty(def_id) => def_id, + WellFormedLoc::Param { function, param_idx: _ } => function, }; + let hir_id = HirId::make_owner(def_id); + + // HIR wfcheck should only ever happen as part of improving an existing error + tcx.sess + .delay_span_bug(tcx.def_span(def_id), "Performed HIR wfcheck without an existing error!"); - // FIXME - figure out how we want to handle wf-checking for - // things inside a function body. let icx = ItemCtxt::new(tcx, def_id.to_def_id()); // To perform HIR-based WF checking, we iterate over all HIR types @@ -72,7 +71,8 @@ fn diagnostic_hir_wf_check<'tcx>( fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { self.tcx.infer_ctxt().enter(|infcx| { let mut fulfill = traits::FulfillmentContext::new(); - let tcx_ty = self.icx.to_ty(ty); + let tcx_ty = + self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx }); let cause = traits::ObligationCause::new( ty.span, self.hir_id, @@ -119,19 +119,66 @@ fn diagnostic_hir_wf_check<'tcx>( depth: 0, }; - let ty = match tcx.hir().get(hir_id) { - hir::Node::ImplItem(item) => match item.kind { - hir::ImplItemKind::TyAlias(ty) => Some(ty), - _ => None, - }, - hir::Node::TraitItem(item) => match item.kind { - hir::TraitItemKind::Type(_, ty) => ty, - _ => None, + // Get the starting `hir::Ty` using our `WellFormedLoc`. + // We will walk 'into' this type to try to find + // a more precise span for our predicate. + let ty = match loc { + WellFormedLoc::Ty(_) => match hir.get(hir_id) { + hir::Node::ImplItem(item) => match item.kind { + hir::ImplItemKind::TyAlias(ty) => Some(ty), + ref item => bug!("Unexpected ImplItem {:?}", item), + }, + hir::Node::TraitItem(item) => match item.kind { + hir::TraitItemKind::Type(_, ty) => ty, + ref item => bug!("Unexpected TraitItem {:?}", item), + }, + hir::Node::Item(item) => match item.kind { + hir::ItemKind::Static(ty, _, _) | hir::ItemKind::Const(ty, _) => Some(ty), + hir::ItemKind::Impl(ref impl_) => { + assert!(impl_.of_trait.is_none(), "Unexpected trait impl: {:?}", impl_); + Some(impl_.self_ty) + } + ref item => bug!("Unexpected item {:?}", item), + }, + ref node => bug!("Unexpected node {:?}", node), }, - _ => None, + WellFormedLoc::Param { function: _, param_idx } => { + let fn_decl = hir.fn_decl_by_hir_id(hir_id).unwrap(); + // Get return type + if param_idx as usize == fn_decl.inputs.len() { + match fn_decl.output { + hir::FnRetTy::Return(ty) => Some(ty), + // The unit type `()` is always well-formed + hir::FnRetTy::DefaultReturn(_span) => None, + } + } else { + Some(&fn_decl.inputs[param_idx as usize]) + } + } }; if let Some(ty) = ty { visitor.visit_ty(ty); } visitor.cause } + +struct EraseAllBoundRegions<'tcx> { + tcx: TyCtxt<'tcx>, +} + +// Higher ranked regions are complicated. +// To make matters worse, the HIR WF check can instantiate them +// outside of a `Binder`, due to the way we (ab)use +// `ItemCtxt::to_ty`. To make things simpler, we just erase all +// of them, regardless of depth. At worse, this will give +// us an inaccurate span for an error message, but cannot +// lead to unsoundess (we call `delay_span_bug` at the start +// of `diagnostic_hir_wf_check`). +impl<'tcx> TypeFolder<'tcx> for EraseAllBoundRegions<'tcx> { + fn tcx<'a>(&'a self) -> TyCtxt<'tcx> { + self.tcx + } + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + if let ty::ReLateBound(..) = r { &ty::ReErased } else { r } + } +} diff --git a/library/std/src/sys/unix/args.rs b/library/std/src/sys/unix/args.rs index ad93fa610c481..0bd1ea645779f 100644 --- a/library/std/src/sys/unix/args.rs +++ b/library/std/src/sys/unix/args.rs @@ -77,10 +77,18 @@ mod imp { use crate::ptr; use crate::sync::atomic::{AtomicIsize, AtomicPtr, Ordering}; + // The system-provided argc and argv, which we store in static memory + // here so that we can defer the work of parsing them until its actually + // needed. + // + // Note that we never mutate argv/argc, the argv array, or the argv + // strings, which allows the code in this file to be very simple. static ARGC: AtomicIsize = AtomicIsize::new(0); static ARGV: AtomicPtr<*const u8> = AtomicPtr::new(ptr::null_mut()); unsafe fn really_init(argc: isize, argv: *const *const u8) { + // These don't need to be ordered with each other or other stores, + // because they only hold the unmodified system-provide argv/argc. ARGC.store(argc, Ordering::Relaxed); ARGV.store(argv as *mut _, Ordering::Relaxed); } @@ -122,8 +130,14 @@ mod imp { fn clone() -> Vec { unsafe { - // Load ARGC and ARGV without a lock. If the store to either ARGV or - // ARGC isn't visible yet, we'll return an empty argument list. + // Load ARGC and ARGV, which hold the unmodified system-provided + // argc/argv, so we can read the pointed-to memory without atomics + // or synchronization. + // + // If either ARGC or ARGV is still zero or null, then either there + // really are no arguments, or someone is asking for `args()` + // before initialization has completed, and we return an empty + // list. let argv = ARGV.load(Ordering::Relaxed); let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) }; (0..argc) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 8c28d0b60fa32..77d2684b5d2a4 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -2,7 +2,7 @@ //! library. //! //! This module contains some of the real meat in the rustbuild build system -//! which is where Cargo is used to compiler the standard library, libtest, and +//! which is where Cargo is used to compile the standard library, libtest, and //! compiler. This module is also responsible for assembling the sysroot as it //! goes along from the output of the previous stage. diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index e21469dc9c343..908e292d968ef 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -57,7 +57,7 @@ pub(crate) fn opts() -> Options { /// A subset of [`opts()`] used for rendering summaries. pub(crate) fn summary_opts() -> Options { - Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION + Options::ENABLE_STRIKETHROUGH | Options::ENABLE_SMART_PUNCTUATION | Options::ENABLE_TABLES } /// When `to_string` is called, this struct will emit the HTML corresponding to @@ -522,6 +522,10 @@ fn check_if_allowed_tag(t: &Tag<'_>) -> bool { ) } +fn is_forbidden_tag(t: &Tag<'_>) -> bool { + matches!(t, Tag::CodeBlock(_) | Tag::Table(_) | Tag::TableHead | Tag::TableRow | Tag::TableCell) +} + impl<'a, I: Iterator>> Iterator for SummaryLine<'a, I> { type Item = Event<'a>; @@ -535,14 +539,17 @@ impl<'a, I: Iterator>> Iterator for SummaryLine<'a, I> { if let Some(event) = self.inner.next() { let mut is_start = true; let is_allowed_tag = match event { - Event::Start(Tag::CodeBlock(_)) | Event::End(Tag::CodeBlock(_)) => { - return None; - } Event::Start(ref c) => { + if is_forbidden_tag(c) { + return None; + } self.depth += 1; check_if_allowed_tag(c) } Event::End(ref c) => { + if is_forbidden_tag(c) { + return None; + } self.depth -= 1; is_start = false; check_if_allowed_tag(c) diff --git a/src/test/codegen/pgo-instrumentation.rs b/src/test/codegen/pgo-instrumentation.rs index c085f3c829ea4..05c2d2fc0d8c1 100644 --- a/src/test/codegen/pgo-instrumentation.rs +++ b/src/test/codegen/pgo-instrumentation.rs @@ -1,8 +1,7 @@ // Test that `-Cprofile-generate` creates expected instrumentation artifacts in LLVM IR. -// Compiling with `-Cpanic=abort` because PGO+unwinding isn't supported on all platforms. // needs-profiler-support -// compile-flags: -Cprofile-generate -Ccodegen-units=1 -Cpanic=abort +// compile-flags: -Cprofile-generate -Ccodegen-units=1 // CHECK: @__llvm_profile_raw_version = // CHECK-DAG: @__profc_{{.*}}pgo_instrumentation{{.*}}some_function{{.*}} = {{.*}}global diff --git a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile index 18828b66ce874..9773e3f1fdfc4 100644 --- a/src/test/run-make-fulldeps/pgo-branch-weights/Makefile +++ b/src/test/run-make-fulldeps/pgo-branch-weights/Makefile @@ -6,19 +6,6 @@ -include ../tools.mk -# This test makes sure that instrumented binaries record the right counts for -# functions being called and branches being taken. We run an instrumented binary -# with an argument that causes a know path through the program and then check -# that the expected counts get added to the use-phase LLVM IR. - -# LLVM doesn't support instrumenting binaries that use SEH: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMMON_FLAGS=-Cpanic=abort -endif - # For some very small programs GNU ld seems to not properly handle # instrumentation sections correctly. Neither Gold nor LLD have that problem. ifeq ($(UNAME),Linux) diff --git a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile index f1ac39aa0ea8a..a7d5c56163257 100644 --- a/src/test/run-make-fulldeps/pgo-gen-lto/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-lto/Makefile @@ -8,14 +8,6 @@ COMPILE_FLAGS=-Copt-level=3 -Clto=fat -Cprofile-generate="$(TMPDIR)" -# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMPILE_FLAGS+= -Cpanic=abort -endif - all: $(RUSTC) $(COMPILE_FLAGS) test.rs $(call RUN,test) || exit 1 diff --git a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile index 3fbfeb09eb373..425bfc28a9766 100644 --- a/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile @@ -4,14 +4,6 @@ COMPILE_FLAGS=-O -Ccodegen-units=1 -Cprofile-generate="$(TMPDIR)" -# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMPILE_FLAGS+= -Cpanic=abort -endif - all: $(RUSTC) $(COMPILE_FLAGS) --emit=llvm-ir test.rs # We expect symbols starting with "__llvm_profile_". diff --git a/src/test/run-make-fulldeps/pgo-gen/Makefile b/src/test/run-make-fulldeps/pgo-gen/Makefile index 69b19801bf091..6533355be3418 100644 --- a/src/test/run-make-fulldeps/pgo-gen/Makefile +++ b/src/test/run-make-fulldeps/pgo-gen/Makefile @@ -8,14 +8,6 @@ COMPILE_FLAGS=-g -Cprofile-generate="$(TMPDIR)" -# LLVM doesn't yet support instrumenting binaries that use unwinding on MSVC: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMPILE_FLAGS+= -Cpanic=abort -endif - all: $(RUSTC) $(COMPILE_FLAGS) test.rs $(call RUN,test) || exit 1 diff --git a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile index 876a9b2c43991..c0195dcbb31be 100644 --- a/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile +++ b/src/test/run-make-fulldeps/pgo-indirect-call-promotion/Makefile @@ -6,20 +6,6 @@ -include ../tools.mk -# This test makes sure that indirect call promotion is performed. The test -# programs calls the same function a thousand times through a function pointer. -# Only PGO data provides the information that it actually always is the same -# function. We verify that the indirect call promotion pass inserts a check -# whether it can make a direct call instead of the indirect call. - -# LLVM doesn't support instrumenting binaries that use SEH: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMMON_FLAGS=-Cpanic=abort -endif - all: # We don't compile `opaque` with either optimizations or instrumentation. # We don't compile `opaque` with either optimizations or instrumentation. diff --git a/src/test/run-make-fulldeps/pgo-use/Makefile b/src/test/run-make-fulldeps/pgo-use/Makefile index 01bc211df1616..d7863c9c587a5 100644 --- a/src/test/run-make-fulldeps/pgo-use/Makefile +++ b/src/test/run-make-fulldeps/pgo-use/Makefile @@ -18,14 +18,6 @@ COMMON_FLAGS=-Copt-level=2 -Ccodegen-units=1 -Cllvm-args=-disable-preinline -# LLVM doesn't support instrumenting binaries that use SEH: -# https://github.com/rust-lang/rust/issues/61002 -# -# Things work fine with -Cpanic=abort though. -ifdef IS_MSVC -COMMON_FLAGS+= -Cpanic=abort -endif - ifeq ($(UNAME),Darwin) # macOS does not have the `tac` command, but `tail -r` does the same thing TAC := tail -r diff --git a/src/test/rustdoc-gui/item-summary-table.goml b/src/test/rustdoc-gui/item-summary-table.goml new file mode 100644 index 0000000000000..6bf4e288c4377 --- /dev/null +++ b/src/test/rustdoc-gui/item-summary-table.goml @@ -0,0 +1,6 @@ +// This test ensures that elements aren't display in items summary. +goto: file://|DOC_PATH|/lib2/summary_table/index.html +// We check that we picked the right item first. +assert-text: (".item-table .item-left", "Foo") +// Then we check that its summary is empty. +assert-text: (".item-table .item-right", "") diff --git a/src/test/rustdoc-gui/src/lib2/lib.rs b/src/test/rustdoc-gui/src/lib2/lib.rs index cd00348cad3d1..d18c91d48680b 100644 --- a/src/test/rustdoc-gui/src/lib2/lib.rs +++ b/src/test/rustdoc-gui/src/lib2/lib.rs @@ -57,3 +57,10 @@ pub mod long_trait { pub trait ALongNameBecauseItHelpsTestingTheCurrentProblem: DerefMut + From + Send + Sync + AsRef + 'static {} } + +pub mod summary_table { + /// | header 1 | header 2 | + /// | -------- | -------- | + /// | content | content | + pub struct Foo; +} diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs index 73b23da5bcb66..7950dd3e99e29 100644 --- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.rs @@ -29,7 +29,6 @@ impl Bar for AssocNoCopy { impl Thing for AssocNoCopy { type Out = Box>; //~^ ERROR the trait bound `String: Copy` is not satisfied - //~| ERROR the trait bound `String: Copy` is not satisfied fn func() -> Self::Out { Box::new(AssocNoCopy) diff --git a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr index 414d74d4786d9..0f1d35be0eb7a 100644 --- a/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr +++ b/src/test/ui/associated-type-bounds/assoc-type-eq-with-dyn-atb-fail.stderr @@ -4,12 +4,6 @@ error[E0277]: the trait bound `String: Copy` is not satisfied LL | type Out = Box>; | ^^^^^^^^^^^ the trait `Copy` is not implemented for `String` -error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/assoc-type-eq-with-dyn-atb-fail.rs:30:28 - | -LL | type Out = Box>; - | ^^^^^^^^^^^ the trait `Copy` is not implemented for `String` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr index e8c11a32bf7fd..25e80159b0b18 100644 --- a/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr +++ b/src/test/ui/associated-types/associated-types-for-unimpl-trait.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-for-unimpl-trait.rs:10:8 + --> $DIR/associated-types-for-unimpl-trait.rs:10:40 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr index e3be434698ab9..19500f58aa688 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-bound.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `T: Get` is not satisfied - --> $DIR/associated-types-no-suitable-bound.rs:11:8 + --> $DIR/associated-types-no-suitable-bound.rs:11:21 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn uhoh(foo: ::Value) {} - | ^^^^ the trait `Get` is not implemented for `T` + | ^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr index 9dc3414e9edf0..0e978f20a6634 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait-2.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:8 + --> $DIR/associated-types-no-suitable-supertrait-2.rs:17:40 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr index c2aed3f9de548..1ec3c05983aef 100644 --- a/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr +++ b/src/test/ui/associated-types/associated-types-no-suitable-supertrait.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:17:8 + --> $DIR/associated-types-no-suitable-supertrait.rs:17:40 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn uhoh(&self, foo: U, bar: ::Value) {} - | ^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | @@ -10,10 +13,13 @@ LL | fn uhoh(&self, foo: U, bar: ::Value) where Self: Ge | ^^^^^^^^^^^^^^^ error[E0277]: the trait bound `(T, U): Get` is not satisfied - --> $DIR/associated-types-no-suitable-supertrait.rs:22:8 + --> $DIR/associated-types-no-suitable-supertrait.rs:22:40 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn uhoh(&self, foo: U, bar: <(T, U) as Get>::Value) {} - | ^^^^ the trait `Get` is not implemented for `(T, U)` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `(T, U)` error: aborting due to 2 previous errors diff --git a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr index fb842d968676d..b6ee1ed733c3e 100644 --- a/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr +++ b/src/test/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `Self: Get` is not satisfied - --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:8 + --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40 | +LL | trait Get { + | --------- required by this bound in `Get` +... LL | fn okay(&self, foo: U, bar: ::Value); - | ^^^^ the trait `Get` is not implemented for `Self` + | ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr b/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr index e0e6029252c00..319e6c2c032a0 100644 --- a/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr +++ b/src/test/ui/const-generics/const_evaluatable_checked/object-safety-err-ret.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/object-safety-err-ret.rs:17:15 + --> $DIR/object-safety-err-ret.rs:17:16 | LL | fn use_dyn(v: &dyn Foo) { - | ^^^^^^^^ `Foo` cannot be made into an object + | ^^^^^^^ `Foo` cannot be made into an object | = help: consider moving `test` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr index eb68a6298d1ac..cead9776e4abb 100644 --- a/src/test/ui/error-codes/E0038.stderr +++ b/src/test/ui/error-codes/E0038.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/E0038.rs:5:16 + --> $DIR/E0038.rs:5:20 | LL | fn call_foo(x: Box) { - | ^^^^^^^^^^^^^^ `Trait` cannot be made into an object + | ^^^^^^^^^ `Trait` cannot be made into an object | = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr index 12195bc1071a0..c13c05f146a7e 100644 --- a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr +++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `NonObjectSafe1` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:38 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:39 | LL | fn takes_non_object_safe_ref(obj: &dyn NonObjectSafe1) { - | ^^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe1` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/feature-gate-object_safe_for_dispatch.rs:4:23 @@ -35,10 +35,10 @@ LL | fn static_fn() where Self: Sized {} | ^^^^^^^^^^^^^^^^^ error[E0038]: the trait `NonObjectSafe3` cannot be made into an object - --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:35 + --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:39 | LL | fn takes_non_object_safe_box(obj: Box) { - | ^^^^^^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^ `NonObjectSafe3` cannot be made into an object | = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr index 50ce6427e8b58..a3ced35155f37 100644 --- a/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr +++ b/src/test/ui/feature-gates/feature-gate-optimize_attribute.stderr @@ -51,4 +51,5 @@ LL | #[optimize(banana)] error: aborting due to 6 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0658, E0722. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr index eb8e101a83d79..8651789688eaa 100644 --- a/src/test/ui/generic-associated-types/gat-in-trait-path.stderr +++ b/src/test/ui/generic-associated-types/gat-in-trait-path.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/gat-in-trait-path.rs:21:13 + --> $DIR/gat-in-trait-path.rs:21:17 | LL | fn f(_arg : Box Foo = &'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object | = help: consider moving `A` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/generic-associated-types/issue-67510-pass.stderr b/src/test/ui/generic-associated-types/issue-67510-pass.stderr index 8cc9f2816a166..b4b89ab047363 100644 --- a/src/test/ui/generic-associated-types/issue-67510-pass.stderr +++ b/src/test/ui/generic-associated-types/issue-67510-pass.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `X` cannot be made into an object - --> $DIR/issue-67510-pass.rs:7:19 + --> $DIR/issue-67510-pass.rs:7:23 | LL | fn _func1<'a>(_x: Box=&'a ()>>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object | = help: consider moving `Y` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/generic-associated-types/trait-objects.stderr b/src/test/ui/generic-associated-types/trait-objects.stderr index a121566bbd884..6429bb8159e1f 100644 --- a/src/test/ui/generic-associated-types/trait-objects.stderr +++ b/src/test/ui/generic-associated-types/trait-objects.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `StreamingIterator` cannot be made into an object - --> $DIR/trait-objects.rs:10:16 + --> $DIR/trait-objects.rs:10:21 | LL | fn min_size(x: &mut dyn for<'a> StreamingIterator = &'a i32>) -> usize { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `StreamingIterator` cannot be made into an object | = help: consider moving `Item` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/impl-trait/auto-trait-leak.rs b/src/test/ui/impl-trait/auto-trait-leak.rs index 087f4582b21c3..c2fbbf94fd666 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.rs +++ b/src/test/ui/impl-trait/auto-trait-leak.rs @@ -12,7 +12,6 @@ fn main() { fn cycle1() -> impl Clone { //~^ ERROR cycle detected send(cycle2().clone()); - //~^ ERROR cannot be sent between threads safely Rc::new(Cell::new(5)) } diff --git a/src/test/ui/impl-trait/auto-trait-leak.stderr b/src/test/ui/impl-trait/auto-trait-leak.stderr index e578c4b4f819e..3eb141cc2bb55 100644 --- a/src/test/ui/impl-trait/auto-trait-leak.stderr +++ b/src/test/ui/impl-trait/auto-trait-leak.stderr @@ -36,37 +36,37 @@ LL | fn cycle1() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which requires evaluating trait selection obligation `impl std::clone::Clone: std::marker::Send`... note: ...which requires computing type of `cycle2::{opaque#0}`... - --> $DIR/auto-trait-leak.rs:20:16 + --> $DIR/auto-trait-leak.rs:19:16 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^ note: ...which requires borrow-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires processing MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires unsafety-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires building MIR for `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ note: ...which requires type-checking `cycle2`... - --> $DIR/auto-trait-leak.rs:20:1 + --> $DIR/auto-trait-leak.rs:19:1 | LL | fn cycle2() -> impl Clone { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -84,22 +84,6 @@ LL | | Rc::new(String::from("foo")) LL | | } | |_^ -error[E0277]: `Rc` cannot be sent between threads safely - --> $DIR/auto-trait-leak.rs:14:5 - | -LL | fn send(_: T) {} - | ---- required by this bound in `send` -... -LL | send(cycle2().clone()); - | ^^^^ `Rc` cannot be sent between threads safely -... -LL | fn cycle2() -> impl Clone { - | ---------- within this `impl Clone` - | - = help: within `impl Clone`, the trait `Send` is not implemented for `Rc` - = note: required because it appears within the type `impl Clone` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0277, E0391. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0391`. diff --git a/src/test/ui/impl-trait/issue-86465.rs b/src/test/ui/impl-trait/issue-86465.rs new file mode 100644 index 0000000000000..23a3748c12c6a --- /dev/null +++ b/src/test/ui/impl-trait/issue-86465.rs @@ -0,0 +1,10 @@ +#![feature(min_type_alias_impl_trait)] + +type X<'a, 'b> = impl std::fmt::Debug; + +fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) { + //~^ ERROR concrete type differs from previous defining opaque type use + (a, a) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/issue-86465.stderr b/src/test/ui/impl-trait/issue-86465.stderr new file mode 100644 index 0000000000000..595b16aa68554 --- /dev/null +++ b/src/test/ui/impl-trait/issue-86465.stderr @@ -0,0 +1,14 @@ +error: concrete type differs from previous defining opaque type use + --> $DIR/issue-86465.rs:5:1 + | +LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&'a u32`, got `&'b u32` + | +note: previous use here + --> $DIR/issue-86465.rs:5:1 + | +LL | fn f<'t, 'u>(a: &'t u32, b: &'u u32) -> (X<'t, 'u>, X<'u, 't>) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 4372de245078f..e9d6208773454 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -9,7 +9,7 @@ LL | fn elided(x: &i32) -> impl Copy { x } help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | LL | fn elided(x: &i32) -> impl Copy + '_ { x } - | ^^^^^^^^^^^^^^ + | ^^^^ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:5:32 @@ -23,7 +23,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } - | ^^^^^^^^^^^^^^ + | ^^^^ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:7:46 diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr index 65178cc9d24c2..6c5264671a912 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -9,7 +9,7 @@ LL | fn iter_values_anon(&self) -> impl Iterator { help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ error: lifetime may not live long enough --> $DIR/static-return-lifetime-infered.rs:9:37 @@ -23,7 +23,7 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator { help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-18611.stderr b/src/test/ui/issues/issue-18611.stderr index 8872f51753c94..0e942e80e2544 100644 --- a/src/test/ui/issues/issue-18611.stderr +++ b/src/test/ui/issues/issue-18611.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `isize: HasState` is not satisfied - --> $DIR/issue-18611.rs:1:4 + --> $DIR/issue-18611.rs:1:18 | LL | fn add_state(op: ::State) { - | ^^^^^^^^^ the trait `HasState` is not implemented for `isize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `HasState` is not implemented for `isize` +... +LL | trait HasState { + | -------------- required by this bound in `HasState` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr index 86b530e85a80a..2a5416ce85ba6 100644 --- a/src/test/ui/issues/issue-18959.stderr +++ b/src/test/ui/issues/issue-18959.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Bar` cannot be made into an object - --> $DIR/issue-18959.rs:11:11 + --> $DIR/issue-18959.rs:11:12 | LL | fn foo(b: &dyn Bar) { - | ^^^^^^^^ `Bar` cannot be made into an object + | ^^^^^^^ `Bar` cannot be made into an object | = help: consider moving `foo` to another trait note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit diff --git a/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs new file mode 100644 index 0000000000000..536c1d7374023 --- /dev/null +++ b/src/test/ui/rfc-2632-const-trait-impl/call-generic-in-impl.rs @@ -0,0 +1,15 @@ +// check-pass +#![feature(const_fn_trait_bound)] +#![feature(const_trait_impl)] + +trait MyPartialEq { + fn eq(&self, other: &Self) -> bool; +} + +impl const MyPartialEq for T { + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(self, other) + } +} + +fn main() {} diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr index f2e556c63cbf3..a678731934f6e 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr @@ -9,7 +9,7 @@ LL | async fn f(self: Pin<&Self>) -> impl Clone { self } help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } - | ^^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr index 73766c31b93b6..962593e411e92 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait.nll.stderr @@ -9,7 +9,7 @@ LL | fn f(self: Pin<&Self>) -> impl Clone { self } help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | LL | fn f(self: Pin<&Self>) -> impl Clone + '_ { self } - | ^^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to previous error diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr index 2407d13714a2a..05ba7808600b0 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr @@ -9,7 +9,7 @@ LL | fn iter(&self) -> impl Iterator> { help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound | LL | fn iter(&self) -> impl Iterator> + '_ { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ error: lifetime may not live long enough --> $DIR/trait-object-nested-in-impl-trait.rs:39:9 @@ -47,7 +47,7 @@ LL | fn iter<'a>(&'a self) -> impl Iterator> { help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound | LL | fn iter<'a>(&'a self) -> impl Iterator> + 'a { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr index 797406f869fe6..f332b7213d8bc 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-references-self.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/object-unsafe-trait-references-self.rs:6:11 + --> $DIR/object-unsafe-trait-references-self.rs:6:12 | LL | fn bar(x: &dyn Trait) {} - | ^^^^^^^^^^ `Trait` cannot be made into an object + | ^^^^^^^^^ `Trait` cannot be made into an object | = help: consider moving `baz` to another trait = help: consider moving `bat` to another trait @@ -17,10 +17,10 @@ LL | fn bat(&self) -> Self {} | ^^^^ ...because method `bat` references the `Self` type in its return type error[E0038]: the trait `Other` cannot be made into an object - --> $DIR/object-unsafe-trait-references-self.rs:10:11 + --> $DIR/object-unsafe-trait-references-self.rs:10:12 | LL | fn foo(x: &dyn Other) {} - | ^^^^^^^^^^ `Other` cannot be made into an object + | ^^^^^^^^^ `Other` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-unsafe-trait-references-self.rs:8:14 diff --git a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr index a2caf846cc5fe..4c18f6d79d077 100644 --- a/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr +++ b/src/test/ui/suggestions/object-unsafe-trait-should-use-where-sized.stderr @@ -1,8 +1,8 @@ error[E0038]: the trait `Trait` cannot be made into an object - --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:11 + --> $DIR/object-unsafe-trait-should-use-where-sized.rs:9:12 | LL | fn bar(x: &dyn Trait) {} - | ^^^^^^^^^^ `Trait` cannot be made into an object + | ^^^^^^^^^ `Trait` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit --> $DIR/object-unsafe-trait-should-use-where-sized.rs:5:8 diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr index 6394a1f8e8509..90a753b5a6de1 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.full_tait.stderr @@ -36,16 +36,7 @@ LL | type WrongGeneric = impl 'static; LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:12:24 - | -LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - = note: ...so that the type `T` will meet its required lifetime bounds - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0308, E0310. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr index 49ead8b094c19..e50282201074e 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.min_tait.stderr @@ -27,16 +27,7 @@ LL | type WrongGeneric = impl 'static; LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound...: `T: 'static` -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:12:24 - | -LL | type WrongGeneric = impl 'static; - | ^^^^^^^^^^^^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - = note: ...so that the type `T` will meet its required lifetime bounds - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0308, E0310. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs index 3dda34ff668ce..9f647d9e737fe 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.rs @@ -11,7 +11,6 @@ fn main() { type WrongGeneric = impl 'static; //~^ ERROR the parameter type `T` may not live long enough -//~| ERROR the parameter type `T` may not live long enough //~| ERROR: at least one trait must be specified fn wrong_generic(t: T) -> WrongGeneric { diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr index d90f328708a7b..61e8da91bbaa9 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.full_tait.stderr @@ -16,52 +16,5 @@ LL | type Bar = impl Baz; = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error: aborting due to 5 previous errors; 1 warning emitted +error: aborting due to previous error; 1 warning emitted -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr index d019f40757eed..f65e91e52c713 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.min_tait.stderr @@ -7,52 +7,5 @@ LL | type Bar = impl Baz; = note: closure with signature `fn(&'2 X) -> &X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error[E0308]: mismatched types - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other - | - = note: expected type `for<'r> Fn<(&'r X,)>` - found type `Fn<(&' X,)>` -note: this closure does not fulfill the lifetime requirements - --> $DIR/issue-57611-trait-alias.rs:28:9 - | -LL | |x| x - | ^^^^^ - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-57611-trait-alias.rs:20:16 - | -LL | type Bar = impl Baz; - | ^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 X) -> &'2 X` must implement `FnOnce<(&'1 X,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 X,)>`, for some specific lifetime `'2` - -error: aborting due to 5 previous errors +error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs index ccc727e0bf01b..508ecdd88a482 100644 --- a/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs +++ b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs @@ -19,10 +19,6 @@ struct X; impl Foo for X { type Bar = impl Baz; //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough - //~| ERROR mismatched types - //~| ERROR mismatched types fn bar(&self) -> Self::Bar { |x| x diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.rs b/src/test/ui/type-alias-impl-trait/issue-60371.rs index b7c8a58a65629..cee5e5a01cc2a 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60371.rs @@ -9,7 +9,6 @@ trait Bug { impl Bug for &() { type Item = impl Bug; //~ ERROR `impl Trait` in type aliases is unstable //~^ ERROR the trait bound `(): Bug` is not satisfied - //~^^ ERROR the trait bound `(): Bug` is not satisfied const FUN: fn() -> Self::Item = || (); //~^ ERROR type alias impl trait is not permitted here diff --git a/src/test/ui/type-alias-impl-trait/issue-60371.stderr b/src/test/ui/type-alias-impl-trait/issue-60371.stderr index 4906ea9c2e261..a9df74689df29 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60371.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60371.stderr @@ -8,7 +8,7 @@ LL | type Item = impl Bug; = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable error[E0658]: type alias impl trait is not permitted here - --> $DIR/issue-60371.rs:14:40 + --> $DIR/issue-60371.rs:13:40 | LL | const FUN: fn() -> Self::Item = || (); | ^ @@ -25,16 +25,7 @@ LL | type Item = impl Bug; = help: the following implementations were found: <&() as Bug> -error[E0277]: the trait bound `(): Bug` is not satisfied - --> $DIR/issue-60371.rs:10:17 - | -LL | type Item = impl Bug; - | ^^^^^^^^ the trait `Bug` is not implemented for `()` - | - = help: the following implementations were found: - <&() as Bug> - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0277, E0658. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.rs b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs new file mode 100644 index 0000000000000..4b0f2afee5484 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.rs @@ -0,0 +1,19 @@ +#![feature(member_constraints)] +#![feature(type_alias_impl_trait)] +//~^ WARN incomplete + +pub trait A { + type B; + fn f(&self) -> Self::B; +} +impl<'a, 'b> A for () { + //~^ ERROR the lifetime parameter `'a` is not constrained + //~| ERROR the lifetime parameter `'b` is not constrained + type B = impl core::fmt::Debug; + //~^ ERROR is unstable + + + fn f(&self) -> Self::B {} +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr new file mode 100644 index 0000000000000..4506a6e23d5c0 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-74761-2.stderr @@ -0,0 +1,34 @@ +error[E0658]: `impl Trait` in type aliases is unstable + --> $DIR/issue-74761-2.rs:12:14 + | +LL | type B = impl core::fmt::Debug; + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #63063 for more information + = help: add `#![feature(min_type_alias_impl_trait)]` to the crate attributes to enable + +warning: the feature `type_alias_impl_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/issue-74761-2.rs:2:12 + | +LL | #![feature(type_alias_impl_trait)] + | ^^^^^^^^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + = note: see issue #63063 for more information + +error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:9:6 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error[E0207]: the lifetime parameter `'b` is not constrained by the impl trait, self type, or predicates + --> $DIR/issue-74761-2.rs:9:10 + | +LL | impl<'a, 'b> A for () { + | ^^ unconstrained lifetime parameter + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0207, E0658. +For more information about an error, try `rustc --explain E0207`. diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs index 38aa18fe40ee7..11756017ad846 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.rs @@ -5,9 +5,9 @@ #![feature(min_type_alias_impl_trait)] type X = impl ToString; -//~^ ERROR could not find defining uses fn f(a: A, b: B) -> (X, X) { + //~^ ERROR concrete type differs from previous defining opaque type (a.clone(), a) } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr index c00973c0761b0..52b0462de988c 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn2.stderr @@ -1,8 +1,14 @@ -error: could not find defining uses - --> $DIR/multiple-def-uses-in-one-fn2.rs:7:52 +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 | -LL | type X = impl ToString; - | ^^^^^^^^^^^^^ +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `B` + | +note: previous use here + --> $DIR/multiple-def-uses-in-one-fn2.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs index 17e900058113d..5f25365666c7f 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.rs @@ -11,6 +11,7 @@ fn f(a: A, b: B) -> (X, X) } fn g(a: A, b: B) -> (X, X) { + //~^ ERROR concrete type differs from previous defining opaque type (a, b) //~^ ERROR mismatched types } diff --git a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr index bbe709dccab4e..3d943b77af57d 100644 --- a/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr +++ b/src/test/ui/type-alias-impl-trait/multiple-def-uses-in-one-fn3.stderr @@ -1,10 +1,11 @@ error[E0308]: mismatched types - --> $DIR/multiple-def-uses-in-one-fn3.rs:14:9 + --> $DIR/multiple-def-uses-in-one-fn3.rs:15:9 | LL | fn g(a: A, b: B) -> (X, X) { | - - found type parameter | | | expected type parameter +LL | LL | (a, b) | ^ expected type parameter `A`, found type parameter `B` | @@ -13,6 +14,18 @@ LL | (a, b) = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters -error: aborting due to previous error +error: concrete type differs from previous defining opaque type use + --> $DIR/multiple-def-uses-in-one-fn3.rs:13:1 + | +LL | fn g(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `A`, got `[type error]` + | +note: previous use here + --> $DIR/multiple-def-uses-in-one-fn3.rs:9:1 + | +LL | fn f(a: A, b: B) -> (X, X) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr index a0eb7d10bd94a..f6b48938f9b04 100644 --- a/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr +++ b/src/test/ui/wf/wf-foreign-fn-decl-ret.stderr @@ -1,8 +1,11 @@ error[E0277]: the trait bound `(): Foo` is not satisfied - --> $DIR/wf-foreign-fn-decl-ret.rs:11:12 + --> $DIR/wf-foreign-fn-decl-ret.rs:11:25 | +LL | pub trait Foo { + | ------------- required by this bound in `Foo` +... LL | pub fn lint_me() -> <() as Foo>::Assoc; - | ^^^^^^^ the trait `Foo` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` error[E0277]: the trait bound `u32: Unsatisfied` is not satisfied --> $DIR/wf-foreign-fn-decl-ret.rs:14:32 diff --git a/src/test/ui/wf/wf-in-fn-arg.stderr b/src/test/ui/wf/wf-in-fn-arg.stderr index 9687658feba43..ca90e9222dea9 100644 --- a/src/test/ui/wf/wf-in-fn-arg.stderr +++ b/src/test/ui/wf/wf-in-fn-arg.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/wf-in-fn-arg.rs:10:14 + --> $DIR/wf-in-fn-arg.rs:10:15 | LL | struct MustBeCopy { | ---- required by this bound in `MustBeCopy` ... LL | fn bar(_: &MustBeCopy) - | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` + | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `T` | help: consider restricting type parameter `T` | diff --git a/src/test/ui/wf/wf-trait-default-fn-arg.stderr b/src/test/ui/wf/wf-trait-default-fn-arg.stderr index c3d5d2b9669b8..2a129538f7633 100644 --- a/src/test/ui/wf/wf-trait-default-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-default-fn-arg.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-default-fn-arg.rs:11:22 + --> $DIR/wf-trait-default-fn-arg.rs:11:23 | LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self, x: &Bar) { - | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self` + | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/test/ui/wf/wf-trait-fn-arg.stderr b/src/test/ui/wf/wf-trait-fn-arg.stderr index 4510f50feea58..7693aa6d2d583 100644 --- a/src/test/ui/wf/wf-trait-fn-arg.stderr +++ b/src/test/ui/wf/wf-trait-fn-arg.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Self: Eq` is not satisfied - --> $DIR/wf-trait-fn-arg.rs:10:22 + --> $DIR/wf-trait-fn-arg.rs:10:23 | LL | struct Bar { value: Box } | -- required by this bound in `Bar` ... LL | fn bar(&self, x: &Bar); - | ^^^^^^^^^^ the trait `Eq` is not implemented for `Self` + | ^^^^^^^^^ the trait `Eq` is not implemented for `Self` | help: consider further restricting `Self` | diff --git a/src/tools/cargo b/src/tools/cargo index 27277d966b3cf..4e143fd131e0c 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 27277d966b3cfa454d6dea7f724cb961c036251c +Subproject commit 4e143fd131e0c16cefd008456e974236ca54e62e diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index fe00358888a24..ea105f9396a9d 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit fe00358888a24c64878abc15f09b0e60e16db9d6 +Subproject commit ea105f9396a9dab68e71efb06016b7c76c83ba7c