Auto merge of #79017 - GuillaumeGomez:rollup-5orhudd, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #77151 (Add regression test for issue #76042) - #77996 (Doc change: Remove mention of `fnv` in HashMap) - #78463 (Add type to `ConstKind::Placeholder`) - #78984 (Rustdoc check option) - #78985 (add dropck test for const params) - #78996 (add explicit test for const param promotion) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f2a11a2537
22 changed files with 286 additions and 62 deletions
|
@ -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");
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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! {
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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) }
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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");
|
||||
|
|
21
src/test/rustdoc-ui/check-fail.rs
Normal file
21
src/test/rustdoc-ui/check-fail.rs
Normal file
|
@ -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() {}
|
57
src/test/rustdoc-ui/check-fail.stderr
Normal file
57
src/test/rustdoc-ui/check-fail.stderr
Normal file
|
@ -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
|
||||
|
11
src/test/rustdoc-ui/check.rs
Normal file
11
src/test/rustdoc-ui/check.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
// check-pass
|
||||
// compile-flags: -Z unstable-options --check
|
||||
|
||||
#![warn(missing_docs)]
|
||||
//~^ WARN
|
||||
//~^^ WARN
|
||||
#![warn(rustdoc)]
|
||||
|
||||
pub fn foo() {}
|
||||
//~^ WARN
|
||||
//~^^ WARN
|
49
src/test/rustdoc-ui/check.stderr
Normal file
49
src/test/rustdoc-ui/check.stderr
Normal file
|
@ -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
|
||||
|
5
src/test/rustdoc/check.rs
Normal file
5
src/test/rustdoc/check.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
// compile-flags: -Z unstable-options --check
|
||||
|
||||
// @!has check/fn.foo.html
|
||||
// @!has check/index.html
|
||||
pub fn foo() {}
|
11
src/test/ui/const-generics/promotion.rs
Normal file
11
src/test/ui/const-generics/promotion.rs
Normal file
|
@ -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);
|
||||
}
|
|
@ -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`
|
||||
|
|
@ -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`.
|
16
src/test/ui/issues/issue-76042.rs
Normal file
16
src/test/ui/issues/issue-76042.rs
Normal file
|
@ -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!();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue