Auto merge of #89417 - Manishearth:rollup-j2gdu95, r=Manishearth

Rollup of 7 pull requests

Successful merges:

 - #88838 (Do not suggest importing inaccessible items)
 - #89251 (Detect when negative literal indices are used and suggest appropriate code)
 - #89321 (Rebase resume argument projections during state transform)
 - #89327 (Pick one possible lifetime in case there are multiple choices)
 - #89344 (Cleanup lower_generics_mut and make span be the bound itself)
 - #89397 (Update `llvm` submodule to fix function name mangling on x86 Windows)
 - #89412 (Add regression test for issues #88969 and #89119 )

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-10-01 09:00:42 +00:00
commit 69eb996b26
28 changed files with 558 additions and 158 deletions

View File

@ -1328,32 +1328,45 @@ impl<'hir> LoweringContext<'_, 'hir> {
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
// where clauses for `?Sized`.
for pred in &generics.where_clause.predicates {
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
'next_bound: for bound in &bound_pred.bounds {
if let GenericBound::Trait(_, TraitBoundModifier::Maybe) = *bound {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| (d.base_res(), d.unresolved_segments()))
{
Some((Res::Def(DefKind::TyParam, def_id), 0))
if bound_pred.bound_generic_params.is_empty() =>
{
for param in &generics.params {
if def_id == self.resolver.local_def_id(param.id).to_def_id() {
continue 'next_bound;
}
}
}
_ => {}
}
self.diagnostic().span_err(
bound_pred.bounded_ty.span,
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
let bound_pred = match *pred {
WherePredicate::BoundPredicate(ref bound_pred) => bound_pred,
_ => continue,
};
let compute_is_param = || {
// Check if the where clause type is a plain type parameter.
match self
.resolver
.get_partial_res(bound_pred.bounded_ty.id)
.map(|d| (d.base_res(), d.unresolved_segments()))
{
Some((Res::Def(DefKind::TyParam, def_id), 0))
if bound_pred.bound_generic_params.is_empty() =>
{
generics
.params
.iter()
.find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
.is_some()
}
// Either the `bounded_ty` is not a plain type parameter, or
// it's not found in the generic type parameters list.
_ => false,
}
};
// We only need to compute this once per `WherePredicate`, but don't
// need to compute this at all unless there is a Maybe bound.
let mut is_param: Option<bool> = None;
for bound in &bound_pred.bounds {
if !matches!(*bound, GenericBound::Trait(_, TraitBoundModifier::Maybe)) {
continue;
}
let is_param = *is_param.get_or_insert_with(compute_is_param);
if !is_param {
self.diagnostic().span_err(
bound.span(),
"`?Trait` bounds are only permitted at the \
point where a type parameter is declared",
);
}
}
}

View File

@ -166,7 +166,7 @@ pub trait ResolverAstLowering {
fn legacy_const_generic_args(&mut self, expr: &Expr) -> Option<Vec<usize>>;
/// Obtains resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes>;
/// Obtains per-namespace resolutions for `use` statement with the given `NodeId`.
fn get_import_res(&mut self, id: NodeId) -> PerNS<Option<Res<NodeId>>>;

View File

@ -124,7 +124,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
ty::ReVar(vid) => {
// Find something that we can name
let upper_bound = self.approx_universal_upper_bound(vid);
self.definitions[upper_bound].external_name.unwrap_or(region)
let upper_bound = &self.definitions[upper_bound];
match upper_bound.external_name {
Some(reg) => reg,
None => {
// Nothing exact found, so we pick the first one that we find.
let scc = self.constraint_sccs.scc(vid);
for vid in self.rev_scc_graph.as_ref().unwrap().upper_bounds(scc) {
match self.definitions[vid].external_name {
None => {}
Some(&ty::ReStatic) => {}
Some(region) => return region,
}
}
region
}
}
}
_ => region,
})

View File

@ -342,7 +342,7 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
let source_info = data.terminator().source_info;
// We must assign the value first in case it gets declared dead below
data.statements.extend(self.make_state(state_idx, v, source_info));
let state = if let Some((resume, resume_arg)) = resume {
let state = if let Some((resume, mut resume_arg)) = resume {
// Yield
let state = 3 + self.suspension_points.len();
@ -350,7 +350,8 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
// live across a yield.
let resume_arg =
if let Some(&(ty, variant, idx)) = self.remap.get(&resume_arg.local) {
self.make_field(variant, idx, ty)
replace_base(&mut resume_arg, self.make_field(variant, idx, ty), self.tcx);
resume_arg
} else {
resume_arg
};

View File

@ -973,7 +973,15 @@ impl<'a> Resolver<'a> {
let import_suggestions =
self.lookup_import_candidates(ident, Namespace::MacroNS, parent_scope, is_expected);
show_candidates(err, None, &import_suggestions, false, true);
show_candidates(
&self.definitions,
self.session,
err,
None,
&import_suggestions,
false,
true,
);
if macro_kind == MacroKind::Derive && (ident.name == sym::Send || ident.name == sym::Sync) {
let msg = format!("unsafe traits like `{}` should be implemented explicitly", ident);
@ -1713,6 +1721,8 @@ fn find_span_immediately_after_crate_name(
/// entities with that name in all crates. This method allows outputting the
/// results of this search in a programmer-friendly way
crate fn show_candidates(
definitions: &rustc_hir::definitions::Definitions,
session: &Session,
err: &mut DiagnosticBuilder<'_>,
// This is `None` if all placement locations are inside expansions
use_placement_span: Option<Span>,
@ -1724,43 +1734,111 @@ crate fn show_candidates(
return;
}
let mut accessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new();
let mut inaccessible_path_strings: Vec<(String, &str, Option<DefId>)> = Vec::new();
candidates.iter().for_each(|c| {
(if c.accessible { &mut accessible_path_strings } else { &mut inaccessible_path_strings })
.push((path_names_to_string(&c.path), c.descr, c.did))
});
// we want consistent results across executions, but candidates are produced
// by iterating through a hash map, so make sure they are ordered:
let mut path_strings: Vec<_> =
candidates.iter().map(|c| path_names_to_string(&c.path)).collect();
for path_strings in [&mut accessible_path_strings, &mut inaccessible_path_strings] {
path_strings.sort_by(|a, b| a.0.cmp(&b.0));
let core_path_strings =
path_strings.drain_filter(|p| p.0.starts_with("core::")).collect::<Vec<_>>();
path_strings.extend(core_path_strings);
path_strings.dedup_by(|a, b| a.0 == b.0);
}
path_strings.sort();
let core_path_strings =
path_strings.drain_filter(|p| p.starts_with("core::")).collect::<Vec<String>>();
path_strings.extend(core_path_strings);
path_strings.dedup();
if !accessible_path_strings.is_empty() {
let (determiner, kind) = if accessible_path_strings.len() == 1 {
("this", accessible_path_strings[0].1)
} else {
("one of these", "items")
};
let (determiner, kind) = if candidates.len() == 1 {
("this", candidates[0].descr)
} else {
("one of these", "items")
};
let instead = if instead { " instead" } else { "" };
let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
let instead = if instead { " instead" } else { "" };
let mut msg = format!("consider importing {} {}{}", determiner, kind, instead);
if let Some(span) = use_placement_span {
for candidate in &mut accessible_path_strings {
// produce an additional newline to separate the new use statement
// from the directly following item.
let additional_newline = if found_use { "" } else { "\n" };
candidate.0 = format!("use {};\n{}", &candidate.0, additional_newline);
}
if let Some(span) = use_placement_span {
for candidate in &mut path_strings {
// produce an additional newline to separate the new use statement
// from the directly following item.
let additional_newline = if found_use { "" } else { "\n" };
*candidate = format!("use {};\n{}", candidate, additional_newline);
err.span_suggestions(
span,
&msg,
accessible_path_strings.into_iter().map(|a| a.0),
Applicability::Unspecified,
);
} else {
msg.push(':');
for candidate in accessible_path_strings {
msg.push('\n');
msg.push_str(&candidate.0);
}
err.note(&msg);
}
err.span_suggestions(span, &msg, path_strings.into_iter(), Applicability::Unspecified);
} else {
msg.push(':');
assert!(!inaccessible_path_strings.is_empty());
for candidate in path_strings {
msg.push('\n');
msg.push_str(&candidate);
if inaccessible_path_strings.len() == 1 {
let (name, descr, def_id) = &inaccessible_path_strings[0];
let msg = format!("{} `{}` exists but is inaccessible", descr, name);
if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
let span = definitions.def_span(local_def_id);
let span = session.source_map().guess_head_span(span);
let mut multi_span = MultiSpan::from_span(span);
multi_span.push_span_label(span, "not accessible".to_string());
err.span_note(multi_span, &msg);
} else {
err.note(&msg);
}
} else {
let (_, descr_first, _) = &inaccessible_path_strings[0];
let descr = if inaccessible_path_strings
.iter()
.skip(1)
.all(|(_, descr, _)| descr == descr_first)
{
format!("{}", descr_first)
} else {
"item".to_string()
};
let mut msg = format!("these {}s exist but are inaccessible", descr);
let mut has_colon = false;
let mut spans = Vec::new();
for (name, _, def_id) in &inaccessible_path_strings {
if let Some(local_def_id) = def_id.and_then(|did| did.as_local()) {
let span = definitions.def_span(local_def_id);
let span = session.source_map().guess_head_span(span);
spans.push((name, span));
} else {
if !has_colon {
msg.push(':');
has_colon = true;
}
msg.push('\n');
msg.push_str(name);
}
}
let mut multi_span = MultiSpan::from_spans(spans.iter().map(|(_, sp)| *sp).collect());
for (name, span) in spans {
multi_span.push_span_label(span, format!("`{}`: not accessible", name));
}
err.span_note(multi_span, &msg);
}
err.note(&msg);
}
}

View File

@ -1152,7 +1152,7 @@ impl ResolverAstLowering for Resolver<'_> {
self.legacy_const_generic_args(expr)
}
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
fn get_partial_res(&self, id: NodeId) -> Option<PartialRes> {
self.partial_res_map.get(&id).cloned()
}
@ -2969,7 +2969,15 @@ impl<'a> Resolver<'a> {
(None, false)
};
if !candidates.is_empty() {
diagnostics::show_candidates(&mut err, span, &candidates, instead, found_use);
diagnostics::show_candidates(
&self.definitions,
self.session,
&mut err,
span,
&candidates,
instead,
found_use,
);
} else if let Some((span, msg, sugg, appl)) = suggestion {
err.span_suggestion(span, msg, sugg, appl);
}

View File

@ -2137,7 +2137,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
idx_t
} else {
let base_t = self.structurally_resolved_type(base.span, base_t);
match self.lookup_indexing(expr, base, base_t, idx_t) {
match self.lookup_indexing(expr, base, base_t, idx, idx_t) {
Some((index_ty, element_ty)) => {
// two-phase not needed because index_ty is never mutable
self.demand_coerce(idx, idx_t, index_ty, None, AllowTwoPhase::No);

View File

@ -1,5 +1,7 @@
use crate::check::method::MethodCallee;
use crate::check::{has_expected_num_generic_args, FnCtxt, PlaceOp};
use rustc_ast as ast;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::InferOk;
@ -47,6 +49,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr: &hir::Expr<'_>,
base_expr: &'tcx hir::Expr<'tcx>,
base_ty: Ty<'tcx>,
index_expr: &'tcx hir::Expr<'tcx>,
idx_ty: Ty<'tcx>,
) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
// FIXME(#18741) -- this is almost but not quite the same as the
@ -56,12 +59,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let mut autoderef = self.autoderef(base_expr.span, base_ty);
let mut result = None;
while result.is_none() && autoderef.next().is_some() {
result = self.try_index_step(expr, base_expr, &autoderef, idx_ty);
result = self.try_index_step(expr, base_expr, &autoderef, idx_ty, index_expr);
}
self.register_predicates(autoderef.into_obligations());
result
}
fn negative_index(
&self,
ty: Ty<'tcx>,
span: Span,
base_expr: &hir::Expr<'_>,
) -> Option<(Ty<'tcx>, Ty<'tcx>)> {
let ty = self.resolve_vars_if_possible(ty);
let mut err = self.tcx.sess.struct_span_err(
span,
&format!("negative integers cannot be used to index on a `{}`", ty),
);
err.span_label(span, &format!("cannot use a negative integer for indexing on `{}`", ty));
if let (hir::ExprKind::Path(..), Ok(snippet)) =
(&base_expr.kind, self.tcx.sess.source_map().span_to_snippet(base_expr.span))
{
// `foo[-1]` to `foo[foo.len() - 1]`
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"to access an element starting from the end of the `{}`, compute the index",
ty,
),
format!("{}.len() ", snippet),
Applicability::MachineApplicable,
);
}
err.emit();
Some((self.tcx.ty_error(), self.tcx.ty_error()))
}
/// To type-check `base_expr[index_expr]`, we progressively autoderef
/// (and otherwise adjust) `base_expr`, looking for a type which either
/// supports builtin indexing or overloaded indexing.
@ -73,6 +106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
base_expr: &hir::Expr<'_>,
autoderef: &Autoderef<'a, 'tcx>,
index_ty: Ty<'tcx>,
index_expr: &hir::Expr<'_>,
) -> Option<(/*index type*/ Ty<'tcx>, /*element type*/ Ty<'tcx>)> {
let adjusted_ty =
self.structurally_resolved_type(autoderef.span(), autoderef.final_ty(false));
@ -82,6 +116,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr, base_expr, adjusted_ty, index_ty
);
if let hir::ExprKind::Unary(
hir::UnOp::Neg,
hir::Expr {
kind: hir::ExprKind::Lit(hir::Lit { node: ast::LitKind::Int(..), .. }),
..
},
) = index_expr.kind
{
match adjusted_ty.kind() {
ty::Adt(ty::AdtDef { did, .. }, _)
if self.tcx.is_diagnostic_item(sym::vec_type, *did) =>
{
return self.negative_index(adjusted_ty, index_expr.span, base_expr);
}
ty::Slice(_) | ty::Array(_, _) => {
return self.negative_index(adjusted_ty, index_expr.span, base_expr);
}
_ => {}
}
}
for unsize in [false, true] {
let mut self_ty = adjusted_ty;
if unsize {

@ -1 +1 @@
Subproject commit cba558df777a045b5657d56c29944e9e8fd3a776
Subproject commit 522c3e3d9c097b53ede7682cc28544b461597b20

View File

@ -1,8 +1,10 @@
// run-pass
// Test that box-statements with yields in them work.
#![feature(generators, box_syntax)]
#![feature(generators, box_syntax, generator_trait)]
use std::pin::Pin;
use std::ops::Generator;
use std::ops::GeneratorState;
fn main() {
let x = 0i32;
@ -15,4 +17,8 @@ fn main() {
_t => {}
}
};
let mut g = |_| box yield;
assert_eq!(Pin::new(&mut g).resume(1), GeneratorState::Yielded(()));
assert_eq!(Pin::new(&mut g).resume(2), GeneratorState::Complete(box 2));
}

View File

@ -1,5 +1,5 @@
warning: unused generator that must be used
--> $DIR/yield-in-box.rs:9:5
--> $DIR/yield-in-box.rs:11:5
|
LL | / || {
LL | | let y = 2u32;

View File

@ -4,7 +4,7 @@ error[E0425]: cannot find function `f` in this scope
LL | f();
| ^ not found in this scope
|
help: consider importing one of these items
help: consider importing this function
|
LL | use foo::f;
|
@ -37,7 +37,7 @@ LL | n!(f);
LL | n!(f);
| ^ not found in this scope
|
= note: consider importing one of these items:
= note: consider importing this function:
foo::f
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
@ -50,7 +50,7 @@ LL | n!(f);
LL | f
| ^ not found in this scope
|
= note: consider importing one of these items:
= note: consider importing this function:
foo::f
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)

View File

@ -4,7 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
| ^^^^^^^^^^^^^^^^^^
|
= note: hidden type `Ordinary<'_>` captures lifetime '_#9r
note: hidden type `Ordinary<'b>` captures the lifetime `'b` as defined on the function body at 16:21
--> $DIR/ordinary-bounds-unrelated.rs:16:21
|
LL | fn upper_bounds<'a, 'b, 'c, 'd, 'e>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'d, 'e>
| ^^
error: aborting due to previous error

View File

@ -4,7 +4,11 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appea
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
| ^^^^^^^^^^^^^^^^^^
|
= note: hidden type `Ordinary<'_>` captures lifetime '_#6r
note: hidden type `Ordinary<'b>` captures the lifetime `'b` as defined on the function body at 18:21
--> $DIR/ordinary-bounds-unsuited.rs:18:21
|
LL | fn upper_bounds<'a, 'b>(a: Ordinary<'a>, b: Ordinary<'b>) -> impl Trait<'a, 'b>
| ^^
error: aborting due to previous error

View File

@ -4,10 +4,11 @@ error[E0425]: cannot find function `fpriv` in this scope
LL | fpriv();
| ^^^^^ not found in this scope
|
help: consider importing this function
|
LL | use bar::fpriv;
note: function `bar::fpriv` exists but is inaccessible
--> $DIR/glob-resolve1.rs:7:5
|
LL | fn fpriv() {}
| ^^^^^^^^^^ not accessible
error[E0425]: cannot find function `epriv` in this scope
--> $DIR/glob-resolve1.rs:27:5
@ -15,10 +16,11 @@ error[E0425]: cannot find function `epriv` in this scope
LL | epriv();
| ^^^^^ not found in this scope
|
help: consider importing this function
|
LL | use bar::epriv;
note: function `bar::epriv` exists but is inaccessible
--> $DIR/glob-resolve1.rs:9:9
|
LL | fn epriv();
| ^^^^^^^^^^^ not accessible
error[E0423]: expected value, found enum `B`
--> $DIR/glob-resolve1.rs:28:5
@ -44,10 +46,11 @@ error[E0425]: cannot find value `C` in this scope
LL | C;
| ^ not found in this scope
|
help: consider importing this unit struct
|
LL | use bar::C;
note: unit struct `bar::C` exists but is inaccessible
--> $DIR/glob-resolve1.rs:18:5
|
LL | struct C;
| ^^^^^^^^^ not accessible
error[E0425]: cannot find function `import` in this scope
--> $DIR/glob-resolve1.rs:30:5
@ -67,16 +70,13 @@ LL | pub enum B {
| ---------- similarly named enum `B` defined here
...
LL | foo::<A>();
| ^
| ^ help: an enum with a similar name exists: `B`
|
help: an enum with a similar name exists
|
LL | foo::<B>();
| ~
help: consider importing this enum
|
LL | use bar::A;
note: enum `bar::A` exists but is inaccessible
--> $DIR/glob-resolve1.rs:11:5
|
LL | enum A {
| ^^^^^^ not accessible
error[E0412]: cannot find type `C` in this scope
--> $DIR/glob-resolve1.rs:33:11
@ -85,16 +85,13 @@ LL | pub enum B {
| ---------- similarly named enum `B` defined here
...
LL | foo::<C>();
| ^
| ^ help: an enum with a similar name exists: `B`
|
help: an enum with a similar name exists
|
LL | foo::<B>();
| ~
help: consider importing this struct
|
LL | use bar::C;
note: struct `bar::C` exists but is inaccessible
--> $DIR/glob-resolve1.rs:18:5
|
LL | struct C;
| ^^^^^^^^^ not accessible
error[E0412]: cannot find type `D` in this scope
--> $DIR/glob-resolve1.rs:34:11
@ -103,16 +100,13 @@ LL | pub enum B {
| ---------- similarly named enum `B` defined here
...
LL | foo::<D>();
| ^
| ^ help: an enum with a similar name exists: `B`
|
help: an enum with a similar name exists
|
LL | foo::<B>();
| ~
help: consider importing this type alias
|
LL | use bar::D;
note: type alias `bar::D` exists but is inaccessible
--> $DIR/glob-resolve1.rs:20:5
|
LL | type D = isize;
| ^^^^^^^^^^^^^^^ not accessible
error: aborting due to 8 previous errors

View File

@ -4,10 +4,11 @@ error[E0412]: cannot find type `Bar` in this scope
LL | fn sub() -> Bar { 1 }
| ^^^ not found in this scope
|
help: consider importing this type alias
|
LL | use a::b::Bar;
note: type alias `a::b::Bar` exists but is inaccessible
--> $DIR/issue-4366-2.rs:11:9
|
LL | type Bar = isize;
| ^^^^^^^^^^^^^^^^^ not accessible
error[E0423]: expected function, found module `foo`
--> $DIR/issue-4366-2.rs:25:5

View File

@ -1,32 +1,32 @@
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:1:23
--> $DIR/maybe-bounds-where.rs:1:28
|
LL | struct S1<T>(T) where (T): ?Sized;
| ^^^
| ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:4:23
--> $DIR/maybe-bounds-where.rs:4:27
|
LL | struct S2<T>(T) where u8: ?Sized;
| ^^
| ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:7:23
--> $DIR/maybe-bounds-where.rs:7:35
|
LL | struct S3<T>(T) where &'static T: ?Sized;
| ^^^^^^^^^^
| ^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:12:31
--> $DIR/maybe-bounds-where.rs:12:34
|
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
| ^
| ^^^^^^^^^^
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
--> $DIR/maybe-bounds-where.rs:21:18
--> $DIR/maybe-bounds-where.rs:21:21
|
LL | fn f() where T: ?Sized {}
| ^
| ^^^^^^
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
--> $DIR/maybe-bounds-where.rs:12:11

View File

@ -16,10 +16,11 @@ error[E0425]: cannot find function, tuple struct or tuple variant `Bx` in this s
LL | Bx(());
| ^^ not found in this scope
|
help: consider importing this tuple struct
|
LL | use foo::Bx;
note: tuple struct `foo::Bx` exists but is inaccessible
--> $DIR/issue-42944.rs:2:5
|
LL | pub struct Bx(());
| ^^^^^^^^^^^^^^^^^^ not accessible
error: aborting due to 2 previous errors

View File

@ -0,0 +1,38 @@
// Regression test for #88472, where a suggestion was issued to
// import an inaccessible struct.
#![warn(unused_imports)]
//~^ NOTE: the lint level is defined here
mod a {
struct Foo;
//~^ NOTE: struct `a::Foo` exists but is inaccessible
//~| NOTE: not accessible
}
mod b {
use crate::a::*;
//~^ WARNING: unused import
type Bar = Foo;
//~^ ERROR: cannot find type `Foo` in this scope [E0412]
//~| NOTE: not found in this scope
}
mod c {
enum Eee {}
//~^ NOTE: these enums exist but are inaccessible
//~| NOTE: `c::Eee`: not accessible
mod d {
enum Eee {}
//~^ NOTE: `c::d::Eee`: not accessible
}
}
mod e {
type Baz = Eee;
//~^ ERROR: cannot find type `Eee` in this scope [E0412]
//~| NOTE: not found in this scope
}
fn main() {}

View File

@ -0,0 +1,42 @@
error[E0412]: cannot find type `Foo` in this scope
--> $DIR/issue-88472.rs:16:16
|
LL | type Bar = Foo;
| ^^^ not found in this scope
|
note: struct `a::Foo` exists but is inaccessible
--> $DIR/issue-88472.rs:8:5
|
LL | struct Foo;
| ^^^^^^^^^^^ not accessible
error[E0412]: cannot find type `Eee` in this scope
--> $DIR/issue-88472.rs:33:16
|
LL | type Baz = Eee;
| ^^^ not found in this scope
|
note: these enums exist but are inaccessible
--> $DIR/issue-88472.rs:22:5
|
LL | enum Eee {}
| ^^^^^^^^ `c::Eee`: not accessible
...
LL | enum Eee {}
| ^^^^^^^^ `c::d::Eee`: not accessible
warning: unused import: `crate::a::*`
--> $DIR/issue-88472.rs:14:9
|
LL | use crate::a::*;
| ^^^^^^^^^^^
|
note: the lint level is defined here
--> $DIR/issue-88472.rs:4:9
|
LL | #![warn(unused_imports)]
| ^^^^^^^^^^^^^^
error: aborting due to 2 previous errors; 1 warning emitted
For more information about this error, try `rustc --explain E0412`.

View File

@ -169,16 +169,13 @@ LL | pub enum E {
| ---------- similarly named enum `E` defined here
...
LL | let _: Z = m::n::Z;
| ^
| ^ help: an enum with a similar name exists: `E`
|
help: an enum with a similar name exists
|
LL | let _: E = m::n::Z;
| ~
help: consider importing this enum
|
LL | use m::Z;
note: enum `m::Z` exists but is inaccessible
--> $DIR/privacy-enum-ctor.rs:11:9
|
LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible
error[E0423]: expected value, found enum `m::n::Z`
--> $DIR/privacy-enum-ctor.rs:57:16
@ -215,16 +212,13 @@ LL | pub enum E {
| ---------- similarly named enum `E` defined here
...
LL | let _: Z = m::n::Z::Fn;
| ^
| ^ help: an enum with a similar name exists: `E`
|
help: an enum with a similar name exists
|
LL | let _: E = m::n::Z::Fn;
| ~
help: consider importing this enum
|
LL | use m::Z;
note: enum `m::Z` exists but is inaccessible
--> $DIR/privacy-enum-ctor.rs:11:9
|
LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:64:12
@ -233,16 +227,13 @@ LL | pub enum E {
| ---------- similarly named enum `E` defined here
...
LL | let _: Z = m::n::Z::Struct;
| ^
| ^ help: an enum with a similar name exists: `E`
|
help: an enum with a similar name exists
|
LL | let _: E = m::n::Z::Struct;
| ~
help: consider importing this enum
|
LL | use m::Z;
note: enum `m::Z` exists but is inaccessible
--> $DIR/privacy-enum-ctor.rs:11:9
|
LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
--> $DIR/privacy-enum-ctor.rs:64:16
@ -262,16 +253,13 @@ LL | pub enum E {
| ---------- similarly named enum `E` defined here
...
LL | let _: Z = m::n::Z::Unit {};
| ^
| ^ help: an enum with a similar name exists: `E`
|
help: an enum with a similar name exists
|
LL | let _: E = m::n::Z::Unit {};
| ~
help: consider importing this enum
|
LL | use m::Z;
note: enum `m::Z` exists but is inaccessible
--> $DIR/privacy-enum-ctor.rs:11:9
|
LL | pub(in m) enum Z {
| ^^^^^^^^^^^^^^^^ not accessible
error[E0603]: enum `Z` is private
--> $DIR/privacy-enum-ctor.rs:57:22

View File

@ -33,10 +33,11 @@ error[E0423]: expected value, found struct `xcrate::S`
LL | xcrate::S;
| ^^^^^^^^^ constructor is not visible here due to private fields
|
help: consider importing this tuple struct instead
|
LL | use m::S;
note: tuple struct `m::S` exists but is inaccessible
--> $DIR/privacy-struct-ctor.rs:6:5
|
LL | pub struct S(u8);
| ^^^^^^^^^^^^^^^^^ not accessible
error[E0603]: tuple struct constructor `Z` is private
--> $DIR/privacy-struct-ctor.rs:18:12

View File

@ -66,10 +66,11 @@ error[E0531]: cannot find unit struct, unit variant or constant `Self` in this s
LL | mut Self => (),
| ^^^^ not found in this scope
|
help: consider importing this unit struct
|
LL | use foo::Self;
note: unit struct `foo::Self` exists but is inaccessible
--> $DIR/self_type_keyword.rs:2:3
|
LL | struct Self;
| ^^^^^^^^^^^^ not accessible
error[E0392]: parameter `'Self` is never used
--> $DIR/self_type_keyword.rs:6:12

View File

@ -0,0 +1,22 @@
// run-rustfix
use std::ops::Index;
struct X;
impl Index<i32> for X {
type Output = ();
fn index(&self, _: i32) -> &() {
&()
}
}
fn main() {
let x = vec![1, 2, 3];
x[x.len() -1]; //~ ERROR negative integers cannot be used to index on a
let x = [1, 2, 3];
x[x.len() -1]; //~ ERROR negative integers cannot be used to index on a
let x = &[1, 2, 3];
x[x.len() -1]; //~ ERROR negative integers cannot be used to index on a
let _ = x;
X[-1];
}

View File

@ -0,0 +1,22 @@
// run-rustfix
use std::ops::Index;
struct X;
impl Index<i32> for X {
type Output = ();
fn index(&self, _: i32) -> &() {
&()
}
}
fn main() {
let x = vec![1, 2, 3];
x[-1]; //~ ERROR negative integers cannot be used to index on a
let x = [1, 2, 3];
x[-1]; //~ ERROR negative integers cannot be used to index on a
let x = &[1, 2, 3];
x[-1]; //~ ERROR negative integers cannot be used to index on a
let _ = x;
X[-1];
}

View File

@ -0,0 +1,35 @@
error: negative integers cannot be used to index on a `Vec<{integer}>`
--> $DIR/negative-literal-index.rs:15:7
|
LL | x[-1];
| ^^ cannot use a negative integer for indexing on `Vec<{integer}>`
|
help: to access an element starting from the end of the `Vec<{integer}>`, compute the index
|
LL | x[x.len() -1];
| +++++++
error: negative integers cannot be used to index on a `[{integer}; 3]`
--> $DIR/negative-literal-index.rs:17:7
|
LL | x[-1];
| ^^ cannot use a negative integer for indexing on `[{integer}; 3]`
|
help: to access an element starting from the end of the `[{integer}; 3]`, compute the index
|
LL | x[x.len() -1];
| +++++++
error: negative integers cannot be used to index on a `[{integer}; 3]`
--> $DIR/negative-literal-index.rs:19:7
|
LL | x[-1];
| ^^ cannot use a negative integer for indexing on `[{integer}; 3]`
|
help: to access an element starting from the end of the `[{integer}; 3]`, compute the index
|
LL | x[x.len() -1];
| +++++++
error: aborting due to 3 previous errors

View File

@ -0,0 +1,60 @@
// This is the auxiliary crate for the regression test for issue #89119, minimized
// from `zvariant-2.8.0`.
use std::convert::TryFrom;
use std::borrow::Cow;
pub struct Str<'a>(Cow<'a, str>);
impl<'a> Str<'a> {
pub fn to_owned(&self) -> Str<'static> {
todo!()
}
}
pub enum Value<'a> {
Str(Str<'a>),
Value(Box<Value<'a>>),
}
impl<'a> Value<'a> {
pub fn to_owned(&self) -> Value<'static> {
match self {
Value::Str(v) => Value::Str(v.to_owned()),
Value::Value(v) => {
let o = OwnedValue::from(&**v);
Value::Value(Box::new(o.into_inner()))
}
}
}
}
struct OwnedValue(Value<'static>);
impl OwnedValue {
pub(crate) fn into_inner(self) -> Value<'static> {
todo!()
}
}
impl<'a, T> TryFrom<OwnedValue> for Vec<T>
where
T: TryFrom<Value<'a>, Error = ()>,
{
type Error = ();
fn try_from(_: OwnedValue) -> Result<Self, Self::Error> {
todo!()
}
}
impl TryFrom<OwnedValue> for Vec<OwnedValue> {
type Error = ();
fn try_from(_: OwnedValue) -> Result<Self, Self::Error> {
todo!()
}
}
impl<'a> From<Value<'a>> for OwnedValue {
fn from(_: Value<'a>) -> Self {
todo!()
}
}
impl<'a> From<&Value<'a>> for OwnedValue {
fn from(_: &Value<'a>) -> Self {
todo!()
}
}

View File

@ -0,0 +1,11 @@
// This is a regression test for issue #89119: an issue in intercrate mode caching.
//
// It requires multiple crates, of course, but the bug is triggered by the code in the dependency,
// not the main crate. This is why this file is empty.
//
// The auxiliary crate used in the test contains the code minimized from `zvariant-2.8.0`.
// check-pass
// aux-build: issue_89119_intercrate_caching.rs
fn main() {}