Skip to content

Commit

Permalink
Rollup merge of rust-lang#57734 - oli-obk:fixes_and_cleanups, r=pnkfelix
Browse files Browse the repository at this point in the history
Fix evaluating trivial drop glue in constants

```rust
struct A;
impl Drop for A {
    fn drop(&mut self) {}
}

const FOO: Option<A> = None;

const BAR: () = (FOO, ()).1;
```

was erroring with

```
error: any use of this value will cause an error
 --> src/lib.rs:9:1
  |
9 | const BAR: () = (FOO, ()).1;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^-^
  |                           |
  |                           calling non-const function `std::ptr::real_drop_in_place::<(std::option::Option<A>, ())> - shim(Some((std::option::Option<A>, ())))`
  |
  = note: #[deny(const_err)] on by default

error: aborting due to previous error
```

before this PR. According to godbolt this last compiled successfully in 1.27
  • Loading branch information
Centril authored Jan 25, 2019
2 parents 7779bb9 + 506393e commit 141fa85
Show file tree
Hide file tree
Showing 7 changed files with 68 additions and 30 deletions.
10 changes: 0 additions & 10 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2937,16 +2937,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}

/// Given the DefId of an item, returns its MIR, borrowed immutably.
/// Returns None if there is no MIR for the DefId
pub fn maybe_optimized_mir(self, did: DefId) -> Option<&'gcx Mir<'gcx>> {
if self.is_mir_available(did) {
Some(self.optimized_mir(did))
} else {
None
}
}

/// Get the attributes of a definition.
pub fn get_attrs(self, did: DefId) -> Attributes<'gcx> {
if let Some(id) = self.hir().as_local_node_id(did) {
Expand Down
29 changes: 16 additions & 13 deletions src/librustc_mir/const_eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,19 +340,22 @@ impl<'a, 'mir, 'tcx> interpret::Machine<'a, 'mir, 'tcx>
ret: Option<mir::BasicBlock>,
) -> EvalResult<'tcx, Option<&'mir mir::Mir<'tcx>>> {
debug!("eval_fn_call: {:?}", instance);
// Execution might have wandered off into other crates, so we cannot to a stability-
// sensitive check here. But we can at least rule out functions that are not const
// at all.
if !ecx.tcx.is_const_fn_raw(instance.def_id()) {
// Some functions we support even if they are non-const -- but avoid testing
// that for const fn! We certainly do *not* want to actually call the fn
// though, so be sure we return here.
return if ecx.hook_fn(instance, args, dest)? {
ecx.goto_block(ret)?; // fully evaluated and done
Ok(None)
} else {
err!(MachineError(format!("calling non-const function `{}`", instance)))
};
// Only check non-glue functions
if let ty::InstanceDef::Item(def_id) = instance.def {
// Execution might have wandered off into other crates, so we cannot to a stability-
// sensitive check here. But we can at least rule out functions that are not const
// at all.
if !ecx.tcx.is_const_fn_raw(def_id) {
// Some functions we support even if they are non-const -- but avoid testing
// that for const fn! We certainly do *not* want to actually call the fn
// though, so be sure we return here.
return if ecx.hook_fn(instance, args, dest)? {
ecx.goto_block(ret)?; // fully evaluated and done
Ok(None)
} else {
err!(MachineError(format!("calling non-const function `{}`", instance)))
};
}
}
// This is a const fn. Call it.
Ok(Some(match ecx.load_mir(instance.def) {
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_mir/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
}
trace!("load mir {:?}", instance);
match instance {
ty::InstanceDef::Item(def_id) => {
self.tcx.maybe_optimized_mir(def_id).ok_or_else(||
EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into()
)
}
ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) {
Ok(self.tcx.optimized_mir(did))
} else {
err!(NoMirFor(self.tcx.item_path_str(def_id)))
},
_ => Ok(self.tcx.instance_mir(instance)),
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/test/ui/consts/drop_none.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// compile-pass
#![allow(dead_code)]
struct A;
impl Drop for A {
fn drop(&mut self) {}
}

const FOO: Option<A> = None;

const BAR: () = (FOO, ()).1;


fn main() {}
14 changes: 13 additions & 1 deletion src/test/ui/static/static-drop-scope.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time
LL | (x, ()).1
| ^^^^^^^ constant functions cannot evaluate destructors

error: aborting due to 8 previous errors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:31:34
|
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors

error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:36:43
|
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
| ^^^^^^^^^^^ constants cannot evaluate destructors

error: aborting due to 10 previous errors

Some errors occurred: E0493, E0716.
For more information about an error, try `rustc --explain E0493`.
8 changes: 8 additions & 0 deletions src/test/ui/static/static-drop-scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,12 @@ const fn const_drop2<T>(x: T) {
//~^ ERROR destructors cannot be evaluated at compile-time
}

const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time

const HELPER: Option<WithDtor> = Some(WithDtor);

const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
//~^ ERROR destructors cannot be evaluated at compile-time

fn main () {}
14 changes: 13 additions & 1 deletion src/test/ui/static/static-drop-scope.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,19 @@ error[E0493]: destructors cannot be evaluated at compile-time
LL | (x, ()).1
| ^^^^^^^ constant functions cannot evaluate destructors

error: aborting due to 8 previous errors
error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:31:34
|
LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
| ^^^^^^^^^^^^^^^^^^^ constants cannot evaluate destructors

error[E0493]: destructors cannot be evaluated at compile-time
--> $DIR/static-drop-scope.rs:36:43
|
LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
| ^^^^^^^^^^^ constants cannot evaluate destructors

error: aborting due to 10 previous errors

Some errors occurred: E0493, E0597.
For more information about an error, try `rustc --explain E0493`.

0 comments on commit 141fa85

Please sign in to comment.