Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion compiler/rustc_ast_lowering/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rustc_errors::codes::*;
use rustc_errors::{DiagArgFromDisplay, DiagSymbolList};
use rustc_errors::{DiagArgFromDisplay, DiagArgValue, DiagSymbolList, IntoDiagArg};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};

Expand Down Expand Up @@ -579,3 +579,33 @@ pub(crate) struct DelegationAttemptedBlockWithDefsRelowering {
#[primary_span]
pub span: Span,
}

/// Whether resolving `impl` or `mut` restriction paths
#[derive(Debug, Clone, Copy)]
pub(crate) enum ResolvingRestrictionKind {
Impl,
Mut,
}

impl IntoDiagArg for ResolvingRestrictionKind {
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
use std::borrow::Cow;
match self {
ResolvingRestrictionKind::Impl => DiagArgValue::Str(Cow::Borrowed("impl")),
ResolvingRestrictionKind::Mut => DiagArgValue::Str(Cow::Borrowed("mut")),
}
}
}

#[derive(Diagnostic)]
#[diag(
"{$kind ->
[impl] trait implementation
*[mut] field mutation
} can only be restricted to ancestor modules"
)]
pub(crate) struct RestrictionAncestorOnly {
#[primary_span]
pub(crate) span: Span,
pub(crate) kind: ResolvingRestrictionKind,
}
64 changes: 43 additions & 21 deletions compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use super::{
FnDeclKind, GenericArgsMode, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode,
RelaxedBoundForbiddenReason, RelaxedBoundPolicy,
};
use crate::diagnostics::ConstComptimeFn;
use crate::diagnostics::{ConstComptimeFn, ResolvingRestrictionKind, RestrictionAncestorOnly};

pub(super) struct ItemLowerer<'a, 'hir> {
pub(super) tcx: TyCtxt<'hir>,
Expand Down Expand Up @@ -498,7 +498,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
items,
}) => {
let constness = self.lower_constness(attrs, *constness);
let impl_restriction = self.lower_impl_restriction(impl_restriction);
let impl_restriction = self.lower_impl_restriction(impl_restriction, hir_id);
let ident = self.lower_ident(*ident);
let (generics, (safety, items, bounds)) = self.lower_generics(
generics,
Expand Down Expand Up @@ -895,7 +895,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
None => Ident::new(sym::integer(index), self.lower_span(f.span)),
},
vis_span: self.lower_span(f.vis.span),
mut_restriction: self.lower_mut_restriction(f.mut_restriction()),
mut_restriction: self.lower_mut_restriction(f.mut_restriction(), hir_id),
default: f
.default_value()
.map(|v| self.lower_anon_const_to_anon_const(v, v.value.span)),
Expand Down Expand Up @@ -1797,26 +1797,46 @@ impl<'hir> LoweringContext<'_, 'hir> {
}
}

fn lower_restriction_kind(&mut self, kind: &RestrictionKind) -> hir::RestrictionKind<'hir> {
match kind {
fn lower_restriction_kind(
&mut self,
restriction_kind: &RestrictionKind,
hir_id: HirId,
resolving_kind: ResolvingRestrictionKind,
) -> hir::RestrictionKind<'hir> {
match restriction_kind {
RestrictionKind::Unrestricted => hir::RestrictionKind::Unrestricted,
RestrictionKind::Restricted { path, id, shorthand: _ } => {
let res = self.get_partial_res(*id);
let parent_module = self.tcx.parent_module(hir_id);
if let Some(did) = res.and_then(|res| res.expect_full_res().opt_def_id()) {
hir::RestrictionKind::Restricted(self.arena.alloc(hir::Path {
res: did,
segments: self.arena.alloc_from_iter(path.segments.iter().map(|segment| {
self.lower_path_segment(
path.span,
segment,
ParamMode::Explicit,
GenericArgsMode::Err,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
)
})),
span: self.lower_span(path.span),
}))
if !self.tcx.is_descendant_of(parent_module, did) {
// If the restriction path is not an ancestor of the item,
// emit an error and recover by lowering the restriction to `Unrestricted`.
self.dcx()
.create_err(RestrictionAncestorOnly {
span: path.span,
kind: resolving_kind,
})
.emit();
hir::RestrictionKind::Unrestricted
} else {
hir::RestrictionKind::Restricted(self.arena.alloc(hir::Path {
res: did,
segments: self.arena.alloc_from_iter(path.segments.iter().map(
|segment| {
self.lower_path_segment(
path.span,
segment,
ParamMode::Explicit,
GenericArgsMode::Err,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
None,
)
},
)),
span: self.lower_span(path.span),
}))
}
} else {
self.dcx().span_delayed_bug(path.span, "should have errored in resolve");
hir::RestrictionKind::Unrestricted
Expand All @@ -1828,16 +1848,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
pub(super) fn lower_impl_restriction(
&mut self,
r: &ImplRestriction,
hir_id: HirId,
) -> &'hir hir::ImplRestriction<'hir> {
let kind = self.lower_restriction_kind(&r.kind);
let kind = self.lower_restriction_kind(&r.kind, hir_id, ResolvingRestrictionKind::Impl);
self.arena.alloc(hir::ImplRestriction { kind, span: self.lower_span(r.span) })
}

pub(super) fn lower_mut_restriction(
&mut self,
r: &MutRestriction,
hir_id: HirId,
) -> &'hir hir::MutRestriction<'hir> {
let kind = self.lower_restriction_kind(&r.kind);
let kind = self.lower_restriction_kind(&r.kind, hir_id, ResolvingRestrictionKind::Mut);
self.arena.alloc(hir::MutRestriction { kind, span: self.lower_span(r.span) })
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4398,6 +4398,8 @@ pub enum RestrictionKind<'hir> {
/// The restriction does not affect the item.
Unrestricted,
/// The restriction only applies outside of this path.
/// The path is guaranteed to resolve to an ancestor module
/// of the restricted item.
Restricted(&'hir Path<'hir, DefId>),
}

Expand Down
15 changes: 1 addition & 14 deletions compiler/rustc_resolve/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Spanned, Symbol};

use crate::Res;
use crate::late::{PatternSource, ResolvingRestrictionKind};
use crate::late::PatternSource;

pub(crate) mod impls;

Expand Down Expand Up @@ -547,19 +547,6 @@ pub(crate) struct ExpectedModuleFound {
#[diag("cannot determine resolution for the visibility", code = E0578)]
pub(crate) struct Indeterminate(#[primary_span] pub(crate) Span);

#[derive(Diagnostic)]
#[diag(
"{$kind ->
[impl] trait implementation
*[mut] field mutation
} can only be restricted to ancestor modules"
)]
pub(crate) struct RestrictionAncestorOnly {
#[primary_span]
pub(crate) span: Span,
pub(crate) kind: ResolvingRestrictionKind,
}

#[derive(Diagnostic)]
#[diag("cannot use a tool module through an import")]
pub(crate) struct ToolModuleImported {
Expand Down
46 changes: 3 additions & 43 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,23 +426,6 @@ pub(crate) enum AliasPossibility {
Maybe,
}

/// Whether resolving `impl` or `mut` restriction paths
#[derive(Debug, Clone, Copy)]
pub(crate) enum ResolvingRestrictionKind {
Impl,
Mut,
}

impl IntoDiagArg for ResolvingRestrictionKind {
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
use std::borrow::Cow;
match self {
ResolvingRestrictionKind::Impl => DiagArgValue::Str(Cow::Borrowed("impl")),
ResolvingRestrictionKind::Mut => DiagArgValue::Str(Cow::Borrowed("mut")),
}
}
}

#[derive(Copy, Clone, Debug)]
pub(crate) enum PathSource<'a, 'ast, 'ra> {
/// Type paths `Path`.
Expand Down Expand Up @@ -1502,7 +1485,7 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc
let FieldDef { attrs, id: _, span: _, vis, ident, ty, is_placeholder: _, extras: _ } = f;
walk_list!(self, visit_attribute, attrs);
try_visit!(self.visit_vis(vis));
self.resolve_restriction_path(&f.mut_restriction().kind, ResolvingRestrictionKind::Mut);
self.resolve_restriction_path(&f.mut_restriction().kind);
visit_opt!(self, visit_ident, ident);
try_visit!(self.visit_ty(ty));
if let Some(v) = f.default_value() {
Expand Down Expand Up @@ -2875,10 +2858,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {

ItemKind::Trait(Trait { generics, bounds, items, impl_restriction, .. }) => {
// resolve paths for `impl` restrictions
self.resolve_restriction_path(
&impl_restriction.kind,
ResolvingRestrictionKind::Impl,
);
self.resolve_restriction_path(&impl_restriction.kind);

// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
Expand Down Expand Up @@ -4494,31 +4474,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
}
}

fn resolve_restriction_path(
&mut self,
restriction: &'ast ast::RestrictionKind,
kind: ResolvingRestrictionKind,
) {
fn resolve_restriction_path(&mut self, restriction: &'ast ast::RestrictionKind) {
match &restriction {
ast::RestrictionKind::Unrestricted => (),
ast::RestrictionKind::Restricted { path, id, shorthand: _ } => {
self.smart_resolve_path(*id, &None, path, PathSource::Module);
if let Some(res) = self.r.partial_res_map[&id].full_res()
&& let Some(def_id) = res.opt_def_id()
{
if !self.r.is_accessible_from(
Visibility::Restricted(def_id),
self.parent_scope.module,
) {
self.r
.dcx()
.create_err(crate::diagnostics::RestrictionAncestorOnly {
span: path.span,
kind,
})
.emit();
}
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions library/core/src/io/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ pub trait WriteThroughCursor: Sized {
}

#[doc(hidden)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: WriteThroughCursor> Write for Cursor<W> {
#[inline]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Expand Down
22 changes: 20 additions & 2 deletions src/bootstrap/src/core/builder/cli_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,30 @@ pub(crate) fn match_paths_to_steps_and_run(
// repository root, to match the paths registered by command-line steps.
//
// E.g. `/home/ferris/rust/tests/ui/asm/cfg.rs` => `tests/ui/asm/cfg.rs`
//
// It is also possible that someone passed a relative path starting with . or ..
// In that case, we have to remove that path prefix.
let mut paths = paths
.iter()
.map(|path| {
// Here we "launder" the path through builder.src, to normalize relative path prefixes
// so ./tests/foo becomes just tests/foo
let path = if path.is_relative() {
builder
.src
.join(path)
.strip_prefix(&builder.src)
.expect("Cannot strip src path prefix")
.to_path_buf()
} else {
path.to_path_buf()
};

if path.is_absolute()
&& path.exists()
&& let Ok(relative) = path.strip_prefix(&builder.src)
{
relative
relative.to_path_buf()
} else {
path
}
Expand All @@ -101,7 +117,9 @@ pub(crate) fn match_paths_to_steps_and_run(
// If any absolute paths couldn't be made relative, stop now and report them.
let bad_abs_paths = paths.iter().filter(|path| path.is_absolute()).collect::<Vec<_>>();
if !bad_abs_paths.is_empty() {
eprintln!("ERROR: failed to resolve absolute paths: {bad_abs_paths:#?}");
eprintln!(
"ERROR: the following paths do not exist on disk or point outside the source directory: {bad_abs_paths:#?}"
);
crate::exit!(1);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
source: src/bootstrap/src/core/builder/cli_paths/tests.rs
expression: test ./tests/ui
---
[Test] test::Ui
targets: [aarch64-unknown-linux-gnu]
- Suite(tests/ui)
1 change: 1 addition & 0 deletions src/bootstrap/src/core/builder/cli_paths/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ declare_tests!(
(x_test_tests, "test tests"),
(x_test_tests_skip_coverage, "test tests --skip=coverage"),
(x_test_tests_ui, "test tests/ui"),
(x_test_tests_ui_dot_prefix, "test ./tests/ui"),
(x_test_tidy, "test tidy"),
(x_test_tidyselftest, "test tidyselftest"),
(x_test_ui, "test ui"),
Expand Down
1 change: 1 addition & 0 deletions src/tools/compiletest/src/directives/directive_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
"ignore-nto",
"ignore-nvptx64",
"ignore-nvptx64-nvidia-cuda",
"ignore-ohos",
"ignore-openbsd",
"ignore-parallel-frontend",
"ignore-pauthtest",
Expand Down
1 change: 1 addition & 0 deletions tests/codegen-llvm/thread-local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//@ ignore-android does not use #[thread_local]
//@ ignore-nto does not use #[thread_local]
//@ ignore-qnx does not use #[thread_local]
//@ ignore-ohos does not use #[thread_local]

#![crate_type = "lib"]

Expand Down
1 change: 1 addition & 0 deletions tests/debuginfo/pretty-huge-vec.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ ignore-windows-gnu: #128981
//@ ignore-android: FIXME(#10381)
//@ ignore-ohos: similiar to android
//@ ignore-aix: FIXME(#137965)
//@ compile-flags:-g
//@ ignore-backends: gcc
Expand Down
1 change: 1 addition & 0 deletions tests/ui/asm/aarch64/sym.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//@ only-aarch64
//@ only-linux
//@ ignore-ohos does not use #[thread_local]
//@ needs-asm-support
//@ run-pass

Expand Down
Loading
Loading