diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 871fc4fafe269..f554b51800a72 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -277,7 +277,7 @@ impl CanonicalizeRegionMode for CanonicalizeFreeRegionsOtherThanStatic { struct Canonicalizer<'cx, 'tcx> { infcx: Option<&'cx InferCtxt<'cx, 'tcx>>, tcx: TyCtxt<'tcx>, - variables: SmallVec<[CanonicalVarInfo; 8]>, + variables: SmallVec<[CanonicalVarInfo<'tcx>; 8]>, query_state: &'cx mut OriginalQueryValues<'tcx>, // Note that indices is only used once `var_values` is big enough to be // heap-allocated. @@ -542,7 +542,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// or returns an existing variable if `kind` has already been /// seen. `kind` is expected to be an unbound variable (or /// potentially a free region). - fn canonical_var(&mut self, info: CanonicalVarInfo, kind: GenericArg<'tcx>) -> BoundVar { + fn canonical_var(&mut self, info: CanonicalVarInfo<'tcx>, kind: GenericArg<'tcx>) -> BoundVar { let Canonicalizer { variables, query_state, indices, .. } = self; let var_values = &mut query_state.var_values; @@ -621,7 +621,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// representing the region `r`; return a region referencing it. fn canonical_var_for_region( &mut self, - info: CanonicalVarInfo, + info: CanonicalVarInfo<'tcx>, r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); @@ -633,7 +633,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// if `ty_var` is bound to anything; if so, canonicalize /// *that*. Otherwise, create a new canonical variable for /// `ty_var`. - fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo, ty_var: Ty<'tcx>) -> Ty<'tcx> { + fn canonicalize_ty_var(&mut self, info: CanonicalVarInfo<'tcx>, ty_var: Ty<'tcx>) -> Ty<'tcx> { let infcx = self.infcx.expect("encountered ty-var without infcx"); let bound_to = infcx.shallow_resolve(ty_var); if bound_to != ty_var { @@ -650,7 +650,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { /// `const_var`. fn canonicalize_const_var( &mut self, - info: CanonicalVarInfo, + info: CanonicalVarInfo<'tcx>, const_var: &'tcx ty::Const<'tcx>, ) -> &'tcx ty::Const<'tcx> { let infcx = self.infcx.expect("encountered const-var without infcx"); diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index 2b8c46f1de42d..0c26639e9b0fe 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -82,7 +82,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { fn instantiate_canonical_vars( &self, span: Span, - variables: &List<CanonicalVarInfo>, + variables: &List<CanonicalVarInfo<'tcx>>, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> CanonicalVarValues<'tcx> { let var_values: IndexVec<BoundVar, GenericArg<'tcx>> = variables @@ -100,7 +100,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { fn instantiate_canonical_var( &self, span: Span, - cv_info: CanonicalVarInfo, + cv_info: CanonicalVarInfo<'tcx>, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> GenericArg<'tcx> { match cv_info.kind { @@ -154,7 +154,7 @@ impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> { self.tcx .mk_const(ty::Const { val: ty::ConstKind::Placeholder(placeholder_mapped), - ty: self.tcx.ty_error(), // FIXME(const_generics) + ty: name.ty, }) .into() } diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs index e3365e8590b5e..4a5fd4b2aa5c8 100644 --- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs +++ b/compiler/rustc_infer/src/infer/higher_ranked/mod.rs @@ -95,7 +95,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(ty::PlaceholderConst { universe: next_universe, - name: bound_var, + name: ty::BoundConst { var: bound_var, ty }, }), ty, }) diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 1e15ae49a0c38..947b016a1fc93 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -40,7 +40,7 @@ pub struct Canonical<'tcx, V> { pub value: V, } -pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo>; +pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; /// A set of values corresponding to the canonical variables from some /// `Canonical`. You can give these values to @@ -88,11 +88,11 @@ impl Default for OriginalQueryValues<'tcx> { /// a copy of the canonical value in some other inference context, /// with fresh inference variables replacing the canonical values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -pub struct CanonicalVarInfo { - pub kind: CanonicalVarKind, +pub struct CanonicalVarInfo<'tcx> { + pub kind: CanonicalVarKind<'tcx>, } -impl CanonicalVarInfo { +impl<'tcx> CanonicalVarInfo<'tcx> { pub fn universe(&self) -> ty::UniverseIndex { self.kind.universe() } @@ -113,7 +113,7 @@ impl CanonicalVarInfo { /// in the type-theory sense of the term -- i.e., a "meta" type system /// that analyzes type-like values. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable, HashStable)] -pub enum CanonicalVarKind { +pub enum CanonicalVarKind<'tcx> { /// Some kind of type inference variable. Ty(CanonicalTyVarKind), @@ -132,10 +132,10 @@ pub enum CanonicalVarKind { Const(ty::UniverseIndex), /// A "placeholder" that represents "any const". - PlaceholderConst(ty::PlaceholderConst), + PlaceholderConst(ty::PlaceholderConst<'tcx>), } -impl CanonicalVarKind { +impl<'tcx> CanonicalVarKind<'tcx> { pub fn universe(self) -> ty::UniverseIndex { match self { CanonicalVarKind::Ty(kind) => match kind { @@ -287,9 +287,11 @@ pub type QueryOutlivesConstraint<'tcx> = ty::Binder<ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>; CloneTypeFoldableAndLiftImpls! { - crate::infer::canonical::Certainty, - crate::infer::canonical::CanonicalVarInfo, - crate::infer::canonical::CanonicalVarKind, + for <'tcx> { + crate::infer::canonical::Certainty, + crate::infer::canonical::CanonicalVarInfo<'tcx>, + crate::infer::canonical::CanonicalVarKind<'tcx>, + } } CloneTypeFoldableImpls! { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index aaf6a8570437c..1def4936860f1 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -278,7 +278,7 @@ impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for ty::Region<'tcx> { impl<'tcx, D: TyDecoder<'tcx>> Decodable<D> for CanonicalVarInfos<'tcx> { fn decode(decoder: &mut D) -> Result<Self, D::Error> { let len = decoder.read_usize()?; - let interned: Result<Vec<CanonicalVarInfo>, _> = + let interned: Result<Vec<CanonicalVarInfo<'tcx>>, _> = (0..len).map(|_| Decodable::decode(decoder)).collect(); Ok(decoder.tcx().intern_canonical_var_infos(interned?.as_slice())) } diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index ede28522000af..ca51f2a941174 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -23,7 +23,7 @@ pub enum ConstKind<'tcx> { Bound(ty::DebruijnIndex, ty::BoundVar), /// A placeholder const - universally quantified higher-ranked const. - Placeholder(ty::PlaceholderConst), + Placeholder(ty::PlaceholderConst<'tcx>), /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other /// variants when the code is monomorphic enough for that. diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1c6937e685c65..3838e1b006f70 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -83,7 +83,7 @@ pub struct CtxtInterners<'tcx> { type_: InternedSet<'tcx, TyS<'tcx>>, type_list: InternedSet<'tcx, List<Ty<'tcx>>>, substs: InternedSet<'tcx, InternalSubsts<'tcx>>, - canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo>>, + canonical_var_infos: InternedSet<'tcx, List<CanonicalVarInfo<'tcx>>>, region: InternedSet<'tcx, RegionKind>, existential_predicates: InternedSet<'tcx, List<ExistentialPredicate<'tcx>>>, predicate: InternedSet<'tcx, PredicateInner<'tcx>>, @@ -1613,7 +1613,7 @@ nop_lift! {predicate; &'a PredicateInner<'a> => &'tcx PredicateInner<'tcx>} nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} -nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo} +nop_list_lift! {canonical_var_infos; CanonicalVarInfo<'a> => CanonicalVarInfo<'tcx>} nop_list_lift! {projs; ProjectionKind => ProjectionKind} // This is the impl for `&'a InternalSubsts<'a>`. @@ -2049,7 +2049,7 @@ macro_rules! slice_interners { slice_interners!( type_list: _intern_type_list(Ty<'tcx>), substs: _intern_substs(GenericArg<'tcx>), - canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo), + canonical_var_infos: _intern_canonical_var_infos(CanonicalVarInfo<'tcx>), existential_predicates: _intern_existential_predicates(ExistentialPredicate<'tcx>), predicates: _intern_predicates(Predicate<'tcx>), projs: _intern_projs(ProjectionKind), @@ -2448,7 +2448,10 @@ impl<'tcx> TyCtxt<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_place_elems(ts) } } - pub fn intern_canonical_var_infos(self, ts: &[CanonicalVarInfo]) -> CanonicalVarInfos<'tcx> { + pub fn intern_canonical_var_infos( + self, + ts: &[CanonicalVarInfo<'tcx>], + ) -> CanonicalVarInfos<'tcx> { if ts.is_empty() { List::empty() } else { self._intern_canonical_var_infos(ts) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 0042b4a3a4279..06e69a0009b1f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1580,11 +1580,9 @@ impl UniverseIndex { } } -/// The "placeholder index" fully defines a placeholder region. -/// Placeholder regions are identified by both a **universe** as well -/// as a "bound-region" within that universe. The `bound_region` is -/// basically a name -- distinct bound regions within the same -/// universe are just two regions with an unknown relationship to one +/// The "placeholder index" fully defines a placeholder region, type, or const. Placeholders are +/// identified by both a universe, as well as a name residing within that universe. Distinct bound +/// regions/types/consts within the same universe simply have an unknown relationship to one /// another. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, PartialOrd, Ord)] pub struct Placeholder<T> { @@ -1606,7 +1604,14 @@ pub type PlaceholderRegion = Placeholder<BoundRegion>; pub type PlaceholderType = Placeholder<BoundVar>; -pub type PlaceholderConst = Placeholder<BoundVar>; +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)] +#[derive(TyEncodable, TyDecodable, PartialOrd, Ord)] +pub struct BoundConst<'tcx> { + pub var: BoundVar, + pub ty: Ty<'tcx>, +} + +pub type PlaceholderConst<'tcx> = Placeholder<BoundConst<'tcx>>; /// A `DefId` which is potentially bundled with its corresponding generic parameter /// in case `did` is a const argument. diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index fa229251703a5..27d90e6613748 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -34,8 +34,8 @@ use crate::sys; /// attacks such as HashDoS. /// /// The hashing algorithm can be replaced on a per-`HashMap` basis using the -/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. Many -/// alternative algorithms are available on crates.io, such as the [`fnv`] crate. +/// [`default`], [`with_hasher`], and [`with_capacity_and_hasher`] methods. +/// There are many alternative [hashing algorithms available on crates.io]. /// /// It is required that the keys implement the [`Eq`] and [`Hash`] traits, although /// this can frequently be achieved by using `#[derive(PartialEq, Eq, Hash)]`. @@ -57,6 +57,7 @@ use crate::sys; /// The original C++ version of SwissTable can be found [here], and this /// [CppCon talk] gives an overview of how the algorithm works. /// +/// [hashing algorithms available on crates.io]: https://crates.io/keywords/hasher /// [SwissTable]: https://abseil.io/blog/20180927-swisstables /// [here]: https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h /// [CppCon talk]: https://www.youtube.com/watch?v=ncHmEUmJZf4 @@ -154,7 +155,6 @@ use crate::sys; /// [`default`]: Default::default /// [`with_hasher`]: Self::with_hasher /// [`with_capacity_and_hasher`]: Self::with_capacity_and_hasher -/// [`fnv`]: https://crates.io/crates/fnv /// /// ``` /// use std::collections::HashMap; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 02885f519363c..c248d57a9ddf4 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -145,6 +145,9 @@ pub struct Options { pub render_options: RenderOptions, /// Output format rendering (used only for "show-coverage" option for the moment) pub output_format: Option<OutputFormat>, + /// If this option is set to `true`, rustdoc will only run checks and not generate + /// documentation. + pub run_check: bool, } impl fmt::Debug for Options { @@ -185,6 +188,7 @@ impl fmt::Debug for Options { .field("runtool", &self.runtool) .field("runtool_args", &self.runtool_args) .field("enable-per-target-ignores", &self.enable_per_target_ignores) + .field("run_check", &self.run_check) .finish() } } @@ -581,6 +585,7 @@ impl Options { let enable_per_target_ignores = matches.opt_present("enable-per-target-ignores"); let document_private = matches.opt_present("document-private-items"); let document_hidden = matches.opt_present("document-hidden-items"); + let run_check = matches.opt_present("check"); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -616,6 +621,7 @@ impl Options { runtool_args, enable_per_target_ignores, test_builder, + run_check, render_options: RenderOptions { output, external_html, diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 616b031814fa5..a88efba77b41c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -423,6 +423,7 @@ fn opts() -> Vec<RustcOptGroup> { "specified the rustc-like binary to use as the test builder", ) }), + unstable("check", |o| o.optflag("", "check", "Run rustdoc checks")), ] } @@ -515,6 +516,7 @@ fn main_options(options: config::Options) -> MainResult { // but we can't crates the Handler ahead of time because it's not Send let diag_opts = (options.error_format, options.edition, options.debugging_opts.clone()); let show_coverage = options.show_coverage; + let run_check = options.run_check; // First, parse the crate and extract all relevant information. info!("starting to run rustc"); @@ -540,6 +542,9 @@ fn main_options(options: config::Options) -> MainResult { // if we ran coverage, bail early, we don't need to also generate docs at this point // (also we didn't load in any of the useful passes) return Ok(()); + } else if run_check { + // Since we're in "check" mode, no need to generate anything beyond this point. + return Ok(()); } info!("going to format"); diff --git a/src/test/rustdoc-ui/check-fail.rs b/src/test/rustdoc-ui/check-fail.rs new file mode 100644 index 0000000000000..291fc112c3407 --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.rs @@ -0,0 +1,21 @@ +// compile-flags: -Z unstable-options --check + +#![deny(missing_docs)] +#![deny(rustdoc)] + +//! ```rust,testharness +//~^ ERROR +//! let x = 12; +//! ``` + +pub fn foo() {} +//~^ ERROR +//~^^ ERROR + +/// hello +//~^ ERROR +/// +/// ```rust,testharness +/// let x = 12; +/// ``` +pub fn bar() {} diff --git a/src/test/rustdoc-ui/check-fail.stderr b/src/test/rustdoc-ui/check-fail.stderr new file mode 100644 index 0000000000000..b4f255642da53 --- /dev/null +++ b/src/test/rustdoc-ui/check-fail.stderr @@ -0,0 +1,57 @@ +error: missing documentation for a function + --> $DIR/check-fail.rs:11:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:3:9 + | +LL | #![deny(missing_docs)] + | ^^^^^^^^^^^^ + +error: missing code example in this documentation + --> $DIR/check-fail.rs:11:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:4:9 + | +LL | #![deny(rustdoc)] + | ^^^^^^^ + = note: `#[deny(missing_doc_code_examples)]` implied by `#[deny(rustdoc)]` + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:6:1 + | +LL | / //! ```rust,testharness +LL | | +LL | | //! let x = 12; +LL | | //! ``` + | |_______^ + | +note: the lint level is defined here + --> $DIR/check-fail.rs:4:9 + | +LL | #![deny(rustdoc)] + | ^^^^^^^ + = note: `#[deny(invalid_codeblock_attributes)]` implied by `#[deny(rustdoc)]` + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: unknown attribute `testharness`. Did you mean `test_harness`? + --> $DIR/check-fail.rs:15:1 + | +LL | / /// hello +LL | | +LL | | /// +LL | | /// ```rust,testharness +LL | | /// let x = 12; +LL | | /// ``` + | |_______^ + | + = help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function + +error: aborting due to 4 previous errors + diff --git a/src/test/rustdoc-ui/check.rs b/src/test/rustdoc-ui/check.rs new file mode 100644 index 0000000000000..022c56214d451 --- /dev/null +++ b/src/test/rustdoc-ui/check.rs @@ -0,0 +1,11 @@ +// check-pass +// compile-flags: -Z unstable-options --check + +#![warn(missing_docs)] +//~^ WARN +//~^^ WARN +#![warn(rustdoc)] + +pub fn foo() {} +//~^ WARN +//~^^ WARN diff --git a/src/test/rustdoc-ui/check.stderr b/src/test/rustdoc-ui/check.stderr new file mode 100644 index 0000000000000..27e5a736148e1 --- /dev/null +++ b/src/test/rustdoc-ui/check.stderr @@ -0,0 +1,49 @@ +warning: missing documentation for the crate + --> $DIR/check.rs:4:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:4:9 + | +LL | #![warn(missing_docs)] + | ^^^^^^^^^^^^ + +warning: missing documentation for a function + --> $DIR/check.rs:9:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^ + +warning: missing code example in this documentation + --> $DIR/check.rs:4:1 + | +LL | / #![warn(missing_docs)] +LL | | +LL | | +LL | | #![warn(rustdoc)] +LL | | +LL | | pub fn foo() {} + | |_______________^ + | +note: the lint level is defined here + --> $DIR/check.rs:7:9 + | +LL | #![warn(rustdoc)] + | ^^^^^^^ + = note: `#[warn(missing_doc_code_examples)]` implied by `#[warn(rustdoc)]` + +warning: missing code example in this documentation + --> $DIR/check.rs:9:1 + | +LL | pub fn foo() {} + | ^^^^^^^^^^^^^^^ + +warning: 4 warnings emitted + diff --git a/src/test/rustdoc/check.rs b/src/test/rustdoc/check.rs new file mode 100644 index 0000000000000..1fb4b35ddbe86 --- /dev/null +++ b/src/test/rustdoc/check.rs @@ -0,0 +1,5 @@ +// compile-flags: -Z unstable-options --check + +// @!has check/fn.foo.html +// @!has check/index.html +pub fn foo() {} diff --git a/src/test/ui/const-generics/promotion.rs b/src/test/ui/const-generics/promotion.rs new file mode 100644 index 0000000000000..ac568bb75f002 --- /dev/null +++ b/src/test/ui/const-generics/promotion.rs @@ -0,0 +1,11 @@ +// run-pass +// tests that promoting expressions containing const parameters is allowed. +#![feature(min_const_generics)] + +fn promotion_test<const N: usize>() -> &'static usize { + &(3 + N) +} + +fn main() { + assert_eq!(promotion_test::<13>(), &16); +} diff --git a/src/test/ui/issues/issue-38868.rs b/src/test/ui/dropck/issue-38868.rs similarity index 100% rename from src/test/ui/issues/issue-38868.rs rename to src/test/ui/dropck/issue-38868.rs diff --git a/src/test/ui/issues/issue-38868.stderr b/src/test/ui/dropck/issue-38868.stderr similarity index 100% rename from src/test/ui/issues/issue-38868.stderr rename to src/test/ui/dropck/issue-38868.stderr diff --git a/src/test/ui/reject-specialized-drops-8142.rs b/src/test/ui/dropck/reject-specialized-drops-8142.rs similarity index 88% rename from src/test/ui/reject-specialized-drops-8142.rs rename to src/test/ui/dropck/reject-specialized-drops-8142.rs index c4671736d79ec..02e8665cd2e3b 100644 --- a/src/test/ui/reject-specialized-drops-8142.rs +++ b/src/test/ui/dropck/reject-specialized-drops-8142.rs @@ -1,5 +1,6 @@ // Issue 8142: Test that Drop impls cannot be specialized beyond the // predicates attached to the type definition itself. +#![feature(min_const_generics)] trait Bound { fn foo(&self) { } } struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } @@ -15,6 +16,8 @@ struct T<'t,Ts:'t> { x: &'t Ts } struct U; struct V<Tva, Tvb> { x: *const Tva, y: *const Tvb } struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } +struct X<const Ca: usize>; +struct Y<const Ca: usize, const Cb: usize>; enum Enum<T> { Variant(T) } struct TupleStruct<T>(T); @@ -58,6 +61,12 @@ impl<One> Drop for V<One,One> { fn drop(&mut self) { } } // REJECT impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter `'lw` +impl Drop for X<3> { fn drop(&mut self) { } } // REJECT +//~^ ERROR `Drop` impls cannot be specialized + +impl<const Ca: usize> Drop for Y<Ca, Ca> { fn drop(&mut self) { } } // REJECT +//~^ ERROR `Drop` impls cannot be specialized + impl<AddsBnd:Bound> Drop for Enum<AddsBnd> { fn drop(&mut self) { } } // REJECT //~^ ERROR `Drop` impl requires `AddsBnd: Bound` diff --git a/src/test/ui/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr similarity index 71% rename from src/test/ui/reject-specialized-drops-8142.stderr rename to src/test/ui/dropck/reject-specialized-drops-8142.stderr index eac2461753355..284cf59c822bd 100644 --- a/src/test/ui/reject-specialized-drops-8142.stderr +++ b/src/test/ui/dropck/reject-specialized-drops-8142.stderr @@ -1,151 +1,175 @@ error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:23:20 + --> $DIR/reject-specialized-drops-8142.rs:26:20 | LL | impl<'al,'adds_bnd:'al> Drop for K<'al,'adds_bnd> { // REJECT | ^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:5:1 + --> $DIR/reject-specialized-drops-8142.rs:6:1 | LL | struct K<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `'adds_bnd: 'al` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:27:67 + --> $DIR/reject-specialized-drops-8142.rs:30:67 | LL | impl<'al,'adds_bnd> Drop for L<'al,'adds_bnd> where 'adds_bnd:'al { // REJECT | ^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:6:1 + --> $DIR/reject-specialized-drops-8142.rs:7:1 | LL | struct L<'l1,'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/reject-specialized-drops-8142.rs:33:1 + --> $DIR/reject-specialized-drops-8142.rs:36:1 | LL | impl Drop for N<'static> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch | = note: expected struct `N<'n>` found struct `N<'static>` -note: the lifetime `'n` as defined on the struct at 8:10... - --> $DIR/reject-specialized-drops-8142.rs:8:10 +note: the lifetime `'n` as defined on the struct at 9:10... + --> $DIR/reject-specialized-drops-8142.rs:9:10 | LL | struct N<'n> { x: &'n i8 } | ^^ = note: ...does not necessarily outlive the static lifetime error[E0366]: `Drop` impls cannot be specialized - --> $DIR/reject-specialized-drops-8142.rs:40:1 + --> $DIR/reject-specialized-drops-8142.rs:43:1 | LL | impl Drop for P<i8> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: use the same sequence of generic type, lifetime and const parameters as the struct definition - --> $DIR/reject-specialized-drops-8142.rs:10:1 + --> $DIR/reject-specialized-drops-8142.rs:11:1 | LL | struct P<Tp> { x: *const Tp } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:43:14 + --> $DIR/reject-specialized-drops-8142.rs:46:14 | LL | impl<AddsBnd:Bound> Drop for Q<AddsBnd> { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:11:1 + --> $DIR/reject-specialized-drops-8142.rs:12:1 | LL | struct Q<Tq> { x: *const Tq } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsRBnd: 'rbnd` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:46:21 + --> $DIR/reject-specialized-drops-8142.rs:49:21 | LL | impl<'rbnd,AddsRBnd:'rbnd> Drop for R<AddsRBnd> { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:12:1 + --> $DIR/reject-specialized-drops-8142.rs:13:1 | LL | struct R<Tr> { x: *const Tr } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0366]: `Drop` impls cannot be specialized - --> $DIR/reject-specialized-drops-8142.rs:55:1 + --> $DIR/reject-specialized-drops-8142.rs:58:1 | LL | impl<One> Drop for V<One,One> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: use the same sequence of generic type, lifetime and const parameters as the struct definition - --> $DIR/reject-specialized-drops-8142.rs:16:1 + --> $DIR/reject-specialized-drops-8142.rs:17:1 | LL | struct V<Tva, Tvb> { x: *const Tva, y: *const Tvb } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'lw` due to conflicting requirements - --> $DIR/reject-specialized-drops-8142.rs:58:1 + --> $DIR/reject-specialized-drops-8142.rs:61:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 17:10... - --> $DIR/reject-specialized-drops-8142.rs:17:10 +note: first, the lifetime cannot outlive the lifetime `'l1` as defined on the struct at 18:10... + --> $DIR/reject-specialized-drops-8142.rs:18:10 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ -note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 17:15... - --> $DIR/reject-specialized-drops-8142.rs:17:15 +note: ...but the lifetime must also be valid for the lifetime `'l2` as defined on the struct at 18:15... + --> $DIR/reject-specialized-drops-8142.rs:18:15 | LL | struct W<'l1, 'l2> { x: &'l1 i8, y: &'l2 u8 } | ^^^ note: ...so that the types are compatible - --> $DIR/reject-specialized-drops-8142.rs:58:1 + --> $DIR/reject-specialized-drops-8142.rs:61:1 | LL | impl<'lw> Drop for W<'lw,'lw> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: expected `W<'l1, 'l2>` found `W<'_, '_>` +error[E0366]: `Drop` impls cannot be specialized + --> $DIR/reject-specialized-drops-8142.rs:64:1 + | +LL | impl Drop for X<3> { fn drop(&mut self) { } } // REJECT + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: use the same sequence of generic type, lifetime and const parameters as the struct definition + --> $DIR/reject-specialized-drops-8142.rs:19:1 + | +LL | struct X<const Ca: usize>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0366]: `Drop` impls cannot be specialized + --> $DIR/reject-specialized-drops-8142.rs:67:1 + | +LL | impl<const Ca: usize> Drop for Y<Ca, Ca> { fn drop(&mut self) { } } // REJECT + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: use the same sequence of generic type, lifetime and const parameters as the struct definition + --> $DIR/reject-specialized-drops-8142.rs:20:1 + | +LL | struct Y<const Ca: usize, const Cb: usize>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the enum it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:61:14 + --> $DIR/reject-specialized-drops-8142.rs:70:14 | LL | impl<AddsBnd:Bound> Drop for Enum<AddsBnd> { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:19:1 + --> $DIR/reject-specialized-drops-8142.rs:22:1 | LL | enum Enum<T> { Variant(T) } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the struct it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:64:14 + --> $DIR/reject-specialized-drops-8142.rs:73:14 | LL | impl<AddsBnd:Bound> Drop for TupleStruct<AddsBnd> { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:20:1 + --> $DIR/reject-specialized-drops-8142.rs:23:1 | LL | struct TupleStruct<T>(T); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0367]: `Drop` impl requires `AddsBnd: Bound` but the union it is implemented for does not - --> $DIR/reject-specialized-drops-8142.rs:67:21 + --> $DIR/reject-specialized-drops-8142.rs:76:21 | LL | impl<AddsBnd:Copy + Bound> Drop for Union<AddsBnd> { fn drop(&mut self) { } } // REJECT | ^^^^^ | note: the implementor must specify the same requirement - --> $DIR/reject-specialized-drops-8142.rs:21:1 + --> $DIR/reject-specialized-drops-8142.rs:24:1 | LL | union Union<T: Copy> { f: T } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0308, E0366, E0367, E0495. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/issues/issue-76042.rs b/src/test/ui/issues/issue-76042.rs new file mode 100644 index 0000000000000..34d5293799aa7 --- /dev/null +++ b/src/test/ui/issues/issue-76042.rs @@ -0,0 +1,16 @@ +// run-pass +// compile-flags: -Coverflow-checks=off -Ccodegen-units=1 -Copt-level=0 + +fn foo(a: i128, b: i128, s: u32) -> (i128, i128) { + if s == 128 { + (0, 0) + } else { + (b >> s, a >> s) + } +} +fn main() { + let r = foo(0, 8, 1); + if r.0 != 4 { + panic!(); + } +}