Auto merge of #102822 - notriddle:rollup-mgfjb62, r=notriddle
Rollup of 8 pull requests Successful merges: - #99818 (don't ICE when normalizing closure input tys) - #102514 (Don't repeat lifetime names from outer binder in print) - #102661 (rustdoc: Document effect of fundamental types) - #102782 (Add regression test for #102124) - #102790 (Fix llvm-tblgen for cross compiling) - #102807 (Document `rust-docs-json` component) - #102812 (Remove empty core::lazy and std::lazy) - #102818 (Clean up rustdoc highlight.rs imports a bit) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c0784109da
@ -52,11 +52,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
Some(error_info) => error_info.to_universe_info(old_universe),
|
||||
None => UniverseInfo::other(),
|
||||
};
|
||||
for u in old_universe..universe {
|
||||
self.borrowck_context
|
||||
.constraints
|
||||
.universe_causes
|
||||
.insert(u + 1, universe_info.clone());
|
||||
for u in (old_universe + 1)..=universe {
|
||||
self.borrowck_context.constraints.universe_causes.insert(u, universe_info.clone());
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,15 +68,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let old_universe = self.infcx.universe();
|
||||
|
||||
let (instantiated, _) =
|
||||
self.infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
|
||||
|
||||
for u in 0..canonical.max_universe.as_u32() {
|
||||
let info = UniverseInfo::other();
|
||||
self.borrowck_context
|
||||
.constraints
|
||||
.universe_causes
|
||||
.insert(ty::UniverseIndex::from_u32(u), info);
|
||||
for u in (old_universe + 1)..=self.infcx.universe() {
|
||||
self.borrowck_context.constraints.universe_causes.insert(u, UniverseInfo::other());
|
||||
}
|
||||
|
||||
instantiated
|
||||
|
@ -8,7 +8,6 @@ use rustc_infer::infer::InferCtxt;
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::traits::query::OutlivesBound;
|
||||
use rustc_middle::ty::{self, RegionVid, Ty};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||
use std::rc::Rc;
|
||||
use type_op::TypeOpOutput;
|
||||
@ -219,6 +218,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
}
|
||||
|
||||
pub(crate) fn create(mut self) -> CreateResult<'tcx> {
|
||||
let span = self.infcx.tcx.def_span(self.universal_regions.defining_ty.def_id());
|
||||
let unnormalized_input_output_tys = self
|
||||
.universal_regions
|
||||
.unnormalized_input_tys
|
||||
@ -250,7 +250,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
self.infcx
|
||||
.tcx
|
||||
.sess
|
||||
.delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty));
|
||||
.delay_span_bug(span, &format!("failed to normalize {:?}", ty));
|
||||
TypeOpOutput {
|
||||
output: self.infcx.tcx.ty_error(),
|
||||
constraints: None,
|
||||
@ -301,8 +301,8 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
|
||||
&self.region_bound_pairs,
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
Locations::All(DUMMY_SP),
|
||||
DUMMY_SP,
|
||||
Locations::All(span),
|
||||
span,
|
||||
ConstraintCategory::Internal,
|
||||
&mut self.constraints,
|
||||
)
|
||||
|
@ -7,16 +7,11 @@
|
||||
//! `RETURN_PLACE` the MIR arguments) are always fully normalized (and
|
||||
//! contain revealed `impl Trait` values).
|
||||
|
||||
use crate::type_check::constraint_conversion::ConstraintConversion;
|
||||
use rustc_index::vec::Idx;
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
|
||||
use rustc_trait_selection::traits::query::Fallible;
|
||||
use type_op::TypeOpOutput;
|
||||
|
||||
use crate::universal_regions::UniversalRegions;
|
||||
|
||||
@ -185,7 +180,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, span), level = "debug")]
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn equate_normalized_input_or_output(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, span: Span) {
|
||||
if let Err(_) =
|
||||
self.eq_types(a, b, Locations::All(span), ConstraintCategory::BoringNoLocation)
|
||||
@ -194,13 +189,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
// `rustc_traits::normalize_after_erasing_regions`. Ideally, we'd
|
||||
// like to normalize *before* inserting into `local_decls`, but
|
||||
// doing so ends up causing some other trouble.
|
||||
let b = match self.normalize_and_add_constraints(b) {
|
||||
Ok(n) => n,
|
||||
Err(_) => {
|
||||
debug!("equate_inputs_and_outputs: NoSolution");
|
||||
b
|
||||
}
|
||||
};
|
||||
let b = self.normalize(b, Locations::All(span));
|
||||
|
||||
// Note: if we have to introduce new placeholders during normalization above, then we won't have
|
||||
// added those universes to the universe info, which we would want in `relate_tys`.
|
||||
@ -218,28 +207,4 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn normalize_and_add_constraints(&mut self, t: Ty<'tcx>) -> Fallible<Ty<'tcx>> {
|
||||
let TypeOpOutput { output: norm_ty, constraints, .. } =
|
||||
self.param_env.and(type_op::normalize::Normalize::new(t)).fully_perform(self.infcx)?;
|
||||
|
||||
debug!("{:?} normalized to {:?}", t, norm_ty);
|
||||
|
||||
for data in constraints {
|
||||
ConstraintConversion::new(
|
||||
self.infcx,
|
||||
&self.borrowck_context.universal_regions,
|
||||
&self.region_bound_pairs,
|
||||
self.implicit_region_bound,
|
||||
self.param_env,
|
||||
Locations::All(DUMMY_SP),
|
||||
DUMMY_SP,
|
||||
ConstraintCategory::Internal,
|
||||
&mut self.borrowck_context.constraints,
|
||||
)
|
||||
.convert_all(&*data);
|
||||
}
|
||||
|
||||
Ok(norm_ty)
|
||||
}
|
||||
}
|
||||
|
@ -138,8 +138,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
use_polonius: bool,
|
||||
) -> MirTypeckResults<'tcx> {
|
||||
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
|
||||
let mut universe_causes = FxHashMap::default();
|
||||
universe_causes.insert(ty::UniverseIndex::from_u32(0), UniverseInfo::other());
|
||||
let mut constraints = MirTypeckRegionConstraints {
|
||||
placeholder_indices: PlaceholderIndices::default(),
|
||||
placeholder_index_to_region: IndexVec::default(),
|
||||
@ -148,7 +146,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
member_constraints: MemberConstraintSet::default(),
|
||||
closure_bounds_mapping: Default::default(),
|
||||
type_tests: Vec::default(),
|
||||
universe_causes,
|
||||
universe_causes: FxHashMap::default(),
|
||||
};
|
||||
|
||||
let CreateResult {
|
||||
@ -165,9 +163,8 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||
|
||||
debug!(?normalized_inputs_and_output);
|
||||
|
||||
for u in ty::UniverseIndex::ROOT..infcx.universe() {
|
||||
let info = UniverseInfo::other();
|
||||
constraints.universe_causes.insert(u, info);
|
||||
for u in ty::UniverseIndex::ROOT..=infcx.universe() {
|
||||
constraints.universe_causes.insert(u, UniverseInfo::other());
|
||||
}
|
||||
|
||||
let mut borrowck_context = BorrowCheckContext {
|
||||
|
@ -2055,7 +2055,14 @@ struct RegionFolder<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
current_index: ty::DebruijnIndex,
|
||||
region_map: BTreeMap<ty::BoundRegion, ty::Region<'tcx>>,
|
||||
name: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
|
||||
name: &'a mut (
|
||||
dyn FnMut(
|
||||
Option<ty::DebruijnIndex>, // Debruijn index of the folded late-bound region
|
||||
ty::DebruijnIndex, // Index corresponding to binder level
|
||||
ty::BoundRegion,
|
||||
) -> ty::Region<'tcx>
|
||||
+ 'a
|
||||
),
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
@ -2086,7 +2093,9 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
|
||||
let name = &mut self.name;
|
||||
let region = match *r {
|
||||
ty::ReLateBound(_, br) => *self.region_map.entry(br).or_insert_with(|| name(br)),
|
||||
ty::ReLateBound(db, br) if db >= self.current_index => {
|
||||
*self.region_map.entry(br).or_insert_with(|| name(Some(db), self.current_index, br))
|
||||
}
|
||||
ty::RePlaceholder(ty::PlaceholderRegion { name: kind, .. }) => {
|
||||
// If this is an anonymous placeholder, don't rename. Otherwise, in some
|
||||
// async fns, we get a `for<'r> Send` bound
|
||||
@ -2095,7 +2104,10 @@ impl<'a, 'tcx> ty::TypeFolder<'tcx> for RegionFolder<'a, 'tcx> {
|
||||
_ => {
|
||||
// Index doesn't matter, since this is just for naming and these never get bound
|
||||
let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
|
||||
*self.region_map.entry(br).or_insert_with(|| name(br))
|
||||
*self
|
||||
.region_map
|
||||
.entry(br)
|
||||
.or_insert_with(|| name(None, self.current_index, br))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2234,24 +2246,63 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
|
||||
})
|
||||
} else {
|
||||
let tcx = self.tcx;
|
||||
let mut name = |br: ty::BoundRegion| {
|
||||
start_or_continue(&mut self, "for<", ", ");
|
||||
let kind = match br.kind {
|
||||
|
||||
// Closure used in `RegionFolder` to create names for anonymous late-bound
|
||||
// regions. We use two `DebruijnIndex`es (one for the currently folded
|
||||
// late-bound region and the other for the binder level) to determine
|
||||
// whether a name has already been created for the currently folded region,
|
||||
// see issue #102392.
|
||||
let mut name = |lifetime_idx: Option<ty::DebruijnIndex>,
|
||||
binder_level_idx: ty::DebruijnIndex,
|
||||
br: ty::BoundRegion| {
|
||||
let (name, kind) = match br.kind {
|
||||
ty::BrAnon(_) | ty::BrEnv => {
|
||||
let name = next_name(&self);
|
||||
do_continue(&mut self, name);
|
||||
ty::BrNamed(CRATE_DEF_ID.to_def_id(), name)
|
||||
|
||||
if let Some(lt_idx) = lifetime_idx {
|
||||
if lt_idx > binder_level_idx {
|
||||
let kind = ty::BrNamed(CRATE_DEF_ID.to_def_id(), name);
|
||||
return tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: br.var, kind },
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(name, ty::BrNamed(CRATE_DEF_ID.to_def_id(), name))
|
||||
}
|
||||
ty::BrNamed(def_id, kw::UnderscoreLifetime) => {
|
||||
let name = next_name(&self);
|
||||
do_continue(&mut self, name);
|
||||
ty::BrNamed(def_id, name)
|
||||
|
||||
if let Some(lt_idx) = lifetime_idx {
|
||||
if lt_idx > binder_level_idx {
|
||||
let kind = ty::BrNamed(def_id, name);
|
||||
return tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: br.var, kind },
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(name, ty::BrNamed(def_id, name))
|
||||
}
|
||||
ty::BrNamed(_, name) => {
|
||||
do_continue(&mut self, name);
|
||||
br.kind
|
||||
if let Some(lt_idx) = lifetime_idx {
|
||||
if lt_idx > binder_level_idx {
|
||||
let kind = br.kind;
|
||||
return tcx.mk_region(ty::ReLateBound(
|
||||
ty::INNERMOST,
|
||||
ty::BoundRegion { var: br.var, kind },
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
(name, br.kind)
|
||||
}
|
||||
};
|
||||
|
||||
start_or_continue(&mut self, "for<", ", ");
|
||||
do_continue(&mut self, name);
|
||||
tcx.mk_region(ty::ReLateBound(ty::INNERMOST, ty::BoundRegion { var: br.var, kind }))
|
||||
};
|
||||
let mut folder = RegionFolder {
|
||||
|
@ -1 +0,0 @@
|
||||
//! Lazy values and one-time initialization of static data.
|
@ -326,8 +326,6 @@ pub mod cell;
|
||||
pub mod char;
|
||||
pub mod ffi;
|
||||
pub mod iter;
|
||||
#[unstable(feature = "once_cell", issue = "74465")]
|
||||
pub mod lazy;
|
||||
pub mod option;
|
||||
pub mod panic;
|
||||
pub mod panicking;
|
||||
|
@ -1 +0,0 @@
|
||||
//! Lazy values and one-time initialization of static data.
|
@ -529,9 +529,6 @@ pub mod process;
|
||||
pub mod sync;
|
||||
pub mod time;
|
||||
|
||||
#[unstable(feature = "once_cell", issue = "74465")]
|
||||
pub mod lazy;
|
||||
|
||||
// Pull in `std_float` crate into libstd. The contents of
|
||||
// `std_float` are in a different repository: rust-lang/portable-simd.
|
||||
#[path = "../../portable-simd/crates/std_float/src/lib.rs"]
|
||||
|
@ -2028,6 +2028,7 @@ impl Step for RustDev {
|
||||
"llvm-nm",
|
||||
"llvm-dwarfdump",
|
||||
"llvm-dis",
|
||||
"llvm-tblgen",
|
||||
] {
|
||||
tarball.add_file(src_bindir.join(exe(bin, target)), "bin", 0o755);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
Change this file to make users of the `download-ci-llvm` configuration download
|
||||
a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
|
||||
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/97550
|
||||
Last change is for: https://github.com/rust-lang/rust/pull/102790
|
||||
|
@ -497,18 +497,18 @@ impl Step for Llvm {
|
||||
|
||||
// https://llvm.org/docs/HowToCrossCompileLLVM.html
|
||||
if target != builder.config.build {
|
||||
builder.ensure(Llvm { target: builder.config.build });
|
||||
// FIXME: if the llvm root for the build triple is overridden then we
|
||||
// should use llvm-tblgen from there, also should verify that it
|
||||
// actually exists most of the time in normal installs of LLVM.
|
||||
let host_bin = builder.llvm_out(builder.config.build).join("bin");
|
||||
cfg.define("LLVM_TABLEGEN", host_bin.join("llvm-tblgen").with_extension(EXE_EXTENSION));
|
||||
// LLVM_NM is required for cross compiling using MSVC
|
||||
cfg.define("LLVM_NM", host_bin.join("llvm-nm").with_extension(EXE_EXTENSION));
|
||||
cfg.define(
|
||||
"LLVM_CONFIG_PATH",
|
||||
host_bin.join("llvm-config").with_extension(EXE_EXTENSION),
|
||||
);
|
||||
let llvm_config = builder.ensure(Llvm { target: builder.config.build });
|
||||
if !builder.config.dry_run {
|
||||
let llvm_bindir = output(Command::new(&llvm_config).arg("--bindir"));
|
||||
let host_bin = Path::new(llvm_bindir.trim());
|
||||
cfg.define(
|
||||
"LLVM_TABLEGEN",
|
||||
host_bin.join("llvm-tblgen").with_extension(EXE_EXTENSION),
|
||||
);
|
||||
// LLVM_NM is required for cross compiling using MSVC
|
||||
cfg.define("LLVM_NM", host_bin.join("llvm-nm").with_extension(EXE_EXTENSION));
|
||||
}
|
||||
cfg.define("LLVM_CONFIG_PATH", llvm_config);
|
||||
if builder.config.llvm_clang {
|
||||
let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin");
|
||||
let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION);
|
||||
|
@ -197,6 +197,35 @@ To do so, the `#[doc(keyword = "...")]` attribute is used. Example:
|
||||
mod empty_mod {}
|
||||
```
|
||||
|
||||
## Effects of other nightly features
|
||||
|
||||
These nightly-only features are not primarily related to Rustdoc,
|
||||
but have convenient effects on the documentation produced.
|
||||
|
||||
### `fundamental` types
|
||||
|
||||
Annotating a type with `#[fundamental]` primarily influences coherence rules about generic types,
|
||||
i.e., they alter whether other crates can provide implementations for that type.
|
||||
The unstable book [links to further information][unstable-fundamental].
|
||||
|
||||
[unstable-fundamental]: https://doc.rust-lang.org/unstable-book/language-features/fundamental.html
|
||||
|
||||
For documentation, this has an additional side effect:
|
||||
If a method is implemented on `F<T>` (or `F<&T>`),
|
||||
where `F` is a fundamental type,
|
||||
then the method is not only documented at the page about `F`,
|
||||
but also on the page about `T`.
|
||||
In a sense, it makes the type transparent to Rustdoc.
|
||||
This is especially convenient for types that work as annotated pointers,
|
||||
such as `Pin<&mut T>`,
|
||||
as it ensures that methods only implemented through those annotated pointers
|
||||
can still be found with the type they act on.
|
||||
|
||||
If the `fundamental` feature's effect on coherence is not intended,
|
||||
such a type can be marked as fundamental only for purposes of documentation
|
||||
by introducing a custom feature and
|
||||
limiting the use of `fundamental` to when documentation is built.
|
||||
|
||||
## Unstable command-line arguments
|
||||
|
||||
These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are
|
||||
@ -465,6 +494,16 @@ Note that the third item is the crate root, which in this case is undocumented.
|
||||
[JSON format](https://doc.rust-lang.org/nightly/nightly-rustc/rustdoc_json_types/). `--output-format html` has no effect,
|
||||
and is also accepted on stable toolchains.
|
||||
|
||||
JSON Output for toolchain crates (`std`, `alloc`, `core`, `test`, and `proc_macro`)
|
||||
is available via the `rust-docs-json` rustup component.
|
||||
|
||||
```shell
|
||||
rustup component add --toolchain nightly rust-docs-json
|
||||
```
|
||||
|
||||
Then the json files will be present in the `share/doc/rust/json/` directory
|
||||
of the rustup toolchain directory.
|
||||
|
||||
It can also be used with `--show-coverage`. Take a look at its
|
||||
[documentation](#--show-coverage-calculate-the-percentage-of-items-with-documentation) for more
|
||||
information.
|
||||
|
@ -7,20 +7,18 @@
|
||||
|
||||
use crate::clean::PrimitiveType;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::render::Context;
|
||||
use crate::html::render::{Context, LinkFromSrc};
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt::{Display, Write};
|
||||
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_lexer::Cursor;
|
||||
use rustc_lexer::{LiteralKind, TokenKind};
|
||||
use rustc_lexer::{Cursor, LiteralKind, TokenKind};
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::{BytePos, Span, DUMMY_SP};
|
||||
|
||||
use super::format::{self, Buffer};
|
||||
use super::render::LinkFromSrc;
|
||||
|
||||
/// This type is needed in case we want to render links on items to allow to go to their definition.
|
||||
pub(crate) struct HrefContext<'a, 'b, 'c> {
|
||||
|
@ -18,7 +18,7 @@ LL | async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
|
||||
| ___________________________________________________________________^
|
||||
LL | | }
|
||||
| |_^
|
||||
= note: required because it captures the following types: `ResumeTy`, `impl for<'a, 'b, 'c> Future<Output = ()>`, `()`
|
||||
= note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
|
||||
note: required because it's used within this `async` block
|
||||
--> $DIR/issue-70935-complex-spans.rs:16:16
|
||||
|
|
||||
|
@ -1,10 +1,10 @@
|
||||
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(for<'r> fn(&'r ()))`
|
||||
error[E0119]: conflicting implementations of trait `Trait` for type `for<'r> fn(fn(&'r ()))`
|
||||
--> $DIR/coherence-fn-covariant-bound-vs-static.rs:17:1
|
||||
|
|
||||
LL | impl Trait for for<'r> fn(fn(&'r ())) {}
|
||||
| ------------------------------------- first implementation here
|
||||
LL | impl<'a> Trait for fn(fn(&'a ())) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(for<'r> fn(&'r ()))`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'r> fn(fn(&'r ()))`
|
||||
|
|
||||
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
|
||||
|
||||
|
20
src/test/ui/const-generics/issue-102124.rs
Normal file
20
src/test/ui/const-generics/issue-102124.rs
Normal file
@ -0,0 +1,20 @@
|
||||
// run-pass
|
||||
// compile-flags: -Zmir-opt-level=3
|
||||
|
||||
// regression test for #102124
|
||||
|
||||
const L: usize = 4;
|
||||
|
||||
pub trait Print<const N: usize> {
|
||||
fn print(&self) -> usize {
|
||||
N
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Printer;
|
||||
impl Print<L> for Printer {}
|
||||
|
||||
fn main() {
|
||||
let p = Printer;
|
||||
assert_eq!(p.print(), 4);
|
||||
}
|
10
src/test/ui/lifetimes/nested-binder-print.rs
Normal file
10
src/test/ui/lifetimes/nested-binder-print.rs
Normal file
@ -0,0 +1,10 @@
|
||||
struct TwoLt<'a, 'b>(&'a (), &'b ());
|
||||
type Foo<'a> = fn(TwoLt<'_, 'a>);
|
||||
|
||||
fn foo() {
|
||||
let y: for<'a> fn(Foo<'a>);
|
||||
let x: u32 = y;
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/lifetimes/nested-binder-print.stderr
Normal file
14
src/test/ui/lifetimes/nested-binder-print.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/nested-binder-print.rs:6:18
|
||||
|
|
||||
LL | let x: u32 = y;
|
||||
| --- ^ expected `u32`, found fn pointer
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `u32`
|
||||
found fn pointer `for<'a> fn(for<'b> fn(TwoLt<'b, 'a>))`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -4,7 +4,7 @@ error: higher-ranked lifetime error
|
||||
LL | foo(&10);
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: could not prove `for<'b, 'a> &'b (): 'a`
|
||||
= note: could not prove `for<'b> &'b (): 'a`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
// Regression test for #102800
|
||||
//
|
||||
// Here we are generating higher-ranked region constraints when normalizing and relating closure
|
||||
// input types. Previously this was an ICE in the error path because we didn't register enough
|
||||
// diagnostic information to render the higher-ranked subtyping error.
|
||||
|
||||
// check-fail
|
||||
|
||||
trait Trait {
|
||||
type Ty;
|
||||
}
|
||||
|
||||
impl Trait for &'static () {
|
||||
type Ty = ();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
//~| ERROR higher-ranked subtype error
|
||||
//~| ERROR higher-ranked subtype error
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
//~| ERROR implementation of `Trait` is not general enough
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^-^
|
||||
| ||
|
||||
| |has type `<&'1 () as Trait>::Ty`
|
||||
| requires that `'1` must outlive `'static`
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^
|
||||
|
||||
error: higher-ranked subtype error
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:12
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: implementation of `Trait` is not general enough
|
||||
--> $DIR/closure-malformed-projection-input-issue-102800.rs:18:48
|
||||
|
|
||||
LL | let _: for<'a> fn(<&'a () as Trait>::Ty) = |_| {};
|
||||
| ^^^^^^ implementation of `Trait` is not general enough
|
||||
|
|
||||
= note: `&'0 ()` must implement `Trait`, for any lifetime `'0`...
|
||||
= note: ...but `Trait` is actually implemented for the type `&'static ()`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
|
6
src/test/ui/regions/issue-102392.rs
Normal file
6
src/test/ui/regions/issue-102392.rs
Normal file
@ -0,0 +1,6 @@
|
||||
fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
|
||||
f
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
14
src/test/ui/regions/issue-102392.stderr
Normal file
14
src/test/ui/regions/issue-102392.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-102392.rs:2:5
|
||||
|
|
||||
LL | fn g(f: for<'a> fn(fn(&str, &'a str))) -> bool {
|
||||
| ---- expected `bool` because of return type
|
||||
LL | f
|
||||
| ^ expected `bool`, found fn pointer
|
||||
|
|
||||
= note: expected type `bool`
|
||||
found fn pointer `for<'a> fn(for<'b> fn(&'b str, &'a str))`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
|
||||
error[E0277]: the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
|
||||
--> $DIR/higher-ranked-fn-type.rs:20:5
|
||||
|
|
||||
LL | called()
|
||||
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `for<'b> fn(&'b ())`
|
||||
| ^^^^^^ the trait `for<'b> Foo` is not implemented for `fn(&'b ())`
|
||||
|
|
||||
note: required by a bound in `called`
|
||||
--> $DIR/higher-ranked-fn-type.rs:12:25
|
||||
|
@ -18,7 +18,7 @@ where
|
||||
(for<'a> fn(&'a ())): Foo,
|
||||
{
|
||||
called()
|
||||
//[quiet]~^ ERROR the trait bound `for<'b> for<'b> fn(&'b ()): Foo` is not satisfied
|
||||
//[quiet]~^ ERROR the trait bound `for<'b> fn(&'b ()): Foo` is not satisfied
|
||||
//[verbose]~^^ ERROR the trait bound `for<'b> fn(&ReLateBound(
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user