mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #117172 - matthiaskrgr:rollup-s56bm2f, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #116801 (Add test for 113326) - #117133 (Merge `impl_wf_inference` (`check_mod_impl_wf`) check into coherence checking) - #117136 (Intern `LocalDefId` list from `opaque_types_defined_by` query) - #117150 (Update cargo) - #117158 (Update THIR unused_unsafe lint) - #117160 (Fix typo in test comment) - #117168 (Fix some coroutine sentences that don't make sense anymore.) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
cf226e93dc
@ -181,14 +181,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
})?;
|
||||
}
|
||||
|
||||
tcx.sess.track_errors(|| {
|
||||
tcx.sess.time("impl_wf_inference", || {
|
||||
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module))
|
||||
});
|
||||
})?;
|
||||
|
||||
tcx.sess.track_errors(|| {
|
||||
tcx.sess.time("coherence_checking", || {
|
||||
// Check impls constrain their parameters
|
||||
tcx.hir().for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
|
||||
|
||||
for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
|
||||
tcx.ensure().coherent_trait(trait_def_id);
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ rustc_queries! {
|
||||
|
||||
query opaque_types_defined_by(
|
||||
key: LocalDefId
|
||||
) -> &'tcx [LocalDefId] {
|
||||
) -> &'tcx ty::List<LocalDefId> {
|
||||
desc {
|
||||
|tcx| "computing the opaque types defined by `{}`",
|
||||
tcx.def_path_str(key.to_def_id())
|
||||
|
@ -161,6 +161,7 @@ pub struct CtxtInterners<'tcx> {
|
||||
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
|
||||
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
|
||||
fields: InternedSet<'tcx, List<FieldIdx>>,
|
||||
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
|
||||
}
|
||||
|
||||
impl<'tcx> CtxtInterners<'tcx> {
|
||||
@ -186,6 +187,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||
external_constraints: Default::default(),
|
||||
predefined_opaques_in_body: Default::default(),
|
||||
fields: Default::default(),
|
||||
local_def_ids: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1572,6 +1574,7 @@ slice_interners!(
|
||||
place_elems: pub mk_place_elems(PlaceElem<'tcx>),
|
||||
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
|
||||
fields: pub mk_fields(FieldIdx),
|
||||
local_def_ids: intern_local_def_ids(LocalDefId),
|
||||
);
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
@ -1801,6 +1804,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
self.intern_clauses(clauses)
|
||||
}
|
||||
|
||||
pub fn mk_local_def_ids(self, clauses: &[LocalDefId]) -> &'tcx List<LocalDefId> {
|
||||
// FIXME consider asking the input slice to be sorted to avoid
|
||||
// re-interning permutations, in which case that would be asserted
|
||||
// here.
|
||||
self.intern_local_def_ids(clauses)
|
||||
}
|
||||
|
||||
pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
@ -379,6 +379,5 @@ mir_build_unused_unsafe = unnecessary `unsafe` block
|
||||
.label = unnecessary `unsafe` block
|
||||
|
||||
mir_build_unused_unsafe_enclosing_block_label = because it's nested under this `unsafe` block
|
||||
mir_build_unused_unsafe_enclosing_fn_label = because it's nested under this `unsafe` fn
|
||||
|
||||
mir_build_variant_defined_here = not covered
|
||||
|
@ -13,6 +13,7 @@ use rustc_span::def_id::{DefId, LocalDefId};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_span::Span;
|
||||
|
||||
use std::mem;
|
||||
use std::ops::Bound;
|
||||
|
||||
struct UnsafetyVisitor<'a, 'tcx> {
|
||||
@ -24,7 +25,6 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
||||
/// The current "safety context". This notably tracks whether we are in an
|
||||
/// `unsafe` block, and whether it has been used.
|
||||
safety_context: SafetyContext,
|
||||
body_unsafety: BodyUnsafety,
|
||||
/// The `#[target_feature]` attributes of the body. Used for checking
|
||||
/// calls to functions with `#[target_feature]` (RFC 2396).
|
||||
body_target_features: &'tcx [Symbol],
|
||||
@ -34,43 +34,50 @@ struct UnsafetyVisitor<'a, 'tcx> {
|
||||
in_union_destructure: bool,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
inside_adt: bool,
|
||||
warnings: &'a mut Vec<UnusedUnsafeWarning>,
|
||||
}
|
||||
|
||||
impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
fn in_safety_context(&mut self, safety_context: SafetyContext, f: impl FnOnce(&mut Self)) {
|
||||
if let (
|
||||
SafetyContext::UnsafeBlock { span: enclosing_span, .. },
|
||||
SafetyContext::UnsafeBlock { span: block_span, hir_id, .. },
|
||||
) = (self.safety_context, safety_context)
|
||||
let prev_context = mem::replace(&mut self.safety_context, safety_context);
|
||||
|
||||
f(self);
|
||||
|
||||
let safety_context = mem::replace(&mut self.safety_context, prev_context);
|
||||
if let SafetyContext::UnsafeBlock { used, span, hir_id, nested_used_blocks } =
|
||||
safety_context
|
||||
{
|
||||
self.warn_unused_unsafe(
|
||||
hir_id,
|
||||
block_span,
|
||||
Some(UnusedUnsafeEnclosing::Block {
|
||||
span: self.tcx.sess.source_map().guess_head_span(enclosing_span),
|
||||
}),
|
||||
);
|
||||
f(self);
|
||||
} else {
|
||||
let prev_context = self.safety_context;
|
||||
self.safety_context = safety_context;
|
||||
if !used {
|
||||
self.warn_unused_unsafe(hir_id, span, None);
|
||||
|
||||
f(self);
|
||||
if let SafetyContext::UnsafeBlock {
|
||||
nested_used_blocks: ref mut prev_nested_used_blocks,
|
||||
..
|
||||
} = self.safety_context
|
||||
{
|
||||
prev_nested_used_blocks.extend(nested_used_blocks);
|
||||
}
|
||||
} else {
|
||||
for block in nested_used_blocks {
|
||||
self.warn_unused_unsafe(
|
||||
block.hir_id,
|
||||
block.span,
|
||||
Some(UnusedUnsafeEnclosing::Block {
|
||||
span: self.tcx.sess.source_map().guess_head_span(span),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
if let SafetyContext::UnsafeBlock { used: false, span, hir_id } = self.safety_context {
|
||||
self.warn_unused_unsafe(
|
||||
hir_id,
|
||||
span,
|
||||
if self.unsafe_op_in_unsafe_fn_allowed() {
|
||||
self.body_unsafety
|
||||
.unsafe_fn_sig_span()
|
||||
.map(|span| UnusedUnsafeEnclosing::Function { span })
|
||||
} else {
|
||||
None
|
||||
},
|
||||
);
|
||||
match self.safety_context {
|
||||
SafetyContext::UnsafeBlock {
|
||||
nested_used_blocks: ref mut prev_nested_used_blocks,
|
||||
..
|
||||
} => {
|
||||
prev_nested_used_blocks.push(NestedUsedBlock { hir_id, span });
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
self.safety_context = prev_context;
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,18 +109,12 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
}
|
||||
|
||||
fn warn_unused_unsafe(
|
||||
&self,
|
||||
&mut self,
|
||||
hir_id: hir::HirId,
|
||||
block_span: Span,
|
||||
enclosing_unsafe: Option<UnusedUnsafeEnclosing>,
|
||||
) {
|
||||
let block_span = self.tcx.sess.source_map().guess_head_span(block_span);
|
||||
self.tcx.emit_spanned_lint(
|
||||
UNUSED_UNSAFE,
|
||||
hir_id,
|
||||
block_span,
|
||||
UnusedUnsafe { span: block_span, enclosing: enclosing_unsafe },
|
||||
);
|
||||
self.warnings.push(UnusedUnsafeWarning { hir_id, block_span, enclosing_unsafe });
|
||||
}
|
||||
|
||||
/// Whether the `unsafe_op_in_unsafe_fn` lint is `allow`ed at the current HIR node.
|
||||
@ -128,7 +129,14 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
||||
self.tcx.ensure_with_value().mir_built(def);
|
||||
let inner_thir = &inner_thir.steal();
|
||||
let hir_context = self.tcx.hir().local_def_id_to_hir_id(def);
|
||||
let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
|
||||
let safety_context = mem::replace(&mut self.safety_context, SafetyContext::Safe);
|
||||
let mut inner_visitor = UnsafetyVisitor {
|
||||
thir: inner_thir,
|
||||
hir_context,
|
||||
safety_context,
|
||||
warnings: self.warnings,
|
||||
..*self
|
||||
};
|
||||
inner_visitor.visit_expr(&inner_thir[expr]);
|
||||
// Unsafe blocks can be used in the inner body, make sure to take it into account
|
||||
self.safety_context = inner_visitor.safety_context;
|
||||
@ -195,8 +203,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
BlockSafety::ExplicitUnsafe(hir_id) => {
|
||||
let used =
|
||||
matches!(self.tcx.lint_level_at_node(UNUSED_UNSAFE, hir_id), (Level::Allow, _));
|
||||
self.in_safety_context(
|
||||
SafetyContext::UnsafeBlock { span: block.span, hir_id, used: false },
|
||||
SafetyContext::UnsafeBlock {
|
||||
span: block.span,
|
||||
hir_id,
|
||||
used,
|
||||
nested_used_blocks: Vec::new(),
|
||||
},
|
||||
|this| visit::walk_block(this, block),
|
||||
);
|
||||
}
|
||||
@ -481,36 +496,29 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone)]
|
||||
enum SafetyContext {
|
||||
Safe,
|
||||
BuiltinUnsafeBlock,
|
||||
UnsafeFn,
|
||||
UnsafeBlock { span: Span, hir_id: hir::HirId, used: bool },
|
||||
UnsafeBlock {
|
||||
span: Span,
|
||||
hir_id: hir::HirId,
|
||||
used: bool,
|
||||
nested_used_blocks: Vec<NestedUsedBlock>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum BodyUnsafety {
|
||||
/// The body is not unsafe.
|
||||
Safe,
|
||||
/// The body is an unsafe function. The span points to
|
||||
/// the signature of the function.
|
||||
Unsafe(Span),
|
||||
struct NestedUsedBlock {
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
}
|
||||
|
||||
impl BodyUnsafety {
|
||||
/// Returns whether the body is unsafe.
|
||||
fn is_unsafe(&self) -> bool {
|
||||
matches!(self, BodyUnsafety::Unsafe(_))
|
||||
}
|
||||
|
||||
/// If the body is unsafe, returns the `Span` of its signature.
|
||||
fn unsafe_fn_sig_span(self) -> Option<Span> {
|
||||
match self {
|
||||
BodyUnsafety::Unsafe(span) => Some(span),
|
||||
BodyUnsafety::Safe => None,
|
||||
}
|
||||
}
|
||||
struct UnusedUnsafeWarning {
|
||||
hir_id: hir::HirId,
|
||||
block_span: Span,
|
||||
enclosing_unsafe: Option<UnusedUnsafeEnclosing>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
@ -803,27 +811,37 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
|
||||
}
|
||||
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
let body_unsafety = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(BodyUnsafety::Safe, |fn_sig| {
|
||||
let safety_context = tcx.hir().fn_sig_by_hir_id(hir_id).map_or(SafetyContext::Safe, |fn_sig| {
|
||||
if fn_sig.header.unsafety == hir::Unsafety::Unsafe {
|
||||
BodyUnsafety::Unsafe(fn_sig.span)
|
||||
SafetyContext::UnsafeFn
|
||||
} else {
|
||||
BodyUnsafety::Safe
|
||||
SafetyContext::Safe
|
||||
}
|
||||
});
|
||||
let body_target_features = &tcx.body_codegen_attrs(def.to_def_id()).target_features;
|
||||
let safety_context =
|
||||
if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
|
||||
let mut warnings = Vec::new();
|
||||
let mut visitor = UnsafetyVisitor {
|
||||
tcx,
|
||||
thir,
|
||||
safety_context,
|
||||
hir_context: hir_id,
|
||||
body_unsafety,
|
||||
body_target_features,
|
||||
assignment_info: None,
|
||||
in_union_destructure: false,
|
||||
param_env: tcx.param_env(def),
|
||||
inside_adt: false,
|
||||
warnings: &mut warnings,
|
||||
};
|
||||
visitor.visit_expr(&thir[expr]);
|
||||
|
||||
warnings.sort_by_key(|w| w.block_span);
|
||||
for UnusedUnsafeWarning { hir_id, block_span, enclosing_unsafe } in warnings {
|
||||
let block_span = tcx.sess.source_map().guess_head_span(block_span);
|
||||
tcx.emit_spanned_lint(
|
||||
UNUSED_UNSAFE,
|
||||
hir_id,
|
||||
block_span,
|
||||
UnusedUnsafe { span: block_span, enclosing: enclosing_unsafe },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -392,11 +392,6 @@ pub enum UnusedUnsafeEnclosing {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[label(mir_build_unused_unsafe_enclosing_fn_label)]
|
||||
Function {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
|
||||
|
@ -20,7 +20,7 @@ mod build;
|
||||
mod check_unsafety;
|
||||
mod errors;
|
||||
pub mod lints;
|
||||
pub mod thir;
|
||||
mod thir;
|
||||
|
||||
use rustc_middle::query::Providers;
|
||||
|
||||
|
@ -264,7 +264,10 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] {
|
||||
fn opaque_types_defined_by<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item: LocalDefId,
|
||||
) -> &'tcx ty::List<LocalDefId> {
|
||||
let kind = tcx.def_kind(item);
|
||||
trace!(?kind);
|
||||
let mut collector = OpaqueTypeCollector::new(tcx, item);
|
||||
@ -306,7 +309,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
|
||||
collector.opaques.extend(tcx.opaque_types_defined_by(tcx.local_parent(item)));
|
||||
}
|
||||
}
|
||||
tcx.arena.alloc_from_iter(collector.opaques)
|
||||
tcx.mk_local_def_ids(&collector.opaques)
|
||||
}
|
||||
|
||||
pub(super) fn provide(providers: &mut Providers) {
|
||||
|
@ -29,7 +29,7 @@ pub enum CoroutineState<Y, R> {
|
||||
|
||||
/// The trait implemented by builtin coroutine types.
|
||||
///
|
||||
/// Coroutines, also commonly referred to as coroutines, are currently an
|
||||
/// Coroutines are currently an
|
||||
/// experimental language feature in Rust. Added in [RFC 2033] coroutines are
|
||||
/// currently intended to primarily provide a building block for async/await
|
||||
/// syntax but will likely extend to also providing an ergonomic definition for
|
||||
|
@ -18,7 +18,7 @@ Coroutines are an extra-unstable feature in the compiler right now. Added in
|
||||
[RFC 2033] they're mostly intended right now as a information/constraint
|
||||
gathering phase. The intent is that experimentation can happen on the nightly
|
||||
compiler before actual stabilization. A further RFC will be required to
|
||||
stabilize coroutines/coroutines and will likely contain at least a few small
|
||||
stabilize coroutines and will likely contain at least a few small
|
||||
tweaks to the overall design.
|
||||
|
||||
[RFC 2033]: https://github.com/rust-lang/rfcs/pull/2033
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d2f6a048529eb8e9ebc55d793abd63456c98fac2
|
||||
Subproject commit df3509237935f9418351b77803df7bc05c009b3d
|
26
tests/ui/async-await/in-trait/coherence-constrained.rs
Normal file
26
tests/ui/async-await/in-trait/coherence-constrained.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// edition: 2021
|
||||
|
||||
trait Foo {
|
||||
type T;
|
||||
|
||||
async fn foo(&self) -> Self::T;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
type T = ();
|
||||
|
||||
async fn foo(&self) {}
|
||||
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
|
||||
}
|
||||
|
||||
impl Foo for Bar {
|
||||
//~^ ERROR conflicting implementations of trait `Foo` for type `Bar`
|
||||
type T = ();
|
||||
|
||||
async fn foo(&self) {}
|
||||
//~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
|
||||
}
|
||||
|
||||
fn main() {}
|
25
tests/ui/async-await/in-trait/coherence-constrained.stderr
Normal file
25
tests/ui/async-await/in-trait/coherence-constrained.stderr
Normal file
@ -0,0 +1,25 @@
|
||||
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
|
||||
--> $DIR/coherence-constrained.rs:14:5
|
||||
|
|
||||
LL | async fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
|
||||
|
||||
error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
|
||||
--> $DIR/coherence-constrained.rs:22:5
|
||||
|
|
||||
LL | async fn foo(&self) {}
|
||||
| ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Foo` for type `Bar`
|
||||
--> $DIR/coherence-constrained.rs:18:1
|
||||
|
|
||||
LL | impl Foo for Bar {
|
||||
| ---------------- first implementation here
|
||||
...
|
||||
LL | impl Foo for Bar {
|
||||
| ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0119, E0284.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
@ -1,5 +1,5 @@
|
||||
// revisions: min
|
||||
// we use a single revision because t his shoudl have a `full` revision
|
||||
// we use a single revision because this should have a `full` revision
|
||||
// but right now that ICEs and I(@BoxyUwU) could not get stderr normalization to work
|
||||
|
||||
#![cfg_attr(full, feature(generic_const_exprs))]
|
||||
|
@ -1,3 +1,5 @@
|
||||
//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized
|
||||
|
||||
trait Foo<A> {
|
||||
fn get(&self, A: &A) { }
|
||||
}
|
||||
@ -23,8 +25,7 @@ impl<T:Bar<Out=U>,U> Foo<T> for [isize;3] {
|
||||
}
|
||||
|
||||
impl<T,U> Foo<T> for U {
|
||||
// OK, T, U are used everywhere. Note that the coherence check
|
||||
// hasn't executed yet, so no errors about overlap.
|
||||
//~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
|
||||
}
|
||||
|
||||
impl<T,U> Bar for T {
|
||||
|
@ -1,33 +1,56 @@
|
||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/impl-unused-tps.rs:13:8
|
||||
--> $DIR/impl-unused-tps.rs:15:8
|
||||
|
|
||||
LL | impl<T,U> Foo<T> for [isize;1] {
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/impl-unused-tps.rs:30:8
|
||||
--> $DIR/impl-unused-tps.rs:31:8
|
||||
|
|
||||
LL | impl<T,U> Bar for T {
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/impl-unused-tps.rs:38:8
|
||||
--> $DIR/impl-unused-tps.rs:39:8
|
||||
|
|
||||
LL | impl<T,U> Bar for T
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/impl-unused-tps.rs:46:8
|
||||
--> $DIR/impl-unused-tps.rs:47:8
|
||||
|
|
||||
LL | impl<T,U,V> Foo<T> for T
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/impl-unused-tps.rs:46:10
|
||||
--> $DIR/impl-unused-tps.rs:47:10
|
||||
|
|
||||
LL | impl<T,U,V> Foo<T> for T
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
|
||||
--> $DIR/impl-unused-tps.rs:27:1
|
||||
|
|
||||
LL | impl<T> Foo<T> for [isize;0] {
|
||||
| ---------------------------- first implementation here
|
||||
...
|
||||
LL | impl<T,U> Foo<T> for U {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
|
||||
|
||||
For more information about this error, try `rustc --explain E0207`.
|
||||
error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized`
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`)
|
||||
note: required for `([isize; 0], _)` to implement `Bar`
|
||||
--> $DIR/impl-unused-tps.rs:31:11
|
||||
|
|
||||
LL | impl<T,U> Bar for T {
|
||||
| - ^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 126 redundant requirements hidden
|
||||
= note: required for `([isize; 0], _)` to implement `Bar`
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0119, E0207, E0275.
|
||||
For more information about an error, try `rustc --explain E0119`.
|
||||
|
@ -1,9 +1,6 @@
|
||||
warning: unnecessary `unsafe` block
|
||||
--> $DIR/expr-unsafe.rs:12:13
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
...
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
|
@ -1,9 +1,6 @@
|
||||
warning: unnecessary `unsafe` block
|
||||
--> $DIR/pat-unsafe.rs:19:17
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
...
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
@ -16,9 +13,6 @@ LL | #![warn(unused_unsafe)]
|
||||
warning: unnecessary `unsafe` block
|
||||
--> $DIR/pat-unsafe.rs:26:17
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
...
|
||||
LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
// FIXME: This file is tracking old lint behavior that's still unchanged in the
|
||||
// unstable -Zthir-unsafeck implementation. See lint-unused-unsafe.rs for more details.
|
||||
//
|
||||
// Exercise the unused_unsafe attribute in some positive and negative cases
|
||||
|
||||
// compile-flags: -Zthir-unsafeck
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![deny(unused_unsafe)]
|
||||
|
||||
|
||||
mod foo {
|
||||
extern "C" {
|
||||
pub fn bar();
|
||||
}
|
||||
}
|
||||
|
||||
fn callback<T, F>(_f: F) -> T where F: FnOnce() -> T { panic!() }
|
||||
unsafe fn unsf() {}
|
||||
|
||||
fn bad1() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
|
||||
fn bad2() { unsafe { bad1() } } //~ ERROR: unnecessary `unsafe` block
|
||||
unsafe fn bad3() { unsafe {} } //~ ERROR: unnecessary `unsafe` block
|
||||
fn bad4() { unsafe { callback(||{}) } } //~ ERROR: unnecessary `unsafe` block
|
||||
unsafe fn bad5() { unsafe { unsf() } }
|
||||
fn bad6() {
|
||||
unsafe { // don't put the warning here
|
||||
unsafe { //~ ERROR: unnecessary `unsafe` block
|
||||
unsf()
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe fn bad7() {
|
||||
unsafe {
|
||||
unsafe { //~ ERROR: unnecessary `unsafe` block
|
||||
unsf()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn good0() { unsf() }
|
||||
fn good1() { unsafe { unsf() } }
|
||||
fn good2() {
|
||||
/* bug uncovered when implementing warning about unused unsafe blocks. Be
|
||||
sure that when purity is inherited that the source of the unsafe-ness
|
||||
is tracked correctly */
|
||||
unsafe {
|
||||
unsafe fn what() -> Vec<String> { panic!() }
|
||||
|
||||
callback(|| {
|
||||
what();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn good3() { foo::bar() }
|
||||
fn good4() { unsafe { foo::bar() } }
|
||||
|
||||
#[allow(unused_unsafe)] fn allowed() { unsafe {} }
|
||||
|
||||
fn main() {}
|
@ -1,50 +0,0 @@
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:21:13
|
||||
|
|
||||
LL | fn bad1() { unsafe {} }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:9:9
|
||||
|
|
||||
LL | #![deny(unused_unsafe)]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:22:13
|
||||
|
|
||||
LL | fn bad2() { unsafe { bad1() } }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:23:20
|
||||
|
|
||||
LL | unsafe fn bad3() { unsafe {} }
|
||||
| ---------------- ^^^^^^ unnecessary `unsafe` block
|
||||
| |
|
||||
| because it's nested under this `unsafe` fn
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:24:13
|
||||
|
|
||||
LL | fn bad4() { unsafe { callback(||{}) } }
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:28:9
|
||||
|
|
||||
LL | unsafe { // don't put the warning here
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
LL | unsafe {
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/lint-unused-unsafe-thir.rs:35:9
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
LL | unsafe {
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -3,12 +3,8 @@
|
||||
|
||||
// edition:2018
|
||||
|
||||
// revisions: mir
|
||||
|
||||
// FIXME: Adapt -Zthir-unsafeck to behave the same as the mir version after #93678,
|
||||
// then delete lint-unused-unsafe-thir.rs, and go back to using the settings below
|
||||
// // revisions: mir thir
|
||||
// // [thir]compile-flags: -Zthir-unsafeck
|
||||
// revisions: mir thir
|
||||
// [thir]compile-flags: -Zthir-unsafeck
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![deny(unused_unsafe)]
|
||||
|
1402
tests/ui/span/lint-unused-unsafe.thir.stderr
Normal file
1402
tests/ui/span/lint-unused-unsafe.thir.stderr
Normal file
File diff suppressed because it is too large
Load Diff
17
tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
Normal file
17
tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// test for #113326
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
pub type Diff = impl Fn(usize) -> usize;
|
||||
|
||||
pub fn lift() -> Diff {
|
||||
|_: usize |loop {}
|
||||
}
|
||||
|
||||
pub fn add(
|
||||
n: Diff,
|
||||
m: Diff,
|
||||
) -> Diff {
|
||||
move |x: usize| m(n(x)) //~ ERROR: concrete type differs
|
||||
}
|
||||
|
||||
fn main() {}
|
14
tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
Normal file
14
tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: concrete type differs from previous defining opaque type use
|
||||
--> $DIR/recursive-fn-tait.rs:14:5
|
||||
|
|
||||
LL | move |x: usize| m(n(x))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:7:5: 7:16}`, got `{closure@$DIR/recursive-fn-tait.rs:14:5: 14:20}`
|
||||
|
|
||||
note: previous use here
|
||||
--> $DIR/recursive-fn-tait.rs:7:5
|
||||
|
|
||||
LL | |_: usize |loop {}
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -16,9 +16,9 @@ LL | #[deny(unused_unsafe)]
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/issue-45107-unnecessary-unsafe-in-closure.rs:12:38
|
||||
|
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
...
|
||||
LL | unsafe {
|
||||
| ------ because it's nested under this `unsafe` block
|
||||
LL | v.set_len(24);
|
||||
LL | |w: &mut Vec<u32>| { unsafe {
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
|
@ -76,12 +76,10 @@ LL | unsafe {}
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error: unnecessary `unsafe` block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:14
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:5
|
||||
|
|
||||
LL | unsafe { unsafe { unsf() } }
|
||||
| ------ ^^^^^^ unnecessary `unsafe` block
|
||||
| |
|
||||
| because it's nested under this `unsafe` block
|
||||
| ^^^^^^ unnecessary `unsafe` block
|
||||
|
||||
error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block
|
||||
--> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5
|
||||
|
Loading…
Reference in New Issue
Block a user