mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Auto merge of #133280 - matthiaskrgr:rollup-8keusum, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #131736 (Emscripten: link with -sWASM_BIGINT) - #132207 (Store resolution for self and crate root module segments) - #133153 (Add visits to nodes that already have flat_maps in ast::MutVisitor) - #133218 (Implement `~const` item bounds in RPIT) - #133228 (Rewrite `show_md_content_with_pager`) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0b1bf71a71
@ -104,8 +104,16 @@ pub trait MutVisitor: Sized {
|
||||
walk_use_tree(self, use_tree);
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, ni: &mut P<ForeignItem>) {
|
||||
walk_item(self, ni);
|
||||
}
|
||||
|
||||
fn flat_map_foreign_item(&mut self, ni: P<ForeignItem>) -> SmallVec<[P<ForeignItem>; 1]> {
|
||||
walk_flat_map_item(self, ni)
|
||||
walk_flat_map_foreign_item(self, ni)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &mut P<Item>) {
|
||||
walk_item(self, i);
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
@ -116,10 +124,18 @@ pub trait MutVisitor: Sized {
|
||||
walk_fn_header(self, header);
|
||||
}
|
||||
|
||||
fn visit_field_def(&mut self, fd: &mut FieldDef) {
|
||||
walk_field_def(self, fd);
|
||||
}
|
||||
|
||||
fn flat_map_field_def(&mut self, fd: FieldDef) -> SmallVec<[FieldDef; 1]> {
|
||||
walk_flat_map_field_def(self, fd)
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, i: &mut P<AssocItem>, ctxt: AssocCtxt) {
|
||||
walk_assoc_item(self, i, ctxt)
|
||||
}
|
||||
|
||||
fn flat_map_assoc_item(
|
||||
&mut self,
|
||||
i: P<AssocItem>,
|
||||
@ -153,6 +169,10 @@ pub trait MutVisitor: Sized {
|
||||
walk_flat_map_stmt(self, s)
|
||||
}
|
||||
|
||||
fn visit_arm(&mut self, arm: &mut Arm) {
|
||||
walk_arm(self, arm);
|
||||
}
|
||||
|
||||
fn flat_map_arm(&mut self, arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
walk_flat_map_arm(self, arm)
|
||||
}
|
||||
@ -199,6 +219,10 @@ pub trait MutVisitor: Sized {
|
||||
walk_foreign_mod(self, nm);
|
||||
}
|
||||
|
||||
fn visit_variant(&mut self, v: &mut Variant) {
|
||||
walk_variant(self, v);
|
||||
}
|
||||
|
||||
fn flat_map_variant(&mut self, v: Variant) -> SmallVec<[Variant; 1]> {
|
||||
walk_flat_map_variant(self, v)
|
||||
}
|
||||
@ -251,6 +275,10 @@ pub trait MutVisitor: Sized {
|
||||
walk_attribute(self, at);
|
||||
}
|
||||
|
||||
fn visit_param(&mut self, param: &mut Param) {
|
||||
walk_param(self, param);
|
||||
}
|
||||
|
||||
fn flat_map_param(&mut self, param: Param) -> SmallVec<[Param; 1]> {
|
||||
walk_flat_map_param(self, param)
|
||||
}
|
||||
@ -271,6 +299,10 @@ pub trait MutVisitor: Sized {
|
||||
walk_variant_data(self, vdata);
|
||||
}
|
||||
|
||||
fn visit_generic_param(&mut self, param: &mut GenericParam) {
|
||||
walk_generic_param(self, param)
|
||||
}
|
||||
|
||||
fn flat_map_generic_param(&mut self, param: GenericParam) -> SmallVec<[GenericParam; 1]> {
|
||||
walk_flat_map_generic_param(self, param)
|
||||
}
|
||||
@ -287,6 +319,10 @@ pub trait MutVisitor: Sized {
|
||||
walk_mt(self, mt);
|
||||
}
|
||||
|
||||
fn visit_expr_field(&mut self, f: &mut ExprField) {
|
||||
walk_expr_field(self, f);
|
||||
}
|
||||
|
||||
fn flat_map_expr_field(&mut self, f: ExprField) -> SmallVec<[ExprField; 1]> {
|
||||
walk_flat_map_expr_field(self, f)
|
||||
}
|
||||
@ -311,6 +347,10 @@ pub trait MutVisitor: Sized {
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
fn visit_pat_field(&mut self, fp: &mut PatField) {
|
||||
walk_pat_field(self, fp)
|
||||
}
|
||||
|
||||
fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
|
||||
walk_flat_map_pat_field(self, fp)
|
||||
}
|
||||
@ -429,16 +469,20 @@ pub fn visit_delim_span<T: MutVisitor>(vis: &mut T, DelimSpan { open, close }: &
|
||||
vis.visit_span(close);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fp: PatField,
|
||||
) -> SmallVec<[PatField; 1]> {
|
||||
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = &mut fp;
|
||||
pub fn walk_pat_field<T: MutVisitor>(vis: &mut T, fp: &mut PatField) {
|
||||
let PatField { attrs, id, ident, is_placeholder: _, is_shorthand: _, pat, span } = fp;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_pat_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fp: PatField,
|
||||
) -> SmallVec<[PatField; 1]> {
|
||||
vis.visit_pat_field(&mut fp);
|
||||
smallvec![fp]
|
||||
}
|
||||
|
||||
@ -459,14 +503,18 @@ fn walk_use_tree<T: MutVisitor>(vis: &mut T, use_tree: &mut UseTree) {
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = &mut arm;
|
||||
pub fn walk_arm<T: MutVisitor>(vis: &mut T, arm: &mut Arm) {
|
||||
let Arm { attrs, pat, guard, body, span, id, is_placeholder: _ } = arm;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_pat(pat);
|
||||
visit_opt(guard, |guard| vis.visit_expr(guard));
|
||||
visit_opt(body, |body| vis.visit_expr(body));
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_arm<T: MutVisitor>(vis: &mut T, mut arm: Arm) -> SmallVec<[Arm; 1]> {
|
||||
vis.visit_arm(&mut arm);
|
||||
smallvec![arm]
|
||||
}
|
||||
|
||||
@ -543,11 +591,8 @@ fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
|
||||
items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
visitor: &mut T,
|
||||
mut variant: Variant,
|
||||
) -> SmallVec<[Variant; 1]> {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = &mut variant;
|
||||
pub fn walk_variant<T: MutVisitor>(visitor: &mut T, variant: &mut Variant) {
|
||||
let Variant { ident, vis, attrs, id, data, disr_expr, span, is_placeholder: _ } = variant;
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
@ -555,6 +600,13 @@ pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
visitor.visit_variant_data(data);
|
||||
visit_opt(disr_expr, |disr_expr| visitor.visit_anon_const(disr_expr));
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_variant<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut variant: Variant,
|
||||
) -> SmallVec<[Variant; 1]> {
|
||||
vis.visit_variant(&mut variant);
|
||||
smallvec![variant]
|
||||
}
|
||||
|
||||
@ -685,13 +737,17 @@ fn walk_meta_item<T: MutVisitor>(vis: &mut T, mi: &mut MetaItem) {
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
|
||||
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = &mut param;
|
||||
pub fn walk_param<T: MutVisitor>(vis: &mut T, param: &mut Param) {
|
||||
let Param { attrs, id, pat, span, ty, is_placeholder: _ } = param;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_pat(pat);
|
||||
vis.visit_ty(ty);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_param<T: MutVisitor>(vis: &mut T, mut param: Param) -> SmallVec<[Param; 1]> {
|
||||
vis.visit_param(&mut param);
|
||||
smallvec![param]
|
||||
}
|
||||
|
||||
@ -950,11 +1006,8 @@ fn walk_precise_capturing_arg<T: MutVisitor>(vis: &mut T, arg: &mut PreciseCaptu
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut param: GenericParam,
|
||||
) -> SmallVec<[GenericParam; 1]> {
|
||||
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = &mut param;
|
||||
pub fn walk_generic_param<T: MutVisitor>(vis: &mut T, param: &mut GenericParam) {
|
||||
let GenericParam { id, ident, attrs, bounds, kind, colon_span, is_placeholder: _ } = param;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
@ -972,6 +1025,13 @@ pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
||||
if let Some(colon_span) = colon_span {
|
||||
vis.visit_span(colon_span);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_generic_param<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut param: GenericParam,
|
||||
) -> SmallVec<[GenericParam; 1]> {
|
||||
vis.visit_generic_param(&mut param);
|
||||
smallvec![param]
|
||||
}
|
||||
|
||||
@ -1054,30 +1114,38 @@ fn walk_poly_trait_ref<T: MutVisitor>(vis: &mut T, p: &mut PolyTraitRef) {
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_field_def<T: MutVisitor>(
|
||||
visitor: &mut T,
|
||||
mut fd: FieldDef,
|
||||
) -> SmallVec<[FieldDef; 1]> {
|
||||
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = &mut fd;
|
||||
pub fn walk_field_def<T: MutVisitor>(visitor: &mut T, fd: &mut FieldDef) {
|
||||
let FieldDef { span, ident, vis, id, ty, attrs, is_placeholder: _ } = fd;
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
visitor.visit_vis(vis);
|
||||
visit_opt(ident, |ident| visitor.visit_ident(ident));
|
||||
visitor.visit_ty(ty);
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_field_def<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut fd: FieldDef,
|
||||
) -> SmallVec<[FieldDef; 1]> {
|
||||
vis.visit_field_def(&mut fd);
|
||||
smallvec![fd]
|
||||
}
|
||||
|
||||
pub fn walk_expr_field<T: MutVisitor>(vis: &mut T, f: &mut ExprField) {
|
||||
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = f;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_expr_field<T: MutVisitor>(
|
||||
vis: &mut T,
|
||||
mut f: ExprField,
|
||||
) -> SmallVec<[ExprField; 1]> {
|
||||
let ExprField { ident, expr, span, is_shorthand: _, attrs, id, is_placeholder: _ } = &mut f;
|
||||
vis.visit_id(id);
|
||||
visit_attrs(vis, attrs);
|
||||
vis.visit_ident(ident);
|
||||
vis.visit_expr(expr);
|
||||
vis.visit_span(span);
|
||||
vis.visit_expr_field(&mut f);
|
||||
smallvec![f]
|
||||
}
|
||||
|
||||
@ -1331,18 +1399,19 @@ pub fn walk_crate<T: MutVisitor>(vis: &mut T, krate: &mut Crate) {
|
||||
vis.visit_span(inject_use_span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item<K: WalkItemKind<Ctxt = ()>>(
|
||||
visitor: &mut impl MutVisitor,
|
||||
item: P<Item<K>>,
|
||||
) -> SmallVec<[P<Item<K>>; 1]> {
|
||||
walk_flat_map_assoc_item(visitor, item, ())
|
||||
pub fn walk_item(visitor: &mut impl MutVisitor, item: &mut P<Item<impl WalkItemKind<Ctxt = ()>>>) {
|
||||
walk_item_ctxt(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
|
||||
pub fn walk_assoc_item(visitor: &mut impl MutVisitor, item: &mut P<AssocItem>, ctxt: AssocCtxt) {
|
||||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<K: WalkItemKind>(
|
||||
visitor: &mut impl MutVisitor,
|
||||
mut item: P<Item<K>>,
|
||||
item: &mut P<Item<K>>,
|
||||
ctxt: K::Ctxt,
|
||||
) -> SmallVec<[P<Item<K>>; 1]> {
|
||||
) {
|
||||
let Item { ident, attrs, id, kind, vis, span, tokens } = item.deref_mut();
|
||||
visitor.visit_id(id);
|
||||
visit_attrs(visitor, attrs);
|
||||
@ -1351,6 +1420,27 @@ pub fn walk_flat_map_assoc_item<K: WalkItemKind>(
|
||||
kind.walk(*span, *id, ident, vis, ctxt, visitor);
|
||||
visit_lazy_tts(visitor, tokens);
|
||||
visitor.visit_span(span);
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_item(vis: &mut impl MutVisitor, mut item: P<Item>) -> SmallVec<[P<Item>; 1]> {
|
||||
vis.visit_item(&mut item);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_foreign_item(
|
||||
vis: &mut impl MutVisitor,
|
||||
mut item: P<ForeignItem>,
|
||||
) -> SmallVec<[P<ForeignItem>; 1]> {
|
||||
vis.visit_foreign_item(&mut item);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
pub fn walk_flat_map_assoc_item(
|
||||
vis: &mut impl MutVisitor,
|
||||
mut item: P<AssocItem>,
|
||||
ctxt: AssocCtxt,
|
||||
) -> SmallVec<[P<AssocItem>; 1]> {
|
||||
vis.visit_assoc_item(&mut item, ctxt);
|
||||
smallvec![item]
|
||||
}
|
||||
|
||||
|
@ -463,13 +463,6 @@ impl WalkItemKind for ItemKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
|
||||
) -> V::Result {
|
||||
walk_assoc_item(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_enum_def<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
EnumDef { variants }: &'a EnumDef,
|
||||
@ -931,7 +924,22 @@ impl WalkItemKind for AssocItemKind {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_assoc_item<'a, V: Visitor<'a>, K: WalkItemKind>(
|
||||
pub fn walk_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<impl WalkItemKind<Ctxt = ()>>,
|
||||
) -> V::Result {
|
||||
walk_item_ctxt(visitor, item, ())
|
||||
}
|
||||
|
||||
pub fn walk_assoc_item<'a, V: Visitor<'a>>(
|
||||
visitor: &mut V,
|
||||
item: &'a AssocItem,
|
||||
ctxt: AssocCtxt,
|
||||
) -> V::Result {
|
||||
walk_item_ctxt(visitor, item, ctxt)
|
||||
}
|
||||
|
||||
fn walk_item_ctxt<'a, V: Visitor<'a>, K: WalkItemKind>(
|
||||
visitor: &mut V,
|
||||
item: &'a Item<K>,
|
||||
ctxt: K::Ctxt,
|
||||
|
@ -215,7 +215,7 @@ impl MutVisitor for CfgEval<'_> {
|
||||
foreign_item: P<ast::ForeignItem>,
|
||||
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
||||
let foreign_item = configure!(self, foreign_item);
|
||||
mut_visit::walk_flat_map_item(self, foreign_item)
|
||||
mut_visit::walk_flat_map_foreign_item(self, foreign_item)
|
||||
}
|
||||
|
||||
fn flat_map_arm(&mut self, arm: ast::Arm) -> SmallVec<[ast::Arm; 1]> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Code that generates a test runner to run all the tests in a crate
|
||||
|
||||
use std::{iter, mem};
|
||||
use std::mem;
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::entry::EntryPointType;
|
||||
@ -19,7 +19,7 @@ use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency};
|
||||
use rustc_span::symbol::{Ident, Symbol, sym};
|
||||
use rustc_span::{DUMMY_SP, Span};
|
||||
use rustc_target::spec::PanicStrategy;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use smallvec::smallvec;
|
||||
use thin_vec::{ThinVec, thin_vec};
|
||||
use tracing::debug;
|
||||
|
||||
@ -129,8 +129,9 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||
c.items.push(mk_main(&mut self.cx));
|
||||
}
|
||||
|
||||
fn flat_map_item(&mut self, mut i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
let item = &mut *i;
|
||||
fn visit_item(&mut self, item: &mut P<ast::Item>) {
|
||||
let item = &mut **item;
|
||||
|
||||
if let Some(name) = get_test_name(&item) {
|
||||
debug!("this is a test item");
|
||||
|
||||
@ -158,7 +159,6 @@ impl<'a> MutVisitor for TestHarnessGenerator<'a> {
|
||||
// But in those cases, we emit a lint to warn the user of these missing tests.
|
||||
walk_item(&mut InnerItemLinter { sess: self.cx.ext_cx.sess }, &item);
|
||||
}
|
||||
smallvec![i]
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,40 +198,30 @@ struct EntryPointCleaner<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MutVisitor for EntryPointCleaner<'a> {
|
||||
fn flat_map_item(&mut self, i: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
|
||||
fn visit_item(&mut self, item: &mut P<ast::Item>) {
|
||||
self.depth += 1;
|
||||
let item = walk_flat_map_item(self, i).expect_one("noop did something");
|
||||
ast::mut_visit::walk_item(self, item);
|
||||
self.depth -= 1;
|
||||
|
||||
// Remove any #[rustc_main] or #[start] from the AST so it doesn't
|
||||
// clash with the one we're going to add, but mark it as
|
||||
// #[allow(dead_code)] to avoid printing warnings.
|
||||
let item = match entry_point_type(&item, self.depth == 0) {
|
||||
match entry_point_type(&item, self.depth == 0) {
|
||||
EntryPointType::MainNamed | EntryPointType::RustcMainAttr | EntryPointType::Start => {
|
||||
item.map(|ast::Item { id, ident, attrs, kind, vis, span, tokens }| {
|
||||
let allow_dead_code = attr::mk_attr_nested_word(
|
||||
&self.sess.psess.attr_id_generator,
|
||||
ast::AttrStyle::Outer,
|
||||
ast::Safety::Default,
|
||||
sym::allow,
|
||||
sym::dead_code,
|
||||
self.def_site,
|
||||
);
|
||||
let attrs = attrs
|
||||
.into_iter()
|
||||
.filter(|attr| {
|
||||
!attr.has_name(sym::rustc_main) && !attr.has_name(sym::start)
|
||||
})
|
||||
.chain(iter::once(allow_dead_code))
|
||||
.collect();
|
||||
|
||||
ast::Item { id, ident, attrs, kind, vis, span, tokens }
|
||||
})
|
||||
let allow_dead_code = attr::mk_attr_nested_word(
|
||||
&self.sess.psess.attr_id_generator,
|
||||
ast::AttrStyle::Outer,
|
||||
ast::Safety::Default,
|
||||
sym::allow,
|
||||
sym::dead_code,
|
||||
self.def_site,
|
||||
);
|
||||
item.attrs
|
||||
.retain(|attr| !attr.has_name(sym::rustc_main) && !attr.has_name(sym::start));
|
||||
item.attrs.push(allow_dead_code);
|
||||
}
|
||||
EntryPointType::None | EntryPointType::OtherMain => item,
|
||||
EntryPointType::None | EntryPointType::OtherMain => {}
|
||||
};
|
||||
|
||||
smallvec![item]
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +282,7 @@ fn generate_test_harness(
|
||||
/// Most of the Ident have the usual def-site hygiene for the AST pass. The
|
||||
/// exception is the `test_const`s. These have a syntax context that has two
|
||||
/// opaque marks: one from the expansion of `test` or `test_case`, and one
|
||||
/// generated in `TestHarnessGenerator::flat_map_item`. When resolving this
|
||||
/// generated in `TestHarnessGenerator::visit_item`. When resolving this
|
||||
/// identifier after failing to find a matching identifier in the root module
|
||||
/// we remove the outer mark, and try resolving at its def-site, which will
|
||||
/// then resolve to `test_const`.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#![feature(panic_update_hook)]
|
||||
#![feature(result_flattening)]
|
||||
#![feature(rustdoc_internals)]
|
||||
#![feature(try_blocks)]
|
||||
#![warn(unreachable_pub)]
|
||||
// tidy-alphabetical-end
|
||||
|
||||
@ -564,71 +565,63 @@ fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, col
|
||||
}
|
||||
}
|
||||
|
||||
/// If color is always or auto, print formatted & colorized markdown. If color is never or
|
||||
/// if formatted printing fails, print the raw text.
|
||||
/// If `color` is `always` or `auto`, try to print pretty (formatted & colorized) markdown. If
|
||||
/// that fails or `color` is `never`, print the raw markdown.
|
||||
///
|
||||
/// Prefers a pager, falls back standard print
|
||||
/// Uses a pager if possible, falls back to stdout.
|
||||
fn show_md_content_with_pager(content: &str, color: ColorConfig) {
|
||||
let mut fallback_to_println = false;
|
||||
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
|
||||
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
|
||||
});
|
||||
|
||||
let mut cmd = Command::new(&pager_name);
|
||||
// FIXME: find if other pagers accept color options
|
||||
let mut print_formatted = if pager_name == "less" {
|
||||
cmd.arg("-R");
|
||||
true
|
||||
} else {
|
||||
["bat", "catbat", "delta"].iter().any(|v| *v == pager_name)
|
||||
if pager_name == "less" {
|
||||
cmd.arg("-R"); // allows color escape sequences
|
||||
}
|
||||
|
||||
let pretty_on_pager = match color {
|
||||
ColorConfig::Auto => {
|
||||
// Add other pagers that accept color escape sequences here.
|
||||
["less", "bat", "batcat", "delta"].iter().any(|v| *v == pager_name)
|
||||
}
|
||||
ColorConfig::Always => true,
|
||||
ColorConfig::Never => false,
|
||||
};
|
||||
|
||||
if color == ColorConfig::Never {
|
||||
print_formatted = false;
|
||||
} else if color == ColorConfig::Always {
|
||||
print_formatted = true;
|
||||
}
|
||||
// Try to prettify the raw markdown text. The result can be used by the pager or on stdout.
|
||||
let pretty_data = {
|
||||
let mdstream = markdown::MdStream::parse_str(content);
|
||||
let bufwtr = markdown::create_stdout_bufwtr();
|
||||
let mut mdbuf = bufwtr.buffer();
|
||||
if mdstream.write_termcolor_buf(&mut mdbuf).is_ok() { Some((bufwtr, mdbuf)) } else { None }
|
||||
};
|
||||
|
||||
let mdstream = markdown::MdStream::parse_str(content);
|
||||
let bufwtr = markdown::create_stdout_bufwtr();
|
||||
let mut mdbuf = bufwtr.buffer();
|
||||
if mdstream.write_termcolor_buf(&mut mdbuf).is_err() {
|
||||
print_formatted = false;
|
||||
}
|
||||
// Try to print via the pager, pretty output if possible.
|
||||
let pager_res: Option<()> = try {
|
||||
let mut pager = cmd.stdin(Stdio::piped()).spawn().ok()?;
|
||||
|
||||
if let Ok(mut pager) = cmd.stdin(Stdio::piped()).spawn() {
|
||||
if let Some(pipe) = pager.stdin.as_mut() {
|
||||
let res = if print_formatted {
|
||||
pipe.write_all(mdbuf.as_slice())
|
||||
} else {
|
||||
pipe.write_all(content.as_bytes())
|
||||
};
|
||||
|
||||
if res.is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
}
|
||||
|
||||
if pager.wait().is_err() {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
} else {
|
||||
fallback_to_println = true;
|
||||
}
|
||||
|
||||
// If pager fails for whatever reason, we should still print the content
|
||||
// to standard output
|
||||
if fallback_to_println {
|
||||
let fmt_success = match color {
|
||||
ColorConfig::Auto => io::stdout().is_terminal() && bufwtr.print(&mdbuf).is_ok(),
|
||||
ColorConfig::Always => bufwtr.print(&mdbuf).is_ok(),
|
||||
ColorConfig::Never => false,
|
||||
let pager_stdin = pager.stdin.as_mut()?;
|
||||
if pretty_on_pager && let Some((_, mdbuf)) = &pretty_data {
|
||||
pager_stdin.write_all(mdbuf.as_slice()).ok()?;
|
||||
} else {
|
||||
pager_stdin.write_all(content.as_bytes()).ok()?;
|
||||
};
|
||||
|
||||
if !fmt_success {
|
||||
safe_print!("{content}");
|
||||
}
|
||||
pager.wait().ok()?;
|
||||
};
|
||||
if pager_res.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
// The pager failed. Try to print pretty output to stdout.
|
||||
if let Some((bufwtr, mdbuf)) = &pretty_data
|
||||
&& bufwtr.print(&mdbuf).is_ok()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Everything failed. Print the raw markdown text.
|
||||
safe_print!("{content}");
|
||||
}
|
||||
|
||||
fn process_rlink(sess: &Session, compiler: &interface::Compiler) {
|
||||
|
@ -1382,7 +1382,7 @@ impl InvocationCollectorNode for P<ast::ForeignItem> {
|
||||
fragment.make_foreign_items()
|
||||
}
|
||||
fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
|
||||
walk_flat_map_item(visitor, self)
|
||||
walk_flat_map_foreign_item(visitor, self)
|
||||
}
|
||||
fn is_mac_call(&self) -> bool {
|
||||
matches!(self.kind, ForeignItemKind::MacCall(..))
|
||||
|
@ -296,7 +296,7 @@ impl MutVisitor for PlaceholderExpander {
|
||||
) -> SmallVec<[P<ast::ForeignItem>; 1]> {
|
||||
match item.kind {
|
||||
ast::ForeignItemKind::MacCall(_) => self.remove(item.id).make_foreign_items(),
|
||||
_ => walk_flat_map_item(self, item),
|
||||
_ => walk_flat_map_foreign_item(self, item),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -339,6 +339,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
|
||||
let misc_cause = ObligationCause::misc(span, def_id);
|
||||
// FIXME: We should just register the item bounds here, rather than equating.
|
||||
// FIXME(const_trait_impl): When we do that, please make sure to also register
|
||||
// the `~const` bounds.
|
||||
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
|
||||
Ok(()) => {}
|
||||
Err(ty_err) => {
|
||||
|
@ -2083,7 +2083,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
||||
if tcx.is_conditionally_const(impl_ty_def_id) {
|
||||
obligations.extend(
|
||||
tcx.implied_const_bounds(trait_ty.def_id)
|
||||
tcx.explicit_implied_const_bounds(trait_ty.def_id)
|
||||
.iter_instantiated_copied(tcx, rebased_args)
|
||||
.map(|(c, span)| {
|
||||
traits::Obligation::new(
|
||||
|
@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
predicates_of::explicit_supertraits_containing_assoc_item,
|
||||
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
||||
const_conditions: predicates_of::const_conditions,
|
||||
implied_const_bounds: predicates_of::implied_const_bounds,
|
||||
explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
|
||||
type_param_predicates: predicates_of::type_param_predicates,
|
||||
trait_def,
|
||||
adt_def,
|
||||
@ -340,6 +340,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
||||
self.tcx.ensure().explicit_item_super_predicates(def_id);
|
||||
self.tcx.ensure().item_bounds(def_id);
|
||||
self.tcx.ensure().item_super_predicates(def_id);
|
||||
if self.tcx.is_conditionally_const(def_id) {
|
||||
self.tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||
self.tcx.ensure().const_conditions(def_id);
|
||||
}
|
||||
intravisit::walk_opaque_ty(self, opaque);
|
||||
}
|
||||
|
||||
@ -682,6 +686,10 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
||||
tcx.ensure().generics_of(item.owner_id);
|
||||
tcx.ensure().type_of(item.owner_id);
|
||||
tcx.ensure().predicates_of(item.owner_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||
tcx.ensure().const_conditions(def_id);
|
||||
}
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(..) => {
|
||||
tcx.ensure().codegen_fn_attrs(item.owner_id);
|
||||
|
@ -959,6 +959,12 @@ pub(super) fn const_conditions<'tcx>(
|
||||
hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
|
||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||
},
|
||||
Node::OpaqueTy(opaque) => match opaque.origin {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent),
|
||||
hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
},
|
||||
// N.B. Tuple ctors are unconditionally constant.
|
||||
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
|
||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||
@ -1018,7 +1024,7 @@ pub(super) fn const_conditions<'tcx>(
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn implied_const_bounds<'tcx>(
|
||||
pub(super) fn explicit_implied_const_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: LocalDefId,
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||
@ -1034,10 +1040,11 @@ pub(super) fn implied_const_bounds<'tcx>(
|
||||
PredicateFilter::SelfConstIfConst,
|
||||
)
|
||||
}
|
||||
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
|
||||
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
|
||||
| Node::OpaqueTy(_) => {
|
||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
|
||||
}
|
||||
_ => bug!("implied_const_bounds called on wrong item: {def_id:?}"),
|
||||
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
|
||||
};
|
||||
|
||||
bounds.map_bound(|bounds| {
|
||||
|
@ -1106,7 +1106,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
.collect::<String>()
|
||||
),
|
||||
[(only, _)] => only.to_string(),
|
||||
[] => "this type".to_string(),
|
||||
[] => bug!("expected one segment to deny"),
|
||||
};
|
||||
|
||||
let arg_spans: Vec<Span> = segments
|
||||
@ -1136,7 +1136,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||
"s",
|
||||
),
|
||||
[only] => (only.to_string(), ""),
|
||||
[] => unreachable!("expected at least one generic to prohibit"),
|
||||
[] => bug!("expected at least one generic to prohibit"),
|
||||
};
|
||||
let last_span = *arg_spans.last().unwrap();
|
||||
let span: MultiSpan = arg_spans.into();
|
||||
|
@ -574,9 +574,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// unexpected region errors.
|
||||
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
|
||||
|
||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
||||
let replace_opaques_in = |clause: ty::Clause<'tcx>, goals: &mut Vec<_>| {
|
||||
clause.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
// We can't normalize associated types from `rustc_infer`,
|
||||
@ -612,11 +611,31 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
},
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
});
|
||||
})
|
||||
};
|
||||
|
||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = replace_opaques_in(predicate, goals);
|
||||
|
||||
// Require that the predicate holds for the concrete type.
|
||||
debug!(?predicate);
|
||||
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||
}
|
||||
|
||||
// If this opaque is being defined and it's conditionally const,
|
||||
if self.tcx.is_conditionally_const(def_id) {
|
||||
let item_bounds = tcx.explicit_implied_const_bounds(def_id);
|
||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||
let predicate = replace_opaques_in(
|
||||
predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe),
|
||||
goals,
|
||||
);
|
||||
|
||||
// Require that the predicate holds for the concrete type.
|
||||
debug!(?predicate);
|
||||
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,15 +230,16 @@ impl<'a, T: EarlyLintPass> ast_visit::Visitor<'a> for EarlyContextAndPass<'a, T>
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: ast_visit::AssocCtxt) {
|
||||
self.with_lint_attrs(item.id, &item.attrs, |cx| match ctxt {
|
||||
ast_visit::AssocCtxt::Trait => {
|
||||
lint_callback!(cx, check_trait_item, item);
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
}
|
||||
ast_visit::AssocCtxt::Impl => {
|
||||
lint_callback!(cx, check_impl_item, item);
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
self.with_lint_attrs(item.id, &item.attrs, |cx| {
|
||||
match ctxt {
|
||||
ast_visit::AssocCtxt::Trait => {
|
||||
lint_callback!(cx, check_trait_item, item);
|
||||
}
|
||||
ast_visit::AssocCtxt::Impl => {
|
||||
lint_callback!(cx, check_impl_item, item);
|
||||
}
|
||||
}
|
||||
ast_visit::walk_assoc_item(cx, item, ctxt);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -275,7 +275,7 @@ provide! { tcx, def_id, other, cdata,
|
||||
defaultness => { table_direct }
|
||||
constness => { table_direct }
|
||||
const_conditions => { table }
|
||||
implied_const_bounds => { table_defaulted_array }
|
||||
explicit_implied_const_bounds => { table_defaulted_array }
|
||||
coerce_unsized_info => {
|
||||
Ok(cdata
|
||||
.root
|
||||
|
@ -1463,8 +1463,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||
module_children.iter().map(|child| child.res.def_id().index));
|
||||
if self.tcx.is_const_trait(def_id) {
|
||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
if let DefKind::TraitAlias = def_kind {
|
||||
@ -1532,6 +1532,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
self.encode_explicit_item_super_predicates(def_id);
|
||||
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
|
||||
self.encode_precise_capturing_args(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||
@ -1654,8 +1658,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
self.encode_explicit_item_super_predicates(def_id);
|
||||
if tcx.is_conditionally_const(def_id) {
|
||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ define_tables! {
|
||||
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||
implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
||||
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
||||
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
||||
|
@ -697,7 +697,7 @@ rustc_queries! {
|
||||
separate_provide_extern
|
||||
}
|
||||
|
||||
query implied_const_bounds(
|
||||
query explicit_implied_const_bounds(
|
||||
key: DefId
|
||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
||||
|
@ -393,12 +393,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
fn implied_const_bounds(
|
||||
fn explicit_implied_const_bounds(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||
self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -2110,7 +2110,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
||||
}
|
||||
}
|
||||
DefKind::Closure | DefKind::OpaqueTy => {
|
||||
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
|
||||
hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
|
||||
hir::OpaqueTyOrigin::AsyncFn { .. } => false,
|
||||
// FIXME(const_trait_impl): ATPITs could be conditionally const?
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => false,
|
||||
},
|
||||
DefKind::Closure => {
|
||||
// Closures and RPITs will eventually have const conditions
|
||||
// for `~const` bounds.
|
||||
false
|
||||
|
@ -102,7 +102,7 @@ where
|
||||
|
||||
/// Assemble additional assumptions for an alias that are not included
|
||||
/// in the item bounds of the alias. For now, this is limited to the
|
||||
/// `implied_const_bounds` for an associated type.
|
||||
/// `explicit_implied_const_bounds` for an associated type.
|
||||
fn consider_additional_alias_assumptions(
|
||||
ecx: &mut EvalCtxt<'_, D>,
|
||||
goal: Goal<I, Self>,
|
||||
|
@ -84,12 +84,9 @@ where
|
||||
let cx = ecx.cx();
|
||||
let mut candidates = vec![];
|
||||
|
||||
// FIXME(const_trait_impl): We elaborate here because the implied const bounds
|
||||
// aren't necessarily elaborated. We probably should prefix this query
|
||||
// with `explicit_`...
|
||||
for clause in elaborate::elaborate(
|
||||
cx,
|
||||
cx.implied_const_bounds(alias_ty.def_id)
|
||||
cx.explicit_implied_const_bounds(alias_ty.def_id)
|
||||
.iter_instantiated(cx, alias_ty.args)
|
||||
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
|
||||
) {
|
||||
|
@ -1478,9 +1478,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
if segment_idx == 0 {
|
||||
if name == kw::SelfLower {
|
||||
let mut ctxt = ident.span.ctxt().normalize_to_macros_2_0();
|
||||
module = Some(ModuleOrUniformRoot::Module(
|
||||
self.resolve_self(&mut ctxt, parent_scope.module),
|
||||
));
|
||||
let self_mod = self.resolve_self(&mut ctxt, parent_scope.module);
|
||||
if let Some(res) = self_mod.res() {
|
||||
record_segment_res(self, res);
|
||||
}
|
||||
module = Some(ModuleOrUniformRoot::Module(self_mod));
|
||||
continue;
|
||||
}
|
||||
if name == kw::PathRoot && ident.span.at_least_rust_2018() {
|
||||
@ -1497,7 +1499,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
}
|
||||
if name == kw::PathRoot || name == kw::Crate || name == kw::DollarCrate {
|
||||
// `::a::b`, `crate::a::b` or `$crate::a::b`
|
||||
module = Some(ModuleOrUniformRoot::Module(self.resolve_crate_root(ident)));
|
||||
let crate_root = self.resolve_crate_root(ident);
|
||||
if let Some(res) = crate_root.res() {
|
||||
record_segment_res(self, res);
|
||||
}
|
||||
module = Some(ModuleOrUniformRoot::Module(crate_root));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,8 @@ use crate::spec::{
|
||||
pub(crate) fn target() -> Target {
|
||||
// Reset flags for non-Em flavors back to empty to satisfy sanity checking tests.
|
||||
let pre_link_args = LinkArgs::new();
|
||||
let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]);
|
||||
let post_link_args =
|
||||
TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0", "-sWASM_BIGINT"]);
|
||||
|
||||
let opts = TargetOptions {
|
||||
os: "emscripten".into(),
|
||||
|
@ -157,7 +157,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
||||
}
|
||||
// `T: ~const Trait` implies `T: ~const Supertrait`.
|
||||
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
|
||||
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||
elaboratable.child(
|
||||
trait_ref
|
||||
.to_host_effect_clause(cx, data.constness)
|
||||
|
@ -229,7 +229,7 @@ pub trait Interner:
|
||||
self,
|
||||
def_id: Self::DefId,
|
||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||
fn implied_const_bounds(
|
||||
fn explicit_implied_const_bounds(
|
||||
self,
|
||||
def_id: Self::DefId,
|
||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||
|
@ -158,9 +158,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.161"
|
||||
version = "0.2.162"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||
checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398"
|
||||
dependencies = [
|
||||
"rustc-std-workspace-core",
|
||||
]
|
||||
|
@ -34,7 +34,7 @@ miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
|
||||
addr2line = { version = "0.22.0", optional = true, default-features = false }
|
||||
|
||||
[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
|
||||
libc = { version = "0.2.161", default-features = false, features = [
|
||||
libc = { version = "0.2.162", default-features = false, features = [
|
||||
'rustc-dep-of-std',
|
||||
], public = true }
|
||||
|
||||
|
18
tests/ui/generics/generics-on-self-mod-segment.rs
Normal file
18
tests/ui/generics/generics-on-self-mod-segment.rs
Normal file
@ -0,0 +1,18 @@
|
||||
struct Ty;
|
||||
|
||||
fn self_(_: self::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
fn crate_(_: crate::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
macro_rules! dollar_crate {
|
||||
() => {
|
||||
fn dollar_crate_(_: $crate::<i32>::Ty) {}
|
||||
//~^ ERROR type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
}
|
||||
}
|
||||
|
||||
dollar_crate!();
|
||||
|
||||
fn main() {}
|
32
tests/ui/generics/generics-on-self-mod-segment.stderr
Normal file
32
tests/ui/generics/generics-on-self-mod-segment.stderr
Normal file
@ -0,0 +1,32 @@
|
||||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:3:20
|
||||
|
|
||||
LL | fn self_(_: self::<i32>::Ty) {}
|
||||
| ---- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:6:22
|
||||
|
|
||||
LL | fn crate_(_: crate::<i32>::Ty) {}
|
||||
| ----- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
|
||||
error[E0109]: type arguments are not allowed on module `generics_on_self_mod_segment`
|
||||
--> $DIR/generics-on-self-mod-segment.rs:11:38
|
||||
|
|
||||
LL | fn dollar_crate_(_: $crate::<i32>::Ty) {}
|
||||
| ------ ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on module `generics_on_self_mod_segment`
|
||||
...
|
||||
LL | dollar_crate!();
|
||||
| --------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `dollar_crate` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0109`.
|
@ -1,7 +1,7 @@
|
||||
trait Trait {}
|
||||
|
||||
fn test<T: ?self::<i32>::Trait>() {}
|
||||
//~^ ERROR type arguments are not allowed on this type
|
||||
//~^ ERROR type arguments are not allowed on module `maybe_bound_has_path_args`
|
||||
//~| WARN relaxing a default bound only does something for `?Sized`
|
||||
|
||||
fn main() {}
|
||||
|
@ -4,13 +4,13 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
|
||||
LL | fn test<T: ?self::<i32>::Trait>() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0109]: type arguments are not allowed on this type
|
||||
error[E0109]: type arguments are not allowed on module `maybe_bound_has_path_args`
|
||||
--> $DIR/maybe-bound-has-path-args.rs:3:20
|
||||
|
|
||||
LL | fn test<T: ?self::<i32>::Trait>() {}
|
||||
| ---- ^^^ type argument not allowed
|
||||
| |
|
||||
| not allowed on this type
|
||||
| not allowed on module `maybe_bound_has_path_args`
|
||||
|
||||
error: aborting due to 1 previous error; 1 warning emitted
|
||||
|
||||
|
@ -12,5 +12,13 @@ LL | const fn test() -> impl ~const Fn() {
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/const-closure-parse-not-item.rs:7:25
|
||||
|
|
||||
LL | const fn test() -> impl ~const Fn() {
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
15
tests/ui/traits/const-traits/const-opaque.no.stderr
Normal file
15
tests/ui/traits/const-traits/const-opaque.no.stderr
Normal file
@ -0,0 +1,15 @@
|
||||
error[E0277]: the trait bound `(): const Foo` is not satisfied
|
||||
--> $DIR/const-opaque.rs:31:18
|
||||
|
|
||||
LL | let opaque = bar(());
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `(): const Foo` is not satisfied
|
||||
--> $DIR/const-opaque.rs:33:5
|
||||
|
|
||||
LL | opaque.method();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
38
tests/ui/traits/const-traits/const-opaque.rs
Normal file
38
tests/ui/traits/const-traits/const-opaque.rs
Normal file
@ -0,0 +1,38 @@
|
||||
//@ revisions: yes no
|
||||
//@ compile-flags: -Znext-solver
|
||||
//@[yes] check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
trait Foo {
|
||||
fn method(&self);
|
||||
}
|
||||
|
||||
impl<T: ~const Foo> const Foo for (T,) {
|
||||
fn method(&self) {}
|
||||
}
|
||||
|
||||
#[cfg(yes)]
|
||||
impl const Foo for () {
|
||||
fn method(&self) {}
|
||||
}
|
||||
|
||||
#[cfg(no)]
|
||||
impl Foo for () {
|
||||
fn method(&self) {}
|
||||
}
|
||||
|
||||
const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
|
||||
(t,)
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
let opaque = bar(());
|
||||
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||
opaque.method();
|
||||
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||
std::mem::forget(opaque);
|
||||
};
|
||||
|
||||
fn main() {}
|
@ -3,6 +3,7 @@
|
||||
const fn test() -> impl ~const Fn() {
|
||||
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||
const move || { //~ ERROR const closures are experimental
|
||||
let sl: &[u8] = b"foo";
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: const closures are experimental
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:6:5
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:7:5
|
||||
|
|
||||
LL | const move || {
|
||||
| ^^^^^
|
||||
@ -22,8 +22,16 @@ LL | const fn test() -> impl ~const Fn() {
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error: `~const` can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
||||
|
|
||||
LL | const fn test() -> impl ~const Fn() {
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||
|
||||
error[E0015]: cannot call non-const operator in constant functions
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
||||
|
|
||||
LL | assert_eq!(first, &b'f');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -32,7 +40,7 @@ LL | assert_eq!(first, &b'f');
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
|
||||
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
||||
|
|
||||
LL | assert_eq!(first, &b'f');
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -40,7 +48,7 @@ LL | assert_eq!(first, &b'f');
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0658.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
Loading…
Reference in New Issue
Block a user